diff --git a/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap b/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap new file mode 100644 index 000000000000..40e24e626313 --- /dev/null +++ b/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap @@ -0,0 +1,371 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`code coverage for Handlebars 1`] = ` +Object { + "greet.hbs": Object { + "b": Object { + "0": Array [ + 2, + 0, + ], + "1": Array [ + 1, + 0, + ], + "2": Array [ + 1, + 0, + ], + "3": Array [ + 1, + 1, + ], + "4": Array [ + 1, + 1, + ], + "5": Array [ + 1, + 0, + ], + }, + "branchMap": Object { + "0": Object { + "loc": Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + ], + "type": "cond-expr", + }, + "1": Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": 6, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + Object { + "end": Object { + "column": 6, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + ], + "type": "cond-expr", + }, + "2": Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 2, + }, + "start": Object { + "column": 6, + "line": 2, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": 10, + "line": 2, + }, + "start": Object { + "column": 6, + "line": 2, + }, + }, + Object { + "end": Object { + "column": 10, + "line": 2, + }, + "start": Object { + "column": 6, + "line": 2, + }, + }, + ], + "type": "cond-expr", + }, + "3": Object { + "loc": Object { + "end": Object { + "column": 2, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 7, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": 2, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 7, + }, + }, + Object { + "end": Object { + "column": 2, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 7, + }, + }, + ], + "type": "cond-expr", + }, + "4": Object { + "loc": Object { + "end": Object { + "column": 2, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 7, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": 2, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 7, + }, + }, + Object { + "end": Object { + "column": 8, + "line": 7, + }, + "start": Object { + "column": 2, + "line": 7, + }, + }, + ], + "type": "binary-expr", + }, + "5": Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 7, + }, + "start": Object { + "column": 2, + "line": 7, + }, + }, + "locations": Array [ + Object { + "end": Object { + "column": 8, + "line": 7, + }, + "start": Object { + "column": 2, + "line": 7, + }, + }, + Object { + "end": Object { + "column": 8, + "line": 7, + }, + "start": Object { + "column": 2, + "line": 7, + }, + }, + ], + "type": "cond-expr", + }, + }, + "f": Object { + "0": 1, + "1": 0, + "2": 1, + }, + "fnMap": Object { + "0": Object { + "decl": Object { + "end": Object { + "column": null, + "line": 2, + }, + "start": Object { + "column": 10, + "line": 2, + }, + }, + "loc": Object { + "end": Object { + "column": null, + "line": 2, + }, + "start": Object { + "column": 10, + "line": 2, + }, + }, + "name": "(anonymous_0)", + }, + "1": Object { + "decl": Object { + "end": Object { + "column": null, + "line": 4, + }, + "start": Object { + "column": 8, + "line": 4, + }, + }, + "loc": Object { + "end": Object { + "column": null, + "line": 4, + }, + "start": Object { + "column": 8, + "line": 4, + }, + }, + "name": "(anonymous_1)", + }, + "2": Object { + "decl": Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "loc": Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "name": "(anonymous_2)", + }, + }, + "path": "greet.hbs", + "s": Object { + "0": 1, + "1": 0, + "2": 2, + "3": 1, + }, + "statementMap": Object { + "0": Object { + "end": Object { + "column": null, + "line": 2, + }, + "start": Object { + "column": 10, + "line": 2, + }, + }, + "1": Object { + "end": Object { + "column": null, + "line": 4, + }, + "start": Object { + "column": 8, + "line": 4, + }, + }, + "2": Object { + "end": Object { + "column": null, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "3": Object { + "end": Object { + "column": null, + "line": 7, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + }, + }, +} +`; diff --git a/e2e/__tests__/coverageHandlebars.test.ts b/e2e/__tests__/coverageHandlebars.test.ts new file mode 100644 index 000000000000..a07e5c529b80 --- /dev/null +++ b/e2e/__tests__/coverageHandlebars.test.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {readFileSync} from 'fs'; +import * as path from 'path'; +import {cleanup, run} from '../Utils'; +import runJest from '../runJest'; + +const dir = path.resolve(__dirname, '../coverage-handlebars'); +const coverageDir = path.join(dir, 'coverage'); + +beforeAll(() => { + cleanup(coverageDir); +}); + +it('code coverage for Handlebars', () => { + run('yarn', dir); + const result = runJest(dir, ['--coverage', '--no-cache']); + + expect(result.exitCode).toBe(0); + + const coverageMapFile = path.join(coverageDir, 'coverage-final.json'); + const coverageMap = JSON.parse(readFileSync(coverageMapFile, 'utf-8')); + + // reduce absolute paths embedded in the coverage map to just filenames + Object.keys(coverageMap).forEach(filename => { + coverageMap[filename].path = path.basename(coverageMap[filename].path); + delete coverageMap[filename].hash; + coverageMap[path.basename(filename)] = coverageMap[filename]; + delete coverageMap[filename]; + }); + expect(coverageMap).toHaveProperty(['greet.hbs']); + expect(coverageMap).toMatchSnapshot(); +}); diff --git a/e2e/coverage-handlebars/__tests__/greet.js b/e2e/coverage-handlebars/__tests__/greet.js new file mode 100644 index 000000000000..5b6b62a1a605 --- /dev/null +++ b/e2e/coverage-handlebars/__tests__/greet.js @@ -0,0 +1,7 @@ +const greet = require('../greet.hbs'); + +test('am', () => { + expect(greet({am: true, name: 'Joe'})).toEqual( + '

Good\n morning\nJoe!

\n' + ); +}); diff --git a/e2e/coverage-handlebars/greet.hbs b/e2e/coverage-handlebars/greet.hbs new file mode 100644 index 000000000000..e6b81e509736 --- /dev/null +++ b/e2e/coverage-handlebars/greet.hbs @@ -0,0 +1,7 @@ +

Good +{{#if am}} + morning +{{else}} + evening +{{/if}} +{{name}}!

diff --git a/e2e/coverage-handlebars/package.json b/e2e/coverage-handlebars/package.json new file mode 100644 index 000000000000..3eb23f01b754 --- /dev/null +++ b/e2e/coverage-handlebars/package.json @@ -0,0 +1,12 @@ +{ + "jest": { + "transform": { + "\\.hbs$": "/transform-handlebars.js" + }, + "testEnvironment": "node" + }, + "dependencies": { + "handlebars": "^4.7.3", + "source-map": "^0.6.1" + } +} diff --git a/e2e/coverage-handlebars/transform-handlebars.js b/e2e/coverage-handlebars/transform-handlebars.js new file mode 100644 index 000000000000..a57ca08030ea --- /dev/null +++ b/e2e/coverage-handlebars/transform-handlebars.js @@ -0,0 +1,13 @@ +const Handlebars = require('handlebars/dist/cjs/handlebars.js'); +const {SourceMapConsumer, SourceNode} = require('source-map'); + +exports.process = (code, filename) => { + const pc = Handlebars.precompile(code, {srcName: filename}); + const out = new SourceNode(null, null, null, [ + 'const Handlebars = require("handlebars/dist/cjs/handlebars.runtime.js");\n', + 'module.exports = Handlebars.template(', + SourceNode.fromStringWithSourceMap(pc.code, new SourceMapConsumer(pc.map)), + ');\n', + ]).toStringWithSourceMap(); + return {code: out.code, map: out.map.toString()}; +}; diff --git a/e2e/coverage-handlebars/yarn.lock b/e2e/coverage-handlebars/yarn.lock new file mode 100644 index 000000000000..71a0f6e78e8b --- /dev/null +++ b/e2e/coverage-handlebars/yarn.lock @@ -0,0 +1,55 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +handlebars@^4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.3.tgz#8ece2797826886cf8082d1726ff21d2a022550ee" + integrity sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +uglify-js@^3.1.4: + version "3.8.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.8.0.tgz#f3541ae97b2f048d7e7e3aa4f39fd8a1f5d7a805" + integrity sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ== + dependencies: + commander "~2.20.3" + source-map "~0.6.1" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=