From 66062c2a8ce2122dd20b487ce46beee76ef14175 Mon Sep 17 00:00:00 2001 From: "Michael J. Currie" Date: Thu, 26 Sep 2019 12:58:36 -0500 Subject: [PATCH] Template literal validation (#10492) * add template literal validation * avoid null/undefined error when validating * simplify validation logic and fix tests Co-authored-by: Michael J. Currie --- .../babel-types/src/definitions/es2015.js | 10 ++++ .../__snapshots__/templateElement.js.snap | 58 +++++++++++++++++++ .../test/builders/es2015/templateElement.js | 29 ++++++++++ 3 files changed, 97 insertions(+) diff --git a/packages/babel-types/src/definitions/es2015.js b/packages/babel-types/src/definitions/es2015.js index 18649b1df1..53f3c1f3df 100644 --- a/packages/babel-types/src/definitions/es2015.js +++ b/packages/babel-types/src/definitions/es2015.js @@ -574,6 +574,16 @@ defineType("TemplateLiteral", { validate: chain( assertValueType("array"), assertEach(assertNodeType("Expression")), + function(node, key, val) { + if (node.quasis.length !== val.length + 1) { + throw new TypeError( + `Number of ${ + node.type + } quasis should be exactly one more than the number of expressions.\nExpected ${val.length + + 1} quasis but got ${node.quasis.length}`, + ); + } + }, ), }, }, diff --git a/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap b/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap index a2f1781692..2915dd3794 100644 --- a/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap +++ b/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap @@ -35,3 +35,61 @@ exports[`builders es2015 templateElement should validate 5`] = ` "Property value of TemplateElement expected to have the following: Property raw expected type of string but got undefined" `; + +exports[`builders es2015 templateLiteral should validate 1`] = ` +Object { + "expressions": Array [], + "quasis": Array [ + Object { + "tail": false, + "type": "TemplateElement", + "value": Object { + "raw": "foo", + }, + }, + ], + "type": "TemplateLiteral", +} +`; + +exports[`builders es2015 templateLiteral should validate 2`] = ` +Object { + "expressions": Array [ + Object { + "type": "StringLiteral", + "value": "baz", + }, + ], + "quasis": Array [ + Object { + "tail": false, + "type": "TemplateElement", + "value": Object { + "raw": "foo", + }, + }, + Object { + "tail": false, + "type": "TemplateElement", + "value": Object { + "raw": "bar", + }, + }, + ], + "type": "TemplateLiteral", +} +`; + +exports[`builders es2015 templateLiteral should validate 3`] = ` +"Number of TemplateLiteral quasis should be exactly one more than the number of expressions. +Expected 3 quasis but got 2" +`; + +exports[`builders es2015 templateLiteral should validate 4`] = ` +"Number of TemplateLiteral quasis should be exactly one more than the number of expressions. +Expected 1 quasis but got 2" +`; + +exports[`builders es2015 templateLiteral should validate 5`] = `"Property quasis expected type of array but got object"`; + +exports[`builders es2015 templateLiteral should validate 6`] = `"Property expressions expected type of array but got null"`; diff --git a/packages/babel-types/test/builders/es2015/templateElement.js b/packages/babel-types/test/builders/es2015/templateElement.js index 0a93e7c866..0e5985ae89 100644 --- a/packages/babel-types/test/builders/es2015/templateElement.js +++ b/packages/babel-types/test/builders/es2015/templateElement.js @@ -21,5 +21,34 @@ describe("builders", function() { expect(() => t.templateElement("foo")).toThrowErrorMatchingSnapshot(); }); }); + describe("templateLiteral", function() { + it("should validate", function() { + const foo = t.templateElement({ raw: "foo" }); + const bar = t.templateElement({ raw: "bar" }); + + const baz = t.stringLiteral("baz"); + const qux = t.stringLiteral("qux"); + + expect(t.templateLiteral([foo], [])).toMatchSnapshot(); + + expect(t.templateLiteral([foo, bar], [baz])).toMatchSnapshot(); + + expect(() => + t.templateLiteral([foo, bar], [baz, qux]), + ).toThrowErrorMatchingSnapshot(); + + expect(() => + t.templateLiteral([foo, bar], []), + ).toThrowErrorMatchingSnapshot(); + + expect(() => + t.templateLiteral({}, [baz]), + ).toThrowErrorMatchingSnapshot(); + + expect(() => + t.templateLiteral([foo, bar]), + ).toThrowErrorMatchingSnapshot(); + }); + }); }); });