From 4b714f8941351ea9f902cbfff05a92d600fdd284 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Thu, 15 Jun 2023 10:51:30 +0200 Subject: [PATCH 1/2] Use test cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using test cases provides a better DX. - It allows running multiple tests - It shows which failed / succeeded - It enables test filtering - Assertion messages hid diffs in `node:test` A describe block was added for the function that’s being tested. --- test.js | 2391 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 1199 insertions(+), 1192 deletions(-) diff --git a/test.js b/test.js index 7428110..37642b8 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import assert from 'node:assert/strict' -import test from 'node:test' +import {describe, test} from 'node:test' import {Parser} from 'acorn' import jsx from 'acorn-jsx' import {walk} from 'estree-walker' @@ -11,16 +11,13 @@ import * as mod from './index.js' const parser = Parser.extend(jsx()) -test('buildJsx', () => { - assert.deepEqual( - Object.keys(mod).sort(), - ['buildJsx'], - 'should expose the public api' - ) +test('should expose the public api', () => { + assert.deepEqual(Object.keys(mod).sort(), ['buildJsx']) +}) - assert.deepEqual( - expression(buildJsx(parse('<>'))), - { +describe('buildJsx', () => { + test('should default to `React.createElement` / `React.Fragment`', () => { + assert.deepEqual(expression(buildJsx(parse('<>'))), { type: 'CallExpression', callee: { type: 'MemberExpression', @@ -52,33 +49,32 @@ test('buildJsx', () => { } ], optional: false - }, - 'should default to `React.createElement` / `React.Fragment`' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse('<>'), {pragma: 'a', pragmaFrag: 'b'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [ - {type: 'Identifier', name: 'b'}, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [{type: 'Literal', value: 'x'}], - optional: false - } - ], - optional: false - }, - 'should support `pragma`, `pragmaFrag`' - ) + test('should support `pragma`, `pragmaFrag`', () => { + assert.deepEqual( + expression(buildJsx(parse('<>'), {pragma: 'a', pragmaFrag: 'b'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [ + {type: 'Identifier', name: 'b'}, + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [{type: 'Literal', value: 'x'}], + optional: false + } + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'a.b-c'})), - { + test('should support `pragma` w/ non-identifiers (1)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'a.b-c'})), { type: 'CallExpression', callee: { type: 'MemberExpression', @@ -89,71 +85,63 @@ test('buildJsx', () => { }, arguments: [{type: 'Literal', value: 'x'}], optional: false - }, - 'should support `pragma` w/ non-identifiers (1)' - ) - - assert.equal( - generate(buildJsx(parse(''), {pragma: 'a.b-c'})), - 'a["b-c"]("x");\n', - 'should support `pragma` w/ non-identifiers (2)' - ) - - assert.deepEqual( - expression(buildJsx(parse('/* @jsx a @jsxFrag b */\n<>'))), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [ - {type: 'Identifier', name: 'b'}, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [{type: 'Literal', value: 'x'}], - optional: false - } - ], - optional: false - }, - 'should support `@jsx`, `@jsxFrag` comments' - ) + }) + }) + + test('should support `pragma` w/ non-identifiers (2)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'a.b-c'})), + 'a["b-c"]("x");\n' + ) + }) + + test('should support `@jsx`, `@jsxFrag` comments', () => { + assert.deepEqual( + expression(buildJsx(parse('/* @jsx a @jsxFrag b */\n<>'))), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [ + {type: 'Identifier', name: 'b'}, + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [{type: 'Literal', value: 'x'}], + optional: false + } + ], + optional: false + } + ) + }) - assert.throws( - () => { + test('should throw when `@jsx` is set in the automatic runtime', () => { + assert.throws(() => { buildJsx(parse('/* @jsx a @jsxRuntime automatic */')) - }, - /Unexpected `@jsx` pragma w\/ automatic runtime/, - 'should throw when `@jsx` is set in the automatic runtime' - ) + }, /Unexpected `@jsx` pragma w\/ automatic runtime/) + }) - assert.throws( - () => { + test('should throw when `@jsxFrag` is set in the automatic runtime', () => { + assert.throws(() => { buildJsx(parse('/* @jsxFrag a @jsxRuntime automatic */')) - }, - /Unexpected `@jsxFrag` pragma w\/ automatic runtime/, - 'should throw when `@jsxFrag` is set in the automatic runtime' - ) + }, /Unexpected `@jsxFrag` pragma w\/ automatic runtime/) + }) - assert.throws( - () => { + test('should throw when `@jsxImportSource` is set in the classic runtime', () => { + assert.throws(() => { buildJsx(parse('/* @jsxImportSource a @jsxRuntime classic */')) - }, - /Unexpected `@jsxImportSource` w\/ classic runtime/, - 'should throw when `@jsxImportSource` is set in the classic runtime' - ) + }, /Unexpected `@jsxImportSource` w\/ classic runtime/) + }) - assert.throws( - () => { + test('should throw on a non-automatic nor classic `@jsxRuntime`', () => { + assert.throws(() => { buildJsx(parse('/* @jsxRuntime a */')) - }, - /Unexpected `jsxRuntime` `a`, expected `automatic` or `classic`/, - 'should throw on a non-automatic nor classic `@jsxRuntime`' - ) - - assert.deepEqual( - expression(buildJsx(parse('// a\n<>'))), - { + }, /Unexpected `jsxRuntime` `a`, expected `automatic` or `classic`/) + }) + + test('should ignore other comments', () => { + assert.deepEqual(expression(buildJsx(parse('// a\n<>'))), { type: 'CallExpression', callee: { type: 'MemberExpression', @@ -185,24 +173,20 @@ test('buildJsx', () => { } ], optional: false - }, - 'should ignore other comments' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support a self-closing element', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [{type: 'Literal', value: 'a'}], optional: false - }, - 'should support a self-closing element' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse('b'), {pragma: 'h'})), - { + test('should support a closed element', () => { + assert.deepEqual(expression(buildJsx(parse('b'), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -211,13 +195,11 @@ test('buildJsx', () => { {type: 'Literal', value: 'b'} ], optional: false - }, - 'should support a closed element' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support dots in a tag name for member expressions', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -230,13 +212,11 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support dots in a tag name for member expressions' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support dots *and* dashes in tag names (1)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -249,19 +229,18 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support dots *and* dashes in tag names (1)' - ) - - assert.equal( - generate(buildJsx(parse(''), {pragma: 'h'})), - 'h(a["b-c"]);\n', - 'should support dots *and* dashes in tag names (2)' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + }) + }) + + test('should support dots *and* dashes in tag names (2)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'h'})), + 'h(a["b-c"]);\n' + ) + }) + + test('should support dots *and* dashes in tag names (3)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -274,83 +253,77 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support dots *and* dashes in tag names (3)' - ) - - assert.equal( - generate(buildJsx(parse(''), {pragma: 'h'})), - 'h(("a-b").c);\n', - 'should support dots *and* dashes in tag names (4)' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - { - type: 'MemberExpression', - object: { + }) + }) + + test('should support dots *and* dashes in tag names (4)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'h'})), + 'h(("a-b").c);\n' + ) + }) + + test('should support dots in a tag name for member expressions (2)', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + { type: 'MemberExpression', object: { type: 'MemberExpression', - object: {type: 'Identifier', name: 'a'}, - property: {type: 'Identifier', name: 'b'}, + object: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'a'}, + property: {type: 'Identifier', name: 'b'}, + computed: false, + optional: false + }, + property: {type: 'Identifier', name: 'c'}, computed: false, optional: false }, - property: {type: 'Identifier', name: 'c'}, + property: {type: 'Identifier', name: 'd'}, computed: false, optional: false - }, - property: {type: 'Identifier', name: 'd'}, - computed: false, - optional: false - } - ], - optional: false - }, - 'should support dots in a tag name for member expressions (2)' - ) + } + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support colons in a tag name for namespaces', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [{type: 'Literal', value: 'a:b'}], optional: false - }, - 'should support colons in a tag name for namespaces' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support dashes in tag names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [{type: 'Literal', value: 'a-b'}], optional: false - }, - 'should support dashes in tag names' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should non-lowercase for components in tag names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [{type: 'Identifier', name: 'A'}], optional: false - }, - 'should non-lowercase for components in tag names' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support a boolean prop', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -371,13 +344,11 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support a boolean prop' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support colons in prop names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -398,13 +369,11 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support colons in prop names' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support a prop name that can’t be an identifier', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -425,579 +394,608 @@ test('buildJsx', () => { } ], optional: false - }, - 'should support a prop name that can’t be an identifier' - ) + }) + }) + + test('should support a prop value', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 'c'}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ) + }) + + test('should support an expression as a prop value', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Identifier', name: 'c'}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ) + }) + + test('should support an expression as a prop value (2)', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 1}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ) + }) + + test('should support a fragment as a prop value', () => { + assert.deepEqual( + expression( + buildJsx(parse('c />'), {pragma: 'h', pragmaFrag: 'f'}) + ), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Identifier', name: 'f'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'c'} + ], + optional: false + }, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ) + }) + + test('should support an element as a prop value', () => { + assert.deepEqual( + expression(buildJsx(parse(' />'), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'c'}], + optional: false + }, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ) + }) + + test('should support a single spread prop', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Identifier', name: 'b'} + ], + optional: false + } + ) + }) + + test('should support a spread prop and another prop', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + {type: 'ObjectExpression', properties: []}, + {type: 'Identifier', name: 'b'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'c'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false + } + ], + optional: false + } + ) + }) + + test('should support a prop and a spread prop', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + }, + {type: 'Identifier', name: 'c'} + ], + optional: false + } + ], + optional: false + } + ) + }) + + test('should support two spread props', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + {type: 'ObjectExpression', properties: []}, + {type: 'Identifier', name: 'b'}, + {type: 'Identifier', name: 'c'} + ], + optional: false + } + ], + optional: false + } + ) + }) + + test('should support more complex spreads', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 1}, + kind: 'init' + }, + { + type: 'SpreadElement', + argument: {type: 'Identifier', name: 'c'} + }, + { + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: {type: 'Identifier', name: 'd'}, + value: {type: 'Literal', value: 2}, + kind: 'init' + } + ] + } + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support expressions content', () => { + assert.deepEqual(expression(buildJsx(parse('{1}'), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 'c'}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } + {type: 'Literal', value: null}, + {type: 'Literal', value: 1} ], optional: false - }, - 'should support a prop value' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support empty expressions content', () => { + assert.deepEqual(expression(buildJsx(parse('{}'), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Identifier', name: 'c'}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], + arguments: [{type: 'Literal', value: 'a'}], optional: false - }, - 'should support an expression as a prop value' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { + test('should support initial spaces in content', () => { + assert.deepEqual(expression(buildJsx(parse(' b'), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 1}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b'} ], optional: false - }, - 'should support an expression as a prop value (2)' - ) - - assert.deepEqual( - expression( - buildJsx(parse('c />'), {pragma: 'h', pragmaFrag: 'f'}) - ), - { + }) + }) + + test('should support final spaces in content', () => { + assert.deepEqual(expression(buildJsx(parse('b '), {pragma: 'h'})), { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Identifier', name: 'f'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'c'} - ], - optional: false - }, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } + {type: 'Literal', value: null}, + {type: 'Literal', value: 'b '} ], optional: false - }, - 'should support a fragment as a prop value' - ) + }) + }) - assert.deepEqual( - expression(buildJsx(parse(' />'), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'c'}], - optional: false - }, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - }, - 'should support an element as a prop value' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Identifier', name: 'b'} - ], - optional: false - }, - 'should support a single spread prop' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - {type: 'ObjectExpression', properties: []}, - {type: 'Identifier', name: 'b'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'c'}, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ], - optional: false - }, - 'should support a spread prop and another prop' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - }, - {type: 'Identifier', name: 'c'} - ], - optional: false - } - ], - optional: false - }, - 'should support a prop and a spread prop' - ) - - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - {type: 'ObjectExpression', properties: []}, - {type: 'Identifier', name: 'b'}, - {type: 'Identifier', name: 'c'} - ], - optional: false - } - ], - optional: false - }, - 'should support two spread props' - ) + test('should support initial and final spaces in content', () => { + assert.deepEqual( + expression(buildJsx(parse(' b '), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b '} + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 1}, - kind: 'init' - }, - {type: 'SpreadElement', argument: {type: 'Identifier', name: 'c'}}, - { - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: {type: 'Identifier', name: 'd'}, - value: {type: 'Literal', value: 2}, - kind: 'init' - } - ] - } - ], - optional: false - }, - 'should support more complex spreads' - ) + test('should support spaces around line endings', () => { + assert.deepEqual( + expression(buildJsx(parse(' b \r c \n d \n '), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b c d'} + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse('{1}'), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 1} - ], - optional: false - }, - 'should support expressions content' - ) + test('should support skip empty or whitespace only line endings', () => { + assert.deepEqual( + expression( + buildJsx(parse(' b \r \n c \n\n d \n '), {pragma: 'h'}) + ), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b c d'} + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse('{}'), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a'}], - optional: false - }, - 'should support empty expressions content' - ) + test('should support skip whitespace only content', () => { + assert.deepEqual( + expression(buildJsx(parse(' \t\n '), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'a'}], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(' b'), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b'} - ], - optional: false - }, - 'should support initial spaces in content' - ) + test('should trim strings with leading line feed', () => { + assert.deepEqual( + expression( + buildJsx(parse(['', ' line1', ''].join('\n')), {pragma: 'h'}) + ), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'line1'} + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse('b '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'b '} - ], - optional: false - }, - 'should support final spaces in content' - ) + test('should trim strings with leading line feed (multiline test)', () => { + assert.deepEqual( + expression( + buildJsx(parse(['', ' line1{" "}', ' line2', ''].join('\n')), { + pragma: 'h' + }) + ), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'line1'}, + {type: 'Literal', value: ' '}, + {type: 'Literal', value: 'line2'} + ], + optional: false + } + ) + }) - assert.deepEqual( - expression(buildJsx(parse(' b '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b '} - ], - optional: false - }, - 'should support initial and final spaces in content' - ) + test('should integrate w/ generators (`astring`)', () => { + assert.equal( + generate( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ), + 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));\n' + ) + }) - assert.deepEqual( - expression(buildJsx(parse(' b \r c \n d \n '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b c d'} - ], - optional: false - }, - 'should support spaces around line endings' - ) + test('should integrate w/ generators (`recast`)', () => { + assert.equal( + recast.print( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ).code, + 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));' + ) + }) - assert.deepEqual( - expression(buildJsx(parse(' b \r \n c \n\n d \n '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b c d'} - ], - optional: false - }, - 'should support skip empty or whitespace only line endings' - ) + test('should integrate w/ generators (`escodegen`)', () => { + assert.equal( + escodegen.generate( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ), + "h(f, null, h('a', Object.assign({\n b: true,\n c: 'd',\n e: f\n}, g), 'h'));" + ) + }) - assert.deepEqual( - expression(buildJsx(parse(' \t\n '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a'}], - optional: false - }, - 'should support skip whitespace only content' - ) - - assert.deepEqual( - expression( - buildJsx(parse(['', ' line1', ''].join('\n')), {pragma: 'h'}) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'line1'} - ], - optional: false - }, - 'should trim strings with leading line feed' - ) - - assert.deepEqual( - expression( - buildJsx(parse(['', ' line1{" "}', ' line2', ''].join('\n')), { - pragma: 'h' - }) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'line1'}, - {type: 'Literal', value: ' '}, - {type: 'Literal', value: 'line2'} - ], - optional: false - }, - 'should trim strings with leading line feed (multiline test)' - ) - - assert.equal( - generate( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ), - 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));\n', - 'should integrate w/ generators (`astring`)' - ) - - assert.equal( - recast.print( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ).code, - 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));', - 'should integrate w/ generators (`recast`)' - ) - - assert.equal( - escodegen.generate( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ), - "h(f, null, h('a', Object.assign({\n b: true,\n c: 'd',\n e: f\n}, g), 'h'));", - 'should integrate w/ generators (`escodegen`)' - ) - - assert.deepEqual( - buildJsx(parse('<>\n h\n', false)), - { - type: 'Program', - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38], - body: [ - { - type: 'ExpressionStatement', - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38], - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, - computed: false, - optional: false - }, - arguments: [ - { + test('should support positional info', () => { + assert.deepEqual( + buildJsx(parse('<>\n h\n', false)), + { + type: 'Program', + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38], + body: [ + { + type: 'ExpressionStatement', + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38], + expression: { + type: 'CallExpression', + callee: { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'Fragment'}, + property: {type: 'Identifier', name: 'createElement'}, computed: false, optional: false }, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: { + arguments: [ + { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + property: {type: 'Identifier', name: 'Fragment'}, computed: false, optional: false }, - arguments: [ - { - type: 'Literal', - value: 'a', - start: 6, - end: 7, - loc: { - start: {line: 2, column: 3}, - end: {line: 2, column: 4} - }, - range: [6, 7] + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false }, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false + arguments: [ + { + type: 'Literal', + value: 'a', + start: 6, + end: 7, + loc: { + start: {line: 2, column: 3}, + end: {line: 2, column: 4} + }, + range: [6, 7] }, - arguments: [ - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: { - type: 'Identifier', - name: 'b', + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: { + type: 'Identifier', + name: 'b', + start: 8, + end: 9, + loc: { + start: {line: 2, column: 5}, + end: {line: 2, column: 6} + }, + range: [8, 9] + }, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false, start: 8, end: 9, loc: { @@ -1006,143 +1004,132 @@ test('buildJsx', () => { }, range: [8, 9] }, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false, - start: 8, - end: 9, - loc: { - start: {line: 2, column: 5}, - end: {line: 2, column: 6} - }, - range: [8, 9] - }, - { - type: 'Property', - key: { - type: 'Identifier', - name: 'c', - start: 10, - end: 11, - loc: { - start: {line: 2, column: 7}, - end: {line: 2, column: 8} + { + type: 'Property', + key: { + type: 'Identifier', + name: 'c', + start: 10, + end: 11, + loc: { + start: {line: 2, column: 7}, + end: {line: 2, column: 8} + }, + range: [10, 11] }, - range: [10, 11] - }, - value: { - type: 'Literal', - start: 12, + value: { + type: 'Literal', + start: 12, + end: 15, + loc: { + start: {line: 2, column: 9}, + end: {line: 2, column: 12} + }, + range: [12, 15], + value: 'd' + }, + kind: 'init', + method: false, + shorthand: false, + computed: false, + start: 10, end: 15, loc: { - start: {line: 2, column: 9}, + start: {line: 2, column: 7}, end: {line: 2, column: 12} }, - range: [12, 15], - value: 'd' - }, - kind: 'init', - method: false, - shorthand: false, - computed: false, - start: 10, - end: 15, - loc: { - start: {line: 2, column: 7}, - end: {line: 2, column: 12} + range: [10, 15] }, - range: [10, 15] - }, - { - type: 'Property', - key: { - type: 'Identifier', - name: 'e', + { + type: 'Property', + key: { + type: 'Identifier', + name: 'e', + start: 16, + end: 17, + loc: { + start: {line: 2, column: 13}, + end: {line: 2, column: 14} + }, + range: [16, 17] + }, + value: { + type: 'Identifier', + start: 19, + end: 20, + loc: { + start: {line: 2, column: 16}, + end: {line: 2, column: 17} + }, + range: [19, 20], + name: 'f' + }, + kind: 'init', + method: false, + shorthand: false, + computed: false, start: 16, - end: 17, + end: 21, loc: { start: {line: 2, column: 13}, - end: {line: 2, column: 14} - }, - range: [16, 17] - }, - value: { - type: 'Identifier', - start: 19, - end: 20, - loc: { - start: {line: 2, column: 16}, - end: {line: 2, column: 17} + end: {line: 2, column: 18} }, - range: [19, 20], - name: 'f' - }, - kind: 'init', - method: false, - shorthand: false, - computed: false, - start: 16, - end: 21, - loc: { - start: {line: 2, column: 13}, - end: {line: 2, column: 18} - }, - range: [16, 21] - } - ] - }, - { - type: 'Identifier', - start: 26, - end: 27, - loc: { - start: {line: 2, column: 23}, - end: {line: 2, column: 24} + range: [16, 21] + } + ] }, - range: [26, 27], - name: 'g' - } - ], - optional: false - }, - { - type: 'Literal', - value: 'h', - start: 29, - end: 30, - loc: { - start: {line: 2, column: 26}, - end: {line: 2, column: 27} + { + type: 'Identifier', + start: 26, + end: 27, + loc: { + start: {line: 2, column: 23}, + end: {line: 2, column: 24} + }, + range: [26, 27], + name: 'g' + } + ], + optional: false }, - range: [29, 30] - } - ], - optional: false, - start: 5, - end: 34, - loc: {start: {line: 2, column: 2}, end: {line: 2, column: 31}}, - range: [5, 34] - } - ], - optional: false, - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38] + { + type: 'Literal', + value: 'h', + start: 29, + end: 30, + loc: { + start: {line: 2, column: 26}, + end: {line: 2, column: 27} + }, + range: [29, 30] + } + ], + optional: false, + start: 5, + end: 34, + loc: { + start: {line: 2, column: 2}, + end: {line: 2, column: 31} + }, + range: [5, 34] + } + ], + optional: false, + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38] + } } - } - ], - sourceType: 'script', - comments: [] - }, - 'should support positional info' - ) - - assert.deepEqual( - buildJsx(parse('<>', true, false)), - { + ], + sourceType: 'script', + comments: [] + } + ) + }) + + test('should support no comments on `program`', () => { + assert.deepEqual(buildJsx(parse('<>', true, false)), { type: 'Program', body: [ { @@ -1183,354 +1170,374 @@ test('buildJsx', () => { } ], sourceType: 'script' - }, - 'should support no comments on `program`' - ) - - assert.deepEqual( - generate(buildJsx(parse('<>a'), {runtime: 'automatic'})), - [ - 'import {Fragment as _Fragment, jsx as _jsx} from "react/jsx-runtime";', - '_jsx(_Fragment, {', - ' children: "a"', - '});', - '' - ].join('\n'), - 'should support the automatic runtime (fragment, jsx, settings)' - ) - - assert.deepEqual( - generate(buildJsx(parse('/*@jsxRuntime automatic*/\nb{1}'))), - [ - 'import {jsxs as _jsxs} from "react/jsx-runtime";', - '_jsxs("a", {', - ' children: ["b", 1]', - '}, "a");', - '' - ].join('\n'), - 'should support the automatic runtime (jsxs, key, comment)' - ) - - assert.deepEqual( - generate(buildJsx(parse('d'), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", Object.assign({', - ' b: "1"', - '}, c, {', - ' children: "d"', - '}));', - '' - ].join('\n'), - 'should support the automatic runtime (props, spread, children)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('f'), { - runtime: 'automatic' - }) - ), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", Object.assign({', - ' b: 1,', - ' c: 2', - '}, {', - ' d: "e",', - ' children: "f"', - '}));', - '' - ].join('\n'), - 'should support the automatic runtime (spread, props, children)' - ) - - assert.deepEqual( - generate(buildJsx(parse('b'), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {', - ' children: "b"', - '});', - '' - ].join('\n'), - 'should support the automatic runtime (no props, children)' - ) - - assert.deepEqual( - generate(buildJsx(parse(''), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {});', - '' - ].join('\n'), - 'should support the automatic runtime (no props, no children)' - ) - - assert.deepEqual( - generate(buildJsx(parse(''), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {}, true);', - '' - ].join('\n'), - 'should support the automatic runtime (key, no props, no children)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('<>a', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {Fragment as _Fragment, jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV(_Fragment, {', - ' children: "a"', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (fragment, jsx, settings, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('b{1}', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: ["b", 1]', - '}, "a", true, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (jsxs, key, comment, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('d', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", Object.assign({', - ' b: "1"', - '}, c, {', - ' children: "d"', - '}), undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (props, spread, children, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('f', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", Object.assign({', - ' b: 1,', - ' c: 2', - '}, {', - ' d: "e",', - ' children: "f"', - '}), undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (spread, props, children, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('b', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: "b"', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, children, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, no children, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, true, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (key, no props, no children, development)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, no children, development, no filePath)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: '' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, no children, development, empty filePath)' - ) - - assert.deepEqual( - generate( - buildJsx(parse(''), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "index.js"', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, no children, development, no locations)' - ) - - assert.deepEqual( - generate( - buildJsx(parse('\n \n', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: _jsxDEV("b", {}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 2,', - ' columnNumber: 3', - ' }, this)', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n'), - 'should support the automatic runtime (no props, nested children, development, positional info)' - ) - - assert.throws( - () => { + }) + }) + + test('should support the automatic runtime (fragment, jsx, settings)', () => { + assert.deepEqual( + generate(buildJsx(parse('<>a'), {runtime: 'automatic'})), + [ + 'import {Fragment as _Fragment, jsx as _jsx} from "react/jsx-runtime";', + '_jsx(_Fragment, {', + ' children: "a"', + '});', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (jsxs, key, comment)', () => { + assert.deepEqual( + generate( + buildJsx(parse('/*@jsxRuntime automatic*/\nb{1}')) + ), + [ + 'import {jsxs as _jsxs} from "react/jsx-runtime";', + '_jsxs("a", {', + ' children: ["b", 1]', + '}, "a");', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (props, spread, children)', () => { + assert.deepEqual( + generate( + buildJsx(parse('d'), {runtime: 'automatic'}) + ), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", Object.assign({', + ' b: "1"', + '}, c, {', + ' children: "d"', + '}));', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (spread, props, children)', () => { + assert.deepEqual( + generate( + buildJsx(parse('f'), { + runtime: 'automatic' + }) + ), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", Object.assign({', + ' b: 1,', + ' c: 2', + '}, {', + ' d: "e",', + ' children: "f"', + '}));', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, children)', () => { + assert.deepEqual( + generate(buildJsx(parse('b'), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {', + ' children: "b"', + '});', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, no children)', () => { + assert.deepEqual( + generate(buildJsx(parse(''), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {});', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (key, no props, no children)', () => { + assert.deepEqual( + generate(buildJsx(parse(''), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {}, true);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (fragment, jsx, settings, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('<>a', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {Fragment as _Fragment, jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV(_Fragment, {', + ' children: "a"', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (jsxs, key, comment, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('b{1}', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: ["b", 1]', + '}, "a", true, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (props, spread, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('d', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", Object.assign({', + ' b: "1"', + '}, c, {', + ' children: "d"', + '}), undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (spread, props, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('f', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", Object.assign({', + ' b: 1,', + ' c: 2', + '}, {', + ' d: "e",', + ' children: "f"', + '}), undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('b', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: "b"', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, no children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (key, no props, no children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, true, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, no children, development, no filePath)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, no children, development, empty filePath)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: '' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, no children, development, no locations)', () => { + assert.deepEqual( + generate( + buildJsx(parse(''), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "index.js"', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should support the automatic runtime (no props, nested children, development, positional info)', () => { + assert.deepEqual( + generate( + buildJsx(parse('\n \n', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: _jsxDEV("b", {}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 2,', + ' columnNumber: 3', + ' }, this)', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) + }) + + test('should throw on spread after `key`', () => { + assert.throws(() => { buildJsx(parse(''), {runtime: 'automatic'}) - }, - /Expected `key` to come before any spread expressions/, - 'should throw on spread after `key`' - ) - - assert.deepEqual( - generate( - buildJsx(parse('/*@jsxRuntime classic*/ '), {runtime: 'automatic'}) - ), - 'React.createElement("a");\n', - 'should prefer a `jsxRuntime` comment over a `runtime` option' - ) + }, /Expected `key` to come before any spread expressions/) + }) + + test('should prefer a `jsxRuntime` comment over a `runtime` option', () => { + assert.deepEqual( + generate( + buildJsx(parse('/*@jsxRuntime classic*/ '), {runtime: 'automatic'}) + ), + 'React.createElement("a");\n' + ) + }) }) /** From cc83143d04f40dbd477890bd16289bc9c6477771 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Thu, 15 Jun 2023 15:34:10 +0200 Subject: [PATCH 2/2] Remove describe block --- test.js | 2552 +++++++++++++++++++++++++++---------------------------- 1 file changed, 1263 insertions(+), 1289 deletions(-) diff --git a/test.js b/test.js index 37642b8..287dfba 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import assert from 'node:assert/strict' -import {describe, test} from 'node:test' +import test from 'node:test' import {Parser} from 'acorn' import jsx from 'acorn-jsx' import {walk} from 'estree-walker' @@ -15,315 +15,465 @@ test('should expose the public api', () => { assert.deepEqual(Object.keys(mod).sort(), ['buildJsx']) }) -describe('buildJsx', () => { - test('should default to `React.createElement` / `React.Fragment`', () => { - assert.deepEqual(expression(buildJsx(parse('<>'))), { - type: 'CallExpression', - callee: { +test('should default to `React.createElement` / `React.Fragment`', () => { + assert.deepEqual(expression(buildJsx(parse('<>'))), { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false + }, + arguments: [ + { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + property: {type: 'Identifier', name: 'Fragment'}, computed: false, optional: false }, - arguments: [ - { + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'Fragment'}, + property: {type: 'Identifier', name: 'createElement'}, computed: false, optional: false }, + arguments: [{type: 'Literal', value: 'x'}], + optional: false + } + ], + optional: false + }) +}) + +test('should support `pragma`, `pragmaFrag`', () => { + assert.deepEqual( + expression(buildJsx(parse('<>'), {pragma: 'a', pragmaFrag: 'b'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [ + {type: 'Identifier', name: 'b'}, {type: 'Literal', value: null}, { type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, - computed: false, - optional: false - }, + callee: {type: 'Identifier', name: 'a'}, arguments: [{type: 'Literal', value: 'x'}], optional: false } ], optional: false - }) - }) + } + ) +}) - test('should support `pragma`, `pragmaFrag`', () => { - assert.deepEqual( - expression(buildJsx(parse('<>'), {pragma: 'a', pragmaFrag: 'b'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [ - {type: 'Identifier', name: 'b'}, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [{type: 'Literal', value: 'x'}], - optional: false - } - ], - optional: false - } - ) +test('should support `pragma` w/ non-identifiers (1)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'a.b-c'})), { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'a'}, + property: {type: 'Literal', value: 'b-c'}, + computed: true, + optional: false + }, + arguments: [{type: 'Literal', value: 'x'}], + optional: false }) +}) + +test('should support `pragma` w/ non-identifiers (2)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'a.b-c'})), + 'a["b-c"]("x");\n' + ) +}) - test('should support `pragma` w/ non-identifiers (1)', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'a.b-c'})), { +test('should support `@jsx`, `@jsxFrag` comments', () => { + assert.deepEqual( + expression(buildJsx(parse('/* @jsx a @jsxFrag b */\n<>'))), + { type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'a'}, - property: {type: 'Literal', value: 'b-c'}, - computed: true, - optional: false - }, - arguments: [{type: 'Literal', value: 'x'}], + callee: {type: 'Identifier', name: 'a'}, + arguments: [ + {type: 'Identifier', name: 'b'}, + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'a'}, + arguments: [{type: 'Literal', value: 'x'}], + optional: false + } + ], optional: false - }) - }) + } + ) +}) - test('should support `pragma` w/ non-identifiers (2)', () => { - assert.equal( - generate(buildJsx(parse(''), {pragma: 'a.b-c'})), - 'a["b-c"]("x");\n' - ) - }) +test('should throw when `@jsx` is set in the automatic runtime', () => { + assert.throws(() => { + buildJsx(parse('/* @jsx a @jsxRuntime automatic */')) + }, /Unexpected `@jsx` pragma w\/ automatic runtime/) +}) + +test('should throw when `@jsxFrag` is set in the automatic runtime', () => { + assert.throws(() => { + buildJsx(parse('/* @jsxFrag a @jsxRuntime automatic */')) + }, /Unexpected `@jsxFrag` pragma w\/ automatic runtime/) +}) + +test('should throw when `@jsxImportSource` is set in the classic runtime', () => { + assert.throws(() => { + buildJsx(parse('/* @jsxImportSource a @jsxRuntime classic */')) + }, /Unexpected `@jsxImportSource` w\/ classic runtime/) +}) + +test('should throw on a non-automatic nor classic `@jsxRuntime`', () => { + assert.throws(() => { + buildJsx(parse('/* @jsxRuntime a */')) + }, /Unexpected `jsxRuntime` `a`, expected `automatic` or `classic`/) +}) - test('should support `@jsx`, `@jsxFrag` comments', () => { - assert.deepEqual( - expression(buildJsx(parse('/* @jsx a @jsxFrag b */\n<>'))), +test('should ignore other comments', () => { + assert.deepEqual(expression(buildJsx(parse('// a\n<>'))), { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false + }, + arguments: [ + { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'Fragment'}, + computed: false, + optional: false + }, + {type: 'Literal', value: null}, { type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [ - {type: 'Identifier', name: 'b'}, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'a'}, - arguments: [{type: 'Literal', value: 'x'}], - optional: false - } - ], + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false + }, + arguments: [{type: 'Literal', value: 'x'}], optional: false } - ) + ], + optional: false }) +}) - test('should throw when `@jsx` is set in the automatic runtime', () => { - assert.throws(() => { - buildJsx(parse('/* @jsx a @jsxRuntime automatic */')) - }, /Unexpected `@jsx` pragma w\/ automatic runtime/) +test('should support a self-closing element', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'a'}], + optional: false }) +}) - test('should throw when `@jsxFrag` is set in the automatic runtime', () => { - assert.throws(() => { - buildJsx(parse('/* @jsxFrag a @jsxRuntime automatic */')) - }, /Unexpected `@jsxFrag` pragma w\/ automatic runtime/) +test('should support a closed element', () => { + assert.deepEqual(expression(buildJsx(parse('b'), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'b'} + ], + optional: false }) +}) - test('should throw when `@jsxImportSource` is set in the classic runtime', () => { - assert.throws(() => { - buildJsx(parse('/* @jsxImportSource a @jsxRuntime classic */')) - }, /Unexpected `@jsxImportSource` w\/ classic runtime/) +test('should support dots in a tag name for member expressions', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'a'}, + property: {type: 'Identifier', name: 'b'}, + computed: false, + optional: false + } + ], + optional: false }) +}) - test('should throw on a non-automatic nor classic `@jsxRuntime`', () => { - assert.throws(() => { - buildJsx(parse('/* @jsxRuntime a */')) - }, /Unexpected `jsxRuntime` `a`, expected `automatic` or `classic`/) +test('should support dots *and* dashes in tag names (1)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'a'}, + property: {type: 'Literal', value: 'b-c'}, + computed: true, + optional: false + } + ], + optional: false }) +}) - test('should ignore other comments', () => { - assert.deepEqual(expression(buildJsx(parse('// a\n<>'))), { - type: 'CallExpression', - callee: { +test('should support dots *and* dashes in tag names (2)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'h'})), + 'h(a["b-c"]);\n' + ) +}) + +test('should support dots *and* dashes in tag names (3)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + { type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + object: {type: 'Literal', value: 'a-b'}, + property: {type: 'Identifier', name: 'c'}, computed: false, optional: false - }, - arguments: [ - { + } + ], + optional: false + }) +}) + +test('should support dots *and* dashes in tag names (4)', () => { + assert.equal( + generate(buildJsx(parse(''), {pragma: 'h'})), + 'h(("a-b").c);\n' + ) +}) + +test('should support dots in a tag name for member expressions (2)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + { + type: 'MemberExpression', + object: { type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'Fragment'}, - computed: false, - optional: false - }, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: { + object: { type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + object: {type: 'Identifier', name: 'a'}, + property: {type: 'Identifier', name: 'b'}, computed: false, optional: false }, - arguments: [{type: 'Literal', value: 'x'}], + property: {type: 'Identifier', name: 'c'}, + computed: false, optional: false - } - ], - optional: false - }) - }) - - test('should support a self-closing element', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a'}], - optional: false - }) - }) - - test('should support a closed element', () => { - assert.deepEqual(expression(buildJsx(parse('b'), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'b'} - ], - optional: false - }) + }, + property: {type: 'Identifier', name: 'd'}, + computed: false, + optional: false + } + ], + optional: false }) +}) - test('should support dots in a tag name for member expressions', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'a'}, - property: {type: 'Identifier', name: 'b'}, - computed: false, - optional: false - } - ], - optional: false - }) +test('should support colons in a tag name for namespaces', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'a:b'}], + optional: false }) +}) - test('should support dots *and* dashes in tag names (1)', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'a'}, - property: {type: 'Literal', value: 'b-c'}, - computed: true, - optional: false - } - ], - optional: false - }) +test('should support dashes in tag names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'a-b'}], + optional: false }) +}) - test('should support dots *and* dashes in tag names (2)', () => { - assert.equal( - generate(buildJsx(parse(''), {pragma: 'h'})), - 'h(a["b-c"]);\n' - ) +test('should non-lowercase for components in tag names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Identifier', name: 'A'}], + optional: false }) +}) - test('should support dots *and* dashes in tag names (3)', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - { - type: 'MemberExpression', - object: {type: 'Literal', value: 'a-b'}, - property: {type: 'Identifier', name: 'c'}, - computed: false, - optional: false - } - ], - optional: false - }) +test('should support a boolean prop', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false }) +}) - test('should support dots *and* dashes in tag names (4)', () => { - assert.equal( - generate(buildJsx(parse(''), {pragma: 'h'})), - 'h(("a-b").c);\n' - ) +test('should support colons in prop names', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Literal', value: 'b:c'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false }) +}) - test('should support dots in a tag name for member expressions (2)', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), +test('should support a prop name that can’t be an identifier', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ + type: 'ObjectExpression', + properties: [ { - type: 'MemberExpression', - object: { - type: 'MemberExpression', - object: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'a'}, - property: {type: 'Identifier', name: 'b'}, - computed: false, - optional: false - }, - property: {type: 'Identifier', name: 'c'}, - computed: false, - optional: false - }, - property: {type: 'Identifier', name: 'd'}, - computed: false, - optional: false + type: 'Property', + key: {type: 'Literal', value: 'b-c'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false } - ], - optional: false + ] } - ) + ], + optional: false }) +}) - test('should support colons in a tag name for namespaces', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a:b'}], - optional: false - }) +test('should support a prop value', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 'c'}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false }) +}) - test('should support dashes in tag names', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a-b'}], - optional: false - }) +test('should support an expression as a prop value', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Identifier', name: 'c'}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false }) +}) - test('should non-lowercase for components in tag names', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Identifier', name: 'A'}], - optional: false - }) +test('should support an expression as a prop value (2)', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 1}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + } + ], + optional: false }) +}) - test('should support a boolean prop', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { +test('should support a fragment as a prop value', () => { + assert.deepEqual( + expression( + buildJsx(parse('c />'), {pragma: 'h', pragmaFrag: 'f'}) + ), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -334,7 +484,16 @@ describe('buildJsx', () => { { type: 'Property', key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: true}, + value: { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Identifier', name: 'f'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'c'} + ], + optional: false + }, kind: 'init', method: false, shorthand: false, @@ -344,11 +503,14 @@ describe('buildJsx', () => { } ], optional: false - }) - }) + } + ) +}) - test('should support colons in prop names', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { +test('should support an element as a prop value', () => { + assert.deepEqual( + expression(buildJsx(parse(' />'), {pragma: 'h'})), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ @@ -358,8 +520,13 @@ describe('buildJsx', () => { properties: [ { type: 'Property', - key: {type: 'Literal', value: 'b:c'}, - value: {type: 'Literal', value: true}, + key: {type: 'Identifier', name: 'b'}, + value: { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'c'}], + optional: false + }, kind: 'init', method: false, shorthand: false, @@ -369,633 +536,432 @@ describe('buildJsx', () => { } ], optional: false - }) + } + ) +}) + +test('should support a single spread prop', () => { + assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Identifier', name: 'b'} + ], + optional: false }) +}) - test('should support a prop name that can’t be an identifier', () => { - assert.deepEqual(expression(buildJsx(parse(''), {pragma: 'h'})), { +test('should support a spread prop and another prop', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, { - type: 'ObjectExpression', - properties: [ + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + {type: 'ObjectExpression', properties: []}, + {type: 'Identifier', name: 'b'}, { - type: 'Property', - key: {type: 'Literal', value: 'b-c'}, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'c'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] } - ] + ], + optional: false } ], optional: false - }) - }) - - test('should support a prop value', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 'c'}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ) - }) + } + ) +}) - test('should support an expression as a prop value', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Identifier', name: 'c'}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ) - }) +test('should support a prop and a spread prop', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false + } + ] + }, + {type: 'Identifier', name: 'c'} + ], + optional: false + } + ], + optional: false + } + ) +}) - test('should support an expression as a prop value (2)', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 1}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ) - }) +test('should support two spread props', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false + }, + arguments: [ + {type: 'ObjectExpression', properties: []}, + {type: 'Identifier', name: 'b'}, + {type: 'Identifier', name: 'c'} + ], + optional: false + } + ], + optional: false + } + ) +}) - test('should support a fragment as a prop value', () => { - assert.deepEqual( - expression( - buildJsx(parse('c />'), {pragma: 'h', pragmaFrag: 'f'}) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Identifier', name: 'f'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'c'} - ], - optional: false - }, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ) - }) +test('should support more complex spreads', () => { + assert.deepEqual( + expression(buildJsx(parse(''), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: {type: 'Identifier', name: 'b'}, + value: {type: 'Literal', value: 1}, + kind: 'init' + }, + { + type: 'SpreadElement', + argument: {type: 'Identifier', name: 'c'} + }, + { + type: 'Property', + method: false, + shorthand: false, + computed: false, + key: {type: 'Identifier', name: 'd'}, + value: {type: 'Literal', value: 2}, + kind: 'init' + } + ] + } + ], + optional: false + } + ) +}) - test('should support an element as a prop value', () => { - assert.deepEqual( - expression(buildJsx(parse(' />'), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'c'}], - optional: false - }, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ) +test('should support expressions content', () => { + assert.deepEqual(expression(buildJsx(parse('{1}'), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 1} + ], + optional: false }) +}) - test('should support a single spread prop', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Identifier', name: 'b'} - ], - optional: false - } - ) +test('should support empty expressions content', () => { + assert.deepEqual(expression(buildJsx(parse('{}'), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [{type: 'Literal', value: 'a'}], + optional: false }) +}) - test('should support a spread prop and another prop', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - {type: 'ObjectExpression', properties: []}, - {type: 'Identifier', name: 'b'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'c'}, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - } - ], - optional: false - } - ], - optional: false - } - ) +test('should support initial spaces in content', () => { + assert.deepEqual(expression(buildJsx(parse(' b'), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b'} + ], + optional: false }) +}) - test('should support a prop and a spread prop', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false - } - ] - }, - {type: 'Identifier', name: 'c'} - ], - optional: false - } - ], - optional: false - } - ) +test('should support final spaces in content', () => { + assert.deepEqual(expression(buildJsx(parse('b '), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: 'b '} + ], + optional: false }) +}) - test('should support two spread props', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - {type: 'ObjectExpression', properties: []}, - {type: 'Identifier', name: 'b'}, - {type: 'Identifier', name: 'c'} - ], - optional: false - } - ], - optional: false - } - ) +test('should support initial and final spaces in content', () => { + assert.deepEqual(expression(buildJsx(parse(' b '), {pragma: 'h'})), { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b '} + ], + optional: false }) +}) - test('should support more complex spreads', () => { - assert.deepEqual( - expression(buildJsx(parse(''), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: {type: 'Identifier', name: 'b'}, - value: {type: 'Literal', value: 1}, - kind: 'init' - }, - { - type: 'SpreadElement', - argument: {type: 'Identifier', name: 'c'} - }, - { - type: 'Property', - method: false, - shorthand: false, - computed: false, - key: {type: 'Identifier', name: 'd'}, - value: {type: 'Literal', value: 2}, - kind: 'init' - } - ] - } - ], - optional: false - } - ) - }) +test('should support spaces around line endings', () => { + assert.deepEqual( + expression(buildJsx(parse(' b \r c \n d \n '), {pragma: 'h'})), + { + type: 'CallExpression', + callee: {type: 'Identifier', name: 'h'}, + arguments: [ + {type: 'Literal', value: 'a'}, + {type: 'Literal', value: null}, + {type: 'Literal', value: ' b c d'} + ], + optional: false + } + ) +}) - test('should support expressions content', () => { - assert.deepEqual(expression(buildJsx(parse('{1}'), {pragma: 'h'})), { +test('should support skip empty or whitespace only line endings', () => { + assert.deepEqual( + expression(buildJsx(parse(' b \r \n c \n\n d \n '), {pragma: 'h'})), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, {type: 'Literal', value: null}, - {type: 'Literal', value: 1} + {type: 'Literal', value: ' b c d'} ], optional: false - }) - }) + } + ) +}) - test('should support empty expressions content', () => { - assert.deepEqual(expression(buildJsx(parse('{}'), {pragma: 'h'})), { +test('should support skip whitespace only content', () => { + assert.deepEqual( + expression(buildJsx(parse(' \t\n '), {pragma: 'h'})), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [{type: 'Literal', value: 'a'}], optional: false - }) - }) + } + ) +}) - test('should support initial spaces in content', () => { - assert.deepEqual(expression(buildJsx(parse(' b'), {pragma: 'h'})), { +test('should trim strings with leading line feed', () => { + assert.deepEqual( + expression( + buildJsx(parse(['', ' line1', ''].join('\n')), {pragma: 'h'}) + ), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, {type: 'Literal', value: null}, - {type: 'Literal', value: ' b'} + {type: 'Literal', value: 'line1'} ], optional: false - }) - }) + } + ) +}) - test('should support final spaces in content', () => { - assert.deepEqual(expression(buildJsx(parse('b '), {pragma: 'h'})), { +test('should trim strings with leading line feed (multiline test)', () => { + assert.deepEqual( + expression( + buildJsx(parse(['', ' line1{" "}', ' line2', ''].join('\n')), { + pragma: 'h' + }) + ), + { type: 'CallExpression', callee: {type: 'Identifier', name: 'h'}, arguments: [ {type: 'Literal', value: 'a'}, {type: 'Literal', value: null}, - {type: 'Literal', value: 'b '} + {type: 'Literal', value: 'line1'}, + {type: 'Literal', value: ' '}, + {type: 'Literal', value: 'line2'} ], optional: false - }) - }) - - test('should support initial and final spaces in content', () => { - assert.deepEqual( - expression(buildJsx(parse(' b '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b '} - ], - optional: false - } - ) - }) - - test('should support spaces around line endings', () => { - assert.deepEqual( - expression(buildJsx(parse(' b \r c \n d \n '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b c d'} - ], - optional: false - } - ) - }) - - test('should support skip empty or whitespace only line endings', () => { - assert.deepEqual( - expression( - buildJsx(parse(' b \r \n c \n\n d \n '), {pragma: 'h'}) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: ' b c d'} - ], - optional: false - } - ) - }) - - test('should support skip whitespace only content', () => { - assert.deepEqual( - expression(buildJsx(parse(' \t\n '), {pragma: 'h'})), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [{type: 'Literal', value: 'a'}], - optional: false - } - ) - }) - - test('should trim strings with leading line feed', () => { - assert.deepEqual( - expression( - buildJsx(parse(['', ' line1', ''].join('\n')), {pragma: 'h'}) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'line1'} - ], - optional: false - } - ) - }) - - test('should trim strings with leading line feed (multiline test)', () => { - assert.deepEqual( - expression( - buildJsx(parse(['', ' line1{" "}', ' line2', ''].join('\n')), { - pragma: 'h' - }) - ), - { - type: 'CallExpression', - callee: {type: 'Identifier', name: 'h'}, - arguments: [ - {type: 'Literal', value: 'a'}, - {type: 'Literal', value: null}, - {type: 'Literal', value: 'line1'}, - {type: 'Literal', value: ' '}, - {type: 'Literal', value: 'line2'} - ], - optional: false - } - ) - }) + } + ) +}) - test('should integrate w/ generators (`astring`)', () => { - assert.equal( - generate( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ), - 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));\n' - ) - }) +test('should integrate w/ generators (`astring`)', () => { + assert.equal( + generate( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ), + 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));\n' + ) +}) - test('should integrate w/ generators (`recast`)', () => { - assert.equal( - recast.print( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ).code, - 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));' - ) - }) +test('should integrate w/ generators (`recast`)', () => { + assert.equal( + recast.print( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ).code, + 'h(f, null, h("a", Object.assign({\n b: true,\n c: "d",\n e: f\n}, g), "h"));' + ) +}) - test('should integrate w/ generators (`escodegen`)', () => { - assert.equal( - escodegen.generate( - buildJsx(parse('<>\n h\n'), { - pragma: 'h', - pragmaFrag: 'f' - }) - ), - "h(f, null, h('a', Object.assign({\n b: true,\n c: 'd',\n e: f\n}, g), 'h'));" - ) - }) +test('should integrate w/ generators (`escodegen`)', () => { + assert.equal( + escodegen.generate( + buildJsx(parse('<>\n h\n'), { + pragma: 'h', + pragmaFrag: 'f' + }) + ), + "h(f, null, h('a', Object.assign({\n b: true,\n c: 'd',\n e: f\n}, g), 'h'));" + ) +}) - test('should support positional info', () => { - assert.deepEqual( - buildJsx(parse('<>\n h\n', false)), - { - type: 'Program', - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38], - body: [ - { - type: 'ExpressionStatement', - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38], - expression: { - type: 'CallExpression', - callee: { +test('should support positional info', () => { + assert.deepEqual( + buildJsx(parse('<>\n h\n', false)), + { + type: 'Program', + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38], + body: [ + { + type: 'ExpressionStatement', + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38], + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false + }, + arguments: [ + { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + property: {type: 'Identifier', name: 'Fragment'}, computed: false, optional: false }, - arguments: [ - { + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'Fragment'}, + property: {type: 'Identifier', name: 'createElement'}, computed: false, optional: false }, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, - computed: false, - optional: false + arguments: [ + { + type: 'Literal', + value: 'a', + start: 6, + end: 7, + loc: { + start: {line: 2, column: 3}, + end: {line: 2, column: 4} + }, + range: [6, 7] }, - arguments: [ - { - type: 'Literal', - value: 'a', - start: 6, - end: 7, - loc: { - start: {line: 2, column: 3}, - end: {line: 2, column: 4} - }, - range: [6, 7] + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'Object'}, + property: {type: 'Identifier', name: 'assign'}, + computed: false, + optional: false }, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'Object'}, - property: {type: 'Identifier', name: 'assign'}, - computed: false, - optional: false - }, - arguments: [ - { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: { - type: 'Identifier', - name: 'b', - start: 8, - end: 9, - loc: { - start: {line: 2, column: 5}, - end: {line: 2, column: 6} - }, - range: [8, 9] - }, - value: {type: 'Literal', value: true}, - kind: 'init', - method: false, - shorthand: false, - computed: false, + arguments: [ + { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: { + type: 'Identifier', + name: 'b', start: 8, end: 9, loc: { @@ -1004,540 +970,548 @@ describe('buildJsx', () => { }, range: [8, 9] }, - { - type: 'Property', - key: { - type: 'Identifier', - name: 'c', - start: 10, - end: 11, - loc: { - start: {line: 2, column: 7}, - end: {line: 2, column: 8} - }, - range: [10, 11] - }, - value: { - type: 'Literal', - start: 12, - end: 15, - loc: { - start: {line: 2, column: 9}, - end: {line: 2, column: 12} - }, - range: [12, 15], - value: 'd' - }, - kind: 'init', - method: false, - shorthand: false, - computed: false, + value: {type: 'Literal', value: true}, + kind: 'init', + method: false, + shorthand: false, + computed: false, + start: 8, + end: 9, + loc: { + start: {line: 2, column: 5}, + end: {line: 2, column: 6} + }, + range: [8, 9] + }, + { + type: 'Property', + key: { + type: 'Identifier', + name: 'c', start: 10, - end: 15, + end: 11, loc: { start: {line: 2, column: 7}, - end: {line: 2, column: 12} + end: {line: 2, column: 8} }, - range: [10, 15] + range: [10, 11] }, - { - type: 'Property', - key: { - type: 'Identifier', - name: 'e', - start: 16, - end: 17, - loc: { - start: {line: 2, column: 13}, - end: {line: 2, column: 14} - }, - range: [16, 17] - }, - value: { - type: 'Identifier', - start: 19, - end: 20, - loc: { - start: {line: 2, column: 16}, - end: {line: 2, column: 17} - }, - range: [19, 20], - name: 'f' + value: { + type: 'Literal', + start: 12, + end: 15, + loc: { + start: {line: 2, column: 9}, + end: {line: 2, column: 12} }, - kind: 'init', - method: false, - shorthand: false, - computed: false, + range: [12, 15], + value: 'd' + }, + kind: 'init', + method: false, + shorthand: false, + computed: false, + start: 10, + end: 15, + loc: { + start: {line: 2, column: 7}, + end: {line: 2, column: 12} + }, + range: [10, 15] + }, + { + type: 'Property', + key: { + type: 'Identifier', + name: 'e', start: 16, - end: 21, + end: 17, loc: { start: {line: 2, column: 13}, - end: {line: 2, column: 18} + end: {line: 2, column: 14} }, - range: [16, 21] - } - ] - }, - { - type: 'Identifier', - start: 26, - end: 27, - loc: { - start: {line: 2, column: 23}, - end: {line: 2, column: 24} - }, - range: [26, 27], - name: 'g' - } - ], - optional: false - }, - { - type: 'Literal', - value: 'h', - start: 29, - end: 30, - loc: { - start: {line: 2, column: 26}, - end: {line: 2, column: 27} + range: [16, 17] + }, + value: { + type: 'Identifier', + start: 19, + end: 20, + loc: { + start: {line: 2, column: 16}, + end: {line: 2, column: 17} + }, + range: [19, 20], + name: 'f' + }, + kind: 'init', + method: false, + shorthand: false, + computed: false, + start: 16, + end: 21, + loc: { + start: {line: 2, column: 13}, + end: {line: 2, column: 18} + }, + range: [16, 21] + } + ] }, - range: [29, 30] - } - ], - optional: false, - start: 5, - end: 34, - loc: { - start: {line: 2, column: 2}, - end: {line: 2, column: 31} + { + type: 'Identifier', + start: 26, + end: 27, + loc: { + start: {line: 2, column: 23}, + end: {line: 2, column: 24} + }, + range: [26, 27], + name: 'g' + } + ], + optional: false }, - range: [5, 34] - } - ], - optional: false, - start: 0, - end: 38, - loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, - range: [0, 38] - } + { + type: 'Literal', + value: 'h', + start: 29, + end: 30, + loc: { + start: {line: 2, column: 26}, + end: {line: 2, column: 27} + }, + range: [29, 30] + } + ], + optional: false, + start: 5, + end: 34, + loc: { + start: {line: 2, column: 2}, + end: {line: 2, column: 31} + }, + range: [5, 34] + } + ], + optional: false, + start: 0, + end: 38, + loc: {start: {line: 1, column: 0}, end: {line: 3, column: 3}}, + range: [0, 38] } - ], - sourceType: 'script', - comments: [] - } - ) - }) + } + ], + sourceType: 'script', + comments: [] + } + ) +}) - test('should support no comments on `program`', () => { - assert.deepEqual(buildJsx(parse('<>', true, false)), { - type: 'Program', - body: [ - { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { +test('should support no comments on `program`', () => { + assert.deepEqual(buildJsx(parse('<>', true, false)), { + type: 'Program', + body: [ + { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: {type: 'Identifier', name: 'React'}, + property: {type: 'Identifier', name: 'createElement'}, + computed: false, + optional: false + }, + arguments: [ + { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, + property: {type: 'Identifier', name: 'Fragment'}, computed: false, optional: false }, - arguments: [ - { + {type: 'Literal', value: null}, + { + type: 'CallExpression', + callee: { type: 'MemberExpression', object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'Fragment'}, + property: {type: 'Identifier', name: 'createElement'}, computed: false, optional: false }, - {type: 'Literal', value: null}, - { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: {type: 'Identifier', name: 'React'}, - property: {type: 'Identifier', name: 'createElement'}, - computed: false, - optional: false - }, - arguments: [{type: 'Literal', value: 'x'}], - optional: false - } - ], - optional: false - } + arguments: [{type: 'Literal', value: 'x'}], + optional: false + } + ], + optional: false } - ], - sourceType: 'script' - }) + } + ], + sourceType: 'script' }) +}) - test('should support the automatic runtime (fragment, jsx, settings)', () => { - assert.deepEqual( - generate(buildJsx(parse('<>a'), {runtime: 'automatic'})), - [ - 'import {Fragment as _Fragment, jsx as _jsx} from "react/jsx-runtime";', - '_jsx(_Fragment, {', - ' children: "a"', - '});', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (fragment, jsx, settings)', () => { + assert.deepEqual( + generate(buildJsx(parse('<>a'), {runtime: 'automatic'})), + [ + 'import {Fragment as _Fragment, jsx as _jsx} from "react/jsx-runtime";', + '_jsx(_Fragment, {', + ' children: "a"', + '});', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (jsxs, key, comment)', () => { - assert.deepEqual( - generate( - buildJsx(parse('/*@jsxRuntime automatic*/\nb{1}')) - ), - [ - 'import {jsxs as _jsxs} from "react/jsx-runtime";', - '_jsxs("a", {', - ' children: ["b", 1]', - '}, "a");', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (jsxs, key, comment)', () => { + assert.deepEqual( + generate(buildJsx(parse('/*@jsxRuntime automatic*/\nb{1}'))), + [ + 'import {jsxs as _jsxs} from "react/jsx-runtime";', + '_jsxs("a", {', + ' children: ["b", 1]', + '}, "a");', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (props, spread, children)', () => { - assert.deepEqual( - generate( - buildJsx(parse('d'), {runtime: 'automatic'}) - ), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", Object.assign({', - ' b: "1"', - '}, c, {', - ' children: "d"', - '}));', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (props, spread, children)', () => { + assert.deepEqual( + generate(buildJsx(parse('d'), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", Object.assign({', + ' b: "1"', + '}, c, {', + ' children: "d"', + '}));', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (spread, props, children)', () => { - assert.deepEqual( - generate( - buildJsx(parse('f'), { - runtime: 'automatic' - }) - ), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", Object.assign({', - ' b: 1,', - ' c: 2', - '}, {', - ' d: "e",', - ' children: "f"', - '}));', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (spread, props, children)', () => { + assert.deepEqual( + generate( + buildJsx(parse('f'), { + runtime: 'automatic' + }) + ), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", Object.assign({', + ' b: 1,', + ' c: 2', + '}, {', + ' d: "e",', + ' children: "f"', + '}));', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, children)', () => { - assert.deepEqual( - generate(buildJsx(parse('b'), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {', - ' children: "b"', - '});', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, children)', () => { + assert.deepEqual( + generate(buildJsx(parse('b'), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {', + ' children: "b"', + '});', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, no children)', () => { - assert.deepEqual( - generate(buildJsx(parse(''), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {});', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, no children)', () => { + assert.deepEqual( + generate(buildJsx(parse(''), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {});', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (key, no props, no children)', () => { - assert.deepEqual( - generate(buildJsx(parse(''), {runtime: 'automatic'})), - [ - 'import {jsx as _jsx} from "react/jsx-runtime";', - '_jsx("a", {}, true);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (key, no props, no children)', () => { + assert.deepEqual( + generate(buildJsx(parse(''), {runtime: 'automatic'})), + [ + 'import {jsx as _jsx} from "react/jsx-runtime";', + '_jsx("a", {}, true);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (fragment, jsx, settings, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('<>a', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {Fragment as _Fragment, jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV(_Fragment, {', - ' children: "a"', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (fragment, jsx, settings, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('<>a', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {Fragment as _Fragment, jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV(_Fragment, {', + ' children: "a"', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (jsxs, key, comment, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('b{1}', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: ["b", 1]', - '}, "a", true, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (jsxs, key, comment, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('b{1}', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: ["b", 1]', + '}, "a", true, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (props, spread, children, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('d', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", Object.assign({', - ' b: "1"', - '}, c, {', - ' children: "d"', - '}), undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (props, spread, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('d', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", Object.assign({', + ' b: "1"', + '}, c, {', + ' children: "d"', + '}), undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (spread, props, children, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('f', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", Object.assign({', - ' b: 1,', - ' c: 2', - '}, {', - ' d: "e",', - ' children: "f"', - '}), undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (spread, props, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('f', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", Object.assign({', + ' b: 1,', + ' c: 2', + '}, {', + ' d: "e",', + ' children: "f"', + '}), undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, children, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('b', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: "b"', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('b', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: "b"', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, no children, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, no children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (key, no props, no children, development)', () => { - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, true, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (key, no props, no children, development)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, true, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, no children, development, no filePath)', () => { - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, no children, development, no filePath)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, no children, development, empty filePath)', () => { - assert.deepEqual( - generate( - buildJsx(parse('', false), { - runtime: 'automatic', - development: true, - filePath: '' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, no children, development, empty filePath)', () => { + assert.deepEqual( + generate( + buildJsx(parse('', false), { + runtime: 'automatic', + development: true, + filePath: '' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, no children, development, no locations)', () => { - assert.deepEqual( - generate( - buildJsx(parse(''), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {}, undefined, false, {', - ' fileName: "index.js"', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, no children, development, no locations)', () => { + assert.deepEqual( + generate( + buildJsx(parse(''), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {}, undefined, false, {', + ' fileName: "index.js"', + '}, this);', + '' + ].join('\n') + ) +}) - test('should support the automatic runtime (no props, nested children, development, positional info)', () => { - assert.deepEqual( - generate( - buildJsx(parse('\n \n', false), { - runtime: 'automatic', - development: true, - filePath: 'index.js' - }) - ), - [ - 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', - '_jsxDEV("a", {', - ' children: _jsxDEV("b", {}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 2,', - ' columnNumber: 3', - ' }, this)', - '}, undefined, false, {', - ' fileName: "index.js",', - ' lineNumber: 1,', - ' columnNumber: 1', - '}, this);', - '' - ].join('\n') - ) - }) +test('should support the automatic runtime (no props, nested children, development, positional info)', () => { + assert.deepEqual( + generate( + buildJsx(parse('\n \n', false), { + runtime: 'automatic', + development: true, + filePath: 'index.js' + }) + ), + [ + 'import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";', + '_jsxDEV("a", {', + ' children: _jsxDEV("b", {}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 2,', + ' columnNumber: 3', + ' }, this)', + '}, undefined, false, {', + ' fileName: "index.js",', + ' lineNumber: 1,', + ' columnNumber: 1', + '}, this);', + '' + ].join('\n') + ) +}) - test('should throw on spread after `key`', () => { - assert.throws(() => { - buildJsx(parse(''), {runtime: 'automatic'}) - }, /Expected `key` to come before any spread expressions/) - }) +test('should throw on spread after `key`', () => { + assert.throws(() => { + buildJsx(parse(''), {runtime: 'automatic'}) + }, /Expected `key` to come before any spread expressions/) +}) - test('should prefer a `jsxRuntime` comment over a `runtime` option', () => { - assert.deepEqual( - generate( - buildJsx(parse('/*@jsxRuntime classic*/ '), {runtime: 'automatic'}) - ), - 'React.createElement("a");\n' - ) - }) +test('should prefer a `jsxRuntime` comment over a `runtime` option', () => { + assert.deepEqual( + generate( + buildJsx(parse('/*@jsxRuntime classic*/ '), {runtime: 'automatic'}) + ), + 'React.createElement("a");\n' + ) }) /**