Ajout de promotion et de commande

This commit is contained in:
Aubert Marvin
2026-04-25 15:28:39 +02:00
parent eddb103755
commit faa3d7718c
8428 changed files with 1126442 additions and 6 deletions
+93
View File
@@ -0,0 +1,93 @@
/* 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];
let isESM = false;
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');
}
}
export function setIsESM() {
isESM = true;
}
beforeEach(() => {
plugins = [...defaultPlugins];
isESM = false;
});
function parse(code) {
if (parserName === undefined) {
throw new Error('No parser specified');
}
if (parserName === 'babel') {
try {
return babelParser.parse(code, { plugins, sourceFilename: 'test.js', ...(isESM && { sourceType: 'module' }) });
} 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;
+118
View File
@@ -0,0 +1,118 @@
/* eslint-env mocha */
import assert from 'assert';
import { getOpeningElement, setParserName, describeIfNotBabylon } 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);
});
describeIfNotBabylon('fragments', () => {
it('should work with fragments', () => {
const code = '<>foo</>';
const node = getOpeningElement(code);
const expected = '<>';
const actual = elementType(node);
assert.equal(actual, expected);
});
it('works with nested fragments', () => {
const code = `
<Hello
role="checkbox"
frag={
<>
<div>Hello</div>
<>
<div>There</div>
</>
</>
}
/>
`;
const node = getOpeningElement(code);
const expected = 'Hello';
const actual = elementType(node);
assert.equal(actual, expected);
});
});
});
+101
View 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
View 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
View 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);
});
});
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+412
View 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
View 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
View 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);
});
});