Timeline = window.mojs.Timeline
easing = window.mojs.easing
describe 'Timeline ->', ->
describe 'init ->', ->
it 'calc totalDuration and totalTime', ->
t = new Timeline duration: 1000, delay: 100
expect(t.props.totalDuration).toBe 1000
expect(t.props.totalTime).toBe 1100
t = new Timeline duration: 1000, delay: 100, repeat: 5
expect(t.props.totalDuration).toBe 6500
expect(t.props.totalTime).toBe 6600
describe 'defaults ->', ->
it 'should have vars', ->
t = new Timeline
expect(t.props) .toBeDefined()
expect(t.h) .toBeDefined()
expect(t.progress).toBe 0
it 'should have defaults', ->
t = new Timeline
expect(t.defaults.duration).toBe 600
expect(t.defaults.delay).toBe 0
expect(t.defaults.yoyo).toBe false
expect(t.defaults.isChained).toBe false
it 'should extend defaults to options', ->
t = new Timeline duration: 1000
expect(t.o.duration).toBe 1000
expect(t.o.delay).toBe 0
describe 'isChained option ->', ->
it 'should recieve isChained option', ->
t = new Timeline
duration: 1000, isChained: true
expect(t.o.isChained).toBe true
it 'should fallback to default isChained option', ->
t = new Timeline
duration: 1000
expect(t.o.isChained).toBe false
describe 'start ->', ->
it 'should calculate start time', ->
t = new Timeline(duration: 1000, delay: 500).start()
now = performance.now() + 500
expect(t.props.startTime).not.toBeGreaterThan now
expect(t.props.startTime).toBeGreaterThan now-50
it 'should recieve the start time', ->
t = new Timeline(duration: 1000).start 1
expect(t.props.startTime).toBe 1
it 'should calculate end time', ->
t = new Timeline(duration: 1000, delay: 500).start()
expect(t.props.endTime).toBe t.props.startTime + 1000
it 'should calculate end time if repeat', ->
t = new Timeline(duration: 1000, delay: 500, repeat: 2).start()
expect(t.props.endTime).toBe t.props.startTime+(3*(1000+500))-500
it 'should restart flags', ->
t = new Timeline(duration: 20, repeat: 2).start()
t.update t.props.startTime + 10
t.update t.props.startTime + 60
expect(t.isCompleted).toBe true
expect(t.isStarted) .toBe true
t.start()
expect(t.isCompleted).toBe false
expect(t.isStarted) .toBe false
describe 'update time ->', ->
it 'should update progress', ->
t = new Timeline(duration: 1000, delay: 500)
t.start()
time = t.props.startTime + 200
t.update time
expect(t.progress).toBe .2
it 'should update progress with repeat', ->
t = new Timeline(duration: 1000, delay: 200, repeat: 2)
t.start()
t.update t.props.startTime + 1400
expect(t.progress).toBe .2
t.update t.props.startTime + 2700
expect(t.progress).toBe .3
t.update t.props.startTime + 3400
expect(t.progress).toBe 1
it 'should update progress to 0 if in delay gap', ->
t = new Timeline(duration: 1000, delay: 200, repeat: 2)
t.start()
t.update t.props.startTime + 1100
expect(t.progress).toBe 0
it 'should update progress to 1 on the end', ->
t = new Timeline(duration: 1000, delay: 200, repeat: 2)
t.start()
t.update t.props.startTime + 1000
expect(t.progress).toBe 1
it 'should not call update method if timeline isnt active "-"', ->
t = new Timeline(duration: 1000, onUpdate:->)
t.start()
spyOn t, 'onUpdate'
t.update(performance.now() - 500)
expect(t.onUpdate).not.toHaveBeenCalled()
it 'should not call update method if timeline isnt active "+"', ->
cnt = 0
t = new Timeline(duration: 1000, onUpdate:-> cnt++ )
t.start(); t.update(performance.now() + 1500)
expect(cnt).toBe 1
it 'should set Timeline to the end if Timeline ended', ->
t = new Timeline(duration: 1000, delay: 500)
t.start()
t.update t.props.startTime + 1200
expect(t.progress).toBe 1
describe 'onUpdate callback ->', ->
it 'should be defined', ->
t = new Timeline onUpdate: ->
expect(t.o.onUpdate).toBeDefined()
it 'should call onUpdate callback with the current progress', ->
t = new Timeline duration: 1000, easing: 'bounce.out', onUpdate: ->
spyOn t, 'onUpdate'
t.start()
t.update t.props.startTime + 500
expect(t.onUpdate).toHaveBeenCalledWith t.easedProgress
it 'should have the right scope', ->
isRightScope = false
t = new Timeline onUpdate:-> isRightScope = @ instanceof Timeline
t.start()
t.update t.props.startTime + 200
expect(isRightScope).toBe true
describe 'onStart callback ->', ->
it 'should be defined', ->
t = new Timeline(onStart: ->)
t.start()
expect(t.o.onStart).toBeDefined()
it 'should call onStart callback', ->
t = new Timeline duration: 32, onStart:->
t.start()
spyOn(t.o, 'onStart')
t.update t.props.startTime + 1
expect(t.o.onStart).toHaveBeenCalled()
it 'should be called just once', ->
cnt = 0
t = new Timeline(duration: 32, onStart:-> cnt++).start()
t.update(t.props.startTime + 1); t.update(t.props.startTime + 1)
expect(cnt).toBe 1
it 'should have the right scope', ->
isRightScope = false
t = new Timeline(onStart:-> isRightScope = @ instanceof Timeline)
t.start()
t.update t.props.startTime + 1
expect(isRightScope).toBe true
describe 'onReverseComplete callback ->', ->
it 'should be defined', ->
t = new Timeline onReverseComplete: ->
expect(t.o.onReverseComplete).toBeDefined()
it 'should call onReverseComplete callback', ->
t = new Timeline(
duration: 100
onReverseComplete:->
).start()
spyOn(t.o, 'onReverseComplete')
t.update t.props.startTime + 55
t.update t.props.startTime
expect(t.o.onReverseComplete).toHaveBeenCalled()
it 'should onReverseComplete only once', ->
cnt = 0
t = new Timeline(
duration: 100
onReverseComplete:-> cnt++
).start()
t.update t.props.startTime + 55
t.update t.props.startTime
t.update t.props.startTime - 20
t.update t.props.startTime - 30
expect(cnt).toBe 1
expect(t.isOnReverseComplete).toBe true
it 'should reset isOnReverseComplete flag', ->
cnt = 0
t = new Timeline(
duration: 100
onReverseComplete:-> cnt++
).start()
t.update t.props.startTime + 55
t.update t.props.startTime
t.update t.props.startTime - 20
t.update t.props.startTime - 30
t.update t.props.startTime + 1
expect(t.isOnReverseComplete).toBe false
it 'should reset isOnReverseComplete flag #2', ->
cnt = 0
t = new Timeline(
duration: 100
onReverseComplete:-> cnt++
).start()
t.update t.props.startTime + 55
t.update t.props.startTime
t.update t.props.startTime - 20
t.update t.props.startTime - 30
t.update t.props.endTime
expect(t.isOnReverseComplete).toBe false
it 'should have the right scope', ->
isRightScope = null
t = new Timeline(
duration: 100
onReverseComplete:-> isRightScope = @ instanceof Timeline
).start()
t.update t.props.startTime + 55
t.update t.props.startTime
expect(isRightScope).toBe true
it 'should setProgress to 0 if progress went before startTime', ->
t = new Timeline(
duration: 100
onReverseComplete:->
onUpdate:->
).start()
spyOn(t, 'onUpdate')
t.update t.props.startTime + 55
t.update t.props.startTime - 20
expect(t.onUpdate).toHaveBeenCalledWith 0
expect(t.progress).toBe 0
it 'should not setProgress to 0 if timeline isChained', ->
t = new Timeline(
duration: 100, isChained: true
onReverseComplete:->
onUpdate:->
).start()
spyOn(t, 'onUpdate')
t.update t.props.startTime + 55
t.update t.props.startTime - 20
expect(t.onUpdate).not.toHaveBeenCalledWith 0
expect(t.progress).toBe 0