From dfca9bdb6180fa22328d9677f90f10fd1546347a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Mon, 10 Jan 2022 22:03:40 +0100 Subject: [PATCH 1/7] fix(print): fix print for NullLiteral --- src/parse-result.test.ts | 10 ++++++++++ src/parse-result.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/src/parse-result.test.ts b/src/parse-result.test.ts index ea1fd692..727e3c95 100644 --- a/src/parse-result.test.ts +++ b/src/parse-result.test.ts @@ -1521,6 +1521,16 @@ describe('ember-template-recast', function () { }); }); + describe('NullLitteral', function () { + test('creating void element', function () { + let template = `{{my-helper null}}`; + + let ast = parse(template); + + expect(print(ast)).toEqual(`{{my-helper null}}`); + }); + }); + test('can remove during traversal by returning `null`', function () { let template = stripIndent`

here is some multiline string

diff --git a/src/parse-result.ts b/src/parse-result.ts index b8c75ec3..ef285b4f 100644 --- a/src/parse-result.ts +++ b/src/parse-result.ts @@ -1109,6 +1109,7 @@ export default class ParseResult { break; case 'BooleanLiteral': case 'NumberLiteral': + case 'NullLiteral': { let { source } = nodeInfo; From be1b4c3d989e2df879e35d3c2d1e47b9293146cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Mon, 10 Jan 2022 22:19:48 +0100 Subject: [PATCH 2/7] fix(typescipt): fix typescript configuration --- package.json | 19 ++++++++++--------- src/parse-result.ts | 2 +- tsconfig.json | 1 + yarn.lock | 13 +++++++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 36970df0..97114086 100644 --- a/package.json +++ b/package.json @@ -22,15 +22,15 @@ "!lib/**/*.test.*" ], "scripts": { - "build": "tsc", - "lint": "npm-run-all lint:*", - "lint:files": "eslint .", - "lint:tsc": "tsc --noEmit", + "build": "npx tsc", + "lint": "npx npm-run-all lint:*", + "lint:files": "npx eslint .", + "lint:tsc": "npx tsc --noEmit", "perf:benchmark": "node scripts/benchmark.mjs", - "prepare": "tsc", - "release": "release-it", - "test": "npm-run-all lint test:*", - "test:jest": "jest" + "prepare": "npx tsc", + "release": "npx release-it", + "test": "npx npm-run-all lint test:*", + "test:jest": "npx jest" }, "dependencies": { "@glimmer/reference": "^0.83.1", @@ -46,7 +46,8 @@ "workerpool": "^6.1.5" }, "devDependencies": { - "@types/jest": "^27.0.3", + "@types/jest": "^27.4.0", + "@types/node": "^17.0.8", "@types/workerpool": "^6.1.0", "@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/parser": "^5.6.0", diff --git a/src/parse-result.ts b/src/parse-result.ts index ef285b4f..005530dc 100644 --- a/src/parse-result.ts +++ b/src/parse-result.ts @@ -1114,7 +1114,7 @@ export default class ParseResult { let { source } = nodeInfo; if (dirtyFields.has('value')) { - source = ast.value.toString(); + source = ast.value?.toString() || ''; dirtyFields.delete('value'); } diff --git a/tsconfig.json b/tsconfig.json index 81d7f732..d1de8604 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,7 @@ "rootDir": "./src", "noImplicitAny": true, "baseUrl": ".", + "types": ["jest", "node"], "paths": { "*": ["types/*"] diff --git a/yarn.lock b/yarn.lock index e0a6c69a..0d8fbdda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -906,10 +906,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.3.tgz#0cf9dfe9009e467f70a342f0f94ead19842a783a" - integrity sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg== +"@types/jest@^27.4.0": + version "27.4.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.0.tgz#037ab8b872067cae842a320841693080f9cb84ed" + integrity sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ== dependencies: jest-diff "^27.0.0" pretty-format "^27.0.0" @@ -943,6 +943,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.2.tgz#2de1ed6670439387da1c9f549a2ade2b0a799256" integrity sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA== +"@types/node@^17.0.8": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" + integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" From 9bbd9167ee8c4f100131101dd57c78f96ab69aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Wed, 12 Jan 2022 08:46:35 +0100 Subject: [PATCH 3/7] Revert "fix(typescipt): fix typescript configuration" This reverts commit be1b4c3d989e2df879e35d3c2d1e47b9293146cf. --- package.json | 19 +++++++++---------- src/parse-result.ts | 2 +- tsconfig.json | 1 - yarn.lock | 13 ++++--------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 97114086..36970df0 100644 --- a/package.json +++ b/package.json @@ -22,15 +22,15 @@ "!lib/**/*.test.*" ], "scripts": { - "build": "npx tsc", - "lint": "npx npm-run-all lint:*", - "lint:files": "npx eslint .", - "lint:tsc": "npx tsc --noEmit", + "build": "tsc", + "lint": "npm-run-all lint:*", + "lint:files": "eslint .", + "lint:tsc": "tsc --noEmit", "perf:benchmark": "node scripts/benchmark.mjs", - "prepare": "npx tsc", - "release": "npx release-it", - "test": "npx npm-run-all lint test:*", - "test:jest": "npx jest" + "prepare": "tsc", + "release": "release-it", + "test": "npm-run-all lint test:*", + "test:jest": "jest" }, "dependencies": { "@glimmer/reference": "^0.83.1", @@ -46,8 +46,7 @@ "workerpool": "^6.1.5" }, "devDependencies": { - "@types/jest": "^27.4.0", - "@types/node": "^17.0.8", + "@types/jest": "^27.0.3", "@types/workerpool": "^6.1.0", "@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/parser": "^5.6.0", diff --git a/src/parse-result.ts b/src/parse-result.ts index 005530dc..ef285b4f 100644 --- a/src/parse-result.ts +++ b/src/parse-result.ts @@ -1114,7 +1114,7 @@ export default class ParseResult { let { source } = nodeInfo; if (dirtyFields.has('value')) { - source = ast.value?.toString() || ''; + source = ast.value.toString(); dirtyFields.delete('value'); } diff --git a/tsconfig.json b/tsconfig.json index d1de8604..81d7f732 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,6 @@ "rootDir": "./src", "noImplicitAny": true, "baseUrl": ".", - "types": ["jest", "node"], "paths": { "*": ["types/*"] diff --git a/yarn.lock b/yarn.lock index 0d8fbdda..e0a6c69a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -906,10 +906,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27.4.0": - version "27.4.0" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.0.tgz#037ab8b872067cae842a320841693080f9cb84ed" - integrity sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ== +"@types/jest@^27.0.3": + version "27.0.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.3.tgz#0cf9dfe9009e467f70a342f0f94ead19842a783a" + integrity sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg== dependencies: jest-diff "^27.0.0" pretty-format "^27.0.0" @@ -943,11 +943,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.2.tgz#2de1ed6670439387da1c9f549a2ade2b0a799256" integrity sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA== -"@types/node@^17.0.8": - version "17.0.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" - integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== - "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" From ce82a09402d4367a3e8ab7350963dfee387690cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Wed, 12 Jan 2022 15:51:43 +0100 Subject: [PATCH 4/7] fix typo Co-authored-by: Bryan Mishkin <698306+bmish@users.noreply.github.com> --- src/parse-result.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse-result.test.ts b/src/parse-result.test.ts index 727e3c95..773bac6b 100644 --- a/src/parse-result.test.ts +++ b/src/parse-result.test.ts @@ -1521,7 +1521,7 @@ describe('ember-template-recast', function () { }); }); - describe('NullLitteral', function () { + describe('NullLiteral', function () { test('creating void element', function () { let template = `{{my-helper null}}`; From a6381b3e2e208112bb44d7623adfe86b85279469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Wed, 12 Jan 2022 16:00:25 +0100 Subject: [PATCH 5/7] fix implem --- src/parse-result.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/parse-result.ts b/src/parse-result.ts index ef285b4f..6ba0bd2d 100644 --- a/src/parse-result.ts +++ b/src/parse-result.ts @@ -1109,7 +1109,6 @@ export default class ParseResult { break; case 'BooleanLiteral': case 'NumberLiteral': - case 'NullLiteral': { let { source } = nodeInfo; @@ -1121,6 +1120,11 @@ export default class ParseResult { output.push(source); } break; + case 'NullLiteral': + { + output.push('null'); + } + break; default: throw new Error( `ember-template-recast does not have the ability to update ${original.type}. Please open an issue so we can add support.` From ef44cd28fa21ec242aa81b8e93e6470193ae5c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Wed, 12 Jan 2022 20:04:27 +0100 Subject: [PATCH 6/7] test: fix tests --- src/parse-result.test.ts | 528 ++++++++++++++++++++------------------- src/parse-result.ts | 8 +- 2 files changed, 271 insertions(+), 265 deletions(-) diff --git a/src/parse-result.test.ts b/src/parse-result.test.ts index 773bac6b..f602b530 100644 --- a/src/parse-result.test.ts +++ b/src/parse-result.test.ts @@ -1,6 +1,11 @@ import { builders, parse, print, transform } from '.'; import type { ASTv1 as AST } from '@glimmer/syntax'; import stripIndent from 'outdent'; +import { + BaseNode, + MustacheStatement, + NullLiteral, +} from '@glimmer/syntax/dist/types/lib/v1/nodes-v1'; describe('ember-template-recast', function () { describe('ElementNode', function () { @@ -126,20 +131,20 @@ describe('ember-template-recast', function () { test('rename element tagname', function () { let template = stripIndent` -
-
`; +
+
`; let ast = parse(template) as any; ast.body[0].tag = 'a'; expect(print(ast)).toEqual(stripIndent` - - `); + + `); }); test('rename element tagname without children', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].tag = 'a'; @@ -198,13 +203,13 @@ describe('ember-template-recast', function () { test('adding attribute when none originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes.push(builders.attr('data-test', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding attribute to ElementNode with block params', function () { @@ -238,19 +243,19 @@ describe('ember-template-recast', function () { test('adding an attribute to existing list', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes.push(builders.attr('data-test', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('creating an element with complex attributes', function () { @@ -281,19 +286,19 @@ describe('ember-template-recast', function () { test('modifying an attribute name (GH#112)', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes[0].name = 'data-test'; expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('modifying attribute after valueless attribute', function () { @@ -307,19 +312,19 @@ describe('ember-template-recast', function () { test('modifying attribute after valueless attribute with special whitespace', function () { let template = stripIndent` - `; + `; let ast = parse(template) as any; ast.body[0].attributes[1].value.path = builders.path('this.hmmm'); expect(print(ast)).toEqual(stripIndent` - `); + `); }); test('adding attribute after valueless attribute', function () { @@ -342,7 +347,7 @@ describe('ember-template-recast', function () { test('adding modifier when no open parts originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.push( @@ -350,12 +355,12 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding modifier with existing attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.push( @@ -363,7 +368,7 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); // This is specifically testing the issue described in https://github.com/glimmerjs/glimmer-vm/pull/953 @@ -382,46 +387,46 @@ describe('ember-template-recast', function () { test('removing a modifier with other attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.shift(); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('removing a modifier with no other attributes/comments/modifiers', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.shift(); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding comment when no open parts originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].comments.push(builders.mustacheComment(' template-lint-disable ')); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding comment with existing attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].comments.push(builders.mustacheComment(' template-lint-disable ')); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding block param', function () { @@ -444,18 +449,18 @@ describe('ember-template-recast', function () { test('removing a block param preserves formatting of "open element closing"', function () { let template = stripIndent` - `; + `; let ast = parse(template) as any; ast.body[0].blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - `); + `); }); test('interleaved attributes and modifiers are not modified when unchanged', function () { @@ -471,10 +476,10 @@ describe('ember-template-recast', function () { test('adding children to element with children', function () { let template = stripIndent` -
    -
  • -
- `; +
    +
  • +
+ `; let ast = parse(template) as any; ast.body[0].children.splice( @@ -485,11 +490,11 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
    -
  • -
  • -
- `); +
    +
  • +
  • +
+ `); }); test('adding children to an empty element', function () { @@ -512,10 +517,10 @@ describe('ember-template-recast', function () { test('moving a child to another ElementNode', function () { let template = stripIndent` - {{ - special-formatting-here - }} - `; + {{ + special-formatting-here + }} + `; let ast = parse(template) as any; let child = ast.body[0].children.pop(); @@ -523,47 +528,47 @@ describe('ember-template-recast', function () { ast.body.unshift(child); expect(print(ast)).toEqual(stripIndent` - {{ - special-formatting-here - }} - - `); + {{ + special-formatting-here + }} + + `); }); test('adding a new attribute to an ElementNode while preserving the existing whitespaces', function () { let template = stripIndent` -
-
- `; +
+
+ `; let ast = parse(template); let element = ast.body[0] as AST.ElementNode; element.attributes.push(builders.attr('foo-foo', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
-
- `); +
+
+ `); }); test('issue 706', function () { let template = `
- {{#each this.data as |chunks|}} - {{#each chunks as |chunk|}} - {{#if (this.shouldShowImage chunk)}} -

foo

- {{else}} -

bar

- {{/if}} + class="pt-2 pb-4 {{this.foo}}" + > + {{#each this.data as |chunks|}} + {{#each chunks as |chunk|}} + {{#if (this.shouldShowImage chunk)}} +

foo

+ {{else}} +

bar

+ {{/if}} + {{/each}} {{/each}} - {{/each}} -
`; + `; let ast = parse(template); let block1 = (ast.body[0] as AST.ElementNode).children[1] as AST.BlockStatement; @@ -574,18 +579,18 @@ describe('ember-template-recast', function () { (attribute.value as AST.TextNode).chars = 'foo'; expect(print(ast)).toEqual(`
- {{#each this.data as |chunks|}} - {{#each chunks as |chunk|}} - {{#if (this.shouldShowImage chunk)}} -

foo

- {{else}} -

bar

- {{/if}} + class="pt-2 pb-4 {{this.foo}}" + > + {{#each this.data as |chunks|}} + {{#each chunks as |chunk|}} + {{#if (this.shouldShowImage chunk)}} +

foo

+ {{else}} +

bar

+ {{/if}} + {{/each}} {{/each}} - {{/each}} -
`); + `); }); }); @@ -628,26 +633,26 @@ describe('ember-template-recast', function () { test('rename non-block component', function () { let template = stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - }}`; + {{foo-bar + baz="stuff" + other='single quote' + }}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{baz-derp - baz="stuff" - other='single quote' - }}`); + {{baz-derp + baz="stuff" + other='single quote' + }}`); }); test('MustacheStatements retain whitespace when multiline replacements occur', function () { let template = stripIndent` -

- {{ other-stuff }} - `; +

+ {{ other-stuff }} + `; let { code } = transform(template, (env) => { let { builders: b } = env.syntax; @@ -663,38 +668,38 @@ describe('ember-template-recast', function () { test('can add param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].params.push(builders.path('zomg')); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - zomg - baz=(stuff - goes='here') - }}`); + {{foo-bar + zomg + baz=(stuff + goes='here') + }}`); }); test('can remove param', function () { let template = stripIndent` - {{foo-bar - hhaahahaha - baz=(stuff - goes='here') - }}`; + {{foo-bar + hhaahahaha + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].params.pop(); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`); + {{foo-bar + baz=(stuff + goes='here') + }}`); }); test('replacing empty hash pair on MustacheStatement works', function () { @@ -708,56 +713,56 @@ describe('ember-template-recast', function () { test('infers indentation of hash when multiple HashPairs existed', function () { let template = stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - }}`; + {{foo-bar + baz="stuff" + other='single quote' + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - some="other-thing" - }}`); + {{foo-bar + baz="stuff" + other='single quote' + some="other-thing" + }}`); }); test('infers indentation of hash when no existing hash existed but params do', function () { let template = stripIndent` - {{foo-bar - someParam - }}`; + {{foo-bar + someParam + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - someParam - some="other-thing" - }}`); + {{foo-bar + someParam + some="other-thing" + }}`); }); test('infers indentation of new HashPairs when existing hash with single entry (but no params)', function () { let template = stripIndent` - {{foo-bar - stuff=here - }}`; + {{foo-bar + stuff=here + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - stuff=here - some="other-thing" - }}`); + {{foo-bar + stuff=here + some="other-thing" + }}`); }); test('can add literal hash pair values', function () { let template = stripIndent` - {{foo-bar - first=thing - }}`; + {{foo-bar + first=thing + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.null())); @@ -767,14 +772,14 @@ describe('ember-template-recast', function () { ast.body[0].hash.pairs.push(builders.pair('here', builders.boolean(false))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - first=thing - some=null - other=undefined - things=true - go=42 - here=false - }}`); + {{foo-bar + first=thing + some=null + other=undefined + things=true + go=42 + here=false + }}`); }); test('creating new MustacheStatement with single param has correct whitespace', function () { @@ -799,62 +804,62 @@ describe('ember-template-recast', function () { describe('SubExpression', function () { test('rename path', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.path = builders.path('zomg'); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(zomg - goes='here') - }}`); + {{foo-bar + baz=(zomg + goes='here') + }}`); }); test('can add param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.params.push(builders.path('zomg')); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - zomg - goes='here') - }}`); + {{foo-bar + baz=(stuff + zomg + goes='here') + }}`); }); test('can remove param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - hhaahahaha - goes='here') - }}`; + {{foo-bar + baz=(stuff + hhaahahaha + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.params.pop(); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`); + {{foo-bar + baz=(stuff + goes='here') + }}`); }); test('replacing empty hash pair', function () { let template = stripIndent` - {{foo-bar - baz=(stuff) - }}`; + {{foo-bar + baz=(stuff) + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.hash = builders.hash([ @@ -868,44 +873,44 @@ describe('ember-template-recast', function () { describe('BlockStatement', function () { test('rename block component', function () { let template = stripIndent` - {{#foo-bar - baz="stuff" - }} -
-
- {{/foo-bar}}`; + {{#foo-bar + baz="stuff" + }} +
+
+ {{/foo-bar}}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{#baz-derp - baz="stuff" - }} -
-
- {{/baz-derp}}`); + {{#baz-derp + baz="stuff" + }} +
+
+ {{/baz-derp}}`); }); test('rename block component from longer to shorter name', function () { let template = stripIndent` - {{#this-is-a-long-name - hello="world" - }} -
-
- {{/this-is-a-long-name}}{{someInlineComponent hello="world"}}`; + {{#this-is-a-long-name + hello="world" + }} +
+
+ {{/this-is-a-long-name}}{{someInlineComponent hello="world"}}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{#baz-derp - hello="world" - }} -
-
- {{/baz-derp}}{{someInlineComponent hello="world"}}`); + {{#baz-derp + hello="world" + }} +
+
+ {{/baz-derp}}{{someInlineComponent hello="world"}}`); }); test('replacing a previously empty hash', function () { @@ -1145,41 +1150,41 @@ describe('ember-template-recast', function () { test('remove one block param of many preserves custom whitespace', function () { let template = stripIndent` - {{#foo-bar - as |a b| - }} - {{/foo-bar}} - `; + {{#foo-bar + as |a b| + }} + {{/foo-bar}} + `; let ast = parse(template) as any; ast.body[0].program.blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - {{#foo-bar - as |a| - }} - {{/foo-bar}} - `); - }); - - test('remove only block param preserves custom whitespace', function () { - let template = stripIndent` {{#foo-bar - some=thing as |a| }} {{/foo-bar}} - `; + `); + }); + + test('remove only block param preserves custom whitespace', function () { + let template = stripIndent` + {{#foo-bar + some=thing + as |a| + }} + {{/foo-bar}} + `; let ast = parse(template) as any; ast.body[0].program.blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - {{#foo-bar - some=thing - }} - {{/foo-bar}} - `); + {{#foo-bar + some=thing + }} + {{/foo-bar}} + `); }); }); @@ -1298,10 +1303,7 @@ describe('ember-template-recast', function () { }); test('mutations retain custom whitespace formatting', function () { - let template = stripIndent` - - `; + let template = ''; let ast = parse(template) as any; ast.body[0].attributes[0].value.path.original = 'bar'; @@ -1311,9 +1313,9 @@ describe('ember-template-recast', function () { test('mutations retain textarea whitespace formatting', function () { let template = stripIndent` - - `; + + `; let ast = parse(template); let element = ast.body[0] as AST.ElementNode; @@ -1323,22 +1325,22 @@ describe('ember-template-recast', function () { attrValue.chars = 'bar'; expect(print(ast)).toEqual(stripIndent` - - `); + + `); }); test('mutations in MustacheStatements retain whitespace in AttrNode', function () { let template = stripIndent` -
- hello -
- `; +
+ hello +
+ `; let ast = parse(template) as any; ast.body[0].attributes[0].value.parts[1].params[1].value = 'bar'; @@ -1522,12 +1524,20 @@ describe('ember-template-recast', function () { }); describe('NullLiteral', function () { - test('creating void element', function () { - let template = `{{my-helper null}}`; + test('it should print correctly', function () { + let template = `{{contact-null\n null\n}}`; let ast = parse(template); - expect(print(ast)).toEqual(`{{my-helper null}}`); + const mustache = ast.body[0] as MustacheStatement; + const param = mustache.params[0] as BaseNode; + + // Mark the param as dirty + const oldType = param.type; + param.type = 'ElementNode'; + param.type = oldType; + + expect(print(ast)).toEqual(`{{contact-null\n null\n}}`); }); }); diff --git a/src/parse-result.ts b/src/parse-result.ts index 6ba0bd2d..005530dc 100644 --- a/src/parse-result.ts +++ b/src/parse-result.ts @@ -1109,22 +1109,18 @@ export default class ParseResult { break; case 'BooleanLiteral': case 'NumberLiteral': + case 'NullLiteral': { let { source } = nodeInfo; if (dirtyFields.has('value')) { - source = ast.value.toString(); + source = ast.value?.toString() || ''; dirtyFields.delete('value'); } output.push(source); } break; - case 'NullLiteral': - { - output.push('null'); - } - break; default: throw new Error( `ember-template-recast does not have the ability to update ${original.type}. Please open an issue so we can add support.` From 6bb6faab59938ee4abcc870102e6d7d290ca06ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Molini=C3=A9?= Date: Thu, 13 Jan 2022 09:28:02 +0100 Subject: [PATCH 7/7] rollback all rettier changes --- src/parse-result.test.ts | 518 +++++++++++++++++++-------------------- 1 file changed, 258 insertions(+), 260 deletions(-) diff --git a/src/parse-result.test.ts b/src/parse-result.test.ts index f602b530..003bd0e7 100644 --- a/src/parse-result.test.ts +++ b/src/parse-result.test.ts @@ -1,11 +1,6 @@ import { builders, parse, print, transform } from '.'; import type { ASTv1 as AST } from '@glimmer/syntax'; import stripIndent from 'outdent'; -import { - BaseNode, - MustacheStatement, - NullLiteral, -} from '@glimmer/syntax/dist/types/lib/v1/nodes-v1'; describe('ember-template-recast', function () { describe('ElementNode', function () { @@ -131,20 +126,20 @@ describe('ember-template-recast', function () { test('rename element tagname', function () { let template = stripIndent` -
-
`; +
+
`; let ast = parse(template) as any; ast.body[0].tag = 'a'; expect(print(ast)).toEqual(stripIndent` - - `); + + `); }); test('rename element tagname without children', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].tag = 'a'; @@ -203,13 +198,13 @@ describe('ember-template-recast', function () { test('adding attribute when none originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes.push(builders.attr('data-test', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding attribute to ElementNode with block params', function () { @@ -243,19 +238,19 @@ describe('ember-template-recast', function () { test('adding an attribute to existing list', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes.push(builders.attr('data-test', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('creating an element with complex attributes', function () { @@ -286,19 +281,19 @@ describe('ember-template-recast', function () { test('modifying an attribute name (GH#112)', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].attributes[0].name = 'data-test'; expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('modifying attribute after valueless attribute', function () { @@ -312,19 +307,19 @@ describe('ember-template-recast', function () { test('modifying attribute after valueless attribute with special whitespace', function () { let template = stripIndent` - `; + `; let ast = parse(template) as any; ast.body[0].attributes[1].value.path = builders.path('this.hmmm'); expect(print(ast)).toEqual(stripIndent` - `); + `); }); test('adding attribute after valueless attribute', function () { @@ -347,7 +342,7 @@ describe('ember-template-recast', function () { test('adding modifier when no open parts originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.push( @@ -355,12 +350,12 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding modifier with existing attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.push( @@ -368,7 +363,7 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); // This is specifically testing the issue described in https://github.com/glimmerjs/glimmer-vm/pull/953 @@ -387,46 +382,46 @@ describe('ember-template-recast', function () { test('removing a modifier with other attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.shift(); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('removing a modifier with no other attributes/comments/modifiers', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].modifiers.shift(); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding comment when no open parts originally existed', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].comments.push(builders.mustacheComment(' template-lint-disable ')); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding comment with existing attributes', function () { let template = stripIndent` -
`; +
`; let ast = parse(template) as any; ast.body[0].comments.push(builders.mustacheComment(' template-lint-disable ')); expect(print(ast)).toEqual(stripIndent` -
`); +
`); }); test('adding block param', function () { @@ -449,18 +444,18 @@ describe('ember-template-recast', function () { test('removing a block param preserves formatting of "open element closing"', function () { let template = stripIndent` - `; + `; let ast = parse(template) as any; ast.body[0].blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - `); + `); }); test('interleaved attributes and modifiers are not modified when unchanged', function () { @@ -476,10 +471,10 @@ describe('ember-template-recast', function () { test('adding children to element with children', function () { let template = stripIndent` -
    -
  • -
- `; +
    +
  • +
+ `; let ast = parse(template) as any; ast.body[0].children.splice( @@ -490,11 +485,11 @@ describe('ember-template-recast', function () { ); expect(print(ast)).toEqual(stripIndent` -
    -
  • -
  • -
- `); +
    +
  • +
  • +
+ `); }); test('adding children to an empty element', function () { @@ -517,10 +512,10 @@ describe('ember-template-recast', function () { test('moving a child to another ElementNode', function () { let template = stripIndent` - {{ - special-formatting-here - }} - `; + {{ + special-formatting-here + }} + `; let ast = parse(template) as any; let child = ast.body[0].children.pop(); @@ -528,47 +523,47 @@ describe('ember-template-recast', function () { ast.body.unshift(child); expect(print(ast)).toEqual(stripIndent` - {{ - special-formatting-here - }} - - `); + {{ + special-formatting-here + }} + + `); }); test('adding a new attribute to an ElementNode while preserving the existing whitespaces', function () { let template = stripIndent` -
-
- `; +
+
+ `; let ast = parse(template); let element = ast.body[0] as AST.ElementNode; element.attributes.push(builders.attr('foo-foo', builders.text('wheee'))); expect(print(ast)).toEqual(stripIndent` -
-
- `); +
+
+ `); }); test('issue 706', function () { let template = `
- {{#each this.data as |chunks|}} - {{#each chunks as |chunk|}} - {{#if (this.shouldShowImage chunk)}} -

foo

- {{else}} -

bar

- {{/if}} - {{/each}} + class="pt-2 pb-4 {{this.foo}}" +> + {{#each this.data as |chunks|}} + {{#each chunks as |chunk|}} + {{#if (this.shouldShowImage chunk)}} +

foo

+ {{else}} +

bar

+ {{/if}} {{/each}} -
`; + {{/each}} +`; let ast = parse(template); let block1 = (ast.body[0] as AST.ElementNode).children[1] as AST.BlockStatement; @@ -579,18 +574,18 @@ describe('ember-template-recast', function () { (attribute.value as AST.TextNode).chars = 'foo'; expect(print(ast)).toEqual(`
- {{#each this.data as |chunks|}} - {{#each chunks as |chunk|}} - {{#if (this.shouldShowImage chunk)}} -

foo

- {{else}} -

bar

- {{/if}} - {{/each}} + class="pt-2 pb-4 {{this.foo}}" +> + {{#each this.data as |chunks|}} + {{#each chunks as |chunk|}} + {{#if (this.shouldShowImage chunk)}} +

foo

+ {{else}} +

bar

+ {{/if}} {{/each}} -
`); + {{/each}} +`); }); }); @@ -633,26 +628,26 @@ describe('ember-template-recast', function () { test('rename non-block component', function () { let template = stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - }}`; + {{foo-bar + baz="stuff" + other='single quote' + }}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{baz-derp - baz="stuff" - other='single quote' - }}`); + {{baz-derp + baz="stuff" + other='single quote' + }}`); }); test('MustacheStatements retain whitespace when multiline replacements occur', function () { let template = stripIndent` -

- {{ other-stuff }} - `; +

+ {{ other-stuff }} + `; let { code } = transform(template, (env) => { let { builders: b } = env.syntax; @@ -668,38 +663,38 @@ describe('ember-template-recast', function () { test('can add param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].params.push(builders.path('zomg')); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - zomg - baz=(stuff - goes='here') - }}`); + {{foo-bar + zomg + baz=(stuff + goes='here') + }}`); }); test('can remove param', function () { let template = stripIndent` - {{foo-bar - hhaahahaha - baz=(stuff - goes='here') - }}`; + {{foo-bar + hhaahahaha + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].params.pop(); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`); + {{foo-bar + baz=(stuff + goes='here') + }}`); }); test('replacing empty hash pair on MustacheStatement works', function () { @@ -713,56 +708,56 @@ describe('ember-template-recast', function () { test('infers indentation of hash when multiple HashPairs existed', function () { let template = stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - }}`; + {{foo-bar + baz="stuff" + other='single quote' + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz="stuff" - other='single quote' - some="other-thing" - }}`); + {{foo-bar + baz="stuff" + other='single quote' + some="other-thing" + }}`); }); test('infers indentation of hash when no existing hash existed but params do', function () { let template = stripIndent` - {{foo-bar - someParam - }}`; + {{foo-bar + someParam + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - someParam - some="other-thing" - }}`); + {{foo-bar + someParam + some="other-thing" + }}`); }); test('infers indentation of new HashPairs when existing hash with single entry (but no params)', function () { let template = stripIndent` - {{foo-bar - stuff=here - }}`; + {{foo-bar + stuff=here + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.string('other-thing'))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - stuff=here - some="other-thing" - }}`); + {{foo-bar + stuff=here + some="other-thing" + }}`); }); test('can add literal hash pair values', function () { let template = stripIndent` - {{foo-bar - first=thing - }}`; + {{foo-bar + first=thing + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs.push(builders.pair('some', builders.null())); @@ -772,14 +767,14 @@ describe('ember-template-recast', function () { ast.body[0].hash.pairs.push(builders.pair('here', builders.boolean(false))); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - first=thing - some=null - other=undefined - things=true - go=42 - here=false - }}`); + {{foo-bar + first=thing + some=null + other=undefined + things=true + go=42 + here=false + }}`); }); test('creating new MustacheStatement with single param has correct whitespace', function () { @@ -804,62 +799,62 @@ describe('ember-template-recast', function () { describe('SubExpression', function () { test('rename path', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.path = builders.path('zomg'); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(zomg - goes='here') - }}`); + {{foo-bar + baz=(zomg + goes='here') + }}`); }); test('can add param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`; + {{foo-bar + baz=(stuff + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.params.push(builders.path('zomg')); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - zomg - goes='here') - }}`); + {{foo-bar + baz=(stuff + zomg + goes='here') + }}`); }); test('can remove param', function () { let template = stripIndent` - {{foo-bar - baz=(stuff - hhaahahaha - goes='here') - }}`; + {{foo-bar + baz=(stuff + hhaahahaha + goes='here') + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.params.pop(); expect(print(ast)).toEqual(stripIndent` - {{foo-bar - baz=(stuff - goes='here') - }}`); + {{foo-bar + baz=(stuff + goes='here') + }}`); }); test('replacing empty hash pair', function () { let template = stripIndent` - {{foo-bar - baz=(stuff) - }}`; + {{foo-bar + baz=(stuff) + }}`; let ast = parse(template) as any; ast.body[0].hash.pairs[0].value.hash = builders.hash([ @@ -873,44 +868,44 @@ describe('ember-template-recast', function () { describe('BlockStatement', function () { test('rename block component', function () { let template = stripIndent` - {{#foo-bar - baz="stuff" - }} -
-
- {{/foo-bar}}`; + {{#foo-bar + baz="stuff" + }} +
+
+ {{/foo-bar}}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{#baz-derp - baz="stuff" - }} -
-
- {{/baz-derp}}`); + {{#baz-derp + baz="stuff" + }} +
+
+ {{/baz-derp}}`); }); test('rename block component from longer to shorter name', function () { let template = stripIndent` - {{#this-is-a-long-name - hello="world" - }} -
-
- {{/this-is-a-long-name}}{{someInlineComponent hello="world"}}`; + {{#this-is-a-long-name + hello="world" + }} +
+
+ {{/this-is-a-long-name}}{{someInlineComponent hello="world"}}`; let ast = parse(template) as any; ast.body[0].path = builders.path('baz-derp'); expect(print(ast)).toEqual(stripIndent` - {{#baz-derp - hello="world" - }} -
-
- {{/baz-derp}}{{someInlineComponent hello="world"}}`); + {{#baz-derp + hello="world" + }} +
+
+ {{/baz-derp}}{{someInlineComponent hello="world"}}`); }); test('replacing a previously empty hash', function () { @@ -1150,41 +1145,41 @@ describe('ember-template-recast', function () { test('remove one block param of many preserves custom whitespace', function () { let template = stripIndent` - {{#foo-bar - as |a b| - }} - {{/foo-bar}} - `; + {{#foo-bar + as |a b| + }} + {{/foo-bar}} + `; let ast = parse(template) as any; ast.body[0].program.blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - {{#foo-bar - as |a| - }} - {{/foo-bar}} - `); + {{#foo-bar + as |a| + }} + {{/foo-bar}} + `); }); test('remove only block param preserves custom whitespace', function () { let template = stripIndent` - {{#foo-bar - some=thing - as |a| - }} - {{/foo-bar}} - `; + {{#foo-bar + some=thing + as |a| + }} + {{/foo-bar}} + `; let ast = parse(template) as any; ast.body[0].program.blockParams.pop(); expect(print(ast)).toEqual(stripIndent` - {{#foo-bar - some=thing - }} - {{/foo-bar}} - `); + {{#foo-bar + some=thing + }} + {{/foo-bar}} + `); }); }); @@ -1303,7 +1298,10 @@ describe('ember-template-recast', function () { }); test('mutations retain custom whitespace formatting', function () { - let template = ''; + let template = stripIndent` + + `; let ast = parse(template) as any; ast.body[0].attributes[0].value.path.original = 'bar'; @@ -1313,9 +1311,9 @@ describe('ember-template-recast', function () { test('mutations retain textarea whitespace formatting', function () { let template = stripIndent` - - `; + + `; let ast = parse(template); let element = ast.body[0] as AST.ElementNode; @@ -1325,22 +1323,22 @@ describe('ember-template-recast', function () { attrValue.chars = 'bar'; expect(print(ast)).toEqual(stripIndent` - - `); + + `); }); test('mutations in MustacheStatements retain whitespace in AttrNode', function () { let template = stripIndent` -
- hello -
- `; +
+ hello +
+ `; let ast = parse(template) as any; ast.body[0].attributes[0].value.parts[1].params[1].value = 'bar'; @@ -1529,8 +1527,8 @@ describe('ember-template-recast', function () { let ast = parse(template); - const mustache = ast.body[0] as MustacheStatement; - const param = mustache.params[0] as BaseNode; + const mustache = ast.body[0] as AST.MustacheStatement; + const param = mustache.params[0] as AST.BaseNode; // Mark the param as dirty const oldType = param.type;