A BDD-style assertion library for Dart.

Overview

A BDD-style assertion library for Dart developers. It has built-in support for most common primitives, including Strings, Numbers Functions, Iterables. It also has type and equality checks built in for all objects.

should is currently in production use in 4 of my projects, and is part of a larger testing framework. This framework is un-named and under development for open-sourcing. should will, upon that package's release, be available both bundled and independently.

Usage

should is based on OO chains; at the end of the assertion, a reflective operation captures each 'section' of the assertion. A simple example:

import 'package:should/should.dart';

main() {
  var dou = 2.0;

  requireThat(dou).be<int>(); //oops, doubles aren't int --> error

  //but we can put in our own logic --> No error
  unless(dou is double).requireThat(dou).be<int>();

  //doubles are not subclass of int --> No error
  requireThat(dou).not.beSubclassOf<int>();

  // There is three options for type checking:
  // dou.should.be<int> is equivalent to: assert(dou is int).
  // dou.should.beSubclass (dou is an instance of a subclass of given type)
  // or dou.should.instantiate (dou is a direct instance of given type).

  //2.0 == 2.0 && 2.0 != 0--> No error
  requireThat(dou).equal(2.0).and.not.equalAllOf([0, 1, 2, 3, 4]);

  print('evaluated 4 should statements');
}

Matchers

should has specific matchers beyond the general matchers displayed above. (It also has a few other general matchers not shown above). These are imported through specific libraries. For instance, if I wanted matchers for numbers as well as Strings, I would import:

import 'package:should/should.dart';
import 'package:should/should_num.dart';
import 'package:should/should_string.dart';

Documentation for all the matchers will come soon. For now, you can check the API reference all the available matchers ( Cap is our name for matchers).

Matchers are currently available for: Numbers, Strings, Zero-parameter functions, and Iterables. Matchers are planned for: Parameterized spies, Streams, and Futures.

File an issue if you think there's a matcher type we should support! Or, write your own (see below)!

Writing Custom Matchers

To write a custom matcher, you'll have to write an extension over BaseShouldObject. Suppose we wanted to check if a num is negative. We would write an extension like this:

extension ShouldNumExtension on BaseShouldObject<num> {
  Cap<num> get beNegative {
    var cap = Cap<num>((obj) {
      num n = obj as num; //cast dynamic object to num
      return n < 0;
    }, this, 'be negative');
    finalEval(cap);
    return cap;
  }
}

There's a few critical pieces here. the declaration starting with var cap = is creating a Cap object, which is the internal representation of a matcher. Cap takes three parameters: a bool Function(dynamic), a BaseShouldObject, and a String. The first is your business logic, as seen above. The second is internal; it should always be this. The last is the debugging description of this matcher. Imagine the matcher in a sentence to come up with this: 2 should (be negative). To adapt this sample to another type is easy: simply replace the word num wherever it appears with your own type.

We could then use our matcher anywhere that both 'package:should/should.dart' and the extension from above have been imported.

requireThat(-2).beNegative;

should vs. assert

should is meant to be used as a drop-in replacement for assert. If assert would not throw an error, this library does not either. However, this library will print short error messages to the console regardless of whether assertions are enabled.

This library, in my opinion, is also easier to read than an arbitrary assertion. It follows the laws of English, which are easier to read intuitively than mathematical lingo.

should additionally has cleaner outputs to the terminal, using some hardcoded psuedo-introspection to determine what a failed assertion was attempting to do. For example, the assertion:

2.0.should.beType<int>();

fails in should with the error message: Your should assertion failed on line 10: 2.0 should be Type int, as well as a StackTrace. assert would just give you the StackTrace. Note that all stacktraces aren't created equal; take a look at a sample I've compiled for assert:

Unhandled exception:
'file:///home/___/___/should/example/generic_example.dart': Failed assertion: line 11 pos 10: 'dou is int': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5)
#2      genericExample (file:///home/akishore/IdeaProjects/should/example/generic_example.dart:11:10)
#3      main (file:///home/akishore/IdeaProjects/should/example/generic_example.dart:5:3)
#4      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#5      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

vs. should for the equivalent call:

┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ Your should assertion failed on line 11: 2.0 should be Type int
│ See the StackTrace below for more details...
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
example/generic_example.dart 11:14              genericExample
example/generic_example.dart 5:3                main

Just like with assert, you can enable or disable error-throwing. Use should.errorOnAssert = true; to make should throw errors on failed assertions. Unfortunately, if this is set to true, then you will lose the enhanced, terse StackTraces from above.

should vs. expect

expect is the assertion method for the built in testing library (https://pub.dev/packages/test). should will work in these tests, but only if you set should.errorOnAssert = true. should will still print the first error message (the introspective one starting with "Your should assertion failed...), but you'll lose the terse stacktrace in exchange for whatever the test package gives you.

should vs. expect, on a functional level, are fairly similar. It is mostly a stylistic difference: expect uses a Unit Test Matcher style, whereas should uses a BDD style. BDD is more readable but less concise than the style expect uses.

TODO: Where We're Heading

  • More tests
  • Conjunction support (see: should.js and/or) (and conjunctions complete)
  • More class integrations (Streams? Futures?)
  • Cleaner code documentation and comments
  • Simple Spies

Features and bugs

Please file feature requests and bugs at the issue tracker.

This library is licensed under the MPL 2.0.
You might also like...

A very easy-to-use navigation tool/widget for having iOS 13 style stacks.

cupertino_stackview A very easy-to-use navigation tool/widget for having iOS 13 style stacks. It is highly recommended to read the documentation and r

Nov 18, 2022

A highly customisable and simple widget for having iOS 13 style tab bars.

cupertino_tabbar A highly customisable and simple widget for having iOS 13 style tab bars. It is highly recommended to read the documentation and run

Oct 31, 2022

Nepali date picker - Material Style Date Picker with Bikram Sambat(Nepali) Calendar Support

Nepali date picker - Material Style Date Picker with Bikram Sambat(Nepali) Calendar Support

Nepali Date Picker + Calendar Material and Cupertino Styled Date Picker, Date Range Picker and Calendar with Bikram Sambat(Nepali) Support. Nepali Dat

Jan 3, 2023

Styledwidget - Simplifying widget style in Flutter.

Styledwidget - Simplifying widget style in Flutter.

Simplifying your widget tree structure by defining widgets using methods. Thanks to the introduction of extension methods in Dart 2.7.0, styled_widget

Jan 2, 2023

Iosish indicator - 🍎 Create awesome and simple iOS style floating indicator which can be found when silent/sleep mode switched on Flutter.

Iosish indicator - 🍎 Create awesome and simple iOS style floating indicator which can be found when silent/sleep mode switched on Flutter.

Iosish indicator - 🍎 Create awesome and simple iOS style floating indicator which can be found when silent/sleep mode switched on Flutter.

Apr 1, 2022

An Instagram like text editor Flutter widget that helps you to change your text style.

An Instagram like text editor Flutter widget that helps you to change your text style.

TextEditor An instagram like text editor widget for flutter Show some ❤️ and star the repo to support the project Features Edit TextStyle object font

Dec 16, 2022

A pattern editor, in the "style" of a Tracker, for the Korg Electribe 2's (synth, sampler, hacktribe).

A pattern editor, in the

elfer A pattern editor, in the "style" of a Tracker, for the Korg Electribe 2's (synth, sampler, hacktribe). Status This is very much a WORK-IN-PROGRE

Dec 5, 2022

A simple "Hello, World" style Flutter app.

A simple

Flutter Sample App - Hello World This is a simple Flutter (Dart) app with a single view. The intention of this application is to demonstrate the usage

May 9, 2022
A kotlin-style extension collection for dart.

Collection of extensions Dart is good but can be better. Kotlin Style Join QQ Group now: 1003811176 For objects: let run also takeIf takeUnless For st

OpenFlutter 6 Nov 2, 2022
A middleware library for Dart's http library.

http_middleware A middleware library for Dart http library. Getting Started http_middleware is a module that lets you build middleware for Dart's http

TED Consulting 38 Oct 23, 2021
This library provides the easiest and powerful Dart/Flutter library for Mastodon API 🎯

The Easiest and Powerful Dart/Flutter Library for Mastodon API ?? 1. Guide ?? 1.1. Features ?? 1.2. Getting Started ⚡ 1.2.1. Install Library 1.2.2. Im

Mastodon.dart 55 Jul 27, 2023
Ubuntu Yaru Style - Distinct look and feel of the Ubuntu Desktop

Ubuntu Yaru Style - Distinct look and feel of the Ubuntu Desktop Using Yaru To be able to use this package follow this steps: Installation Make you su

Ubuntu 226 Dec 28, 2022
Flutter cupertino style date picker.

Flutter Cupertino Date Picker [pub packages] | 中文说明 Flutter cupertino date picker. Usage 1. Depend Add this to you package's pubspec.yaml file: depend

Dylan Wu 333 Dec 26, 2022
Flutter cupertino style date picker.

Flutter Cupertino Date Picker [pub packages] | 中文说明 Flutter cupertino date picker. Usage 1. Depend Add this to you package's pubspec.yaml file: depend

Dylan Wu 333 Dec 26, 2022
🎮 Style your flutter game with a beautiful splash screen.

Flame Splash Screen Style your flame game with a beautiful splash screen. This package includes a FlameSplashScreen widget. Install Add flame_splash_s

Flame Engine 38 Sep 13, 2022
(RPG maker) Create RPG-style or similar games more simply with Flame.

Bonfire Build RPG games and similar with the power of FlameEngine! Bonfire is ideal for building games from the following perspectives: Test our onlin

Rafael Almeida Barbosa 787 Jan 7, 2023
Flutter page widget that is dismissed by swipe gestures, with Hero style animations, Inspired by Facebook and Instagram stories.

dismissible_page ?? ?? Creates page that is dismissed by swipe gestures, with Hero style animations, Inspired by FB, IG stories. Live Demo Contents Su

Tornike 76 Dec 22, 2022
The easiest way to style custom text snippets in flutter

Super Rich Text Check it out at Pub.Dev The easiest way to style custom text snippets Help Maintenance I've been maintaining quite many repos these da

Woton Sampaio 14 Nov 4, 2022