spec/clock_spec.lua (4082 bytes)
1 local Clock = require("subread.clock") 2 3 describe("SubRead clock", function() 4 it("starts paused at zero", function() 5 local c = Clock.new() 6 assert.is_false(c:isRunning()) 7 assert.equals(0, c:getPosition(1000)) 8 end) 9 10 it("does not move while paused", function() 11 local c = Clock.new{ position = 30 } 12 assert.equals(30, c:getPosition(1000)) 13 assert.equals(30, c:getPosition(9999)) 14 end) 15 16 it("moves with real time when running", function() 17 local c = Clock.new() 18 c:start(100) 19 assert.near(0, c:getPosition(100), 1e-9) 20 assert.near(5, c:getPosition(105), 1e-9) 21 end) 22 23 it("keeps the position over a pause", function() 24 local c = Clock.new() 25 c:start(100) 26 c:pause(110) 27 assert.near(10, c:getPosition(500), 1e-9) 28 c:start(500) 29 assert.near(12, c:getPosition(502), 1e-9) 30 end) 31 32 it("applies the speed", function() 33 local c = Clock.new{ speed = 2.0 } 34 c:start(0) 35 assert.near(20, c:getPosition(10), 1e-9) 36 end) 37 38 it("keeps the position when the speed changes", function() 39 local c = Clock.new() 40 c:start(0) 41 c:setSpeed(3.0, 10) 42 assert.near(10, c:getPosition(10), 1e-9) 43 assert.near(40, c:getPosition(20), 1e-9) 44 end) 45 46 it("holds the speed inside its limits", function() 47 local c = Clock.new() 48 c:setSpeed(0.1, 0) 49 assert.equals(Clock.SPEED_MIN, c.speed) 50 c:setSpeed(99, 0) 51 assert.equals(Clock.SPEED_MAX, c.speed) 52 end) 53 54 it("takes the offset off the cue time", function() 55 local c = Clock.new{ position = 100, offset = 20 } 56 assert.equals(100, c:getPosition(0)) 57 assert.equals(80, c:getCueTime(0)) 58 c:setOffset(-5) 59 assert.equals(105, c:getCueTime(0)) 60 end) 61 62 it("seeks to an absolute position", function() 63 local c = Clock.new() 64 c:start(0) 65 c:seek(60, 10) 66 assert.near(60, c:getPosition(10), 1e-9) 67 assert.near(65, c:getPosition(15), 1e-9) 68 assert.is_true(c:isRunning()) 69 end) 70 71 it("never seeks before zero", function() 72 local c = Clock.new{ position = 5 } 73 c:seek(-10, 0) 74 assert.equals(0, c.position) 75 end) 76 77 it("skips forward and back", function() 78 local c = Clock.new{ position = 100 } 79 c:skip(10, 0) 80 assert.equals(110, c:getPosition(0)) 81 c:skip(-10, 0) 82 assert.equals(100, c:getPosition(0)) 83 end) 84 85 it("seeks by cue time through the offset", function() 86 local c = Clock.new{ offset = 20 } 87 c:seekCueTime(50, 0) 88 assert.equals(70, c:getPosition(0)) 89 assert.equals(50, c:getCueTime(0)) 90 end) 91 92 it("toggles between running and paused", function() 93 local c = Clock.new() 94 assert.is_true(c:toggle(0)) 95 assert.is_false(c:toggle(5)) 96 assert.equals(5, c:getPosition(100)) 97 end) 98 99 it("tells how long until a cue time", function() 100 local c = Clock.new{ speed = 2.0, offset = 10 } 101 c:start(0) 102 -- Cue time 30 is player position 40, which comes after 20 real seconds. 103 assert.near(20, c:realSecondsUntilCueTime(30, 0), 1e-9) 104 -- Cue time -20 is player position -10, which is already past. 105 assert.is_nil(c:realSecondsUntilCueTime(-20, 0)) 106 end) 107 108 it("gives no wait time while paused", function() 109 local c = Clock.new() 110 assert.is_nil(c:realSecondsUntilCueTime(100, 0)) 111 end) 112 113 it("keeps position and cue time in step over any sequence", function() 114 local c = Clock.new{ speed = 1.5, offset = 3 } 115 local now = 0 116 c:start(now) 117 for step = 1, 40 do 118 now = now + 0.25 119 if step % 7 == 0 then c:toggle(now) end 120 if step % 11 == 0 then c:skip(-10, now) end 121 if step % 13 == 0 then c:setSpeed(0.5 + (step % 5) / 2, now) end 122 assert.near(c:getPosition(now) - c.offset, c:getCueTime(now), 1e-9) 123 assert.is_true(c:getPosition(now) >= 0) 124 end 125 end) 126 end)