Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

karma-parallel

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

karma-parallel - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

2

karma.conf.js

@@ -23,3 +23,3 @@ // Karma configuration

// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'parallel'],
frameworks: ['parallel', 'jasmine'],

@@ -26,0 +26,0 @@

'use strict';
const path = require('path');
// jshint node: true

@@ -54,2 +56,9 @@

module.exports = function(/* config */fullConfig, emitter, logger) {
if (fullConfig.frameworks[0] !== 'parallel') {
// We have to be loaded first to make sure we load our parallelizer script *after* the jasmine/mocha script runs
throw new Error(`The "parallel" framework must be loaded first into the karma frameworks array. \nActual: config.frameworks: ${JSON.stringify(fullConfig.frameworks)}`);
}
fullConfig.files.unshift({pattern: path.join(__dirname, 'karma-parallelizer.js'), included: true, served: true, watched: false});
const log = logger.create('framework:karma-parallel');

@@ -56,0 +65,0 @@ const config = getConfig(fullConfig);

@@ -5,3 +5,3 @@ 'use strict';

function initKarmaParallelizer(root, shardIndexInfo) {
function initKarmaParallelizer(root, karma, shardIndexInfo) {
if (!shardIndexInfo || !shardIndexInfo.shouldShard) {

@@ -12,40 +12,12 @@ // console.log('Skipping sharding. Could not find index and count values');

const strategy = getSpecSuiteStrategy(shardIndexInfo);
const overrideSpecSuite = createSpecSuiteOverrider(strategy);
var strategy = getSpecSuiteStrategy(shardIndexInfo);
var fakeContextStatus = createFakeTestContext(root, strategy);
// Mocha uses describe.only|skip
// Jasmine uses fdescribe|ddescribe|xdescribe
replaceMethod(root, 'describe', function(method) {
const overriden = overrideSpecSuite(method);
replaceMethod(overriden, 'only', overrideSpecSuite);
replaceMethod(overriden, 'skip', overrideSpecSuite);
return overriden;
});
replaceMethod(root, 'xdescribe', overrideSpecSuite);
replaceMethod(root, 'fdescribe', overrideSpecSuite);
replaceMethod(root, 'ddescribe', overrideSpecSuite);
var origStart = karma.start;
karma.start = function() {
fakeContextStatus.beforeStartup();
origStart.call(this);
};
}
function replaceMethod(root, methodName, overrider) {
const tmpOriginalFunction = root[methodName];
let overriddenFunction;
// Make a getter / setter that overrides the method when initialized
Object.defineProperty(root, methodName, {
enumerable: true,
configurable: true,
get: function() {
return overriddenFunction;
},
set: function(method) {
overriddenFunction = overrider(method);
}
});
// If we already have a function on the global, immediately set it back which wraps and overrides it
if (typeof tmpOriginalFunction === 'function') {
root[methodName] = tmpOriginalFunction;
}
}
function getSpecSuiteStrategy(shardIndexInfo) {

@@ -62,21 +34,6 @@ switch (shardIndexInfo.shardStrategy) {

function createSpecSuiteOverrider(strategy) {
let depth = 0;
return function overrideSpecSuite(origDescribe) {
return function(description, specDefinitions) {
// If we are a top-level, ask our strategy if we should be interested in this suite
if (depth === 0 && !strategy(description, specDefinitions)) {
// console.log('[skipping]', description);
} else {
origDescribe(description, function() {
depth++;
specDefinitions();
depth--;
});
}
};
};
}
function createDescriptionLengthStragegy({shardIndex, executors}) {
function createDescriptionLengthStragegy(shardIndexInfo) {
var
shardIndex = shardIndexInfo.shardIndex,
executors = shardIndexInfo.executors;
return function overrideSpecSuite(description/*, specDefinitions*/) {

@@ -87,6 +44,9 @@ return description.length % executors === shardIndex;

function createRoundRobinStrategy({shardIndex, executors}) {
function createRoundRobinStrategy(shardIndexInfo) {
var
shardIndex = shardIndexInfo.shardIndex,
executors = shardIndexInfo.executors;
// Increment the count on each top level describe to determine
// round-robin responsibility
let count = 0;
var count = 0;
return function(/*description, specDefinitions*/) {

@@ -97,2 +57,95 @@ return count++ % executors === shardIndex;

initKarmaParallelizer(window, JSON.parse('%KARMA_SHARD_INFO%'));
function createFakeTestContext(ctx, shouldUseDescription) {
var depth = 0;
var isFaking = false; // Are we currently faking out describe blocks to look for tests for other instances
var hasFocusedWhileFaking = false; // Have we found a focus tests for another instance
var hasFocusedWithoutFaking = false; // Have we registerd at least one focus test for this instance
var hasSpecs = false; // Have we registered at least one test for this instance
var forceDescribe = false; //
function wrapDescription(def) {
return function() {
try {
depth++;
def.call(this);
} finally {
depth--;
}
};
}
function wrap(fn, isFocus, isDescription, isSpec) {
if (!fn) return fn;
return function(name, def) {
if (isDescription && depth === 0) {
// Reset isFaking on top-level descriptions
isFaking = !shouldUseDescription(name, def);
}
hasSpecs = hasSpecs || (isSpec && !isFaking);
hasFocusedWhileFaking = hasFocusedWhileFaking || (isFocus && isFaking);
hasFocusedWithoutFaking = hasFocusedWithoutFaking || (isFocus && !isFaking);
if (isDescription) def = wrapDescription(def);
if (!isFaking || forceDescribe) {
// Call through to framework
fn.call(this, name, def);
} else if (isDescription) {
// If its a fake description, then we need to call through to eval inner its() looking for focuses
// TODO, do we ever need parameters?
def();
}
};
}
// Save as vars before we replace them
var describeOnly = ctx.describe.only;
var describeSkip = ctx.describe.skip;
var itOnly = ctx.it.only;
var itSkip = ctx.it.skip;
ctx.describe = wrap(ctx.describe, false, true, false);
ctx.context = wrap(ctx.context, false, true, false);
ctx.xdescribe = wrap(ctx.xdescribe, false, true, false);
ctx.describe.skip = wrap(describeSkip, false, true, false);
ctx.fdescribe = wrap(ctx.fdescribe, true, true, false);
ctx.ddescribe = wrap(ctx.ddescribe, true, true, false);
ctx.describe.only = wrap(describeOnly, true, true, false);
ctx.it = wrap(ctx.it, false, false, true);
ctx.specify = wrap(ctx.specify, false, false, true);
ctx.xit = wrap(ctx.xit, false, false, true);
ctx.xspecify = wrap(ctx.xspecify, false, false, true);
ctx.it.skip = wrap(itSkip, false, false, true);
ctx.fit = wrap(ctx.fit, true, false, true);
ctx.iit = wrap(ctx.iit, true, false, true);
ctx.it.only = wrap(itOnly, true, false, true);
ctx.before = wrap(ctx.before, false, false, false);
ctx.beforeAll = wrap(ctx.beforeAll, false, false, false);
ctx.beforeEach = wrap(ctx.beforeEach, false, false, false);
ctx.beforeAll = wrap(ctx.beforeAll, false, false, false);
ctx.after = wrap(ctx.after, false, false, false);
ctx.afterEach = wrap(ctx.afterEach, false, false, false);
return {
beforeStartup: function() {
forceDescribe = true;
if (hasFocusedWhileFaking && !hasFocusedWithoutFaking) {
ctx.describe('[karma-parallel] Fake focused test spec', function() {
(ctx.fit || ctx.iit || ctx.it.only).call(ctx, 'should prevent other tests from running', function(){});
});
}
if (!hasSpecs) {
ctx.describe('[karma-parallel] Add single test to prevent failure', function() {
(ctx.it || ctx.specify).call(ctx, 'should prevent failing by having sucessful tests', function(){});
});
}
forceDescribe = false;
}
};
}
initKarmaParallelizer(window, window.__karma__, JSON.parse('%KARMA_SHARD_INFO%'));

@@ -9,4 +9,3 @@ 'use strict';

const karmaParallelScriptName = 'karma-parallelizer.js';
const karmaParallelScriptPath = path.join(__dirname, karmaParallelScriptName);
const karmaParallelScript = fs.readFileSync(karmaParallelScriptPath, 'utf8'); // eslint-disable-line security/detect-non-literal-fs-filename
const karmaParallelScript = fs.readFileSync(path.join(__dirname, karmaParallelScriptName), 'utf8'); // eslint-disable-line security/detect-non-literal-fs-filename

@@ -41,4 +40,2 @@ const idParamExtractor = /\/\?id=(\d+)/;

module.exports = function(/* config */fullConfig, /* config.parallelOptions */config) {
fullConfig.files.unshift({pattern: karmaParallelScriptPath, included: true, served: true, watched: false});
return function (request, response, next) {

@@ -45,0 +42,0 @@ // Responsible for finding the id of the browser and saving it as a cookie so all future requests can access it

@@ -57,3 +57,3 @@ {

},
"version": "0.1.1"
"version": "0.1.2"
}

@@ -45,8 +45,9 @@ # karma-parallel

config.set({
frameworks: ['mocha' /* or 'jasmine' */, 'parallel'], // this will load the framework and beforeMiddleware
// NOTE: 'parallel' must be the first framework in the list
frameworks: ['parallel', 'mocha' /* or 'jasmine' */, ],
parallelOptions: {
executors: 4,
shardStrategy: 'round-robin' /* or 'description-length' */
executors: 4, // Defaults to cpu-count - 1
shardStrategy: 'round-robin'
// shardStrategy: 'description-length'
}

@@ -74,3 +75,13 @@ });

## Important Notes
**Why are there extra tests in my output?**
If this plugin discovers that you have focused some tests (fit, it.only, etc...) in other browser instances, it will add an extra focused test in the current browser instance to limit the running of the tests in the given browser. Similarly, when dividing up the tests, if there are not enough tests for a given browser, it will add an extra test to prevent karma from failing due to no running tests.
**What about code coverage?**
Currently, code-coverage reports are not supported, although soon they will be. Stay tuned (or make a PR)!
----

@@ -77,0 +88,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc