shouldly 0.0.2 copy "shouldly: ^0.0.2" to clipboard
shouldly: ^0.0.2 copied to clipboard

outdated

A simple, extensible, readable BDD assertion library.

shouldly #

Shouldly is an assertion framework which focuses on giving great error messages when the assertion fails while being simple and terse.

shouldly allows you write more readable test assertions.

Features #

  • Better test failure messages
  • More readable test code
  • Conjunction support (and only for now)
  • Custom matchers

Better test failure messages #

Readability #

More readable test code as an English sentence.

// without shouldly
expect(calculator.currentValue, 1);

// shouldly
calculator.currentValue.should.be(1);

You can mix up with Expected or Actual 🤔. But with shouldly there is no way to mix up.

// without shouldly
expect(playerCharacter.health, 100);
expect(100, playerCharacter.health);

// shouldly
playerCharacter.health.should.be(100);

Conjunctions #

This is a real English sentence, is it not?

13.should.beOdd().and.beGreaterOrEqualThan(13);

participants.should.contain('Andrew').and.not.contain('Bobby');

Custom matchers #

extension CustomNumberExtensions on Cap<num> {
  Cap<num> get beNegative {
    if (value >= 0) {
      throw Exception('Value\n  should be negative\n  but was\n$value');
    }
    return Cap(value);
  }
}

Or more exotic matchers

test('Custom matchers', () {
  final bobby = Customer(
    isMarried: true,
    gender: Gender.male,
  );
  bobby.should.beMale.and.beMarried;

  final kate = Customer(
    isMarried: true,
    gender: Gender.female,
  );
  kate.should.beMarried.and.not.beMale;
});

Getting started #

Simple add shouldly dependency into your project.

Usage #

Booleans #

test('false should be `false`', () {
  false.should.beFalse();
});

test('false should not be `true`', () {
  false.should.not.beTrue();
});

Numbers #

test('Int should be type of `num`', () {
  10.should.beTypeOf<num>();
});

Strings #

test('should not start with substring', () {
  const str = 'Flutter';
  str.should.not.startWith('A');
});

Iterables #

test('should contain', () {
  [1, 200, 3].should.contain(200);
});

test('should not contain', () {
  [1, 2, 4].should.not.contain(3);
});

test('with every element in collection is true for predicate', () {
  [3, 5, 7, 9].should.every((item) => item < 10);
});

test('with some elements in collection is true for predicate', () {
  [3, 5, 7, 9].should.any((item) => item > 8);
});

Maps #

final target = {
  'name': 'John',
  'age': 18,
};

test('should contain key', () {
  target.should.containKey('name');
});

test('should contain key with exact value', () {
  target.should.containKeyWithValue('age', 18);
});

Functions #

test('should not throw throw an exception', () {
  someMethod.should.notThrowException();
});

test('should throw exact type of exception', () {
  throwExactException.should.throwExact<CustomException>();
});

test('async function should throw exception', () async {
  await Should.throwAsync(() {
    Future.delayed(Duration(milliseconds: 100));
    throw Exception('test');
  });
});

test('async function should throw exact exception', () async {
  await Should.throwAsync<CustomException>(() {
    Future.delayed(Duration(milliseconds: 100));
    throw CustomException('custom exception test');
  });
});

test('should complete in a duration', () async {
  await Should.completeIn(
    Duration(seconds: 1),
    func: () => slowFunction(
      Duration(milliseconds: 900),
    ),
  );
});

More examples here

Writing Custom Matchers #

class Customer {
  final bool isMarried;
  final Gender gender;

  Customer(this.isMarried, this.gender);
}

extension CustomerExtension on Customer {
  Cap<Customer> get should => Cap<Customer>(this);
}

extension CustomerMatcherExtension on Cap<Customer> {
  Cap<Customer> get beMarried {
    if (!target.isMarried) {
      throw Exception('target should be married');
    }
    return Cap(target);
  }

  Cap<Customer> get beMale {
    if (isReversed) {
      if (target.gender == Gender.male) {
        throw Exception('target should be female');
      }
    } else {
      if (target.gender != Gender.male) {
        throw Exception('target should be male');
      }
    }

    return Cap(target);
  }
}

Contributing #

We accept the following contributions:

  • Reporting issues
  • Fixing bugs
  • More tests
  • Conjunction support (see: should.js and/or) (and conjunctions complete)
  • More class integrations (Streams? Futures?)
  • Improving documentation and comments

Maintainers #

23
likes
0
pub points
64%
popularity

Publisher

verified publisherdevcraft.ninja

A simple, extensible, readable BDD assertion library.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

collection

More

Packages that depend on shouldly