diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..9f48cc2 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: 'smartcar', +}; diff --git a/.gitignore b/.gitignore index 7c54e2b..3fa7633 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,52 @@ -node_modules +# System generated files *.log -.nyc_output +*.lnk +.DS_Store +Thumbs.db +ehthumbs.db +Desktop.ini + +# Packages +node_modules +bower_components + +# Testing/Coverage/Lint +out +doc +dist coverage +.dockerignore +.eslintcache +.tern-project +.nyc_output + +# Editors + +## Vscode +.vscode +.settings +tsconfig.json +jsconfig.json + +## Vim +*~ +tags +.netrwhist +Session.vim +[._]s[a-w][a-z] +[._]*.]s[a-w][a-z]] + +## Sublime +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +sftp-config.json +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +bh_unicode_properties.cache +GitHub.sublime-settings diff --git a/.nycrc b/.nycrc new file mode 100644 index 0000000..b9cf161 --- /dev/null +++ b/.nycrc @@ -0,0 +1,15 @@ +{ + "lines": 95, + "all" : true, + "cache": true, + "reporter": [ + "lcov", + "text" + ], + "exclude": [ + "test", + "node_modules" + ], + "check-coverage": true, + "report-dir": ".nyc_output" +} diff --git a/.travis.yml b/.travis.yml index e1486bb..92ec951 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,31 @@ language: - node_js node_js: - - stable + - 'node' + - '6' - '4' +cache: + directories: + - $HOME/.npm + - node_modules + - .eslintcache + +install: + - npm update + - npm prune + +script: + - npm test + - npm run cover + +after_success: + - test $TRAVIS_NODE_VERSION = 6 && bash <(curl -s https://codecov.io/bash) + deploy: on: branch: master - node: stable + node: 6 provider: npm email: hello@smartcar.com api_key: $NPM_API_TOKEN diff --git a/lib/assert.js b/lib/assert.js index 74c0efd..a683d8e 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -33,7 +33,7 @@ assert.pass = function(msg) { }; assert.fail = function(msg) { - msg = msg || 'Test failed via t.fail()'; + msg = msg || 'Test failed via assert.fail()'; test(false, create(false, false, 'fail', msg, assert.fail)); }; @@ -100,7 +100,7 @@ assert.throws = function(fn, err, msg) { } if (typeof fn !== 'function') { // eslint-disable-next-line max-len - throw new TypeError('t.throws must be called with a function, Promise, or Observable'); + throw new TypeError('assert.throws must be called with a function, Promise, or Observable'); } try { @@ -143,7 +143,7 @@ assert.notThrows = function(fn, msg) { } if (typeof fn !== 'function') { // eslint-disable-next-line max-len - throw new TypeError('t.notThrows must be called with a function, Promise, or Observable'); + throw new TypeError('assert.notThrows must be called with a function, Promise, or Observable'); } try { diff --git a/package.json b/package.json index 47d5d62..2e75221 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clutch-assert", - "version": "0.0.4", + "version": "0.0.5", "description": "Combine Ava's assertion API with Power Assert", "main": "index.js", "license": "MIT", @@ -32,8 +32,10 @@ "node": ">=4.0.0" }, "scripts": { - "test": "nyc ava", - "lint": "eslint ." + "test": "ava", + "posttest": "npm run lint -s", + "lint": "eslint . --cache", + "cover": "nyc npm test -s" }, "dependencies": { "empower": "^1.2.1", @@ -44,17 +46,11 @@ "power-assert-formatter": "^1.4.1" }, "devDependencies": { - "ava": "^0.16.0", + "ava": "^0.17.0", "call-signature": "0.0.2", "eslint": "^3.7.1", - "eslint-config-smartcar": "^1.0.0", - "nyc": "^8.3.0", + "eslint-config-smartcar": "^2.0.0", + "nyc": "^10.0.0", "zen-observable": "^0.3.0" - }, - "eslintConfig": { - "extends": "smartcar", - "env": { - "es6": true - } } } diff --git a/readme.md b/readme.md index b2f561d..164e318 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ -# Clutch Assert [![Build Status][ci-image]][ci-url] [![NPM package][npm-image]][npm-url] +# Clutch Assert [![NPM package][npm-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coverage][coverage-image]][coverage-url] + > "The only assert library that truly comes in clutch" ## What is this?! @@ -14,7 +15,7 @@ provides a handy [`.keys`] assertion which can be useful if switching from chai. ## Why/When should I use this? The library can be very helpful when porting an older codebase to use ava for -testing. Using clutch assert will allow you to incrementaly convert all of your +testing. Using clutch assert will allow you to incrementally convert all of your assertions to ava style assertions and then once you're ready to switch just replace the word assert with ava's assertion mixin variable. @@ -136,19 +137,19 @@ const assert = require('clutch-assert').customize({ #### options.assertion -customization options for [empower](https://github.com/power-assert-js/empower) module. +Customization options for [empower](https://github.com/power-assert-js/empower) module. See [empower API documentation](https://github.com/power-assert-js/empower#api) for details. Note that some default values are different from `empower`'s (`modifyMessageOnRethrow: true` and `saveContextOnRethrow: true`). #### options.output -customization options for [power-assert-formatter](https://github.com/power-assert-js/power-assert-formatter) module. +Customization options for [power-assert-formatter](https://github.com/power-assert-js/power-assert-formatter) module. See [power-assert-formatter API documentation](https://github.com/power-assert-js/power-assert-formatter#api) for details. #### default values -customizable properties and their default values are as follows. +Customizable properties and their default values are as follows. ```js const assert = require('clutch-assert').customize({ @@ -157,24 +158,17 @@ const assert = require('clutch-assert').customize({ modifyMessageOnRethrow: true, saveContextOnRethrow: true, patterns: [ - 't.truthy(value, [message])', - 't.falsy(value, [message])', - 't.true(value, [message])', - 't.false(value, [message])', - 't.is(value, expected, [message])', - 't.not(value, expected, [message])', - 't.deepEqual(value, expected, [message])', - 't.notDeepEqual(value, expected, [message])', - 't.regex(contents, regex, [message])', - 't.notRegex(contents, regex, [message])', - 't.keys(object, keys, [message])', - ], - wrapOnlyPatterns: [ - 't.pass([message])', - 't.fail([message])', - 't.throws(fn, [message])', - 't.notThrows(fn, [message])', - 't.ifError(error, [message])', + 'assert.truthy(value, [message])', + 'assert.falsy(value, [message])', + 'assert.true(value, [message])', + 'assert.false(value, [message])', + 'assert.is(value, expected, [message])', + 'assert.not(value, expected, [message])', + 'assert.deepEqual(value, expected, [message])', + 'assert.notDeepEqual(value, expected, [message])', + 'assert.regex(contents, regex, [message])', + 'assert.notRegex(contents, regex, [message])', + 'assert.keys(object, keys, [message])', ], }, output: { @@ -184,10 +178,10 @@ const assert = require('clutch-assert').customize({ circular: '#@Circular#', lineSeparator: '\n', ambiguousEastAsianCharWidth: 2, - widthOf: (Function to calculate width of string. Please see power-assert-formatter's documentation) - stringify: (Function to stringify any target value. Please see power-assert-formatter's documentation) - diff: (Function to create diff string between two strings. Please see power-assert-formatter's documentation) - writerClass: (Constructor Function for output writer class. Please see power-assert-formatter's documentation) + widthOf: "(Function to calculate width of string. Please see power-assert-formatter's documentation)" + stringify: "(Function to stringify any target value. Please see power-assert-formatter's documentation)" + diff: "(Function to create diff string between two strings. Please see power-assert-formatter's documentation)" + writerClass: "(Constructor Function for output writer class. Please see power-assert-formatter's documentation)" renderers: [ './built-in/file', './built-in/assertion', @@ -203,3 +197,6 @@ const assert = require('clutch-assert').customize({ [ci-url]: https://travis-ci.org/smartcar/clutch-assert [ci-image]: https://img.shields.io/travis/smartcar/clutch-assert/master.svg?style=flat-square + +[coverage-url]: https://codecov.io/gh/smartcar/clutch-assert +[coverage-image]: https://img.shields.io/codecov/c/github/smartcar/clutch-assert/master.svg?style=flat-square diff --git a/test/.eslintrc.js b/test/.eslintrc.js index 6bb51c4..c461402 100644 --- a/test/.eslintrc.js +++ b/test/.eslintrc.js @@ -1,8 +1,7 @@ -// Lint settings to support 'import' and 'export' for AVA tests +// Lint settings to support 'async' and 'await' for AVA tests module.exports = { parserOptions: { ecmaVersion: 2017, - sourceType: 'module', }, }; diff --git a/test/test_index.js b/test/index.js similarity index 79% rename from test/test_index.js rename to test/index.js index 7e153d0..7ec371f 100644 --- a/test/test_index.js +++ b/test/index.js @@ -1,8 +1,9 @@ -import test from 'ava'; -import callSignature from 'call-signature'; +'use strict'; -import clutch from '../index'; -import {ENHANCED, NOT_ENHANCED} from '../lib/patterns'; +const test = require('ava'); +const clutch = require('../index'); +const callSignature = require('call-signature'); +const {ENHANCED, NOT_ENHANCED} = require('../lib/patterns'); /** * Helper method for getting function name from patterns @@ -12,7 +13,7 @@ function methodName(signature) { return callSignature.parse(signature).callee.member; } -test('default api', t => { +test('default api', function(t) { const methods = Object.keys(clutch).sort(); const allPatterns = ENHANCED.concat(NOT_ENHANCED).map(methodName) .concat(['default', 'customize']) // add in the default property for modules @@ -21,7 +22,7 @@ test('default api', t => { t.deepEqual(methods, allPatterns); }); -test('customize', t => { +test('customize', function(t) { const assert = clutch.customize({ assertion: { patterns: [], diff --git a/test/test_assert.js b/test/lib/assert.js similarity index 61% rename from test/test_assert.js rename to test/lib/assert.js index b191d27..0d101b1 100644 --- a/test/test_assert.js +++ b/test/lib/assert.js @@ -1,115 +1,117 @@ -import test from 'ava'; -import assert from '../lib/assert'; +'use strict'; -test('.pass()', t => { - t.notThrows(() => { +const test = require('ava'); +const assert = require('../../lib/assert'); + +test('.pass()', function(t) { + t.notThrows(function() { assert.pass(); }); }); -test('.fail()', t => { - t.throws(() => { +test('.fail()', function(t) { + t.throws(function() { assert.fail(); }); }); -test('.truthy()', t => { - t.throws(() => { +test('.truthy()', function(t) { + t.throws(function() { assert.truthy(0); assert.truthy(false); }); - t.notThrows(() => { + t.notThrows(function() { assert.truthy(1); assert.truthy(true); }); }); -test('.falsy()', t => { - t.throws(() => { +test('.falsy()', function(t) { + t.throws(function() { assert.falsy(1); assert.falsy(true); }); - t.notThrows(() => { + t.notThrows(function() { assert.falsy(0); assert.falsy(false); }); }); -test('.true()', t => { - t.throws(() => { +test('.true()', function(t) { + t.throws(function() { assert.true(1); }); - t.throws(() => { + t.throws(function() { assert.true(0); }); - t.throws(() => { + t.throws(function() { assert.true(false); }); - t.throws(() => { + t.throws(function() { assert.true('foo'); }); - t.notThrows(() => { + t.notThrows(function() { assert.true(true); }); }); -test('.false()', t => { - t.throws(() => { +test('.false()', function(t) { + t.throws(function() { assert.false(0); }); - t.throws(() => { + t.throws(function() { assert.false(1); }); - t.throws(() => { + t.throws(function() { assert.false(true); }); - t.throws(() => { + t.throws(function() { assert.false('foo'); }); - t.notThrows(() => { + t.notThrows(function() { assert.false(false); }); }); -test('.is()', t => { - t.notThrows(() => { +test('.is()', function(t) { + t.notThrows(function() { assert.is('foo', 'foo'); }); - t.throws(() => { + t.throws(function() { assert.is('foo', 'bar'); }); }); -test('.not()', t => { - t.notThrows(() => { +test('.not()', function(t) { + t.notThrows(function() { assert.not('foo', 'bar'); }); - t.throws(() => { + t.throws(function() { assert.not('foo', 'foo'); }); }); -test('.deepEqual()', t => { +test('.deepEqual()', function(t) { // Tests starting here are to detect regressions in the underlying libraries // used to test deep object equality - t.throws(() => { + t.throws(function() { assert.deepEqual({a: false}, {a: 0}); }); - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual({ a: 'a', b: 'b', @@ -119,7 +121,7 @@ test('.deepEqual()', t => { }); }); - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual({ a: 'a', b: 'b', @@ -135,19 +137,19 @@ test('.deepEqual()', t => { }); }); - t.throws(() => { + t.throws(function() { assert.deepEqual([1, 2, 3], [1, 2, 3, 4]); }); - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual([1, 2, 3], [1, 2, 3]); }); - t.throws(() => { + t.throws(function() { assert.deepEqual([1, 2, 3], [1, 2, 3, 4]); }); - t.throws(() => { + t.throws(function() { var fnA = function(a) { return a; }; @@ -158,7 +160,7 @@ test('.deepEqual()', t => { assert.deepEqual(fnA, fnB); }); - t.notThrows(() => { + t.notThrows(function() { var x1 = {z: 4}; var y1 = {x: x1}; x1.y = y1; @@ -170,7 +172,7 @@ test('.deepEqual()', t => { assert.deepEqual(x1, x2); }); - t.notThrows(() => { + t.notThrows(function() { function Foo(a) { this.a = a; } @@ -181,7 +183,7 @@ test('.deepEqual()', t => { assert.deepEqual(x, y); }); - t.notThrows(() => { + t.notThrows(function() { function Foo(a) { this.a = a; } @@ -196,7 +198,7 @@ test('.deepEqual()', t => { assert.deepEqual(x, y); }); - t.throws(() => { + t.throws(function() { assert.deepEqual({ a: 'a', b: 'b', @@ -214,123 +216,123 @@ test('.deepEqual()', t => { // Regression test end here - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual({a: 'a'}, {a: 'a'}); }); - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual(['a', 'b'], ['a', 'b']); }); - t.throws(() => { + t.throws(function() { assert.deepEqual({a: 'a'}, {a: 'b'}); }); - t.throws(() => { + t.throws(function() { assert.deepEqual(['a', 'b'], ['a', 'a']); }); - t.throws(() => { + t.throws(function() { assert.deepEqual([['a', 'b'], 'c'], [['a', 'b'], 'd']); }, / 'c' ].*? 'd' ]/); - t.throws(() => { + t.throws(function() { var circular = ['a', 'b']; circular.push(circular); assert.deepEqual([circular, 'c'], [circular, 'd']); }, / 'c' ].*? 'd' ]/); }); -test('.notDeepEqual()', t => { - t.notThrows(() => { +test('.notDeepEqual()', function(t) { + t.notThrows(function() { assert.notDeepEqual({a: 'a'}, {a: 'b'}); }); - t.notThrows(() => { + t.notThrows(function() { assert.notDeepEqual(['a', 'b'], ['c', 'd']); }); - t.throws(() => { + t.throws(function() { assert.notDeepEqual({a: 'a'}, {a: 'a'}); }); - t.throws(() => { + t.throws(function() { assert.notDeepEqual(['a', 'b'], ['a', 'b']); }); }); -test('.keys()', t => { - t.notThrows(() => { +test('.keys()', function(t) { + t.notThrows(function() { assert.keys({}, []); }); - t.notThrows(() => { + t.notThrows(function() { assert.keys({'': 2}, ['']); }); - t.notThrows(() => { + t.notThrows(function() { assert.keys({a: 1}, 'a'); }); - t.notThrows(() => { + t.notThrows(function() { assert.keys({a: 1, b: 2}, ['b', 'a']); }); - t.notThrows(() => { + t.notThrows(function() { assert.keys({a: 1, b: {c: 2}}, ['b', 'a']); }); - t.throws(() => { + t.throws(function() { assert.keys({}, ''); }); - t.throws(() => { + t.throws(function() { assert.keys({a: 1, b: 2}, ['a']); }); - t.throws(() => { + t.throws(function() { assert.keys({a: 1}, ['a', 'b']); }); - t.throws(() => { + t.throws(function() { assert.keys({}, 'a'); }); }); -test('.throws()', t => { - t.throws(() => { // eslint-disable-next-line no-empty-function - assert.throws(() => {}); +test('.throws()', function(t) { + t.throws(function() { // eslint-disable-next-line no-empty-function + assert.throws(function() {}); }); - t.notThrows(() => { - assert.throws(() => { + t.notThrows(function() { + assert.throws(function() { throw new Error('foo'); }); }); }); -test('.throws() - Promises', t => { +test('.throws() - Promises', function(t) { t.notThrows(assert.throws(Promise.reject(new Error('foo')))); t.throws(assert.throws(Promise.resolve())); }); -test('.notThrows() - Promises', t => { +test('.notThrows() - Promises', function(t) { t.notThrows(assert.notThrows(Promise.resolve())); t.throws(assert.notThrows(Promise.reject(new Error('foo')))); }); -test('.throws() returns the thrown error', t => { +test('.throws() returns the thrown error', function(t) { const expected = new Error(); - const actual = assert.throws(() => { + const actual = assert.throws(function() { throw expected; }); t.is(actual, expected); }); -test('.throws() returns the rejection reason of promise', async t => { +test('.throws() returns the rejection reason of promise', async function(t) { const expected = new Error(); const actual = await assert.throws(Promise.reject(expected)); @@ -338,22 +340,22 @@ test('.throws() returns the rejection reason of promise', async t => { t.is(actual, expected); }); -test('.throws(fn, str) checks that error.message === str', t => { - const throwFoo = () => { +test('.throws(fn, str) checks that error.message === str', function(t) { + const throwFoo = function() { throw new Error('foo'); }; const rejectFoo = Promise.reject(new Error('foo')); - t.notThrows(() => assert.throws(throwFoo, 'foo')); - t.throws(() => assert.throws(throwFoo, 'bar')); + t.notThrows(function() { assert.throws(throwFoo, 'foo'); }); + t.throws(function() { assert.throws(throwFoo, 'bar'); }); t.notThrows(assert.throws(rejectFoo, 'foo')); t.throws(assert.throws(rejectFoo, 'bar')); }); -test('.throws should throw if passed a bad value', t => { - const err = t.throws(() => { +test('.throws should throw if passed a bad value', function(t) { + const err = t.throws(function() { assert.throws('not a function'); }); @@ -361,8 +363,8 @@ test('.throws should throw if passed a bad value', t => { t.regex(err.message, /t\.throws must be called with a function, Promise, or Observable/); }); -test('.notThrows should throw if passed a bad value', t => { - const err = t.throws(() => { +test('.notThrows should throw if passed a bad value', function(t) { + const err = t.throws(function() { assert.notThrows('not a function'); }); @@ -370,49 +372,49 @@ test('.notThrows should throw if passed a bad value', t => { t.regex(err.message, /t\.notThrows must be called with a function, Promise, or Observable/); }); -test('.notThrows()', t => { - t.notThrows(() => { // eslint-disable-next-line no-empty-function - assert.notThrows(() => {}); +test('.notThrows()', function(t) { + t.notThrows(function() { // eslint-disable-next-line no-empty-function + assert.notThrows(function() {}); }); - t.throws(() => { - assert.notThrows(() => { + t.throws(function() { + assert.notThrows(function() { throw new Error('foo'); }); }); }); -test('.regex()', t => { - t.notThrows(() => { +test('.regex()', function(t) { + t.notThrows(function() { assert.regex('abc', /^abc$/); }); - t.throws(() => { + t.throws(function() { assert.regex('foo', /^abc$/); }); }); -test('.notRegex()', t => { - t.notThrows(() => { +test('.notRegex()', function(t) { + t.notThrows(function() { assert.notRegex('abc', /def/); }); - t.throws(() => { + t.throws(function() { assert.notRegex('abc', /abc/); }); }); -test('.ifError()', t => { - t.throws(() => { +test('.ifError()', function(t) { + t.throws(function() { assert.ifError(new Error()); }); - t.notThrows(() => { + t.notThrows(function() { assert.ifError(null); }); }); -test('.deepEqual() should not mask RangeError from underlying assert', t => { +test('.deepEqual() should not mask RangeError from assert', function(t) { function Circular() { this.test = this; } @@ -420,11 +422,11 @@ test('.deepEqual() should not mask RangeError from underlying assert', t => { var a = new Circular(); var b = new Circular(); - t.throws(() => { + t.throws(function() { assert.notDeepEqual(a, b); }); - t.notThrows(() => { + t.notThrows(function() { assert.deepEqual(a, b); }); }); diff --git a/test/test_observables.js b/test/lib/observables.js similarity index 51% rename from test/test_observables.js rename to test/lib/observables.js index a972d50..96e1ac8 100644 --- a/test/test_observables.js +++ b/test/lib/observables.js @@ -1,23 +1,21 @@ -import test from 'ava'; -import Observable from 'zen-observable'; +'use strict'; -import assert from '../lib/assert'; - -// Must export Promise to support Observables on 0.10 -global.Promise = Promise; +const test = require('ava'); +const assert = require('../../lib/assert'); +const Observable = require('zen-observable'); function throwingObservable() { return new Observable(function(subscriber) { - setTimeout(() => subscriber.error(new Error('foo')), 0); + setTimeout(function() { subscriber.error(new Error('foo')); }, 0); }); } -test('.throws()', t => { +test('.throws()', function(t) { t.notThrows(assert.throws(throwingObservable())); t.throws(assert.throws(Observable.of(1, 2, 3))); }); -test('.notThrows()', t => { +test('.notThrows()', function(t) { t.notThrows(assert.notThrows(Observable.of(1, 2, 3))); t.throws(assert.notThrows(throwingObservable())); }); diff --git a/test/test_patterns.js b/test/lib/patterns.js similarity index 64% rename from test/test_patterns.js rename to test/lib/patterns.js index a676149..50a2102 100644 --- a/test/test_patterns.js +++ b/test/lib/patterns.js @@ -1,10 +1,11 @@ -import test from 'ava'; -import callSignature from 'call-signature'; +'use strict'; -import assert from '../lib/assert'; -import {ENHANCED, NOT_ENHANCED} from '../lib/patterns'; +const test = require('ava'); +const assert = require('../../lib/assert'); +const callSignature = require('call-signature'); +const {ENHANCED, NOT_ENHANCED} = require('../../lib/patterns'); -test('patterns', t => { +test('patterns', function(t) { // Validates that our power-assert patterns match the API function methodName(signature) {