react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / jstransform / visitors / __tests__ / es6-template-visitors-test.js
81153 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) {36if (scope) {37Object.keys(scope).forEach((key) => this[key] = scope[key]);38}3940var tagCalls = 0;41var tag = function(...args) {42tagCalls++;43return tagFn.apply(this, args);44};45var result = transform(code);46expect(result.split('\n').length).toBe(code.split('\n').length);47eval(result);48expect(tagCalls).toBe(1);49}5051function expectSiteObj(siteObj, cooked, raw) {52expect(Array.isArray(siteObj)).toBe(true);53expect(Object.isFrozen(siteObj)).toBe(true);54expect(Array.isArray(siteObj.raw)).toBe(true);55expect(Object.isFrozen(siteObj.raw)).toBe(true);56expect(siteObj.length).toBe(cooked.length);57expect(siteObj.raw.length).toBe(raw.length);58for (var ii = 0; ii < cooked.length; ii++) {59expect(siteObj[ii]).toEqual(cooked[ii]);60}61expect(siteObj.raw).toEqual(raw);62}6364it('should transform simple literals', function() {65expectTransform('`foo bar`', '("foo bar")');6667expectEval('`foo bar`', 'foo bar');68expectEval('`$`', '$');69expectEval('`$foo`', '$foo');70});7172it('should properly escape templates containing quotes', function() {73expectTransform('`foo "bar"`', '("foo \\"bar\\"")');74expectEval('`foo "bar"`', 'foo "bar"');7576expectTransform("`foo 'bar'`", '("foo \'bar\'")');77expectEval("`foo 'bar'`", "foo 'bar'");7879// `foo \\"bar\\"` (foo, literal slash, "bar", literal slash)80expectTransform('`foo \\\\"bar\\\\"`', '("foo \\\\\\"bar\\\\\\"")');81expectEval('`foo \\\\\\"bar\\\\\\"`', 'foo \\"bar\\"');82});8384it('should transform simple substitutions', function() {85expectTransform('`foo ${bar}`', '("foo " + bar)');86expectTransform('`${foo} bar`', '(foo + " bar")');87expectTransform('`${foo} ${bar}`', '(foo + " " + bar)');88expectTransform('`${foo}${bar}`', '(foo + bar)');89});9091it('should transform expressions', function() {92expectTransform('`foo ${bar()}`', '("foo " + bar())');93expectTransform('`foo ${bar.baz}`', '("foo " + bar.baz)');94expectTransform('`foo ${bar + 5}`', '("foo " + (bar + 5))');95expectTransform('`${foo + 5} bar`', '((foo + 5) + " bar")');96expectTransform('`${foo + 5} ${bar}`', '((foo + 5) + " " + bar)');97expectTransform(98'`${(function(b) {alert(4);})(a)}`',99'((function(b) {alert(4);})(a))');100});101102it('should transform tags with simple templates', function() {103var tag = function(elements) {104expectSiteObj(elements, ['foo bar'], ['foo bar']);105};106var result = transform("tag`foo bar`");107expect(result.split('\n').length).toBe(1);108eval(result);109110var a = { b: tag };111eval(transform("a.b`foo bar`"));112eval(transform("a['b']`foo bar`"));113114var getTag = function() { return tag; };115eval(transform("getTag()`foo bar`"));116eval(transform("(getTag())`foo bar`"));117});118119it('should transform tags with substitutions', function() {120expectTransform(121"tag`foo ${bar} baz`",122'tag(function() { var siteObj = ["foo ", " baz"]; ' +123'siteObj.raw = ["foo ", " baz"]; Object.freeze(siteObj.raw); ' +124'Object.freeze(siteObj); return siteObj; }(), bar)'125);126127expectEvalTag(128"tag`foo ${bar + 'abc'} baz`",129function(elements, ...args) {130expectSiteObj(elements, ['foo ', ' baz'], ['foo ', ' baz']);131expect(args.length).toBe(1);132expect(args[0]).toBe('barabc');133},134{bar: 'bar'}135);136137expectEvalTag(138"tag`foo ${bar + 'abc'}`",139function(elements, ...args) {140expectSiteObj(elements, ['foo ', ''], ['foo ', '']);141expect(args.length).toBe(1);142expect(args[0]).toBe('barabc');143},144{bar: 'bar'}145);146147expectEvalTag(148"tag`foo\n\n\nbar`",149(elements) => {150expectSiteObj(elements, ['foo\n\n\nbar'], ['foo\n\n\nbar']);151}152);153154expectEvalTag(155"tag`a\nb\n${c}\nd`",156(elements, ...args) => {157expectSiteObj(elements, ['a\nb\n', '\nd'], ['a\nb\n', '\nd']);158expect(args.length).toBe(1);159expect(args[0]).toBe('c');160},161{c: 'c'}162);163});164165it('should maintain line numbers', function() {166expectTransform("`foo\n\nbar`", '("foo\\n\\nbar"\n\n)');167expectTransform("`foo\n${bar}\nbaz`", '("foo\\n" + \nbar + "\\nbaz"\n)');168expectTransform("`foo\\nbar`", '("foo\\nbar")');169170expectTransform(171"tag`a\nb\n${c}${d}\ne`",172'tag(function() { var siteObj = ["a\\nb\\n", "", "\\ne"]; ' +173'siteObj.raw = ["a\\nb\\n", "", "\\ne"]; Object.freeze(siteObj.raw); ' +174'Object.freeze(siteObj); return siteObj; }(), \n\nc, d\n)'175);176});177178it('should handle multiple lines', function() {179expectEval("`foo\n\nbar`", 'foo\n\nbar');180expectEval("`foo\\nbar`", 'foo\nbar');181expectEval("`foo\\\\nbar`", 'foo\\nbar');182expectEval("`foo\n${bar}\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');183});184185it('should canonicalize line endings', function() {186// TODO: should this be '("foo\\nbar"\r\n)' to maintain the number of lines187// for editors that break on \r\n? I don't think we care in the transformed188// code.189expectTransform("`foo\r\nbar`", '("foo\\nbar"\n)');190// TODO: same as above but with trailing \r191expectTransform("`foo\rbar`", '("foo\\nbar")');192193expectEval("`foo\r\nbar`", 'foo\nbar');194expectEval("`foo\rbar`", 'foo\nbar');195expectEval("`foo\r\n${bar}\r\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');196197expectEvalTag(198"tag`foo\rbar`",199(elements) => {200expectSiteObj(elements, ['foo\nbar'], ['foo\rbar']);201}202);203});204});205206207208