From 363723fc84f7b8477592e0105aeb331ec9a017af Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 14 Aug 2017 05:01:11 +0200 Subject: node_modules --- node_modules/ava/lib/assert.js | 171 +++++++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 58 deletions(-) (limited to 'node_modules/ava/lib/assert.js') diff --git a/node_modules/ava/lib/assert.js b/node_modules/ava/lib/assert.js index c16e11a1a..a0e9fe82c 100644 --- a/node_modules/ava/lib/assert.js +++ b/node_modules/ava/lib/assert.js @@ -1,12 +1,32 @@ 'use strict'; +const concordance = require('concordance'); 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 concordanceOptions = require('./concordance-options').default; +const concordanceDiffOptions = require('./concordance-options').diff; const enhanceAssert = require('./enhance-assert'); -const formatAssertError = require('./format-assert-error'); +const snapshotManager = require('./snapshot-manager'); + +function formatDescriptorDiff(actualDescriptor, expectedDescriptor, options) { + options = Object.assign({}, options, concordanceDiffOptions); + return { + label: 'Difference:', + formatted: concordance.diffDescriptors(actualDescriptor, expectedDescriptor, options) + }; +} + +function formatDescriptorWithLabel(label, descriptor) { + return { + label, + formatted: concordance.formatDescriptor(descriptor, concordanceOptions) + }; +} + +function formatWithLabel(label, value) { + return formatDescriptorWithLabel(label, concordance.describe(value, concordanceOptions)); +} class AssertionError extends Error { constructor(opts) { @@ -19,6 +39,11 @@ class AssertionError extends Error { this.operator = opts.operator; this.values = opts.values || []; + // Raw expected and actual objects are stored for custom reporters + // (such as wallaby.js), that manage worker processes directly and + // use the values for custom diff views + this.raw = opts.raw; + // Reserved for power-assert statements this.statements = []; @@ -41,7 +66,6 @@ function wrapAssertions(callbacks) { const fail = callbacks.fail; const noop = () => {}; - const makeNoop = () => noop; const makeRethrow = reason => () => { throw reason; }; @@ -59,31 +83,27 @@ function wrapAssertions(callbacks) { }, is(actual, expected, message) { - if (actual === expected) { + if (Object.is(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) - ]; - + const actualDescriptor = concordance.describe(actual, concordanceOptions); + const expectedDescriptor = concordance.describe(expected, concordanceOptions); fail(this, new AssertionError({ assertion: 'is', message, - operator: '===', - values + raw: {actual, expected}, + values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)] })); } }, not(actual, expected, message) { - if (actual === expected) { + if (Object.is(actual, expected)) { fail(this, new AssertionError({ assertion: 'not', message, - operator: '!==', - values: [formatAssertError.formatWithLabel('Value is strictly equal:', actual)] + raw: {actual, expected}, + values: [formatWithLabel('Value is the same as:', actual)] })); } else { pass(this); @@ -91,29 +111,30 @@ function wrapAssertions(callbacks) { }, deepEqual(actual, expected, message) { - if (deepEqual(actual, expected)) { + const result = concordance.compare(actual, expected, concordanceOptions); + if (result.pass) { 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) - ]; - + const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions); + const expectedDescriptor = result.expected || concordance.describe(expected, concordanceOptions); fail(this, new AssertionError({ assertion: 'deepEqual', message, - values + raw: {actual, expected}, + values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)] })); } }, notDeepEqual(actual, expected, message) { - if (deepEqual(actual, expected)) { + const result = concordance.compare(actual, expected, concordanceOptions); + if (result.pass) { + const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions); fail(this, new AssertionError({ assertion: 'notDeepEqual', message, - values: [formatAssertError.formatWithLabel('Value is deeply equal:', actual)] + raw: {actual, expected}, + values: [formatDescriptorWithLabel('Value is deeply equal:', actualDescriptor)] })); } else { pass(this); @@ -131,7 +152,7 @@ function wrapAssertions(callbacks) { assertion: 'throws', improperUsage: true, message: '`t.throws()` must be called with a function, Promise, or Observable', - values: [formatAssertError.formatWithLabel('Called with:', fn)] + values: [formatWithLabel('Called with:', fn)] })); return; } @@ -160,15 +181,13 @@ function wrapAssertions(callbacks) { }, coreAssertThrowsErrorArg); return actual; } catch (err) { - const values = threw ? - [formatAssertError.formatWithLabel('Threw unexpected exception:', actual)] : - null; - throw new AssertionError({ assertion: 'throws', message, stack, - values + values: threw ? + [formatWithLabel('Threw unexpected exception:', actual)] : + null }); } }; @@ -176,7 +195,14 @@ function wrapAssertions(callbacks) { 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)); + const intermediate = promise.then(value => { + throw new AssertionError({ + assertion: 'throws', + message: 'Expected promise to be rejected, but it was resolved instead', + values: [formatWithLabel('Resolved with:', value)] + }); + }, reason => test(makeRethrow(reason), stack)); + pending(this, intermediate); // Don't reject the returned promise, even if the assertion fails. return intermediate.catch(noop); @@ -202,7 +228,7 @@ function wrapAssertions(callbacks) { assertion: 'notThrows', improperUsage: true, message: '`t.notThrows()` must be called with a function, Promise, or Observable', - values: [formatAssertError.formatWithLabel('Called with:', fn)] + values: [formatWithLabel('Called with:', fn)] })); return; } @@ -215,7 +241,7 @@ function wrapAssertions(callbacks) { assertion: 'notThrows', message, stack, - values: [formatAssertError.formatWithLabel('Threw:', err.actual)] + values: [formatWithLabel('Threw:', err.actual)] }); } }; @@ -242,28 +268,57 @@ function wrapAssertions(callbacks) { fail(this, new AssertionError({ assertion: 'ifError', message, - values: [formatAssertError.formatWithLabel('Error:', actual)] + values: [formatWithLabel('Error:', actual)] })); } else { pass(this); } }, - snapshot(actual, message) { - const state = this._test.getSnapshotState(); - const result = state.match(this.title, actual); + snapshot(expected, optionsOrMessage, message) { + const options = {}; + if (typeof optionsOrMessage === 'string') { + message = optionsOrMessage; + } else if (optionsOrMessage) { + options.id = optionsOrMessage.id; + } + options.expected = expected; + options.message = message; + + let result; + try { + result = this._test.compareWithSnapshot(options); + } catch (err) { + if (!(err instanceof snapshotManager.SnapshotError)) { + throw err; + } + + const improperUsage = {name: err.name, snapPath: err.snapPath}; + if (err instanceof snapshotManager.VersionMismatchError) { + improperUsage.snapVersion = err.snapVersion; + improperUsage.expectedVersion = err.expectedVersion; + } + + fail(this, new AssertionError({ + assertion: 'snapshot', + message: message || 'Could not compare snapshot', + improperUsage + })); + return; + } + 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'); + } else if (result.actual) { fail(this, new AssertionError({ assertion: 'snapshot', message: message || 'Did not match snapshot', - values: [{label: 'Difference:', formatted: diff}] + values: [formatDescriptorDiff(result.actual, result.expected, {invert: true})] + })); + } else { + fail(this, new AssertionError({ + assertion: 'snapshot', + message: message || 'No snapshot available, run with --update-snapshots' })); } } @@ -276,7 +331,7 @@ function wrapAssertions(callbacks) { assertion: 'truthy', message, operator: '!!', - values: [formatAssertError.formatWithLabel('Value is not truthy:', actual)] + values: [formatWithLabel('Value is not truthy:', actual)] }); } }, @@ -287,7 +342,7 @@ function wrapAssertions(callbacks) { assertion: 'falsy', message, operator: '!', - values: [formatAssertError.formatWithLabel('Value is not falsy:', actual)] + values: [formatWithLabel('Value is not falsy:', actual)] }); } }, @@ -297,7 +352,7 @@ function wrapAssertions(callbacks) { throw new AssertionError({ assertion: 'true', message, - values: [formatAssertError.formatWithLabel('Value is not `true`:', actual)] + values: [formatWithLabel('Value is not `true`:', actual)] }); } }, @@ -307,7 +362,7 @@ function wrapAssertions(callbacks) { throw new AssertionError({ assertion: 'false', message, - values: [formatAssertError.formatWithLabel('Value is not `false`:', actual)] + values: [formatWithLabel('Value is not `false`:', actual)] }); } }, @@ -318,7 +373,7 @@ function wrapAssertions(callbacks) { assertion: 'regex', improperUsage: true, message: '`t.regex()` must be called with a string', - values: [formatAssertError.formatWithLabel('Called with:', string)] + values: [formatWithLabel('Called with:', string)] }); } if (!(regex instanceof RegExp)) { @@ -326,7 +381,7 @@ function wrapAssertions(callbacks) { assertion: 'regex', improperUsage: true, message: '`t.regex()` must be called with a regular expression', - values: [formatAssertError.formatWithLabel('Called with:', regex)] + values: [formatWithLabel('Called with:', regex)] }); } @@ -335,8 +390,8 @@ function wrapAssertions(callbacks) { assertion: 'regex', message, values: [ - formatAssertError.formatWithLabel('Value must match expression:', string), - formatAssertError.formatWithLabel('Regular expression:', regex) + formatWithLabel('Value must match expression:', string), + formatWithLabel('Regular expression:', regex) ] }); } @@ -348,7 +403,7 @@ function wrapAssertions(callbacks) { assertion: 'notRegex', improperUsage: true, message: '`t.notRegex()` must be called with a string', - values: [formatAssertError.formatWithLabel('Called with:', string)] + values: [formatWithLabel('Called with:', string)] }); } if (!(regex instanceof RegExp)) { @@ -356,7 +411,7 @@ function wrapAssertions(callbacks) { assertion: 'notRegex', improperUsage: true, message: '`t.notRegex()` must be called with a regular expression', - values: [formatAssertError.formatWithLabel('Called with:', regex)] + values: [formatWithLabel('Called with:', regex)] }); } @@ -365,8 +420,8 @@ function wrapAssertions(callbacks) { assertion: 'notRegex', message, values: [ - formatAssertError.formatWithLabel('Value must not match expression:', string), - formatAssertError.formatWithLabel('Regular expression:', regex) + formatWithLabel('Value must not match expression:', string), + formatWithLabel('Regular expression:', regex) ] }); } -- cgit v1.2.3