diff --git a/.changeset/perf-tap-registration.md b/.changeset/perf-tap-registration.md index 5d12ae6..3cb7bec 100644 --- a/.changeset/perf-tap-registration.md +++ b/.changeset/perf-tap-registration.md @@ -2,32 +2,4 @@ "tapable": patch --- -Perf: reduce allocations and work on the tap registration and compile paths. - -- `Hook#_tap` builds the final tap descriptor in a single allocation for the - common `hook.tap("name", fn)` string-options case instead of creating an - intermediate `{ name }` object that was then merged via `Object.assign`. -- `Hook#_insert` takes an O(1) fast path for the common append case (no - `before`, and stage consistent with the last tap) - the previous - implementation always ran the shift loop once. -- `Hook#_runRegisterInterceptors` early-returns when there are no - interceptors and uses an indexed loop instead of `for…of`. -- `HookMap#for` inlines the `_map.get` lookup instead of routing through - `this.get(key)`, saving a method dispatch on a path hit once per hook - access in consumers like webpack. -- `HookCodeFactory#setup` builds `_x` with a preallocated array + explicit - loop instead of `Array.prototype.map`. -- `HookCodeFactory#init` uses `Array.prototype.slice` instead of spread to - skip the iterator protocol. -- `HookCodeFactory#args` memoizes the common no-before/no-after result so - arguments are joined once per compile rather than once per tap. -- `HookCodeFactory#needContext`, `callTapsSeries`, `callTapsParallel` and - `MultiHook`'s iteration use indexed loops with cached length, and the - series/parallel code hoists the per-tap `done`/`doneBreak` closures - out of the compile-time loop. Replaces `Array.prototype.findIndex` - with a local loop to avoid callback allocation. - -Registering 10 taps on a `SyncHook` is roughly 2× faster, -`SyncHook: tap 5 + first call (compile)` is ~15% faster, and -`HookMap#for (existing key)` is ~6% faster in the micro-benchmarks. -The `.call()` path is unchanged. +Improved performance in many places. diff --git a/eslint.config.mjs b/eslint.config.mjs index 9075656..2379219 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -12,7 +12,7 @@ export default defineConfig([ } }, { - files: ["lib/__tests__/**/*.js"], + files: ["test/**/*"], languageOptions: { parserOptions: { ecmaVersion: 2018 @@ -20,7 +20,7 @@ export default defineConfig([ } }, { - files: ["benchmark/**/*.mjs"], + files: ["benchmark/**/*"], languageOptions: { parserOptions: { ecmaVersion: 2022 diff --git a/package.json b/package.json index a1aa075..1adb212 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "types": "./tapable.d.ts", "files": [ "lib", - "!lib/__tests__", "tapable.d.ts" ], "scripts": { @@ -38,7 +37,7 @@ }, "jest": { "transform": { - "__tests__[\\\\/].+\\.js$": "babel-jest" + "test[\\\\/].+\\.js$": "babel-jest" }, "snapshotFormat": { "escapeString": true, diff --git a/lib/__tests__/AsyncParallelHooks.js b/test/AsyncParallelHooks.test.js similarity index 77% rename from lib/__tests__/AsyncParallelHooks.js rename to test/AsyncParallelHooks.test.js index ce1e8e6..b730cd2 100644 --- a/lib/__tests__/AsyncParallelHooks.js +++ b/test/AsyncParallelHooks.test.js @@ -4,9 +4,9 @@ */ "use strict"; -const AsyncParallelBailHook = require("../AsyncParallelBailHook"); -const AsyncParallelHook = require("../AsyncParallelHook"); -const HookTester = require("./HookTester"); +const AsyncParallelBailHook = require("../lib/AsyncParallelBailHook"); +const AsyncParallelHook = require("../lib/AsyncParallelHook"); +const HookTester = require("./HookTester.test"); describe("AsyncParallelHook", () => { it("should have to correct behavior", async () => { diff --git a/lib/__tests__/AsyncSeriesHooks.js b/test/AsyncSeriesHooks.test.js similarity index 91% rename from lib/__tests__/AsyncSeriesHooks.js rename to test/AsyncSeriesHooks.test.js index fa49992..8aaf12f 100644 --- a/lib/__tests__/AsyncSeriesHooks.js +++ b/test/AsyncSeriesHooks.test.js @@ -4,11 +4,11 @@ */ "use strict"; -const AsyncSeriesBailHook = require("../AsyncSeriesBailHook"); -const AsyncSeriesHook = require("../AsyncSeriesHook"); -const AsyncSeriesLoopHook = require("../AsyncSeriesLoopHook"); -const AsyncSeriesWaterfallHook = require("../AsyncSeriesWaterfallHook"); -const HookTester = require("./HookTester"); +const AsyncSeriesBailHook = require("../lib/AsyncSeriesBailHook"); +const AsyncSeriesHook = require("../lib/AsyncSeriesHook"); +const AsyncSeriesLoopHook = require("../lib/AsyncSeriesLoopHook"); +const AsyncSeriesWaterfallHook = require("../lib/AsyncSeriesWaterfallHook"); +const HookTester = require("./HookTester.test"); describe("AsyncSeriesHook", () => { it("should not have call method", () => { diff --git a/lib/__tests__/DefaultArgs.js b/test/DefaultArgs.test.js similarity index 82% rename from lib/__tests__/DefaultArgs.js rename to test/DefaultArgs.test.js index 435034d..468f6ab 100644 --- a/lib/__tests__/DefaultArgs.js +++ b/test/DefaultArgs.test.js @@ -3,16 +3,16 @@ */ "use strict"; -const AsyncParallelBailHook = require("../AsyncParallelBailHook"); -const AsyncParallelHook = require("../AsyncParallelHook"); -const AsyncSeriesBailHook = require("../AsyncSeriesBailHook"); -const AsyncSeriesHook = require("../AsyncSeriesHook"); -const AsyncSeriesLoopHook = require("../AsyncSeriesLoopHook"); -const AsyncSeriesWaterfallHook = require("../AsyncSeriesWaterfallHook"); -const SyncBailHook = require("../SyncBailHook"); -const SyncHook = require("../SyncHook"); -const SyncLoopHook = require("../SyncLoopHook"); -const SyncWaterfallHook = require("../SyncWaterfallHook"); +const AsyncParallelBailHook = require("../lib/AsyncParallelBailHook"); +const AsyncParallelHook = require("../lib/AsyncParallelHook"); +const AsyncSeriesBailHook = require("../lib/AsyncSeriesBailHook"); +const AsyncSeriesHook = require("../lib/AsyncSeriesHook"); +const AsyncSeriesLoopHook = require("../lib/AsyncSeriesLoopHook"); +const AsyncSeriesWaterfallHook = require("../lib/AsyncSeriesWaterfallHook"); +const SyncBailHook = require("../lib/SyncBailHook"); +const SyncHook = require("../lib/SyncHook"); +const SyncLoopHook = require("../lib/SyncLoopHook"); +const SyncWaterfallHook = require("../lib/SyncWaterfallHook"); describe("Hooks without explicit args", () => { it("should construct SyncHook without args", () => { diff --git a/lib/__tests__/Hook.js b/test/Hook.test.js similarity index 97% rename from lib/__tests__/Hook.js rename to test/Hook.test.js index e2ed299..bb6d2a8 100644 --- a/lib/__tests__/Hook.js +++ b/test/Hook.test.js @@ -4,12 +4,12 @@ */ "use strict"; -const Hook = require("../Hook"); -const SyncHook = require("../SyncHook"); +const HookTest = require("../lib/Hook"); +const SyncHook = require("../lib/SyncHook"); describe("Hook", () => { it("should throw when compile is not overridden", () => { - const hook = new Hook(["arg"]); + const hook = new HookTest(["arg"]); expect(() => hook.compile({ taps: [], interceptors: [], args: [], type: "sync" }) ).toThrow(/Abstract: should be overridden/); diff --git a/lib/__tests__/HookCodeFactory.js b/test/HookCodeFactory.test.js similarity index 97% rename from lib/__tests__/HookCodeFactory.js rename to test/HookCodeFactory.test.js index 2d2a345..55f0d66 100644 --- a/lib/__tests__/HookCodeFactory.js +++ b/test/HookCodeFactory.test.js @@ -4,7 +4,7 @@ */ "use strict"; -const HookCodeFactory = require("../HookCodeFactory"); +const HookCodeFactoryTest = require("../lib/HookCodeFactory"); const expectNoSyntaxError = (code) => { // eslint-disable-next-line no-new @@ -80,7 +80,7 @@ describe("HookCodeFactory", () => { let factory; beforeEach(() => { - factory = new HookCodeFactory(); + factory = new HookCodeFactoryTest(); factory.init(factoryConfigurations[configurationName]); }); @@ -233,7 +233,7 @@ describe("HookCodeFactory", () => { let factory; beforeEach(() => { - factory = new HookCodeFactory(); + factory = new HookCodeFactoryTest(); factory.init(factoryConfigurations[configurationName]); }); diff --git a/lib/__tests__/HookMap.js b/test/HookMap.test.js similarity index 79% rename from lib/__tests__/HookMap.js rename to test/HookMap.test.js index 2aa57ce..6aa5b2a 100644 --- a/lib/__tests__/HookMap.js +++ b/test/HookMap.test.js @@ -3,18 +3,18 @@ */ "use strict"; -const HookMap = require("../HookMap"); -const SyncHook = require("../SyncHook"); +const HookMapTest = require("../lib/HookMap"); +const SyncHook = require("../lib/SyncHook"); describe("HookMap", () => { it("should return undefined from get when the key is unknown", () => { - const map = new HookMap(() => new SyncHook()); + const map = new HookMapTest(() => new SyncHook()); expect(map.get("missing")).toBeUndefined(); }); it("should lazily create hooks through for(...) and cache them", () => { const factory = jest.fn(() => new SyncHook(["a"])); - const map = new HookMap(factory, "myMap"); + const map = new HookMapTest(factory, "myMap"); expect(map.name).toBe("myMap"); @@ -32,7 +32,7 @@ describe("HookMap", () => { }); it("should apply interceptor factories when creating hooks", () => { - const map = new HookMap(() => new SyncHook()); + const map = new HookMapTest(() => new SyncHook()); const wrapped = new SyncHook(); map.intercept({ @@ -47,7 +47,7 @@ describe("HookMap", () => { }); it("should default the interceptor factory to pass-through", () => { - const map = new HookMap(() => new SyncHook()); + const map = new HookMapTest(() => new SyncHook()); map.intercept({}); const hook = map.for("bar"); expect(hook).toBeDefined(); @@ -56,15 +56,15 @@ describe("HookMap", () => { it("should forward deprecated tap helpers to the underlying hook", () => { const warn = jest.spyOn(console, "warn").mockImplementation(() => {}); - const map = new HookMap(() => new SyncHook(["a"])); + const map = new HookMapTest(() => new SyncHook(["a"])); const syncMock = jest.fn(); map.tap("k", "plugin-sync", syncMock); map.for("k").call(1); expect(syncMock).toHaveBeenCalledWith(1); - const asyncMap = new HookMap( - () => new (require("../AsyncSeriesHook"))(["a"]) + const asyncMap = new HookMapTest( + () => new (require("../lib/AsyncSeriesHook"))(["a"]) ); const asyncMock = jest.fn((_a, cb) => cb()); asyncMap.tapAsync("k", "plugin-async", asyncMock); @@ -73,8 +73,8 @@ describe("HookMap", () => { asyncMap.for("k").callAsync(2, () => { expect(asyncMock).toHaveBeenCalled(); - const promiseMap = new HookMap( - () => new (require("../AsyncSeriesHook"))(["a"]) + const promiseMap = new HookMapTest( + () => new (require("../lib/AsyncSeriesHook"))(["a"]) ); const promiseMock = jest.fn(() => Promise.resolve()); promiseMap.tapPromise("k", "plugin-promise", promiseMock); diff --git a/lib/__tests__/HookStackOverflow.js b/test/HookStackOverflow.test.js similarity index 88% rename from lib/__tests__/HookStackOverflow.js rename to test/HookStackOverflow.test.js index 2e79012..ca42ffc 100644 --- a/lib/__tests__/HookStackOverflow.js +++ b/test/HookStackOverflow.test.js @@ -1,6 +1,6 @@ "use strict"; -const AsyncSeriesHook = require("../AsyncSeriesHook"); +const AsyncSeriesHook = require("../lib/AsyncSeriesHook"); describe("HookStackOverflow", () => { it("should not crash when compiling a large hook", () => { diff --git a/lib/__tests__/HookTester.js b/test/HookTester.test.js similarity index 99% rename from lib/__tests__/HookTester.js rename to test/HookTester.test.js index b436fbd..7f7acf8 100644 --- a/lib/__tests__/HookTester.js +++ b/test/HookTester.test.js @@ -11,7 +11,7 @@ describe("HookTester", () => { process.on("unhandledRejection", (err) => console.error(err.stack)); -class HookTester { +class HookTesterTest { constructor(hookCreator, sync) { this.hookCreator = hookCreator; this.sync = sync; @@ -1339,4 +1339,4 @@ class HookTester { } // eslint-disable-next-line jest/no-export -module.exports = HookTester; +module.exports = HookTesterTest; diff --git a/lib/__tests__/MultiHook.js b/test/MultiHook.test.js similarity index 69% rename from lib/__tests__/MultiHook.js rename to test/MultiHook.test.js index 4b186ed..4b3e8cd 100644 --- a/lib/__tests__/MultiHook.js +++ b/test/MultiHook.test.js @@ -4,7 +4,7 @@ */ "use strict"; -const MultiHook = require("../MultiHook"); +const MultiHookTest = require("../lib/MultiHook"); describe("MultiHook", () => { const redirectedMethods = ["tap", "tapAsync", "tapPromise"]; @@ -16,7 +16,7 @@ describe("MultiHook", () => { calls.push({ options, fn }); } }; - new MultiHook([fakeHook, fakeHook])[name]("options", "fn"); + new MultiHookTest([fakeHook, fakeHook])[name]("options", "fn"); expect(calls).toEqual([ { options: "options", fn: "fn" }, { options: "options", fn: "fn" } @@ -31,7 +31,7 @@ describe("MultiHook", () => { calls.push(interceptor); } }; - new MultiHook([fakeHook, fakeHook]).intercept("interceptor"); + new MultiHookTest([fakeHook, fakeHook]).intercept("interceptor"); expect(calls).toEqual(["interceptor", "interceptor"]); }); @@ -47,7 +47,9 @@ describe("MultiHook", () => { }; } }; - const newHook = new MultiHook([fakeHook, fakeHook]).withOptions("options"); + const newHook = new MultiHookTest([fakeHook, fakeHook]).withOptions( + "options" + ); newHook.tap("options", "fn"); expect(calls).toEqual([ "options", @@ -64,9 +66,9 @@ describe("MultiHook", () => { const fakeHook2 = { isUsed: () => false }; - expect(new MultiHook([fakeHook1, fakeHook1]).isUsed()).toBe(true); - expect(new MultiHook([fakeHook1, fakeHook2]).isUsed()).toBe(true); - expect(new MultiHook([fakeHook2, fakeHook1]).isUsed()).toBe(true); - expect(new MultiHook([fakeHook2, fakeHook2]).isUsed()).toBe(false); + expect(new MultiHookTest([fakeHook1, fakeHook1]).isUsed()).toBe(true); + expect(new MultiHookTest([fakeHook1, fakeHook2]).isUsed()).toBe(true); + expect(new MultiHookTest([fakeHook2, fakeHook1]).isUsed()).toBe(true); + expect(new MultiHookTest([fakeHook2, fakeHook2]).isUsed()).toBe(false); }); }); diff --git a/lib/__tests__/SyncBailHook.js b/test/SyncBailHook.test.js similarity index 86% rename from lib/__tests__/SyncBailHook.js rename to test/SyncBailHook.test.js index a73c1b2..a6d93c3 100644 --- a/lib/__tests__/SyncBailHook.js +++ b/test/SyncBailHook.test.js @@ -4,7 +4,7 @@ */ "use strict"; -const SyncBailHook = require("../SyncBailHook"); +const SyncBailHookTest = require("../lib/SyncBailHook"); function pify(fn) { return new Promise((resolve, reject) => { @@ -17,8 +17,8 @@ function pify(fn) { describe("SyncBailHook", () => { it("should allow to create sync bail hooks", async () => { - const h1 = new SyncBailHook(["a"]); - const h2 = new SyncBailHook(["a", "b"]); + const h1 = new SyncBailHookTest(["a"]); + const h2 = new SyncBailHookTest(["a", "b"]); const r = h1.call(1); expect(r).toBeUndefined(); @@ -45,7 +45,7 @@ describe("SyncBailHook", () => { }); it("should bail on non-null return", async () => { - const h1 = new SyncBailHook(["a"]); + const h1 = new SyncBailHookTest(["a"]); const mockCall1 = jest.fn(); const mockCall2 = jest.fn(() => "B"); const mockCall3 = jest.fn(() => "C"); @@ -59,7 +59,7 @@ describe("SyncBailHook", () => { }); it("should allow to intercept calls", () => { - const hook = new SyncBailHook(["x"]); + const hook = new SyncBailHookTest(["x"]); const mockCall = jest.fn(); const mockTap = jest.fn((x) => x); @@ -83,17 +83,17 @@ describe("SyncBailHook", () => { }); it("should throw on tapAsync", () => { - const hook = new SyncBailHook(["x"]); + const hook = new SyncBailHookTest(["x"]); expect(() => hook.tapAsync()).toThrow(/tapAsync/); }); it("should throw on tapPromise", () => { - const hook = new SyncBailHook(["x"]); + const hook = new SyncBailHookTest(["x"]); expect(() => hook.tapPromise()).toThrow(/tapPromise/); }); it("should not crash with many plugins", () => { - const hook = new SyncBailHook(["x"]); + const hook = new SyncBailHookTest(["x"]); for (let i = 0; i < 1000; i++) { hook.tap("Test", () => 42); } diff --git a/lib/__tests__/SyncHook.js b/test/SyncHook.test.js similarity index 87% rename from lib/__tests__/SyncHook.js rename to test/SyncHook.test.js index af002cb..fb1eb7b 100644 --- a/lib/__tests__/SyncHook.js +++ b/test/SyncHook.test.js @@ -4,14 +4,14 @@ */ "use strict"; -const SyncHook = require("../SyncHook"); +const SyncHookTest = require("../lib/SyncHook"); describe("SyncHook", () => { it("should allow to create sync hooks", async () => { - const h0 = new SyncHook(); - const h1 = new SyncHook(["test"]); - const h2 = new SyncHook(["test", "arg2"]); - const h3 = new SyncHook(["test", "arg2", "arg3"]); + const h0 = new SyncHookTest(); + const h1 = new SyncHookTest(["test"]); + const h2 = new SyncHookTest(["test", "arg2"]); + const h3 = new SyncHookTest(["test", "arg2", "arg3"]); h0.call(); await h0.promise(); @@ -72,7 +72,7 @@ describe("SyncHook", () => { }); it("should sync execute hooks", () => { - const h1 = new SyncHook(["a"]); + const h1 = new SyncHookTest(["a"]); const mockCall1 = jest.fn(); const mockCall2 = jest.fn(() => "B"); const mockCall3 = jest.fn(() => "C"); @@ -86,7 +86,7 @@ describe("SyncHook", () => { }); it("should allow to intercept calls", () => { - const hook = new SyncHook(["arg1", "arg2"]); + const hook = new SyncHookTest(["arg1", "arg2"]); const mockCall = jest.fn(); const mock0 = jest.fn(); @@ -121,12 +121,12 @@ describe("SyncHook", () => { }); it("should throw error on tapAsync", () => { - const hook = new SyncHook(["arg1", "arg2"]); + const hook = new SyncHookTest(["arg1", "arg2"]); expect(() => hook.tapAsync()).toThrow(/tapAsync/); }); it("should throw error on tapPromise", () => { - const hook = new SyncHook(["arg1", "arg2"]); + const hook = new SyncHookTest(["arg1", "arg2"]); expect(() => hook.tapPromise()).toThrow(/tapPromise/); }); }); diff --git a/lib/__tests__/SyncHooks.js b/test/SyncHooks.test.js similarity index 80% rename from lib/__tests__/SyncHooks.js rename to test/SyncHooks.test.js index 28e5434..e30ee65 100644 --- a/lib/__tests__/SyncHooks.js +++ b/test/SyncHooks.test.js @@ -4,11 +4,11 @@ */ "use strict"; -const SyncBailHook = require("../SyncBailHook"); -const SyncHook = require("../SyncHook"); -const SyncLoopHook = require("../SyncLoopHook"); -const SyncWaterfallHook = require("../SyncWaterfallHook"); -const HookTester = require("./HookTester"); +const SyncBailHook = require("../lib/SyncBailHook"); +const SyncHook = require("../lib/SyncHook"); +const SyncLoopHook = require("../lib/SyncLoopHook"); +const SyncWaterfallHook = require("../lib/SyncWaterfallHook"); +const HookTester = require("./HookTester.test"); describe("SyncHook", () => { it("should have to correct behavior", async () => { diff --git a/lib/__tests__/SyncLoopHook.js b/test/SyncLoopHook.test.js similarity index 80% rename from lib/__tests__/SyncLoopHook.js rename to test/SyncLoopHook.test.js index 527576e..e742224 100644 --- a/lib/__tests__/SyncLoopHook.js +++ b/test/SyncLoopHook.test.js @@ -3,25 +3,25 @@ */ "use strict"; -const SyncLoopHook = require("../SyncLoopHook"); +const SyncLoopHookTest = require("../lib/SyncLoopHook"); describe("SyncLoopHook", () => { it("should throw on tapAsync", () => { - const hook = new SyncLoopHook(["a"]); + const hook = new SyncLoopHookTest(["a"]); expect(() => hook.tapAsync("A", () => {})).toThrow( /tapAsync is not supported on a SyncLoopHook/ ); }); it("should throw on tapPromise", () => { - const hook = new SyncLoopHook(["a"]); + const hook = new SyncLoopHookTest(["a"]); expect(() => hook.tapPromise("A", () => {})).toThrow( /tapPromise is not supported on a SyncLoopHook/ ); }); it("should loop through taps until all return undefined", () => { - const hook = new SyncLoopHook(["counter"]); + const hook = new SyncLoopHookTest(["counter"]); let firstCalls = 0; let secondCalls = 0; hook.tap("first", () => { @@ -36,7 +36,7 @@ describe("SyncLoopHook", () => { }); it("should be callable without arguments using default args", () => { - const hook = new SyncLoopHook(); + const hook = new SyncLoopHookTest(); const mock = jest.fn(); hook.tap("A", mock); hook.call(); diff --git a/lib/__tests__/SyncWaterfallHook.js b/test/SyncWaterfallHook.test.js similarity index 85% rename from lib/__tests__/SyncWaterfallHook.js rename to test/SyncWaterfallHook.test.js index 95d0019..1098570 100644 --- a/lib/__tests__/SyncWaterfallHook.js +++ b/test/SyncWaterfallHook.test.js @@ -4,7 +4,7 @@ */ "use strict"; -const SyncWaterfallHook = require("../SyncWaterfallHook"); +const SyncWaterfallHookTest = require("../lib/SyncWaterfallHook"); function pify(fn) { return new Promise((resolve, reject) => { @@ -17,13 +17,13 @@ function pify(fn) { describe("SyncWaterfallHook", () => { it("should throw an error when hook has no argument", () => { - expect(() => new SyncWaterfallHook()).toThrow( + expect(() => new SyncWaterfallHookTest()).toThrow( "Waterfall hooks must have at least one argument" ); }); it("should work", () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("string", () => "str"); hook.tap("false", () => false); @@ -31,21 +31,21 @@ describe("SyncWaterfallHook", () => { }); it("should work with undefined", async () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("undefined", () => undefined); return expect(hook.call()).toBe(42); }); it("should work with void", async () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("undefined", () => {}); return expect(hook.call()).toBe(42); }); it("should work with undefined and number again", async () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("undefined", () => {}); hook.tap("number-again", () => 43); @@ -53,21 +53,21 @@ describe("SyncWaterfallHook", () => { }); it("should work with null", async () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("undefined", () => null); return expect(hook.call()).toBeNull(); }); it("should work with different types", async () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); hook.tap("number", () => 42); hook.tap("string", () => "string"); return expect(hook.call()).toBe("string"); }); it("should allow to create sync hooks", async () => { - const hook = new SyncWaterfallHook(["arg1", "arg2"]); + const hook = new SyncWaterfallHookTest(["arg1", "arg2"]); const mock0 = jest.fn((arg) => `${arg},0`); const mock1 = jest.fn((arg) => `${arg},1`); @@ -100,7 +100,7 @@ describe("SyncWaterfallHook", () => { }); it("should allow to intercept calls", () => { - const hook = new SyncWaterfallHook(["arg1", "arg2"]); + const hook = new SyncWaterfallHookTest(["arg1", "arg2"]); const mockCall = jest.fn(); const mock0 = jest.fn(() => "mock0"); @@ -139,8 +139,8 @@ describe("SyncWaterfallHook", () => { }); it("should allow to create waterfall hooks", async () => { - const h1 = new SyncWaterfallHook(["a"]); - const h2 = new SyncWaterfallHook(["a", "b"]); + const h1 = new SyncWaterfallHookTest(["a"]); + const h2 = new SyncWaterfallHookTest(["a", "b"]); expect(h1.call(1)).toBe(1); @@ -164,12 +164,12 @@ describe("SyncWaterfallHook", () => { it("should throw when args have length less than 1", () => { expect(() => { // eslint-disable-next-line no-new - new SyncWaterfallHook([]); + new SyncWaterfallHookTest([]); }).toThrow(/Waterfall/); }); it("should allow to intercept calls #2", () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); const mockCall = jest.fn(); const mockTap = jest.fn((x) => x); @@ -193,12 +193,12 @@ describe("SyncWaterfallHook", () => { }); it("should throw on tapAsync", () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); expect(() => hook.tapAsync()).toThrow(/tapAsync/); }); it("should throw on tapPromise", () => { - const hook = new SyncWaterfallHook(["x"]); + const hook = new SyncWaterfallHookTest(["x"]); expect(() => hook.tapPromise()).toThrow(/tapPromise/); }); }); diff --git a/lib/__tests__/UtilBrowser.js b/test/UtilBrowser.test.js similarity index 83% rename from lib/__tests__/UtilBrowser.js rename to test/UtilBrowser.test.js index d44b707..bec5eda 100644 --- a/lib/__tests__/UtilBrowser.js +++ b/test/UtilBrowser.test.js @@ -3,13 +3,13 @@ */ "use strict"; -const utilBrowser = require("../util-browser"); +const utilBrowserTest = require("../lib/util-browser"); describe("util-browser", () => { it("should warn only once and forward arguments", () => { const warn = jest.spyOn(console, "warn").mockImplementation(() => {}); const inner = jest.fn((...args) => args.reduce((a, b) => a + b, 0)); - const wrapped = utilBrowser.deprecate(inner, "do not use"); + const wrapped = utilBrowserTest.deprecate(inner, "do not use"); expect(wrapped(1, 2, 3)).toBe(6); expect(wrapped(4, 5)).toBe(9); @@ -25,7 +25,7 @@ describe("util-browser", () => { const warn = jest.spyOn(console, "warn").mockImplementation(() => {}); const obj = { value: 42, - run: utilBrowser.deprecate(function run() { + run: utilBrowserTest.deprecate(function run() { return this.value; }, "method deprecated") }; diff --git a/lib/__tests__/__snapshots__/AsyncParallelHooks.js.snap b/test/__snapshots__/AsyncParallelHooks.test.js.snap similarity index 100% rename from lib/__tests__/__snapshots__/AsyncParallelHooks.js.snap rename to test/__snapshots__/AsyncParallelHooks.test.js.snap diff --git a/lib/__tests__/__snapshots__/AsyncSeriesHooks.js.snap b/test/__snapshots__/AsyncSeriesHooks.test.js.snap similarity index 100% rename from lib/__tests__/__snapshots__/AsyncSeriesHooks.js.snap rename to test/__snapshots__/AsyncSeriesHooks.test.js.snap diff --git a/lib/__tests__/__snapshots__/HookCodeFactory.js.snap b/test/__snapshots__/HookCodeFactory.test.js.snap similarity index 100% rename from lib/__tests__/__snapshots__/HookCodeFactory.js.snap rename to test/__snapshots__/HookCodeFactory.test.js.snap diff --git a/lib/__tests__/__snapshots__/SyncHooks.js.snap b/test/__snapshots__/SyncHooks.test.js.snap similarity index 100% rename from lib/__tests__/__snapshots__/SyncHooks.js.snap rename to test/__snapshots__/SyncHooks.test.js.snap