diff --git a/README.md b/README.md index cdcf816..bff9756 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Guinness2 is a port of the Jasmine library to Dart. It is based on the AngularDa Backed by `dart:test` instead of `dart:unittest`. Run via `pub run test` instead of a Karma setup. Removed bits referring to 'runner' programatically - just use `pub run test`. Removed deprecated -showStats option. +showStats option. Remove all context-keeping, as this is now handles by package:test directly. ## Installation @@ -41,7 +41,7 @@ Guinness specs are comprised of `describe`, `it`, `beforeEach`, and `afterEach` ```dart import 'package:guinness2/guinness2.dart'; -main(){ +main() { describe("syntax", () { beforeEach(() { print("outer before"); @@ -81,8 +81,7 @@ This will print: * 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 `iit`s. In this case `ddescribe`s will be ignored. +* *Important:* to run exclusive tests, add `--tags solo` to your command line invocation. ### Pending Specs @@ -92,11 +91,9 @@ Guinness supports pending describe and it blocks (blocks without a callback). ```dart describe("pending describe"); xdescribe("pending xdescribe"); -ddescribe("pending ddescribe"); it("pending it"); xit("pending xit"); -iit("pending iit"); ``` ## Async @@ -264,29 +261,13 @@ expect(s.invoke(1,2)).toEqual(3); You can also use the `mock` and `dart_mocks` libraries with it. -## 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. +Dart's `package:test` supports most of the original Guinness test organization natively, +so we simply forward to the appropriate `package:test` function. -Since the library is a DSL, there can be multiple backend libraries actually executing the specs. By default, -the library comes with the test backend. +The large exception is expectations, matchers, and spies, which are unchanged +from original Guinness. diff --git a/example/example.dart b/example/example.dart index a96b988..5669a00 100644 --- a/example/example.dart +++ b/example/example.dart @@ -8,7 +8,7 @@ import 'dart:html'; class TestClass {} main() { - GuinnessEnableHtmlMatchers(); + guinnessEnableHtmlMatchers(); describe("guinness2", () { it("has various built-in matchers", () { diff --git a/lib/guinness2.dart b/lib/guinness2.dart index 91446d1..90a165c 100644 --- a/lib/guinness2.dart +++ b/lib/guinness2.dart @@ -8,16 +8,12 @@ import 'dart:math' as math; export 'package:test/test.dart' show TestOn; -part 'src/common/model.dart'; -part 'src/common/context.dart'; part 'src/common/syntax.dart'; part 'src/common/expect.dart'; part 'src/common/spy.dart'; part 'src/common/interfaces.dart'; part 'src/common/guinness_config.dart'; part 'src/common/test_backend.dart'; -part 'src/common/exclusive_visitor.dart'; -part 'src/common/suite_info.dart'; class _Undefined { const _Undefined(); @@ -25,5 +21,4 @@ class _Undefined { const _u = const _Undefined(); final Guinness guinness = new Guinness( - matchers: new TestMatchers(), - initSpecs: testInitSpecs); + matchers: new TestMatchers()); diff --git a/lib/src/common/context.dart b/lib/src/common/context.dart deleted file mode 100644 index 70bc7ac..0000000 --- a/lib/src/common/context.dart +++ /dev/null @@ -1,43 +0,0 @@ -part of guinness2; - -class Context { - final List describes = []; - - Describe get currentDescribe => describes.last; - Describe get suite => describes.first; - - Context() { - describes.add(new Suite(this)); - } - - void withDescribe(Describe describe, Function definition) { - describes.add(describe); - try { - definition(); - } finally { - describes.removeLast(); - } - } - - void addBeforeEach(Function fn, {int priority}) { - final beforeEach = new BeforeEach(fn, priority: priority); - currentDescribe.addBeforeEach(beforeEach); - } - - void addAfterEach(Function fn, {int priority}) { - final afterEach = new AfterEach(fn, priority: priority); - currentDescribe.addAfterEach(afterEach); - } - - void addIt(String name, Function fn, {bool excluded, bool exclusive}) { - final it = new It(name, currentDescribe, fn, - excluded: excluded, exclusive: exclusive); - currentDescribe.add(it); - } - - void addDescribe(String name, Function fn, {bool excluded, bool exclusive}) { - final describe = new Describe(name, currentDescribe, this, fn, - excluded: excluded, exclusive: exclusive); - currentDescribe.add(describe); - } -} diff --git a/lib/src/common/exclusive_visitor.dart b/lib/src/common/exclusive_visitor.dart deleted file mode 100644 index b7421db..0000000 --- a/lib/src/common/exclusive_visitor.dart +++ /dev/null @@ -1,26 +0,0 @@ -part of guinness2; - -class ExclusiveVisitor implements SpecVisitor { - bool containsExclusiveIt = false; - bool containsExclusiveDescribe = false; - - void visitSuite(Suite suite) { - _visitChildren(suite.children); - } - - void visitDescribe(Describe describe) { - if (describe.excluded) return; - if (describe.exclusive) containsExclusiveDescribe = true; - - _visitChildren(describe.children); - } - - void visitIt(It it) { - if (it.excluded) return; - if (it.exclusive) containsExclusiveIt = true; - } - - _visitChildren(children) { - children.forEach((c) => c.visit(this)); - } -} diff --git a/lib/src/common/guinness_config.dart b/lib/src/common/guinness_config.dart index 9ddb836..2440670 100644 --- a/lib/src/common/guinness_config.dart +++ b/lib/src/common/guinness_config.dart @@ -1,14 +1,9 @@ part of guinness2; class Guinness { - Context _context = new Context(); dynamic matchers; - SpecRunner _initSpecs; - bool autoInit = true; - Guinness({this.matchers, SpecRunner initSpecs}) - : _initSpecs = initSpecs { - _scheduleAutoInit(); + Guinness({this.matchers}) { } SpyFunction createSpy([String name]) => new SpyFunction(name); @@ -16,20 +11,4 @@ class Guinness { SpyFunction spyOn(obj, String name) { throw "Not implemented"; } - - void initSpecs() { - _initSpecs(_context.suite); - } - - void resetContext([Context context]) { - _context = context == null ? new Context() : context; - } - - SuiteInfo suiteInfo() => _suiteInfo(_context.suite); - - void _scheduleAutoInit() { - async.scheduleMicrotask(() { - if (autoInit) initSpecs(); - }); - } } diff --git a/lib/src/common/interfaces.dart b/lib/src/common/interfaces.dart index d37ceaa..b8091b2 100644 --- a/lib/src/common/interfaces.dart +++ b/lib/src/common/interfaces.dart @@ -1,13 +1,5 @@ part of guinness2; -typedef void SpecRunner(Suite suite); - -abstract class SpecVisitor { - void visitSuite(Suite suite); - void visitDescribe(Describe describe); - void visitIt(It it); -} - abstract class Matchers { dynamic get config; diff --git a/lib/src/common/model.dart b/lib/src/common/model.dart deleted file mode 100644 index 5f2fb0c..0000000 --- a/lib/src/common/model.dart +++ /dev/null @@ -1,123 +0,0 @@ -part of guinness2; - -class BeforeEach { - final Function fn; - final int priority; - - BeforeEach(this.fn, {this.priority}); - - call() => fn(); -} - -class AfterEach { - final Function fn; - final int priority; - - AfterEach(this.fn, {this.priority}); - - call() => fn(); -} - -abstract class Spec { - final String name; - final Describe parent; - final bool excluded; - final bool exclusive; - final bool pending; - - Spec(this.name, this.parent, {this.excluded, this.exclusive, this.pending}); -} - -class It extends Spec { - final Function fn; - - It(String name, Describe parent, Function fn, {bool excluded, bool exclusive}) - : super(name, parent, - excluded: excluded, exclusive: exclusive, pending: fn == null), - this.fn = fn; - - String get name => pending ? 'PENDING: ${super.name}' : super.name; - - Function get withSetupAndTeardown { - if (pending) { - return () => new async.Future.value(true); - } else { - return () => _runAllBeforeEach().then(_runItWithAfterEach); - } - } - - Iterable get beforeEachFns { - final fns = []; - var c = parent; - while (c != null) { - fns.insertAll(0, c.beforeEachFns); - c = c.parent; - } - fns.sort((a, b) => Comparable.compare(b.priority, a.priority)); - return fns; - } - - Iterable get afterEachFns { - final fns = []; - var c = parent; - while (c != null) { - fns.addAll(c.afterEachFns); - c = c.parent; - } - fns.sort((a, b) => Comparable.compare(b.priority, a.priority)); - return fns; - } - - void visit(SpecVisitor visitor) => visitor.visitIt(this); - - _runItWithAfterEach(_) { - final success = (_) => _runAllAfterEach(); - final failure = (errorThrownByIt, stackTrace) => _runAllAfterEach() - .whenComplete( - () => new async.Future.error(errorThrownByIt, stackTrace)); - return _runIt().then(success, onError: failure); - } - - _runIt() => new async.Future.sync(fn); - _runAllBeforeEach() => _runAll(beforeEachFns); - _runAllAfterEach() => _runAll(afterEachFns); - _runAll(List fns) => async.Future.forEach(fns, (fn) => fn()); -} - -class Describe extends Spec { - final Context context; - final List beforeEachFns = []; - final List afterEachFns = []; - final List children = []; - - Describe(String name, Describe parent, this.context, Function definition, - {bool excluded, bool exclusive}) - : super(name, parent, - excluded: excluded, - exclusive: exclusive, - pending: definition == null) { - if (definition != null) context.withDescribe(this, definition); - } - - void addBeforeEach(BeforeEach beforeEach) { - beforeEachFns.add(beforeEach); - } - - void addAfterEach(AfterEach afterEach) { - afterEachFns.add(afterEach); - } - - void add(child) { - children.add(child); - } - - String get name => exclusive ? 'DDESCRIBE: ${super.name}' : super.name; - - void visit(SpecVisitor visitor) => visitor.visitDescribe(this); -} - -class Suite extends Describe { - Suite(Context context) : super(null, null, context, () {}); - - void visit(SpecVisitor visitor) => visitor.visitSuite(this); -} diff --git a/lib/src/common/suite_info.dart b/lib/src/common/suite_info.dart deleted file mode 100644 index ca29309..0000000 --- a/lib/src/common/suite_info.dart +++ /dev/null @@ -1,92 +0,0 @@ -part of guinness2; - -_suiteInfo(Suite suite) { - final visitor = new _SuiteInfoVisitor(); - visitor.visitSuite(suite); - return visitor.info; -} - -class SuiteInfo { - final List exclusiveDescribes = []; - final List excludedDescribes = []; - final List pendingDescribes = []; - - final List exclusiveIts = []; - final List excludedIts = []; - final List activeIts = []; - final List pendingIts = []; - - int numberOfIts = 0; - int numberOfDescribes = 0; - - int get numberOfActiveIts => activeIts.length; - bool get hasActiveIts => activeIts.isNotEmpty; - int get activeItsPercent => - numberOfIts > 0 ? (activeIts.length / numberOfIts * 100).toInt() : 0; -} - -class _SuiteInfoVisitor implements SpecVisitor { - final SuiteInfo info = new SuiteInfo(); - - bool containsExclusiveIt; - bool containsExclusiveDescribe; - - void visitSuite(Suite suite) { - final v = new ExclusiveVisitor(); - v.visitSuite(suite); - containsExclusiveIt = v.containsExclusiveIt; - containsExclusiveDescribe = v.containsExclusiveDescribe; - - _visitChildren(suite.children); - } - - void visitDescribe(Describe describe) { - if (describe.excluded) info.excludedDescribes.add(describe); - if (describe.exclusive) info.exclusiveDescribes.add(describe); - if (describe.pending) info.pendingDescribes.add(describe); - - info.numberOfDescribes += 1; - - _visitChildren(describe.children); - } - - void visitIt(It it) { - if (it.excluded) info.excludedIts.add(it); - if (it.exclusive) info.exclusiveIts.add(it); - if (it.pending) info.pendingIts.add(it); - - info.numberOfIts += 1; - - if (_isActive(it)) info.activeIts.add(it); - } - - bool _isActive(it) { - if (it.pending) { - return false; - } else if (containsExclusiveIt) { - return it.exclusive; - } else if (containsExclusiveDescribe) { - return _exclusiveParent(it.parent); - } else { - return _activeParent(it.parent); - } - } - - void _visitChildren(children) { - children.forEach((c) => c.visit(this)); - } - - bool _exclusiveParent(spec) { - if (spec == null) return false; - if (spec.excluded == true) return false; - if (spec.exclusive == true) return true; - return _exclusiveParent(spec.parent); - } - - bool _activeParent(spec) { - if (spec == null) return true; - if (spec.excluded == true) return false; - if (spec.exclusive == true) return true; - return _activeParent(spec.parent); - } -} diff --git a/lib/src/common/syntax.dart b/lib/src/common/syntax.dart index a8cdd58..bc18287 100644 --- a/lib/src/common/syntax.dart +++ b/lib/src/common/syntax.dart @@ -1,28 +1,34 @@ part of guinness2; -void beforeEach(Function fn, {int priority: 0}) => - guinness._context.addBeforeEach(fn, priority: priority); - -void afterEach(Function fn, {int priority: 0}) => - guinness._context.addAfterEach(fn, priority: priority); - -void it(name, [Function fn]) => guinness._context.addIt(name.toString(), fn, - excluded: false, exclusive: false); +void beforeEach(Function fn) => + dartTest.setUp(fn); + +void afterEach(Function fn) => + dartTest.tearDown(fn); + +void it(name, [Function fn]) { + if (fn != null) { + dartTest.test(name, fn); + } else { + dartTest.test(name, () {}, skip: 'skipping emtpy it'); + } +} -void xit(name, [Function fn]) => guinness._context.addIt(name.toString(), fn, - excluded: true, exclusive: false); +void xit(name, [Function fn]) => dartTest.test(name, fn, skip: 'skipping xit'); -void iit(name, [Function fn]) => guinness._context.addIt(name.toString(), fn, - excluded: false, exclusive: true); +void iit(name, [Function fn]) => dartTest.test(name, fn, tags: 'solo'); -void describe(name, [Function fn]) => guinness._context.addDescribe( - name.toString(), fn, excluded: false, exclusive: false); +void describe(name, [Function fn]) { + if (fn != null) { + dartTest.group(name, fn); + } else { + dartTest.group(name, () {}, skip: 'skipping empty describe'); + } +} -void xdescribe(name, [Function fn]) => guinness._context.addDescribe( - name.toString(), fn, excluded: true, exclusive: false); +void xdescribe(name, [Function fn]) => dartTest.group(name, fn, skip: 'skipping xdescribe'); -void ddescribe(name, [Function fn]) => guinness._context.addDescribe( - name.toString(), fn, excluded: false, exclusive: true); +void ddescribe(name, [Function fn]) => dartTest.group(name, fn, tags: 'solo'); Expect expect(actual, [matcher]) { final expect = new Expect(actual); diff --git a/lib/src/common/test_backend.dart b/lib/src/common/test_backend.dart index b93160a..9ad3a44 100644 --- a/lib/src/common/test_backend.dart +++ b/lib/src/common/test_backend.dart @@ -1,81 +1,5 @@ part of guinness2; -class TestAdapter { - const TestAdapter(); - void group(String name, Function fn) => dartTest.group(name, fn); - void test(String name, Function fn) => dartTest.test(name, fn); -} - -class TestVisitor implements SpecVisitor { - bool containsExclusiveIt = false; - bool containsExclusiveDescribe = false; - Set initializedSpecs; - dynamic dartTest; - - TestVisitor(this.initializedSpecs, {this.dartTest: const TestAdapter()}); - - void visitSuite(Suite suite) { - final v = new ExclusiveVisitor(); - v.visitSuite(suite); - // v now has containsExclusiveIt and containsExclusiveDescibe properties for the whole suite - - containsExclusiveIt = v.containsExclusiveIt; - - // If there is an exclusive it, ignore exclusive describes. - containsExclusiveDescribe = !containsExclusiveIt && v.containsExclusiveDescribe; - - if (containsExclusiveDescribe) { - _visitChildDescribes(suite.children); - } else { - _visitChildren(suite.children); - } - } - - void visitDescribe(Describe describe) { - _once(describe, () { - if (describe.excluded) return; - - // If there exists an exclusive describe, and this isn't it, only look - // at children that are instances of Describe. - if (containsExclusiveDescribe && !describe.exclusive) { - _visitChildDescribes(describe.children); - } - - dartTest.group(describe.name, () { - _visitChildren(describe.children); - }); - }); - } - - void visitIt(It it) { - _once(it, () { - if (it.excluded) return; - - if (containsExclusiveIt && !it.exclusive) return; - - dartTest.test(it.name, it.withSetupAndTeardown); - }); - } - - _visitChildren(children) { - children.forEach((c) => c.visit(this)); - } - - _visitChildDescribes(children) { - children.forEach((c) { - if (c is Describe) { - c.visit(this); - } - }); - } - - _once(spec, Function func) { - if (initializedSpecs.contains(spec)) return; - func(); - initializedSpecs.add(spec); - } -} - class TestMatchers implements Matchers { get config => {}; @@ -349,11 +273,4 @@ class IsInstanceOf extends dartTest.Matcher { description.add('an instance of $_type'); } -Set _initializedSpecs = new Set(); - -void testInitSpecs(Suite suite) { - var r = new TestVisitor(_initializedSpecs); - suite.visit(r); -} - bool get _isDart2js => identical(1, 1.0); diff --git a/pubspec.yaml b/pubspec.yaml index 06a0908..e11ffd4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/juliemr/guinness2 description: A port of the Jasmine testing framework. dependencies: collection: ">=1.4.0 <2.0.0" - test: "^0.12.9" + test: "^0.12.10" dev_dependencies: mockito: "0.11.0" environment: diff --git a/scripts/travis/run_tests.sh b/scripts/travis/run_tests.sh index 09776fa..3e1140e 100755 --- a/scripts/travis/run_tests.sh +++ b/scripts/travis/run_tests.sh @@ -56,7 +56,7 @@ function testAndVerifyOutput { set +e -testAndVerifyOutput "pub run test test_e2e/common -r expanded --no-color" "+7: All tests passed" +testAndVerifyOutput "pub run test test_e2e/common -r expanded --no-color" "+7 ~3: All tests passed" testAndVerifyOutput "pub run test test_e2e/html -r expanded --no-color" "No tests ran" @@ -64,10 +64,10 @@ testAndVerifyOutput "pub run test test_e2e/html -p dartium -r expanded --no-colo # TODO - uncomment when focused tests are working. -# testAndVerifyOutput "pub run test test_e2e/focused -r expanded --no-color" "+1 All tests passed" +testAndVerifyOutput "pub run test test_e2e/focused --tags solo -r expanded --no-color" "+1: All tests passed" -# testAndVerifyOutput "pub run test test_e2e/focused_describe -r expanded --no-color" "+2 All tests passed" +testAndVerifyOutput "pub run test test_e2e/focused_describe --tags solo -r expanded --no-color" "+2: All tests passed" -testAndVerifyOutput "pub run test -p dartium -r expanded --no-color" "+312: All tests passed" +testAndVerifyOutput "pub run test -p dartium -r expanded --no-color" "+75: All tests passed" -testAndVerifyOutput "pub run test example/example.dart -p dartium -r expanded --no-color" "+6: All tests passed" +testAndVerifyOutput "pub run test example/example.dart -p dartium -r expanded --no-color" "+5 ~4: All tests passed" diff --git a/test/common/exclusive_visitor_test.dart b/test/common/exclusive_visitor_test.dart deleted file mode 100644 index 9500e64..0000000 --- a/test/common/exclusive_visitor_test.dart +++ /dev/null @@ -1,65 +0,0 @@ -library guinness2.test.exclusive_visitor_test; - -import 'package:guinness2/guinness2.dart' as guinness2; -import 'package:test/test.dart'; - -import '../test_utils.dart'; - -bool _containsExclusiveIt(suite) { - final v = new guinness2.ExclusiveVisitor(); - v.visitSuite(suite); - return v.containsExclusiveIt; -} - -bool _containsExclusiveDescribe(suite) { - final v = new guinness2.ExclusiveVisitor(); - v.visitSuite(suite); - return v.containsExclusiveDescribe; -} - -void main() { - group("[containsExlclusiveIt]", () { - test("return true when a suite has an iit", () { - final suite = createSuite() - ..add(createDescribe()..add(createIt(exclusive: true))); - - expect(_containsExclusiveIt(suite), isTrue); - }); - - test("ignores iit inside xdescribe", () { - final suite = createSuite() - ..add(createDescribe(excluded: true)..add(createIt(exclusive: true))); - - expect(_containsExclusiveIt(suite), isFalse); - }); - - test("returns false otherwise", () { - final suite = createSuite() - ..add(createDescribe()..add(createIt(exclusive: false))); - - expect(_containsExclusiveIt(suite), isFalse); - }); - }); - - group("[containsExlclusiveDescribe]", () { - test("return true when a suite has an ddescribe", () { - final suite = createSuite()..add(createDescribe(exclusive: true)); - - expect(_containsExclusiveDescribe(suite), isTrue); - }); - - test("ignores ddescribe inside xdescribe", () { - final suite = createSuite() - ..add(createDescribe(excluded: true) - ..add(createDescribe(exclusive: true))); - - expect(_containsExclusiveDescribe(suite), isFalse); - }); - - test("returns false otherwise", () { - final suite = createSuite()..add(createDescribe()); - - expect(_containsExclusiveDescribe(suite), isFalse); - }); - }); -} diff --git a/test/common/integration_test.dart b/test/common/integration_test.dart deleted file mode 100644 index d5836a6..0000000 --- a/test/common/integration_test.dart +++ /dev/null @@ -1,143 +0,0 @@ -library guinness2.test.integration_test; - -import 'dart:async'; - -import 'package:guinness2/guinness2.dart' as guinness2; -import 'package:test/test.dart'; - -class DummyVisitor implements guinness2.SpecVisitor { - List allFutures = []; - - void visitSuite(guinness2.Suite suite) { - suite.children.forEach((c) => c.visit(this)); - } - - void visitDescribe(guinness2.Describe describe) { - describe.children.forEach((c) => c.visit(this)); - } - - void visitIt(guinness2.It it) { - allFutures.add(it.withSetupAndTeardown()); - } - - waitForAll() => Future.wait(allFutures); -} - -main() { - var context; - - void verify(Function fn) { - final visitor = new DummyVisitor(); - context.suite.visit(visitor); - visitor - .waitForAll() - .then(expectAsync((_) => fn())) - .catchError((e) => print(e)); - } - - setUp(() { - context = new guinness2.Context(); - guinness2.guinness.resetContext(context); - }); - - test("runs specs once", () { - var log = []; - - guinness2.describe("outer describe", () { - guinness2.it("outer it", () { - log.add("outer it"); - }); - - guinness2.describe("inner describe", () { - guinness2.it("inner it", () { - log.add("inner it"); - }); - }); - }); - - verify(() { - expect(log, equals(["outer it", "inner it"])); - }); - }); - - test("runs beforeEach and afterEach blocks", () { - var log = []; - - guinness2.describe("outer describe", () { - guinness2.beforeEach(() { - log.add("outer beforeEach"); - }); - - guinness2.afterEach(() { - log.add("outer afterEach"); - }); - - guinness2.describe("inner describe", () { - guinness2.beforeEach(() { - log.add("inner beforeEach"); - }); - - guinness2.afterEach(() { - log.add("inner afterEach"); - }); - - guinness2.it("inner it", () { - log.add("inner it"); - }); - }); - }); - - verify(() { - expect(log, equals([ - "outer beforeEach", - "inner beforeEach", - "inner it", - "inner afterEach", - "outer afterEach" - ])); - }); - }); - - group("when beforeEach, afterEach, and it return futures", () { - test("waits for them to be completed", () { - var log = []; - - futurePrinting(message) => new Future.microtask(() { - log.add(message); - }); - - guinness2.describe("outer describe", () { - guinness2.beforeEach(() => futurePrinting("outer beforeEach")); - guinness2.afterEach(() => futurePrinting("outer afterEach")); - - guinness2.describe("inner describe", () { - guinness2.beforeEach(() => futurePrinting("inner beforeEach")); - guinness2.afterEach(() => futurePrinting("inner afterEach")); - - guinness2.it("inner it", () => futurePrinting("inner it")); - }); - }); - - verify(() { - expect(log, equals([ - "outer beforeEach", - "inner beforeEach", - "inner it", - "inner afterEach", - "outer afterEach" - ])); - }); - }); - }); - - test("pending describes and its", () { - guinness2.describe("pending describe"); - guinness2.xdescribe("pending excluded describe"); - guinness2.ddescribe("pending exclusive describe"); - - guinness2.it("pending it"); - guinness2.xit("pending exlcluded it"); - guinness2.iit("pending exclusive it"); - verify(() {}); - }); -} diff --git a/test/common/model_test.dart b/test/common/model_test.dart deleted file mode 100644 index 329c938..0000000 --- a/test/common/model_test.dart +++ /dev/null @@ -1,177 +0,0 @@ -library guinness2.test.model_test; - -import 'dart:async'; - -import 'package:guinness2/guinness2.dart' as guinness2; -import 'package:test/test.dart'; - -import '../test_utils.dart'; - -void main() { - group("[It]", () { - test("returns all before each functions", () { - final outerBeforeEach = new guinness2.BeforeEach(noop, priority: 0); - final outer = createDescribe()..addBeforeEach(outerBeforeEach); - - final innerBeforeEach = new guinness2.BeforeEach(noop, priority: 0); - final inner = createDescribe(parent: outer) - ..addBeforeEach(innerBeforeEach); - - final it = createIt(parent: inner); - - expect(it.beforeEachFns, equals([outerBeforeEach, innerBeforeEach])); - }); - - test("returns all after each functions", () { - final outerAfterEach = new guinness2.AfterEach(noop, priority: 0); - final outer = createDescribe()..addAfterEach(outerAfterEach); - - final innerAfterEach = new guinness2.AfterEach(noop, priority: 0); - final inner = createDescribe(parent: outer)..addAfterEach(innerAfterEach); - - final it = createIt(parent: inner); - - expect(it.afterEachFns, equals([innerAfterEach, outerAfterEach])); - }); - - test("sorts all beforeEach fns by priority", () { - final beforeEach1 = new guinness2.BeforeEach(noop, priority: 0); - final beforeEach2 = new guinness2.BeforeEach(noop, priority: 1); - - final describe = createDescribe() - ..addBeforeEach(beforeEach1) - ..addBeforeEach(beforeEach2); - - final it = createIt(parent: describe); - - expect(it.beforeEachFns, equals([beforeEach2, beforeEach1])); - }); - - test("sorts all afterEach fns by priority", () { - final afterEach1 = new guinness2.AfterEach(noop, priority: 0); - final afterEach2 = new guinness2.AfterEach(noop, priority: 1); - - final describe = createDescribe() - ..addAfterEach(afterEach1) - ..addAfterEach(afterEach2); - - final it = createIt(parent: describe); - - expect(it.afterEachFns, equals([afterEach2, afterEach1])); - }); - - test("runs async beforeEach callbacks in order", () { - final log = []; - - createBeforeEach(delay, message) { - var func = () => new Future.delayed( - new Duration(milliseconds: delay), () => log.add(message)); - return new guinness2.BeforeEach(func, priority: 1); - } - - final beforeEach1 = createBeforeEach(2, "one"); - final beforeEach2 = createBeforeEach(1, "two"); - - final describe = createDescribe() - ..addBeforeEach(beforeEach1) - ..addBeforeEach(beforeEach2); - - final it = createIt(parent: describe); - - it.withSetupAndTeardown().then(expectAsync((_) { - expect(log, equals(["one", "two"])); - })); - }); - - test("runs async afterEach callbacks in order", () { - final log = []; - - createAfterEach(delay, message) { - var func = () => new Future.delayed( - new Duration(milliseconds: delay), () => log.add(message)); - return new guinness2.AfterEach(func, priority: 1); - } - - final afterEach1 = createAfterEach(2, "one"); - final afterEach2 = createAfterEach(1, "two"); - - final describe = createDescribe() - ..addAfterEach(afterEach1) - ..addAfterEach(afterEach2); - - final it = createIt(parent: describe); - - it.withSetupAndTeardown().then(expectAsync((_) { - expect(log, equals(["one", "two"])); - })); - }); - - test("does not run any callbacks when pending", () { - final log = []; - - final be = new guinness2.BeforeEach(() => log.add("before"), priority: 0); - final ae = new guinness2.AfterEach(() => log.add("after"), priority: 0); - - final describe = createDescribe() - ..addBeforeEach(be) - ..addAfterEach(ae); - - final it = createIt(parent: describe, func: null); - - it.withSetupAndTeardown().then(expectAsync((_) { - expect(log, isEmpty); - })); - }); - - group("[name]", () { - test("indicates that the spec is pending", () { - final it = createIt(name: "name", func: null); - - expect(it.name, equals("PENDING: name")); - }); - }); - - group("[error handling]", () { - test("does not run afterEach callbacks if beforeEach callbacks errored", - () { - final be = new guinness2.BeforeEach(() => throw "BOOM", priority: 1); - - var run = false; - final ae = new guinness2.AfterEach(() => run = true, priority: 1); - - final describe = createDescribe() - ..addBeforeEach(be) - ..addAfterEach(ae); - - final it = createIt(parent: describe); - - it.withSetupAndTeardown().catchError(expectAsync((_) { - expect(run, isFalse); - })); - }); - - test("returns the original error when both it and afterEach throw", () { - final ae = new guinness2.AfterEach(() => throw "after", priority: 1); - final describe = createDescribe()..addAfterEach(ae); - - final it = new guinness2.It("it", describe, () => throw "it"); - - it.withSetupAndTeardown().catchError(expectAsync((err) { - expect(err, equals("it")); - })); - }); - - test("return the error thrown by `afterEach` if `it` returns normally", - () { - final ae = new guinness2.AfterEach(() => throw "after", priority: 1); - final describe = createDescribe()..addAfterEach(ae); - - final it = new guinness2.It("it", describe, noop); - - it.withSetupAndTeardown().catchError(expectAsync((err) { - expect(err, equals("after")); - })); - }); - }); - }); -} diff --git a/test/common/suite_info_test.dart b/test/common/suite_info_test.dart deleted file mode 100644 index 0993078..0000000 --- a/test/common/suite_info_test.dart +++ /dev/null @@ -1,110 +0,0 @@ -library guinness2.test.suit_info_test; - -import 'package:guinness2/guinness2.dart' as guinness2; -import 'package:test/test.dart'; - -import '../test_utils.dart'; - -void main() { - setUp(() { - final context = new guinness2.Context(); - guinness2.guinness.resetContext(context); - }); - - test("describes", () { - guinness2.describe("outer", () { - guinness2.xdescribe("xdescribe", noop); - guinness2.ddescribe("ddescribe", noop); - guinness2.describe("inner describe", noop); - }); - guinness2.describe("pending describe"); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.numberOfDescribes, equals(5)); - expect(suiteInfo.exclusiveDescribes.length, equals(1)); - expect(suiteInfo.excludedDescribes.length, equals(1)); - expect(suiteInfo.pendingDescribes.length, equals(1)); - }); - - test("its", () { - guinness2.it("one", noop); - guinness2.xit("two", noop); - guinness2.iit("three", noop); - guinness2.it("pending it"); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.numberOfIts, equals(4)); - expect(suiteInfo.exclusiveIts.length, equals(1)); - expect(suiteInfo.excludedIts.length, equals(1)); - expect(suiteInfo.pendingIts.length, equals(1)); - }); - - group("[activeIts]", () { - test("ignores its in xdescribe", () { - guinness2.it("one", noop); - - guinness2.xdescribe("xdescribe", () { - guinness2.it("two", noop); - }); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeIts.length, equals(1)); - }); - - test("ignores pending its", () { - guinness2.it("one"); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeIts.length, equals(0)); - }); - - test("counts only its in ddescribes", () { - guinness2.it("one", noop); - - guinness2.ddescribe("ddescribe", () { - guinness2.it("two", noop); - }); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeIts.length, equals(1)); - }); - - test("counts only iits", () { - guinness2.it("one", noop); - - guinness2.describe("describe", () { - guinness2.iit("two", noop); - }); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeIts.length, equals(1)); - }); - - test("ignores iits in xdescribe", () { - guinness2.it("one", noop); - - guinness2.xdescribe("xdescribe", () { - guinness2.iit("two", noop); - guinness2.iit("three", noop); - }); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeIts.length, equals(1)); - }); - - group('[activeItsPercent]', () { - test("is the percent of active tests in the suite", () { - guinness2.it("one", noop); - guinness2.iit("one", noop); - - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeItsPercent, equals(50)); - }); - - test("is zero when not specs", () { - final suiteInfo = guinness2.guinness.suiteInfo(); - expect(suiteInfo.activeItsPercent, equals(0)); - }); - }); - }); -} diff --git a/test/common/syntax_test.dart b/test/common/syntax_test.dart deleted file mode 100644 index 54d16dd..0000000 --- a/test/common/syntax_test.dart +++ /dev/null @@ -1,150 +0,0 @@ -library guinness2.test.syntax_test; - -import 'package:guinness2/guinness2.dart' as guinness2; -import 'package:test/test.dart'; - -void main() { - var context; - - setUp(() { - context = new guinness2.Context(); - guinness2.guinness.resetContext(context); - }); - - group("[describe]", () { - test("adds a describe to the current describe block", () { - guinness2.describe("new describe", () {}); - - final actualDescribe = context.suite.children.first; - - expect(actualDescribe.name, equals("new describe")); - }); - }); - - group("[xdescribe]", () { - test( - "adds a describe to the current describe block with excluded set to true", - () { - guinness2.xdescribe("new xdescribe", () {}); - - final actualDescribe = context.suite.children.first; - - expect(actualDescribe.name, equals("new xdescribe")); - expect(actualDescribe.excluded, isTrue); - }); - }); - - group("[ddescribe]", () { - test( - "adds a describe to the current describe block with exclusive set to true", - () { - guinness2.ddescribe("new ddescribe", () {}); - - final actualDescribe = context.suite.children.first; - - expect(actualDescribe.name, equals("DDESCRIBE: new ddescribe")); - expect(actualDescribe.exclusive, isTrue); - }); - }); - - group("[it]", () { - test("adds an `it` to the current describe block", () { - guinness2.it("new it", () {}); - - final actualIt = context.suite.children.first; - - expect(actualIt.name, equals("new it")); - expect(actualIt.excluded, isFalse); - expect(actualIt.exclusive, isFalse); - }); - }); - - group("[xit]", () { - test("adds an `it` to the current describe block with excluded set to true", - () { - guinness2.xit("new xit", () {}); - - final actualIt = context.suite.children.first; - - expect(actualIt.name, equals("new xit")); - expect(actualIt.excluded, isTrue); - }); - }); - - group("[iit]", () { - test( - "adds an `it` to the current describe block with exclusive set to true", - () { - guinness2.iit("new iit", () {}); - - final actualIt = context.suite.children.first; - - expect(actualIt.name, equals("new iit")); - expect(actualIt.exclusive, isTrue); - }); - }); - - group("[beforeEach]", () { - test("adds a before each fn to the current describe block", () { - guinness2.beforeEach(() {}); - - expect(context.suite.beforeEachFns.length, equals(1)); - expect(context.suite.beforeEachFns[0].priority, equals(0)); - }); - - test("supports different priorities", () { - guinness2.beforeEach(() {}, priority: 2); - - expect(context.suite.beforeEachFns[0].priority, equals(2)); - }); - }); - - group("[afterEach]", () { - test("adds a after each fn to the current describe block", () { - guinness2.afterEach(() {}); - - expect(context.suite.afterEachFns.length, equals(1)); - expect(context.suite.afterEachFns[0].priority, equals(0)); - }); - - test("supports different priorities", () { - guinness2.afterEach(() {}, priority: 2); - - expect(context.suite.afterEachFns[0].priority, equals(2)); - }); - }); - - test("handles nested describes and its", () { - guinness2.describe("outer describe", () { - guinness2.it("outer it", () {}); - guinness2.describe("inner describe", () { - guinness2.it("inner it", () {}); - }); - }); - - expect(context.suite.children.length, equals(1)); - - final outerDescribe = context.suite.children[0]; - expect(outerDescribe.name, equals("outer describe")); - expect(outerDescribe.children[0].name, equals("outer it")); - expect(outerDescribe.children[1].name, equals("inner describe")); - - final innerDescribe = outerDescribe.children[1]; - expect(innerDescribe.children.length, equals(1)); - expect(innerDescribe.children[0].name, equals("inner it")); - }); - - group("[expect]", () { - test("creates an Expect object", () { - final e = guinness2.expect("actual"); - - expect(e.actual, equals("actual")); - }); - - test("executes the given matcher", () { - expect(() { - guinness2.expect(true, isFalse); - }, throws); - }); - }); -} diff --git a/test/common_test.dart b/test/common_test.dart deleted file mode 100644 index 366cbae..0000000 --- a/test/common_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -library guinness2.test.common_tests; - -import 'package:guinness2/guinness2.dart'; -import 'package:test/test.dart'; - -import 'common/exclusive_visitor_test.dart' as exclusive_visitor; -import 'common/integration_test.dart' as integration; -import 'common/model_test.dart' as model; -import 'common/spy_test.dart' as spy; -import 'common/suite_info_test.dart' as suite_info; -import 'common/syntax_test.dart' as syntax; - -void main() { - guinness.autoInit = false; - - group("[ExclusiveVisitor]", exclusive_visitor.main); - group("[integration]", integration.main); - group('[model]', model.main); - spy.main(); - group('[suiteInfo]', suite_info.main); - group('[syntax]', syntax.main); -} diff --git a/test/guinness_test.dart b/test/guinness_test.dart deleted file mode 100644 index c66ebed..0000000 --- a/test/guinness_test.dart +++ /dev/null @@ -1,20 +0,0 @@ -@TestOn('browser') - - -library guinness2_test; - -import 'package:guinness2/guinness2_html.dart'; -import 'dart:html'; - -import 'common_test.dart' as common; -import 'html/html_utils_test.dart' as htmlUtilsTest; -import 'html/test_backend_test.dart' as test_backend; - -void main() { - GuinnessEnableHtmlMatchers(); - guinness.autoInit = false; - - common.main(); - htmlUtilsTest.main(); - test_backend.main(); -} diff --git a/test/html/test_backend_test.dart b/test/html/test_backend_test.dart index 059bb92..f59319c 100644 --- a/test/html/test_backend_test.dart +++ b/test/html/test_backend_test.dart @@ -8,8 +8,6 @@ import 'package:mockito/mockito.dart'; import 'package:guinness2/guinness2_html.dart' as guinness2; import 'package:test/test.dart'; -import '../test_utils.dart'; - assertTrue(Function fn) => expect(fn, returnsNormally); assertFalse(Function fn) => expect(fn, throws); @@ -31,81 +29,6 @@ class MockTest extends Mock { } void main() { - group("[TestVisitor]", () { - var visitor, dartTest; - - setUp(() { - dartTest = new MockTest(); - visitor = new guinness2.TestVisitor(new Set(), dartTest: dartTest); - }); - - tearDown(() { - verifyNoMoreInteractions(dartTest); - }); - - test('handles an empty suite', () { - visitor.visitSuite(createSuite()); - }); - - test('uses group for describe', () { - final suite = createSuite()..add(createDescribe()); - - visitor.visitSuite(suite); - verify(dartTest.group(any, any)); - }); - - test('skips excluded describes', () { - final suite = createSuite()..add(createDescribe(excluded: true)); - - visitor.visitSuite(suite); - }); - - test('uses test for it', () { - final suite = createSuite()..add(createIt()); - - visitor.visitSuite(suite); - verify(dartTest.test(any, any)); - }); - - test('only adds exclusive it', () { - final suite = createSuite()..add(createIt(exclusive: true)) - ..add(createIt()); - - visitor.visitSuite(suite); - verify(dartTest.test(any, any)).called(1); - }); - - test('skips excluded its', () { - final suite = createSuite()..add(createIt(excluded: true)); - - visitor.visitSuite(suite); - }); - - test('runs only exlusive its', () { - final suite = createSuite(); - var exclusiveDescribe = createDescribe(exclusive: true); - var exclusiveIt = createIt(exclusive: true); - var otherIt = createIt(parent: exclusiveDescribe); - suite..add(exclusiveDescribe)..add(exclusiveIt); - - visitor.visitSuite(suite); - verify(dartTest.group(any, any)); - verify(dartTest.test(any, any)); - }); - - test("initializes specs only once", () { - final suite = createSuite() - ..add(createIt()) - ..add(createDescribe()); - - visitor.visitSuite(suite); - - visitor.visitSuite(suite); - verify(dartTest.test(any, any)); - verify(dartTest.group(any, any)); - }); - }); - group("[TestMatchers]", () { final matchers = new guinness2.TestMatchersWithHtml(); diff --git a/test/test_utils.dart b/test/test_utils.dart deleted file mode 100644 index 1eb74fe..0000000 --- a/test/test_utils.dart +++ /dev/null @@ -1,21 +0,0 @@ -library guinness2.test_utils; - -import 'package:guinness2/guinness2.dart' as guinness2; - -final _context = new _DummyContext(); - -noop() {} - -createSuite() => new guinness2.Suite(_context); - -createDescribe({bool exclusive: false, bool excluded: false, parent, - Function func: noop, String name: ""}) => new guinness2.Describe( - name, parent, _context, func, exclusive: exclusive, excluded: excluded); - -createIt({bool exclusive: false, bool excluded: false, parent, - Function func: noop, String name: ""}) => new guinness2.It( - name, parent, func, exclusive: exclusive, excluded: excluded); - -class _DummyContext implements guinness2.Context { - withDescribe(guinness2.Describe describe, Function definition) {} -} diff --git a/test_e2e/common/e2e_test.dart b/test_e2e/common/e2e_test.dart index 6047e0f..3fdadcc 100644 --- a/test_e2e/common/e2e_test.dart +++ b/test_e2e/common/e2e_test.dart @@ -18,4 +18,7 @@ main() { xit('skipped spec should not run', () { expect(1).toEqual(2); }); + + it('test without function should count as skipped'); + describe('describe without function should count as skipped'); } diff --git a/test_e2e/focused/focused_it.dart b/test_e2e/focused/focused_it_test.dart similarity index 100% rename from test_e2e/focused/focused_it.dart rename to test_e2e/focused/focused_it_test.dart