1 | define([ |
---|
2 | "../_base/array", |
---|
3 | "../hash", |
---|
4 | "../router/RouterBase", |
---|
5 | "doh" |
---|
6 | ], function(arrayUtil, hash, RouterBase, doh){ |
---|
7 | // This test uses RouterBase so that I can test a few different behaviors of the router |
---|
8 | // which require re-initializing a new router |
---|
9 | var count = 0, |
---|
10 | router = new RouterBase(), |
---|
11 | handle, foo; |
---|
12 | |
---|
13 | // Simple helper to make tearDown simpler |
---|
14 | function removeAll(handles) { |
---|
15 | arrayUtil.forEach(handles, function(handle){ |
---|
16 | handle.remove(); |
---|
17 | }); |
---|
18 | } |
---|
19 | |
---|
20 | doh.register("tests.router", [ |
---|
21 | { |
---|
22 | name: "Router API", |
---|
23 | setUp: function(t){ |
---|
24 | // Reset the hash to make sure we get a clean test |
---|
25 | hash("", true); |
---|
26 | }, |
---|
27 | runTest: function(t){ |
---|
28 | t.t(router.register, "Router has a register"); |
---|
29 | t.t(router.go, "Router has a go"); |
---|
30 | t.t(router.startup, "Router has a startup"); |
---|
31 | t.t(router.destroy, "Router has a destroy"); |
---|
32 | } |
---|
33 | }, |
---|
34 | { |
---|
35 | name: "Registering a route by string", |
---|
36 | runTest: function(t){ |
---|
37 | handle = router.register("/foo", function(){ |
---|
38 | count++; |
---|
39 | console.log("/foo fired! New count:", count); |
---|
40 | }); |
---|
41 | |
---|
42 | // Make sure it looks right |
---|
43 | t.t(handle.remove, "Handle has a remove"); |
---|
44 | t.t(handle.register, "Handle has a register"); |
---|
45 | } |
---|
46 | }, |
---|
47 | { |
---|
48 | name: "Ensuring routes don't fire before startup", |
---|
49 | setUp: function(){ |
---|
50 | count = 0; |
---|
51 | }, |
---|
52 | runTest: function(t){ |
---|
53 | hash("/foo"); |
---|
54 | t.t(count === 0, "Count should have been 0, was " + count); |
---|
55 | } |
---|
56 | }, |
---|
57 | { |
---|
58 | name: "Ensuring routes do fire after startup", |
---|
59 | runTest: function(t){ |
---|
60 | router.startup(); |
---|
61 | t.t(count === 1, "Count should have been 1, was " + count); |
---|
62 | } |
---|
63 | }, |
---|
64 | { |
---|
65 | name: "Ensuring that hash changes fire routes", |
---|
66 | runTest: function(t){ |
---|
67 | // Due to the nature of the hashchange event, |
---|
68 | // this test is going to be async - but we have to nest it, |
---|
69 | // sadly. |
---|
70 | |
---|
71 | var d = new doh.Deferred(); |
---|
72 | |
---|
73 | // Reset the hash |
---|
74 | hash(""); |
---|
75 | |
---|
76 | setTimeout(function(){ |
---|
77 | // As soon as possible, set it back to our test... |
---|
78 | hash("/foo"); |
---|
79 | console.log("Setting hash"); |
---|
80 | |
---|
81 | // ... and then check to make sure the events fired |
---|
82 | setTimeout(d.getTestCallback(function(){ |
---|
83 | console.log("Checking count, current hash:", hash()); |
---|
84 | t.t(count === 2, "Count should have been 2, was " + count); |
---|
85 | }), 50); |
---|
86 | }, 0); |
---|
87 | |
---|
88 | return d; |
---|
89 | } |
---|
90 | }, |
---|
91 | { |
---|
92 | name: "Ensuring that router.go fires changes", |
---|
93 | runTest: function(t){ |
---|
94 | var d = new doh.Deferred(); |
---|
95 | |
---|
96 | // Since router.go fires off routes immediately, this should |
---|
97 | // kick off changes! |
---|
98 | router.go(""); |
---|
99 | router.go("/foo"); |
---|
100 | |
---|
101 | t.t(count === 3, "Count should have been 3, was " + count); |
---|
102 | } |
---|
103 | }, |
---|
104 | { |
---|
105 | name: "Ensuring route doesn't fire after removal", |
---|
106 | runTest: function(t){ |
---|
107 | handle.remove(); |
---|
108 | router.go(""); |
---|
109 | router.go("/foo"); |
---|
110 | |
---|
111 | t.t(count === 3, "Count should have been 3, was " + count); |
---|
112 | } |
---|
113 | }, |
---|
114 | { |
---|
115 | name: "Registering a route by regexp", |
---|
116 | runTest: function(t){ |
---|
117 | handle = router.register(/^\/bar$/, function(){ |
---|
118 | count++; |
---|
119 | }); |
---|
120 | router.go("/bar"); |
---|
121 | |
---|
122 | t.t(count === 4, "Count should have been 4, was " + count); |
---|
123 | }, |
---|
124 | tearDown: function(){ |
---|
125 | handle.remove(); |
---|
126 | } |
---|
127 | }, |
---|
128 | { |
---|
129 | name: "Checking event object", |
---|
130 | runTest: function(t){ |
---|
131 | var oldPath, newPath, params, stopImmediatePropagation, preventDefault; |
---|
132 | |
---|
133 | router.go(""); |
---|
134 | |
---|
135 | handle = router.register("/checkEventObject/:foo", function(event){ |
---|
136 | oldPath = event.oldPath; |
---|
137 | newPath = event.newPath; |
---|
138 | params = event.params; |
---|
139 | stopImmediatePropagation = typeof event.stopImmediatePropagation; |
---|
140 | preventDefault = typeof event.preventDefault; |
---|
141 | }); |
---|
142 | |
---|
143 | router.go("/checkEventObject/bar"); |
---|
144 | |
---|
145 | t.t(oldPath === "", "oldPath should be empty string, was " + oldPath); |
---|
146 | t.t(newPath === "/checkEventObject/bar", "newPath should be '/checkEventObject/bar', was " + newPath); |
---|
147 | t.t(params, "params should be a truthy value, was " + params); |
---|
148 | t.t(params.hasOwnProperty("foo"), "params should have a .foo property"); |
---|
149 | t.t(params.foo === "bar", "params.foo should be bar, was " + params.foo); |
---|
150 | t.t(stopImmediatePropagation === "function", "stopImmediatePropagation should be a function, was " + stopImmediatePropagation); |
---|
151 | t.t(preventDefault === "function", "preventDefault should be a function, was " + preventDefault); |
---|
152 | }, |
---|
153 | tearDown: function(){ |
---|
154 | handle.remove(); |
---|
155 | } |
---|
156 | }, |
---|
157 | { |
---|
158 | name: "Checking extra arguments - string route", |
---|
159 | runTest: function(t){ |
---|
160 | var a, b; |
---|
161 | |
---|
162 | handle = router.register("/stringtest/:applied/:arg", function(event, applied, arg){ |
---|
163 | a = applied; |
---|
164 | b = arg; |
---|
165 | }); |
---|
166 | |
---|
167 | router.go("/stringtest/extra/args"); |
---|
168 | |
---|
169 | t.t(a === "extra", "a should have been 'extra', was " + a); |
---|
170 | t.t(b === "args", "b should have been 'args', was " + b); |
---|
171 | }, |
---|
172 | tearDown: function(){ |
---|
173 | handle.remove(); |
---|
174 | } |
---|
175 | }, |
---|
176 | { |
---|
177 | name: "Checking extra arguments - regex route", |
---|
178 | runTest: function(t){ |
---|
179 | var a, b; |
---|
180 | |
---|
181 | handle = router.register(/\/regextest\/(\w+)\/(\w+)/, function(event, applied, arg){ |
---|
182 | a = applied; |
---|
183 | b = arg; |
---|
184 | }); |
---|
185 | |
---|
186 | router.go("/regextest/extra/args"); |
---|
187 | |
---|
188 | t.t(a === "extra", "a should have been 'extra', was " + a); |
---|
189 | t.t(b === "args", "b should have been 'args', was " + b); |
---|
190 | }, |
---|
191 | tearDown: function(){ |
---|
192 | handle.remove(); |
---|
193 | } |
---|
194 | }, |
---|
195 | { |
---|
196 | name: "Registering long routes with placeholders", |
---|
197 | runTest: function(t){ |
---|
198 | var testObject; |
---|
199 | |
---|
200 | handle = router.register("/path/:to/:some/:long/*thing", function(event){ |
---|
201 | testObject = event.params; |
---|
202 | }); |
---|
203 | |
---|
204 | router.go("/path/to/some/long/thing/this/is/in/splat"); |
---|
205 | |
---|
206 | t.t(testObject instanceof Object, "testObject should have been an object, but wasn't"); |
---|
207 | t.t(testObject.to === "to", "testObject.to should have been 'to', was " + testObject.to); |
---|
208 | t.t(testObject.some === "some", "testObject.some should have been 'some', was " + testObject.some); |
---|
209 | t.t(testObject["long"] === "long", "testObject.long should have been 'long', was " + testObject["long"]); |
---|
210 | t.t(testObject.thing === "thing/this/is/in/splat", "testObject.thing should have been 'thing/this/is/in/splat', was " + testObject.thing); |
---|
211 | |
---|
212 | testObject = null; |
---|
213 | |
---|
214 | router.go("/path/1/2/3/4/5/6"); |
---|
215 | |
---|
216 | t.t(testObject instanceof Object, "testObject should have been an object, but wasn't"); |
---|
217 | t.t(testObject.to === "1", "testObject.to should have been '1', was " + testObject.to); |
---|
218 | t.t(testObject.some === "2", "testObject.some should have been '2', was " + testObject.some); |
---|
219 | t.t(testObject["long"] === "3", "testObject.long should have been '3', was " + testObject["long"]); |
---|
220 | t.t(testObject.thing === "4/5/6", "testObject.thing should have been '4/5/6', was " + testObject.thing); |
---|
221 | }, |
---|
222 | tearDown: function(){ |
---|
223 | handle.remove(); |
---|
224 | } |
---|
225 | }, |
---|
226 | { |
---|
227 | name: "Using capture groups in a regex route", |
---|
228 | runTest: function(t){ |
---|
229 | var testObject; |
---|
230 | |
---|
231 | handle = router.register(/^\/path\/(\w+)\/(\d+)$/, function(event){ |
---|
232 | testObject = event.params; |
---|
233 | }); |
---|
234 | |
---|
235 | router.go("/path/abcdef/1234"); |
---|
236 | |
---|
237 | t.t(testObject instanceof Array, "testObject should have been an array, but wasn't"); |
---|
238 | t.t(testObject[0] === "abcdef", "testObject[0] should have been 'abcdef', was " + testObject[0]); |
---|
239 | t.t(testObject[1] === "1234", "testObject[1] should have been '1234', was " + testObject[1]); |
---|
240 | |
---|
241 | testObject = null; |
---|
242 | |
---|
243 | router.go("/path/abc/def"); |
---|
244 | |
---|
245 | t.t(testObject === null, "testObject should have been null, but wasn't"); |
---|
246 | |
---|
247 | router.go("/path/abc123/456def"); |
---|
248 | |
---|
249 | t.t(testObject === null, "testObject should have been null, but wasn't"); |
---|
250 | |
---|
251 | router.go("/path/abc123/456"); |
---|
252 | |
---|
253 | t.t(testObject instanceof Array, "testObject should have been an array, but wasn't"); |
---|
254 | t.t(testObject[0] === "abc123", "testObject[0] should have been 'abc123', was " + testObject[0]); |
---|
255 | t.t(testObject[1] === "456", "testObject[1] should have been '456', was " + testObject[1]); |
---|
256 | }, |
---|
257 | tearDown: function(){ |
---|
258 | handle.remove(); |
---|
259 | } |
---|
260 | }, |
---|
261 | { |
---|
262 | name: "Testing registerBefore", |
---|
263 | runTest: function(t){ |
---|
264 | var test = ""; |
---|
265 | |
---|
266 | handle = []; |
---|
267 | |
---|
268 | handle.push(router.register("/isBefore", function(){ |
---|
269 | test += "1"; |
---|
270 | })); |
---|
271 | |
---|
272 | handle.push(router.registerBefore("/isBefore", function(){ |
---|
273 | test += "2"; |
---|
274 | })); |
---|
275 | |
---|
276 | handle.push(router.register("/isBefore", function(){ |
---|
277 | test += "3"; |
---|
278 | })); |
---|
279 | |
---|
280 | handle.push(router.registerBefore("/isBefore", function(){ |
---|
281 | test += "4"; |
---|
282 | })); |
---|
283 | |
---|
284 | handle.push(router.register("/isBefore", function(){ |
---|
285 | test += "5"; |
---|
286 | })); |
---|
287 | |
---|
288 | router.go("/isBefore"); |
---|
289 | |
---|
290 | t.t(test === "42135", "test should have been '42135', was " + test); |
---|
291 | }, |
---|
292 | tearDown: function(){ |
---|
293 | removeAll(handle); |
---|
294 | } |
---|
295 | }, |
---|
296 | { |
---|
297 | name: "Stopping propagation", |
---|
298 | runTest: function(t){ |
---|
299 | var test = ""; |
---|
300 | |
---|
301 | handle = []; |
---|
302 | |
---|
303 | handle.push(router.register("/stopImmediatePropagation", function(){ test += "A"; })); |
---|
304 | handle.push(router.register("/stopImmediatePropagation", function(){ test += "B"; })); |
---|
305 | |
---|
306 | handle.push(router.register("/stopImmediatePropagation", function(event){ |
---|
307 | event.stopImmediatePropagation(); |
---|
308 | test += "C"; |
---|
309 | })); |
---|
310 | |
---|
311 | handle.push(router.register("/stopImmediatePropagation", function(){ test += "D"; })); |
---|
312 | handle.push(router.register("/stopImmediatePropagation", function(){ test += "E"; })); |
---|
313 | |
---|
314 | router.go("/stopImmediatePropagation"); |
---|
315 | |
---|
316 | t.t(test === "ABC", "test should have been 'ABC', was " + test); |
---|
317 | }, |
---|
318 | tearDown: function(){ |
---|
319 | removeAll(handle); |
---|
320 | } |
---|
321 | }, |
---|
322 | { |
---|
323 | name: "Preventing default (change)", |
---|
324 | runTest: function(t){ |
---|
325 | var prevented = false, goResult; |
---|
326 | |
---|
327 | hash(""); |
---|
328 | |
---|
329 | t.t(hash() === "", "hash should be empty"); |
---|
330 | |
---|
331 | handle.push(router.register("/preventDefault", function(event){ |
---|
332 | event.preventDefault(); |
---|
333 | })); |
---|
334 | |
---|
335 | goResult = router.go("/preventDefault"); |
---|
336 | |
---|
337 | t.t(hash() === "", "hash should still be empty"); |
---|
338 | t.t(goResult === false, "goResult should be false"); |
---|
339 | |
---|
340 | goResult = router.go("/someOtherPath"); |
---|
341 | |
---|
342 | t.t(hash() === "/someOtherPath", "hash should be '/someOtherPath'"); |
---|
343 | t.t(goResult === true, "goResult should be true"); |
---|
344 | |
---|
345 | handle.push(router.register("/allowDefault", function(event){ |
---|
346 | console.log("Doing something here without explicitly stopping"); |
---|
347 | })); |
---|
348 | }, |
---|
349 | tearDown: function(){ |
---|
350 | removeAll(handle); |
---|
351 | } |
---|
352 | }, |
---|
353 | { |
---|
354 | name: "Default router path", |
---|
355 | setUp: function(){ |
---|
356 | // Set up a new router for use in this test |
---|
357 | router.destroy(); |
---|
358 | router = new RouterBase(); |
---|
359 | |
---|
360 | // Start with a clean hash |
---|
361 | hash(""); |
---|
362 | }, |
---|
363 | runTest: function(t){ |
---|
364 | var routeHit = false; |
---|
365 | |
---|
366 | handle = router.register("/default", function(event){ |
---|
367 | routeHit = true; |
---|
368 | }); |
---|
369 | |
---|
370 | router.startup("/default"); |
---|
371 | |
---|
372 | t.t(routeHit, "Our route was not hit, but should have been"); |
---|
373 | }, |
---|
374 | tearDown: function(){ |
---|
375 | handle.remove(); |
---|
376 | } |
---|
377 | } |
---|
378 | ]); |
---|
379 | }); |
---|