diff --git a/__tests__/helper.js b/__tests__/helper.js index 364fe04..58f6ed1 100644 --- a/__tests__/helper.js +++ b/__tests__/helper.js @@ -1,17 +1,31 @@ +/* eslint-env jest */ import getProp from '../src/getProp'; -const parser = require('babylon'); +const nodeVersion = parseInt(process.version.match(/^v(\d+)\./)[1], 10); + +export const fallbackToBabylon = nodeVersion < 6; + +const parser = fallbackToBabylon ? require('babylon') : require('@babel/parser'); + +const defaultPlugins = ['jsx', 'functionBind', 'estree', 'objectRestSpread', 'optionalChaining']; +let plugins = [...defaultPlugins]; + +export function changePlugins(pluginOrFn) { + if (Array.isArray(pluginOrFn)) { + plugins = pluginOrFn; + } else if (typeof pluginOrFn === 'function') { + plugins = pluginOrFn(plugins); + } else { + throw new Error('changePlugins argument should be either an array or a function'); + } +} + +beforeEach(() => { + plugins = [...defaultPlugins]; +}); function parse(code) { - return parser.parse(code, { - plugins: [ - 'estree', - 'functionBind', - 'jsx', - 'objectRestSpread', - 'optionalChaining', - ], - }); + return parser.parse(code, { plugins }); } export function getOpeningElement(code) { diff --git a/__tests__/src/getPropValue-test.js b/__tests__/src/getPropValue-test.js index d3e4479..39ed621 100644 --- a/__tests__/src/getPropValue-test.js +++ b/__tests__/src/getPropValue-test.js @@ -1,9 +1,11 @@ /* eslint-env mocha */ /* eslint no-template-curly-in-string: 0 */ import assert from 'assert'; -import { extractProp } from '../helper'; +import { extractProp, changePlugins, fallbackToBabylon } from '../helper'; import getPropValue from '../../src/getPropValue'; +const describeIfNotBabylon = fallbackToBabylon ? describe.skip : describe; + describe('getPropValue', () => { it('should export a function', () => { const expected = 'function'; @@ -357,17 +359,21 @@ describe('getPropValue', () => { }); it('should evaluate to a correct representation of member expression with a nullable member', () => { - // This tell will not throw when Babel is upgraded from 6 to 7. Remove - // the throw expectation wrapper at that time. - // eslint-disable-next-line no-undef - expect(() => { + const runTest = () => { const prop = extractProp('
'); const expected = 'bar?.baz'; const actual = getPropValue(prop); assert.equal(expected, actual); - }).toThrow(); + }; + + if (fallbackToBabylon) { + // eslint-disable-next-line no-undef + expect(runTest).toThrow(); + } else { + runTest(); + } }); }); @@ -875,4 +881,38 @@ describe('getPropValue', () => { assert.deepEqual(otherExpected, otherActual); }); }); + + describeIfNotBabylon('Typescript', () => { + beforeEach(() => { + changePlugins(pls => [...pls, 'typescript']); + }); + + it('should return string representation of variable identifier wrapped in a Typescript non-null assertion', () => { + const prop = extractProp('
'); + + const expected = 'bar'; + const actual = getPropValue(prop); + + assert.equal(expected, actual); + }); + + it('should return string representation of variable identifier wrapped in a deep Typescript non-null assertion', () => { + const prop = extractProp('
'); + + const expected = 'bar'; + const actual = getPropValue(prop); + + assert.equal(expected, actual); + }); + + it('should return string representation of variable identifier wrapped in a Typescript type coercion', () => { + changePlugins(pls => [...pls, 'typescript']); + const prop = extractProp('
'); + + const expected = 'bar'; + const actual = getPropValue(prop); + + assert.equal(expected, actual); + }); + }); }); diff --git a/package.json b/package.json index 966f60f..82cc410 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "test:watch": "npm test -- --watch" }, "devDependencies": { + "@babel/parser": "^7.3.2", "babel-cli": "^6.14.0", "babel-core": "^6.14.0", "babel-eslint": "^7.0.0", @@ -26,6 +27,7 @@ "eslint-config-airbnb-base": "^11.1.0", "eslint-plugin-import": "^2.2.0", "jest": "^20.0.0", + "jest-cli": "^20.0.4", "rimraf": "^2.5.2" }, "engines": { diff --git a/src/values/expressions/index.js b/src/values/expressions/index.js index 7ba66f7..d16ab1f 100644 --- a/src/values/expressions/index.js +++ b/src/values/expressions/index.js @@ -70,7 +70,12 @@ export default function extract(value) { } else { expression = value; } - const { type } = expression; + let { type } = expression; + + while (type === 'TSNonNullExpression' || type === 'TSAsExpression') { + expression = expression.expression; + type = expression.type; + } if (TYPES[type] === undefined) { throw new Error(errorMessage(type));