diff --git a/test/core/Clock.js b/test/core/Clock.js index d18f6fe8..88dd3581 100644 --- a/test/core/Clock.js +++ b/test/core/Clock.js @@ -206,8 +206,13 @@ define(["Test", "Tone/core/Clock", "helper/Offline"], it ("resets ticks on stop", function(){ return Offline(function(){ var clock = new Clock(function(){}, 20).start(0).stop(0.1); - return function(){ - expect(clock.ticks).to.equal(0); + return function(time){ + Test.whenBetween(time, 0, 0.09, function(){ + expect(clock.ticks).to.be.greaterThan(0); + }); + Test.whenBetween(time, 0.1, Infinity, function(){ + expect(clock.ticks).to.equal(0); + }); }; }, 0.2); }); @@ -215,8 +220,15 @@ define(["Test", "Tone/core/Clock", "helper/Offline"], it ("does not reset ticks on pause but stops incrementing", function(){ return Offline(function(){ var clock = new Clock(function(){}, 20).start(0).pause(0.1); - return function(){ - expect(clock.ticks).to.equal(2); + var pausedTicks = 0; + return function(time){ + Test.whenBetween(time, 0, 0.1, function(){ + expect(clock.ticks).to.be.greaterThan(0); + pausedTicks = clock.ticks; + }); + Test.whenBetween(time, 0.1, Infinity, function(){ + expect(clock.ticks).to.equal(pausedTicks); + }); }; }, 0.2); }); @@ -224,78 +236,92 @@ define(["Test", "Tone/core/Clock", "helper/Offline"], it ("starts incrementing where it left off after pause", function(){ return Offline(function(){ + var clock = new Clock(function(){}, 20).start(0).pause(0.1).start(0.2); + var pausedTicks = 0; var tested = false; - var clock = new Clock(function(time){ - if (time < 0.1){ + return function(time){ + Test.whenBetween(time, 0, 0.1, function(){ + expect(clock.ticks).to.be.greaterThan(0); pausedTicks = clock.ticks; - } else if (time >= 0.2 && !tested){ - tested = true; - expect(clock.ticks).to.equal(pausedTicks + 1); - } - }, 20).start(0).pause(0.1).start(0.2); + }); + Test.whenBetween(time, 0.1, 0.19, function(){ + expect(clock.ticks).to.equal(pausedTicks); + }); + Test.whenBetween(time, 0.2, Infinity, function(){ + if (!tested){ + tested = true; + expect(clock.ticks).to.equal(pausedTicks + 1); + } + }); + }; }, 0.3); }); - it ("can start with a tick offset", function(done){ - var clock = new Clock(function(){ - expect(clock.ticks).to.equal(4); - clock.dispose(); - done(); - }, 10); - expect(clock.ticks).to.equal(0); - clock.start(undefined, 4); + it ("can start with a tick offset", function(){ + return Offline(function(){ + var tested = false; + var clock = new Clock(function(){ + if (!tested){ + tested = true; + expect(clock.ticks).to.equal(4); + } + }, 10); + expect(clock.ticks).to.equal(0); + clock.start(0, 4); + }); }); }); context("Events", function(){ - it ("triggers the start event on start", function(done){ - var clock = new Clock(function(){}, 20); - var startTime = clock.now() + 0.3; - clock.on("start", function(time, offset){ - expect(time).to.be.closeTo(startTime, 0.05); - expect(offset).to.equal(0); - clock.dispose(); - done(); - }); - clock.start(startTime); + it ("triggers the start event on start", function(){ + return Offline(function(){ + var clock = new Clock(function(){}, 20); + var startTime = 0.3; + clock.on("start", function(time, offset){ + expect(time).to.be.closeTo(startTime, 0.05); + expect(offset).to.equal(0); + }); + clock.start(startTime); + }, 0.4); }); it ("triggers the start event with an offset", function(done){ - var clock = new Clock(function(){}, 20); - var startTime = clock.now() + 0.3; - clock.on("start", function(time, offset){ - expect(time).to.be.closeTo(startTime, 0.05); - expect(offset).to.equal(2); - clock.dispose(); - done(); - }); - clock.start(startTime, 2); + return Offline(function(){ + var clock = new Clock(function(){}, 20); + var startTime = 0.3; + clock.on("start", function(time, offset){ + expect(time).to.be.closeTo(startTime, 0.05); + expect(offset).to.equal(2); + clock.dispose(); + done(); + }); + clock.start(startTime, 2); + }, 0.4); }); - it ("triggers stop event", function(done){ - var clock = new Clock(function(){}, 20); - var stopTime = clock.now() + 0.3; - clock.on("stop", function(time){ - expect(time).to.be.closeTo(stopTime, 0.05); - clock.dispose(); - done(); + it ("triggers stop event", function(){ + return Offline(function(){ + var clock = new Clock(function(){}, 20); + var stopTime = 0.3; + clock.on("stop", function(time){ + expect(time).to.be.closeTo(stopTime, 0.05); + }); + clock.start().stop(stopTime); }); - clock.start().stop(stopTime); }); - it ("triggers pause stop event", function(done){ - var clock = new Clock(function(){}, 20); - var now = clock.now(); - clock.on("pause", function(time){ - expect(time).to.be.closeTo(now + 0.1, 0.05); - }).on("stop", function(time){ - expect(time).to.be.closeTo(now + 0.2, 0.05); - clock.dispose(); - done(); + it ("triggers pause stop event", function(){ + return Offline(function(){ + var clock = new Clock(function(){}, 20); + clock.on("pause", function(time){ + expect(time).to.be.closeTo(0.1, 0.05); + }).on("stop", function(time){ + expect(time).to.be.closeTo(0.2, 0.05); + }); + clock.start().pause(0.1).stop(0.2); }); - clock.start().pause("+0.1").stop("+0.2"); }); }); diff --git a/test/core/Transport.js b/test/core/Transport.js index f18c4b6c..a2d8f5ad 100644 --- a/test/core/Transport.js +++ b/test/core/Transport.js @@ -1,16 +1,16 @@ -define(["Test", "Tone/core/Transport", "Tone/core/Tone", "helper/Offline2", "Tone/type/TransportTime"], -function (Test, Transport, Tone, Offline, TransportTime) { +define(["Test", "Tone/core/Transport", "Tone/core/Tone", "helper/Offline", + "Tone/type/TransportTime", "Tone/signal/Signal", "helper/BufferTest"], +function (Test, Transport, Tone, Offline, TransportTime, Signal, BufferTest) { describe("Transport", function(){ function resetTransport(done){ Tone.Transport.cancel(0); - Tone.Transport.off("start stop pause loop"); + Tone.Transport.off("start stop pause loop loopStart loopEnd"); Tone.Transport.stop(); - Tone.Transport.loop = false; - Tone.Transport.bpm.value = 120; - Tone.Transport.timeSignature = [4, 4]; - setTimeout(done, 200); + // set the defaults + Tone.Transport.set(Tone.Transport.constructor.defaults); + setTimeout(done, 300); } it("exists", function(){ @@ -19,184 +19,199 @@ function (Test, Transport, Tone, Offline, TransportTime) { context("BPM and timeSignature", function(){ - afterEach(resetTransport); - it("can get and set bpm", function(){ - Tone.Transport.bpm.value = 125; - expect(Tone.Transport.bpm.value).to.be.closeTo(125, 0.001); - //reset the bpm - Tone.Transport.bpm.value = 120; - expect(Tone.Transport.bpm._param.value).to.equal(2 * Tone.Transport.PPQ); + return Offline(function(Transport){ + Transport.bpm.value = 125; + expect(Transport.bpm.value).to.be.closeTo(125, 0.001); + Transport.bpm.value = 120; + expect(Transport.bpm._param.value).to.equal(2 * Transport.PPQ); + }); }); it("can get and set timeSignature as both an array or number", function(){ - Tone.Transport.timeSignature = [6, 8]; - expect(Tone.Transport.timeSignature).to.equal(3); - Tone.Transport.timeSignature = 5; - expect(Tone.Transport.timeSignature).to.equal(5); - Tone.Transport.timeSignature = [4, 4]; + return Offline(function(Transport){ + Transport.timeSignature = [6, 8]; + expect(Transport.timeSignature).to.equal(3); + Transport.timeSignature = 5; + expect(Transport.timeSignature).to.equal(5); + }); }); it("can get and set timeSignature as both an array or number", function(){ - Tone.Transport.timeSignature = [6, 8]; - expect(Tone.Transport.timeSignature).to.equal(3); - Tone.Transport.timeSignature = 5; - expect(Tone.Transport.timeSignature).to.equal(5); - Tone.Transport.timeSignature = [4, 4]; + return Offline(function(Transport){ + Transport.timeSignature = [6, 8]; + expect(Transport.timeSignature).to.equal(3); + Transport.timeSignature = 5; + expect(Transport.timeSignature).to.equal(5); + }); }); }); context("looping", function(){ - afterEach(resetTransport); - it("can get and set loop points", function(){ - Tone.Transport.loopStart = 0.2; - Tone.Transport.loopEnd = 0.4; - expect(Tone.Transport.loopStart).to.be.closeTo(0.2, 0.01); - expect(Tone.Transport.loopEnd).to.be.closeTo(0.4, 0.01); - Tone.Transport.setLoopPoints(0, "1m"); - expect(Tone.Transport.loopStart).to.be.closeTo(0, 0.01); - expect(Tone.Transport.loopEnd).to.be.closeTo(Tone.Transport.toSeconds("1m"), 0.01); + return Offline(function(Transport){ + Transport.loopStart = 0.2; + Transport.loopEnd = 0.4; + expect(Transport.loopStart).to.be.closeTo(0.2, 0.01); + expect(Transport.loopEnd).to.be.closeTo(0.4, 0.01); + Transport.setLoopPoints(0, "1m"); + expect(Transport.loopStart).to.be.closeTo(0, 0.01); + expect(Transport.loopEnd).to.be.closeTo(Transport.toSeconds("1m"), 0.01); + }); }); - it ("can loop events scheduled on the transport", function(done){ - Offline(function(dest, testFn, after){ - var invocations = 0; - Tone.Transport.schedule(function(){ + it ("can loop events scheduled on the transport", function(){ + var invocations = 0; + return Offline(function(Transport){ + Transport.schedule(function(){ invocations++; }, 0); - Tone.Transport.setLoopPoints(0, "4n").start(0); - Tone.Transport.loop = true; - after(function(){ - expect(invocations).to.be.greaterThan(1); - Tone.Transport.loop = false; - Tone.Transport.stop(); - Tone.Transport.cancel(0); - done(); - }); - }, 1); + Transport.setLoopPoints(0, 0.1).start(0); + Transport.loop = true; + }, 0.4).then(function(){ + expect(invocations).to.equal(5); + }); }); }); context("nextSubdivision", function(){ - afterEach(resetTransport); - it("returns 0 if the transports not started", function(){ - expect(Tone.Transport.nextSubdivision()).to.equal(0); + return Offline(function(Transport){ + expect(Transport.nextSubdivision()).to.equal(0); + }); }); - it("can get the next subdivision of the transport", function(done){ - Offline(function(dest, testFn, after){ - Tone.Transport.start(0); - after(function(){ - expect(Tone.Transport.nextSubdivision(0.5)).to.be.closeTo(1, 0.01); - expect(Tone.Transport.nextSubdivision(2)).to.be.closeTo(2, 0.01); - expect(Tone.Transport.nextSubdivision("8n")).to.be.closeTo(0.75, 0.01); - done(); - }); - }, 0.7); + it("can get the next subdivision of the transport", function(){ + return Offline(function(Transport){ + Transport.start(0); + return function(time){ + Test.whenBetween(time, 0.05, 0.07, function(){ + expect(Transport.nextSubdivision(0.5)).to.be.closeTo(0.5, 0.01); + expect(Transport.nextSubdivision(0.04)).to.be.closeTo(0.08, 0.01); + expect(Transport.nextSubdivision(2)).to.be.closeTo(2, 0.01); + }); + Test.whenBetween(time, 0.09, 0.1, function(){ + expect(Transport.nextSubdivision(0.04)).to.be.closeTo(0.12, 0.01); + expect(Transport.nextSubdivision("8n")).to.be.closeTo(0.25, 0.01); + }); + }; + }, 0.1); }); }); context("PPQ", function(){ - afterEach(resetTransport); - it("can get and set pulses per quarter", function(){ - var origPPQ = Tone.Transport.PPQ; - Tone.Transport.PPQ = 96; - expect(Tone.Transport.PPQ).to.equal(96); - Tone.Transport.PPQ = origPPQ; + return Offline(function(Transport){ + Transport.PPQ = 96; + expect(Transport.PPQ).to.equal(96); + }); }); - it("schedules a quarter note at the same time with a different PPQ", function(done){ - var origPPQ = Tone.Transport.PPQ; - Tone.Transport.PPQ = 1; - var start = Tone.now(); - var id = Tone.Transport.schedule(function(time){ - expect(time - start).to.be.closeTo(Tone.Transport.toSeconds("4n"), 0.1); - Tone.Transport.cancel(id); - Tone.Transport.PPQ = origPPQ; - done(); - }, "4n"); - Tone.Transport.start(); + it("schedules a quarter note at the same time with a different PPQ", function(){ + return Offline(function(Transport){ + Transport.PPQ = 1; + var id = Transport.schedule(function(time){ + expect(time).to.be.closeTo(Transport.toSeconds("4n"), 0.1); + Transport.cancel(id); + }, "4n"); + Transport.start(); + }); + }); + + it ("invokes the right number of ticks with a different PPQ", function(){ + return Offline(function(Transport){ + Transport.bpm.value = 120; + var ppq = 20; + Transport.PPQ = ppq; + Transport.start(); + + return function(time){ + if (time > 0.5){ + expect(Transport.ticks).to.be.within(ppq, ppq * 1.2); + } + }; + }, 0.55); }); }); context("position", function(){ - afterEach(resetTransport); - - it("can jump to a specific tick number", function(done){ - Offline(function(dest, test, after){ - Tone.Transport.ticks = 200; - expect(Tone.Transport.ticks).to.equal(200); - Tone.Transport.start(0); - after(function(){ - expect(Tone.Transport.ticks).to.at.least(200); - Tone.Transport.stop(); - done(); - }); + it("can jump to a specific tick number", function(){ + return Offline(function(Transport){ + Transport.ticks = 200; + expect(Transport.ticks).to.equal(200); + Transport.start(0); + var tested = false; + return function(){ + if (!tested){ + expect(Transport.ticks).to.at.least(200); + tested = true; + } + }; }, 0.1); }); - it("can get the current position in BarsBeatsSixteenths", function(done){ - Offline(function(dest, test, after){ - expect(Tone.Transport.position).to.equal("0:0:0"); - Tone.Transport.start(0); - after(function(){ - expect(Tone.Transport.position).to.not.equal("0:0:0"); - Tone.Transport.stop(); - done(); - }); + it("can get the current position in BarsBeatsSixteenths", function(){ + return Offline(function(Transport){ + expect(Transport.position).to.equal("0:0:0"); + Transport.start(0); + var tested = false; + return function(){ + if (!tested){ + tested = true; + expect(Transport.position).to.not.equal("0:0:0"); + } + }; }, 0.1); }); - it("can get the current position in seconds", function(done){ - Offline(function(dest, test, after){ - expect(Tone.Transport.seconds).to.equal(0); - Tone.Transport.start(0); - test(function(sample, time){ - expect(Tone.Transport.seconds).to.be.closeTo(time, 0.05); - }); - after(function(){ - expect(Tone.Transport.seconds).to.be.closeTo(0.8, 0.05); - Tone.Transport.stop(); - done(); - }); - }, 0.8); + it("can get the current position in seconds", function(){ + return Offline(function(Transport){ + expect(Transport.seconds).to.equal(0); + Transport.start(0.05); + return function(time){ + if (time > 0.05){ + expect(Transport.seconds).to.be.closeTo(time - 0.05, 0.01); + } + }; + }, 0.1); }); it("can set the current position in seconds", function(){ - expect(Tone.Transport.seconds).to.equal(0); - Tone.Transport.seconds = 3; - expect(Tone.Transport.seconds).to.be.closeTo(3, 0.05); - Tone.Transport.seconds = 0; - expect(Tone.Transport.seconds).to.equal(0); + return Offline(function(Transport){ + expect(Transport.seconds).to.equal(0); + Transport.seconds = 3; + expect(Transport.seconds).to.be.closeTo(3, 0.01); + }); }); it("can set the current position in BarsBeatsSixteenths", function(){ - expect(Tone.Transport.position).to.equal("0:0:0"); - Tone.Transport.position = "3:0"; - expect(Tone.Transport.position).to.equal("3:0:0"); - Tone.Transport.position = "0:0"; - expect(Tone.Transport.position).to.equal("0:0:0"); + return Offline(function(Transport){ + expect(Transport.position).to.equal("0:0:0"); + Transport.position = "3:0"; + expect(Transport.position).to.equal("3:0:0"); + Transport.position = "0:0"; + expect(Transport.position).to.equal("0:0:0"); + }); }); it ("can get the progress of the loop", function(){ - Tone.Transport.setLoopPoints(0, "1m").start(); - Tone.Transport.loop = true; - expect(Tone.Transport.progress).to.be.equal(0); - Tone.Transport.position = "2n"; - expect(Tone.Transport.progress).to.be.closeTo(0.5, 0.001); - Tone.Transport.position = "2n + 4n"; - expect(Tone.Transport.progress).to.be.closeTo(0.75, 0.001); + return Offline(function(Transport){ + Transport.setLoopPoints(0, "1m").start(); + Transport.loop = true; + expect(Transport.progress).to.be.equal(0); + Transport.position = "2n"; + expect(Transport.progress).to.be.closeTo(0.5, 0.001); + Transport.position = "2n + 4n"; + expect(Transport.progress).to.be.closeTo(0.75, 0.001); + }); }); }); @@ -204,26 +219,49 @@ function (Test, Transport, Tone, Offline, TransportTime) { context("state", function(){ - afterEach(resetTransport); + it("can start, pause, and restart", function(){ + return Offline(function(Transport){ + Transport.start(0).pause(0.2).start(0.4); - it("can start, pause, and stop", function(done){ - Offline(function(dest, test, after){ - Tone.Transport.start(0).pause(0.2).stop(0.4); + var pulse = new Signal(0).toMaster(); - test(function(sample, time){ - if (time < 0.2){ - expect(Tone.Transport.state).to.equal("started"); - } else if (time < 0.4){ - expect(Tone.Transport.state).to.equal("paused"); - } else { - expect(Tone.Transport.state).to.equal("stopped"); - } + Transport.schedule(function(time){ + pulse.setValueAtTime(1, time); + pulse.setValueAtTime(0, time + 0.1); + }, 0); + + Transport.schedule(function(time){ + pulse.setValueAtTime(1, time); + pulse.setValueAtTime(0, time + 0.1); + }, 0.3); + + return function(time){ + Test.whenBetween(time, 0, 0.2, function(){ + expect(Transport.state).to.equal("started"); + }); + + Test.whenBetween(time, 0.2, 0.4, function(){ + expect(Transport.state).to.equal("paused"); + }); + + Test.whenBetween(time, 0.4, Infinity, function(){ + expect(Transport.state).to.equal("started"); + }); + }; + }, 0.6).then(function(buffer){ + + BufferTest.forEach(buffer, function(sample, time){ + Test.whenBetween(time, 0, 0.01, function(){ + expect(sample).to.equal(1); + }); + Test.whenBetween(time, 0.1, 0.11, function(){ + expect(sample).to.equal(0); + }); + Test.whenBetween(time, 0.5, 0.51, function(){ + expect(sample).to.equal(1); + }); }); - after(function(){ - expect(Tone.Transport.state).to.equal("stopped"); - done(); - }); - }, 0.5); + }); }); }); @@ -231,503 +269,512 @@ function (Test, Transport, Tone, Offline, TransportTime) { context("ticks", function(){ - afterEach(resetTransport); - - it("resets ticks on stop but not on pause", function(done){ - Offline(function(dest, test, after){ - Tone.Transport.start(0).pause(0.1).stop(0.2); - + it("resets ticks on stop but not on pause", function(){ + return Offline(function(Transport){ + Transport.start(0).pause(0.1).stop(0.2); + var pausedTicks = 0; - test(function(sample, time){ - if (time <= 0.1){ - expect(Tone.Transport.ticks).to.be.greaterThan(0); - pausedTicks = Tone.Transport.ticks; - } else if (time <= 0.19){ - expect(Tone.Transport.ticks).to.equal(pausedTicks); - } else if (time > 0.21){ - expect(Tone.Transport.ticks).to.equal(0); - } - }); - - after(done); - }, 0.5); + return function(time){ + Test.whenBetween(time, 0, 0.1, function(){ + pausedTicks = Transport.ticks; + }); + Test.whenBetween(time, 0.1, 0.19, function(){ + expect(Transport.ticks).to.equal(pausedTicks); + }); + Test.whenBetween(time, 0.2, Infinity, function(){ + expect(Transport.ticks).to.equal(0); + }); + }; + }, 0.3); }); - it("tracks ticks after start", function(done){ + it("tracks ticks after start", function(){ - Offline(function(dest, test, after){ - Tone.Transport.bpm.value = 120; - Tone.Transport.start(); + return Offline(function(Transport){ + Transport.bpm.value = 120; + var ppq = Transport.PPQ; + Transport.start(); - after(function(){ - expect(Tone.Transport.ticks).to.at.least(192); - done(); - }); + return function(time){ + if (time > 0.5){ + expect(Transport.ticks).to.at.least(ppq); + } + }; }, 0.6); }); - it("can start with a tick offset", function(done){ - Offline(function(dest, test, after){ - Tone.Transport.start(0, "200i"); + it("can start with a tick offset", function(){ + return Offline(function(Transport){ + Transport.start(0, "200i"); - test(function(sample, time){ - if (time > 0){ - expect(Tone.Transport.ticks).to.at.least(200); + return function(time){ + if (time < 0.01){ + expect(Transport.ticks).to.at.least(200); } - }); - - after(function(){ - expect(Tone.Transport.ticks).to.at.least(200); - done(); - }); + }; }, 0.1); }); - it("tracks ticks correctly with a different PPQ and BPM", function(done){ + it("tracks ticks correctly with a different PPQ and BPM", function(){ - Offline(function(dest, test, after){ - var origPPQ = Tone.Transport.PPQ; - Tone.Transport.PPQ = 96; - Tone.Transport.bpm.value = 90; - Tone.Transport.start(); + return Offline(function(Transport){ + Transport.PPQ = 96; + Transport.bpm.value = 90; + Transport.start(); - after(function(){ - expect(Tone.Transport.ticks).to.at.least(72); - Tone.Transport.PPQ = origPPQ; - done(); - }); + return function(time){ + if (time > 0.5){ + expect(Tone.Transport.ticks).to.at.least(72); + } + }; }, 0.6); }); }); context("schedule", function(){ - - afterEach(resetTransport); it ("can schedule an event on the timeline", function(){ - var eventID = Tone.Transport.schedule(function(){}, 0); - expect(eventID).to.be.a.number; + return Offline(function(Transport){ + var eventID = Transport.schedule(function(){}, 0); + expect(eventID).to.be.a.number; + }); }); - it ("scheduled event gets invoked with the time of the event", function(done){ - var startTime = Tone.Transport.now() + 0.1; - Tone.Transport.schedule(function(time){ - expect(time).to.equal(startTime); - done(); - }, 0); - Tone.Transport.start(startTime); + it ("scheduled event gets invoked with the time of the event", function(){ + return Offline(function(Transport){ + var startTime = 0.1; + Transport.schedule(function(time){ + expect(time).to.equal(startTime); + }, 0); + Transport.start(startTime); + }, 0.2); }); - it ("can schedule events with TransportTime", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eighth = Tone.Transport.toSeconds("8n"); - Tone.Transport.schedule(function(time){ - expect(time).to.be.closeTo(startTime + eighth, 0.01); - done(); - }, TransportTime("8n")); - Tone.Transport.start(startTime); + it ("can schedule events with TransportTime", function(){ + return Offline(function(Transport){ + var startTime = 0.1; + var eighth = Transport.toSeconds("8n"); + Transport.schedule(function(time){ + expect(time).to.be.closeTo(startTime + eighth, 0.01); + }, TransportTime("8n")); + Transport.start(startTime); + }, 0.5); }); - it ("can cancel a scheduled event", function(done){ - var eventID = Tone.Transport.schedule(function(){ - throw new Error("should not call this function"); - }, 0); - Tone.Transport.cancel(eventID); - Tone.Transport.stop(); - setTimeout(done, 100); + it ("can cancel a scheduled event", function(){ + return Offline(function(Transport){ + var eventID = Transport.schedule(function(){ + throw new Error("should not call this function"); + }, 0); + Transport.cancel(eventID); + Transport.start(); + }); }); it ("can cancel the timeline of scheduled object", function(){ - Tone.Transport.schedule(Tone.noOp, 0); - Tone.Transport.schedule(Tone.noOp, 1); - Tone.Transport.schedule(Tone.noOp, 2); - expect(Tone.Transport._timeline.length).to.equal(3); - Tone.Transport.cancel(2); - expect(Tone.Transport._timeline.length).to.equal(2); - Tone.Transport.cancel(0); - expect(Tone.Transport._timeline.length).to.equal(0); + return Offline(function(Transport){ + Transport.schedule(Tone.noOp, 0); + Transport.schedule(Tone.noOp, 1); + Transport.schedule(Tone.noOp, 2); + expect(Transport._timeline.length).to.equal(3); + Transport.cancel(2); + expect(Transport._timeline.length).to.equal(2); + Transport.cancel(0); + expect(Transport._timeline.length).to.equal(0); + }); }); it ("can cancel the timeline of schedulOnce object", function(){ - Tone.Transport.scheduleOnce(Tone.noOp, 0); - Tone.Transport.scheduleOnce(Tone.noOp, 1); - Tone.Transport.scheduleOnce(Tone.noOp, 2); - expect(Tone.Transport._onceEvents.length).to.equal(3); - Tone.Transport.cancel(2); - expect(Tone.Transport._onceEvents.length).to.equal(2); - Tone.Transport.cancel(0); - expect(Tone.Transport._onceEvents.length).to.equal(0); + return Offline(function(Transport){ + Transport.scheduleOnce(Tone.noOp, 0); + Transport.scheduleOnce(Tone.noOp, 1); + Transport.scheduleOnce(Tone.noOp, 2); + expect(Transport._onceEvents.length).to.equal(3); + Transport.cancel(2); + expect(Transport._onceEvents.length).to.equal(2); + Transport.cancel(0); + expect(Transport._onceEvents.length).to.equal(0); + }); }); - it ("scheduled event anywhere along the timeline", function(done){ - var startTime = Tone.Transport.now(); - Tone.Transport.schedule(function(time){ - expect(time).to.be.closeTo(startTime + 0.5, 0.001); - done(); - }, 0.5); - Tone.Transport.start(startTime); + it ("scheduled event anywhere along the timeline", function(){ + return Offline(function(Transport){ + var startTime = Transport.now(); + Transport.schedule(function(time){ + expect(time).to.be.closeTo(startTime + 0.5, 0.001); + }, 0.5); + Transport.start(startTime); + }, 0.6); }); - it ("can schedule multiple events and invoke them in the right order", function(done){ - var first = false; - Tone.Transport.schedule(function(){ - first = true; - }, 0.5); - Tone.Transport.schedule(function(){ - expect(first).to.be.true; - done(); - }, 0.51); - Tone.Transport.start(); + it ("can schedule multiple events and invoke them in the right order", function(){ + return Offline(function(Transport){ + var first = false; + Transport.schedule(function(){ + first = true; + }, 0.1); + Transport.schedule(function(){ + expect(first).to.be.true; + }, 0.11); + Tone.Transport.start(); + }, 0.2); }); - it ("invokes the event again if the timeline is restarted", function(done){ - Offline(function(dest, test, after){ - var iterations = 0; - - Tone.Transport.schedule(function(){ + it ("invokes the event again if the timeline is restarted", function(){ + var iterations = 0; + return Offline(function(Transport){ + Transport.schedule(function(){ iterations++; }, 0.05); - - Tone.Transport.start(0).stop(0.1).start(0.2); - - after(function(){ - expect(iterations).to.be.equal(2); - done(); - }); - }, 0.3); + Transport.start(0).stop(0.1).start(0.2); + }, 0.3).then(function(){ + expect(iterations).to.be.equal(2); + }); }); }); context("scheduleRepeat", function(){ - afterEach(resetTransport); - it ("can schedule a repeated event", function(){ - var eventID = Tone.Transport.scheduleRepeat(function(){}, 1, 0); - expect(eventID).to.be.a.number; + return Offline(function(Transport){ + var eventID = Transport.scheduleRepeat(function(){}, 1, 0); + expect(eventID).to.be.a.number; + }); }); - it ("scheduled event gets invoked with the time of the event", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eventID = Tone.Transport.scheduleRepeat(function(time){ - Tone.Transport.clear(eventID); - expect(time).to.equal(startTime); - done(); - }, 1, 0); - Tone.Transport.start(startTime); + it ("scheduled event gets invoked with the time of the event", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = 0.1; + var eventID = Transport.scheduleRepeat(function(time){ + Transport.clear(eventID); + expect(time).to.equal(startTime); + invoked = true; + }, 1, 0); + Transport.start(startTime); + }, 0.3).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("can schedule events with TransportTime", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eighth = Tone.Transport.toSeconds("8n"); - Tone.Transport.scheduleRepeat(function(time){ - expect(time).to.be.closeTo(startTime + eighth, 0.01); - done(); - }, "1n", TransportTime("8n")); - Tone.Transport.start(startTime); + it ("can schedule events with TransportTime", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = 0.1; + var eighth = Transport.toSeconds("8n"); + Transport.scheduleRepeat(function(time){ + expect(time).to.be.closeTo(startTime + eighth, 0.01); + invoked = true; + }, "1n", TransportTime("8n")); + Transport.start(startTime); + }, 0.4).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("can clear a scheduled event", function(done){ - var eventID = Tone.Transport.scheduleRepeat(function(){ - throw new Error("should not call this function"); - }, 1, 0); - Tone.Transport.clear(eventID); - Tone.Transport.stop(); - setTimeout(done, 100); + it ("can clear a scheduled event", function(){ + return Offline(function(Transport){ + var eventID = Transport.scheduleRepeat(function(){ + throw new Error("should not call this function"); + }, 1, 0); + Transport.clear(eventID); + Transport.stop(); + }); }); - it ("can be scheduled in the future", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eventID = Tone.Transport.scheduleRepeat(function(time){ - Tone.Transport.clear(eventID); - expect(time).to.be.closeTo(startTime + 0.2, 0.01); - done(); - }, 1, 0.2); - Tone.Transport.start(startTime); + it ("can be scheduled in the future", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = 0.1; + var eventID = Transport.scheduleRepeat(function(time){ + Transport.clear(eventID); + expect(time).to.be.closeTo(startTime + 0.2, 0.01); + invoked = true; + }, 1, 0.2); + Transport.start(startTime); + }, 0.5).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("repeats a repeat event", function(done){ - Offline(function(output, test, after){ - var invocations = 0; - - Tone.Transport.scheduleRepeat(function(){ + it ("repeats a repeat event", function(){ + var invocations = 0; + return Offline(function(Transport){ + Transport.scheduleRepeat(function(){ invocations++; }, 0.1, 0); - - Tone.Transport.start(); - - after(function(){ - expect(invocations).to.be.above(9); - done(); - }); - }, 1); + Transport.start(); + }, 0.5).then(function(){ + expect(invocations).to.equal(6); + }); }); - it ("repeats at the repeat interval", function(done){ - Offline(function(output, test, after){ + it ("repeats at the repeat interval", function(){ + return Offline(function(Transport){ var repeatTime = -1; - - var eventID = Tone.Transport.scheduleRepeat(function(time){ + Transport.scheduleRepeat(function(time){ if (repeatTime !== -1){ expect(time - repeatTime).to.be.closeTo(0.1, 0.01); } repeatTime = time; }, 0.1, 0); + Transport.start(); + }, 0.5); + }); - Tone.Transport.start(); - - after(function(){ - Tone.Transport.clear(eventID); - done(); - }); + it ("can schedule multiple events and invoke them in the right order", function(){ + var first = false; + var second = false; + return Offline(function(Transport){ + var firstID = Transport.scheduleRepeat(function(){ + first = true; + Transport.clear(firstID); + }, 1, 0.1); + var secondID = Transport.scheduleRepeat(function(){ + Transport.clear(secondID); + expect(first).to.be.true; + second = true; + }, 1, 0.11); + Transport.start(); + }, 0.3).then(function(){ + expect(first); + expect(second); }); }); - it ("can schedule multiple events and invoke them in the right order", function(done){ - var first = false; - var firstID = Tone.Transport.scheduleRepeat(function(){ - first = true; - Tone.Transport.clear(firstID); - }, 1, 0.5); - var secondID = Tone.Transport.scheduleRepeat(function(){ - Tone.Transport.clear(secondID); - expect(first).to.be.true; - done(); - }, 1, 0.51); - Tone.Transport.start(); - }); - it ("cannot schedule an event with an interval of 0", function(){ - expect(function(){ - Tone.Transport.scheduleRepeat(function(){}, 0, 10); - }).to.throw(Error); + return Offline(function(Transport){ + expect(function(){ + Transport.scheduleRepeat(function(){}, 0, 10); + }).to.throw(Error); + }); }); - it ("repeats for the given duration", function(done){ - Offline(function(output, test, after){ - - var repeatCount = 0; - - var eventID = Tone.Transport.scheduleRepeat(function(){ + it ("repeats for the given interval", function(){ + var repeatCount = 0; + return Offline(function(Transport){ + Transport.scheduleRepeat(function(){ repeatCount++; }, 0.1, 0, 0.5); - - Tone.Transport.start(); - - after(function(){ - expect(repeatCount).to.at.least(5); - Tone.Transport.clear(eventID); - done(); - }); - - }, 0.6); + Transport.start(); + }, 0.6).then(function(){ + expect(repeatCount).to.equal(6); + }); }); }); context("scheduleOnce", function(){ - afterEach(resetTransport); - it ("can schedule a single event on the timeline", function(){ - var eventID = Tone.Transport.scheduleOnce(function(){}, 0); - expect(eventID).to.be.a.number; - }); - - it ("scheduled event gets invoked with the time of the event", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eventID = Tone.Transport.scheduleOnce(function(time){ - Tone.Transport.clear(eventID); - expect(time).to.equal(startTime); - done(); - }, 0); - Tone.Transport.start(startTime); - }); - - it ("can schedule events with TransportTime", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eighth = Tone.Transport.toSeconds("8n"); - Tone.Transport.scheduleOnce(function(time){ - expect(time).to.be.closeTo(startTime + eighth, 0.01); - done(); - }, TransportTime("8n")); - Tone.Transport.start(startTime); + return Offline(function(Transport){ + var eventID = Transport.scheduleOnce(function(){}, 0); + expect(eventID).to.be.a.number; + }); }); - it ("can cancel a scheduled event", function(done){ - var eventID = Tone.Transport.scheduleOnce(function(){ - throw new Error("should not call this function"); - }, 0); - Tone.Transport.clear(eventID); - Tone.Transport.stop(); - setTimeout(done, 200); + it ("scheduled event gets invoked with the time of the event", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = 0.1; + var eventID = Transport.scheduleOnce(function(time){ + invoked = true; + Transport.clear(eventID); + expect(time).to.equal(startTime); + }, 0); + Tone.Transport.start(startTime); + }, 0.2).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("can be scheduled in the future", function(done){ - var startTime = Tone.Transport.now() + 0.1; - var eventID = Tone.Transport.scheduleOnce(function(time){ - Tone.Transport.clear(eventID); - expect(time).to.be.closeTo(startTime + 0.3, 0.01); - done(); - }, 0.3); - Tone.Transport.start(startTime); + it ("can schedule events with TransportTime", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = 0.1; + var eighth = Transport.toSeconds("8n"); + Transport.scheduleOnce(function(time){ + expect(time).to.be.closeTo(startTime + eighth, 0.01); + invoked = true; + }, TransportTime("8n")); + Transport.start(startTime); + }, 0.5).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("the event is removed after is is invoked", function(done){ + + it ("can cancel a scheduled event", function(){ + return Offline(function(Transport){ + var eventID = Transport.scheduleOnce(function(){ + throw new Error("should not call this function"); + }, 0); + Transport.clear(eventID); + Transport.start(); + }); + }); + + it ("can be scheduled in the future", function(){ + var invoked = false; + return Offline(function(Transport){ + var startTime = Tone.Transport.now() + 0.1; + var eventID = Transport.scheduleOnce(function(time){ + Transport.clear(eventID); + expect(time).to.be.closeTo(startTime + 0.3, 0.01); + invoked = true; + }, 0.3); + Transport.start(startTime); + }, 0.5).then(function(){ + expect(invoked).to.be.true; + }); + }); + + it ("the event is removed after is is invoked", function(){ var iterations = 0; - Tone.Transport.scheduleOnce(function(){ - iterations++; + return Offline(function(Transport){ + Transport.scheduleOnce(function(){ + iterations++; + }, 0); + Transport.start().stop("+0.1").start("+0.2"); + }, 0.5).then(function(){ expect(iterations).to.be.lessThan(2); - }, 0); - Tone.Transport.start().stop("+0.1").start("+0.2"); - setTimeout(done, 500); + }); }); }); context("events", function(){ - afterEach(resetTransport); - - it("invokes start/stop/pause events", function(done){ - var count = 0; - Tone.Transport.on("start pause stop", function(){ - count++; - if (count === 3){ - done(); - } + it("invokes start/stop/pause events", function(){ + var invokations = 0; + return Offline(function(Transport){ + Tone.Transport.on("start pause stop", function(){ + invokations++; + }); + Transport.start().stop(0.1).start(0.2); + }, 0.5).then(function(){ + expect(invokations).to.equal(3); }); - Tone.Transport.start("+0.1").pause("+0.2").stop("+0.3"); }); - it("invokes start event with correct offset", function(done){ - var now = Tone.now(); - Tone.Transport.on("start", function(time, offset){ - expect(time).to.be.closeTo(now + 0.1, 0.01); - expect(offset).to.be.closeTo(0.5, 0.001); - done(); - }); - Tone.Transport.start("+0.1", "4n"); + it("invokes start event with correct offset", function(){ + return Offline(function(Transport){ + Transport.on("start", function(time, offset){ + expect(time).to.be.closeTo(0.2, 0.01); + expect(offset).to.be.closeTo(0.5, 0.001); + }); + Transport.start(0.2, "4n"); + }, 0.3); }); - it("passes in the time argument to the events", function(done){ - var now = Tone.Transport.now(); - Tone.Transport.on("start", function(time){ - expect(time).to.be.closeTo(now + 0.1, 0.01); + it("invokes the event just before the scheduled time", function(){ + var invoked = false; + return Offline(function(Transport){ + Transport.on("start", function(time, offset){ + expect(time - Transport.now()).to.be.within(0, 0.05); + expect(offset).to.equal(0); + invoked = true; + }); + Transport.start(0.2); + }, 0.3).then(function(){ + expect(invoked).to.be.true; }); - Tone.Transport.on("stop", function(time){ - expect(time).to.be.closeTo(now + 0.2, 0.01); - done(); - }); - Tone.Transport.start("+0.1").stop("+0.2"); }); - it("invokes the 'loop' method on loop", function(done){ - - Offline(function(output, test, after){ - - var sixteenth = Tone.Transport.toSeconds("16n"); - - Tone.Transport.setLoopPoints(0, sixteenth); - Tone.Transport.loop = true; + it("passes in the time argument to the events", function(){ + var invokations = 0; + return Offline(function(Transport){ + var now = Transport.now(); + Transport.on("start", function(time){ + invokations++; + expect(time).to.be.closeTo(now + 0.1, 0.01); + }); + Transport.on("stop", function(time){ + invokations++; + expect(time).to.be.closeTo(now + 0.2, 0.01); + }); + Transport.start("+0.1").stop("+0.2"); + }, 0.3).then(function(){ + expect(invokations).to.equal(2); + }); + }); + it("invokes the 'loop' method on loop", function(){ + var loops = 0; + return Offline(function(Transport){ + var sixteenth = Transport.toSeconds("16n"); + Transport.setLoopPoints(0, sixteenth); + Transport.loop = true; var lastLoop = -1; - var loops = 0; - - Tone.Transport.on("loop", function(time){ + Transport.on("loop", function(time){ loops++; if (lastLoop !== -1){ expect(time - lastLoop).to.be.closeTo(sixteenth, 0.001); } lastLoop = time; }); - - Tone.Transport.start(0).stop(sixteenth * 5.1); - - after(function(){ - expect(loops).to.equal(5); - done(); - }); - - }, 0.7); + Transport.start(0).stop(sixteenth * 5.1); + }, 0.7).then(function(){ + expect(loops).to.equal(5); + }); }); }); context("swing", function(){ - afterEach(resetTransport); - it("can get/set the swing subdivision", function(){ - Tone.Transport.swingSubdivision = "8n"; - expect(Tone.Transport.swingSubdivision).to.equal("8n"); - Tone.Transport.swingSubdivision = "4n"; - expect(Tone.Transport.swingSubdivision).to.equal("4n"); + return Offline(function(Transport){ + Transport.swingSubdivision = "8n"; + expect(Transport.swingSubdivision).to.equal("8n"); + Transport.swingSubdivision = "4n"; + expect(Transport.swingSubdivision).to.equal("4n"); + }); }); it("can get/set the swing amount", function(){ - Tone.Transport.swing = 0.5; - expect(Tone.Transport.swing).to.equal(0.5); - Tone.Transport.swing = 0; - expect(Tone.Transport.swing).to.equal(0); + return Offline(function(Transport){ + Transport.swing = 0.5; + expect(Transport.swing).to.equal(0.5); + Transport.swing = 0; + expect(Transport.swing).to.equal(0); + }); }); - it("can swing", function(done){ - Offline(function(output, test, after){ - - Tone.Transport.swing = 1; - Tone.Transport.swingSubdivision = "8n"; - var eightNote = Tone.Transport.toSeconds("8n"); - + it("can swing", function(){ + var invokations = 0; + return Offline(function(Transport){ + Transport.swing = 1; + Transport.swingSubdivision = "8n"; + var eightNote = Transport.toSeconds("8n"); //downbeat, no swing - Tone.Transport.schedule(function(time){ + Transport.schedule(function(time){ + invokations++; expect(time).is.closeTo(0, 0.001); }, 0); - //eighth note has swing - Tone.Transport.schedule(function(time){ + Transport.schedule(function(time){ + invokations++; expect(time).is.closeTo(eightNote * 5/3, 0.001); }, "8n"); - //sixteenth note is also swung - Tone.Transport.schedule(function(time){ + Transport.schedule(function(time){ + invokations++; expect(time).is.closeTo(eightNote, 0.05); }, "16n"); - //no swing on the quarter - Tone.Transport.schedule(function(time){ + Transport.schedule(function(time){ + invokations++; expect(time).is.closeTo(eightNote * 2, 0.001); }, "4n"); - - Tone.Transport.start(0).stop(0.7); - - after(function(){ - Tone.Transport.swing = 0; - done(); - }); - - }, 0.7); - }); - }); - - context("latencyHint", function(){ - - afterEach(resetTransport); - - it ("can get/set the latencyHint in seconds", function(){ - Tone.Transport.latencyHint = 0.2; - expect(Tone.Transport.latencyHint).to.be.a.number; - Tone.Transport.latencyHint = "interactive"; - }); - - it ("can set the latencyHint to 'performance', 'interactive' and 'balanced'", function(){ - Tone.Transport.latencyHint = "performance"; - Tone.Transport.latencyHint = "balanced"; - Tone.Transport.latencyHint = "interactive"; + Transport.start(0).stop(0.7); + }, 0.7).then(function(){ + expect(invokations).to.equal(4); + }); }); }); diff --git a/test/event/Event.js b/test/event/Event.js index 5a39757e..f36c9305 100644 --- a/test/event/Event.js +++ b/test/event/Event.js @@ -1,282 +1,259 @@ -define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transport", "helper/Offline2"], - function (Basic, Event, Tone, Transport, Offline) { +define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transport", "helper/Offline", "Test"], + function (Basic, Event, Tone, Transport, Offline, Test) { describe("Event", function(){ Basic(Event); - function resetTransport(done){ - Tone.Transport.cancel(0); - Tone.Transport.off("start stop pause loop"); - Tone.Transport.stop(); - Tone.Transport.loop = false; - Tone.Transport.bpm.value = 120; - Tone.Transport.timeSignature = [4, 4]; - setTimeout(done, 200); - } - context("Constructor", function(){ - afterEach(resetTransport); - it ("takes a callback and a value", function(){ - var callback = function(){}; - var note = new Event(callback, "C4"); - expect(note.callback).to.equal(callback); - expect(note.value).to.equal("C4"); - note.dispose(); + return Offline(function(){ + var callback = function(){}; + var note = new Event(callback, "C4"); + expect(note.callback).to.equal(callback); + expect(note.value).to.equal("C4"); + note.dispose(); + }); }); it ("can be constructed with no arguments", function(){ - var note = new Event(); - expect(note.value).to.be.null; - note.dispose(); + return Offline(function(){ + var note = new Event(); + expect(note.value).to.be.null; + note.dispose(); + }); }); it ("can pass in arguments in options object", function(){ - var callback = function(){}; - var value = {"a" : 1}; - var note = new Event({ - "callback" : callback, - "value" : value, - "loop" : true, - "loopEnd" : "4n", - "probability" : 0.3 + return Offline(function(){ + var callback = function(){}; + var value = {"a" : 1}; + var note = new Event({ + "callback" : callback, + "value" : value, + "loop" : true, + "loopEnd" : "4n", + "probability" : 0.3 + }); + expect(note.callback).to.equal(callback); + expect(note.value).to.equal(value); + expect(note.loop).to.be.true; + expect(note.loopEnd).to.equal("4n"); + expect(note.probability).to.equal(0.3); + note.dispose(); }); - expect(note.callback).to.equal(callback); - expect(note.value).to.equal(value); - expect(note.loop).to.be.true; - expect(note.loopEnd).to.equal("4n"); - expect(note.probability).to.equal(0.3); - note.dispose(); }); }); context("Get/Set", function(){ - afterEach(resetTransport); - it ("can set values with object", function(){ - var callback = function(){}; - var note = new Event(); - note.set({ - "callback" : callback, - "value" : "D4", - "loop" : 8 + return Offline(function(){ + var callback = function(){}; + var note = new Event(); + note.set({ + "callback" : callback, + "value" : "D4", + "loop" : 8 + }); + expect(note.callback).to.equal(callback); + expect(note.value).to.equal("D4"); + expect(note.loop).to.equal(8); + note.dispose(); }); - expect(note.callback).to.equal(callback); - expect(note.value).to.equal("D4"); - expect(note.loop).to.equal(8); - note.dispose(); }); it ("can set get a the values as an object", function(){ - var callback = function(){}; - var note = new Event({ - "callback" : callback, - "value" : "D3", - "loop" : 4 + return Offline(function(){ + var callback = function(){}; + var note = new Event({ + "callback" : callback, + "value" : "D3", + "loop" : 4 + }); + var values = note.get(); + expect(values.value).to.equal("D3"); + expect(values.loop).to.equal(4); + note.dispose(); }); - var values = note.get(); - expect(values.value).to.equal("D3"); - expect(values.loop).to.equal(4); - note.dispose(); }); }); context("Event callback", function(){ - afterEach(resetTransport); - - it ("does not invoke get invoked until started", function(done){ - Offline(function(output, test, after){ - - var note = new Event(function(){ + it ("does not invoke get invoked until started", function(){ + return Offline(function(Transport){ + new Event(function(){ throw new Error("shouldn't call this callback"); }, "C4"); - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(); }, 0.3); }); - it ("is invoked after it's started", function(done){ - var note = new Event(function(){ - note.dispose(); - done(); - }, "C4").start(0); - Tone.Transport.start(); - }); - - it ("passes in the scheduled time to the callback", function(done){ - var now = Tone.Transport.now() + 0.1; - var note = new Event(function(time){ - expect(time).to.be.a.number; - expect(time - now).to.be.closeTo(0.3, 0.01); - note.dispose(); - done(); + it ("is invoked after it's started", function(){ + var invoked = false; + return Offline(function(Transport){ + var note = new Event(function(){ + note.dispose(); + invoked = true; + }, "C4").start(0); + Transport.start(); + }, 0.3).then(function(){ + expect(invoked).to.be.true; }); - note.start(0.3); - Tone.Transport.start(now); }); - it ("passes in the value to the callback", function(done){ - var note = new Event(function(time, thing){ - expect(time).to.be.a.number; - expect(thing).to.equal("thing"); - note.dispose(); - done(); - }, "thing").start(); - Tone.Transport.start(); + it ("passes in the scheduled time to the callback", function(){ + var invoked = false; + return Offline(function(Transport){ + var now = 0.1; + var note = new Event(function(time){ + expect(time).to.be.a.number; + expect(time - now).to.be.closeTo(0.3, 0.01); + note.dispose(); + invoked = true; + }); + note.start(0.3); + Transport.start(now); + }, 0.5).then(function(){ + expect(invoked).to.be.true; + }); }); - it ("can mute the callback", function(done){ - Offline(function(output, test, after){ + it ("passes in the value to the callback", function(){ + var invoked = false; + return Offline(function(Transport){ + var note = new Event(function(time, thing){ + expect(time).to.be.a.number; + expect(thing).to.equal("thing"); + note.dispose(); + invoked = true; + }, "thing").start(); + Transport.start(); + }, 0.3).then(function(){ + expect(invoked).to.be.true; + }); + }); + + it ("can mute the callback", function(){ + return Offline(function(Transport){ var note = new Event(function(){ throw new Error("shouldn't call this callback"); }, "C4").start(); - note.mute = true; expect(note.mute).to.be.true; - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(); }, 0.3); }); - it ("can trigger with some probability", function(done){ + it ("can trigger with some probability", function(){ - Offline(function(output, test, after){ + return Offline(function(Transport){ var note = new Event(function(){ throw new Error("shouldn't call this callback"); }, "C4").start(); - note.probability = 0; expect(note.probability).to.equal(0); - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(); }, 0.3); }); }); context("Scheduling", function(){ - afterEach(resetTransport); - - it ("can be started and stopped multiple times", function(done){ - Offline(function(output, test, after){ + it ("can be started and stopped multiple times", function(){ + return Offline(function(Transport){ var note = new Event().start(0).stop(0.2).start(0.4); - - Tone.Transport.start(0); - - test(function(sample, time){ - if (time > 0 && time < 0.18){ + Transport.start(0); + return function(time){ + Test.whenBetween(time, 0, 0.19, function(){ expect(note.state).to.equal("started"); - } else if (time > 0.2 && time < 0.38){ + }); + Test.whenBetween(time, 0.2, 0.39, function(){ expect(note.state).to.equal("stopped"); - } else if (time > 0.4){ + }); + Test.whenBetween(time, 0.4, Infinity, function(){ expect(note.state).to.equal("started"); - } - }); - - after(function(){ - expect(note.state).to.equal("started"); - note.dispose(); - done(); - }); + }); + }; }, 0.5); }); - it ("restarts when transport is restarted", function(done){ + it ("restarts when transport is restarted", function(){ - Offline(function(output, test, after){ + return Offline(function(Transport){ var note = new Event().start(0).stop(0.4); - - Tone.Transport.start(0).stop(0.5).start(0.55); - - test(function(sample, time){ - if (time > 0 && time < 0.38){ - expect(note.state).to.equal("started"); - } else if (time > 0.4 && time < 0.5){ + Transport.start(0).stop(0.5).start(0.55); + return function(sample, time){ + Test.whenBetween(time, 0, 0.39, function(){ + expect(note.state).to.equal("started"); + }); + Test.whenBetween(time, 0.4, 0.5, function(){ expect(note.state).to.equal("stopped"); - } else if (time > 0.55 && time < 0.8){ - expect(note.state).to.equal("started"); - } - }); - - after(function(){ - expect(Tone.Transport.state).to.equal("started"); - expect(note.state).to.equal("stopped"); - note.dispose(); - done(); - }); + }); + Test.whenBetween(time, 0.55, 0.8, function(){ + expect(note.state).to.equal("started"); + }); + }; }, 1); }); - it ("can be cancelled", function(done){ - var note = new Event().start(0); - setTimeout(function(){ + it ("can be cancelled", function(){ + return Offline(function(Transport){ + var note = new Event().start(0); expect(note.state).to.equal("started"); - Tone.Transport.stop(); - note.cancel(); - setTimeout(function(){ - Tone.Transport.start(); - setTimeout(function(){ + Transport.start(); + + var firstStop = false; + var restarted = false; + var tested = false; + return function(time){ + //stop the transport + if (time > 0.2 && !firstStop){ + firstStop = true; + Transport.stop(); + note.cancel(); + } + if (time > 0.3 && !restarted){ + restarted = true; + Transport.start(); + } + if (time > 0.4 && !tested){ + restarted = true; + Transport.start(); expect(note.state).to.equal("stopped"); - note.dispose(); - done(); - }, 100); - }, 100); - }, 100); - Tone.Transport.start(); + } + }; + }, 0.5); }); }); context("Looping", function(){ - afterEach(resetTransport); - - it ("can be set to loop", function(done){ - - Offline(function(output, test, after){ - - var callCount = 0; - - var note = new Event({ + it ("can be set to loop", function(){ + var callCount = 0; + return Offline(function(Transport){ + new Event({ "loopEnd" : 0.25, "loop" : true, "callback" : function(){ callCount++; } }).start(0); - - Tone.Transport.start(0); - - after(function(){ - expect(callCount).to.equal(4); - note.dispose(); - done(); - }); - }, 0.8); + Transport.start(0); + }, 0.8).then(function(){ + expect(callCount).to.equal(4); + }); }); - it ("can be set to loop at a specific interval", function(done){ - Offline(function(output, test, after){ + it ("can be set to loop at a specific interval", function(){ + return Offline(function(Transport){ var lastCall; - var note = new Event({ + new Event({ "loopEnd" : 0.25, "loop" : true, "callback" : function(time){ @@ -286,22 +263,13 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo lastCall = time; } }).start(0); - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); - + Transport.start(); }, 1); }); - it ("can adjust the loop duration after starting", function(done){ - - Offline(function(output, test, after){ - + it ("can adjust the loop duration after starting", function(){ + return Offline(function(Transport){ var lastCall; - var note = new Event({ "loopEnd" : 0.5, "loop" : true, @@ -314,48 +282,31 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo lastCall = time; } }).start(0); - - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(); }, 0.8); }); - it ("can loop a specific number of times", function(done){ - - Offline(function(output, test, after){ - - var callCount = 0; - - var note = new Event({ + it ("can loop a specific number of times", function(){ + var callCount = 0; + return Offline(function(Transport){ + new Event({ "loopEnd" : 0.125, "loop" : 3, "callback" : function(){ callCount++; } }).start(0); - - Tone.Transport.start(); - - after(function(){ - expect(callCount).to.equal(3); - note.dispose(); - done(); - }); - }, 0.8); + Transport.start(); + }, 0.8).then(function(){ + expect(callCount).to.equal(3); + }); }); - it ("can be started and stopped multiple times", function(done){ - - Offline(function(output, test, after){ - + it ("can be started and stopped multiple times", function(){ + return Offline(function(Transport){ var eventTimes = [0.3, 0.4, 0.9, 1.0, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9]; var eventTimeIndex = 0; - - var note = new Event({ + new Event({ "loopEnd" : 0.1, "loop" : true, "callback" : function(time){ @@ -364,21 +315,13 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo eventTimeIndex++; } }).start(0.1).stop(0.2).start(0.5).stop(1.1); - - Tone.Transport.start(0.2).stop(0.5).start(0.8); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(0.2).stop(0.5).start(0.8); }, 2); }); - it ("loops the correct amount of times when the event is started in the Transport's past", function(done){ - - Offline(function(output, test, after){ - - var callCount = 0; + it ("loops the correct amount of times when the event is started in the Transport's past", function(){ + var callCount = 0; + return Offline(function(Transport){ var note = new Event({ "loopEnd" : 0.2, "loop" : 3, @@ -386,76 +329,53 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo callCount++; } }); - - Tone.Transport.start(); - + Transport.start(); var wasCalled = false; - - test(function(sample, time){ - + return function(time){ if (time > 0.1 && !wasCalled) { wasCalled = true; note.start(0); } - }); - - after(function(){ - expect(callCount).to.equal(2); - note.dispose(); - done(); - }); - - }, 1); + }; + }, 1).then(function(){ + expect(callCount).to.equal(2); + }); }); - it ("reports the progress of the loop", function(done){ - - Offline(function(output, test, after){ - + it ("reports the progress of the loop", function(){ + return Offline(function(Transport){ var note = new Event({ "loopEnd" : 1, "loop" : true, }).start(0); - - Tone.Transport.start(); - - after(function(){ - expect(note.progress).to.be.closeTo(0.8, 0.1); - note.dispose(); - done(); - }); + Transport.start(); + return function(time){ + expect(note.progress).to.be.closeTo(time, 0.05); + }; }, 0.8); }); - it ("progress is 0 when not looping", function(done){ - Offline(function(output, test, after){ - + it ("progress is 0 when not looping", function(){ + Offline(function(Transport){ var note = new Event({ "loopEnd" : 0.25, "loop" : false, }).start(0); - - Tone.Transport.start(); - - after(function(){ + Transport.start(); + return function(){ expect(note.progress).to.equal(0); - note.dispose(); - done(); - }); - }, 0.8); + }; + }, 0.2); }); }); context("playbackRate and humanize", function(){ - afterEach(resetTransport); - - it ("can adjust the playbackRate", function(done){ - - Offline(function(output, test, after){ + it ("can adjust the playbackRate", function(){ + return Offline(function(Transport){ var lastCall; - var note = new Event({ + new Event({ "playbackRate" : 2, "loopEnd" : 0.5, "loop" : true, @@ -466,20 +386,12 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo lastCall = time; } }).start(0); - - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); - + Transport.start(); }, 0.7); }); - it ("can adjust the playbackRate after starting", function(done){ - - Offline(function(output, test, after){ + it ("can adjust the playbackRate after starting", function(){ + return Offline(function(Transport){ var lastCall; var note = new Event({ "playbackRate" : 1, @@ -494,22 +406,14 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo lastCall = time; } }).start(0); - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); + Transport.start(); }, 1.2); }); - it ("can humanize the callback by some amount", function(done){ - - Offline(function(output, test, after){ - + it ("can humanize the callback by some amount", function(){ + return Offline(function(Transport){ var lastCall; - var note = new Event({ "humanize" : 0.05, "loopEnd" : 0.25, @@ -521,14 +425,7 @@ define(["helper/Basic", "Tone/event/Event", "Tone/core/Tone", "Tone/core/Transpo lastCall += 0.25; } }).start(0); - - Tone.Transport.start(); - - after(function(){ - note.dispose(); - done(); - }); - + Transport.start(); }, 0.6); }); diff --git a/test/helper/Offline.js b/test/helper/Offline.js index 47432d1f..415309ce 100644 --- a/test/helper/Offline.js +++ b/test/helper/Offline.js @@ -1,29 +1,21 @@ -define(["Tone/core/Tone", "Tone/core/Offline", "helper/BufferTest"], function (Tone, Offline, BufferTest) { +define(["Tone/core/Tone", "Tone/core/Offline", "helper/BufferTest", "Tone/core/Master"], + function (Tone, Offline, BufferTest, Master) { return function(callback, duration, channels){ - duration = duration || 0.5; + duration = duration || 0.1; channels = channels || 1; - var testFn = null; return Offline(function(Transport){ - testFn = callback(Transport); + var testFn = callback(Transport); + if (testFn){ + Transport.context.on("tick", function(){ + testFn(Transport.now()); + }); + } }, duration).then(function(buffer){ if (channels === 1){ buffer.toMono(); - } - if (testFn){ - var currentTime = 0; - Tone.context.now = function(){ - return currentTime; - }; - BufferTest.forEach(buffer, function(){ - if (arguments.length === 3){ - currentTime = arguments[2]; - } else { - currentTime = arguments[1]; - } - testFn.apply(undefined, arguments); - }); } + return buffer; }); }; }); \ No newline at end of file