From be404d4d5218eb5291cfa03eaa91762624b3b85a Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Sun, 5 Feb 2017 15:52:39 -0800 Subject: [PATCH] Add flow type tests Closes #1224 This adds flow-bin, adds it to the test running script, and adds some regression tests based on prior issues. In an immediate proof of value (and proof of my own prior sloppiness) it spotted an issue that #1219 sought to fix and did not do so. Fix included along with test. --- .flowconfig | 7 ++++ index.js.flow | 4 +- package.json | 3 +- test/flow-types/regression-1114.js.flow | 53 +++++++++++++++++++++++++ test/flow-types/regression-1148.js.flow | 19 +++++++++ 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 .flowconfig create mode 100644 test/flow-types/regression-1114.js.flow create mode 100644 test/flow-types/regression-1148.js.flow diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 000000000..d0c7084f7 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,7 @@ +[ignore] +/node_modules/.* +/.*\.js$ + +[options] +emoji=true +suppress_comment=\\(.\\|\n\\)*\\$ExpectError diff --git a/index.js.flow b/index.js.flow index 54367a94e..2aed4c128 100644 --- a/index.js.flow +++ b/index.js.flow @@ -63,8 +63,8 @@ type AssertContext = { }; // Assert that function doesn't throw an error or promise resolves. notThrows: { - notThrows(value: PromiseLike, message?: string): Promise; - notThrows(value: () => mixed, message?: string): void; + (value: PromiseLike, message?: string): Promise; + (value: () => mixed, message?: string): void; }; // Assert that contents matches regex. regex(contents: string, regex: RegExp, message?: string): void; diff --git a/package.json b/package.json index 8fc440215..4ec1a36f5 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "node": ">=4" }, "scripts": { - "test": "xo && nyc tap --no-cov --timeout=150 --jobs=4 test/*.js test/reporters/*.js", + "test": "xo && flow check && nyc tap --no-cov --timeout=150 --jobs=4 test/*.js test/reporters/*.js", "test-win": "tap --no-cov --reporter=classic --timeout=150 --jobs=4 test/*.js test/reporters/*.js", "visual": "node test/visual/run-visual-tests.js", "prepublish": "npm run make-ts", @@ -167,6 +167,7 @@ "coveralls": "^2.11.4", "delay": "^1.3.0", "execa": "^0.6.0", + "flow-bin": "^0.38.0", "get-stream": "^3.0.0", "git-branch": "^0.3.0", "has-ansi": "^2.0.0", diff --git a/test/flow-types/regression-1114.js.flow b/test/flow-types/regression-1114.js.flow new file mode 100644 index 000000000..60101316d --- /dev/null +++ b/test/flow-types/regression-1114.js.flow @@ -0,0 +1,53 @@ +/* @flow */ + +const test = require('../../'); + +test('Named test', t => { + t.pass('Success'); + // $ExpectError: Unknown method "unknownAssertion" + t.unknownAssertion('Whoops'); + const context = t.context; + // $ExpectError: Unknown method "end" + t.end(); +}); + +test(t => { + t.pass('Success'); + // $ExpectError: Unknown method "unknownAssertion" + t.unknownAssertion('Whoops'); + const context = t.context; + // $ExpectError: Unknown method "end" + t.end(); +}); + +test.cb(t => { + t.pass('Success'); + t.end(); +}); + +test.beforeEach(t => { + // $ExpectError: Unknown property "context" + const context = t.context; +}) + +function macro(t, input, expected) { + t.is(eval(input), expected); +} +macro.title = (title, input, expected) => title || input; + +function macro2(t, input, expected) { + t.is(eval(input), expected); +} + +test('2 + 2 === 4', macro, '2 + 2', 4); +test(macro, '2 * 3', 6); + +test('2 + 2 === 4', [macro, macro2], '2 + 2', 4); +test([macro, macro2], '2 * 3', 6); + +function macroBadTitle(t, input, expected) { + t.is(eval(input), expected); +} +macroBadTitle.title = 'Not a function'; +// $ExpectError: Macro "title" is not a function +test('2 + 2 === 4', macroBadTitle, '2 + 2', 4); diff --git a/test/flow-types/regression-1148.js.flow b/test/flow-types/regression-1148.js.flow new file mode 100644 index 000000000..feb279f8e --- /dev/null +++ b/test/flow-types/regression-1148.js.flow @@ -0,0 +1,19 @@ +/* @flow */ + +const test = require('../../'); + +test(t => { + t.throws(() => { throw new Error(); }); + t.throws(Promise.reject(new Error())); + + t.notThrows(() => { return; }); + t.notThrows(Promise.resolve('Success')); + + const error = t.throws(() => { throw new Error(); }); + const message: string = error.message; + + const promise = t.throws(Promise.reject(new Error())); + promise.then(error => { + const message: string = error.message; + }) +});