/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at . */ import mapExpressionBindings from "../mapBindings"; import { parseConsoleScript } from "../utils/ast"; import cases from "jest-in-case"; const prettier = require("prettier"); function format(code) { return prettier.format(code, { semi: false, parser: "babel" }); } function excludedTest({ name, expression, bindings = [] }) { const safeExpression = mapExpressionBindings( expression, parseConsoleScript(expression), bindings ); expect(format(safeExpression)).toEqual(format(expression)); } function includedTest({ name, expression, newExpression, bindings }) { const safeExpression = mapExpressionBindings( expression, parseConsoleScript(expression), bindings ); expect(format(safeExpression)).toEqual(format(newExpression)); } describe("mapExpressionBindings", () => { cases("included cases", includedTest, [ { name: "single declaration", expression: "const a = 2; let b = 3; var c = 4;", newExpression: "self.a = 2; self.b = 3; self.c = 4;", }, { name: "multiple declarations", expression: "const a = 2, b = 3", newExpression: "self.a = 2; self.b = 3", }, { name: "declaration with separate assignment", expression: "let a; a = 2;", newExpression: "self.a = void 0; self.a = 2;", }, { name: "multiple declarations with no assignment", expression: "let a = 2, b;", newExpression: "self.a = 2; self.b = void 0;", }, { name: "local bindings become assignments", bindings: ["a"], expression: "var a = 2;", newExpression: "a = 2;", }, { name: "assignments", expression: "a = 2;", newExpression: "self.a = 2;", }, { name: "assignments with +=", expression: "a += 2;", newExpression: "self.a += 2;", }, { name: "destructuring (objects)", expression: "const { a } = {}; ", newExpression: "({ a: self.a } = {})", }, { name: "destructuring (arrays)", expression: " var [a, ...foo] = [];", newExpression: "([self.a, ...self.foo] = [])", }, { name: "destructuring (declarations)", expression: "var {d,e} = {}, {f} = {}; ", newExpression: `({ d: self.d, e: self.e } = {}); ({ f: self.f } = {}) `, }, { name: "destructuring & declaration", expression: "const { a } = {}; var b = 3", newExpression: `({ a: self.a } = {}); self.b = 3 `, }, { name: "destructuring assignment", expression: "[a] = [3]", newExpression: "[self.a] = [3]", }, { name: "destructuring assignment (declarations)", expression: "[a] = [3]; var b = 4", newExpression: "[self.a] = [3];\n self.b = 4", }, ]); cases("excluded cases", excludedTest, [ { name: "local variables", expression: "function a() { var b = 2}" }, { name: "functions", expression: "function a() {}" }, { name: "classes", expression: "class a {}" }, { name: "with", expression: "with (obj) {var a = 2;}" }, { name: "with & declaration", expression: "with (obj) {var a = 2;}; ; var b = 3", }, { name: "hoisting", expression: "{ const h = 3; }", }, { name: "assignments", bindings: ["a"], expression: "a = 2;", }, { name: "identifier", expression: "a", }, ]); cases("cases that we should map in the future", excludedTest, [ { name: "blocks (IF)", expression: "if (true) { var a = 3; }" }, { name: "hoisting", expression: "{ var g = 5; }", }, { name: "for loops bindings", expression: "for (let foo = 4; false;){}", }, ]); cases("cases that we shouldn't map in the future", includedTest, [ { name: "window properties", expression: "var innerHeight = 3; var location = 5;", newExpression: "self.innerHeight = 3; self.location = 5;", }, { name: "self declaration", expression: "var self = 3", newExpression: "self.self = 3", }, { name: "self assignment", expression: "self = 3", newExpression: "self.self = 3", }, ]); });