UNPKG

4.81 kBJavaScriptView Raw
1// Load our dependencies
2var assert = require('assert');
3var fs = require('fs');
4var path = require('path');
5var minstache = require('minstache');
6var jsStringEscape = require('js-string-escape');
7var combineSourceMap = require('combine-source-map');
8var convertSourceMap = require('convert-source-map');
9
10// Define our constants
11var CONTENT_PLACEHOLDER_STR = '__CONTENT__';
12
13// Resolve filepath to Karma's `context.html` and `debug.html`
14// https://github.com/karma-runner/karma/blob/v1.3.0/lib/middleware/karma.js#L138-L157
15// https://github.com/karma-runner/karma/blob/v1.3.0/lib/web-server.js#L33-L37
16// https://github.com/karma-runner/karma/blob/v1.3.0/lib/middleware/common.js#L30-L70
17var karmaWebServerFilepath = require.resolve('karma/lib/web-server');
18var karmaStaticDirectoryFilepath = path.normalize(path.join(path.dirname(karmaWebServerFilepath), '/../static'));
19// Example: /home/todd/github/karma-electron/node_modules/karma/static/context.html
20var karmaDefaultContextFile = karmaStaticDirectoryFilepath + '/context.html';
21var karmaDefaultDebugFile = karmaStaticDirectoryFilepath + '/debug.html';
22
23// Load our template
24// DEV: We minify to remove impact of line numbers
25// To reproduce this, make a test fail and remove minification
26// Notice how the error line goes from 10 to 30 =(
27// DEV: We should be using a minifier but the mustache template prevents this
28var templateStr = fs.readFileSync(__dirname + '/node-integration-iframe.mustache.js', 'utf8');
29var minifiedTemplateStr = templateStr.replace(/\/\/[^\n]+/g, '\n').replace(/\n/g, '');
30// DEV: Fix up JSCS work arounds
31minifiedTemplateStr = minifiedTemplateStr.replace(/{{if_/g, '{{#')
32 .replace(/{{notif_/g, '{{^').replace(/{{end_/g, '{{/');
33// DEV: We inject a newline after content to prevent `//` comments from breaking our closure
34minifiedTemplateStr = minifiedTemplateStr.replace(CONTENT_PLACEHOLDER_STR, CONTENT_PLACEHOLDER_STR + '\n');
35var template = minstache.compile(minifiedTemplateStr);
36
37// Define our framework to inject our `node-integration`
38var $inject = ['config.basePath', 'config.client', 'config.customContextFile', 'config.customDebugFile'];
39function createElectronPreprocessor(karmaBasePath, karmaClientConfig, karmaCustomContextFile, karmaCustomDebugFile) {
40 // Generate our preprocessor function
41 function electronPreprocessor(content, file, done) {
42 // Render our content without a source map
43 var output = template({
44 __filenameOverride: karmaClientConfig.__filenameOverride,
45 dirname: jsStringEscape(path.dirname(file.originalPath)),
46 filename: jsStringEscape(file.originalPath),
47 karmaBasePath: jsStringEscape(karmaBasePath),
48 karmaContextFile: jsStringEscape(karmaCustomContextFile || karmaDefaultContextFile),
49 karmaDebugFile: jsStringEscape(karmaCustomDebugFile || karmaDefaultDebugFile),
50 loadScriptsViaRequire: !!karmaClientConfig.loadScriptsViaRequire,
51 sep: jsStringEscape(path.sep)
52 });
53
54 // If we are using `loadScriptsViaRequire`
55 if (karmaClientConfig.loadScriptsViaRequire) {
56 // If there was a source map, notify user about sourcemap loss
57 var contentSourceMap = convertSourceMap.fromSource(content);
58 if (contentSourceMap) {
59 console.warn('Detected sourcemap in "' + file.originalPath + '" while `loadScriptsViaRequire: true` was set. ' +
60 '`karma-electron` cannot sourcemap this content as it\'s no longer present in the file ' +
61 'as it\'s loaded via `require`');
62 }
63 // Otherwise, we are directly injecting content
64 } else {
65 // Create a source map with our content on a new line
66 // DEV: Heavily based on https://github.com/browserify/browser-pack/blob/v6.1.0/index.js#L56-L102
67 var splitOutput = output.split(CONTENT_PLACEHOLDER_STR);
68 assert.strictEqual(splitOutput.length, 2);
69 var sourcemapCombiner = combineSourceMap.create();
70 sourcemapCombiner.addFile({
71 // /home/todd/.../_node-integration-iframe.mustache.js/home/path/to/file
72 sourceFile: __dirname + '/_node-integration-iframe.mustache.js' + file.originalPath,
73 source: splitOutput[0]
74 }, {line: 0});
75 sourcemapCombiner.addFile({
76 sourceFile: file.originalPath,
77 source: content
78 }, {line: 1});
79
80 // Generate our output with our combiner's result
81 output = [
82 splitOutput[0],
83 content,
84 splitOutput[1],
85 sourcemapCombiner.comment()
86 ].join('\n');
87 }
88
89 // Callback with our content
90 done(null, output);
91 }
92
93 // Return our preprocessor
94 return electronPreprocessor;
95}
96
97// Define depenencies so our function can receive them
98createElectronPreprocessor.$inject = $inject;
99
100// Export our launcher
101module.exports = {
102 'preprocessor:electron': ['factory', createElectronPreprocessor]
103};