'use strict'; const fs = require('fs'); const path = require('path'); const test = require('tap').test; const uniqueTempDir = require('unique-temp-dir'); const sinon = require('sinon'); const babel = require('babel-core'); const fromMapFileSource = require('convert-source-map').fromMapFileSource; const CachingPrecompiler = require('../lib/caching-precompiler'); const fixture = name => path.join(__dirname, 'fixture', name); const endsWithJs = filename => /\.js$/.test(filename); const endsWithMap = filename => /\.js\.map$/.test(filename); sinon.spy(babel, 'transform'); test('creation with new', t => { const tempDir = uniqueTempDir(); const precompiler = new CachingPrecompiler({path: tempDir}); t.is(precompiler.cacheDirPath, tempDir); t.end(); }); test('adds files and source maps to the cache directory as needed', t => { const tempDir = uniqueTempDir(); const precompiler = new CachingPrecompiler({path: tempDir}); t.false(fs.existsSync(tempDir), 'cache directory is not created before it is needed'); precompiler.precompileFile(fixture('es2015.js')); t.true(fs.existsSync(tempDir), 'cache directory is lazily created'); const files = fs.readdirSync(tempDir); t.is(files.length, 2); t.is(files.filter(endsWithJs).length, 1, 'one .js file is saved to the cache'); t.is(files.filter(endsWithMap).length, 1, 'one .js.map file is saved to the cache'); t.end(); }); test('adds a map file comment to the cached files', t => { const tempDir = uniqueTempDir(); const precompiler = new CachingPrecompiler({path: tempDir}); precompiler.precompileFile(fixture('es2015.js')); let cachedCode; let cachedMap; fs.readdirSync(tempDir).map(file => path.join(tempDir, file)).forEach(file => { if (endsWithJs(file)) { cachedCode = fs.readFileSync(file, 'utf8'); } else if (endsWithMap(file)) { cachedMap = fs.readFileSync(file, 'utf8'); } }); // This is comparable to how nyc resolves the source map. It has access to the // cached code but believes it to come from the original es2015.js fixture. // Ensure the cached map can be resolved from the cached code. Also see // . const foundMap = fromMapFileSource(cachedCode, path.join(__dirname, 'fixture')); t.ok(foundMap); t.is(foundMap.toJSON(), cachedMap); t.end(); }); test('uses default babel options when babelConfig === "default"', t => { const tempDir = uniqueTempDir(); const precompiler = new CachingPrecompiler({ path: tempDir, babel: 'default' }); babel.transform.reset(); precompiler.precompileFile(fixture('es2015.js')); t.true(babel.transform.calledOnce); const options = babel.transform.firstCall.args[1]; t.true('filename' in options); t.true(options.sourceMaps); t.false(options.ast); t.true('inputSourceMap' in options); t.false(options.babelrc); t.true(Array.isArray(options.presets)); t.end(); }); test('allows babel config from package.json/babel when babelConfig === "inherit"', t => { const tempDir = uniqueTempDir(); const precompiler = new CachingPrecompiler({ path: tempDir, babel: 'inherit' }); babel.transform.reset(); precompiler.precompileFile(fixture('es2015.js')); t.true(babel.transform.calledOnce); const options = babel.transform.firstCall.args[1]; t.true('filename' in options); t.true(options.sourceMaps); t.false(options.ast); t.true('inputSourceMap' in options); t.true(options.babelrc); t.end(); }); test('does not modify plugins array in babelConfig', t => { const plugins = []; const precompiler = new CachingPrecompiler({ path: uniqueTempDir(), plugins }); precompiler.precompileFile(fixture('es2015.js')); t.strictDeepEqual(plugins, []); t.end(); });