• Stars
    star
    43
  • Rank 645,449 (Top 13 %)
  • Language
    Dart
  • License
    MIT License
  • Created over 10 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A port of the Jasmine testing framework to Dart.

Guinness

Guinness is a port of the Jasmine library to Dart. It is based on the AngularDart implementation of Jasmine.

Build Status

Installation

You can find the Guinness installation instructions here.

Importing the Library

import 'package:guinness/guinness.dart';

main() {
  //you specs
}

If you are testing a client-side application, and you want to use html matchers, import the guinness_html library.

import 'package:guinness/guinness_html.dart';

main() {
  guinnessEnableHtmlMatchers();
  //you specs
}

Syntax

Guinness specs are comprised of describe, it, beforeEach, and afterEach blocks.

import 'package:guinness/guinness.dart';

main(){
  describe("syntax", () {
    beforeEach(() {
      print("outer before");
    });

    afterEach(() {
      print("outer after");
    });

    it("runs first", () {
      print("first");
    });

    describe("nested describe", () {
      beforeEach(() {
        print("inner before");
      });

      afterEach(() {
        print("inner after");
      });

      it("runs second", () {
        print("second");
      });
    });
  });
}

This will print:

outer before, first, outer after
outer before, inner before, second, inner after, outer after
  • To exclude a describe, change it to xdescribe.
  • To exclude an it, change it to xit.
  • To make a describe exclusive, change it to ddescribe.
  • To make an it exclusive, change it to iit.

If there is an iit in your spec files, Guinness will run only iits. In this case ddescribes will be ignored.

Pending Specs

Guinness supports pending describe and it blocks (blocks without a callback).

describe("pending describe");
xdescribe("pending xdescribe");
ddescribe("pending ddescribe");

it("pending it");
xit("pending xit");
iit("pending iit");

Async

Since Dart has built-in futures, the Guinness framework makes a good use out of them. If you return a future from beforeEach, afterEach, or it, the framework will wait for that future to be resolved.

For instance:

beforeEach(connectToTheDatabase);

where connectToTheDatabase returns a future.

Similarly, you can write:

afterEach(releaseConnection);

You can also write async specs using the following technique:

it("should return an empty list when the database is empty", () {
  return queryDatabase().then((results){
    expect(results).toEqual([]);
  });
});

If a returned future gets rejected, the test fails.

Expect

They way you write assertions in Guinness is by using the expect function, as follows:

expect(2).toEqual(2);

These are a few examples:

expect(2).toEqual(2);
expect([1,2]).toContain(2);
expect(2).toBe(2);
expect(()=> throw "BOOM").toThrow();
expect(()=> throw "BOOM").toThrow("BOOM");
expect(()=> throw "Invalid Argument").toThrowWith(message: "Invalid");
expect(()=> throw new InvalidArgument()).toThrowWith(anInstanceOf: InvalidArgument);
expect(()=> throw new InvalidArgument()).toThrowWith(type: ArgumentException);
expect(false).toBeFalsy();
expect(null).toBeFalsy();
expect(true).toBeTruthy();
expect("any object").toBeTruthy();
expect("any object").toBeDefined();
expect(null).toBeNull();
expect("not null").toBeNotNull();

expect(2).not.toEqual(1);
expect([1,2]).not.toContain(3);
expect([1,2]).not.toBe([1,2]);
expect((){}).not.toThrow();
expect(null).not.toBeDefined();

expect(new DocumentFragment.html("<div>some html</div>"))
    .toHaveHtml("<div>some html</div>");

expect(new DocumentFragment.html("<div>some text</div>"))
    .toHaveText("some text");

expect(new DivElement()..classes.add('abc'))
    .toHaveClass("abc");

expect(new DivElement()..attributes['attr'] = 'value')
    .toHaveAttribute("attr");

expect(new DocumentFragment.html("<div>some html</div>"))
    .not.toHaveHtml("<div>some other html</div>");

expect(new DocumentFragment.html("<div>some text</div>"))
    .not.toHaveText("some other text");

expect(new DivElement()..classes.add('abc'))
    .not.toHaveClass("def");

expect(new DivElement()..attributes['attr'] = 'value')
    .not.toHaveAttribute("other-attr");

final select = new SelectElement();
select.children
  ..add(new OptionElement(value: "1"))
  ..add(new OptionElement(value: "2", selected: true))
  ..add(new OptionElement(value: "3"));
expect(select).toEqualSelect(["1", ["2"], "3"]);

You can also use unittest matchers, like this:

expect(myObject).to(beValid); //where beValid is a unittest matcher

Migrating from Unittest

To make migration from the unittest library to Guinness easier, expect supports an optional second argument.

expect(myObject, beValid); //same as expect(myObject).to(beValid);

This keeps your unittest assertions working, so you can change them one by one.

While transitioning you can have both the unittest and guinness libraries imported:

import 'package:unittest/unittest.dart' hide expect;
import 'package:guinness/guinness.dart';

Extending Guinness

If you are using a lot of custom matchers, and using expect(object).to(matcher) is tedious, you can extend the library, as follows:

library test_helper;

import 'guinness.dart' as gns;
export 'guinness.dart';

final _m = gns.guinness.matchers;

class CustomExpect extends gns.Expect {
  CustomExpect(actual) : super(actual);

  toBePositive() => _m.expect(actual > 0, true, reason: 'is not positive');
}

CustomExpect expect(actual) => new CustomExpect(actual);

Spy

Guinness supports Jasmine-like spy functions:

final s = guinness.createSpy("my spy");
expect(s).not.toHaveBeenCalled();

s(1);
expect(s).toHaveBeenCalled();
expect(s).toHaveBeenCalledOnce();
expect(s).toHaveBeenCalledWith(1);
expect(s).toHaveBeenCalledOnceWith(1);
expect(s).not.toHaveBeenCalledWith(2);

s(2);
expect((){
  expect(s).toHaveBeenCalledOnce();
}).toThrow();

expect((){
  expect(s).toHaveBeenCalledOnceWith(1);
}).toThrow();

In addition, Guinness support spy objects:

class SomeSpy extends SpyObject implements SomeInterface {}

...

final s = new SomeSpy();
s.invoke(1,2);
s.name;
s.name = 'some name';

expect(s.spy("invoke")).toHaveBeenCalled();
expect(s.spy("get:name")).toHaveBeenCalled();
expect(s.spy("set:name")).toHaveBeenCalled();

And:

final s = new SomeSpy();
s.spy("invoke").andCallFake((a,b) => a + b);

expect(s.invoke(1,2)).toEqual(3);

You can also use the mock and dart_mocks libraries with it.

Guinness and Unittest

Guinness supports pluggable backends, but by default runs on top of the unittest library. Which means that if unittest.autoStart is set to true, your specs will run automatically.

You can always initialize specs manually:

guinness.initSpecs();

You can also run the specs, like this:

guinness.runSpecs();

Usually, you don't need to worry about it.

Guinness and Karma

Guinness works with Karma. Just include initSpecs, as follows:

files: [
  "test/main1_test.dart",
  "test/main2_test.dart",
  "packages/guinness/init_specs.dart",
  {pattern: '**/*.dart', watched: true, included: false, served: true}
]

Status

There are a few things that are still not supported (e.g., handling named parameters in expectations).

Implementation Details

Key Ideas

The main idea is to treat the Jasmine syntax as a domain specific language. Therefore, the implementation clearly separates such things as: syntax, semantic model, and execution model. Let's quickly look at the benefits this approach provides:

The semantic model is separate from the syntax.

The semantic model consists of It, Describe, Suite, BeforeEach, and AfterEach objects. You can create and analyse them without using the context-dependent nested Jasmine syntax.

The parsing of specs is separate from the execution of specs.

The library builds a tree of the It, Describe, Suite, BeforeEach, and AfterEach objects first. And after that, as a separate step, executes them. It enables all sorts of preprocessing (e.g., filtering, reordering).

Pluggable backends.

Since the library is a DSL, there can be multiple backend libraries actually executing the specs. By default, the library comes with the unittest backend.

Contributors

  • Google Inc
  • Victor Savkin
  • Victor Berchet
  • Marko Vuksanovic

More Repositories

1

large-monorepo

Benchmarking Nx and Turborepo
TypeScript
435
star
2

state_management_ngrx4

TypeScript
208
star
3

DCI-Sample

A sample application illustrating the Data Context Interaction paradigm (in Ruby)
Ruby
152
star
4

router_mailapp

TypeScript
114
star
5

angulardart-sample-app

A sample Web application built using AngularDart
Dart
102
star
6

RuntimeTypeChecks

Runtime type checks for JavaScript and TypeScript
TypeScript
85
star
7

ng1ng2router

TypeScript
73
star
8

essential-angular-book-app

TypeScript
66
star
9

router_lazyloading

TypeScript
62
star
10

state-app-examples

TypeScript
57
star
11

router-store

TypeScript
51
star
12

interstellar

Nx: On how to make your CI 10 times faster with 1-line config change
TypeScript
50
star
13

fpdart

Functional Programming in Dart
Dart
47
star
14

upgrade-book-examples

TypeScript
38
star
15

SimpleMVP

VINT is a library for building single-page applications in Dart.
Dart
36
star
16

hammock

AngularDart service for working with Rest APIs
Dart
34
star
17

tex

tex
TypeScript
18
star
18

chat-dart

Dart
17
star
19

frp_dart

Functional Reactive Programming in Dart
Dart
15
star
20

custom-renderer

Experiments with Angular Renderers
TypeScript
15
star
21

HabiticaClient

App built using Angular 2 and Immutable JS
TypeScript
15
star
22

ngselectors

Redux-style selectors for Angular 2.
TypeScript
15
star
23

angular2-immutable-kanban

JavaScript
14
star
24

marble_testing_and_race_conditions

TypeScript
14
star
25

CoolCodeSnippets

Collection of interesting code snippets in JavaScript and TypeScript
TypeScript
13
star
26

actors

Actors.Dart - Building Distributed Applications on the Web Platform
Dart
12
star
27

databinder

DataBinder is a Dart library implementing data binding via object mirrors.
Dart
12
star
28

composing-ngrxstore-reducers

TypeScript
11
star
29

large-repo

TypeScript
11
star
30

router-store-prototype

TypeScript
11
star
31

polymer_dart_sample_app

Auctions (a sample application built using Polymer.Dart)
Dart
10
star
32

lerna-dte

"Lerna & Distributed Task Execution" Example
TypeScript
9
star
33

dartmocks

DartMocks is a mock framework for Dart inspired by RSpec.
Dart
9
star
34

rubyast

Allows AST Transformations for Ruby.
Ruby
8
star
35

webpack_angular_dev_and_prod

TypeScript
6
star
36

chat-node

JavaScript
6
star
37

XmlTransformer

Groovy
6
star
38

ng-conf-app

TypeScript
6
star
39

nx-dev-ergonomics

Nx and its wonderful DX
TypeScript
5
star
40

router-spinners

TypeScript
5
star
41

Gradle-Project-Generator

Groovy script generating Gradle projects
Groovy
5
star
42

Testing-Framework--Picard-

Ruby
4
star
43

libandapp

TypeScript
4
star
44

novosibirsk

TypeScript
4
star
45

TypedFields

Ruby Gem adding AR like type conversions for regular ruby objects
Ruby
3
star
46

atscript_todomvc

CSS
3
star
47

serializers

Serializers is a Dart library for serializing objects into maps.
Dart
3
star
48

AST-Transformations

Groovy
3
star
49

csw-catalog

CSW 2.0.2 + Client
Ruby
3
star
50

router-nested-outlets

TypeScript
3
star
51

use-case-service

TypeScript
3
star
52

GroovyMigrationScript

Performs database migrations
Groovy
2
star
53

learnwords

a simple application for learning new words
Ruby
2
star
54

dci-in-ruby.github.com

DCI in Ruby
Ruby
2
star
55

routerrefresh

TypeScript
2
star
56

PersistentHashMap

An implementation of a map that can be saved to a file and can be read from a file.
Groovy
2
star
57

vimconfig

my vim config
Vim Script
2
star
58

InspectPartials

A small gem showing partial names
Ruby
1
star
59

TinyDiary

Small Grails app helping you to keep track of your productive and unproductive days
Groovy
1
star
60

rmilk

A console application for managing your remember-the-milk tasks
Ruby
1
star
61

vint

Dart
1
star
62

dotfiles

Shell
1
star
63

patched_cli

JavaScript
1
star
64

RTM

Ruby
1
star
65

jruby_ast_transformations

Ruby
1
star
66

robots

Clojure
1
star
67

emacs.d

Emacs Lisp
1
star
68

pallets-samples

Ruby
1
star
69

nx-large-repo-perf

JavaScript
1
star
70

JasmineDart

Dart
1
star
71

demoapp

TypeScript
1
star
72

RailsH2

Ruby
1
star
73

TestProject

Showing how to publish artifacts using Gradle
1
star
74

fake-server

TypeScript
1
star
75

angulardart-angularjs

Side-by-side comparison of AngularDart and AngularJS.
Dart
1
star
76

vladivostok_demo

TypeScript
1
star
77

rabbitmq_samples

Ruby
1
star
78

oald_parser

a simple parser of the oxford online dictionary
Ruby
1
star
79

hammock_mapper

Hammock Mapper
Dart
1
star
80

samplenx

TypeScript
1
star
81

westormsettings

1
star
82

LogsUI

Groovy
1
star
83

lazyload_angular13

TypeScript
1
star