react / wstein / node_modules / react / node_modules / envify / node_modules / jstransform / visitors / __tests__ / es6-template-visitors-test.js
80552 views/**1* @emails [email protected]2*/34/*jshint evil:true*/56require('mock-modules').autoMockOff();78describe('ES6 Template Visitor', function() {9var transformFn;10var visitors;1112beforeEach(function() {13require('mock-modules').dumpCache();14visitors = require('../es6-template-visitors').visitorList;15transformFn = require('../../src/jstransform').transform;16});1718function transform(code) {19return transformFn(visitors, code).code;20}2122function expectTransform(code, result) {23expect(transform(code)).toEqual(result);24}2526function expectEval(code, result, setupFn) {27var actual;28if (setupFn) {29eval(setupFn);30}31eval('actual = ' + transform(code));32expect(actual).toEqual(result);33}3435function expectEvalTag(code, tagFn, scope) {36/*jshint unused:false*/37if (scope) {38Object.keys(scope).forEach((key) => this[key] = scope[key]);39}4041var tagCalls = 0;42var tag = function(...args) {43tagCalls++;44return tagFn.apply(this, args);45};46var result = transform(code);47expect(result.split('\n').length).toBe(code.split('\n').length);48eval(result);49expect(tagCalls).toBe(1);50}5152function expectSiteObj(siteObj, cooked, raw) {53expect(Array.isArray(siteObj)).toBe(true);54expect(Object.isFrozen(siteObj)).toBe(true);55expect(Array.isArray(siteObj.raw)).toBe(true);56expect(Object.isFrozen(siteObj.raw)).toBe(true);57expect(siteObj.length).toBe(cooked.length);58expect(siteObj.raw.length).toBe(raw.length);59for (var ii = 0; ii < cooked.length; ii++) {60expect(siteObj[ii]).toEqual(cooked[ii]);61}62expect(siteObj.raw).toEqual(raw);63}6465it('should transform simple literals', function() {66expectTransform('`foo bar`', '("foo bar")');6768expectEval('`foo bar`', 'foo bar');69expectEval('`$`', '$');70expectEval('`$foo`', '$foo');71});7273it('should properly escape templates containing quotes', function() {74expectTransform('`foo "bar"`', '("foo \\"bar\\"")');75expectEval('`foo "bar"`', 'foo "bar"');7677expectTransform("`foo 'bar'`", '("foo \'bar\'")');78expectEval("`foo 'bar'`", "foo 'bar'");7980// `foo \\"bar\\"` (foo, literal slash, "bar", literal slash)81expectTransform('`foo \\\\"bar\\\\"`', '("foo \\\\\\"bar\\\\\\"")');82expectEval('`foo \\\\\\"bar\\\\\\"`', 'foo \\"bar\\"');83});8485it('should transform simple substitutions', function() {86expectTransform('`foo ${bar}`', '("foo " + bar)');87expectTransform('`${foo} bar`', '(foo + " bar")');88expectTransform('`${foo} ${bar}`', '(foo + " " + bar)');89expectTransform('`${foo}${bar}`', '(foo + bar)');90});9192it('should transform expressions', function() {93expectTransform('`foo ${bar()}`', '("foo " + bar())');94expectTransform('`foo ${bar.baz}`', '("foo " + bar.baz)');95expectTransform('`foo ${bar + 5}`', '("foo " + (bar + 5))');96expectTransform('`${foo + 5} bar`', '((foo + 5) + " bar")');97expectTransform('`${foo + 5} ${bar}`', '((foo + 5) + " " + bar)');98expectTransform(99'`${(function(b) {alert(4);})(a)}`',100'((function(b) {alert(4);})(a))');101});102103it('should transform tags with simple templates', function() {104/*jshint unused:false*/105var tag = function(elements) {106expectSiteObj(elements, ['foo bar'], ['foo bar']);107};108var result = transform("tag`foo bar`");109expect(result.split('\n').length).toBe(1);110eval(result);111112var a = { b: tag };113eval(transform("a.b`foo bar`"));114eval(transform("a['b']`foo bar`"));115116var getTag = function() { return tag; };117eval(transform("getTag()`foo bar`"));118eval(transform("(getTag())`foo bar`"));119});120121it('should transform tags with substitutions', function() {122expectTransform(123"tag`foo ${bar} baz`",124'tag(function() { var siteObj = ["foo ", " baz"]; ' +125'siteObj.raw = ["foo ", " baz"]; Object.freeze(siteObj.raw); ' +126'Object.freeze(siteObj); return siteObj; }(), bar)'127);128129expectEvalTag(130"tag`foo ${bar + 'abc'} baz`",131function(elements, ...args) {132expectSiteObj(elements, ['foo ', ' baz'], ['foo ', ' baz']);133expect(args.length).toBe(1);134expect(args[0]).toBe('barabc');135},136{bar: 'bar'}137);138139expectEvalTag(140"tag`foo ${bar + 'abc'}`",141function(elements, ...args) {142expectSiteObj(elements, ['foo ', ''], ['foo ', '']);143expect(args.length).toBe(1);144expect(args[0]).toBe('barabc');145},146{bar: 'bar'}147);148149expectEvalTag(150"tag`foo\n\n\nbar`",151(elements) => {152expectSiteObj(elements, ['foo\n\n\nbar'], ['foo\n\n\nbar']);153}154);155156expectEvalTag(157"tag`a\nb\n${c}\nd`",158(elements, ...args) => {159expectSiteObj(elements, ['a\nb\n', '\nd'], ['a\nb\n', '\nd']);160expect(args.length).toBe(1);161expect(args[0]).toBe('c');162},163{c: 'c'}164);165});166167it('should maintain line numbers', function() {168expectTransform("`foo\n\nbar`", '("foo\\n\\nbar"\n\n)');169expectTransform("`foo\n${bar}\nbaz`", '("foo\\n" + \nbar + "\\nbaz"\n)');170expectTransform("`foo\\nbar`", '("foo\\nbar")');171172expectTransform(173"tag`a\nb\n${c}${d}\ne`",174'tag(function() { var siteObj = ["a\\nb\\n", "", "\\ne"]; ' +175'siteObj.raw = ["a\\nb\\n", "", "\\ne"]; Object.freeze(siteObj.raw); ' +176'Object.freeze(siteObj); return siteObj; }(), \n\nc, d\n)'177);178});179180it('should handle multiple lines', function() {181expectEval("`foo\n\nbar`", 'foo\n\nbar');182expectEval("`foo\\nbar`", 'foo\nbar');183expectEval("`foo\\\\nbar`", 'foo\\nbar');184expectEval("`foo\n${bar}\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');185});186187it('should canonicalize line endings', function() {188// TODO: should this be '("foo\\nbar"\r\n)' to maintain the number of lines189// for editors that break on \r\n? I don't think we care in the transformed190// code.191expectTransform("`foo\r\nbar`", '("foo\\nbar"\n)');192// TODO: same as above but with trailing \r193expectTransform("`foo\rbar`", '("foo\\nbar")');194195expectEval("`foo\r\nbar`", 'foo\nbar');196expectEval("`foo\rbar`", 'foo\nbar');197expectEval("`foo\r\n${bar}\r\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');198199expectEvalTag(200"tag`foo\rbar`",201(elements) => {202expectSiteObj(elements, ['foo\nbar'], ['foo\rbar']);203}204);205});206});207208209210