From 7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 28 May 2017 00:38:50 +0200 Subject: add linting (and some initial fixes) --- node_modules/ava/lib/assert.js | 378 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 node_modules/ava/lib/assert.js (limited to 'node_modules/ava/lib/assert.js') diff --git a/node_modules/ava/lib/assert.js b/node_modules/ava/lib/assert.js new file mode 100644 index 000000000..c16e11a1a --- /dev/null +++ b/node_modules/ava/lib/assert.js @@ -0,0 +1,378 @@ +'use strict'; +const coreAssert = require('core-assert'); +const deepEqual = require('lodash.isequal'); +const observableToPromise = require('observable-to-promise'); +const isObservable = require('is-observable'); +const isPromise = require('is-promise'); +const jestDiff = require('jest-diff'); +const enhanceAssert = require('./enhance-assert'); +const formatAssertError = require('./format-assert-error'); + +class AssertionError extends Error { + constructor(opts) { + super(opts.message || ''); + this.name = 'AssertionError'; + + this.assertion = opts.assertion; + this.fixedSource = opts.fixedSource; + this.improperUsage = opts.improperUsage || false; + this.operator = opts.operator; + this.values = opts.values || []; + + // Reserved for power-assert statements + this.statements = []; + + if (opts.stack) { + this.stack = opts.stack; + } + } +} +exports.AssertionError = AssertionError; + +function getStack() { + const obj = {}; + Error.captureStackTrace(obj, getStack); + return obj.stack; +} + +function wrapAssertions(callbacks) { + const pass = callbacks.pass; + const pending = callbacks.pending; + const fail = callbacks.fail; + + const noop = () => {}; + const makeNoop = () => noop; + const makeRethrow = reason => () => { + throw reason; + }; + + const assertions = { + pass() { + pass(this); + }, + + fail(message) { + fail(this, new AssertionError({ + assertion: 'fail', + message: message || 'Test failed via `t.fail()`' + })); + }, + + is(actual, expected, message) { + if (actual === expected) { + pass(this); + } else { + const diff = formatAssertError.formatDiff(actual, expected); + const values = diff ? [diff] : [ + formatAssertError.formatWithLabel('Actual:', actual), + formatAssertError.formatWithLabel('Must be strictly equal to:', expected) + ]; + + fail(this, new AssertionError({ + assertion: 'is', + message, + operator: '===', + values + })); + } + }, + + not(actual, expected, message) { + if (actual === expected) { + fail(this, new AssertionError({ + assertion: 'not', + message, + operator: '!==', + values: [formatAssertError.formatWithLabel('Value is strictly equal:', actual)] + })); + } else { + pass(this); + } + }, + + deepEqual(actual, expected, message) { + if (deepEqual(actual, expected)) { + pass(this); + } else { + const diff = formatAssertError.formatDiff(actual, expected); + const values = diff ? [diff] : [ + formatAssertError.formatWithLabel('Actual:', actual), + formatAssertError.formatWithLabel('Must be deeply equal to:', expected) + ]; + + fail(this, new AssertionError({ + assertion: 'deepEqual', + message, + values + })); + } + }, + + notDeepEqual(actual, expected, message) { + if (deepEqual(actual, expected)) { + fail(this, new AssertionError({ + assertion: 'notDeepEqual', + message, + values: [formatAssertError.formatWithLabel('Value is deeply equal:', actual)] + })); + } else { + pass(this); + } + }, + + throws(fn, err, message) { + let promise; + if (isPromise(fn)) { + promise = fn; + } else if (isObservable(fn)) { + promise = observableToPromise(fn); + } else if (typeof fn !== 'function') { + fail(this, new AssertionError({ + assertion: 'throws', + improperUsage: true, + message: '`t.throws()` must be called with a function, Promise, or Observable', + values: [formatAssertError.formatWithLabel('Called with:', fn)] + })); + return; + } + + let coreAssertThrowsErrorArg; + if (typeof err === 'string') { + const expectedMessage = err; + coreAssertThrowsErrorArg = error => error.message === expectedMessage; + } else { + // Assume it's a constructor function or regular expression + coreAssertThrowsErrorArg = err; + } + + const test = (fn, stack) => { + let actual; + let threw = false; + try { + coreAssert.throws(() => { + try { + fn(); + } catch (err) { + actual = err; + threw = true; + throw err; + } + }, coreAssertThrowsErrorArg); + return actual; + } catch (err) { + const values = threw ? + [formatAssertError.formatWithLabel('Threw unexpected exception:', actual)] : + null; + + throw new AssertionError({ + assertion: 'throws', + message, + stack, + values + }); + } + }; + + if (promise) { + // Record stack before it gets lost in the promise chain. + const stack = getStack(); + const intermediate = promise.then(makeNoop, makeRethrow).then(fn => test(fn, stack)); + pending(this, intermediate); + // Don't reject the returned promise, even if the assertion fails. + return intermediate.catch(noop); + } + + try { + const retval = test(fn); + pass(this); + return retval; + } catch (err) { + fail(this, err); + } + }, + + notThrows(fn, message) { + let promise; + if (isPromise(fn)) { + promise = fn; + } else if (isObservable(fn)) { + promise = observableToPromise(fn); + } else if (typeof fn !== 'function') { + fail(this, new AssertionError({ + assertion: 'notThrows', + improperUsage: true, + message: '`t.notThrows()` must be called with a function, Promise, or Observable', + values: [formatAssertError.formatWithLabel('Called with:', fn)] + })); + return; + } + + const test = (fn, stack) => { + try { + coreAssert.doesNotThrow(fn); + } catch (err) { + throw new AssertionError({ + assertion: 'notThrows', + message, + stack, + values: [formatAssertError.formatWithLabel('Threw:', err.actual)] + }); + } + }; + + if (promise) { + // Record stack before it gets lost in the promise chain. + const stack = getStack(); + const intermediate = promise.then(noop, reason => test(makeRethrow(reason), stack)); + pending(this, intermediate); + // Don't reject the returned promise, even if the assertion fails. + return intermediate.catch(noop); + } + + try { + test(fn); + pass(this); + } catch (err) { + fail(this, err); + } + }, + + ifError(actual, message) { + if (actual) { + fail(this, new AssertionError({ + assertion: 'ifError', + message, + values: [formatAssertError.formatWithLabel('Error:', actual)] + })); + } else { + pass(this); + } + }, + + snapshot(actual, message) { + const state = this._test.getSnapshotState(); + const result = state.match(this.title, actual); + if (result.pass) { + pass(this); + } else { + const diff = jestDiff(result.expected.trim(), result.actual.trim(), {expand: true}) + // Remove annotation + .split('\n') + .slice(3) + .join('\n'); + fail(this, new AssertionError({ + assertion: 'snapshot', + message: message || 'Did not match snapshot', + values: [{label: 'Difference:', formatted: diff}] + })); + } + } + }; + + const enhancedAssertions = enhanceAssert(pass, fail, { + truthy(actual, message) { + if (!actual) { + throw new AssertionError({ + assertion: 'truthy', + message, + operator: '!!', + values: [formatAssertError.formatWithLabel('Value is not truthy:', actual)] + }); + } + }, + + falsy(actual, message) { + if (actual) { + throw new AssertionError({ + assertion: 'falsy', + message, + operator: '!', + values: [formatAssertError.formatWithLabel('Value is not falsy:', actual)] + }); + } + }, + + true(actual, message) { + if (actual !== true) { + throw new AssertionError({ + assertion: 'true', + message, + values: [formatAssertError.formatWithLabel('Value is not `true`:', actual)] + }); + } + }, + + false(actual, message) { + if (actual !== false) { + throw new AssertionError({ + assertion: 'false', + message, + values: [formatAssertError.formatWithLabel('Value is not `false`:', actual)] + }); + } + }, + + regex(string, regex, message) { + if (typeof string !== 'string') { + throw new AssertionError({ + assertion: 'regex', + improperUsage: true, + message: '`t.regex()` must be called with a string', + values: [formatAssertError.formatWithLabel('Called with:', string)] + }); + } + if (!(regex instanceof RegExp)) { + throw new AssertionError({ + assertion: 'regex', + improperUsage: true, + message: '`t.regex()` must be called with a regular expression', + values: [formatAssertError.formatWithLabel('Called with:', regex)] + }); + } + + if (!regex.test(string)) { + throw new AssertionError({ + assertion: 'regex', + message, + values: [ + formatAssertError.formatWithLabel('Value must match expression:', string), + formatAssertError.formatWithLabel('Regular expression:', regex) + ] + }); + } + }, + + notRegex(string, regex, message) { + if (typeof string !== 'string') { + throw new AssertionError({ + assertion: 'notRegex', + improperUsage: true, + message: '`t.notRegex()` must be called with a string', + values: [formatAssertError.formatWithLabel('Called with:', string)] + }); + } + if (!(regex instanceof RegExp)) { + throw new AssertionError({ + assertion: 'notRegex', + improperUsage: true, + message: '`t.notRegex()` must be called with a regular expression', + values: [formatAssertError.formatWithLabel('Called with:', regex)] + }); + } + + if (regex.test(string)) { + throw new AssertionError({ + assertion: 'notRegex', + message, + values: [ + formatAssertError.formatWithLabel('Value must not match expression:', string), + formatAssertError.formatWithLabel('Regular expression:', regex) + ] + }); + } + } + }); + + return Object.assign(assertions, enhancedAssertions); +} +exports.wrapAssertions = wrapAssertions; -- cgit v1.2.3