Skip to content

Commit

Permalink
[jest-each]: Add flag to prevent done callback being supplied to desc…
Browse files Browse the repository at this point in the history
…ribe (#6843)

* Add flag to prevent done callback being supplied to describe

* Add changelog entry

* Refactor with thymikee linter ;)
  • Loading branch information
mattphillips authored and SimenB committed Aug 18, 2018
1 parent c5389cb commit 21e35cc
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 116 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

- `[docs]` Add custom toMatchSnapshot matcher docs ([#6837](https://github.com/facebook/jest/pull/6837))

### Fixes

- `[jest-each`] Prevent done callback being supplied to describe ([#6843](https://github.com/facebook/jest/pull/6843))

## 23.5.0

### Features
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-circus/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ test.each = bindEach(test);
test.only.each = bindEach(test.only);
test.skip.each = bindEach(test.skip);

describe.each = bindEach(describe);
describe.only.each = bindEach(describe.only);
describe.skip.each = bindEach(describe.skip);
describe.each = bindEach(describe, false);
describe.only.each = bindEach(describe.only, false);
describe.skip.each = bindEach(describe.skip, false);

module.exports = {
afterAll,
Expand Down
103 changes: 59 additions & 44 deletions packages/jest-each/src/__tests__/array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ const expectFunction = expect.any(Function);
const get = (object, lensPath) =>
lensPath.reduce((acc, key) => acc[key], object);

const getGlobalTestMocks = () => {
const globals = {
describe: jest.fn(),
fdescribe: jest.fn(),
fit: jest.fn(),
it: jest.fn(),
test: jest.fn(),
xdescribe: jest.fn(),
xit: jest.fn(),
xtest: jest.fn(),
};
globals.test.only = jest.fn();
globals.test.skip = jest.fn();
globals.it.only = jest.fn();
globals.it.skip = jest.fn();
globals.describe.only = jest.fn();
globals.describe.skip = jest.fn();
return globals;
};

describe('jest-each', () => {
[
['test'],
Expand All @@ -27,20 +47,6 @@ describe('jest-each', () => {
['describe', 'only'],
].forEach(keyPath => {
describe(`.${keyPath.join('.')}`, () => {
const getGlobalTestMocks = () => {
const globals = {
describe: jest.fn(),
fdescribe: jest.fn(),
fit: jest.fn(),
it: jest.fn(),
test: jest.fn(),
};
globals.test.only = jest.fn();
globals.it.only = jest.fn();
globals.describe.only = jest.fn();
return globals;
};

test('calls global with given title', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([[]]);
Expand Down Expand Up @@ -237,18 +243,6 @@ describe('jest-each', () => {
expect(testCallBack).toHaveBeenCalledWith('joe', 'bloggs');
});

test('calls global with async done when cb function has more args than params of given test row', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([['hello']]);

const testFunction = get(eachObject, keyPath);
testFunction('expected string', (hello, done) => {
expect(hello).toBe('hello');
expect(done).toBe('DONE');
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
});

test('calls global with given timeout', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([['hello']]);
Expand All @@ -265,6 +259,45 @@ describe('jest-each', () => {
});
});

describe('done callback', () => {
test.each([
[['test']],
[['test', 'only']],
[['it']],
[['fit']],
[['it', 'only']],
])(
'calls %O with done when cb function has more args than params of given test row',
keyPath => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([['hello']]);

const testFunction = get(eachObject, keyPath);
testFunction('expected string', (hello, done) => {
expect(hello).toBe('hello');
expect(done).toBe('DONE');
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
},
);

test.each([[['describe']], [['fdescribe']], [['describe', 'only']]])(
'does not call %O with done when test function has more args than params of given test row',
keyPath => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([['hello']]);

const testFunction = get(eachObject, keyPath);
testFunction('expected string', function(hello, done) {
expect(hello).toBe('hello');
expect(arguments.length).toBe(1);
expect(done).toBe(undefined);
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
},
);
});

[
['xtest'],
['test', 'skip'],
Expand All @@ -274,24 +307,6 @@ describe('jest-each', () => {
['describe', 'skip'],
].forEach(keyPath => {
describe(`.${keyPath.join('.')}`, () => {
const getGlobalTestMocks = () => {
const globals = {
describe: {
skip: jest.fn(),
},
it: {
skip: jest.fn(),
},
test: {
skip: jest.fn(),
},
xdescribe: jest.fn(),
xit: jest.fn(),
xtest: jest.fn(),
};
return globals;
};

test('calls global with given title', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)([[]]);
Expand Down
115 changes: 67 additions & 48 deletions packages/jest-each/src/__tests__/template.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ const expectFunction = expect.any(Function);
const get = (object, lensPath) =>
lensPath.reduce((acc, key) => acc[key], object);

const getGlobalTestMocks = () => {
const globals = {
describe: jest.fn(),
fdescribe: jest.fn(),
fit: jest.fn(),
it: jest.fn(),
test: jest.fn(),
xdescribe: jest.fn(),
xit: jest.fn(),
xtest: jest.fn(),
};
globals.test.only = jest.fn();
globals.test.skip = jest.fn();
globals.it.only = jest.fn();
globals.it.skip = jest.fn();
globals.describe.only = jest.fn();
globals.describe.skip = jest.fn();
return globals;
};

describe('jest-each', () => {
[
['test'],
Expand All @@ -26,20 +46,6 @@ describe('jest-each', () => {
['describe', 'only'],
].forEach(keyPath => {
describe(`.${keyPath.join('.')}`, () => {
const getGlobalTestMocks = () => {
const globals = {
describe: jest.fn(),
fdescribe: jest.fn(),
fit: jest.fn(),
it: jest.fn(),
test: jest.fn(),
};
globals.test.only = jest.fn();
globals.it.only = jest.fn();
globals.describe.only = jest.fn();
return globals;
};

test('throws error when there are fewer arguments than headings when given one row', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
Expand Down Expand Up @@ -228,22 +234,6 @@ describe('jest-each', () => {
expect(testCallBack).toHaveBeenCalledWith({a: 1, b: 1, expected: 2});
});

test('calls global with async done when cb function has more than one argument', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
a | b | expected
${0} | ${1} | ${1}
`;
const testFunction = get(eachObject, keyPath);
testFunction('expected string', ({a, b, expected}, done) => {
expect(a).toBe(0);
expect(b).toBe(1);
expect(expected).toBe(1);
expect(done).toBe('DONE');
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
});

test('calls global with given timeout', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
Expand All @@ -263,6 +253,53 @@ describe('jest-each', () => {
});
});

describe('done callback', () => {
test.each([
[['test']],
[['test', 'only']],
[['it']],
[['fit']],
[['it', 'only']],
])(
'calls %O with done when cb function has more args than params of given test row',
keyPath => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
a | b | expected
${0} | ${1} | ${1}
`;
const testFunction = get(eachObject, keyPath);
testFunction('expected string', ({a, b, expected}, done) => {
expect(a).toBe(0);
expect(b).toBe(1);
expect(expected).toBe(1);
expect(done).toBe('DONE');
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
},
);

test.each([[['describe']], [['fdescribe']], [['describe', 'only']]])(
'does not call %O with done when test function has more args than params of given test row',
keyPath => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
a | b | expected
${0} | ${1} | ${1}
`;
const testFunction = get(eachObject, keyPath);
testFunction('expected string', function({a, b, expected}, done) {
expect(a).toBe(0);
expect(b).toBe(1);
expect(expected).toBe(1);
expect(done).toBe(undefined);
expect(arguments.length).toBe(1);
});
get(globalTestMocks, keyPath).mock.calls[0][1]('DONE');
},
);
});

[
['xtest'],
['test', 'skip'],
Expand All @@ -272,24 +309,6 @@ describe('jest-each', () => {
['describe', 'skip'],
].forEach(keyPath => {
describe(`.${keyPath.join('.')}`, () => {
const getGlobalTestMocks = () => {
const globals = {
describe: {
skip: jest.fn(),
},
it: {
skip: jest.fn(),
},
test: {
skip: jest.fn(),
},
xdescribe: jest.fn(),
xit: jest.fn(),
xtest: jest.fn(),
};
return globals;
};

test('calls global with given title', () => {
const globalTestMocks = getGlobalTestMocks();
const eachObject = each.withGlobal(globalTestMocks)`
Expand Down
34 changes: 21 additions & 13 deletions packages/jest-each/src/bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ const SUPPORTED_PLACEHOLDERS = /%[sdifjoOp%]/g;
const PRETTY_PLACEHOLDER = '%p';
const INDEX_PLACEHOLDER = '%#';

export default (cb: Function) => (...args: any) =>
export default (cb: Function, supportsDone: boolean = true) => (...args: any) =>
function eachBind(title: string, test: Function, timeout: number): void {
if (args.length === 1) {
const table: Table = args[0].every(Array.isArray)
? args[0]
: args[0].map(entry => [entry]);
return table.forEach((row, i) =>
cb(arrayFormat(title, i, ...row), applyRestParams(row, test), timeout),
cb(
arrayFormat(title, i, ...row),
applyRestParams(supportsDone, row, test),
timeout,
),
);
}

Expand Down Expand Up @@ -66,7 +70,11 @@ export default (cb: Function) => (...args: any) =>
}

return table.forEach(row =>
cb(interpolate(title, row), applyObjectParams(row, test), timeout),
cb(
interpolate(title, row),
applyObjectParams(supportsDone, row, test),
timeout,
),
);
};

Expand Down Expand Up @@ -107,11 +115,14 @@ const arrayFormat = (title, rowIndex, ...args) => {
);
};

const applyRestParams = (params: Array<any>, test: Function) => {
if (params.length < test.length) return done => test(...params, done);

return () => test(...params);
};
const applyRestParams = (
supportsDone: boolean,
params: Array<any>,
test: Function,
) =>
supportsDone && params.length < test.length
? done => test(...params, done)
: () => test(...params);

const getHeadingKeys = (headings: string): Array<string> =>
headings.replace(/\s/g, '').split('|');
Expand Down Expand Up @@ -144,11 +155,8 @@ const interpolate = (title: string, data: any) =>
.reduce(getMatchingKeyPaths(title), []) // aka flatMap
.reduce(replaceKeyPathWithValue(data), title);

const applyObjectParams = (obj: any, test: Function) => {
if (test.length > 1) return done => test(obj, done);

return () => test(obj);
};
const applyObjectParams = (supportsDone: boolean, obj: any, test: Function) =>
supportsDone && test.length > 1 ? done => test(obj, done) : () => test(obj);

const pluralize = (word: string, count: number) =>
word + (count === 1 ? '' : 's');
Expand Down
10 changes: 5 additions & 5 deletions packages/jest-each/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ const install = (g: GlobalCallbacks, ...args: Array<mixed>) => {
const xtest = bind(g.xtest)(...args);

const describe = (title: string, suite: Function, timeout: number) =>
bind(g.describe)(...args)(title, suite, timeout);
describe.skip = bind(g.describe.skip)(...args);
describe.only = bind(g.describe.only)(...args);
const fdescribe = bind(g.fdescribe)(...args);
const xdescribe = bind(g.xdescribe)(...args);
bind(g.describe, false)(...args)(title, suite, timeout);
describe.skip = bind(g.describe.skip, false)(...args);
describe.only = bind(g.describe.only, false)(...args);
const fdescribe = bind(g.fdescribe, false)(...args);
const xdescribe = bind(g.xdescribe, false)(...args);

return {describe, fdescribe, fit, it, test, xdescribe, xit, xtest};
};
Expand Down
Loading

0 comments on commit 21e35cc

Please sign in to comment.