diff --git a/packages/jest-editor-support/package.json b/packages/jest-editor-support/package.json index 6ef6f37f4153..d4a84ba28f97 100644 --- a/packages/jest-editor-support/package.json +++ b/packages/jest-editor-support/package.json @@ -8,7 +8,9 @@ "license": "BSD-3-Clause", "main": "build/index.js", "dependencies": { - "babylon": "^6.14.1" + "babylon": "^6.14.1", + "babel-traverse": "^6.14.1", + "jest-snapshot": "^19.0.2" }, "typings": "index.d.ts" } diff --git a/packages/jest-editor-support/src/Snapshot.js b/packages/jest-editor-support/src/Snapshot.js new file mode 100644 index 000000000000..825ea8d1b894 --- /dev/null +++ b/packages/jest-editor-support/src/Snapshot.js @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + */ + +'use strict'; + +const traverse = require('babel-traverse').default; +const {getASTfor} = require('./parsers/BabylonParser'); +const {utils} = require('jest-snapshot'); + +type Node = any; + +type SnapshotMetadata = { + exists: true | false, + name: string, + node: Node, + content?: string, +}; + +const describeVariants = Object.assign( + (Object.create(null): {[string]: boolean}), + { + describe: true, + fdescribe: true, + xdescribe: true, + }, +); +const base = Object.assign((Object.create(null): {[string]: boolean}), { + describe: true, + it: true, + test: true, +}); +const decorators = Object.assign((Object.create(null): {[string]: boolean}), { + only: true, + skip: true, +}); + +const validParents = Object.assign( + (Object.create(null): any), + base, + describeVariants, + Object.assign((Object.create(null): {[string]: boolean}), { + fit: true, + xit: true, + xtest: true, + }), +); + +const isValidMemberExpression = node => + node.object && + base[node.object.name] && + node.property && + decorators[node.property.name]; + +const isDescribe = node => + describeVariants[node.name] || + (isValidMemberExpression(node) && node.object.name === 'describe'); + +const isValidParent = parent => + parent.callee && + (validParents[parent.callee.name] || isValidMemberExpression(parent.callee)); + +const getArrayOfParents = path => { + const result = []; + let parent = path.parentPath; + while (parent) { + result.unshift(parent.node); + parent = parent.parentPath; + } + return result; +}; + +const buildName: ( + snapshotNode: Node, + parents: Array, + position: number, +) => string = (snapshotNode, parents, position) => { + const fullName = parents.map(parent => parent.arguments[0].value).join(' '); + + let describeLess = ''; + if (!isDescribe(parents[0].callee)) { + // If `it` or `test` exists without a surrounding `describe` + // then `test ` is prepended to the snapshot fullName. + describeLess = 'test '; + } + + return utils.testNameToKey(describeLess + fullName, position); +}; + +module.exports = class Snapshot { + _parser: Function; + _matchers: Array; + constructor(parser: any, customMatchers?: Array) { + this._parser = parser || getASTfor; + this._matchers = ['toMatchSnapshot', 'toThrowErrorMatchingSnapshot'].concat( + customMatchers || [], + ); + } + + getMetadata(filePath: string): Array { + const fileNode = this._parser(filePath); + const state = { + found: [], + }; + const Visitors = { + Identifier(path, state, matchers) { + if (matchers.includes(path.node.name)) { + state.found.push({node: path.node, parents: getArrayOfParents(path)}); + } + }, + }; + + traverse(fileNode, { + enter: path => { + const visitor = Visitors[path.node.type]; + if (visitor != null) { + visitor(path, state, this._matchers); + } + }, + }); + + const snapshotPath = utils.getSnapshotPath(filePath); + const snapshots = utils.getSnapshotData(snapshotPath, false).data; + let lastParent = null; + let count = 1; + + return state.found.map((snapshotNode, index) => { + const parents = snapshotNode.parents.filter(isValidParent); + const innerAssertion = parents[parents.length - 1]; + + if (lastParent !== innerAssertion) { + lastParent = innerAssertion; + count = 1; + } + + const result = { + content: undefined, + count: count++, + exists: false, + name: '', + node: snapshotNode.node, + }; + + if (!innerAssertion || isDescribe(innerAssertion.callee)) { + // An expectation inside describe never gets executed. + return result; + } + + result.name = buildName(snapshotNode, parents, result.count); + + if (snapshots[result.name]) { + result.exists = true; + result.content = snapshots[result.name]; + } + return result; + }); + } +}; diff --git a/packages/jest-editor-support/src/__tests__/Snapshot-test.js b/packages/jest-editor-support/src/__tests__/Snapshot-test.js new file mode 100644 index 000000000000..dcb71e21d0f5 --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/Snapshot-test.js @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +const path = require('path'); +const Snapshot = require('../Snapshot'); +const snapshotHelper = new Snapshot(); +const snapshotFixturePath = path.resolve(__dirname, 'fixtures/snapshots'); + +test('nodescribe.example', () => { + const filePath = path.join(snapshotFixturePath, 'nodescribe.example'); + const results = snapshotHelper.getMetadata(filePath); + const allAssertion = [ + 'fit', + 'it', + 'it.only', + 'it.skip', + 'test', + 'test.only', + 'test.skip', + 'xit', + 'xtest', + ]; + + const expectations = Object.create(null); + allAssertion.forEach(assertion => { + expectations['test ' + assertion + ' 1'] = { + assertion, + checked: false, + number: 1, + }; + expectations['test ' + assertion + ' 2'] = { + assertion, + checked: false, + number: 2, + }; + }); + + results.forEach(result => { + const check = expectations[result.name]; + check.checked = result.content === `${check.assertion} ${check.number}`; + }); + + expect( + Object.keys(expectations) + .map(key => expectations[key]) + .filter(expectation => !expectation.checked).length, + ).toBe(0); +}); + +test('describe.example', () => { + const filePath = path.join(snapshotFixturePath, 'describe.example'); + const results = snapshotHelper.getMetadata(filePath); + const allDescribe = [ + 'describe', + 'describe.only', + 'describe.skip', + 'fdescribe', + 'xdescribe', + ]; + const allAssertion = [ + 'fit', + 'it', + 'it.only', + 'it.skip', + 'test', + 'test.only', + 'test.skip', + 'xit', + 'xtest', + ]; + + const expectations = Object.create(null); + + allDescribe.forEach(describe => { + allAssertion.forEach(assertion => { + expectations[describe.toUpperCase() + ' ' + assertion + ' 1'] = { + assertion, + checked: false, + describe, + number: 1, + }; + + expectations[describe.toUpperCase() + ' ' + assertion + ' 2'] = { + assertion, + checked: false, + describe, + number: 2, + }; + }); + }); + + results.forEach(result => { + const check = expectations[result.name]; + check.checked = result.content === + `${check.number} ${check.assertion} ${check.describe}`; + }); + expect( + Object.keys(expectations) + .map(key => expectations[key]) + .filter(expectation => !expectation.checked).length, + ).toBe(0); +}); + +test('nested.example', () => { + const filePath = path.join(snapshotFixturePath, 'nested.example'); + const results = snapshotHelper.getMetadata(filePath); + expect(results[0].content).toBe('first nested'); + expect(results[1].content).toBe('second nested'); + + expect(results[0].name).toBe( + 'outer describe outer it inner describe inner it 1', + ); + expect(results[1].name).toBe( + 'outer describe outer it inner describe inner it 2', + ); + + expect(results[0].node.loc.start).toEqual({column: 21, line: 5}); + expect(results[0].node.loc.end).toEqual({column: 36, line: 5}); + expect(results[1].node.loc.start).toEqual({column: 21, line: 6}); + expect(results[1].node.loc.end).toEqual({column: 36, line: 6}); +}); diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/describe.example.snap b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/describe.example.snap new file mode 100644 index 000000000000..d60e6dc0998d --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/describe.example.snap @@ -0,0 +1,91 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`DESCRIBE fit 1`] = `1 fit describe`; +exports[`DESCRIBE fit 2`] = `2 fit describe`; +exports[`DESCRIBE it 1`] = `1 it describe`; +exports[`DESCRIBE it 2`] = `2 it describe`; +exports[`DESCRIBE it.only 1`] = `1 it.only describe`; +exports[`DESCRIBE it.only 2`] = `2 it.only describe`; +exports[`DESCRIBE it.skip 1`] = `1 it.skip describe`; +exports[`DESCRIBE it.skip 2`] = `2 it.skip describe`; +exports[`DESCRIBE test 1`] = `1 test describe`; +exports[`DESCRIBE test 2`] = `2 test describe`; +exports[`DESCRIBE test.only 1`] = `1 test.only describe`; +exports[`DESCRIBE test.only 2`] = `2 test.only describe`; +exports[`DESCRIBE test.skip 1`] = `1 test.skip describe`; +exports[`DESCRIBE test.skip 2`] = `2 test.skip describe`; +exports[`DESCRIBE xit 1`] = `1 xit describe`; +exports[`DESCRIBE xit 2`] = `2 xit describe`; +exports[`DESCRIBE xtest 1`] = `1 xtest describe`; +exports[`DESCRIBE xtest 2`] = `2 xtest describe`; +exports[`DESCRIBE.ONLY fit 1`] = `1 fit describe.only`; +exports[`DESCRIBE.ONLY fit 2`] = `2 fit describe.only`; +exports[`DESCRIBE.ONLY it 1`] = `1 it describe.only`; +exports[`DESCRIBE.ONLY it 2`] = `2 it describe.only`; +exports[`DESCRIBE.ONLY it.only 1`] = `1 it.only describe.only`; +exports[`DESCRIBE.ONLY it.only 2`] = `2 it.only describe.only`; +exports[`DESCRIBE.ONLY it.skip 1`] = `1 it.skip describe.only`; +exports[`DESCRIBE.ONLY it.skip 2`] = `2 it.skip describe.only`; +exports[`DESCRIBE.ONLY test 1`] = `1 test describe.only`; +exports[`DESCRIBE.ONLY test 2`] = `2 test describe.only`; +exports[`DESCRIBE.ONLY test.only 1`] = `1 test.only describe.only`; +exports[`DESCRIBE.ONLY test.only 2`] = `2 test.only describe.only`; +exports[`DESCRIBE.ONLY test.skip 1`] = `1 test.skip describe.only`; +exports[`DESCRIBE.ONLY test.skip 2`] = `2 test.skip describe.only`; +exports[`DESCRIBE.ONLY xit 1`] = `1 xit describe.only`; +exports[`DESCRIBE.ONLY xit 2`] = `2 xit describe.only`; +exports[`DESCRIBE.ONLY xtest 1`] = `1 xtest describe.only`; +exports[`DESCRIBE.ONLY xtest 2`] = `2 xtest describe.only`; +exports[`DESCRIBE.SKIP fit 1`] = `1 fit describe.skip`; +exports[`DESCRIBE.SKIP fit 2`] = `2 fit describe.skip`; +exports[`DESCRIBE.SKIP it 1`] = `1 it describe.skip`; +exports[`DESCRIBE.SKIP it 2`] = `2 it describe.skip`; +exports[`DESCRIBE.SKIP it.only 1`] = `1 it.only describe.skip`; +exports[`DESCRIBE.SKIP it.only 2`] = `2 it.only describe.skip`; +exports[`DESCRIBE.SKIP it.skip 1`] = `1 it.skip describe.skip`; +exports[`DESCRIBE.SKIP it.skip 2`] = `2 it.skip describe.skip`; +exports[`DESCRIBE.SKIP test 1`] = `1 test describe.skip`; +exports[`DESCRIBE.SKIP test 2`] = `2 test describe.skip`; +exports[`DESCRIBE.SKIP test.only 1`] = `1 test.only describe.skip`; +exports[`DESCRIBE.SKIP test.only 2`] = `2 test.only describe.skip`; +exports[`DESCRIBE.SKIP test.skip 1`] = `1 test.skip describe.skip`; +exports[`DESCRIBE.SKIP test.skip 2`] = `2 test.skip describe.skip`; +exports[`DESCRIBE.SKIP xit 1`] = `1 xit describe.skip`; +exports[`DESCRIBE.SKIP xit 2`] = `2 xit describe.skip`; +exports[`DESCRIBE.SKIP xtest 1`] = `1 xtest describe.skip`; +exports[`DESCRIBE.SKIP xtest 2`] = `2 xtest describe.skip`; +exports[`FDESCRIBE fit 1`] = `1 fit fdescribe`; +exports[`FDESCRIBE fit 2`] = `2 fit fdescribe`; +exports[`FDESCRIBE it 1`] = `1 it fdescribe`; +exports[`FDESCRIBE it 2`] = `2 it fdescribe`; +exports[`FDESCRIBE it.only 1`] = `1 it.only fdescribe`; +exports[`FDESCRIBE it.only 2`] = `2 it.only fdescribe`; +exports[`FDESCRIBE it.skip 1`] = `1 it.skip fdescribe`; +exports[`FDESCRIBE it.skip 2`] = `2 it.skip fdescribe`; +exports[`FDESCRIBE test 1`] = `1 test fdescribe`; +exports[`FDESCRIBE test 2`] = `2 test fdescribe`; +exports[`FDESCRIBE test.only 1`] = `1 test.only fdescribe`; +exports[`FDESCRIBE test.only 2`] = `2 test.only fdescribe`; +exports[`FDESCRIBE test.skip 1`] = `1 test.skip fdescribe`; +exports[`FDESCRIBE test.skip 2`] = `2 test.skip fdescribe`; +exports[`FDESCRIBE xit 1`] = `1 xit fdescribe`; +exports[`FDESCRIBE xit 2`] = `2 xit fdescribe`; +exports[`FDESCRIBE xtest 1`] = `1 xtest fdescribe`; +exports[`FDESCRIBE xtest 2`] = `2 xtest fdescribe`; +exports[`XDESCRIBE fit 1`] = `1 fit xdescribe`; +exports[`XDESCRIBE fit 2`] = `2 fit xdescribe`; +exports[`XDESCRIBE it 1`] = `1 it xdescribe`; +exports[`XDESCRIBE it 2`] = `2 it xdescribe`; +exports[`XDESCRIBE it.only 1`] = `1 it.only xdescribe`; +exports[`XDESCRIBE it.only 2`] = `2 it.only xdescribe`; +exports[`XDESCRIBE it.skip 1`] = `1 it.skip xdescribe`; +exports[`XDESCRIBE it.skip 2`] = `2 it.skip xdescribe`; +exports[`XDESCRIBE test 1`] = `1 test xdescribe`; +exports[`XDESCRIBE test 2`] = `2 test xdescribe`; +exports[`XDESCRIBE test.only 1`] = `1 test.only xdescribe`; +exports[`XDESCRIBE test.only 2`] = `2 test.only xdescribe`; +exports[`XDESCRIBE test.skip 1`] = `1 test.skip xdescribe`; +exports[`XDESCRIBE test.skip 2`] = `2 test.skip xdescribe`; +exports[`XDESCRIBE xit 1`] = `1 xit xdescribe`; +exports[`XDESCRIBE xit 2`] = `2 xit xdescribe`; +exports[`XDESCRIBE xtest 1`] = `1 xtest xdescribe`; +exports[`XDESCRIBE xtest 2`] = `2 xtest xdescribe`; diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nested.example.snap b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nested.example.snap new file mode 100644 index 000000000000..ee8a6ffce3a2 --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nested.example.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`outer describe outer it inner describe inner it 1`] = `first nested`; +exports[`outer describe outer it inner describe inner it 2`] = `second nested`; diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nodescribe.example.snap b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nodescribe.example.snap new file mode 100644 index 000000000000..36680c31ce0c --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/__snapshots__/nodescribe.example.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`test fit 1`]=`fit 1`; +exports[`test fit 2`]=`fit 2`; +exports[`test it 1`]=`it 1`; +exports[`test it 2`]=`it 2`; +exports[`test it.only 1`]=`it.only 1`; +exports[`test it.only 2`]=`it.only 2`; +exports[`test it.skip 1`]=`it.skip 1`; +exports[`test it.skip 2`]=`it.skip 2`; +exports[`test test 1`]=`test 1`; +exports[`test test 2`]=`test 2`; +exports[`test test.only 1`]=`test.only 1`; +exports[`test test.only 2`]=`test.only 2`; +exports[`test test.skip 1`]=`test.skip 1`; +exports[`test test.skip 2`]=`test.skip 2`; +exports[`test xit 1`]=`xit 1`; +exports[`test xit 2`]=`xit 2`; +exports[`test xtest 1`]=`xtest 1`; +exports[`test xtest 2`]=`xtest 2`; diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/describe.example b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/describe.example new file mode 100644 index 000000000000..5380757ef2e8 --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/describe.example @@ -0,0 +1,194 @@ +describe('DESCRIBE', () => { + fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) +}) + +describe.only('DESCRIBE.ONLY', () => { + fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) +}) + +describe.skip('DESCRIBE.SKIP', () => { + fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) +}) + +fdescribe('FDESCRIBE', () => { + fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) +}) + +xdescribe('XDESCRIBE', () => { + fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) +}) diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nested.example b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nested.example new file mode 100644 index 000000000000..260bd5a556a4 --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nested.example @@ -0,0 +1,10 @@ +describe('outer describe', () => { + it('outer it', () => { + describe('inner describe', () => { + it('inner it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); + }) + }) + }) +}) diff --git a/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nodescribe.example b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nodescribe.example new file mode 100644 index 000000000000..90634fdc7560 --- /dev/null +++ b/packages/jest-editor-support/src/__tests__/fixtures/snapshots/nodescribe.example @@ -0,0 +1,36 @@ +fit('fit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +it('it', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +it.only('it.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +it.skip('it.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +test('test', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +test.only('test.only', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +test.skip('test.skip', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +xit('xit', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) +xtest('xtest', () => { + expect(fake).toMatchSnapshot(); + expect(fake).toMatchSnapshot(); +}) diff --git a/packages/jest-editor-support/src/index.js b/packages/jest-editor-support/src/index.js index 51c99fca95ee..49d6c7a66396 100644 --- a/packages/jest-editor-support/src/index.js +++ b/packages/jest-editor-support/src/index.js @@ -14,6 +14,7 @@ const Process = require('./Process'); const ProjectWorkspace = require('./ProjectWorkspace'); const Runner = require('./Runner'); const Settings = require('./Settings'); +const Snapshot = require('./Snapshot'); const {Expect, ItBlock, Node} = require('./parsers/ParserNodes'); const {parse} = require('./parsers/BabylonParser'); const TestReconciler = require('./TestReconciler'); @@ -26,6 +27,7 @@ module.exports = { ProjectWorkspace, Runner, Settings, + Snapshot, TestReconciler, parse, }; diff --git a/packages/jest-editor-support/src/parsers/BabylonParser.js b/packages/jest-editor-support/src/parsers/BabylonParser.js index 32122ab2d06b..d6095d26d306 100644 --- a/packages/jest-editor-support/src/parsers/BabylonParser.js +++ b/packages/jest-editor-support/src/parsers/BabylonParser.js @@ -43,10 +43,7 @@ const getBabelRC = (filename, {useCache}) => { return cache[directory] || ''; }; -const parse = (file: string) => { - const itBlocks: ItBlock[] = []; - const expects: Expect[] = []; - +const getASTfor = (file: string) => { const data = readFileSync(file).toString(); const babelRC = getBabelRC(file, {useCache: true}); const babel = JSON.parse(babelRC); @@ -56,7 +53,13 @@ const parse = (file: string) => { : ['*']; const config = {plugins, sourceType: 'module'}; - const ast = babylon.parse(data, config); + return babylon.parse(data, config); +}; + +const parse = (file: string) => { + const itBlocks: ItBlock[] = []; + const expects: Expect[] = []; + const ast = getASTfor(file); // An `it`/`test` was found in the AST // So take the AST node and create an object for us @@ -188,5 +191,6 @@ const parse = (file: string) => { }; module.exports = { + getASTfor, parse, }; diff --git a/packages/jest-snapshot/src/index.js b/packages/jest-snapshot/src/index.js index 7dc1990baafa..8949bb420f4b 100644 --- a/packages/jest-snapshot/src/index.js +++ b/packages/jest-snapshot/src/index.js @@ -15,6 +15,7 @@ import type {Path} from 'types/Config'; const diff = require('jest-diff'); const fs = require('fs'); const path = require('path'); +const utils = require('./utils'); const SnapshotState = require('./State'); const {addSerializer, getSerializers} = require('./plugins'); @@ -157,4 +158,5 @@ module.exports = { initializeSnapshotState, toMatchSnapshot, toThrowErrorMatchingSnapshot, + utils, };