From ed5d11880baf45a66619c756f7c4506eb8ad4466 Mon Sep 17 00:00:00 2001 From: vvakame Date: Mon, 25 Aug 2014 17:56:18 +0900 Subject: [PATCH 01/14] refactor(grunt-espower): switch dependency espower-source to espower https://gist.github.com/twada/103d34a3237cecd463a6 --- .jshintrc | 4 ++-- package.json | 6 +++++- tasks/espower.js | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/.jshintrc b/.jshintrc index f257bbd..aa25346 100644 --- a/.jshintrc +++ b/.jshintrc @@ -21,9 +21,9 @@ "unused": "vars", "strict": true, "trailing": true, - "maxparams": 2, + "maxparams": 3, "maxdepth": 2, - "maxstatements": 8, + "maxstatements": 9, "maxcomplexity": 5, "maxlen": 100, "asi": false, diff --git a/package.json b/package.json index af6fe6a..c98aa99 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,11 @@ "test": "grunt test" }, "dependencies": { - "espower-source": "~0.8.0" + "convert-source-map": "~0.4.0", + "escodegen": "~1.3.3", + "espower": "~0.8.0", + "esprima": "~1.2.2", + "xtend": "~4.0.0" }, "devDependencies": { "empower": "~0.8.0", diff --git a/tasks/espower.js b/tasks/espower.js index d5bc7a9..80feb9c 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -8,7 +8,38 @@ * https://github.com/twada/grunt-espower/blob/master/LICENSE-MIT */ var fs = require('fs'), - espowerSource = require('espower-source'); + espower = require('espower'), + esprima = require('esprima'), + escodegen = require('escodegen'), + extend = require('xtend'), + convert = require('convert-source-map'); + +function espowerSource(jsCode, filepath, options) { + 'use strict'; + + var jsAst, espowerOptions, modifiedAst, escodegenOutput, code, map; + + jsAst = esprima.parse(jsCode, { + tolerant: true, + loc: true, + tokens: true, + raw: true, + source: filepath + }); + espowerOptions = extend(espower.defaultOptions(), options, { + destructive: true, + path: filepath + }); + modifiedAst = espower(jsAst, espowerOptions); + escodegenOutput = escodegen.generate(modifiedAst, { + sourceMap: true, + sourceMapWithCode: true + }); + code = escodegenOutput.code; // Generated source code + map = convert.fromJSON(escodegenOutput.map.toString()); + map.sourcemap.sourcesContent = [jsCode]; + return code + '\n' + map.toComment() + '\n'; +} module.exports = function(grunt) { 'use strict'; From f6c672d676f6a5d036457c20f498607350a54096 Mon Sep 17 00:00:00 2001 From: vvakame Date: Mon, 25 Aug 2014 20:07:39 +0900 Subject: [PATCH 02/14] feat(grunt-espower): initial support for multi stage sourcemap --- .gitignore | 3 ++ .jshintrc | 4 +-- Gruntfile.js | 21 +++++++++++++- package.json | 20 +++++++------ tasks/espower.js | 40 +++++++++++++++++++++----- test/fixtures/coffee_mocha_node.coffee | 16 +++++++++++ 6 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 test/fixtures/coffee_mocha_node.coffee diff --git a/.gitignore b/.gitignore index a289018..8994020 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ node_modules npm-debug.log tmp demo/dest/ + +test/fixtures/coffee_*.js +test/fixtures/coffee_*.map diff --git a/.jshintrc b/.jshintrc index aa25346..739e062 100644 --- a/.jshintrc +++ b/.jshintrc @@ -23,9 +23,9 @@ "trailing": true, "maxparams": 3, "maxdepth": 2, - "maxstatements": 9, + "maxstatements": 15, "maxcomplexity": 5, - "maxlen": 100, + "maxlen": 120, "asi": false, "boss": false, "debug": false, diff --git a/Gruntfile.js b/Gruntfile.js index 7e68bc9..1737cbe 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,6 +14,24 @@ module.exports = function(grunt) { } }, + coffee: { + test: { + options: { + sourceMap: true, + bare: true + }, + files: [ + { + expand: true, + cwd: 'test/', + src: ['**/*.coffee'], + dest: 'test/', + ext: '.js' + } + ] + } + }, + clean: { test: ['tmp'], demo: ['demo/dest/'] @@ -62,10 +80,11 @@ module.exports = function(grunt) { grunt.loadTasks('tasks'); grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-coffee'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); - grunt.registerTask('test', ['jshint', 'clean:test', 'espower:test', 'nodeunit:test']); + grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'espower:test', 'nodeunit:test']); grunt.registerTask('demo', ['clean:demo', 'espower:demo', 'nodeunit:demo']); grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/package.json b/package.json index c98aa99..503ce20 100644 --- a/package.json +++ b/package.json @@ -26,22 +26,24 @@ "test": "grunt test" }, "dependencies": { - "convert-source-map": "~0.4.0", - "escodegen": "~1.3.3", - "espower": "~0.8.0", - "esprima": "~1.2.2", - "xtend": "~4.0.0" + "convert-source-map": "~0.4.0", + "escodegen": "~1.3.3", + "espower": "~0.9.0", + "esprima": "~1.2.2", + "multi-stage-sourcemap": "~0.1.1", + "xtend": "~4.0.0" }, "devDependencies": { "empower": "~0.8.0", - "power-assert-formatter": "~0.8.0", - "grunt-contrib-jshint": "~0.10.0", + "grunt": "~0.4.2", "grunt-contrib-clean": "~0.6.0", + "grunt-contrib-coffee": "^0.11.1", + "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-nodeunit": "~0.4.1", - "grunt": "~0.4.2" + "power-assert-formatter": "~0.8.0" }, "peerDependencies": { - "grunt": "~0.4.1" + "grunt": "~0.4.2" }, "author": { "name": "Takuto Wada", diff --git a/tasks/espower.js b/tasks/espower.js index 80feb9c..d9fc0f4 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -8,16 +8,30 @@ * https://github.com/twada/grunt-espower/blob/master/LICENSE-MIT */ var fs = require('fs'), + path = require('path'), espower = require('espower'), esprima = require('esprima'), escodegen = require('escodegen'), extend = require('xtend'), - convert = require('convert-source-map'); + convert = require('convert-source-map'), + transfer = require('multi-stage-sourcemap').transfer; + +function mergeSourceMap(incomingSourceMap, outgoingSourceMap) { + 'use strict'; + + if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) { + outgoingSourceMap = JSON.parse(outgoingSourceMap); + } + if (!incomingSourceMap) { + return outgoingSourceMap; + } + return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap})); +} function espowerSource(jsCode, filepath, options) { 'use strict'; - var jsAst, espowerOptions, modifiedAst, escodegenOutput, code, map; + var jsAst, espowerOptions, modifiedAst, escodegenOutput; jsAst = esprima.parse(jsCode, { tolerant: true, @@ -26,19 +40,31 @@ function espowerSource(jsCode, filepath, options) { raw: true, source: filepath }); + // TODO use options.mapRoot or anything + var inMap = convert.fromSource(jsCode) || convert.fromMapFileSource(jsCode, path.dirname(filepath)); + inMap = (inMap || {}).sourcemap; espowerOptions = extend(espower.defaultOptions(), options, { destructive: true, - path: filepath + path: filepath, + sourceMap: inMap }); modifiedAst = espower(jsAst, espowerOptions); escodegenOutput = escodegen.generate(modifiedAst, { sourceMap: true, sourceMapWithCode: true }); - code = escodegenOutput.code; // Generated source code - map = convert.fromJSON(escodegenOutput.map.toString()); - map.sourcemap.sourcesContent = [jsCode]; - return code + '\n' + map.toComment() + '\n'; + var outMap = convert.fromJSON(escodegenOutput.map.toString()); + if (inMap) { + var mergedRawMap = mergeSourceMap(inMap, outMap.toObject()); + outMap = convert.fromObject(mergedRawMap); + // TODO need sourceRoot resolver for inMap to outMap + // outMap.sourcemap.sourceRoot = "..";// inMap.sourceRoot; + outMap.sourcemap.sources = inMap.sources; + outMap.sourcemap.sourcesContent = inMap.sourcesContent; + } else { + outMap.sourcemap.sourcesContent = [jsCode]; + } + return escodegenOutput.code + '\n' + outMap.toComment() + '\n'; } module.exports = function(grunt) { diff --git a/test/fixtures/coffee_mocha_node.coffee b/test/fixtures/coffee_mocha_node.coffee new file mode 100644 index 0000000..d6f62d0 --- /dev/null +++ b/test/fixtures/coffee_mocha_node.coffee @@ -0,0 +1,16 @@ +assert = require 'power-assert' + +describe 'Array', () -> + beforeEach () -> + @ary = [1,2,3]; + + describe '#indexOf()', () -> + it 'should return -1 when the value is not present', () -> + zero = 0 + two = 2 + assert @ary.indexOf(zero) == two + + it 'should return index when the value is present', () -> + minusOne = -1 + two = 2 + assert.ok @ary.indexOf(two) == minusOne, 'THIS IS AN ASSERTION MESSAGE' From 0d74379916edc3ebc0ebda2cb733e3d8aabed763 Mon Sep 17 00:00:00 2001 From: vvakame Date: Mon, 25 Aug 2014 22:41:15 +0900 Subject: [PATCH 03/14] refactor(grunt-espower): improve sourceRoot resolution --- .jshintrc | 4 ++-- tasks/espower.js | 31 +++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/.jshintrc b/.jshintrc index 739e062..37b0ed4 100644 --- a/.jshintrc +++ b/.jshintrc @@ -21,9 +21,9 @@ "unused": "vars", "strict": true, "trailing": true, - "maxparams": 3, + "maxparams": 4, "maxdepth": 2, - "maxstatements": 15, + "maxstatements": 22, "maxcomplexity": 5, "maxlen": 120, "asi": false, diff --git a/tasks/espower.js b/tasks/espower.js index d9fc0f4..6facb7f 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -28,7 +28,7 @@ function mergeSourceMap(incomingSourceMap, outgoingSourceMap) { return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap})); } -function espowerSource(jsCode, filepath, options) { +function espowerSource(jsCode, filepath, options, dest) { 'use strict'; var jsAst, espowerOptions, modifiedAst, escodegenOutput; @@ -42,6 +42,7 @@ function espowerSource(jsCode, filepath, options) { }); // TODO use options.mapRoot or anything var inMap = convert.fromSource(jsCode) || convert.fromMapFileSource(jsCode, path.dirname(filepath)); + // TODO fix breaking type mismatch inMap and outMap inMap = (inMap || {}).sourcemap; espowerOptions = extend(espower.defaultOptions(), options, { destructive: true, @@ -55,12 +56,30 @@ function espowerSource(jsCode, filepath, options) { }); var outMap = convert.fromJSON(escodegenOutput.map.toString()); if (inMap) { + var inWorkingDir = path.relative(path.dirname(inMap.file), path.dirname(filepath)); + var outTo = path.resolve(process.cwd(), dest); + var sourceRoot = path.relative(path.dirname(outTo), inWorkingDir); + var sourcesContent = inMap.sourcesContent || inMap.sources + .map(function (src) { + var fullpath = path.resolve(inWorkingDir, inMap.sourceRoot || '', src); + // TODO use grunt.file.read + return fs.readFileSync(fullpath, {encoding: 'utf8'}); + }); + var inSources = inMap.sources + .map(function (src) { + // to full path + return path.resolve(inWorkingDir, inMap.sourceRoot || '', src); + }) + .map(function (src) { + var rootPath = path.resolve(path.dirname(outTo), sourceRoot); + return path.relative(rootPath, src); + }); var mergedRawMap = mergeSourceMap(inMap, outMap.toObject()); outMap = convert.fromObject(mergedRawMap); - // TODO need sourceRoot resolver for inMap to outMap - // outMap.sourcemap.sourceRoot = "..";// inMap.sourceRoot; - outMap.sourcemap.sources = inMap.sources; - outMap.sourcemap.sourcesContent = inMap.sourcesContent; + outMap.sourcemap.file = path.basename(dest); + outMap.sourcemap.sourceRoot = sourceRoot; + outMap.sourcemap.sources = inSources; + outMap.sourcemap.sourcesContent = sourcesContent; } else { outMap.sourcemap.sourcesContent = [jsCode]; } @@ -87,7 +106,7 @@ module.exports = function(grunt) { var modifiedSource, jsCode = fs.readFileSync(filepath, 'utf-8'); grunt.verbose.writeln('espower src: ' + f.src); - modifiedSource = espowerSource(jsCode, filepath, options); + modifiedSource = espowerSource(jsCode, filepath, options, f.dest); grunt.file.write(f.dest, modifiedSource); grunt.verbose.writeln('espower dest: ' + f.dest); }); From ac64fb195b0a64c1da6f596970f4f215e88622db Mon Sep 17 00:00:00 2001 From: vvakame Date: Mon, 25 Aug 2014 22:58:48 +0900 Subject: [PATCH 04/14] test(grunt-espower): add coffeescript demo with SourceMap --- .gitignore | 6 ++- Gruntfile.js | 17 ++++++- .../coffee_power_assert_demo_test.coffee | 49 +++++++++++++++++++ package.json | 3 +- 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 demo/src/tests/coffee_power_assert_demo_test.coffee diff --git a/.gitignore b/.gitignore index 8994020..cbca169 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,7 @@ npm-debug.log tmp demo/dest/ -test/fixtures/coffee_*.js -test/fixtures/coffee_*.map +test/fixtures/**/coffee_*.js +test/fixtures/**/coffee_*.map +demo/src/**/coffee_*.js +demo/src/**/coffee_*.map diff --git a/Gruntfile.js b/Gruntfile.js index 1737cbe..ece2956 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -29,6 +29,21 @@ module.exports = function(grunt) { ext: '.js' } ] + }, + demo: { + options: { + sourceMap: true, + bare: true + }, + files: [ + { + expand: true, + cwd: 'demo/src', + src: ['**/*.coffee'], + dest: 'demo/src', + ext: '.js' + } + ] } }, @@ -85,6 +100,6 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-nodeunit'); grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'espower:test', 'nodeunit:test']); - grunt.registerTask('demo', ['clean:demo', 'espower:demo', 'nodeunit:demo']); + grunt.registerTask('demo', ['clean:demo', 'coffee:demo', 'espower:demo', 'nodeunit:demo']); grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/demo/src/tests/coffee_power_assert_demo_test.coffee b/demo/src/tests/coffee_power_assert_demo_test.coffee new file mode 100644 index 0000000..69aef21 --- /dev/null +++ b/demo/src/tests/coffee_power_assert_demo_test.coffee @@ -0,0 +1,49 @@ +'use strict' + +empower = require 'empower' +formatter = require('power-assert-formatter')() +empowerOptions = {destructive: false, modifyMessageOnRethrow: false, saveContextOnRethrow: false} +require('source-map-support').install() + +exports.coffee = + setUp: (done) -> + done() + + demo1: (test) -> + test = empower test, formatter, empowerOptions + + test.expect 1 + + three = 3 + five = 5 + test.ok three == five, 'MESSAGE' + + test.done() + + demo2: (test) -> + test = empower test, formatter, empowerOptions + + test.expect 1 + + one = 1 + two = 2 + three = 3 + seven = 7 + ten = 10 + test.ok (three * (seven * ten)) == three + + test.done() + + demo3: (test) -> + test = empower test, formatter, empowerOptions + + test.expect 1 + + one = 1 + two = 2 + three = 3 + seven = 7 + ten = 10 + test.equal three * (seven * ten), three + + test.done() diff --git a/package.json b/package.json index 503ce20..df4d9e6 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-nodeunit": "~0.4.1", - "power-assert-formatter": "~0.8.0" + "power-assert-formatter": "~0.8.0", + "source-map-support": "^0.2.7" }, "peerDependencies": { "grunt": "~0.4.2" From e213989b5814e7f4cdc6be5bb19ca6992364ff83 Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 11:40:33 +0900 Subject: [PATCH 05/14] test(grunt-espower): add typescript demo with SourceMap --- .gitignore | 6 +++ Gruntfile.js | 23 ++++++++- .../typescript_power_assert_demo_test.ts | 47 +++++++++++++++++++ package.json | 4 +- test/fixtures/typescript_mocha_node.ts | 25 ++++++++++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 demo/src/tests/typescript_power_assert_demo_test.ts create mode 100644 test/fixtures/typescript_mocha_node.ts diff --git a/.gitignore b/.gitignore index cbca169..0b3c9cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ node_modules npm-debug.log +.tscache/ + tmp demo/dest/ test/fixtures/**/coffee_*.js test/fixtures/**/coffee_*.map +test/fixtures/**/typescript_*.js +test/fixtures/**/typescript_*.map demo/src/**/coffee_*.js demo/src/**/coffee_*.map +demo/src/**/typescript_*.js +demo/src/**/typescript_*.map diff --git a/Gruntfile.js b/Gruntfile.js index ece2956..fe25f61 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -47,6 +47,24 @@ module.exports = function(grunt) { } }, + ts: { + options: { + comments: true, + target: 'es5', + module: 'commonjs', + noImplicitAny: false, + sourceMap: true, + sourceRoot: '', + mapRoot: '' + }, + test: { + src: ['test/**/*.ts'] + }, + demo: { + src: ['demo/src/**/*.ts'] + } + }, + clean: { test: ['tmp'], demo: ['demo/dest/'] @@ -96,10 +114,11 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-coffee'); + grunt.loadNpmTasks('grunt-ts'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); - grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'espower:test', 'nodeunit:test']); - grunt.registerTask('demo', ['clean:demo', 'coffee:demo', 'espower:demo', 'nodeunit:demo']); + grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'ts:test', 'espower:test', 'nodeunit:test']); + grunt.registerTask('demo', ['clean:demo', 'coffee:demo', 'ts:demo', 'espower:demo', 'nodeunit:demo']); grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/demo/src/tests/typescript_power_assert_demo_test.ts b/demo/src/tests/typescript_power_assert_demo_test.ts new file mode 100644 index 0000000..2164c6e --- /dev/null +++ b/demo/src/tests/typescript_power_assert_demo_test.ts @@ -0,0 +1,47 @@ +declare var require:any; +declare var describe:any; +declare var it:any; +declare var beforeEach:any; + +'use strict'; + +var empower = require('empower'), + formatter = require('power-assert-formatter')(), + empowerOptions = {destructive: false, modifyMessageOnRethrow: false, saveContextOnRethrow: false}; + +export var typescript = { + setUp: function(done) { + done(); + }, + demo1: function(test) { + test = empower(test, formatter, empowerOptions); + + test.expect(1); + + var three = 3, + five = 5; + test.ok(three == five, 'MESSAGE'); + + test.done(); + }, + demo2: function(test) { + test = empower(test, formatter, empowerOptions); + + test.expect(1); + + var one = 1, two = 2, three = 3, seven = 7, ten = 10; + test.ok((three * (seven * ten)) === three); + + test.done(); + }, + demo3: function(test) { + test = empower(test, formatter, empowerOptions); + + test.expect(1); + + var one = 1, two = 2, three = 3, seven = 7, ten = 10; + test.equal(three * (seven * ten), three); + + test.done(); + } +}; diff --git a/package.json b/package.json index df4d9e6..e3589c4 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,10 @@ "grunt-contrib-coffee": "^0.11.1", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-nodeunit": "~0.4.1", + "grunt-ts": "^1.11.7", "power-assert-formatter": "~0.8.0", - "source-map-support": "^0.2.7" + "source-map-support": "^0.2.7", + "typescript": "^1.0.1" }, "peerDependencies": { "grunt": "~0.4.2" diff --git a/test/fixtures/typescript_mocha_node.ts b/test/fixtures/typescript_mocha_node.ts new file mode 100644 index 0000000..84d3254 --- /dev/null +++ b/test/fixtures/typescript_mocha_node.ts @@ -0,0 +1,25 @@ +declare var require:any; +declare var describe:any; +declare var it:any; +declare var beforeEach:any; + +var assert = require('power-assert'); + +describe('Array', () => { + var ary: number[]; + + beforeEach(() => { + ary = [1, 2, 3]; + }); + + describe('#indexOf()', () => { + it('should return -1 when the value is not present', () => { + var zero = 0, two = 2; + assert(ary.indexOf(zero) === two); + }); + it('should return index when the value is present', () => { + var minusOne = -1, two = 2; + assert.ok(ary.indexOf(two) === minusOne, 'THIS IS AN ASSERTION MESSAGE'); + }); + }); +}); From 680550e9ab4f170f25bc434c4e9a5793b0ea9f47 Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 11:46:54 +0900 Subject: [PATCH 06/14] test(grunt-espower): add compatibility test for espower generated code --- test/espower_test.js | 26 ++++++++++++++++++-- test/expected/coffee_mocha_node.js | 34 ++++++++++++++++++++++++++ test/expected/typescript_mocha_node.js | 30 +++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 test/expected/coffee_mocha_node.js create mode 100644 test/expected/typescript_mocha_node.js diff --git a/test/espower_test.js b/test/espower_test.js index 03e0e3e..9716daf 100644 --- a/test/espower_test.js +++ b/test/espower_test.js @@ -27,14 +27,36 @@ exports.espower = { setUp: function(done) { done(); }, - instrumentationTest: function(test) { + jsInstrumentationTest: function(test) { test.expect(3); var outputPath = 'tmp/mocha_node.js'; test.ok(grunt.file.exists(outputPath)); test.ok(grunt.file.isFile(outputPath)); test.equal(fs.readFileSync(outputPath, 'utf8'), - fs.readFileSync('test/expected/mocha_node.js', 'utf8')); + fs.readFileSync('test/expected/mocha_node.js', 'utf8')); + + test.done(); + }, + coffeeInstrumentationTest: function(test) { + test.expect(3); + + var outputPath = 'tmp/coffee_mocha_node.js'; + test.ok(grunt.file.exists(outputPath)); + test.ok(grunt.file.isFile(outputPath)); + test.equal(fs.readFileSync(outputPath, 'utf8'), + fs.readFileSync('test/expected/coffee_mocha_node.js', 'utf8')); + + test.done(); + }, + typescriptInstrumentationTest: function(test) { + test.expect(3); + + var outputPath = 'tmp/typescript_mocha_node.js'; + test.ok(grunt.file.exists(outputPath)); + test.ok(grunt.file.isFile(outputPath)); + test.equal(fs.readFileSync(outputPath, 'utf8'), + fs.readFileSync('test/expected/typescript_mocha_node.js', 'utf8')); test.done(); }, diff --git a/test/expected/coffee_mocha_node.js b/test/expected/coffee_mocha_node.js new file mode 100644 index 0000000..ed82687 --- /dev/null +++ b/test/expected/coffee_mocha_node.js @@ -0,0 +1,34 @@ +var assert; +assert = require('power-assert'); +describe('Array', function () { + beforeEach(function () { + return this.ary = [ + 1, + 2, + 3 + ]; + }); + return describe('#indexOf()', function () { + it('should return -1 when the value is not present', function () { + var two, zero; + zero = 0; + two = 2; + return assert(assert._expr(assert._capt(assert._capt(assert._capt(this.ary, 'arguments/0/left/callee/object').indexOf(assert._capt(zero, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(two, 'arguments/0/right'), 'arguments/0'), { + content: 'assert(this.ary.indexOf(zero) === two)', + filepath: 'coffee_mocha_node.coffee', + line: 11 + })); + }); + return it('should return index when the value is present', function () { + var minusOne, two; + minusOne = -1; + two = 2; + return assert.ok(assert._expr(assert._capt(assert._capt(assert._capt(this.ary, 'arguments/0/left/callee/object').indexOf(assert._capt(two, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(minusOne, 'arguments/0/right'), 'arguments/0'), { + content: 'assert.ok(this.ary.indexOf(two) === minusOne, \'THIS IS AN ASSERTION MESSAGE\')', + filepath: 'coffee_mocha_node.coffee', + line: 16 + }), 'THIS IS AN ASSERTION MESSAGE'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvZmZlZV9tb2NoYV9ub2RlLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFBLE1BQUE7QUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFRLGNBQVIsQ0FBVCxDQUFBO0FBQUEsUUFBQSxDQUVTLE9BRlQsRUFFa0IsWUFBQTtBQUFBLElBQ2hCLFVBQUEsQ0FBVyxZQUFBO0FBQUEsZUFDVCxLQUFDLEdBQUQsR0FBTztBQUFBLFlBQUMsQ0FBRDtBQUFBLFlBQUcsQ0FBSDtBQUFBLFlBQUssQ0FBTDtBQUFBLFVBREU7QUFBQSxLQUFYLEVBRGdCO0FBQUEsV0FJaEIsUUFBQSxDQUFTLFlBQVQsRUFBdUIsWUFBQTtBQUFBLFFBQ3JCLEVBQUEsQ0FBRyxnREFBSCxFQUFxRCxZQUFBO0FBQUEsWUFDbkQsSUFBQSxHQUFBLEVBQUEsSUFBQSxDQURtRDtBQUFBLFlBQ25ELElBQUEsR0FBTyxDQUFQLENBRG1EO0FBQUEsWUFFbkQsR0FBQSxHQUFNLENBQU4sQ0FGbUQ7QUFBQSxtQkFHbkQsTUFBQSxDQUFPLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLE1BQUMsR0FBRCxvQ0FBSyxPQUFMLENBQWEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxJQUFBLGlDQUFiLDJCQUFzQixNQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsc0JBQXRCO0FBQUEsZ0JBQUEsT0FBQTtBQUFBLGdCQUFBLFFBQUE7QUFBQSxnQkFBQSxJQUFBO0FBQUEsY0FBUCxFQUhtRDtBQUFBLFNBQXJELEVBRHFCO0FBQUEsZUFNckIsRUFBQSxDQUFHLCtDQUFILEVBQW9ELFlBQUE7QUFBQSxZQUNsRCxJQUFBLFFBQUEsRUFBQSxHQUFBLENBRGtEO0FBQUEsWUFDbEQsUUFBQSxHQUFXLENBQUEsQ0FBWCxDQURrRDtBQUFBLFlBRWxELEdBQUEsR0FBTSxDQUFOLENBRmtEO0FBQUEsbUJBR2xELE1BQUEsQ0FBTyxFQUFQLENBQVUsTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsTUFBQyxHQUFELG9DQUFLLE9BQUwsQ0FBYSxNQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsaUNBQWIsMkJBQXFCLE1BQUEsQ0FBQSxLQUFBLENBQUEsUUFBQSxzQkFBckI7QUFBQSxnQkFBQSxPQUFBO0FBQUEsZ0JBQUEsUUFBQTtBQUFBLGdCQUFBLElBQUE7QUFBQSxjQUFWLEVBQXlDLDhCQUF6QyxFQUhrRDtBQUFBLFNBQXBELEVBTnFCO0FBQUEsS0FBdkIsRUFKZ0I7QUFBQSxDQUZsQiIsImZpbGUiOiJjb2ZmZWVfbW9jaGFfbm9kZS5qcyIsInNvdXJjZVJvb3QiOiIuLi90ZXN0L2ZpeHR1cmVzIiwic291cmNlc0NvbnRlbnQiOlsiYXNzZXJ0ID0gcmVxdWlyZSAncG93ZXItYXNzZXJ0J1xuXG5kZXNjcmliZSAnQXJyYXknLCAoKSAtPlxuICBiZWZvcmVFYWNoICgpIC0+XG4gICAgQGFyeSA9IFsxLDIsM107XG5cbiAgZGVzY3JpYmUgJyNpbmRleE9mKCknLCAoKSAtPlxuICAgIGl0ICdzaG91bGQgcmV0dXJuIC0xIHdoZW4gdGhlIHZhbHVlIGlzIG5vdCBwcmVzZW50JywgKCkgLT5cbiAgICAgIHplcm8gPSAwXG4gICAgICB0d28gPSAyXG4gICAgICBhc3NlcnQgQGFyeS5pbmRleE9mKHplcm8pID09IHR3b1xuXG4gICAgaXQgJ3Nob3VsZCByZXR1cm4gaW5kZXggd2hlbiB0aGUgdmFsdWUgaXMgcHJlc2VudCcsICgpIC0+XG4gICAgICBtaW51c09uZSA9IC0xXG4gICAgICB0d28gPSAyXG4gICAgICBhc3NlcnQub2sgQGFyeS5pbmRleE9mKHR3bykgPT0gbWludXNPbmUsICdUSElTIElTIEFOIEFTU0VSVElPTiBNRVNTQUdFJ1xuIl19 diff --git a/test/expected/typescript_mocha_node.js b/test/expected/typescript_mocha_node.js new file mode 100644 index 0000000..f0c4c03 --- /dev/null +++ b/test/expected/typescript_mocha_node.js @@ -0,0 +1,30 @@ +var assert = require('power-assert'); +describe('Array', function () { + var ary; + beforeEach(function () { + ary = [ + 1, + 2, + 3 + ]; + }); + describe('#indexOf()', function () { + it('should return -1 when the value is not present', function () { + var zero = 0, two = 2; + assert(assert._expr(assert._capt(assert._capt(assert._capt(ary, 'arguments/0/left/callee/object').indexOf(assert._capt(zero, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(two, 'arguments/0/right'), 'arguments/0'), { + content: 'assert(ary.indexOf(zero) === two)', + filepath: 'typescript_mocha_node.ts', + line: 18 + })); + }); + it('should return index when the value is present', function () { + var minusOne = -1, two = 2; + assert.ok(assert._expr(assert._capt(assert._capt(assert._capt(ary, 'arguments/0/left/callee/object').indexOf(assert._capt(two, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(minusOne, 'arguments/0/right'), 'arguments/0'), { + content: 'assert.ok(ary.indexOf(two) === minusOne, \'THIS IS AN ASSERTION MESSAGE\')', + filepath: 'typescript_mocha_node.ts', + line: 22 + }), 'THIS IS AN ASSERTION MESSAGE'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR5cGVzY3JpcHRfbW9jaGFfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxJQUFJLE1BQUEsR0FBUyxPQUFBLENBQVEsY0FBUixDQUFiO0FBRUEsUUFBQSxDQUFTLE9BQVQsRUFBa0IsWUFBQTtBQUFBLElBQ2QsSUFBSSxHQUFKLENBRGM7QUFBQSxJQUdkLFVBQUEsQ0FBVyxZQUFBO0FBQUEsUUFDUCxHQUFBLEdBQU07QUFBQSxZQUFDLENBQUQ7QUFBQSxZQUFJLENBQUo7QUFBQSxZQUFPLENBQVA7QUFBQSxTQUFOLENBRE87QUFBQSxLQUFYLEVBSGM7QUFBQSxJQU9kLFFBQUEsQ0FBUyxZQUFULEVBQXVCLFlBQUE7QUFBQSxRQUNuQixFQUFBLENBQUcsZ0RBQUgsRUFBcUQsWUFBQTtBQUFBLFlBQ2pELElBQUksSUFBQSxHQUFPLENBQVgsRUFBYyxHQUFBLEdBQU0sQ0FBcEIsQ0FEaUQ7QUFBQSxZQUVqRCxNQUFBLENBQU8sTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLG9DQUFJLE9BQUosQ0FBWSxNQUFBLENBQUEsS0FBQSxDQUFBLElBQUEsaUNBQVosMkJBQXNCLE1BQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxzQkFBdEI7QUFBQSxnQkFBQSxPQUFBO0FBQUEsZ0JBQUEsUUFBQTtBQUFBLGdCQUFBLElBQUE7QUFBQSxjQUFQLEVBRmlEO0FBQUEsU0FBckQsRUFEbUI7QUFBQSxRQUtuQixFQUFBLENBQUcsK0NBQUgsRUFBb0QsWUFBQTtBQUFBLFlBQ2hELElBQUksUUFBQSxHQUFXLENBQUMsQ0FBaEIsRUFBbUIsR0FBQSxHQUFNLENBQXpCLENBRGdEO0FBQUEsWUFFaEQsTUFBQSxDQUFPLEVBQVAsQ0FBVSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsb0NBQUksT0FBSixDQUFZLE1BQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxpQ0FBWiwyQkFBcUIsTUFBQSxDQUFBLEtBQUEsQ0FBQSxRQUFBLHNCQUFyQjtBQUFBLGdCQUFBLE9BQUE7QUFBQSxnQkFBQSxRQUFBO0FBQUEsZ0JBQUEsSUFBQTtBQUFBLGNBQVYsRUFBeUMsOEJBQXpDLEVBRmdEO0FBQUEsU0FBcEQsRUFMbUI7QUFBQSxLQUF2QixFQVBjO0FBQUEsQ0FBbEIiLCJmaWxlIjoidHlwZXNjcmlwdF9tb2NoYV9ub2RlLmpzIiwic291cmNlUm9vdCI6Ii4uL3Rlc3QvZml4dHVyZXMiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIHZhciByZXF1aXJlOmFueTtcbmRlY2xhcmUgdmFyIGRlc2NyaWJlOmFueTtcbmRlY2xhcmUgdmFyIGl0OmFueTtcbmRlY2xhcmUgdmFyIGJlZm9yZUVhY2g6YW55O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgncG93ZXItYXNzZXJ0Jyk7XG5cbmRlc2NyaWJlKCdBcnJheScsICgpID0+IHtcbiAgICB2YXIgYXJ5OiBudW1iZXJbXTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBhcnkgPSBbMSwgMiwgM107XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnI2luZGV4T2YoKScsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gLTEgd2hlbiB0aGUgdmFsdWUgaXMgbm90IHByZXNlbnQnLCAoKSA9PiB7XG4gICAgICAgICAgICB2YXIgemVybyA9IDAsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQoYXJ5LmluZGV4T2YoemVybykgPT09IHR3byk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbmRleCB3aGVuIHRoZSB2YWx1ZSBpcyBwcmVzZW50JywgKCkgPT4ge1xuICAgICAgICAgICAgdmFyIG1pbnVzT25lID0gLTEsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQub2soYXJ5LmluZGV4T2YodHdvKSA9PT0gbWludXNPbmUsICdUSElTIElTIEFOIEFTU0VSVElPTiBNRVNTQUdFJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7XG4iXX0= From 52002a48d58ef3349343216a31c456813f847bd4 Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 14:42:17 +0900 Subject: [PATCH 07/14] chore(grunt-espower): update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0b3c9cd..9326953 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules npm-debug.log +.idea/ .tscache/ tmp From aaba13c5c4d1f71dd2158721d2a5ee5fddf4556f Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 15:27:21 +0900 Subject: [PATCH 08/14] test(grunt-espower): add multi ts sample --- .gitignore | 2 ++ .jshintrc | 2 +- Gruntfile.js | 24 ++++++++++++++++++------ test/fixtures/multi-ts/main.ts | 7 +++++++ test/fixtures/multi-ts/subdir/util2.ts | 6 ++++++ test/fixtures/multi-ts/util1.ts | 6 ++++++ 6 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/multi-ts/main.ts create mode 100644 test/fixtures/multi-ts/subdir/util2.ts create mode 100644 test/fixtures/multi-ts/util1.ts diff --git a/.gitignore b/.gitignore index 9326953..345b12c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ test/fixtures/**/coffee_*.js test/fixtures/**/coffee_*.map test/fixtures/**/typescript_*.js test/fixtures/**/typescript_*.map +test/fixtures/*-ts/*.js +test/fixtures/*-ts/*.js.map demo/src/**/coffee_*.js demo/src/**/coffee_*.map demo/src/**/typescript_*.js diff --git a/.jshintrc b/.jshintrc index 37b0ed4..34e4c0e 100644 --- a/.jshintrc +++ b/.jshintrc @@ -25,7 +25,7 @@ "maxdepth": 2, "maxstatements": 22, "maxcomplexity": 5, - "maxlen": 120, + "maxlen": 140, "asi": false, "boss": false, "debug": false, diff --git a/Gruntfile.js b/Gruntfile.js index fe25f61..6a37284 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -51,16 +51,28 @@ module.exports = function(grunt) { options: { comments: true, target: 'es5', - module: 'commonjs', noImplicitAny: false, - sourceMap: true, - sourceRoot: '', - mapRoot: '' + sourceMap: true }, test: { - src: ['test/**/*.ts'] + options: { + module: 'commonjs' + }, + src: [ + 'test/**/*.ts', + '!test/fixtures/multi-ts/**/*.ts' + ] + }, + testConcat: { + src: [ + 'test/fixtures/multi-ts/main.ts' + ], + out: 'test/fixtures/multi-ts/concat.js' }, demo: { + options: { + module: 'commonjs' + }, src: ['demo/src/**/*.ts'] } }, @@ -118,7 +130,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); - grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'ts:test', 'espower:test', 'nodeunit:test']); + grunt.registerTask('test', ['jshint', 'clean:test', 'coffee:test', 'ts:test', 'ts:testConcat', 'espower:test', 'nodeunit:test']); grunt.registerTask('demo', ['clean:demo', 'coffee:demo', 'ts:demo', 'espower:demo', 'nodeunit:demo']); grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/test/fixtures/multi-ts/main.ts b/test/fixtures/multi-ts/main.ts new file mode 100644 index 0000000..5431a71 --- /dev/null +++ b/test/fixtures/multi-ts/main.ts @@ -0,0 +1,7 @@ +/// +/// + +declare var assert: any; + +assert(Util.hello("grunt-espower") === "Hello, grunt-espower!"); +assert(Util.bye("grunt-espower") === "Good bye, grunt-espower!"); diff --git a/test/fixtures/multi-ts/subdir/util2.ts b/test/fixtures/multi-ts/subdir/util2.ts new file mode 100644 index 0000000..265e4e1 --- /dev/null +++ b/test/fixtures/multi-ts/subdir/util2.ts @@ -0,0 +1,6 @@ +module Util { + export function bye(target = "world") { + assert(target != null); + return "Good bye, " + target + "!"; + } +} diff --git a/test/fixtures/multi-ts/util1.ts b/test/fixtures/multi-ts/util1.ts new file mode 100644 index 0000000..6210bc8 --- /dev/null +++ b/test/fixtures/multi-ts/util1.ts @@ -0,0 +1,6 @@ +module Util { + export function hello(target = "world") { + assert(target != null); + return "Hello, " + target + "!"; + } +} From 773db350d367e2807bb7e5511e13d7762cb32b44 Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 23:16:33 +0900 Subject: [PATCH 09/14] chore(grunt-espower): update dependency. multi-stage-sourcemap 0.1.1 to 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3589c4..8da8d64 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "escodegen": "~1.3.3", "espower": "~0.9.0", "esprima": "~1.2.2", - "multi-stage-sourcemap": "~0.1.1", + "multi-stage-sourcemap": "~0.2.1", "xtend": "~4.0.0" }, "devDependencies": { From feba758297a5243eb412f58aa37e29599a52dd4e Mon Sep 17 00:00:00 2001 From: vvakame Date: Tue, 26 Aug 2014 23:23:33 +0900 Subject: [PATCH 10/14] test(grunt-espower): add compatibility test for espower generated code. multi-ts --- test/espower_test.js | 11 +++++++++ test/expected/multi-ts/concat.js | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 test/expected/multi-ts/concat.js diff --git a/test/espower_test.js b/test/espower_test.js index 9716daf..8d89bbe 100644 --- a/test/espower_test.js +++ b/test/espower_test.js @@ -60,6 +60,17 @@ exports.espower = { test.done(); }, + typescriptMultiSourceTest: function(test) { + test.expect(3); + + var outputPath = 'tmp/multi-ts/concat.js'; + test.ok(grunt.file.exists(outputPath)); + test.ok(grunt.file.isFile(outputPath)); + test.equal(fs.readFileSync(outputPath, 'utf8'), + fs.readFileSync('test/expected/multi-ts/concat.js', 'utf8')); + + test.done(); + }, subdirTest: function(test) { test.expect(3); diff --git a/test/expected/multi-ts/concat.js b/test/expected/multi-ts/concat.js new file mode 100644 index 0000000..d68cffe --- /dev/null +++ b/test/expected/multi-ts/concat.js @@ -0,0 +1,41 @@ +var Util; +(function (Util) { + function hello(target) { + if (typeof target === 'undefined') { + target = 'world'; + } + assert(assert._expr(assert._capt(assert._capt(target, 'arguments/0/left') != null, 'arguments/0'), { + content: 'assert(target != null)', + filepath: 'util1.ts', + line: 3 + })); + return 'Hello, ' + target + '!'; + } + Util.hello = hello; +}(Util || (Util = {}))); +var Util; +(function (Util) { + function bye(target) { + if (typeof target === 'undefined') { + target = 'world'; + } + assert(assert._expr(assert._capt(assert._capt(target, 'arguments/0/left') != null, 'arguments/0'), { + content: 'assert(target != null)', + filepath: 'subdir/util2.ts', + line: 3 + })); + return 'Good bye, ' + target + '!'; + } + Util.bye = bye; +}(Util || (Util = {}))); +assert(assert._expr(assert._capt(assert._capt(assert._capt(Util, 'arguments/0/left/callee/object').hello('grunt-espower'), 'arguments/0/left') === 'Hello, grunt-espower!', 'arguments/0'), { + content: 'assert(Util.hello("grunt-espower") === "Hello, grunt-espower!")', + filepath: 'main.ts', + line: 6 +})); +assert(assert._expr(assert._capt(assert._capt(assert._capt(Util, 'arguments/0/left/callee/object').bye('grunt-espower'), 'arguments/0/left') === 'Good bye, grunt-espower!', 'arguments/0'), { + content: 'assert(Util.bye("grunt-espower") === "Good bye, grunt-espower!")', + filepath: 'main.ts', + line: 7 +})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInV0aWwxLnRzIiwic3ViZGlyL3V0aWwyLnRzIiwibWFpbi50cyJdLCJuYW1lcyI6WyJVdGlsIiwiVXRpbC5oZWxsbyIsIlV0aWwuYnllIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFPLElBQVA7QUFLQyxDQUxELFVBQU8sSUFBUCxFQUFXO0FBQUEsSUFDUEEsU0FBZ0JBLEtBQWhCQSxDQUFzQkEsTUFBdEJBLEVBQXNDQTtBQUFBQSxRQUFoQkMsSUFBQUEsT0FBQUEsTUFBQUEsS0FBQUEsV0FBQUEsRUFBQUE7QUFBQUEsWUFBQUEsTUFBQUEsR0FBU0EsT0FBVEEsQ0FBQUE7QUFBQUEsU0FBZ0JEO0FBQUFBLFFBQ2xDQyxNQUFBQSxDQUFPQSxNQUFBQSxDQUFBQSxLQUFBQSxDQUFBQSxNQUFBQSxDQUFBQSxLQUFBQSxDQUFBQSxNQUFBQSxDQUFBQSxLQUFBQSxDQUFBQSxNQUFBQSx5QkFBVUEsSUFBVkE7QUFBQUEsWUFBQUEsT0FBQUE7QUFBQUEsWUFBQUEsUUFBQUE7QUFBQUEsWUFBQUEsSUFBQUE7QUFBQUEsVUFBUEEsRUFEa0NEO0FBQUFBLFFBRWxDQyxPQUFPQSxZQUFZQSxNQUFaQSxHQUFxQkEsR0FBNUJBLENBRmtDRDtBQUFBQSxLQUQvQjtBQUFBLElBQ1BBLElBQUFBLENBQUFBLEtBQUFBLEdBQUFBLEtBQUFBLENBRE87QUFBQSxDQUtWLENBQUFBLElBQUFBLElBQUFBLENBQUFBLElBQUFBLEdBQUFBLEVBQUFBLENBQUEsR0FMRDtBQ0FBLElBQU8sSUFBUCxDREFBO0FDS0MsQ0FMRCxVQUFPLElBQVAsRUFBVztBQUFBLElBQ1BBLFNBQWdCQSxHQUFoQkEsQ0FBb0JBLE1BQXBCQSxFQUFvQ0E7QUFBQUEsUUFBaEJFLElBQUFBLE9BQUFBLE1BQUFBLEtBQUFBLFdBQUFBLEVBQUFBO0FBQUFBLFlBQUFBLE1BQUFBLEdBQVNBLE9BQVRBLENBQUFBO0FBQUFBLFNBQWdCRjtBQUFBQSxRQUNoQ0UsTUFBQUEsQ0FBT0EsTUFBQUEsQ0FBQUEsS0FBQUEsQ0FBQUEsTUFBQUEsQ0FBQUEsS0FBQUEsQ0FBQUEsTUFBQUEsQ0FBQUEsS0FBQUEsQ0FBQUEsTUFBQUEseUJBQVVBLElBQVZBO0FBQUFBLFlBQUFBLE9BQUFBO0FBQUFBLFlBQUFBLFFBQUFBO0FBQUFBLFlBQUFBLElBQUFBO0FBQUFBLFVBQVBBLEVBRGdDRjtBQUFBQSxRQUVoQ0UsT0FBT0EsZUFBZUEsTUFBZkEsR0FBd0JBLEdBQS9CQSxDQUZnQ0Y7QUFBQUEsS0FEN0I7QUFBQSxJQUNQQSxJQUFBQSxDQUFBQSxHQUFBQSxHQUFBQSxHQUFBQSxDQURPO0FBQUEsQ0FLVixDQUFBQSxJQUFBQSxJQUFBQSxDQUFBQSxJQUFBQSxHQUFBQSxFQUFBQSxDQUFBLEdETEQ7QUVLQSxNQUFBLENBQU8sTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxJQUFBLG9DQUFLLEtBQUwsQ0FBVyxlQUFYLDJCQUFnQyx1QkFBaEM7QUFBQSxJQUFBLE9BQUE7QUFBQSxJQUFBLFFBQUE7QUFBQSxJQUFBLElBQUE7QUFBQSxFQUFQLEVGTEE7QUVNQSxNQUFBLENBQU8sTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxJQUFBLG9DQUFLLEdBQUwsQ0FBUyxlQUFULDJCQUE4QiwwQkFBOUI7QUFBQSxJQUFBLE9BQUE7QUFBQSxJQUFBLFFBQUE7QUFBQSxJQUFBLElBQUE7QUFBQSxFQUFQIiwiZmlsZSI6ImNvbmNhdC5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi90ZXN0L2ZpeHR1cmVzL211bHRpLXRzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlIFV0aWwge1xuICAgIGV4cG9ydCBmdW5jdGlvbiBoZWxsbyh0YXJnZXQgPSBcIndvcmxkXCIpIHtcbiAgICAgICAgYXNzZXJ0KHRhcmdldCAhPSBudWxsKTtcbiAgICAgICAgcmV0dXJuIFwiSGVsbG8sIFwiICsgdGFyZ2V0ICsgXCIhXCI7XG4gICAgfVxufVxuIiwibW9kdWxlIFV0aWwge1xuICAgIGV4cG9ydCBmdW5jdGlvbiBieWUodGFyZ2V0ID0gXCJ3b3JsZFwiKSB7XG4gICAgICAgIGFzc2VydCh0YXJnZXQgIT0gbnVsbCk7XG4gICAgICAgIHJldHVybiBcIkdvb2QgYnllLCBcIiArIHRhcmdldCArIFwiIVwiO1xuICAgIH1cbn1cbiIsIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuL3V0aWwxLnRzXCIgLz5cbi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuL3N1YmRpci91dGlsMi50c1wiIC8+XG5cbmRlY2xhcmUgdmFyIGFzc2VydDogYW55O1xuXG5hc3NlcnQoVXRpbC5oZWxsbyhcImdydW50LWVzcG93ZXJcIikgPT09IFwiSGVsbG8sIGdydW50LWVzcG93ZXIhXCIpO1xuYXNzZXJ0KFV0aWwuYnllKFwiZ3J1bnQtZXNwb3dlclwiKSA9PT0gXCJHb29kIGJ5ZSwgZ3J1bnQtZXNwb3dlciFcIik7XG4iXX0= From 7e7dcf97f498897d8e6d2547657ef39f724e4469 Mon Sep 17 00:00:00 2001 From: vvakame Date: Wed, 27 Aug 2014 00:10:54 +0900 Subject: [PATCH 11/14] refactor(grunt-espower): finish TODO in tasks/espower.js --- .jshintrc | 2 +- tasks/espower.js | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/.jshintrc b/.jshintrc index 34e4c0e..9b221f6 100644 --- a/.jshintrc +++ b/.jshintrc @@ -21,7 +21,7 @@ "unused": "vars", "strict": true, "trailing": true, - "maxparams": 4, + "maxparams": 5, "maxdepth": 2, "maxstatements": 22, "maxcomplexity": 5, diff --git a/tasks/espower.js b/tasks/espower.js index 6facb7f..57241fd 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -7,8 +7,7 @@ * Licensed under the MIT license. * https://github.com/twada/grunt-espower/blob/master/LICENSE-MIT */ -var fs = require('fs'), - path = require('path'), +var path = require('path'), espower = require('espower'), esprima = require('esprima'), escodegen = require('escodegen'), @@ -28,7 +27,7 @@ function mergeSourceMap(incomingSourceMap, outgoingSourceMap) { return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap})); } -function espowerSource(jsCode, filepath, options, dest) { +function espowerSource(grunt, jsCode, filepath, dest, options) { 'use strict'; var jsAst, espowerOptions, modifiedAst, escodegenOutput; @@ -40,14 +39,11 @@ function espowerSource(jsCode, filepath, options, dest) { raw: true, source: filepath }); - // TODO use options.mapRoot or anything var inMap = convert.fromSource(jsCode) || convert.fromMapFileSource(jsCode, path.dirname(filepath)); - // TODO fix breaking type mismatch inMap and outMap - inMap = (inMap || {}).sourcemap; espowerOptions = extend(espower.defaultOptions(), options, { destructive: true, path: filepath, - sourceMap: inMap + sourceMap: inMap ? inMap.sourcemap : void 0 }); modifiedAst = espower(jsAst, espowerOptions); escodegenOutput = escodegen.generate(modifiedAst, { @@ -56,25 +52,25 @@ function espowerSource(jsCode, filepath, options, dest) { }); var outMap = convert.fromJSON(escodegenOutput.map.toString()); if (inMap) { - var inWorkingDir = path.relative(path.dirname(inMap.file), path.dirname(filepath)); + // NOTE https://gist.github.com/twada/103d34a3237cecd463a6#comment-1288208 + var inWorkingDir = path.relative(path.dirname(inMap.sourcemap.file), path.dirname(filepath)); var outTo = path.resolve(process.cwd(), dest); var sourceRoot = path.relative(path.dirname(outTo), inWorkingDir); - var sourcesContent = inMap.sourcesContent || inMap.sources + var sourcesContent = inMap.sourcemap.sourcesContent || inMap.sourcemap.sources .map(function (src) { - var fullpath = path.resolve(inWorkingDir, inMap.sourceRoot || '', src); - // TODO use grunt.file.read - return fs.readFileSync(fullpath, {encoding: 'utf8'}); + var fullpath = path.resolve(inWorkingDir, inMap.sourcemap.sourceRoot || '', src); + return grunt.file.read(fullpath); }); - var inSources = inMap.sources + var inSources = inMap.sourcemap.sources .map(function (src) { // to full path - return path.resolve(inWorkingDir, inMap.sourceRoot || '', src); + return path.resolve(inWorkingDir, inMap.sourcemap.sourceRoot || '', src); }) .map(function (src) { var rootPath = path.resolve(path.dirname(outTo), sourceRoot); return path.relative(rootPath, src); }); - var mergedRawMap = mergeSourceMap(inMap, outMap.toObject()); + var mergedRawMap = mergeSourceMap(inMap.toObject(), outMap.toObject()); outMap = convert.fromObject(mergedRawMap); outMap.sourcemap.file = path.basename(dest); outMap.sourcemap.sourceRoot = sourceRoot; @@ -104,9 +100,9 @@ module.exports = function(grunt) { return true; }).forEach(function(filepath) { var modifiedSource, - jsCode = fs.readFileSync(filepath, 'utf-8'); + jsCode = grunt.file.read(filepath); grunt.verbose.writeln('espower src: ' + f.src); - modifiedSource = espowerSource(jsCode, filepath, options, f.dest); + modifiedSource = espowerSource(grunt, jsCode, filepath, f.dest, options); grunt.file.write(f.dest, modifiedSource); grunt.verbose.writeln('espower dest: ' + f.dest); }); From 2edf7314a8b9fbde878bf6217475b3e6eff417be Mon Sep 17 00:00:00 2001 From: vvakame Date: Wed, 27 Aug 2014 00:24:49 +0900 Subject: [PATCH 12/14] refactor(grunt-espower): extract function. it named `resolveOutgoingSourcesInfo` --- tasks/espower.js | 62 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/tasks/espower.js b/tasks/espower.js index 57241fd..01fc6dd 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -7,6 +7,8 @@ * Licensed under the MIT license. * https://github.com/twada/grunt-espower/blob/master/LICENSE-MIT */ +'use strict'; + var path = require('path'), espower = require('espower'), esprima = require('esprima'), @@ -16,8 +18,6 @@ var path = require('path'), transfer = require('multi-stage-sourcemap').transfer; function mergeSourceMap(incomingSourceMap, outgoingSourceMap) { - 'use strict'; - if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) { outgoingSourceMap = JSON.parse(outgoingSourceMap); } @@ -27,9 +27,35 @@ function mergeSourceMap(incomingSourceMap, outgoingSourceMap) { return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap})); } -function espowerSource(grunt, jsCode, filepath, dest, options) { - 'use strict'; +function resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap) { + // NOTE https://gist.github.com/twada/103d34a3237cecd463a6#comment-1288208 + var incomingWorkingDir = path.relative(path.dirname(inMap.sourcemap.file), path.dirname(filepath)); + var destTo = path.resolve(process.cwd(), dest); + var sourceRoot = path.relative(path.dirname(destTo), incomingWorkingDir); + var sources = inMap.sourcemap.sources + .map(function (src) { + // to full path + return path.resolve(incomingWorkingDir, inMap.sourcemap.sourceRoot || '', src); + }) + .map(function (src) { + var rootPath = path.resolve(path.dirname(destTo), sourceRoot); + return path.relative(rootPath, src); + }); + var sourcesContent = inMap.sourcemap.sourcesContent || inMap.sourcemap.sources + .map(function (src) { + var fullpath = path.resolve(incomingWorkingDir, inMap.sourcemap.sourceRoot || '', src); + return grunt.file.read(fullpath); + }); + + return { + sourceRoot: sourceRoot, + sources: sources, + sourcesContent: sourcesContent + }; +} + +function espowerSource(grunt, jsCode, filepath, dest, options) { var jsAst, espowerOptions, modifiedAst, escodegenOutput; jsAst = esprima.parse(jsCode, { @@ -52,30 +78,14 @@ function espowerSource(grunt, jsCode, filepath, dest, options) { }); var outMap = convert.fromJSON(escodegenOutput.map.toString()); if (inMap) { - // NOTE https://gist.github.com/twada/103d34a3237cecd463a6#comment-1288208 - var inWorkingDir = path.relative(path.dirname(inMap.sourcemap.file), path.dirname(filepath)); - var outTo = path.resolve(process.cwd(), dest); - var sourceRoot = path.relative(path.dirname(outTo), inWorkingDir); - var sourcesContent = inMap.sourcemap.sourcesContent || inMap.sourcemap.sources - .map(function (src) { - var fullpath = path.resolve(inWorkingDir, inMap.sourcemap.sourceRoot || '', src); - return grunt.file.read(fullpath); - }); - var inSources = inMap.sourcemap.sources - .map(function (src) { - // to full path - return path.resolve(inWorkingDir, inMap.sourcemap.sourceRoot || '', src); - }) - .map(function (src) { - var rootPath = path.resolve(path.dirname(outTo), sourceRoot); - return path.relative(rootPath, src); - }); var mergedRawMap = mergeSourceMap(inMap.toObject(), outMap.toObject()); + var resolved = resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap); + outMap = convert.fromObject(mergedRawMap); outMap.sourcemap.file = path.basename(dest); - outMap.sourcemap.sourceRoot = sourceRoot; - outMap.sourcemap.sources = inSources; - outMap.sourcemap.sourcesContent = sourcesContent; + outMap.sourcemap.sourceRoot = resolved.sourceRoot; + outMap.sourcemap.sources = resolved.sources; + outMap.sourcemap.sourcesContent = resolved.sourcesContent; } else { outMap.sourcemap.sourcesContent = [jsCode]; } @@ -83,8 +93,6 @@ function espowerSource(grunt, jsCode, filepath, dest, options) { } module.exports = function(grunt) { - 'use strict'; - grunt.registerMultiTask('espower', 'instrument power assert feature into code.', function() { // Merge task-specific and/or target-specific options with these defaults. var options = this.options(); From 32e05800f6fc7b41d6feeb0eb9775fab5ddddd0a Mon Sep 17 00:00:00 2001 From: vvakame Date: Wed, 27 Aug 2014 01:19:16 +0900 Subject: [PATCH 13/14] test(grunt-espower): add compatibility test for espower generated code. embed base64 format --- test/espower_test.js | 11 +++++++ test/expected/mocha_test_sm_base64comment.js | 30 ++++++++++++++++++++ test/fixtures/mocha_test_sm_base64comment.js | 21 ++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 test/expected/mocha_test_sm_base64comment.js create mode 100644 test/fixtures/mocha_test_sm_base64comment.js diff --git a/test/espower_test.js b/test/espower_test.js index 8d89bbe..cebf535 100644 --- a/test/espower_test.js +++ b/test/espower_test.js @@ -60,6 +60,17 @@ exports.espower = { test.done(); }, + typescriptInstrumentationBase64CommentTest: function(test) { + test.expect(3); + + var outputPath = 'tmp/mocha_test_sm_base64comment.js'; + test.ok(grunt.file.exists(outputPath)); + test.ok(grunt.file.isFile(outputPath)); + test.equal(fs.readFileSync(outputPath, 'utf8'), + fs.readFileSync('test/expected/mocha_test_sm_base64comment.js', 'utf8')); + + test.done(); + }, typescriptMultiSourceTest: function(test) { test.expect(3); diff --git a/test/expected/mocha_test_sm_base64comment.js b/test/expected/mocha_test_sm_base64comment.js new file mode 100644 index 0000000..4a87b8b --- /dev/null +++ b/test/expected/mocha_test_sm_base64comment.js @@ -0,0 +1,30 @@ +var assert = require('power-assert'); +describe('Array', function () { + var ary; + beforeEach(function () { + ary = [ + 1, + 2, + 3 + ]; + }); + describe('#indexOf()', function () { + it('should return -1 when the value is not present', function () { + var zero = 0, two = 2; + assert(assert._expr(assert._capt(assert._capt(assert._capt(ary, 'arguments/0/left/callee/object').indexOf(assert._capt(zero, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(two, 'arguments/0/right'), 'arguments/0'), { + content: 'assert(ary.indexOf(zero) === two)', + filepath: 'typescript_mocha_node.ts', + line: 18 + })); + }); + it('should return index when the value is present', function () { + var minusOne = -1, two = 2; + assert.ok(assert._expr(assert._capt(assert._capt(assert._capt(ary, 'arguments/0/left/callee/object').indexOf(assert._capt(two, 'arguments/0/left/arguments/0')), 'arguments/0/left') === assert._capt(minusOne, 'arguments/0/right'), 'arguments/0'), { + content: 'assert.ok(ary.indexOf(two) === minusOne, \'THIS IS AN ASSERTION MESSAGE\')', + filepath: 'typescript_mocha_node.ts', + line: 22 + }), 'THIS IS AN ASSERTION MESSAGE'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR5cGVzY3JpcHRfbW9jaGFfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxJQUFJLE1BQUEsR0FBUyxPQUFBLENBQVEsY0FBUixDQUFiO0FBRUEsUUFBQSxDQUFTLE9BQVQsRUFBa0IsWUFBQTtBQUFBLElBQ2QsSUFBSSxHQUFKLENBRGM7QUFBQSxJQUdkLFVBQUEsQ0FBVyxZQUFBO0FBQUEsUUFDUCxHQUFBLEdBQU07QUFBQSxZQUFDLENBQUQ7QUFBQSxZQUFJLENBQUo7QUFBQSxZQUFPLENBQVA7QUFBQSxTQUFOLENBRE87QUFBQSxLQUFYLEVBSGM7QUFBQSxJQU9kLFFBQUEsQ0FBUyxZQUFULEVBQXVCLFlBQUE7QUFBQSxRQUNuQixFQUFBLENBQUcsZ0RBQUgsRUFBcUQsWUFBQTtBQUFBLFlBQ2pELElBQUksSUFBQSxHQUFPLENBQVgsRUFBYyxHQUFBLEdBQU0sQ0FBcEIsQ0FEaUQ7QUFBQSxZQUVqRCxNQUFBLENBQU8sTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLG9DQUFJLE9BQUosQ0FBWSxNQUFBLENBQUEsS0FBQSxDQUFBLElBQUEsaUNBQVosMkJBQXNCLE1BQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxzQkFBdEI7QUFBQSxnQkFBQSxPQUFBO0FBQUEsZ0JBQUEsUUFBQTtBQUFBLGdCQUFBLElBQUE7QUFBQSxjQUFQLEVBRmlEO0FBQUEsU0FBckQsRUFEbUI7QUFBQSxRQUtuQixFQUFBLENBQUcsK0NBQUgsRUFBb0QsWUFBQTtBQUFBLFlBQ2hELElBQUksUUFBQSxHQUFXLENBQUMsQ0FBaEIsRUFBbUIsR0FBQSxHQUFNLENBQXpCLENBRGdEO0FBQUEsWUFFaEQsTUFBQSxDQUFPLEVBQVAsQ0FBVSxNQUFBLENBQUEsS0FBQSxDQUFBLE1BQUEsQ0FBQSxLQUFBLENBQUEsTUFBQSxDQUFBLEtBQUEsQ0FBQSxNQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsb0NBQUksT0FBSixDQUFZLE1BQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxpQ0FBWiwyQkFBcUIsTUFBQSxDQUFBLEtBQUEsQ0FBQSxRQUFBLHNCQUFyQjtBQUFBLGdCQUFBLE9BQUE7QUFBQSxnQkFBQSxRQUFBO0FBQUEsZ0JBQUEsSUFBQTtBQUFBLGNBQVYsRUFBeUMsOEJBQXpDLEVBRmdEO0FBQUEsU0FBcEQsRUFMbUI7QUFBQSxLQUF2QixFQVBjO0FBQUEsQ0FBbEIiLCJmaWxlIjoibW9jaGFfdGVzdF9zbV9iYXNlNjRjb21tZW50LmpzIiwic291cmNlUm9vdCI6Ii4uL3Rlc3QvZml4dHVyZXMiLCJzb3VyY2VzQ29udGVudCI6WyJkZWNsYXJlIHZhciByZXF1aXJlOmFueTtcbmRlY2xhcmUgdmFyIGRlc2NyaWJlOmFueTtcbmRlY2xhcmUgdmFyIGl0OmFueTtcbmRlY2xhcmUgdmFyIGJlZm9yZUVhY2g6YW55O1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgncG93ZXItYXNzZXJ0Jyk7XG5cbmRlc2NyaWJlKCdBcnJheScsICgpID0+IHtcbiAgICB2YXIgYXJ5OiBudW1iZXJbXTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgICBhcnkgPSBbMSwgMiwgM107XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnI2luZGV4T2YoKScsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gLTEgd2hlbiB0aGUgdmFsdWUgaXMgbm90IHByZXNlbnQnLCAoKSA9PiB7XG4gICAgICAgICAgICB2YXIgemVybyA9IDAsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQoYXJ5LmluZGV4T2YoemVybykgPT09IHR3byk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBpbmRleCB3aGVuIHRoZSB2YWx1ZSBpcyBwcmVzZW50JywgKCkgPT4ge1xuICAgICAgICAgICAgdmFyIG1pbnVzT25lID0gLTEsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQub2soYXJ5LmluZGV4T2YodHdvKSA9PT0gbWludXNPbmUsICdUSElTIElTIEFOIEFTU0VSVElPTiBNRVNTQUdFJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7XG4iXX0= diff --git a/test/fixtures/mocha_test_sm_base64comment.js b/test/fixtures/mocha_test_sm_base64comment.js new file mode 100644 index 0000000..10597e9 --- /dev/null +++ b/test/fixtures/mocha_test_sm_base64comment.js @@ -0,0 +1,21 @@ +var assert = require('power-assert'); + +describe('Array', function () { + var ary; + + beforeEach(function () { + ary = [1, 2, 3]; + }); + + describe('#indexOf()', function () { + it('should return -1 when the value is not present', function () { + var zero = 0, two = 2; + assert(ary.indexOf(zero) === two); + }); + it('should return index when the value is present', function () { + var minusOne = -1, two = 2; + assert.ok(ary.indexOf(two) === minusOne, 'THIS IS AN ASSERTION MESSAGE'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXNjcmlwdF9tb2NoYV9ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidHlwZXNjcmlwdF9tb2NoYV9ub2RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7O0FBRXBDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDZCxJQUFJLEdBQUc7O0lBRVAsVUFBVSxDQUFDO1FBQ1AsR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkIsQ0FBQyxDQUFDOztJQUVGLFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDbkIsRUFBRSxDQUFDLGdEQUFnRCxFQUFFO1lBQ2pELElBQUksSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztZQUNyQixNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUM7UUFDckMsQ0FBQyxDQUFDO1FBQ0YsRUFBRSxDQUFDLCtDQUErQyxFQUFFO1lBQ2hELElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1lBQzFCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxRQUFRLEVBQUUsOEJBQThCLENBQUM7UUFDNUUsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxDQUFDO0FBQ04sQ0FBQyxDQUFDIn0= From e99a6351f5737b715d3b0e789e2e5680c005bc0c Mon Sep 17 00:00:00 2001 From: vvakame Date: Wed, 27 Aug 2014 18:49:37 +0900 Subject: [PATCH 14/14] fix(grunt-espower): fix invalid sourcemap generation in single-stage process --- tasks/espower.js | 19 ++++++++++++++++--- test/expected/mocha_node.js | 2 +- test/expected/subdir/test_in_subdir.js | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/tasks/espower.js b/tasks/espower.js index 01fc6dd..cb21679 100644 --- a/tasks/espower.js +++ b/tasks/espower.js @@ -56,7 +56,7 @@ function resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap) { } function espowerSource(grunt, jsCode, filepath, dest, options) { - var jsAst, espowerOptions, modifiedAst, escodegenOutput; + var jsAst, espowerOptions, modifiedAst, escodegenOutput, resolved; jsAst = esprima.parse(jsCode, { tolerant: true, @@ -79,7 +79,7 @@ function espowerSource(grunt, jsCode, filepath, dest, options) { var outMap = convert.fromJSON(escodegenOutput.map.toString()); if (inMap) { var mergedRawMap = mergeSourceMap(inMap.toObject(), outMap.toObject()); - var resolved = resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap); + resolved = resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap); outMap = convert.fromObject(mergedRawMap); outMap.sourcemap.file = path.basename(dest); @@ -87,7 +87,20 @@ function espowerSource(grunt, jsCode, filepath, dest, options) { outMap.sourcemap.sources = resolved.sources; outMap.sourcemap.sourcesContent = resolved.sourcesContent; } else { - outMap.sourcemap.sourcesContent = [jsCode]; + inMap = { + sourcemap: { + file: path.basename(dest), + sources: [path.basename(filepath)], + sourceRoot: '', + sourcesContent: [jsCode] + } + }; + resolved = resolveOutgoingSourcesInfo(grunt, filepath, dest, inMap); + + outMap.sourcemap.file = path.basename(dest); + outMap.sourcemap.sourceRoot = resolved.sourceRoot; + outMap.sourcemap.sources = resolved.sources; + outMap.sourcemap.sourcesContent = resolved.sourcesContent; } return escodegenOutput.code + '\n' + outMap.toComment() + '\n'; } diff --git a/test/expected/mocha_node.js b/test/expected/mocha_node.js index 3b3dd37..f56faf4 100644 --- a/test/expected/mocha_node.js +++ b/test/expected/mocha_node.js @@ -26,4 +26,4 @@ describe('Array', function () { }); }); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvbW9jaGFfbm9kZS5qcyJdLCJuYW1lcyI6WyJhc3NlcnQiLCJyZXF1aXJlIiwiZGVzY3JpYmUiLCJiZWZvcmVFYWNoIiwiYXJ5IiwiaXQiLCJ6ZXJvIiwidHdvIiwiX2V4cHIiLCJfY2FwdCIsImluZGV4T2YiLCJjb250ZW50IiwiZmlsZXBhdGgiLCJsaW5lIiwibWludXNPbmUiLCJvayJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsTUFBQSxHQUFTQyxPQUFBLENBQVEsY0FBUixDQUFiO0FBRUFDLFFBQUEsQ0FBUyxPQUFULEVBQWtCLFlBQVU7QUFBQSxJQUN4QkMsVUFBQSxDQUFXLFlBQVU7QUFBQSxRQUNqQixLQUFLQyxHQUFMLEdBQVc7QUFBQSxZQUFDLENBQUQ7QUFBQSxZQUFHLENBQUg7QUFBQSxZQUFLLENBQUw7QUFBQSxTQUFYLENBRGlCO0FBQUEsS0FBckIsRUFEd0I7QUFBQSxJQUl4QkYsUUFBQSxDQUFTLFlBQVQsRUFBdUIsWUFBVTtBQUFBLFFBQzdCRyxFQUFBLENBQUcsZ0RBQUgsRUFBcUQsWUFBVTtBQUFBLFlBQzNELElBQUlDLElBQUEsR0FBTyxDQUFYLEVBQWNDLEdBQUEsR0FBTSxDQUFwQixDQUQyRDtBQUFBLFlBRTNEUCxNQUFBLENBQU9BLE1BQUEsQ0FBQVEsS0FBQSxDQUFBUixNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLENBQUFULE1BQUEsQ0FBQVMsS0FBQSxNQUFLTCxHQUFMLG9DQUFTTSxPQUFULENBQWlCVixNQUFBLENBQUFTLEtBQUEsQ0FBQUgsSUFBQSxpQ0FBakIsMkJBQTJCTixNQUFBLENBQUFTLEtBQUEsQ0FBQUYsR0FBQSxzQkFBM0I7QUFBQSxnQkFBQUksT0FBQTtBQUFBLGdCQUFBQyxRQUFBO0FBQUEsZ0JBQUFDLElBQUE7QUFBQSxjQUFQLEVBRjJEO0FBQUEsU0FBL0QsRUFENkI7QUFBQSxRQUs3QlIsRUFBQSxDQUFHLCtDQUFILEVBQW9ELFlBQVU7QUFBQSxZQUMxRCxJQUFJUyxRQUFBLEdBQVcsQ0FBQyxDQUFoQixFQUFtQlAsR0FBQSxHQUFNLENBQXpCLENBRDBEO0FBQUEsWUFFMURQLE1BQUEsQ0FBT2UsRUFBUCxDQUFVZixNQUFBLENBQUFRLEtBQUEsQ0FBQVIsTUFBQSxDQUFBUyxLQUFBLENBQUFULE1BQUEsQ0FBQVMsS0FBQSxDQUFBVCxNQUFBLENBQUFTLEtBQUEsTUFBS0wsR0FBTCxvQ0FBU00sT0FBVCxDQUFpQlYsTUFBQSxDQUFBUyxLQUFBLENBQUFGLEdBQUEsaUNBQWpCLDJCQUEwQlAsTUFBQSxDQUFBUyxLQUFBLENBQUFLLFFBQUEsc0JBQTFCO0FBQUEsZ0JBQUFILE9BQUE7QUFBQSxnQkFBQUMsUUFBQTtBQUFBLGdCQUFBQyxJQUFBO0FBQUEsY0FBVixFQUE4Qyw4QkFBOUMsRUFGMEQ7QUFBQSxTQUE5RCxFQUw2QjtBQUFBLEtBQWpDLEVBSndCO0FBQUEsQ0FBNUIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXNzZXJ0ID0gcmVxdWlyZSgncG93ZXItYXNzZXJ0Jyk7XG5cbmRlc2NyaWJlKCdBcnJheScsIGZ1bmN0aW9uKCl7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbigpe1xuICAgICAgICB0aGlzLmFyeSA9IFsxLDIsM107XG4gICAgfSk7XG4gICAgZGVzY3JpYmUoJyNpbmRleE9mKCknLCBmdW5jdGlvbigpe1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiAtMSB3aGVuIHRoZSB2YWx1ZSBpcyBub3QgcHJlc2VudCcsIGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB2YXIgemVybyA9IDAsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5hcnkuaW5kZXhPZih6ZXJvKSA9PT0gdHdvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGluZGV4IHdoZW4gdGhlIHZhbHVlIGlzIHByZXNlbnQnLCBmdW5jdGlvbigpe1xuICAgICAgICAgICAgdmFyIG1pbnVzT25lID0gLTEsIHR3byA9IDI7XG4gICAgICAgICAgICBhc3NlcnQub2sodGhpcy5hcnkuaW5kZXhPZih0d28pID09PSBtaW51c09uZSwgJ1RISVMgSVMgQU4gQVNTRVJUSU9OIE1FU1NBR0UnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59KTtcbiJdfQ== +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1vY2hhX25vZGUuanMiXSwibmFtZXMiOlsiYXNzZXJ0IiwicmVxdWlyZSIsImRlc2NyaWJlIiwiYmVmb3JlRWFjaCIsImFyeSIsIml0IiwiemVybyIsInR3byIsIl9leHByIiwiX2NhcHQiLCJpbmRleE9mIiwiY29udGVudCIsImZpbGVwYXRoIiwibGluZSIsIm1pbnVzT25lIiwib2siXSwibWFwcGluZ3MiOiJBQUFBLElBQUlBLE1BQUEsR0FBU0MsT0FBQSxDQUFRLGNBQVIsQ0FBYjtBQUVBQyxRQUFBLENBQVMsT0FBVCxFQUFrQixZQUFVO0FBQUEsSUFDeEJDLFVBQUEsQ0FBVyxZQUFVO0FBQUEsUUFDakIsS0FBS0MsR0FBTCxHQUFXO0FBQUEsWUFBQyxDQUFEO0FBQUEsWUFBRyxDQUFIO0FBQUEsWUFBSyxDQUFMO0FBQUEsU0FBWCxDQURpQjtBQUFBLEtBQXJCLEVBRHdCO0FBQUEsSUFJeEJGLFFBQUEsQ0FBUyxZQUFULEVBQXVCLFlBQVU7QUFBQSxRQUM3QkcsRUFBQSxDQUFHLGdEQUFILEVBQXFELFlBQVU7QUFBQSxZQUMzRCxJQUFJQyxJQUFBLEdBQU8sQ0FBWCxFQUFjQyxHQUFBLEdBQU0sQ0FBcEIsQ0FEMkQ7QUFBQSxZQUUzRFAsTUFBQSxDQUFPQSxNQUFBLENBQUFRLEtBQUEsQ0FBQVIsTUFBQSxDQUFBUyxLQUFBLENBQUFULE1BQUEsQ0FBQVMsS0FBQSxDQUFBVCxNQUFBLENBQUFTLEtBQUEsTUFBS0wsR0FBTCxvQ0FBU00sT0FBVCxDQUFpQlYsTUFBQSxDQUFBUyxLQUFBLENBQUFILElBQUEsaUNBQWpCLDJCQUEyQk4sTUFBQSxDQUFBUyxLQUFBLENBQUFGLEdBQUEsc0JBQTNCO0FBQUEsZ0JBQUFJLE9BQUE7QUFBQSxnQkFBQUMsUUFBQTtBQUFBLGdCQUFBQyxJQUFBO0FBQUEsY0FBUCxFQUYyRDtBQUFBLFNBQS9ELEVBRDZCO0FBQUEsUUFLN0JSLEVBQUEsQ0FBRywrQ0FBSCxFQUFvRCxZQUFVO0FBQUEsWUFDMUQsSUFBSVMsUUFBQSxHQUFXLENBQUMsQ0FBaEIsRUFBbUJQLEdBQUEsR0FBTSxDQUF6QixDQUQwRDtBQUFBLFlBRTFEUCxNQUFBLENBQU9lLEVBQVAsQ0FBVWYsTUFBQSxDQUFBUSxLQUFBLENBQUFSLE1BQUEsQ0FBQVMsS0FBQSxDQUFBVCxNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLE1BQUtMLEdBQUwsb0NBQVNNLE9BQVQsQ0FBaUJWLE1BQUEsQ0FBQVMsS0FBQSxDQUFBRixHQUFBLGlDQUFqQiwyQkFBMEJQLE1BQUEsQ0FBQVMsS0FBQSxDQUFBSyxRQUFBLHNCQUExQjtBQUFBLGdCQUFBSCxPQUFBO0FBQUEsZ0JBQUFDLFFBQUE7QUFBQSxnQkFBQUMsSUFBQTtBQUFBLGNBQVYsRUFBOEMsOEJBQTlDLEVBRjBEO0FBQUEsU0FBOUQsRUFMNkI7QUFBQSxLQUFqQyxFQUp3QjtBQUFBLENBQTVCIiwiZmlsZSI6Im1vY2hhX25vZGUuanMiLCJzb3VyY2VSb290IjoiLi4vdGVzdC9maXh0dXJlcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBhc3NlcnQgPSByZXF1aXJlKCdwb3dlci1hc3NlcnQnKTtcblxuZGVzY3JpYmUoJ0FycmF5JywgZnVuY3Rpb24oKXtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uKCl7XG4gICAgICAgIHRoaXMuYXJ5ID0gWzEsMiwzXTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnI2luZGV4T2YoKScsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIC0xIHdoZW4gdGhlIHZhbHVlIGlzIG5vdCBwcmVzZW50JywgZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHZhciB6ZXJvID0gMCwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLmFyeS5pbmRleE9mKHplcm8pID09PSB0d28pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5kZXggd2hlbiB0aGUgdmFsdWUgaXMgcHJlc2VudCcsIGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB2YXIgbWludXNPbmUgPSAtMSwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydC5vayh0aGlzLmFyeS5pbmRleE9mKHR3bykgPT09IG1pbnVzT25lLCAnVEhJUyBJUyBBTiBBU1NFUlRJT04gTUVTU0FHRScpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pO1xuIl19 diff --git a/test/expected/subdir/test_in_subdir.js b/test/expected/subdir/test_in_subdir.js index b2c9061..3ef193b 100644 --- a/test/expected/subdir/test_in_subdir.js +++ b/test/expected/subdir/test_in_subdir.js @@ -26,4 +26,4 @@ describe('Array', function () { }); }); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvc3ViZGlyL3Rlc3RfaW5fc3ViZGlyLmpzIl0sIm5hbWVzIjpbImFzc2VydCIsInJlcXVpcmUiLCJkZXNjcmliZSIsImJlZm9yZUVhY2giLCJhcnkiLCJpdCIsInplcm8iLCJ0d28iLCJfZXhwciIsIl9jYXB0IiwiaW5kZXhPZiIsImNvbnRlbnQiLCJmaWxlcGF0aCIsImxpbmUiLCJtaW51c09uZSIsIm9rIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxNQUFBLEdBQVNDLE9BQUEsQ0FBUSxjQUFSLENBQWI7QUFFQUMsUUFBQSxDQUFTLE9BQVQsRUFBa0IsWUFBVTtBQUFBLElBQ3hCQyxVQUFBLENBQVcsWUFBVTtBQUFBLFFBQ2pCLEtBQUtDLEdBQUwsR0FBVztBQUFBLFlBQUMsQ0FBRDtBQUFBLFlBQUcsQ0FBSDtBQUFBLFlBQUssQ0FBTDtBQUFBLFNBQVgsQ0FEaUI7QUFBQSxLQUFyQixFQUR3QjtBQUFBLElBSXhCRixRQUFBLENBQVMsWUFBVCxFQUF1QixZQUFVO0FBQUEsUUFDN0JHLEVBQUEsQ0FBRyxnREFBSCxFQUFxRCxZQUFVO0FBQUEsWUFDM0QsSUFBSUMsSUFBQSxHQUFPLENBQVgsRUFBY0MsR0FBQSxHQUFNLENBQXBCLENBRDJEO0FBQUEsWUFFM0RQLE1BQUEsQ0FBT0EsTUFBQSxDQUFBUSxLQUFBLENBQUFSLE1BQUEsQ0FBQVMsS0FBQSxDQUFBVCxNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLE1BQUtMLEdBQUwsb0NBQVNNLE9BQVQsQ0FBaUJWLE1BQUEsQ0FBQVMsS0FBQSxDQUFBSCxJQUFBLGlDQUFqQiwyQkFBMkJOLE1BQUEsQ0FBQVMsS0FBQSxDQUFBRixHQUFBLHNCQUEzQjtBQUFBLGdCQUFBSSxPQUFBO0FBQUEsZ0JBQUFDLFFBQUE7QUFBQSxnQkFBQUMsSUFBQTtBQUFBLGNBQVAsRUFGMkQ7QUFBQSxTQUEvRCxFQUQ2QjtBQUFBLFFBSzdCUixFQUFBLENBQUcsK0NBQUgsRUFBb0QsWUFBVTtBQUFBLFlBQzFELElBQUlTLFFBQUEsR0FBVyxDQUFDLENBQWhCLEVBQW1CUCxHQUFBLEdBQU0sQ0FBekIsQ0FEMEQ7QUFBQSxZQUUxRFAsTUFBQSxDQUFPZSxFQUFQLENBQVVmLE1BQUEsQ0FBQVEsS0FBQSxDQUFBUixNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLENBQUFULE1BQUEsQ0FBQVMsS0FBQSxNQUFLTCxHQUFMLG9DQUFTTSxPQUFULENBQWlCVixNQUFBLENBQUFTLEtBQUEsQ0FBQUYsR0FBQSxpQ0FBakIsMkJBQTBCUCxNQUFBLENBQUFTLEtBQUEsQ0FBQUssUUFBQSxzQkFBMUI7QUFBQSxnQkFBQUgsT0FBQTtBQUFBLGdCQUFBQyxRQUFBO0FBQUEsZ0JBQUFDLElBQUE7QUFBQSxjQUFWLEVBQThDLDhCQUE5QyxFQUYwRDtBQUFBLFNBQTlELEVBTDZCO0FBQUEsS0FBakMsRUFKd0I7QUFBQSxDQUE1QiIsInNvdXJjZXNDb250ZW50IjpbInZhciBhc3NlcnQgPSByZXF1aXJlKCdwb3dlci1hc3NlcnQnKTtcblxuZGVzY3JpYmUoJ0FycmF5JywgZnVuY3Rpb24oKXtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uKCl7XG4gICAgICAgIHRoaXMuYXJ5ID0gWzEsMiwzXTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnI2luZGV4T2YoKScsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIC0xIHdoZW4gdGhlIHZhbHVlIGlzIG5vdCBwcmVzZW50JywgZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHZhciB6ZXJvID0gMCwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLmFyeS5pbmRleE9mKHplcm8pID09PSB0d28pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5kZXggd2hlbiB0aGUgdmFsdWUgaXMgcHJlc2VudCcsIGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB2YXIgbWludXNPbmUgPSAtMSwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydC5vayh0aGlzLmFyeS5pbmRleE9mKHR3bykgPT09IG1pbnVzT25lLCAnVEhJUyBJUyBBTiBBU1NFUlRJT04gTUVTU0FHRScpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pO1xuIl19 +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3RfaW5fc3ViZGlyLmpzIl0sIm5hbWVzIjpbImFzc2VydCIsInJlcXVpcmUiLCJkZXNjcmliZSIsImJlZm9yZUVhY2giLCJhcnkiLCJpdCIsInplcm8iLCJ0d28iLCJfZXhwciIsIl9jYXB0IiwiaW5kZXhPZiIsImNvbnRlbnQiLCJmaWxlcGF0aCIsImxpbmUiLCJtaW51c09uZSIsIm9rIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxNQUFBLEdBQVNDLE9BQUEsQ0FBUSxjQUFSLENBQWI7QUFFQUMsUUFBQSxDQUFTLE9BQVQsRUFBa0IsWUFBVTtBQUFBLElBQ3hCQyxVQUFBLENBQVcsWUFBVTtBQUFBLFFBQ2pCLEtBQUtDLEdBQUwsR0FBVztBQUFBLFlBQUMsQ0FBRDtBQUFBLFlBQUcsQ0FBSDtBQUFBLFlBQUssQ0FBTDtBQUFBLFNBQVgsQ0FEaUI7QUFBQSxLQUFyQixFQUR3QjtBQUFBLElBSXhCRixRQUFBLENBQVMsWUFBVCxFQUF1QixZQUFVO0FBQUEsUUFDN0JHLEVBQUEsQ0FBRyxnREFBSCxFQUFxRCxZQUFVO0FBQUEsWUFDM0QsSUFBSUMsSUFBQSxHQUFPLENBQVgsRUFBY0MsR0FBQSxHQUFNLENBQXBCLENBRDJEO0FBQUEsWUFFM0RQLE1BQUEsQ0FBT0EsTUFBQSxDQUFBUSxLQUFBLENBQUFSLE1BQUEsQ0FBQVMsS0FBQSxDQUFBVCxNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLE1BQUtMLEdBQUwsb0NBQVNNLE9BQVQsQ0FBaUJWLE1BQUEsQ0FBQVMsS0FBQSxDQUFBSCxJQUFBLGlDQUFqQiwyQkFBMkJOLE1BQUEsQ0FBQVMsS0FBQSxDQUFBRixHQUFBLHNCQUEzQjtBQUFBLGdCQUFBSSxPQUFBO0FBQUEsZ0JBQUFDLFFBQUE7QUFBQSxnQkFBQUMsSUFBQTtBQUFBLGNBQVAsRUFGMkQ7QUFBQSxTQUEvRCxFQUQ2QjtBQUFBLFFBSzdCUixFQUFBLENBQUcsK0NBQUgsRUFBb0QsWUFBVTtBQUFBLFlBQzFELElBQUlTLFFBQUEsR0FBVyxDQUFDLENBQWhCLEVBQW1CUCxHQUFBLEdBQU0sQ0FBekIsQ0FEMEQ7QUFBQSxZQUUxRFAsTUFBQSxDQUFPZSxFQUFQLENBQVVmLE1BQUEsQ0FBQVEsS0FBQSxDQUFBUixNQUFBLENBQUFTLEtBQUEsQ0FBQVQsTUFBQSxDQUFBUyxLQUFBLENBQUFULE1BQUEsQ0FBQVMsS0FBQSxNQUFLTCxHQUFMLG9DQUFTTSxPQUFULENBQWlCVixNQUFBLENBQUFTLEtBQUEsQ0FBQUYsR0FBQSxpQ0FBakIsMkJBQTBCUCxNQUFBLENBQUFTLEtBQUEsQ0FBQUssUUFBQSxzQkFBMUI7QUFBQSxnQkFBQUgsT0FBQTtBQUFBLGdCQUFBQyxRQUFBO0FBQUEsZ0JBQUFDLElBQUE7QUFBQSxjQUFWLEVBQThDLDhCQUE5QyxFQUYwRDtBQUFBLFNBQTlELEVBTDZCO0FBQUEsS0FBakMsRUFKd0I7QUFBQSxDQUE1QiIsImZpbGUiOiJ0ZXN0X2luX3N1YmRpci5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi90ZXN0L2ZpeHR1cmVzL3N1YmRpciIsInNvdXJjZXNDb250ZW50IjpbInZhciBhc3NlcnQgPSByZXF1aXJlKCdwb3dlci1hc3NlcnQnKTtcblxuZGVzY3JpYmUoJ0FycmF5JywgZnVuY3Rpb24oKXtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uKCl7XG4gICAgICAgIHRoaXMuYXJ5ID0gWzEsMiwzXTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnI2luZGV4T2YoKScsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIC0xIHdoZW4gdGhlIHZhbHVlIGlzIG5vdCBwcmVzZW50JywgZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHZhciB6ZXJvID0gMCwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLmFyeS5pbmRleE9mKHplcm8pID09PSB0d28pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gaW5kZXggd2hlbiB0aGUgdmFsdWUgaXMgcHJlc2VudCcsIGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB2YXIgbWludXNPbmUgPSAtMSwgdHdvID0gMjtcbiAgICAgICAgICAgIGFzc2VydC5vayh0aGlzLmFyeS5pbmRleE9mKHR3bykgPT09IG1pbnVzT25lLCAnVEhJUyBJUyBBTiBBU1NFUlRJT04gTUVTU0FHRScpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn0pO1xuIl19