diff --git a/.jshintrc b/.jshintrc index 36a93d9..0ad136c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,4 +1,5 @@ { "node": true, - "strict": true -} \ No newline at end of file + "strict": true, + "esversion": 6 +} diff --git a/index.js b/index.js index 1849a46..cb84ce2 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,8 @@ var urlRegex = /^(https?|webpack(-[^:]+)?):\/\//; * Initialize source mapping chain */ module.exports.init = function init(options) { + var debug = require('debug-fabulous')()(PLUGIN_NAME + ':init'); + function sourceMapInit(file, encoding, callback) { /*jshint validthis:true */ @@ -33,11 +35,13 @@ module.exports.init = function init(options) { if (options === undefined) { options = {}; } + debug(() => {return options;}); var fileContent = file.contents.toString(); var sourceMap; if (options.loadMaps) { + debug('loadMaps'); var sourcePath = ''; //root path for the sources in the map // Try to read inline source map @@ -99,11 +103,11 @@ module.exports.init = function init(options) { } else { try { if (options.debug) - console.log(PLUGIN_NAME + '-init: No source content for "' + source + '". Loading from file.'); + debug('No source content for "' + source + '". Loading from file.'); sourceContent = stripBom(fs.readFileSync(absPath, 'utf8')); } catch (e) { if (options.debug) - console.warn(PLUGIN_NAME + '-init: source file not found: ' + absPath); + debug('warn: source file not found: ' + absPath); } } sourceMap.sourcesContent[i] = sourceContent; @@ -116,6 +120,7 @@ module.exports.init = function init(options) { } if (!sourceMap && options.identityMap) { + debug(() => { return 'identityMap'; }); var fileType = path.extname(file.path); var source = unixStylePath(file.relative); var generator = new SourceMapGenerator({file: source}); @@ -140,7 +145,9 @@ module.exports.init = function init(options) { sourceMap = generator.toJSON(); } else if (fileType === '.css') { + debug('css'); var ast = css.parse(fileContent, {silent: true}); + debug(() => { return ast;}); var registerTokens = function(ast) { if (ast.position) { generator.addMapping({ @@ -149,11 +156,19 @@ module.exports.init = function init(options) { source: source, }); } + + function logAst(key, ast) { + debug(() => { return 'key: ' + key;}); + debug(() => { return ast[key];}); + } + for (var key in ast) { + logAst(key, ast); if (key !== "position") { if (Object.prototype.toString.call(ast[key]) === '[object Object]') { registerTokens(ast[key]); - } else if (ast[key].constructor === Array) { + } else if (Array.isArray(ast[key])) { + debug(() => { return "@@@@ ast[key] isArray @@@@";}); for (var i = 0; i < ast[key].length; i++) { registerTokens(ast[key][i]); } @@ -195,6 +210,8 @@ module.exports.init = function init(options) { * */ module.exports.write = function write(destPath, options) { + var debug = require('debug-fabulous')()(PLUGIN_NAME + ':write'); + if (options === undefined && Object.prototype.toString.call(destPath) === '[object Object]') { options = destPath; destPath = undefined; @@ -209,6 +226,7 @@ module.exports.write = function write(destPath, options) { if (options.charset === undefined) options.charset = "utf8"; + debug(()=> {return options;}); function sourceMapWrite(file, encoding, callback) { /*jshint validthis:true */ @@ -253,11 +271,11 @@ module.exports.write = function write(destPath, options) { var sourcePath = path.resolve(sourceMap.sourceRoot || file.base, sourceMap.sources[i]); try { if (options.debug) - console.log(PLUGIN_NAME + '-write: No source content for "' + sourceMap.sources[i] + '". Loading from file.'); + debug('No source content for "' + sourceMap.sources[i] + '". Loading from file.'); sourceMap.sourcesContent[i] = stripBom(fs.readFileSync(sourcePath, 'utf8')); } catch (e) { if (options.debug) - console.warn(PLUGIN_NAME + '-write: source file not found: ' + sourcePath); + debug('source file not found: ' + sourcePath); } } } diff --git a/package.json b/package.json index 195c627..fd08b3e 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "acorn": "4.X", "convert-source-map": "1.X", "css": "2.X", + "debug-fabulous": "0.0.X", "detect-newline": "2.X", "graceful-fs": "4.X", "source-map": "0.X", @@ -31,11 +32,12 @@ "vinyl": "1.X" }, "devDependencies": { - "jshint": "2.X", - "tape": "4.X", - "istanbul": "0.X", + "coveralls": "2.X", "faucet": "0.0.X", - "coveralls": "2.X" + "hook-std": "0.2.X", + "istanbul": "0.X", + "jshint": "2.X", + "tape": "4.X" }, "files": [ "index.js" diff --git a/test/consolerecorder.js b/test/consolerecorder.js deleted file mode 100644 index 86e38f9..0000000 --- a/test/consolerecorder.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; -module.exports = function recordConsole() { - var functions = ['log', 'warn', 'error']; - var originals = {}; - var history = {}; - functions.forEach(function(func) { - originals[func] = console[func]; - history[func] = []; - console[func] = function(msg) { - history[func].push(msg); - }; - }); - return { - history: history, - restore: function() { - functions.forEach(function(func) { - console[func] = originals[func]; - }); - } - }; -}; diff --git a/test/init.js b/test/init.js index 8d032bf..0ba03fb 100644 --- a/test/init.js +++ b/test/init.js @@ -6,7 +6,8 @@ var File = require('vinyl'); var ReadableStream = require('stream').Readable; var path = require('path'); var fs = require('fs'); -var recordConsole = require('./consolerecorder.js'); +var hookStd = require('hook-std'); +var debug = require('debug-fabulous')(); var sourceContent = fs.readFileSync(path.join(__dirname, 'assets/helloworld.js')).toString(); var sourceContentCSS = fs.readFileSync(path.join(__dirname, 'assets/test.css')).toString(); @@ -20,6 +21,20 @@ function makeFile() { }); } +function makeNullFile() { + var junkBuffer = new Buffer([]); + junkBuffer.toString = function(){ + return null; + }; + + return new File({ + cwd: __dirname, + base: path.join(__dirname, 'assets'), + path: path.join(__dirname, 'assets', 'helloworld.js'), + contents: junkBuffer + }); +} + function makeStreamFile() { return new File({ cwd: __dirname, @@ -334,22 +349,6 @@ test('init: should not load source content if the path is a url', function(t) { .write(file); }); -test('init: should output an error message if debug option is set and sourceContent is missing', function(t) { - var file = makeFile(); - file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld4.js.map'); - - var hConsole = recordConsole(); - var pipeline = sourcemaps.init({loadMaps: true, debug: true}); - pipeline - .on('data', function(data) { - hConsole.restore(); - t.equal(hConsole.history.log[0], 'gulp-sourcemap-init: No source content for "missingfile". Loading from file.', 'should log missing source content'); - t.ok(hConsole.history.warn[0].indexOf('gulp-sourcemap-init: source file not found: ') === 0, 'should warn about missing file'); - t.end(); - }) - .write(file); -}); - test('init: should pass through when file already has a source map', function(t) { var sourceMap = { version : 3, @@ -376,3 +375,51 @@ test('init: should pass through when file already has a source map', function(t) }) .write(file); }); + + +test('init: handle null contents', function(t) { + var pipeline = sourcemaps.init({addComment:true}); + pipeline + .on('data', function(data) { + t.ok(data, 'should pass something through'); + t.ok(data instanceof File, 'should pass a vinyl file through'); + t.ok(data.sourceMap, 'should add a source map object'); + t.equal(String(data.sourceMap.version), '3', 'should have version 3'); + t.equal(data.sourceMap.sources[0], 'helloworld.js', 'should add file to sources'); + t.equal(data.sourceMap.sourcesContent[0], null, 'should add file content to sourcesContent'); + t.deepEqual(data.sourceMap.names, [], 'should add empty names'); + t.equal(data.sourceMap.mappings, '', 'should add empty mappings'); + t.end(); + }) + .on('error', function() { + t.fail('emitted error'); + t.end(); + }) + .write(makeNullFile()); +}); + +//should always be last as disabling a debug namespace does not work +test('init: should output an error message if debug option is set and sourceContent is missing', function(t) { + debug.save('gulp-sourcemap:init'); + debug.enable(debug.load()); + + var file = makeFile(); + file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld4.js.map'); + + var history = []; + console.log('HOOKING'); + var unhook = hookStd.stderr((s) => history.push(s)); + var pipeline = sourcemaps.init({loadMaps: true, debug: true}); + + pipeline + .on('data', function() { + unhook(); + debug.save(null); + t.ok(history.length == 4, 'history len'); + t.ok(history[2].match(/No source content for \"missingfile\". Loading from file./), 'should log missing source content'); + t.ok(history[3].match(/source file not found: /), 'should warn about missing file'); + t.end(); + }) + .write(file); + +}); diff --git a/test/write.js b/test/write.js index e04a63c..d141b0a 100644 --- a/test/write.js +++ b/test/write.js @@ -6,7 +6,8 @@ var File = require('vinyl'); var ReadableStream = require('stream').Readable; var path = require('path'); var fs = require('fs'); -var recordConsole = require('./consolerecorder.js'); +var hookStd = require('hook-std'); +var debug = require('debug-fabulous')(); var sourceContent = fs.readFileSync(path.join(__dirname, 'assets/helloworld.js')).toString(); @@ -554,23 +555,6 @@ test('write: should invoke sourceMappingURLPrefix every time', function(t) { .write(makeFile()); }); -test('write: should output an error message if debug option is set and sourceContent is missing', function(t) { - var file = makeFile(); - file.sourceMap.sources[0] += '.invalid'; - delete file.sourceMap.sourcesContent; - - var hConsole = recordConsole(); - var pipeline = sourcemaps.write({debug: true}); - pipeline - .on('data', function(data) { - hConsole.restore(); - t.equal(hConsole.history.log[0], 'gulp-sourcemap-write: No source content for "helloworld.js.invalid". Loading from file.', 'should log missing source content'); - t.ok(hConsole.history.warn[0].indexOf('gulp-sourcemap-write: source file not found: ') === 0, 'should warn about missing file'); - t.end(); - }) - .write(file); -}); - test('write: null as sourceRoot should not set the sourceRoot', function(t) { var file = makeFile(); var pipeline = sourcemaps.write({sourceRoot: null}); @@ -641,3 +625,27 @@ test('write: should allow to change sources', function(t) { }) .write(file); }); + +//should always be last as disabling a debug namespace does not work +test('write: should output an error message if debug option is set and sourceContent is missing', function(t) { + debug.save('gulp-sourcemap:write'); + debug.enable(debug.load()); + var file = makeFile(); + file.sourceMap.sources[0] += '.invalid'; + delete file.sourceMap.sourcesContent; + + var history = []; + var unhook = hookStd.stderr(s => history.push(s)); + var pipeline = sourcemaps.write({debug: true}); + pipeline + .on('data', function(data) { + unhook(); + debug.save(null); + // console.log(JSON.stringify(history)) + t.ok(history.length == 3, 'history len'); + t.ok(history[1].match(/No source content for "helloworld.js.invalid". Loading from file./), 'should log missing source content'); + t.ok(history[2].match(/source file not found: /), 'should warn about missing file'); + t.end(); + }) + .write(file); +});