Merge pull request #107 from noscripter/v1.1.3_tests

test: add some more tests
This commit is contained in:
Tobias Koppers 2019-07-30 14:05:58 +02:00 committed by GitHub
commit 66d80e685c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 224 additions and 3 deletions

View File

@ -263,7 +263,8 @@ interface Tap {
type: string
fn: Function,
stage: number,
context: boolean
context: boolean,
before?: string | Array
}
```

View File

@ -11,6 +11,29 @@ const AsyncSeriesWaterfallHook = require("../AsyncSeriesWaterfallHook");
const AsyncSeriesLoopHook = require("../AsyncSeriesLoopHook");
describe("AsyncSeriesHook", () => {
it('should not have call method', () => {
const hook = new AsyncSeriesHook([]);
expect(hook.call).toEqual(undefined)
expect(typeof hook.callAsync).toEqual('function')
expect(typeof hook.promise).toEqual('function')
})
it('should have tap method', (done) => {
const hook = new AsyncSeriesHook([]);
const mockTap = jest.fn()
hook.tap('somePlugin', mockTap)
hook.callAsync(() => done())
expect(mockTap).toHaveBeenCalledTimes(1)
})
it('should have promise method', (done) => {
const hook = new AsyncSeriesHook([]);
const mockTap = jest.fn()
hook.tap('somePlugin', mockTap)
hook.promise().then(() => done())
expect(mockTap).toHaveBeenCalledTimes(1)
})
it("should have to correct behavior", async () => {
const tester = new HookTester(args => new AsyncSeriesHook(args));

View File

@ -12,7 +12,6 @@ describe("SyncBailHook", () => {
it("should allow to create sync bail hooks", async () => {
const h1 = new SyncBailHook(["a"]);
const h2 = new SyncBailHook(["a", "b"]);
const h3 = new SyncBailHook(["a"]);
let r = h1.call(1);
expect(r).toEqual(undefined);
@ -38,6 +37,20 @@ describe("SyncBailHook", () => {
expect(await pify(cb => h2.callAsync(10, 20, cb))).toEqual([10, 20]);
});
it('should bail on non-null return', async() => {
const h1 = new SyncBailHook(["a"]);
const mockCall1 = jest.fn();
const mockCall2 = jest.fn(() => 'B')
const mockCall3 = jest.fn(() => 'C')
h1.tap('A', mockCall1)
h1.tap('B', mockCall2)
h1.tap('C', mockCall3)
expect(h1.call()).toEqual('B')
expect(mockCall1).toHaveBeenCalledTimes(1)
expect(mockCall2).toHaveBeenCalledTimes(1)
expect(mockCall3).toHaveBeenCalledTimes(0)
})
it("should allow to intercept calls", () => {
const hook = new SyncBailHook(["x"]);
@ -61,6 +74,16 @@ describe("SyncBailHook", () => {
expect(mockCall).toHaveBeenLastCalledWith(7);
expect(mockTap).toHaveBeenCalled();
});
it('should throw on tapAsync', () => {
const hook = new SyncBailHook(["x"]);
expect(() => hook.tapAsync()).toThrow(/tapAsync/)
})
it('should throw on tapPromise', () => {
const hook = new SyncBailHook(["x"]);
expect(() => hook.tapPromise()).toThrow(/tapPromise/)
})
});
function pify(fn) {

View File

@ -67,6 +67,20 @@ describe("SyncHook", () => {
expect(mock5).toHaveBeenLastCalledWith("x", "y", undefined);
});
it('should sync execute hooks', () => {
const h1 = new SyncHook(["a"]);
const mockCall1 = jest.fn();
const mockCall2 = jest.fn(() => 'B')
const mockCall3 = jest.fn(() => 'C')
h1.tap('A', mockCall1)
h1.tap('B', mockCall2)
h1.tap('C', mockCall3)
expect(h1.call()).toEqual(undefined)
expect(mockCall1).toHaveBeenCalledTimes(1)
expect(mockCall2).toHaveBeenCalledTimes(1)
expect(mockCall3).toHaveBeenCalledTimes(1)
})
it("should allow to intercept calls", () => {
const hook = new SyncHook(["arg1", "arg2"]);
@ -101,4 +115,14 @@ describe("SyncHook", () => {
expect(mock2).not.toHaveBeenLastCalledWith(1, 2);
expect(mock0).toHaveBeenLastCalledWith(1, 2);
});
it('should throw error on tapAsync', () => {
const hook = new SyncHook(["arg1", "arg2"]);
expect(() => hook.tapAsync()).toThrow(/tapAsync/)
})
it('should throw error on tapPromise', () => {
const hook = new SyncHook(["arg1", "arg2"]);
expect(() => hook.tapPromise()).toThrow(/tapPromise/)
})
});

View File

@ -0,0 +1,83 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
require("babel-polyfill");
const SyncWaterfallHook = require("../SyncWaterfallHook");
describe("SyncWaterfallHook", () => {
it('should allow to create waterfall hooks', async () => {
const h1 = new SyncWaterfallHook(["a"]);
const h2 = new SyncWaterfallHook(["a", "b"]);
expect(h1.call(1)).toEqual(1);
h1.tap("A", a => undefined);
h2.tap("A", (a, b) => [a, b]);
expect(h1.call(1)).toEqual(1);
expect(await h1.promise(1)).toEqual(1);
expect(await pify(cb => h1.callAsync(1, cb))).toEqual(1);
expect(h2.call(1, 2)).toEqual([1, 2]);
expect(await h2.promise(1, 2)).toEqual([1, 2]);
expect(await pify(cb => h2.callAsync(1, 2, cb))).toEqual([1, 2]);
let count = 1
count = h1.call(count + ++count) // 1 + 2 => 3
count = h1.call(count + ++count) // 3 + 4 => 7
count = h1.call(count + ++count) // 7 + 8 => 15
expect(count).toEqual(15)
})
it('should throw when args have length less than 1', () => {
expect(() => {
new SyncWaterfallHook([]);
}).toThrow(/Waterfall/)
})
it("should allow to intercept calls", () => {
const hook = new SyncWaterfallHook(["x"]);
const mockCall = jest.fn();
const mockTap = jest.fn(x => x);
hook.intercept({
call: mockCall,
tap: mockTap
});
hook.call(5);
expect(mockCall).toHaveBeenLastCalledWith(5);
expect(mockTap).not.toHaveBeenCalled();
hook.tap("test", () => 10);
hook.call(7);
expect(mockCall).toHaveBeenLastCalledWith(7);
expect(mockTap).toHaveBeenCalled();
});
it('should throw on tapAsync', () => {
const hook = new SyncWaterfallHook(["x"]);
expect(() => hook.tapAsync()).toThrow(/tapAsync/)
})
it('should throw on tapPromise', () => {
const hook = new SyncWaterfallHook(["x"]);
expect(() => hook.tapPromise()).toThrow(/tapPromise/)
})
});
function pify(fn) {
return new Promise((resolve, reject) => {
fn((err, result) => {
if (err) reject(err);
else resolve(result);
});
});
}

View File

@ -33,6 +33,40 @@ describe("Tapable", () => {
t.hooks.myHook.call();
});
it('should addCompatLayer', () => {
const inst = {}
Tapable.addCompatLayer(inst)
expect(inst).toHaveProperty('plugin')
expect(inst).toHaveProperty('apply')
inst.hooks = {
myHook: new SyncHook()
};
let called = 0;
inst.plugin("my-hook", () => called++);
inst.hooks.myHook.call();
inst.plugin("myHook", () => (called += 10));
inst.hooks.myHook.call();
expect(called).toEqual(12);
})
it('should use apply', () => {
let called = 0
const customPlugin = {
apply: instance => { // NOTE: argument is a compiler instance
instance.hooks.myHook.tap('do-some-hook', () => called++)
}
}
const t = new Tapable()
t.hooks = {
myHook: new SyncHook()
}
t.apply(customPlugin)
t.hooks.myHook.call()
expect(called).toEqual(1)
})
it("should use custom mapping", () => {
const t = new Tapable();
t.hooks = {
@ -53,11 +87,44 @@ describe("Tapable", () => {
});
t.plugin("my-hook", () => called++);
t.plugin("hookMap test", () => (called += 10));
const otherHookMapName = 'nothookMap other'
expect(() => {
t.plugin("nothookMap other", () => (called -= 10));
}).toThrow(new RegExp(otherHookMapName))
t.plugin("hookMap other", () => (called -= 10));
t.hooks.myHook.call();
expect(called).toEqual(1);
t.hooks.hookMap.for("test").call();
expect(called).toEqual(11);
t.hooks.hookMap.for("other").call();
expect(called).toEqual(11);
expect(called).toEqual(1);
});
it('should throw if hook not defined', () => {
const t = new Tapable()
t.hooks = {
hello: new SyncHook(),
}
let called = 0
t.plugin('hello', () => (called += 2))
t.hooks.hello.call()
expect(called).toEqual(2)
expect(() => {
t.plugin('world', () => (called += 1000))
}).toThrow(/world/)
})
it('should support Array name plugin', () => {
const t = new Tapable()
t.hooks = {
hello: new SyncHook(),
world: new SyncHook(),
}
let called = 0
t.plugin(['hello', 'world'], () => (called += 2))
t.hooks.hello.call()
expect(called).toEqual(2)
t.hooks.world.call()
expect(called).toEqual(4)
})
});