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

@fatso83/mini-mocha

Package Overview
Dependencies
Maintainers
2
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fatso83/mini-mocha - npm Package Compare versions

Comparing version 2.2.0 to 2.2.1

lib/functions.js

141

index.js

@@ -1,94 +0,51 @@

const { assertFunction, assertTitle } = require("./lib/util");
const { Processor, TASK_TYPE, TASK_ADDED_EVENT_NAME } = require("./lib/processor");
const { META_DATA } = require("./lib/executor");
const { assertNumber } = require("./lib/util");
const { Processor } = require("./lib/processor");
const { DefaultReporter, RunKitReporter } = require("./lib/reporters");
const functions = require("./lib/functions");
/**
* Purpose of using the "caller" is to
* keep the each "it"s and "eachHooks" inside the function.
* I set the metaData attribute in the caller function.
* (check the "describe" function)
*
* TODO:
* Since "caller" attribute is none standard approach,
* Lets try to replace this with better approach
*/
function after(fn) {
assertFunction(fn);
after.caller[META_DATA].afterHook = fn;
}
function afterEach(fn) {
assertFunction(fn);
afterEach.caller[META_DATA].afterEachHookCollection.push(fn);
}
function before(fn) {
assertFunction(fn);
before.caller[META_DATA].beforeHook = fn;
}
function beforeEach(fn) {
assertFunction(fn);
beforeEach.caller[META_DATA].beforeEachHookCollection.push(fn);
}
function describe(title, fn) {
assertTitle(title);
assertFunction(fn);
fn[META_DATA] = {
title,
afterHook: null,
afterEachHookCollection: [],
beforeHook: null,
beforeEachHookCollection: [],
fns: [],
itCollection: []
};
if (describe.caller && describe.caller[META_DATA]) {
describe.caller[META_DATA].fns.push(fn);
} else {
this.processor.queue.push({
type: TASK_TYPE.describe,
fn
});
this.processor.emit(TASK_ADDED_EVENT_NAME);
const testingHookInterfaces = {
bdd: {
pre: "before",
preEach: "beforeEach",
post: "after",
postEach: "afterEach"
},
tdd: {
pre: "setup",
preEach: "suiteSetup",
pre: "teardown",
preEach: "suiteTeardown"
}
}
};
function it(title, fn) {
assertTitle(title);
assertFunction(fn);
// BDD
const { post: after, postEach: afterEach, pre: before, preEach: beforeEach } = functions;
// TDD
const { post: teardown, postEach: suiteTeardown, pre: setup, preEach: suiteSetup } = functions;
const caller = it.caller ? it.caller[META_DATA] : undefined;
if (!caller) {
this.processor.queue.push({
type: TASK_TYPE.it,
title,
fn
});
module.exports = {
install: function install(isRunKit = false, timeOut = 500) {
if (timeOut !== undefined) {
assertNumber(timeOut);
}
this.processor.emit(TASK_ADDED_EVENT_NAME);
} else {
caller.itCollection.push({
title,
fn
});
}
}
module.exports = {
install: function install(isRunKit = false) {
const reporter = isRunKit ? RunKitReporter : DefaultReporter;
const processor = Processor.getProcessor(reporter);
global.describe = describe.bind({
processor
});
global.it = it.bind({
processor
});
const params = {
processor,
timeOut
};
// BDD
const bddParams = {
testingHookInterfaces: testingHookInterfaces.bdd,
...params
};
const describe = functions.testBlock.bind(bddParams);
const it = functions.testCase.bind(bddParams);
global.context = describe;
global.describe = describe;
global.it = it;
global.specify = it;
global.after = after;

@@ -98,3 +55,17 @@ global.afterEach = afterEach;

global.beforeEach = beforeEach;
// TDD
const tddParams = {
testingHookInterfaces: testingHookInterfaces.tdd,
...params
};
const suite = functions.testBlock.bind(tddParams);
const test = functions.testCase.bind(tddParams);
global.suite = suite;
global.test = test;
global.teardown = teardown;
global.suiteTeardown = suiteTeardown;
global.setup = setup;
global.suiteSetup = suiteSetup;
}
};

@@ -5,11 +5,16 @@ const { isAsync, isCallbackFunction, getPromisify, getErrorMessage } = require("./util");

class Executor {
constructor(reporter) {
passes = 0;
failures = 0;
constructor(reporter, timeOut, testingHookInterfaces) {
this.reporter = reporter;
this.timeOut = timeOut;
this.testingHookInterfaces = testingHookInterfaces;
}
static getExecutor(reporter) {
return new Executor(reporter);
static getExecutor(reporter, timeOut, testingHookInterfaces) {
return new Executor(reporter, timeOut, testingHookInterfaces);
}
async describe(fn) {
async testBlock(fn) {
await this.run(fn);

@@ -22,39 +27,41 @@

// Before
if (metaDataSection.beforeHook) {
await this.hook("before", metaDataSection.beforeHook);
if (metaDataSection.preHook) {
await this.hook(this.testingHookInterfaces.pre, metaDataSection.preHook);
}
// It blocks
for (const singleIt of metaDataSection.itCollection) {
for (const singleTestCase of metaDataSection.testCaseCollection) {
// BeforeEach
for (const be of metaDataSection.beforeEachHookCollection) {
await this.hook("beforeEach", be);
for (const be of metaDataSection.preEachHookCollection) {
await this.hook(this.testingHookInterfaces.preEach, be);
}
// It
await this.it(singleIt.title, singleIt.fn);
await this.testCase(singleTestCase.title, singleTestCase.fn);
// AfterEach
for (const ae of metaDataSection.afterEachHookCollection) {
await this.hook("afterEach", ae);
for (const ae of metaDataSection.postEachHookCollection) {
await this.hook(this.testingHookInterfaces.postEach, ae);
}
}
// describe
// testBlock
if (metaDataSection.fns.length) {
for (const otherDescribe of metaDataSection.fns) {
await this.describe(otherDescribe);
await this.testBlock(otherDescribe);
}
}
if (metaDataSection.afterHook) {
await this.hook("after", metaDataSection.afterHook);
if (metaDataSection.postHook) {
await this.hook(this.testingHookInterfaces.post, metaDataSection.postHook);
}
}
async it(title, fn) {
async testCase(title, fn) {
try {
await this.run(fn);
this.passes++;
this.reporter.log(title);
} catch (err) {
this.failures++;
this.reporter.log(title, getErrorMessage(err));

@@ -65,2 +72,15 @@ }

async run(fn) {
return Promise.race([this.runFn(fn), this.timeOutTrigger(this.timeOut)]);
}
timeOutTrigger(value) {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new Error(`Error: Timeout of ${value}ms exceeded`)), value);
});
}
// issue #22: lack of `this`
// TODO: to enable use of of Mocha API utils such as `this.timeout()`, etc.
// we would need to create a new context for `fn` here, a la fn.call(Object.create(null))
async runFn(fn) {
if (isCallbackFunction(fn)) {

@@ -67,0 +87,0 @@ await getPromisify(fn)();

@@ -0,1 +1,2 @@

const debug = require("debug")("processor");
const { EventEmitter } = require("events");

@@ -7,7 +8,10 @@

const TASK_TYPE = {
describe: "describe",
it: "it"
testBlock: "testBlock",
testCase: "testCase"
};
class Processor extends EventEmitter {
totalFailures = 0;
totalPasses = 0;
constructor(reporterClass) {

@@ -29,20 +33,35 @@ super();

if (this.queue.length) {
debug(`Processing queue (${this.queue.length} elements remaining)`);
if (!this.isProcessing) {
this.isProcessing = true;
this.task();
this.pickNextTaskForProcessing();
}
} else {
debug("No more tasks in processor queue");
debug(`${this.totalFailures} failures out of ${this.totalFailures + this.totalPasses} testcases`);
// needs to be checked at this point, not at start, as test scripts can alter the value after startup
const testMode = !!process.env["MINI_MOCHA_IGNORE_FAILURE"];
if (!testMode && this.totalFailures > 0) {
debug("Exiting with non-zero value. Not test mode");
process.exit(1);
}
}
}
async task() {
async pickNextTaskForProcessing() {
const task = this.queue.shift();
const { fn, type, title } = task;
const { fn, type, title, timeOut, testingHookInterfaces } = task;
const reporter = this.reporterClass.getReporter();
const executor = Executor.getExecutor(reporter);
const executor = Executor.getExecutor(reporter, timeOut, testingHookInterfaces);
try {
type === TASK_TYPE.it ? await executor.it(title, fn) : await executor.describe(fn);
type === TASK_TYPE.testCase ? await executor.testCase(title, fn) : await executor.testBlock(fn);
this.totalPasses += executor.passes;
this.totalFailures += executor.failures;
this.isProcessing = false;
reporter.flush();
// restarts the loop (tail recursion)
this.process();

@@ -49,0 +68,0 @@ } catch (error) {

@@ -16,2 +16,7 @@ const assert = require("assert");

function assertNumber(number) {
assert(typeof number === "number", "given value is not a number");
assert(number >= 0, "given value is not a positive number");
}
function isCallbackFunction(fn) {

@@ -39,3 +44,4 @@ return fn && fn.length === 1;

getPromisify,
getErrorMessage
getErrorMessage,
assertNumber
};
{
"name": "@fatso83/mini-mocha",
"version": "2.2.0",
"version": "2.2.1",
"description": "A minimal emulation of Mocha",

@@ -16,3 +16,4 @@ "main": "index.js",

"test:tarball": "./scripts/test-tarball.sh",
"update-snapshots": "rimraf test/snapshot/* && npm t",
"test:exit-status": "./integration-test/test.sh",
"update-snapshots": "rimraf test/snapshot/tdd/* && rimraf test/snapshot/bdd/* && npm t",
"clean": "rimraf package *.tgz"

@@ -35,3 +36,4 @@ },

"dependencies": {
"@runkit/value-viewer": "1.0.0"
"@runkit/value-viewer": "1.0.0",
"debug": "^4.3.3"
},

@@ -38,0 +40,0 @@ "devDependencies": {

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