Skip to content
Permalink
Browse files
Use babel-generator to regenerate enhanced assertion statements
Fixes #1513.
  • Loading branch information
codeslikejaggars authored and novemberborn committed Oct 26, 2017
1 parent 3b81e2c commit 37e8b49af78dc72bbf6a4ff674650cd57f48ea58
Showing 5 changed files with 95 additions and 25 deletions.
@@ -1,6 +1,7 @@
'use strict';
const concordance = require('concordance');
const dotProp = require('dot-prop');
const generate = require('babel-generator').default;
const concordanceOptions = require('./concordance-options').default;

// When adding patterns, don't forget to add to
@@ -15,31 +16,16 @@ const PATTERNS = [
't.notRegex(contents, regex, [message])'
];

const isRangeMatch = (a, b) => {
return (a[0] === b[0] && a[1] === b[1]) ||
(a[0] > b[0] && a[0] < b[1]) ||
(a[1] > b[0] && a[1] < b[1]);
};

const computeStatement = (tokens, range) => {
return tokens
.filter(token => isRangeMatch(token.range, range))
.map(token => token.value === undefined ? token.type.label : token.value)
.join('');
};

const computeStatement = node => generate(node, {quotes: 'single'}).code;
const getNode = (ast, path) => dotProp.get(ast, path.replace(/\//g, '.'));

const formatter = context => {
const ast = JSON.parse(context.source.ast);
const tokens = JSON.parse(context.source.tokens);
const args = context.args[0].events;

return args
.map(arg => {
const range = getNode(ast, arg.espath).range;
const statement = computeStatement(tokens, range);

const node = getNode(ast, arg.espath);
const statement = computeStatement(node);
const formatted = concordance.format(arg.value, concordanceOptions);
return [statement, formatted];
})

Some generated files are not rendered by default. Learn more.

@@ -107,6 +107,7 @@
"auto-bind": "^1.1.0",
"ava-init": "^0.2.0",
"babel-core": "^6.17.0",
"babel-generator": "^6.26.0",
"bluebird": "^3.0.0",
"caching-transform": "^1.0.0",
"chalk": "^2.0.1",
@@ -371,6 +371,43 @@ function generateTests(prefix, apiCreator) {
});
});

test(`${prefix} enhanced assertion formatting necessary whitespace and empty strings`, t => {
const expected = [
[
/foo === '' && '' === foo/,
/foo === ''/,
/foo/
],
[
/new Object\(foo\) instanceof Object/,
/Object/,
/new Object\(foo\)/,
/foo/
],
[
/\[foo].filter\(item => {\n\s+return item === 'bar';\n}\).length > 0/,
/\[foo].filter\(item => {\n\s+return item === 'bar';\n}\).length/,
/\[foo].filter\(item => {\n\s+return item === 'bar';\n}\)/,
/\[foo]/,
/foo/
]
];

t.plan(14);
const api = apiCreator();
return api.run([path.join(__dirname, 'fixture/enhanced-assertion-formatting.js')])
.then(result => {
t.is(result.errors.length, 3);
t.is(result.passCount, 0);

result.errors.forEach((error, errorIndex) => {
error.error.statements.forEach((statement, statementIndex) => {
t.match(statement[0], expected[errorIndex][statementIndex]);
});
});
});
});

test(`${prefix} stack traces for exceptions are corrected using a source map file (cache off)`, t => {
t.plan(4);

@@ -0,0 +1,21 @@
import test from '../..';

const foo = 'foo';

test('fails with multiple empty string expressions and mixed quotes', t => {
// eslint-disable-next-line quotes, yoda
t.true(foo === '' && "" === foo);
});

test('fails with "instanceof" expression', t => {
// eslint-disable-next-line no-new-object
t.false(new Object(foo) instanceof Object);
});

test('fails with multiple lines', t => {
t.true(
[foo].filter(item => {
return item === 'bar';
}).length > 0
);
});

0 comments on commit 37e8b49

Please sign in to comment.