12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277 |
- /* eslint-env mocha */
- /* eslint no-template-curly-in-string: 0 */
- import assert from 'assert';
- import {
- extractProp,
- changePlugins,
- fallbackToBabylon,
- describeIfNotBabylon,
- setParserName,
- } from '../helper';
- import getPropValue from '../../src/getPropValue';
- describe('getPropValue', () => {
- beforeEach(() => {
- setParserName('babel');
- });
- 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 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 = 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);
- });
- it('should return correct representation of JSX element with children as a string', () => {
- const prop = extractProp('<div foo={<bar><baz />foo</bar>} />');
- const expected = '<bar><baz />foo</bar>';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- });
- (fallbackToBabylon ? describe.skip : describe)('JSXFragment', () => {
- it('should return correct representation of JSX fragment as a string', () => {
- const prop = extractProp('<div foo={<></>} />');
- const expected = '<></>';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return correct representation of JSX fragment with children as a string', () => {
- const prop = extractProp('<div foo={<><div />abc</>} />');
- const expected = '<><div />abc</>';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('supports a prop value containing nested fragments', () => {
- const propCode = `
- <>
- <div>Hello</div>
- <>
- <div>There</div>
- </>
- </>
- `;
- const code = `
- <Hello
- role="checkbox"
- frag={${propCode}}
- />
- `;
- const prop = extractProp(code, 'frag');
- const actual = getPropValue(prop);
- assert.deepEqual(actual, propCode.trim());
- });
- });
- 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);
- });
- it('should correctly infer result of ?? logical expression based on derived values', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={bar ?? baz} />');
- const expected = 'bar';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should correctly infer result of ?? logical expression based on derived values', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={undefined ?? baz} />');
- const expected = 'baz';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should return undefined when evaluating `undefined ?? undefined` ', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={undefined ?? undefined} />');
- const expected = undefined;
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should return undefined when evaluating `null ?? undefined` ', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={null ?? undefined} />');
- const expected = undefined;
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should return undefined when evaluating `undefined ?? null` ', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={undefined ?? null} />');
- const expected = null;
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should return null when evaluating `null ?? null` ', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={null ?? null} />');
- const expected = null;
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- });
- 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 runTest = () => {
- const prop = extractProp('<div foo={bar?.baz} />');
- const expected = 'bar?.baz';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- it('should evaluate to a correct representation of optional call expression', () => {
- const runTest = () => {
- const prop = extractProp('<div foo={bar.baz?.(quux)} />');
- const expected = 'bar.baz?.(quux)';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- };
- if (fallbackToBabylon) {
- // eslint-disable-next-line no-undef
- expect(runTest).toThrow();
- } else {
- runTest();
- }
- });
- });
- 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('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, undefined, 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 = 'this.handleClick.bind(this)';
- 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 = 'bar.bind(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.c.bind(a.b)';
- const actual = getPropValue(prop);
- const otherExpected = 'a.b.c.bind(a.b)';
- const otherActual = getPropValue(otherProp);
- assert.deepEqual(actual, expected);
- assert.deepEqual(otherExpected, otherActual);
- });
- });
- describe('Type Cast Expression', () => {
- it('should throw a parsing error', () => {
- let counter = 0;
- // eslint-disable-next-line no-console
- const warnOrig = console.warn;
- // eslint-disable-next-line no-console
- console.warn = () => {
- counter += 1;
- };
- // eslint-disable-next-line no-undef
- expect(() => {
- extractProp('<div foo={(this.handleClick: (event: MouseEvent) => void))} />');
- }).toThrow();
- assert.equal(counter, 1);
- // eslint-disable-next-line no-console
- console.warn = warnOrig;
- });
- });
- describe('AssignmentExpression', () => {
- it('should recognize and extract assignment', () => {
- const prop = extractProp('<div foo={foo = bar} />');
- const expected = 'foo = bar';
- const actual = getPropValue(prop);
- assert.deepEqual(actual, expected);
- });
- it('should recognize and extract combination assignments', () => {
- const prop = extractProp('<div foo={foo += bar} />');
- const expected = 'foo += bar';
- 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', () => {
- const prop = extractProp('<div foo={bar as any} />');
- const expected = 'bar';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- });
- describeIfNotBabylon('TSNonNullExpression', () => {
- beforeEach(() => {
- changePlugins((pls) => [...pls, 'typescript']);
- });
- it('should return string representation of a TSNonNullExpression of form `variable!`', () => {
- const prop = extractProp('<div foo={bar!} />');
- const expected = 'bar!';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `object!.property`', () => {
- const prop = extractProp('<div foo={bar!.bar} />');
- const expected = 'bar!.bar';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `function()!.property`', () => {
- const prop = extractProp('<div foo={bar()!.bar} />');
- const expected = 'bar()!.bar';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `object!.property!`', () => {
- const prop = extractProp('<div foo={bar!.bar!} />');
- const actual = getPropValue(prop);
- const expected = 'bar!.bar!';
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `object.property!`', () => {
- const prop = extractProp('<div foo={bar.bar!} />');
- const actual = getPropValue(prop);
- const expected = 'bar.bar!';
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `object.property.property!`', () => {
- const prop = extractProp('<div foo={bar.bar.bar!} />');
- const actual = getPropValue(prop);
- const expected = 'bar.bar.bar!';
- assert.equal(actual, expected);
- });
- it('should return string representation of a TSNonNullExpression of form `object!.property.property!`', () => {
- const prop = extractProp('<div foo={bar!.bar.bar!} />');
- const actual = getPropValue(prop);
- const expected = 'bar!.bar.bar!';
- assert.equal(actual, expected);
- });
- it('should return string representation of an object wrapped in a deep Typescript non-null assertion', () => {
- const prop = extractProp('<div foo={(bar!.bar)!} />');
- const expected = '(bar!.bar)!';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return string representation of a cast wrapped in a deep Typescript non-null assertion', () => {
- const prop = extractProp('<div foo={(bar as Bar).baz!} />');
- const actual = getPropValue(prop);
- const expected = 'bar.baz!';
- assert.equal(actual, expected);
- });
- it('should return string representation of an object wrapped in a deep Typescript non-null assertion', () => {
- const prop = extractProp('<div foo={(bar.bar)!} />');
- const expected = '(bar.bar)!';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should return string representation of an object wrapped in a deep Typescript non-null assertion', () => {
- const prop = extractProp('<div foo={(bar!.bar.bar!)!} />');
- const expected = '(bar!.bar.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 work with a this.props value', () => {
- const prop = extractProp('<a foo={this.props.href!}>Download</a>');
- const expected = 'this.props.href!';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('should correctly evaluate a bracketed navigation expression that prefixes with !', () => {
- const prop = extractProp('<Link foo={data![0].url} />');
- const expected = 'data![0].url';
- const actual = getPropValue(prop);
- assert.equal(actual, expected);
- });
- it('works with an optional chain with an `as`', () => {
- const prop = extractProp('<img src={images?.footer as string} />', 'src');
- const expected = 'images?.footer';
- const actual = getPropValue(prop, 'src');
- 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);
- });
- });
- });
|