1 | {MockWindow, MockDocument} = require('../lib/karen')
|
2 |
|
3 | describe 'MockWindow', ->
|
4 | def 'window', -> new MockWindow
|
5 |
|
6 | describe '#top', ->
|
7 | it 'is itself', ->
|
8 | @window.top.should.equal(@window)
|
9 |
|
10 | describe '#console', ->
|
11 | describe '#log', ->
|
12 | it 'emits console-log event', (done) ->
|
13 | @window.on 'console-log', (argument1, argument2) ->
|
14 | done() if argument1 == 'log-1' &&
|
15 | argument2 == 'log-2'
|
16 |
|
17 | @window.console.log('log-1', 'log-2')
|
18 |
|
19 | describe '#postMessage', ->
|
20 | it 'emits message event', ->
|
21 | origin = {}
|
22 | @window.on 'message', (event) ->
|
23 | event.data.should.equal('message')
|
24 | event.origin.should.equal(origin)
|
25 | event.source.should.be.an('object')
|
26 | @window.postMessage('message', origin)
|
27 |
|
28 | describe '#document', ->
|
29 | it 'is a MockDocument', ->
|
30 | @window.document.should.be.an('object')
|
31 |
|
32 | it 'returns same object every time', ->
|
33 | @window.document.should.equal(@window.document)
|
34 |
|
35 | describe '#location', ->
|
36 | it 'returns a MockLocation', ->
|
37 | @window.location.should.be.an('object')
|
38 |
|
39 | it 'returns same object every time', ->
|
40 | @window.location.should.equal(@window.location)
|
41 |
|
42 | describe '#screen', ->
|
43 | it 'returns a MockScreen', ->
|
44 | @window.screen.should.be.an('object')
|
45 |
|
46 | it 'returns same object every time', ->
|
47 | @window.screen.should.equal(@window.screen)
|
48 |
|
49 | describe '#navigator', ->
|
50 | it 'returns a MockNavigator', ->
|
51 | @window.navigator.should.be.an('object')
|
52 |
|
53 | it 'returns same object every time', ->
|
54 | @window.navigator.should.equal(@window.navigator)
|
55 |
|
56 | describe 'encodeURIComponent', ->
|
57 | it 'returns encoded string', ->
|
58 | @window.encodeURIComponent('foo/bar').should.equal('foo%2Fbar')
|
59 |
|
60 | describe 'decodeURIComponent', ->
|
61 | it 'returns decoded string', ->
|
62 | @window.decodeURIComponent('foo%2Fbar').should.equal('foo/bar')
|
63 |
|
64 | describe '#setTimeout', ->
|
65 | it 'runs callback after delay', (done) ->
|
66 | @window.setTimeout(done, 100)
|
67 | @window.tick(100)
|
68 |
|
69 | it 'does not run callback if delay has not passed', (done) ->
|
70 | @window.setTimeout ->
|
71 | done('should not callback function, but did')
|
72 | , 100
|
73 | @window.tick(99)
|
74 | done()
|
75 |
|
76 | it 'runs multiple callbacks', (done) ->
|
77 | count = 0
|
78 | doneCheck = ->
|
79 | done() if (++count) >= 3
|
80 | @window.setTimeout(doneCheck, 50)
|
81 | @window.setTimeout(doneCheck, 100)
|
82 | @window.setTimeout(doneCheck, 150)
|
83 | @window.tick(150)
|
84 |
|
85 | it 'does not run callback when ticking half before', (done) ->
|
86 | @window.tick(50)
|
87 | @window.setTimeout ->
|
88 | done('should not callback, but did')
|
89 | , 100
|
90 | @window.tick(50)
|
91 | done()
|
92 |
|
93 | it 'handles floats', (done) ->
|
94 | @window.setTimeout(done, 123.456)
|
95 | @window.setTimeout ->
|
96 | done('should not call this, but did')
|
97 | , 125
|
98 | @window.tick(123)
|
99 | @window.tick(1.999)
|
100 |
|
101 | it 'runs timeouts in correct order', (done) ->
|
102 | order = []
|
103 |
|
104 | @window.setTimeout =>
|
105 | order.push(1)
|
106 |
|
107 | @window.setTimeout ->
|
108 | order.push(2)
|
109 | , 100
|
110 | , 100
|
111 |
|
112 | @window.setTimeout ->
|
113 | order.push(3)
|
114 | , 300
|
115 |
|
116 | @window.tick 300, ->
|
117 | expect(order).to.eql([1, 2, 3])
|
118 | done()
|
119 |
|
120 | it 'supports nested timeouts', (done) ->
|
121 | @window.setTimeout =>
|
122 | @window.setTimeout(done, 100)
|
123 | , 100
|
124 | @window.tick(200)
|
125 |
|
126 | it 'is called async if callback', (done) ->
|
127 | called = false
|
128 | @window.setTimeout ->
|
129 | called = true
|
130 | done()
|
131 | , 100
|
132 | @window.tick 50, ->
|
133 | @window.tick 50, ->
|
134 | expect(called).to.be.false
|
135 |
|
136 | it 'is not called async unless callback', (done) ->
|
137 | called = false
|
138 | @window.setTimeout ->
|
139 | called = true
|
140 | done()
|
141 | , 100
|
142 | @window.tick(50)
|
143 | @window.tick(50)
|
144 | expect(called).to.be.true
|
145 |
|
146 | describe '#clearTimeout', ->
|
147 | it 'does nothing when given a non timeout object', ->
|
148 | @window.clearTimeout({})
|
149 |
|
150 | it 'does not run timeout if cleared', (done) ->
|
151 | timeout = @window.setTimeout ->
|
152 | done('should not callback, but did')
|
153 | , 100
|
154 | @window.clearTimeout(timeout)
|
155 | @window.tick(100)
|
156 | done()
|
157 |
|
158 | describe '#setInterval', ->
|
159 | it 'runs callback after delay', (done) ->
|
160 | @window.setInterval(done, 100)
|
161 | @window.tick(100)
|
162 |
|
163 | it 'runs callback after every delay', (done) ->
|
164 | count = 0
|
165 | doneCheck = -> done() if (++count) >= 3
|
166 | @window.setInterval(doneCheck, 100)
|
167 | @window.tick(300)
|
168 |
|
169 | it 'does not run callback if delay has not passed', (done) ->
|
170 | @window.setInterval ->
|
171 | done('should not callback function, but did')
|
172 | , 100
|
173 | @window.tick(99)
|
174 | done()
|
175 |
|
176 | it 'runs multiple callbacks', (done) ->
|
177 | count = 0
|
178 | doneCheck = ->
|
179 | done() if (++count) >= 3
|
180 | @window.setInterval(doneCheck, 50)
|
181 | @window.setInterval(doneCheck, 100)
|
182 | @window.tick(100)
|
183 |
|
184 | it 'does not run callback when ticking half before', (done) ->
|
185 | @window.tick(50)
|
186 | @window.setInterval ->
|
187 | done('should not callback, but did')
|
188 | , 100
|
189 | @window.tick(50)
|
190 | done()
|
191 |
|
192 | it 'handles floats', (done) ->
|
193 | count = 0
|
194 | doneCheck = -> done() if (++count) >= 2
|
195 | @window.setInterval(doneCheck, 123.456)
|
196 | @window.setInterval ->
|
197 | done('should not call this, but did')
|
198 | , 249
|
199 | @window.tick(247)
|
200 | @window.tick(1.999)
|
201 |
|
202 | it 'runs intervals in correct order', (done) ->
|
203 | order = []
|
204 |
|
205 | @window.setInterval =>
|
206 | order.push(1)
|
207 |
|
208 | @window.setInterval ->
|
209 | order.push(2)
|
210 | , 100
|
211 | , 100
|
212 |
|
213 | @window.setInterval ->
|
214 | order.push(3)
|
215 | , 300
|
216 |
|
217 | @window.tick 300, ->
|
218 | expect(order).to.eql([1, 1, 2, 1, 3, 2, 2])
|
219 | done()
|
220 |
|
221 | it 'supports nested intervals', (done) ->
|
222 | @window.setInterval =>
|
223 | @window.setInterval(done, 100)
|
224 | , 100
|
225 | @window.tick(200)
|
226 |
|
227 | describe '#clearInterval', ->
|
228 | it 'does nothing when given a non timeout object', ->
|
229 | @window.clearInterval({})
|
230 |
|
231 | it 'does not run interval once cleared', (done) ->
|
232 | count = 0
|
233 | doneCheck = -> done() if (++count) >= 2
|
234 | interval = @window.setInterval(doneCheck, 100)
|
235 | @window.tick(100)
|
236 | @window.tick(100)
|
237 | @window.clearInterval(interval)
|
238 | @window.tick(100)
|
239 |
|
240 | describe '#tick', ->
|
241 | it 'callbacks when done', (done) ->
|
242 | aDone = false
|
243 | bDone = false
|
244 | cDone = false
|
245 |
|
246 | @window.setTimeout ->
|
247 | aDone = true
|
248 | , 100
|
249 |
|
250 | @window.setTimeout ->
|
251 | bDone = true
|
252 | , 200
|
253 |
|
254 | @window.setTimeout ->
|
255 | cDone = true
|
256 | , 300
|
257 |
|
258 | @window.tick 300, ->
|
259 | done() if aDone && bDone && cDone
|
260 |
|
261 | describe '#tickAsync', ->
|
262 | it 'is called async', (done) ->
|
263 | called = false
|
264 | @window.setTimeout ->
|
265 | called = true
|
266 | done()
|
267 | , 100
|
268 | @window.tickAsync(50)
|
269 | @window.tickAsync(50)
|
270 | expect(called).to.be.false
|
271 |
|
272 | it 'is callbacks', (done) ->
|
273 | fn = ->
|
274 | @window.setTimeout(fn, 100)
|
275 | @window.tickAsync(50, done)
|
276 |
|
277 | describe '#setImmediate', ->
|
278 | it 'callbacks', (done) ->
|
279 | @window.setImmediate (foo, bar) ->
|
280 | expect(foo).to.equal('foo')
|
281 | expect(bar).to.equal('bar')
|
282 | done()
|
283 | , 'foo', 'bar'
|