From 91f6571625e5f8da39ab5a07092b0cccf5813f95 Mon Sep 17 00:00:00 2001 From: Abhay Date: Tue, 23 Jul 2024 06:20:19 +0000 Subject: [PATCH 1/4] Added Test Cases For FreeQueue Class --- .eleventy.js | 1 + src/lib/free-queue/coi-serviceworker.js | 115 +++++++++++++++ src/lib/free-queue/free-queue.js | 8 + src/lib/free-queue/test/free-queue.test.html | 38 +++++ src/lib/free-queue/test/free-queue.test.js | 147 +++++++++++++++++++ 5 files changed, 309 insertions(+) create mode 100644 src/lib/free-queue/coi-serviceworker.js create mode 100644 src/lib/free-queue/test/free-queue.test.html create mode 100644 src/lib/free-queue/test/free-queue.test.js diff --git a/.eleventy.js b/.eleventy.js index f62a0be5c..f8b5ab24a 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -81,6 +81,7 @@ module.exports = function(eleventyConfig) { 'src/README.md', 'src/sitemap.xml', 'src/lib/**/*.js', + 'src/lib/**/*.html', ].map(path => eleventyConfig.addPassthroughCopy(path)); // eleventyConfig.addPassthroughCopy('src/favicon'); diff --git a/src/lib/free-queue/coi-serviceworker.js b/src/lib/free-queue/coi-serviceworker.js new file mode 100644 index 000000000..646aadf10 --- /dev/null +++ b/src/lib/free-queue/coi-serviceworker.js @@ -0,0 +1,115 @@ +/*! coi-serviceworker v0.1.6 - Guido Zuidhof, licensed under MIT */ +let coepCredentialless = false; +if (typeof window === 'undefined') { + self.addEventListener("install", () => self.skipWaiting()); + self.addEventListener("activate", (event) => event.waitUntil(self.clients.claim())); + + self.addEventListener("message", (ev) => { + if (!ev.data) { + return; + } else if (ev.data.type === "deregister") { + self.registration + .unregister() + .then(() => { + return self.clients.matchAll(); + }) + .then(clients => { + clients.forEach((client) => client.navigate(client.url)); + }); + } else if (ev.data.type === "coepCredentialless") { + coepCredentialless = ev.data.value; + } + }); + + self.addEventListener("fetch", function (event) { + const r = event.request; + if (r.cache === "only-if-cached" && r.mode !== "same-origin") { + return; + } + + const request = (coepCredentialless && r.mode === "no-cors") + ? new Request(r, { + credentials: "omit", + }) + : r; + event.respondWith( + fetch(request) + .then((response) => { + if (response.status === 0) { + return response; + } + + const newHeaders = new Headers(response.headers); + newHeaders.set("Cross-Origin-Embedder-Policy", + coepCredentialless ? "credentialless" : "require-corp" + ); + newHeaders.set("Cross-Origin-Opener-Policy", "same-origin"); + + return new Response(response.body, { + status: response.status, + statusText: response.statusText, + headers: newHeaders, + }); + }) + .catch((e) => console.error(e)) + ); + }); + +} else { + (() => { + // You can customize the behavior of this script through a global `coi` variable. + const coi = { + shouldRegister: () => true, + shouldDeregister: () => false, + coepCredentialless: () => false, + doReload: () => window.location.reload(), + quiet: false, + ...window.coi + }; + + const n = navigator; + + if (n.serviceWorker && n.serviceWorker.controller) { + n.serviceWorker.controller.postMessage({ + type: "coepCredentialless", + value: coi.coepCredentialless(), + }); + + if (coi.shouldDeregister()) { + n.serviceWorker.controller.postMessage({ type: "deregister" }); + } + } + + // If we're already coi: do nothing. Perhaps it's due to this script doing its job, or COOP/COEP are + // already set from the origin server. Also if the browser has no notion of crossOriginIsolated, just give up here. + if (window.crossOriginIsolated !== false || !coi.shouldRegister()) return; + + if (!window.isSecureContext) { + !coi.quiet && console.log("COOP/COEP Service Worker not registered, a secure context is required."); + return; + } + + // In some environments (e.g. Chrome incognito mode) this won't be available + if (n.serviceWorker) { + n.serviceWorker.register(window.document.currentScript.src).then( + (registration) => { + !coi.quiet && console.log("COOP/COEP Service Worker registered", registration.scope); + + registration.addEventListener("updatefound", () => { + !coi.quiet && console.log("Reloading page to make use of updated COOP/COEP Service Worker."); + coi.doReload(); + }); + + // If the registration is active, but it's not controlling the page + if (registration.active && !n.serviceWorker.controller) { + !coi.quiet && console.log("Reloading page to make use of COOP/COEP Service Worker."); + coi.doReload(); + } + }, + (err) => { + !coi.quiet && console.error("COOP/COEP Service Worker failed to register:", err); + } + ); + } + })(); +} \ No newline at end of file diff --git a/src/lib/free-queue/free-queue.js b/src/lib/free-queue/free-queue.js index 122d5b2bc..e9e7e19d0 100644 --- a/src/lib/free-queue/free-queue.js +++ b/src/lib/free-queue/free-queue.js @@ -190,6 +190,10 @@ class FreeQueue { // The channel count of arraySequence and the length of each channel must // match with this buffer obejct. + if (arraySequence.length !== this._channelCount) { + throw new Error('Channel count mismatch'); + } + // Transfer data from the |arraySequence| storage to the internal buffer. const sourceLength = arraySequence[0].length; for (let i = 0; i < sourceLength; ++i) { @@ -215,6 +219,10 @@ class FreeQueue { // The channel count of arraySequence and the length of each channel must // match with this buffer obejct. + if (arraySequence.length !== this._channelCount) { + throw new Error('Channel count mismatch'); + } + // If the FIFO is completely empty, do nothing. if (this._framesAvailable === 0) { return; diff --git a/src/lib/free-queue/test/free-queue.test.html b/src/lib/free-queue/test/free-queue.test.html new file mode 100644 index 000000000..0835af873 --- /dev/null +++ b/src/lib/free-queue/test/free-queue.test.html @@ -0,0 +1,38 @@ + + + + + + FreeQueue Tests + + + + +

FreeQueue Test

+
+ + + + + + + + + new ArrayBuffer(size), // Simulate memory allocation + _free: () => {}, // Simulate memory deallocation + HEAPF32: new Float32Array(1024), // Simulate HEAPF32 +}; + +describe('FreeQueue Class', () => { + const bufferLength = 512; + const channelCount = 2; + const maxChannelCount = 4; + let freeQueue; + + beforeEach(() => { + freeQueue = new FreeQueue(mockWasmModule, bufferLength, channelCount, maxChannelCount); + }); + + afterEach(() => { + freeQueue.free(); + }); + + describe('Initialization', () => { + it('should initialize with correct properties', () => { + expect(freeQueue.length).to.equal(bufferLength); + expect(freeQueue.numberOfChannels).to.equal(channelCount); + expect(freeQueue.maxChannelCount).to.equal(maxChannelCount); + }); + + it('should allocate the correct amount of memory', () => { + const dataByteSize = channelCount * bufferLength * Float32Array.BYTES_PER_ELEMENT; + expect(freeQueue.getPointer()).to.be.instanceof(ArrayBuffer); + expect(freeQueue.getPointer().byteLength).to.equal(dataByteSize); + }); + }); + + describe('Channel Adaptation', () => { + it('should adapt to a new channel count within limits', () => { + freeQueue.adaptChannel(3); + expect(freeQueue.numberOfChannels).to.equal(3); + }); + }); + + describe('Pushing and Pulling Data', () => { + it('should correctly push and pull data', () => { + const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; + freeQueue.push(testData); + + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + freeQueue.pull(outputData); + + expect(outputData[0]).to.deep.equal(testData[0]); + expect(outputData[1]).to.deep.equal(testData[1]); + }); + + it('should handle buffer overflow correctly', () => { + const testData = [new Float32Array(bufferLength * 2).fill(1), new Float32Array(bufferLength * 2).fill(2)]; + freeQueue.push(testData); + + expect(freeQueue.framesAvailable).to.equal(bufferLength); + }); + + it('should not pull data when buffer is empty', () => { + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + freeQueue.pull(outputData); + + expect(outputData[0]).to.deep.equal(new Float32Array(bufferLength)); + expect(outputData[1]).to.deep.equal(new Float32Array(bufferLength)); + }); + + it('should manage partial data pulls', () => { + const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; + freeQueue.push(testData); + + const partialOutput = [new Float32Array(bufferLength / 2), new Float32Array(bufferLength / 2)]; + freeQueue.pull(partialOutput); + + expect(partialOutput[0]).to.deep.equal(new Float32Array(bufferLength / 2).fill(1)); + expect(partialOutput[1]).to.deep.equal(new Float32Array(bufferLength / 2).fill(2)); + expect(freeQueue.framesAvailable).to.equal(bufferLength / 2); + }); + + it('should handle multiple push and pull cycles', () => { + const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; + + for (let i = 0; i < 5; i++) { + freeQueue.push(testData); + + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + freeQueue.pull(outputData); + + expect(outputData[0]).to.deep.equal(testData[0]); + expect(outputData[1]).to.deep.equal(testData[1]); + expect(freeQueue.framesAvailable).to.equal(0); + } + }); + }); + + describe('Error Handling', () => { + it('should return null for invalid channel index in getChannelData', () => { + const invalidIndex = channelCount + 1; + expect(freeQueue.getChannelData(invalidIndex)).to.be.null; + }); + + it('should throw an error if pushing with mismatched channel count', () => { + const invalidTestData = [new Float32Array(bufferLength).fill(1)]; + expect(() => freeQueue.push(invalidTestData)).to.throw(Error, 'Channel count mismatch'); + }); + + it('should throw an error if pulling with mismatched channel count', () => { + const invalidOutputData = [new Float32Array(bufferLength)]; + expect(() => freeQueue.pull(invalidOutputData)).to.throw(Error, 'Channel count mismatch'); + }); + }); + + describe('Performance', () => { + it('should efficiently handle large data transfers', function() { + this.timeout(5000); + const largeBuffer = 1024 * 1024; // 1 MB buffer + const testData = [new Float32Array(largeBuffer).fill(1), new Float32Array(largeBuffer).fill(2)]; + + const start = performance.now(); + freeQueue.push(testData); + freeQueue.pull(testData); + const end = performance.now(); + + expect(end - start).to.be.below(1000); // Ensure operations complete within 1 second + }); + + it('should perform consistently over many operations', function() { + this.timeout(10000); + const iterations = 10000; + const testData = [new Float32Array(RENDER_QUANTUM_FRAMES).fill(1), new Float32Array(RENDER_QUANTUM_FRAMES).fill(2)]; + + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + freeQueue.push(testData); + freeQueue.pull(testData); + } + const end = performance.now(); + + expect(end - start).to.be.below(5000); // Ensure it completes within 5 seconds + }); + }); +}); From c0106d08052b0e6d4f24100b8457a4f241f73778 Mon Sep 17 00:00:00 2001 From: Abhay Date: Thu, 25 Jul 2024 05:30:46 +0000 Subject: [PATCH 2/4] optimizations --- src/lib/free-queue/free-queue.js | 4 +- src/lib/free-queue/test/free-queue.test.html | 73 +++++++++++--------- src/lib/free-queue/test/free-queue.test.js | 39 +++++++---- 3 files changed, 71 insertions(+), 45 deletions(-) diff --git a/src/lib/free-queue/free-queue.js b/src/lib/free-queue/free-queue.js index e9e7e19d0..0ad7ade9b 100644 --- a/src/lib/free-queue/free-queue.js +++ b/src/lib/free-queue/free-queue.js @@ -191,7 +191,7 @@ class FreeQueue { // match with this buffer obejct. if (arraySequence.length !== this._channelCount) { - throw new Error('Channel count mismatch'); + throw new Error(`Channel count mismatch: expected ${this._channelCount}, but got ${arraySequence.length}.`); } // Transfer data from the |arraySequence| storage to the internal buffer. @@ -220,7 +220,7 @@ class FreeQueue { // match with this buffer obejct. if (arraySequence.length !== this._channelCount) { - throw new Error('Channel count mismatch'); + throw new Error(`Channel count mismatch: expected ${this._channelCount}, but got ${arraySequence.length}.`); } // If the FIFO is completely empty, do nothing. diff --git a/src/lib/free-queue/test/free-queue.test.html b/src/lib/free-queue/test/free-queue.test.html index 0835af873..ae35422d6 100644 --- a/src/lib/free-queue/test/free-queue.test.html +++ b/src/lib/free-queue/test/free-queue.test.html @@ -1,38 +1,49 @@ + - - - FreeQueue Tests - - + -

FreeQueue Test

-
- - - - - - - +

FreeQueue Test

+
+ + + + + + + + - \ No newline at end of file diff --git a/src/lib/free-queue/test/free-queue.test.js b/src/lib/free-queue/test/free-queue.test.js index 14c94e123..721edd3b9 100644 --- a/src/lib/free-queue/test/free-queue.test.js +++ b/src/lib/free-queue/test/free-queue.test.js @@ -3,16 +3,19 @@ import { FreeQueue, MAX_CHANNEL_COUNT, RENDER_QUANTUM_FRAMES } from '../free-que // Mock WASM module const mockWasmModule = { - _malloc: (size) => new ArrayBuffer(size), // Simulate memory allocation - _free: () => {}, // Simulate memory deallocation - HEAPF32: new Float32Array(1024), // Simulate HEAPF32 + // Simulate memory allocation + _malloc: (size) => new ArrayBuffer(size), + // Simulate memory deallocation + _free: () => {}, + // Simulate HEAPF32 + HEAPF32: new Float32Array(1024), }; describe('FreeQueue Class', () => { const bufferLength = 512; const channelCount = 2; const maxChannelCount = 4; - let freeQueue; + let freeQueue = null; beforeEach(() => { freeQueue = new FreeQueue(mockWasmModule, bufferLength, channelCount, maxChannelCount); @@ -106,19 +109,30 @@ describe('FreeQueue Class', () => { it('should throw an error if pushing with mismatched channel count', () => { const invalidTestData = [new Float32Array(bufferLength).fill(1)]; - expect(() => freeQueue.push(invalidTestData)).to.throw(Error, 'Channel count mismatch'); + + const expectedChannelCount = freeQueue._channelCount; + const actualChannelCount = invalidTestData.length; + + expect(() => freeQueue.push(invalidTestData)) + .to.throw(Error, `Channel count mismatch: expected ${expectedChannelCount}, but got ${actualChannelCount}.`); }); it('should throw an error if pulling with mismatched channel count', () => { - const invalidOutputData = [new Float32Array(bufferLength)]; - expect(() => freeQueue.pull(invalidOutputData)).to.throw(Error, 'Channel count mismatch'); + const invalidOutputData = [new Float32Array(bufferLength)]; + + const expectedChannelCount = freeQueue._channelCount; + const actualChannelCount = invalidOutputData.length; + + expect(() => freeQueue.pull(invalidOutputData)) + .to.throw(Error, `Channel count mismatch: expected ${expectedChannelCount}, but got ${actualChannelCount}.`); }); }); describe('Performance', () => { it('should efficiently handle large data transfers', function() { - this.timeout(5000); - const largeBuffer = 1024 * 1024; // 1 MB buffer + // this.timeout(5000); + // 1 MB buffer + const largeBuffer = 1024 * 1024; const testData = [new Float32Array(largeBuffer).fill(1), new Float32Array(largeBuffer).fill(2)]; const start = performance.now(); @@ -126,7 +140,8 @@ describe('FreeQueue Class', () => { freeQueue.pull(testData); const end = performance.now(); - expect(end - start).to.be.below(1000); // Ensure operations complete within 1 second + // Ensure operations complete within 1 second + expect(end - start).to.be.below(1000); }); it('should perform consistently over many operations', function() { @@ -140,8 +155,8 @@ describe('FreeQueue Class', () => { freeQueue.pull(testData); } const end = performance.now(); - - expect(end - start).to.be.below(5000); // Ensure it completes within 5 seconds + // Ensure it completes within 1 seconds + expect(end - start).to.be.below(1000); }); }); }); From f57256536a08611c7b638494752dd7fe4cf875a4 Mon Sep 17 00:00:00 2001 From: Abhay Date: Fri, 9 Aug 2024 06:03:09 +0000 Subject: [PATCH 3/4] optimized push and pull test cases --- src/lib/free-queue/test/free-queue.test.js | 120 ++++++++++++--------- 1 file changed, 68 insertions(+), 52 deletions(-) diff --git a/src/lib/free-queue/test/free-queue.test.js b/src/lib/free-queue/test/free-queue.test.js index 721edd3b9..793a1dbab 100644 --- a/src/lib/free-queue/test/free-queue.test.js +++ b/src/lib/free-queue/test/free-queue.test.js @@ -4,15 +4,15 @@ import { FreeQueue, MAX_CHANNEL_COUNT, RENDER_QUANTUM_FRAMES } from '../free-que // Mock WASM module const mockWasmModule = { // Simulate memory allocation - _malloc: (size) => new ArrayBuffer(size), + _malloc: (size) => new ArrayBuffer(size), // Simulate memory deallocation - _free: () => {}, + _free: () => { }, // Simulate HEAPF32 - HEAPF32: new Float32Array(1024), + HEAPF32: new Float32Array(1024), }; describe('FreeQueue Class', () => { - const bufferLength = 512; + const bufferLength = 1024; const channelCount = 2; const maxChannelCount = 4; let freeQueue = null; @@ -46,54 +46,82 @@ describe('FreeQueue Class', () => { }); }); - describe('Pushing and Pulling Data', () => { - it('should correctly push and pull data', () => { + describe('Push Data', () => { + it('should correctly push data', () => { const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; freeQueue.push(testData); - + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; freeQueue.pull(outputData); - + expect(outputData[0]).to.deep.equal(testData[0]); expect(outputData[1]).to.deep.equal(testData[1]); }); - + it('should handle buffer overflow correctly', () => { const testData = [new Float32Array(bufferLength * 2).fill(1), new Float32Array(bufferLength * 2).fill(2)]; freeQueue.push(testData); - + expect(freeQueue.framesAvailable).to.equal(bufferLength); }); + + it('should handle multiple push cycles', () => { + const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; + + for (let i = 0; i < 5; i++) { + freeQueue.push(testData); + + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + freeQueue.pull(outputData); + + expect(outputData[0]).to.deep.equal(testData[0]); + expect(outputData[1]).to.deep.equal(testData[1]); + expect(freeQueue.framesAvailable).to.equal(0); + } + }); + }); + describe('Pull Data', () => { + it('should correctly pull data', () => { + const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; + freeQueue.push(testData); + + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + freeQueue.pull(outputData); + + expect(outputData[0]).to.deep.equal(testData[0]); + expect(outputData[1]).to.deep.equal(testData[1]); + }); + it('should not pull data when buffer is empty', () => { const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; freeQueue.pull(outputData); - + expect(outputData[0]).to.deep.equal(new Float32Array(bufferLength)); expect(outputData[1]).to.deep.equal(new Float32Array(bufferLength)); }); - + it('should manage partial data pulls', () => { const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; freeQueue.push(testData); - + const partialOutput = [new Float32Array(bufferLength / 2), new Float32Array(bufferLength / 2)]; freeQueue.pull(partialOutput); - + expect(partialOutput[0]).to.deep.equal(new Float32Array(bufferLength / 2).fill(1)); expect(partialOutput[1]).to.deep.equal(new Float32Array(bufferLength / 2).fill(2)); expect(freeQueue.framesAvailable).to.equal(bufferLength / 2); }); - - it('should handle multiple push and pull cycles', () => { + + it('should handle multiple pull cycles', () => { const testData = [new Float32Array(bufferLength).fill(1), new Float32Array(bufferLength).fill(2)]; - + for (let i = 0; i < 5; i++) { freeQueue.push(testData); - + const outputData = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; freeQueue.pull(outputData); - + expect(outputData[0]).to.deep.equal(testData[0]); expect(outputData[1]).to.deep.equal(testData[1]); expect(freeQueue.framesAvailable).to.equal(0); @@ -109,54 +137,42 @@ describe('FreeQueue Class', () => { it('should throw an error if pushing with mismatched channel count', () => { const invalidTestData = [new Float32Array(bufferLength).fill(1)]; - - const expectedChannelCount = freeQueue._channelCount; + + const expectedChannelCount = freeQueue._channelCount; const actualChannelCount = invalidTestData.length; - + expect(() => freeQueue.push(invalidTestData)) .to.throw(Error, `Channel count mismatch: expected ${expectedChannelCount}, but got ${actualChannelCount}.`); }); it('should throw an error if pulling with mismatched channel count', () => { - const invalidOutputData = [new Float32Array(bufferLength)]; - - const expectedChannelCount = freeQueue._channelCount; + const invalidOutputData = [new Float32Array(bufferLength)]; + + const expectedChannelCount = freeQueue._channelCount; const actualChannelCount = invalidOutputData.length; - + expect(() => freeQueue.pull(invalidOutputData)) .to.throw(Error, `Channel count mismatch: expected ${expectedChannelCount}, but got ${actualChannelCount}.`); }); }); - describe('Performance', () => { - it('should efficiently handle large data transfers', function() { - // this.timeout(5000); - // 1 MB buffer - const largeBuffer = 1024 * 1024; - const testData = [new Float32Array(largeBuffer).fill(1), new Float32Array(largeBuffer).fill(2)]; - - const start = performance.now(); - freeQueue.push(testData); - freeQueue.pull(testData); - const end = performance.now(); - - // Ensure operations complete within 1 second - expect(end - start).to.be.below(1000); + describe('Performance Tests', function () { + it('should handle large data efficiently', function () { + const input = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + const output = [new Float32Array(bufferLength), new Float32Array(bufferLength)]; + for (let i = 0; i < 10000; i++) { + freeQueue.push(input, bufferLength); + freeQueue.pull(output, bufferLength); + } }); - it('should perform consistently over many operations', function() { - this.timeout(10000); - const iterations = 10000; - const testData = [new Float32Array(RENDER_QUANTUM_FRAMES).fill(1), new Float32Array(RENDER_QUANTUM_FRAMES).fill(2)]; - - const start = performance.now(); - for (let i = 0; i < iterations; i++) { - freeQueue.push(testData); - freeQueue.pull(testData); + it('should handle small data efficiently', function () { + const input = [new Float32Array(1), new Float32Array(1)]; + const output = [new Float32Array(1), new Float32Array(1)]; + for (let i = 0; i < 1000000; i++) { + freeQueue.push(input, 1); + freeQueue.pull(output, 1); } - const end = performance.now(); - // Ensure it completes within 1 seconds - expect(end - start).to.be.below(1000); }); }); }); From 5082408744cca21e4abb0db6b334d57253231301 Mon Sep 17 00:00:00 2001 From: Abhay Date: Fri, 9 Aug 2024 06:06:39 +0000 Subject: [PATCH 4/4] added a test case in channel adaption --- src/lib/free-queue/test/free-queue.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/lib/free-queue/test/free-queue.test.js b/src/lib/free-queue/test/free-queue.test.js index 793a1dbab..25cbe9411 100644 --- a/src/lib/free-queue/test/free-queue.test.js +++ b/src/lib/free-queue/test/free-queue.test.js @@ -44,6 +44,19 @@ describe('FreeQueue Class', () => { freeQueue.adaptChannel(3); expect(freeQueue.numberOfChannels).to.equal(3); }); + it('should not adapt to a channel count exceeding maxChannelCount', () => { + const maxChannelCount = 8; + const initialChannelCount = freeQueue.numberOfChannels; + + try { + freeQueue.adaptChannel(maxChannelCount + 1); + } catch (error) { + expect(error).to.be.instanceOf(Error); + expect(error.message).to.include('exceeds the maximum channel count'); + } + + expect(freeQueue.numberOfChannels).to.equal(initialChannelCount); + }); }); describe('Push Data', () => {