dartunit
A dart library to write unit tests based on XUnit Patterns.
test\stack_test.dart
// ignore_for_file: non_constant_identifier_names
library stack_test;
import 'package:dartunit/dartunit.dart';
import 'package:stack/stack.dart';
void main() {
runTestsByLibraryName('stack_test');
}
mixin ComposedExpect{
Stack get stack;
void expectStackIsEmpty(){
expect(stack.isEmpty, isTrue);
expect(stack.size, isZero);
}
void expectStackSizeIsOne(){
expect(stack.size, equals(1));
expect(stack.isEmpty, isFalse);
}
void expectStackSizeIsTwo(){
expect(stack.size, equals(2));
expect(stack.isEmpty, isFalse);
}
}
@TestCase()
@Root()
class StackTest with ComposedExpect{
@override
late final Stack stack;
}
@TestCase()
class GivenNewlyCreatedStackWith3Capacity extends StackTest{
@SetUp()
void createStackWith3Capacity() {
stack = Stack<int>(capacity: 3);
}
@Test()
void shouldBeEmpty(){
expectStackIsEmpty();
}
@Test()
void push_ShouldIncrementSizeByOne(){
stack.push(10);
expectStackSizeIsOne();
stack.push(10);
expectStackSizeIsTwo();
}
@Test()
void push_WhenPastCapacity_ShouldThrowStackOverFlow(){
void act(){
stack.push(10);
stack.push(10);
stack.push(10);
stack.push(10);
}
expect(act, throwsA(isA<StackOverflowException>()));
}
@Test()
void pop_ShouldThrowStackUnderFLow(){
void act(){
stack.pop();
}
expect(act, throwsA(isA<StackUnderflowException>()));
}
@Test()
void pop_GivenPushingTwoItems_ShouldDecrementSizeByOne(){
stack.push(10);
stack.push(10);
stack.pop();
expectStackSizeIsOne();
stack.pop();
expectStackIsEmpty();
}
@Test()
void peek_ShouldThrowStackEmpty(){
void act(){
stack.peek();
}
expect(act, throwsA(isA<StackEmptyException>()));
}
@Test()
void push_pop_WhenXIsPushed_XShouldBePopped(){
final x = 10;
stack.push(x);
expect(stack.pop(), equals(x));
}
@Test()
void push_pop_WhenXAndYArePushed_YAndXShouldBePopped(){
final x = 10;
final y = 20;
stack.push(x);
stack.push(y);
expect(stack.pop(), equals(y));
expect(stack.pop(), equals(x));
}
@Test()
void peek_GivenPushingXAndY_ShouldReturnY(){
final x = 10;
final y = 20;
stack.push(x);
stack.push(y);
expect(stack.peek(), equals(y));
}
}
@TestCase()
class NegativeCapacityStack extends StackTest{
@Test()
void whenStackWithNegativeCapacityIsCreated_IllegalCapacityShouldBeThrown(){
void act(){
Stack<int>(capacity: -1);
}
expect(act, throwsA(isA<IllegalCapacityException>()));
}
}
@TestCase()
class GivenZeroCapacityStack extends StackTest{
@SetUp()
void createStackWithZeroCapacity() {
stack = Stack<int>(capacity: 0);
}
@Test()
void shouldBeEmpty(){
expectStackIsEmpty();
}
@Test()
void push_ShouldThrowStackOverFlow(){
void act(){
stack.push(10);
}
expect(act, throwsA(isA<StackOverflowException>()));
}
@Test()
void pop_ShouldThrowStackUnderFLow(){
void act(){
stack.pop();
}
expect(act, throwsA(isA<StackUnderflowException>()));
}
@Test()
void peek_ShouldThrowStackEmpty(){
void act(){
stack.peek();
}
expect(act, throwsA(isA<StackEmptyException>()));
}
}
lib\stack.dart
class Stack<T>{
factory Stack({int capacity = 5}){
if(capacity < 0)
throw IllegalCapacityException();
if(capacity == 0)
return _ZeroCapacityStack<T>();
return Stack<T>._(capacity: capacity);
}
Stack._({int capacity = 5}) : _items = List.filled(capacity, null);
final List<T?> _items;
bool get isEmpty => _size == 0;
int get size => _size;
int _size = 0;
void push(T item) {
if(_isFull)
throw StackOverflowException();
_items[_size++] = item;
}
bool get _isFull => _size == _items.length;
T pop() {
if(isEmpty)
throw StackUnderflowException();
return _items[--_size]!;
}
T peek() {
if(isEmpty)
throw StackEmptyException();
return _items[size-1]!;
}
}
class _ZeroCapacityStack<T> extends Stack<T>{
_ZeroCapacityStack() : super._(capacity: 0);
@override
bool get isEmpty => true;
@override
int get size => 0;
@override
void push(T item) {
throw StackOverflowException();
}
@override
T pop() {
throw StackUnderflowException();
}
@override
T peek() {
throw StackEmptyException();
}
}
class StackOverflowException implements Exception{}
class StackUnderflowException implements Exception{}
class StackEmptyException implements Exception{}
class IllegalCapacityException implements Exception{}
Then run tests with following command:
dart test test/your_file.dart --reporter=expanded