mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-17 05:21:53 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
87
web/node_modules/jsx-ast-utils/__tests__/helper.js
generated
vendored
Normal file
87
web/node_modules/jsx-ast-utils/__tests__/helper.js
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* eslint-env jest */
|
||||
import getProp from '../src/getProp';
|
||||
|
||||
const nodeVersion = parseInt(process.version.match(/^v(\d+)\./)[1], 10);
|
||||
|
||||
export const fallbackToBabylon = nodeVersion < 6;
|
||||
|
||||
let parserName;
|
||||
const babelParser = fallbackToBabylon ? require('babylon') : require('@babel/parser');
|
||||
const flowParser = require('flow-parser');
|
||||
|
||||
const defaultPlugins = [
|
||||
'jsx',
|
||||
'functionBind',
|
||||
'estree',
|
||||
'objectRestSpread',
|
||||
'optionalChaining',
|
||||
// 'nullishCoalescing', // TODO: update to babel 7
|
||||
];
|
||||
let plugins = [...defaultPlugins];
|
||||
|
||||
export function setParserName(name) {
|
||||
parserName = name;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (parserName === undefined) {
|
||||
throw new Error('No parser specified');
|
||||
}
|
||||
if (parserName === 'babel') {
|
||||
try {
|
||||
return babelParser.parse(code, { plugins, sourceFilename: 'test.js' });
|
||||
} catch (_) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Failed to parse with ${fallbackToBabylon ? 'babylon' : 'Babel'} parser.`);
|
||||
}
|
||||
}
|
||||
if (parserName === 'flow') {
|
||||
try {
|
||||
return flowParser.parse(code, { plugins });
|
||||
} catch (_) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('Failed to parse with the Flow parser');
|
||||
}
|
||||
}
|
||||
throw new Error(`The parser ${parserName} is not yet supported for testing.`);
|
||||
}
|
||||
|
||||
export function getOpeningElement(code) {
|
||||
const parsedCode = parse(code);
|
||||
let body;
|
||||
if (parsedCode.program) {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
body = parsedCode.program.body;
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
body = parsedCode.body;
|
||||
}
|
||||
if (Array.isArray(body) && body[0] != null) {
|
||||
const [{ expression }] = body;
|
||||
return expression.type === 'JSXFragment' ? expression.openingFragment : expression.openingElement;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function extractProp(code, prop = 'foo') {
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
return getProp(props, prop);
|
||||
}
|
||||
|
||||
export const describeIfNotBabylon = fallbackToBabylon ? describe.skip : describe;
|
95
web/node_modules/jsx-ast-utils/__tests__/src/elementType-test.js
generated
vendored
Normal file
95
web/node_modules/jsx-ast-utils/__tests__/src/elementType-test.js
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import { getOpeningElement, setParserName } from '../helper';
|
||||
import elementType from '../../src/elementType';
|
||||
|
||||
describe('elementType tests', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('babel');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof elementType;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should throw an error if the argument is missing', () => {
|
||||
assert.throws(() => { elementType(); }, Error);
|
||||
});
|
||||
|
||||
it('should throw an error if the argument not a JSX node', () => {
|
||||
assert.throws(() => { elementType({ a: 'foo' }); }, Error);
|
||||
});
|
||||
|
||||
it('should return the correct type of the DOM element given its node object', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'div';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct type of the custom element given its node object', () => {
|
||||
const code = '<Slider />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'Slider';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct type of the custom object element given its node object', () => {
|
||||
const code = '<UX.Slider />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'UX.Slider';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct type of the namespaced element given its node object', () => {
|
||||
const code = '<UX:Slider />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'UX:Slider';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct type of the multiple custom object element given its node object',
|
||||
() => {
|
||||
const code = '<UX.Slider.Blue.Light />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'UX.Slider.Blue.Light';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return this.Component when given its node object', () => {
|
||||
const code = '<this.Component />';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = 'this.Component';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should work with fragments', () => {
|
||||
const code = '<>foo</>';
|
||||
const node = getOpeningElement(code);
|
||||
|
||||
const expected = '<>';
|
||||
const actual = elementType(node);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
101
web/node_modules/jsx-ast-utils/__tests__/src/eventHandlers-test.js
generated
vendored
Normal file
101
web/node_modules/jsx-ast-utils/__tests__/src/eventHandlers-test.js
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import includes from 'array-includes';
|
||||
import eventHandlers, { eventHandlersByType } from '../../src/eventHandlers';
|
||||
|
||||
describe('eventHandlers', () => {
|
||||
it('should contain a list of common JSX event handlers', () => {
|
||||
assert([
|
||||
'onCopy',
|
||||
'onCut',
|
||||
'onPaste',
|
||||
'onCompositionEnd',
|
||||
'onCompositionStart',
|
||||
'onCompositionUpdate',
|
||||
'onKeyDown',
|
||||
'onKeyPress',
|
||||
'onKeyUp',
|
||||
'onFocus',
|
||||
'onBlur',
|
||||
'onChange',
|
||||
'onInput',
|
||||
'onSubmit',
|
||||
'onClick',
|
||||
'onContextMenu',
|
||||
'onDblClick',
|
||||
'onDoubleClick',
|
||||
'onDrag',
|
||||
'onDragEnd',
|
||||
'onDragEnter',
|
||||
'onDragExit',
|
||||
'onDragLeave',
|
||||
'onDragOver',
|
||||
'onDragStart',
|
||||
'onDrop',
|
||||
'onMouseDown',
|
||||
'onMouseEnter',
|
||||
'onMouseLeave',
|
||||
'onMouseMove',
|
||||
'onMouseOut',
|
||||
'onMouseOver',
|
||||
'onMouseUp',
|
||||
'onSelect',
|
||||
'onTouchCancel',
|
||||
'onTouchEnd',
|
||||
'onTouchMove',
|
||||
'onTouchStart',
|
||||
'onScroll',
|
||||
'onWheel',
|
||||
'onAbort',
|
||||
'onCanPlay',
|
||||
'onCanPlayThrough',
|
||||
'onDurationChange',
|
||||
'onEmptied',
|
||||
'onEncrypted',
|
||||
'onEnded',
|
||||
'onError',
|
||||
'onLoadedData',
|
||||
'onLoadedMetadata',
|
||||
'onLoadStart',
|
||||
'onPause',
|
||||
'onPlay',
|
||||
'onPlaying',
|
||||
'onProgress',
|
||||
'onRateChange',
|
||||
'onSeeked',
|
||||
'onSeeking',
|
||||
'onStalled',
|
||||
'onSuspend',
|
||||
'onTimeUpdate',
|
||||
'onVolumeChange',
|
||||
'onWaiting',
|
||||
'onLoad',
|
||||
'onError',
|
||||
'onAnimationStart',
|
||||
'onAnimationEnd',
|
||||
'onAnimationIteration',
|
||||
'onTransitionEnd',
|
||||
].every((handlerName) => includes(eventHandlers, handlerName)));
|
||||
});
|
||||
});
|
||||
|
||||
describe('eventHandlersByType', () => {
|
||||
it('should be keyed by type', () => {
|
||||
assert([
|
||||
'clipboard',
|
||||
'composition',
|
||||
'keyboard',
|
||||
'focus',
|
||||
'form',
|
||||
'mouse',
|
||||
'selection',
|
||||
'touch',
|
||||
'ui',
|
||||
'wheel',
|
||||
'media',
|
||||
'image',
|
||||
'animation',
|
||||
'transition',
|
||||
].every((type) => !!eventHandlersByType[type]));
|
||||
});
|
||||
});
|
176
web/node_modules/jsx-ast-utils/__tests__/src/getProp-parser-test.js
generated
vendored
Normal file
176
web/node_modules/jsx-ast-utils/__tests__/src/getProp-parser-test.js
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import entries from 'object.entries';
|
||||
import fromEntries from 'object.fromentries';
|
||||
import { getOpeningElement, setParserName, fallbackToBabylon } from '../helper';
|
||||
import getProp from '../../src/getProp';
|
||||
|
||||
const literal = {
|
||||
source: '<div {...{ id: "foo" }} />',
|
||||
target: '<div id="foo" />',
|
||||
offset: { keyOffset: -6, valueOffset: -7 },
|
||||
};
|
||||
|
||||
const expression1 = {
|
||||
source: '<div {...{ id }} />',
|
||||
target: '<div id={id} />',
|
||||
offset: { keyOffset: -6, valueOffset: -2 },
|
||||
};
|
||||
|
||||
const expression2 = {
|
||||
source: '<div {...{ id: `foo${bar}baz` }} />', // eslint-disable-line no-template-curly-in-string
|
||||
target: '<div id={`foo${bar}baz`} />', // eslint-disable-line no-template-curly-in-string
|
||||
offset: { keyOffset: -6, valueOffset: -6 },
|
||||
};
|
||||
|
||||
describe('getProp', () => {
|
||||
it('should create the correct AST for literal with flow parser', () => {
|
||||
actualTest('flow', literal);
|
||||
});
|
||||
it('should create the correct AST for literal with babel parser', () => {
|
||||
actualTest('babel', literal);
|
||||
});
|
||||
it('should create the correct AST for expression with flow parser (1)', () => {
|
||||
actualTest('flow', expression1);
|
||||
});
|
||||
it('should create the correct AST for expression with babel parser (1)', () => {
|
||||
actualTest('babel', expression1);
|
||||
});
|
||||
it('should create the correct AST for expression with flow parser (2)', () => {
|
||||
actualTest('flow', expression2);
|
||||
});
|
||||
it('should create the correct AST for expression with babel parser (2)', () => {
|
||||
actualTest('babel', expression2);
|
||||
});
|
||||
});
|
||||
|
||||
function actualTest(parserName, test) {
|
||||
setParserName(parserName);
|
||||
const { source, target, offset } = test;
|
||||
const sourceProps = stripConstructors(getOpeningElement(source).attributes);
|
||||
const targetProps = stripConstructors(getOpeningElement(target).attributes);
|
||||
const prop = 'id';
|
||||
const sourceResult = getProp(sourceProps, prop);
|
||||
const targetResult = getProp(targetProps, prop);
|
||||
|
||||
if (fallbackToBabylon && parserName === 'babel' && test === literal) {
|
||||
// Babylon (node < 6) adds an `extra: null` prop to a literal if it is parsed from a
|
||||
// JSXAttribute, other literals don't get this.
|
||||
sourceResult.value.extra = null;
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(
|
||||
adjustLocations(sourceResult, offset),
|
||||
adjustRange(targetResult),
|
||||
);
|
||||
}
|
||||
|
||||
function adjustRange({ name, value: { expression, ...value }, ...node }) {
|
||||
return {
|
||||
...adjustNodeRange(node),
|
||||
name: adjustNodeRange(name),
|
||||
value: {
|
||||
...adjustNodeRange(value),
|
||||
...(expression ? { expression: adjustNodeRangeRecursively(expression) } : {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function adjustNodeRange(node) {
|
||||
if (!node.loc) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const [start, end] = node.range || [node.start, node.end];
|
||||
return {
|
||||
...node,
|
||||
end: undefined,
|
||||
range: [start, end],
|
||||
start: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function adjustNodeRangeRecursively(node) {
|
||||
if (Array.isArray(node)) {
|
||||
return node.map(adjustNodeRangeRecursively);
|
||||
}
|
||||
|
||||
if (node && typeof node === 'object') {
|
||||
return adjustNodeRange(mapValues(node, adjustNodeRangeRecursively));
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function stripConstructors(value) {
|
||||
return JSON.parse(JSON.stringify(value));
|
||||
}
|
||||
|
||||
function adjustLocations(node, { keyOffset, valueOffset }) {
|
||||
const hasExpression = !!node.value.expression;
|
||||
return {
|
||||
...adjustNodeLocations(node, {
|
||||
startOffset: keyOffset,
|
||||
endOffset: valueOffset + (hasExpression ? 1 : 0),
|
||||
}),
|
||||
name: adjustNodeLocations(node.name, { startOffset: keyOffset, endOffset: keyOffset }),
|
||||
value: {
|
||||
...adjustNodeLocations(node.value, {
|
||||
startOffset: valueOffset - (hasExpression ? 1 : 0),
|
||||
endOffset: valueOffset + (hasExpression ? 1 : 0),
|
||||
}),
|
||||
...(hasExpression
|
||||
? {
|
||||
expression: adjustLocationsRecursively(
|
||||
node.value.expression,
|
||||
{ startOffset: valueOffset, endOffset: valueOffset },
|
||||
),
|
||||
}
|
||||
: {}
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function adjustNodeLocations(node, { startOffset, endOffset }) {
|
||||
if (!node.loc) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const [start, end] = node.range || [];
|
||||
return {
|
||||
...node,
|
||||
end: undefined,
|
||||
loc: {
|
||||
...node.loc,
|
||||
start: {
|
||||
...node.loc.start,
|
||||
column: node.loc.start.column + startOffset,
|
||||
},
|
||||
end: {
|
||||
...node.loc.end,
|
||||
column: node.loc.end.column + endOffset,
|
||||
},
|
||||
},
|
||||
range: [start + startOffset, end + endOffset],
|
||||
start: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function adjustLocationsRecursively(node, { startOffset, endOffset }) {
|
||||
if (Array.isArray(node)) {
|
||||
return node.map((x) => adjustLocationsRecursively(x, { startOffset, endOffset }));
|
||||
}
|
||||
if (node && typeof node === 'object') {
|
||||
return adjustNodeLocations(
|
||||
mapValues(node, (x) => adjustLocationsRecursively(x, { startOffset, endOffset })),
|
||||
{ startOffset, endOffset },
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function mapValues(o, f) {
|
||||
return fromEntries(entries(o).map(([k, v]) => [k, f(v)]));
|
||||
}
|
149
web/node_modules/jsx-ast-utils/__tests__/src/getProp-test.js
generated
vendored
Normal file
149
web/node_modules/jsx-ast-utils/__tests__/src/getProp-test.js
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import { getOpeningElement, setParserName } from '../helper';
|
||||
import getProp from '../../src/getProp';
|
||||
|
||||
describe('getProp', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('babel');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof getProp;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined if no arguments are provided', () => {
|
||||
const expected = undefined;
|
||||
const actual = getProp();
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined if the attribute is absent', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct attribute if the attribute exists', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = 'id';
|
||||
const actual = getProp(props, prop).name.name;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct attribute if the attribute exists in spread', () => {
|
||||
const code = '<div {...{ id: "foo" }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'ID';
|
||||
|
||||
const expected = 'id';
|
||||
const actual = getProp(props, prop).name.name;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return the correct attribute if the attribute exists in spread as an expression', () => {
|
||||
const code = '<div {...{ id }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = 'id';
|
||||
const actual = getProp(props, prop);
|
||||
const actualName = actual.name.name;
|
||||
const actualValue = actual.value.expression.name;
|
||||
|
||||
assert.equal(actualName, expected);
|
||||
assert.equal(actualValue, expected);
|
||||
});
|
||||
|
||||
it('should return the correct attribute if the attribute exists in spread (case sensitive)', () => {
|
||||
const code = '<div {...{ id: "foo" }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = { ignoreCase: false };
|
||||
|
||||
const expected = 'id';
|
||||
const actual = getProp(props, prop, options).name.name;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined if the attribute does not exist in spread (case sensitive)', () => {
|
||||
const code = '<div {...{ id: "foo" }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'ID';
|
||||
const options = { ignoreCase: false };
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined for key in spread', () => {
|
||||
// https://github.com/reactjs/rfcs/pull/107
|
||||
const code = '<div {...{ key }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'key';
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined if the attribute may exist in spread', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should not crash if the spread contains a spread', () => {
|
||||
const code = '<div {...{ ...props }} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
getProp(props, prop);
|
||||
});
|
||||
|
||||
it('should return undefined if the attribute is considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
529
web/node_modules/jsx-ast-utils/__tests__/src/getPropLiteralValue-babelparser-test.js
generated
vendored
Normal file
529
web/node_modules/jsx-ast-utils/__tests__/src/getPropLiteralValue-babelparser-test.js
generated
vendored
Normal file
|
@ -0,0 +1,529 @@
|
|||
/* eslint-env mocha */
|
||||
/* eslint no-template-curly-in-string: 0 */
|
||||
import assert from 'assert';
|
||||
import {
|
||||
extractProp,
|
||||
describeIfNotBabylon,
|
||||
changePlugins,
|
||||
setParserName,
|
||||
} from '../helper';
|
||||
import { getLiteralPropValue } from '../../src/getPropValue';
|
||||
|
||||
describe('getLiteralPropValue', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('babel');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof getLiteralPropValue;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when not provided with a JSXAttribute', () => {
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(1);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should not throw error when trying to get value from unknown node type', () => {
|
||||
const prop = {
|
||||
type: 'JSXAttribute',
|
||||
value: {
|
||||
type: 'JSXExpressionContainer',
|
||||
},
|
||||
};
|
||||
let counter = 0;
|
||||
// eslint-disable-next-line no-console
|
||||
const errorOrig = console.error;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = () => {
|
||||
counter += 1;
|
||||
};
|
||||
let value;
|
||||
assert.doesNotThrow(() => {
|
||||
value = getLiteralPropValue(prop);
|
||||
}, Error);
|
||||
|
||||
assert.equal(null, value);
|
||||
assert.equal(counter, 1);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = errorOrig;
|
||||
});
|
||||
|
||||
describe('Null', () => {
|
||||
it('should return true when no value is given', () => {
|
||||
const prop = extractProp('<div foo />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Literal', () => {
|
||||
it('should return correct string if value is a string', () => {
|
||||
const prop = extractProp('<div foo="bar" />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct string if value is a string expression', () => {
|
||||
const prop = extractProp('<div foo={"bar"} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct integer if value is a integer expression', () => {
|
||||
const prop = extractProp('<div foo={1} />');
|
||||
|
||||
const expected = 1;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "true" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="true" />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "TrUE" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="TrUE" />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "false" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="false" />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "FaLsE" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="FaLsE" />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return String null when value is null', () => {
|
||||
const prop = extractProp('<div foo={null} />');
|
||||
|
||||
const expected = 'null';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSXElement', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={<bar />} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Identifier', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when identifier is literally `undefined`', () => {
|
||||
const prop = extractProp('<div foo={undefined} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tagged Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Arrow function expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ () => { return "bar"; }} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Function expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ function() { return "bar"; } } />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logical expression', () => {
|
||||
it('should return null for && operator', () => {
|
||||
const prop = extractProp('<div foo={bar && baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return null for || operator', () => {
|
||||
const prop = extractProp('<div foo={bar || baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Member expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar.baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Call expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar()} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unary expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-bar} />');
|
||||
|
||||
// -"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-42} />');
|
||||
|
||||
const expected = -42;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+bar} />');
|
||||
|
||||
// +"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+42} />');
|
||||
|
||||
const expected = 42;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with !', () => {
|
||||
const prop = extractProp('<div foo={!bar} />');
|
||||
|
||||
const expected = false; // !"bar" === false
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with ~', () => {
|
||||
const prop = extractProp('<div foo={~bar} />');
|
||||
|
||||
const expected = -1; // ~"bar" === -1
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true when evaluating `delete foo`', () => {
|
||||
const prop = extractProp('<div foo={delete x} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when evaluating `void foo`', () => {
|
||||
const prop = extractProp('<div foo={void x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
// TODO: We should fix this to check to see if we can evaluate it.
|
||||
it('should return undefined when evaluating `typeof foo`', () => {
|
||||
const prop = extractProp('<div foo={typeof x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with ++', () => {
|
||||
const prop = extractProp('<div foo={++bar} />');
|
||||
|
||||
// ++"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with --', () => {
|
||||
const prop = extractProp('<div foo={--bar} />');
|
||||
|
||||
// --"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with ++', () => {
|
||||
const prop = extractProp('<div foo={bar++} />');
|
||||
|
||||
// "bar"++ => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with --', () => {
|
||||
const prop = extractProp('<div foo={bar--} />');
|
||||
|
||||
// "bar"-- => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('This expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={this} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Conditional expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar ? baz : bam} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Binary expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={1 == "1"} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Object expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ { bar: "baz" } } />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('New expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={new Bar()} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Array expression', () => {
|
||||
it('should evaluate to correct representation of the the array in props', () => {
|
||||
const prop = extractProp('<div foo={["bar", 42, null]} />');
|
||||
|
||||
const expected = ['bar', 42];
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array provided an empty array in props', () => {
|
||||
const prop = extractProp('<div foo={[]} />');
|
||||
|
||||
const expected = [];
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
describe('Bind expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={::this.handleClick} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
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('<div foo={bar!} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a deep Typescript non-null assertion', () => {
|
||||
const prop = extractProp('<div foo={(bar!)!} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a Typescript type coercion', () => {
|
||||
changePlugins((pls) => [...pls, 'typescript']);
|
||||
const prop = extractProp('<div foo={bar as any} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should work with a this.props value', () => {
|
||||
const prop = extractProp('<a href={this.props.href!}>Download</a>');
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
522
web/node_modules/jsx-ast-utils/__tests__/src/getPropLiteralValue-flowparser-test.js
generated
vendored
Normal file
522
web/node_modules/jsx-ast-utils/__tests__/src/getPropLiteralValue-flowparser-test.js
generated
vendored
Normal file
|
@ -0,0 +1,522 @@
|
|||
/* eslint-env mocha */
|
||||
/* eslint no-template-curly-in-string: 0 */
|
||||
import assert from 'assert';
|
||||
import {
|
||||
extractProp,
|
||||
describeIfNotBabylon,
|
||||
changePlugins,
|
||||
setParserName,
|
||||
} from '../helper';
|
||||
import { getLiteralPropValue } from '../../src/getPropValue';
|
||||
|
||||
describe('getLiteralPropValue', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('flow');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof getLiteralPropValue;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when not provided with a JSXAttribute', () => {
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(1);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should not throw error when trying to get value from unknown node type', () => {
|
||||
const prop = {
|
||||
type: 'JSXAttribute',
|
||||
value: {
|
||||
type: 'JSXExpressionContainer',
|
||||
},
|
||||
};
|
||||
let counter = 0;
|
||||
// eslint-disable-next-line no-console
|
||||
const errorOrig = console.error;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = () => {
|
||||
counter += 1;
|
||||
};
|
||||
let value;
|
||||
assert.doesNotThrow(() => {
|
||||
value = getLiteralPropValue(prop);
|
||||
}, Error);
|
||||
|
||||
assert.equal(null, value);
|
||||
assert.equal(counter, 1);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = errorOrig;
|
||||
});
|
||||
|
||||
describe('Null', () => {
|
||||
it('should return true when no value is given', () => {
|
||||
const prop = extractProp('<div foo />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Literal', () => {
|
||||
it('should return correct string if value is a string', () => {
|
||||
const prop = extractProp('<div foo="bar" />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct string if value is a string expression', () => {
|
||||
const prop = extractProp('<div foo={"bar"} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct integer if value is a integer expression', () => {
|
||||
const prop = extractProp('<div foo={1} />');
|
||||
|
||||
const expected = 1;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "true" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="true" />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "TrUE" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="TrUE" />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "false" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="false" />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "FaLsE" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="FaLsE" />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return String null when value is null', () => {
|
||||
const prop = extractProp('<div foo={null} />');
|
||||
|
||||
const expected = 'null';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSXElement', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={<bar />} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Identifier', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when identifier is literally `undefined`', () => {
|
||||
const prop = extractProp('<div foo={undefined} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tagged Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Arrow function expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ () => { return "bar"; }} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Function expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ function() { return "bar"; } } />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logical expression', () => {
|
||||
it('should return null for && operator', () => {
|
||||
const prop = extractProp('<div foo={bar && baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return null for || operator', () => {
|
||||
const prop = extractProp('<div foo={bar || baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Member expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar.baz} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Call expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar()} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unary expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-bar} />');
|
||||
|
||||
// -"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-42} />');
|
||||
|
||||
const expected = -42;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+bar} />');
|
||||
|
||||
// +"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+42} />');
|
||||
|
||||
const expected = 42;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with !', () => {
|
||||
const prop = extractProp('<div foo={!bar} />');
|
||||
|
||||
const expected = false; // !"bar" === false
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with ~', () => {
|
||||
const prop = extractProp('<div foo={~bar} />');
|
||||
|
||||
const expected = -1; // ~"bar" === -1
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true when evaluating `delete foo`', () => {
|
||||
const prop = extractProp('<div foo={delete x} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when evaluating `void foo`', () => {
|
||||
const prop = extractProp('<div foo={void x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
// TODO: We should fix this to check to see if we can evaluate it.
|
||||
it('should return undefined when evaluating `typeof foo`', () => {
|
||||
const prop = extractProp('<div foo={typeof x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with ++', () => {
|
||||
const prop = extractProp('<div foo={++bar} />');
|
||||
|
||||
// ++"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with --', () => {
|
||||
const prop = extractProp('<div foo={--bar} />');
|
||||
|
||||
// --"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with ++', () => {
|
||||
const prop = extractProp('<div foo={bar++} />');
|
||||
|
||||
// "bar"++ => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with --', () => {
|
||||
const prop = extractProp('<div foo={bar--} />');
|
||||
|
||||
// "bar"-- => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getLiteralPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('This expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={this} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Conditional expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={bar ? baz : bam} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Binary expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={1 == "1"} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Object expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={ { bar: "baz" } } />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('New expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={new Bar()} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Array expression', () => {
|
||||
it('should evaluate to correct representation of the the array in props', () => {
|
||||
const prop = extractProp('<div foo={["bar", 42, null]} />');
|
||||
|
||||
const expected = ['bar', 42];
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array provided an empty array in props', () => {
|
||||
const prop = extractProp('<div foo={[]} />');
|
||||
|
||||
const expected = [];
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
describe('Bind expression', () => {
|
||||
it('should return null', () => {
|
||||
const prop = extractProp('<div foo={::this.handleClick} />');
|
||||
|
||||
const expected = 'null';
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
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('<div foo={bar!} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a deep Typescript non-null assertion', () => {
|
||||
const prop = extractProp('<div foo={(bar!)!} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a Typescript type coercion', () => {
|
||||
changePlugins((pls) => [...pls, 'typescript']);
|
||||
const prop = extractProp('<div foo={bar as any} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getLiteralPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
1195
web/node_modules/jsx-ast-utils/__tests__/src/getPropValue-babelparser-test.js
generated
vendored
Normal file
1195
web/node_modules/jsx-ast-utils/__tests__/src/getPropValue-babelparser-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
963
web/node_modules/jsx-ast-utils/__tests__/src/getPropValue-flowparser-test.js
generated
vendored
Normal file
963
web/node_modules/jsx-ast-utils/__tests__/src/getPropValue-flowparser-test.js
generated
vendored
Normal file
|
@ -0,0 +1,963 @@
|
|||
/* eslint-env mocha */
|
||||
/* eslint no-template-curly-in-string: 0 */
|
||||
import assert from 'assert';
|
||||
import {
|
||||
extractProp,
|
||||
changePlugins,
|
||||
describeIfNotBabylon,
|
||||
setParserName,
|
||||
} from '../helper';
|
||||
import getPropValue from '../../src/getPropValue';
|
||||
|
||||
describe('getPropValue', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('flow');
|
||||
});
|
||||
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof getPropValue;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when not provided with a JSXAttribute', () => {
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(1);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should throw not error when trying to get value from unknown node type', () => {
|
||||
const prop = {
|
||||
type: 'JSXAttribute',
|
||||
value: {
|
||||
type: 'JSXExpressionContainer',
|
||||
},
|
||||
};
|
||||
let counter = 0;
|
||||
// eslint-disable-next-line no-console
|
||||
const errorOrig = console.error;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = () => {
|
||||
counter += 1;
|
||||
};
|
||||
let value;
|
||||
assert.doesNotThrow(() => {
|
||||
value = getPropValue(prop);
|
||||
}, Error);
|
||||
|
||||
assert.equal(null, value);
|
||||
assert.equal(counter, 1);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = errorOrig;
|
||||
});
|
||||
|
||||
describe('Null', () => {
|
||||
it('should return true when no value is given', () => {
|
||||
const prop = extractProp('<div foo />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Literal', () => {
|
||||
it('should return correct string if value is a string', () => {
|
||||
const prop = extractProp('<div foo="bar" />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct string if value is a string expression', () => {
|
||||
const prop = extractProp('<div foo={"bar"} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct integer if value is a integer expression', () => {
|
||||
const prop = extractProp('<div foo={1} />');
|
||||
|
||||
const expected = 1;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "true" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="true" />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should convert "false" to boolean type', () => {
|
||||
const prop = extractProp('<div foo="false" />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSXElement', () => {
|
||||
it('should return correct representation of JSX element as a string', () => {
|
||||
const prop = extractProp('<div foo={<bar />} />');
|
||||
|
||||
const expected = '<bar />';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Identifier', () => {
|
||||
it('should return string representation of variable identifier', () => {
|
||||
const prop = extractProp('<div foo={bar} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when identifier is literally `undefined`', () => {
|
||||
const prop = extractProp('<div foo={undefined} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return String object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={String} />');
|
||||
|
||||
const expected = String;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Array object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Array} />');
|
||||
|
||||
const expected = Array;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Date object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Date} />');
|
||||
|
||||
const expected = Date;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Infinity object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Infinity} />');
|
||||
|
||||
const expected = Infinity;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Math object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Math} />');
|
||||
|
||||
const expected = Math;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Number object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Number} />');
|
||||
|
||||
const expected = Number;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return Object object when using a reserved JavaScript object', () => {
|
||||
const prop = extractProp('<div foo={Object} />');
|
||||
|
||||
const expected = Object;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return template literal with expression type wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={`bar ${baz()}`} />');
|
||||
|
||||
const expected = 'bar {CallExpression}';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should ignore non-expressions in the template literal', () => {
|
||||
const prop = extractProp('<div foo={`bar ${<baz />}`} />');
|
||||
|
||||
const expected = 'bar ';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tagged Template literal', () => {
|
||||
it('should return template literal with vars wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${baz}`} />');
|
||||
|
||||
const expected = 'bar {baz}';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string "undefined" for expressions that evaluate to undefined', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${undefined}`} />');
|
||||
|
||||
const expected = 'bar undefined';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return template literal with expression type wrapped in curly braces', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${baz()}`} />');
|
||||
|
||||
const expected = 'bar {CallExpression}';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should ignore non-expressions in the template literal', () => {
|
||||
const prop = extractProp('<div foo={noop`bar ${<baz />}`} />');
|
||||
|
||||
const expected = 'bar ';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Arrow function expression', () => {
|
||||
it('should return a function', () => {
|
||||
const prop = extractProp('<div foo={ () => { return "bar"; }} />');
|
||||
|
||||
const expected = 'function';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(expected, typeof actual);
|
||||
|
||||
// For code coverage ¯\_(ツ)_/¯
|
||||
actual();
|
||||
});
|
||||
it('should handle ArrowFunctionExpression as conditional consequent', () => {
|
||||
const prop = extractProp('<div foo={ (true) ? () => null : () => ({})} />');
|
||||
|
||||
const expected = 'function';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(expected, typeof actual);
|
||||
|
||||
// For code coverage ¯\_(ツ)_/¯
|
||||
actual();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Function expression', () => {
|
||||
it('should return a function', () => {
|
||||
const prop = extractProp('<div foo={ function() { return "bar"; } } />');
|
||||
|
||||
const expected = 'function';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(expected, typeof actual);
|
||||
|
||||
// For code coverage ¯\_(ツ)_/¯
|
||||
actual();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logical expression', () => {
|
||||
it('should correctly infer result of && logical expression based on derived values', () => {
|
||||
const prop = extractProp('<div foo={bar && baz} />');
|
||||
|
||||
const expected = 'baz';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when evaluating `undefined && undefined` ', () => {
|
||||
const prop = extractProp('<div foo={undefined && undefined} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly infer result of || logical expression based on derived values', () => {
|
||||
const prop = extractProp('<div foo={bar || baz} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly infer result of || logical expression based on derived values', () => {
|
||||
const prop = extractProp('<div foo={undefined || baz} />');
|
||||
|
||||
const expected = 'baz';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when evaluating `undefined || undefined` ', () => {
|
||||
const prop = extractProp('<div foo={undefined || undefined} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Member expression', () => {
|
||||
it('should return string representation of form `object.property`', () => {
|
||||
const prop = extractProp('<div foo={bar.baz} />');
|
||||
|
||||
const expected = 'bar.baz';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate to a correct representation of member expression with a nullable member', () => {
|
||||
const prop = extractProp('<div foo={bar?.baz} />');
|
||||
|
||||
const expected = 'bar?.baz';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Call expression', () => {
|
||||
it('should return string representation of callee', () => {
|
||||
const prop = extractProp('<div foo={bar()} />');
|
||||
|
||||
const expected = 'bar()';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of callee', () => {
|
||||
const prop = extractProp('<div foo={bar.call()} />');
|
||||
|
||||
const expected = 'bar.call()';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unary expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-bar} />');
|
||||
|
||||
// -"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with -', () => {
|
||||
const prop = extractProp('<div foo={-42} />');
|
||||
|
||||
const expected = -42;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+bar} />');
|
||||
|
||||
// +"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with +', () => {
|
||||
const prop = extractProp('<div foo={+42} />');
|
||||
|
||||
const expected = 42;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with !', () => {
|
||||
const prop = extractProp('<div foo={!bar} />');
|
||||
|
||||
const expected = false; // !"bar" === false
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with ~', () => {
|
||||
const prop = extractProp('<div foo={~bar} />');
|
||||
|
||||
const expected = -1; // ~"bar" === -1
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true when evaluating `delete foo`', () => {
|
||||
const prop = extractProp('<div foo={delete x} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return undefined when evaluating `void foo`', () => {
|
||||
const prop = extractProp('<div foo={void x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
// TODO: We should fix this to check to see if we can evaluate it.
|
||||
it('should return undefined when evaluating `typeof foo`', () => {
|
||||
const prop = extractProp('<div foo={typeof x} />');
|
||||
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update expression', () => {
|
||||
it('should correctly evaluate an expression that prefixes with ++', () => {
|
||||
const prop = extractProp('<div foo={++bar} />');
|
||||
|
||||
// ++"bar" => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that prefixes with --', () => {
|
||||
const prop = extractProp('<div foo={--bar} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with ++', () => {
|
||||
const prop = extractProp('<div foo={bar++} />');
|
||||
|
||||
// "bar"++ => NaN
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should correctly evaluate an expression that suffixes with --', () => {
|
||||
const prop = extractProp('<div foo={bar--} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = Number.isNaN(getPropValue(prop));
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('This expression', () => {
|
||||
it('should return string value `this`', () => {
|
||||
const prop = extractProp('<div foo={this} />');
|
||||
|
||||
const expected = 'this';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Conditional expression', () => {
|
||||
it('should evaluate the conditional based on the derived values correctly', () => {
|
||||
const prop = extractProp('<div foo={bar ? baz : bam} />');
|
||||
|
||||
const expected = 'baz';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the conditional based on the derived values correctly', () => {
|
||||
const prop = extractProp('<div foo={undefined ? baz : bam} />');
|
||||
|
||||
const expected = 'bam';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the conditional based on the derived values correctly', () => {
|
||||
const prop = extractProp('<div foo={(1 > 2) ? baz : bam} />');
|
||||
|
||||
const expected = 'bam';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Binary expression', () => {
|
||||
it('should evaluate the `==` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 == "1"} />');
|
||||
const falseProp = extractProp('<div foo={1 == bar} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `!=` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 != "2"} />');
|
||||
const falseProp = extractProp('<div foo={1 != "1"} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `===` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 === 1} />');
|
||||
const falseProp = extractProp('<div foo={1 === "1"} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `!==` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 !== "1"} />');
|
||||
const falseProp = extractProp('<div foo={1 !== 1} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `<` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 < 2} />');
|
||||
const falseProp = extractProp('<div foo={1 < 0} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `>` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 > 0} />');
|
||||
const falseProp = extractProp('<div foo={1 > 2} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `<=` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 <= 1} />');
|
||||
const falseProp = extractProp('<div foo={1 <= 0} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `>=` operator correctly', () => {
|
||||
const trueProp = extractProp('<div foo={1 >= 1} />');
|
||||
const falseProp = extractProp('<div foo={1 >= 2} />');
|
||||
|
||||
const trueVal = getPropValue(trueProp);
|
||||
const falseVal = getPropValue(falseProp);
|
||||
|
||||
assert.equal(true, trueVal);
|
||||
assert.equal(false, falseVal);
|
||||
});
|
||||
|
||||
it('should evaluate the `<<` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={1 << 2} />');
|
||||
|
||||
const expected = 4;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `>>` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={1 >> 2} />');
|
||||
|
||||
const expected = 0;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `>>>` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={2 >>> 1} />');
|
||||
|
||||
const expected = 1;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `+` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={1 + 1} />');
|
||||
|
||||
const expected = 2;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `-` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={1 - 1} />');
|
||||
|
||||
const expected = 0;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `*` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 * 10} />');
|
||||
|
||||
const expected = 100;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `/` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 / 2} />');
|
||||
|
||||
const expected = 5;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `%` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 % 3} />');
|
||||
|
||||
const expected = 1;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `|` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 | 1} />');
|
||||
|
||||
const expected = 11;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `^` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 ^ 1} />');
|
||||
|
||||
const expected = 11;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `&` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={10 & 1} />');
|
||||
|
||||
const expected = 0;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `in` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={foo in bar} />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `instanceof` operator correctly', () => {
|
||||
const prop = extractProp('<div foo={{} instanceof Object} />');
|
||||
|
||||
const expected = true;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate the `instanceof` operator when right side is not a function', () => {
|
||||
const prop = extractProp('<div foo={"bar" instanceof Baz} />');
|
||||
|
||||
const expected = false;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Object expression', () => {
|
||||
it('should evaluate to a correct representation of the object in props', () => {
|
||||
const prop = extractProp('<div foo={ { bar: "baz" } } />');
|
||||
|
||||
const expected = { bar: 'baz' };
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate to a correct representation of the object, ignore spread properties', () => {
|
||||
const prop = extractProp('<div foo={{bar: "baz", ...{baz: "bar", foo: {...{bar: "meh"}}}}} />');
|
||||
|
||||
const expected = { bar: 'baz', baz: 'bar', foo: { bar: 'meh' } };
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate to a correct representation of the object, ignore spread properties', () => {
|
||||
const prop = extractProp('<div foo={{ pathname: manageRoute, state: {...data}}} />');
|
||||
|
||||
const expected = { pathname: 'manageRoute', state: {} };
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('New expression', () => {
|
||||
it('should return a new empty object', () => {
|
||||
const prop = extractProp('<div foo={new Bar()} />');
|
||||
|
||||
const expected = {};
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sequence array expression', () => {
|
||||
it('should evaluate to correct representation of the the array in props', () => {
|
||||
const prop = extractProp('<div foo={[{"type":"Literal","start":821,"end":827}]} />');
|
||||
|
||||
const expected = [{
|
||||
type: 'Literal',
|
||||
start: 821,
|
||||
end: 827,
|
||||
}];
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Array expression', () => {
|
||||
it('should evaluate to correct representation of the the array in props', () => {
|
||||
const prop = extractProp('<div foo={["bar", 42, null]} />');
|
||||
|
||||
const expected = ['bar', 42, null];
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('should evaluate to a correct representation of an array with spread elements', () => {
|
||||
const prop = extractProp('<div foo={[...this.props.params, bar]} />');
|
||||
|
||||
const expected = [undefined, 'bar'];
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array provided an empty array in props', () => {
|
||||
const prop = extractProp('<div foo={[]} />');
|
||||
|
||||
const expected = [];
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
describe('Bind expression', () => {
|
||||
it('should return string representation of bind function call when object is null', () => {
|
||||
const prop = extractProp('<div foo={::this.handleClick} />');
|
||||
|
||||
const expected = null;
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of bind function call when object is not null', () => {
|
||||
const prop = extractProp('<div foo={foo::bar} />');
|
||||
|
||||
const expected = 'foo';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of bind function call when binding to object properties', () => {
|
||||
const prop = extractProp('<div foo={a.b::c} />');
|
||||
const otherProp = extractProp('<div foo={::a.b.c} />');
|
||||
|
||||
const expected = 'a.b';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
const otherExpected = null;
|
||||
const otherActual = getPropValue(otherProp);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
assert.deepEqual(otherActual, otherExpected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Type Cast Expression', () => {
|
||||
it('should return the expression from a type cast', () => {
|
||||
const prop = extractProp('<div foo={(this.handleClick: (event: MouseEvent) => void))} />');
|
||||
|
||||
const expected = 'this.handleClick';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
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('<div foo={bar!} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a deep Typescript non-null assertion', () => {
|
||||
const prop = extractProp('<div foo={(bar!)!} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return string representation of variable identifier wrapped in a Typescript type coercion', () => {
|
||||
changePlugins((pls) => [...pls, 'typescript']);
|
||||
const prop = extractProp('<div foo={bar as any} />');
|
||||
|
||||
const expected = 'bar';
|
||||
const actual = getPropValue(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSX empty expression', () => {
|
||||
it('should work with an empty expression', () => {
|
||||
const prop = extractProp('<div>\n{/* Hello there */}\n</div>', 'children');
|
||||
const expected = undefined;
|
||||
const actual = getPropValue(prop);
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
412
web/node_modules/jsx-ast-utils/__tests__/src/hasProp-test.js
generated
vendored
Normal file
412
web/node_modules/jsx-ast-utils/__tests__/src/hasProp-test.js
generated
vendored
Normal file
|
@ -0,0 +1,412 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import { getOpeningElement, setParserName } from '../helper';
|
||||
import hasProp, { hasAnyProp, hasEveryProp } from '../../src/hasProp';
|
||||
|
||||
describe('hasProp', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('babel');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof hasProp;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if no arguments are provided', () => {
|
||||
const expected = false;
|
||||
const actual = hasProp();
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is absent', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the prop exists', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = true;
|
||||
const actual = hasProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the prop may exist in spread loose mode', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
spreadStrict: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = false;
|
||||
const actual = hasProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasAnyProp tests', () => {
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof hasAnyProp;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if no arguments are provided', () => {
|
||||
const expected = false;
|
||||
const actual = hasAnyProp();
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is absent', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasAnyProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are absent in array', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = ['id', 'className'];
|
||||
|
||||
const expected = false;
|
||||
const actual = hasAnyProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are absent in space delimited string', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = 'id className';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasAnyProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the prop exists', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = true;
|
||||
const actual = hasAnyProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if any prop exists in array', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['className', 'id'];
|
||||
|
||||
const expected = true;
|
||||
const actual = hasAnyProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if any prop exists in space delimited string', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'className id';
|
||||
|
||||
const expected = true;
|
||||
const actual = hasAnyProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the prop may exist in spread loose mode', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
spreadStrict: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasAnyProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if any prop may exist in spread loose mode', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['id', 'className'];
|
||||
const options = {
|
||||
spreadStrict: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasAnyProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = false;
|
||||
const actual = hasAnyProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['id', 'iD', 'className'];
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = false;
|
||||
const actual = hasAnyProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasEveryProp tests', () => {
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof hasEveryProp;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if no arguments are provided', () => {
|
||||
const expected = true;
|
||||
const actual = hasEveryProp();
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is absent', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if any props are absent in array', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = ['id', 'className'];
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are absent in array', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = ['id', 'className'];
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if any props are absent in space delimited string', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = 'id className';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are absent in space delimited string', () => {
|
||||
const code = '<div />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const propsToCheck = 'id className';
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, propsToCheck);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the prop exists', () => {
|
||||
const code = '<div id="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if all props exist in array', () => {
|
||||
const code = '<div id="foo" className="box" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['className', 'id'];
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if all props exist in space delimited string', () => {
|
||||
const code = '<div id="foo" className="box" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'className id';
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if the props may exist in spread loose mode', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
spreadStrict: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if all props may exist in spread loose mode', () => {
|
||||
const code = '<div {...props} />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['id', 'className'];
|
||||
const options = {
|
||||
spreadStrict: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if the prop is considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = 'id';
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return false if all props are considered absent in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['id', 'iD', 'className'];
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = false;
|
||||
const actual = hasEveryProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return true if all props are considered present in case-sensitive mode', () => {
|
||||
const code = '<div ID="foo" className="box" />';
|
||||
const node = getOpeningElement(code);
|
||||
const { attributes: props } = node;
|
||||
const prop = ['ID', 'className'];
|
||||
const options = {
|
||||
ignoreCase: false,
|
||||
};
|
||||
|
||||
const expected = true;
|
||||
const actual = hasEveryProp(props, prop, options);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
35
web/node_modules/jsx-ast-utils/__tests__/src/index-test.js
generated
vendored
Normal file
35
web/node_modules/jsx-ast-utils/__tests__/src/index-test.js
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* eslint-env mocha */
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import assert from 'assert';
|
||||
import core from '../../src/index';
|
||||
|
||||
const src = fs.readdirSync(path.resolve(__dirname, '../../src'))
|
||||
.filter((f) => f.indexOf('.js') >= 0)
|
||||
.map((f) => path.basename(f, '.js'));
|
||||
|
||||
describe('main export', () => {
|
||||
it('should export an object', () => {
|
||||
const expected = 'object';
|
||||
const actual = typeof core;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
src.filter((f) => f !== 'index').forEach((f) => {
|
||||
it(`should export ${f}`, () => {
|
||||
assert.equal(
|
||||
core[f],
|
||||
require(path.join('../../src/', f)).default // eslint-disable-line
|
||||
);
|
||||
});
|
||||
|
||||
it(`should export ${f} from root`, () => {
|
||||
const file = `${f}.js`;
|
||||
const expected = true;
|
||||
const actual = fs.statSync(path.join(path.resolve('.'), file)).isFile();
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
42
web/node_modules/jsx-ast-utils/__tests__/src/propName-test.js
generated
vendored
Normal file
42
web/node_modules/jsx-ast-utils/__tests__/src/propName-test.js
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* eslint-env mocha */
|
||||
import assert from 'assert';
|
||||
import { extractProp, setParserName } from '../helper';
|
||||
import propName from '../../src/propName';
|
||||
|
||||
describe('propName', () => {
|
||||
beforeEach(() => {
|
||||
setParserName('babel');
|
||||
});
|
||||
it('should export a function', () => {
|
||||
const expected = 'function';
|
||||
const actual = typeof propName;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should throw an error if the argument is missing', () => {
|
||||
assert.throws(() => { propName(); }, Error);
|
||||
});
|
||||
|
||||
it('should throw an error if the argument not a JSX node', () => {
|
||||
assert.throws(() => { propName({ a: 'foo' }); }, Error);
|
||||
});
|
||||
|
||||
it('should return correct name for normal prop', () => {
|
||||
const prop = extractProp('<div foo="bar" />');
|
||||
|
||||
const expected = 'foo';
|
||||
const actual = propName(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
it('should return correct name for namespaced prop', () => {
|
||||
const prop = extractProp('<div foo:bar="baz" />', 'foo:bar');
|
||||
|
||||
const expected = 'foo:bar';
|
||||
const actual = propName(prop);
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue