From 2bb395b2224d9f313892bbb96dc3ad45b015fa1a Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 27 Aug 2019 19:19:39 +0300 Subject: [PATCH] test: heredoc and nowdoc --- src/ast.js | 9 +- .../__snapshots__/heredoc.test.js.snap | 423 ++++++++++++++++++ .../__snapshots__/nowdoc.test.js.snap | 223 +++++++++ test/snapshot/heredoc.test.js | 79 ++++ test/snapshot/nowdoc.test.js | 67 +++ 5 files changed, 795 insertions(+), 6 deletions(-) create mode 100644 test/snapshot/__snapshots__/heredoc.test.js.snap create mode 100644 test/snapshot/__snapshots__/nowdoc.test.js.snap create mode 100644 test/snapshot/heredoc.test.js create mode 100644 test/snapshot/nowdoc.test.js diff --git a/src/ast.js b/src/ast.js index 0c2c5ea8a..2c7c5ab7b 100644 --- a/src/ast.js +++ b/src/ast.js @@ -323,18 +323,15 @@ AST.prototype.resolvePrecedence = function(result, parser) { result = buffer; } } - } else if ( - result.kind === "silent" && - !result.expr.parenthesizedExpression - ) { - if (result.expr.kind === 'assign') return result; + } else if (result.kind === "silent" && !result.expr.parenthesizedExpression) { + if (result.expr.kind === "assign") return result; // overall least precedence if (result.expr.right) { buffer = result.expr; result.expr = buffer.left; buffer.left = result; this.swapLocations(buffer, buffer.left, buffer.right, parser); - result = buffer; + result = buffer; } } return result; diff --git a/test/snapshot/__snapshots__/heredoc.test.js.snap b/test/snapshot/__snapshots__/heredoc.test.js.snap new file mode 100644 index 000000000..141bccc68 --- /dev/null +++ b/test/snapshot/__snapshots__/heredoc.test.js.snap @@ -0,0 +1,423 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`heredoc inside call 1`] = ` +Program { + "children": Array [ + ExpressionStatement { + "expression": Call { + "arguments": Array [ + Array { + "items": Array [ + Encapsed { + "kind": "encapsed", + "label": "EOD", + "raw": " +foobar! +EOD +", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "foobar! +", + "unicode": false, + "value": "foobar! +", + }, + "kind": "encapsedpart", + }, + ], + }, + ], + "kind": "array", + "shortForm": false, + }, + ], + "kind": "call", + "what": ClassReference { + "kind": "classreference", + "name": "var_dump", + "resolution": "uqn", + }, + }, + "kind": "expressionstatement", + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`heredoc inside class 1`] = ` +Program { + "children": Array [ + Class { + "body": Array [ + ClassConstant { + "constants": Array [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "BAR", + }, + "value": Encapsed { + "kind": "encapsed", + "label": "FOOBAR", + "raw": " +Constant example +FOOBAR", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "Constant example +", + "unicode": false, + "value": "Constant example +", + }, + "kind": "encapsedpart", + }, + ], + }, + }, + ], + "kind": "classconstant", + "visibility": "", + }, + PropertyStatement { + "isStatic": false, + "kind": "propertystatement", + "properties": Array [ + Property { + "kind": "property", + "name": Identifier { + "kind": "identifier", + "name": "baz", + }, + "value": Encapsed { + "kind": "encapsed", + "label": "FOOBAR", + "raw": " +Property example +FOOBAR", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "Property example +", + "unicode": false, + "value": "Property example +", + }, + "kind": "encapsedpart", + }, + ], + }, + }, + ], + "visibility": "public", + }, + ], + "extends": null, + "implements": null, + "isAbstract": false, + "isAnonymous": false, + "isFinal": false, + "kind": "class", + "name": Identifier { + "kind": "identifier", + "name": "foo", + }, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`heredoc inside function 1`] = ` +Program { + "children": Array [ + _Function { + "arguments": Array [], + "body": Block { + "children": Array [ + Static { + "kind": "static", + "variables": Array [ + StaticVariable { + "defaultValue": Encapsed { + "kind": "encapsed", + "label": "LABEL", + "raw": " +Nothing in here... +LABEL", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "Nothing in here... +", + "unicode": false, + "value": "Nothing in here... +", + }, + "kind": "encapsedpart", + }, + ], + }, + "kind": "staticvariable", + "variable": Variable { + "curly": false, + "kind": "variable", + "name": "bar", + }, + }, + ], + }, + ], + "kind": "block", + }, + "byref": false, + "kind": "function", + "name": Identifier { + "kind": "identifier", + "name": "foo", + }, + "nullable": false, + "type": null, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`heredoc simple 1`] = ` +Program { + "children": Array [ + Echo { + "expressions": Array [ + Encapsed { + "kind": "encapsed", + "label": "EOD", + "raw": " +Example of string +spanning multiple lines +using heredoc syntax. +EOD", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "Example of string +spanning multiple lines +using heredoc syntax. +", + "unicode": false, + "value": "Example of string +spanning multiple lines +using heredoc syntax. +", + }, + "kind": "encapsedpart", + }, + ], + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`heredoc with double quotes 1`] = ` +Program { + "children": Array [ + Echo { + "expressions": Array [ + Encapsed { + "kind": "encapsed", + "label": "EOD", + "raw": " +Example of string +spanning multiple lines +using heredoc syntax. +EOD", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "Example of string +spanning multiple lines +using heredoc syntax. +", + "unicode": false, + "value": "Example of string +spanning multiple lines +using heredoc syntax. +", + }, + "kind": "encapsedpart", + }, + ], + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`heredoc with variables 1`] = ` +Program { + "children": Array [ + Echo { + "expressions": Array [ + Encapsed { + "kind": "encapsed", + "label": "EOT", + "raw": " +My name is \\"$name\\". I am printing some $foo->foo. +Now, I am printing some {$foo->bar[1]}. +This should print a capital 'A': A +EOT", + "type": "heredoc", + "value": Array [ + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "My name is \\"", + "unicode": false, + "value": "My name is \\"", + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": false, + "expression": Variable { + "curly": false, + "kind": "variable", + "name": "name", + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "\\". I am printing some ", + "unicode": false, + "value": "\\". I am printing some ", + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": false, + "expression": PropertyLookup { + "kind": "propertylookup", + "offset": Identifier { + "kind": "identifier", + "name": "foo", + }, + "what": Variable { + "curly": false, + "kind": "variable", + "name": "foo", + }, + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": ". +Now, I am printing some ", + "unicode": false, + "value": ". +Now, I am printing some ", + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": true, + "expression": OffsetLookup { + "kind": "offsetlookup", + "offset": Number { + "kind": "number", + "value": "1", + }, + "what": PropertyLookup { + "kind": "propertylookup", + "offset": Identifier { + "kind": "identifier", + "name": "bar", + }, + "what": Variable { + "curly": false, + "kind": "variable", + "name": "foo", + }, + }, + }, + "kind": "encapsedpart", + }, + EncapsedPart { + "curly": false, + "expression": String { + "isDoubleQuote": false, + "kind": "string", + "raw": ". +This should print a capital 'A': A +", + "unicode": false, + "value": ". +This should print a capital 'A': A +", + }, + "kind": "encapsedpart", + }, + ], + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; diff --git a/test/snapshot/__snapshots__/nowdoc.test.js.snap b/test/snapshot/__snapshots__/nowdoc.test.js.snap new file mode 100644 index 000000000..ff54b0a35 --- /dev/null +++ b/test/snapshot/__snapshots__/nowdoc.test.js.snap @@ -0,0 +1,223 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`nowdoc inside call 1`] = ` +Program { + "children": Array [ + ExpressionStatement { + "expression": Call { + "arguments": Array [ + Array { + "items": Array [ + Nowdoc { + "kind": "nowdoc", + "label": "EOD", + "quote": true, + "raw": "<<<'EOD' +foobar! +EOD +)); + ", + "value": "foobar!", + }, + ], + "kind": "array", + "shortForm": false, + }, + ], + "kind": "call", + "what": ClassReference { + "kind": "classreference", + "name": "var_dump", + "resolution": "uqn", + }, + }, + "kind": "expressionstatement", + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`nowdoc inside class 1`] = ` +Program { + "children": Array [ + Class { + "body": Array [ + ClassConstant { + "constants": Array [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "BAR", + }, + "value": Nowdoc { + "kind": "nowdoc", + "label": "FOOBAR", + "quote": true, + "raw": "<<<'FOOBAR' +Constant example +FOOBAR; + + public $baz = <<<'FOOBAR' +Property example +FOOBAR; +} + ", + "value": "Constant example", + }, + }, + ], + "kind": "classconstant", + "visibility": "", + }, + PropertyStatement { + "isStatic": false, + "kind": "propertystatement", + "properties": Array [ + Property { + "kind": "property", + "name": Identifier { + "kind": "identifier", + "name": "baz", + }, + "value": Nowdoc { + "kind": "nowdoc", + "label": "FOOBAR", + "quote": true, + "raw": "<<<'FOOBAR' +Property example +FOOBAR; +} + ", + "value": "Property example", + }, + }, + ], + "visibility": "public", + }, + ], + "extends": null, + "implements": null, + "isAbstract": false, + "isAnonymous": false, + "isFinal": false, + "kind": "class", + "name": Identifier { + "kind": "identifier", + "name": "foo", + }, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`nowdoc inside function 1`] = ` +Program { + "children": Array [ + _Function { + "arguments": Array [], + "body": Block { + "children": Array [ + Static { + "kind": "static", + "variables": Array [ + StaticVariable { + "defaultValue": Nowdoc { + "kind": "nowdoc", + "label": "LABEL", + "quote": true, + "raw": "<<<'LABEL' +Nothing in here... +LABEL; +} + ", + "value": "Nothing in here...", + }, + "kind": "staticvariable", + "variable": Variable { + "curly": false, + "kind": "variable", + "name": "bar", + }, + }, + ], + }, + ], + "kind": "block", + }, + "byref": false, + "kind": "function", + "name": Identifier { + "kind": "identifier", + "name": "foo", + }, + "nullable": false, + "type": null, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`nowdoc simple 1`] = ` +Program { + "children": Array [ + Echo { + "expressions": Array [ + Nowdoc { + "kind": "nowdoc", + "label": "EOD", + "quote": true, + "raw": "<<<'EOD' +Example of string +spanning multiple lines +using heredoc syntax. +EOD; + ", + "value": "Example of string +spanning multiple lines +using heredoc syntax.", + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`nowdoc with variables 1`] = ` +Program { + "children": Array [ + Echo { + "expressions": Array [ + Nowdoc { + "kind": "nowdoc", + "label": "EOT", + "quote": true, + "raw": "<<<'EOT' +My name is \\"$name\\". I am printing some $foo->foo. +Now, I am printing some {$foo->bar[1]}. +This should print a capital 'A': A +EOT; + ", + "value": "My name is \\"$name\\". I am printing some $foo->foo. +Now, I am printing some {$foo->bar[1]}. +This should print a capital 'A': A", + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; diff --git a/test/snapshot/heredoc.test.js b/test/snapshot/heredoc.test.js new file mode 100644 index 000000000..023486286 --- /dev/null +++ b/test/snapshot/heredoc.test.js @@ -0,0 +1,79 @@ +const parser = require("../main"); + +describe("heredoc", function() { + it("simple", function() { + expect( + parser.parseEval(` +echo <<foo. +Now, I am printing some {$foo->bar[1]}. +This should print a capital 'A': \x41 +EOT; + `) + ).toMatchSnapshot(); + }); + + it("inside call", function() { + expect( + parser.parseEval(` +var_dump(array(<<foo. +Now, I am printing some {$foo->bar[1]}. +This should print a capital 'A': \x41 +EOT; + `) + ).toMatchSnapshot(); + }); + + it("inside call", function() { + expect( + parser.parseEval(` +var_dump(array(<<<'EOD' +foobar! +EOD +)); + `) + ).toMatchSnapshot(); + }); + + it("inside function", function() { + expect( + parser.parseEval(` +function foo() +{ + static $bar = <<<'LABEL' +Nothing in here... +LABEL; +} + `) + ).toMatchSnapshot(); + }); + + it("inside class", function() { + expect( + parser.parseEval(` +class foo { + const BAR = <<<'FOOBAR' +Constant example +FOOBAR; + + public $baz = <<<'FOOBAR' +Property example +FOOBAR; +} + `) + ).toMatchSnapshot(); + }); +});