unpoly-rails 0.37.0 → 0.50.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +127 -25
  3. data/LICENSE +1 -1
  4. data/README_RAILS.md +4 -2
  5. data/Rakefile +6 -1
  6. data/dist/unpoly.js +3192 -2198
  7. data/dist/unpoly.min.js +4 -3
  8. data/lib/assets/javascripts/unpoly/browser.coffee +51 -63
  9. data/lib/assets/javascripts/unpoly/bus.coffee +58 -33
  10. data/lib/assets/javascripts/unpoly/classes/cache.coffee +117 -0
  11. data/lib/assets/javascripts/unpoly/{dom → classes}/extract_cascade.coffee +3 -3
  12. data/lib/assets/javascripts/unpoly/{dom → classes}/extract_plan.coffee +1 -1
  13. data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +57 -0
  14. data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +52 -0
  15. data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +95 -0
  16. data/lib/assets/javascripts/unpoly/classes/record.coffee +16 -0
  17. data/lib/assets/javascripts/unpoly/classes/request.coffee +228 -0
  18. data/lib/assets/javascripts/unpoly/classes/response.coffee +138 -0
  19. data/lib/assets/javascripts/unpoly/dom.coffee +151 -142
  20. data/lib/assets/javascripts/unpoly/feedback.coffee +67 -38
  21. data/lib/assets/javascripts/unpoly/form.coffee +156 -139
  22. data/lib/assets/javascripts/unpoly/history.coffee +22 -19
  23. data/lib/assets/javascripts/unpoly/layout.coffee +108 -90
  24. data/lib/assets/javascripts/unpoly/link.coffee +159 -158
  25. data/lib/assets/javascripts/unpoly/log.coffee +5 -5
  26. data/lib/assets/javascripts/unpoly/modal.coffee +93 -81
  27. data/lib/assets/javascripts/unpoly/motion.coffee +291 -250
  28. data/lib/assets/javascripts/unpoly/popup.coffee +67 -53
  29. data/lib/assets/javascripts/unpoly/protocol.coffee +67 -16
  30. data/lib/assets/javascripts/unpoly/proxy.coffee +282 -211
  31. data/lib/assets/javascripts/unpoly/rails.coffee +3 -14
  32. data/lib/assets/javascripts/unpoly/syntax.coffee +54 -49
  33. data/lib/assets/javascripts/unpoly/tooltip.coffee +18 -25
  34. data/lib/assets/javascripts/unpoly/util.coffee +236 -477
  35. data/lib/assets/javascripts/unpoly.coffee +1 -1
  36. data/lib/unpoly/rails/inspector.rb +67 -22
  37. data/lib/unpoly/rails/version.rb +1 -1
  38. data/package.json +1 -1
  39. data/spec_app/Gemfile.lock +13 -13
  40. data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
  41. data/spec_app/app/assets/javascripts/jasmine_specs.coffee +1 -1
  42. data/spec_app/app/assets/stylesheets/jasmine_specs.sass +10 -0
  43. data/spec_app/app/controllers/binding_test_controller.rb +19 -2
  44. data/spec_app/app/controllers/method_test_controller.rb +16 -0
  45. data/spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb +20 -0
  46. data/spec_app/app/views/method_test/form_target.erb +17 -0
  47. data/spec_app/app/views/method_test/page1.erb +11 -0
  48. data/spec_app/app/views/method_test/page2.erb +6 -0
  49. data/spec_app/app/views/pages/start.erb +33 -19
  50. data/spec_app/config/initializers/assets.rb +5 -0
  51. data/spec_app/config/routes.rb +3 -0
  52. data/spec_app/spec/controllers/binding_test_controller_spec.rb +82 -27
  53. data/spec_app/spec/javascripts/helpers/agent_detector.coffee +17 -0
  54. data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +102 -0
  55. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +1 -1
  56. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +5 -2
  57. data/spec_app/spec/javascripts/helpers/promise_state.js +18 -0
  58. data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +9 -0
  59. data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +22 -0
  60. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +11 -3
  61. data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +10 -0
  62. data/spec_app/spec/javascripts/helpers/to_be_error.coffee +5 -0
  63. data/spec_app/spec/javascripts/helpers/to_match_url.coffee +13 -0
  64. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +13 -6
  65. data/spec_app/spec/javascripts/up/browser_spec.js.coffee +92 -33
  66. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +64 -15
  67. data/spec_app/spec/javascripts/up/classes/.keep +0 -0
  68. data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +1 -0
  69. data/spec_app/spec/javascripts/up/dom_spec.js.coffee +759 -551
  70. data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +155 -82
  71. data/spec_app/spec/javascripts/up/form_spec.js.coffee +490 -349
  72. data/spec_app/spec/javascripts/up/history_spec.js.coffee +226 -179
  73. data/spec_app/spec/javascripts/up/layout_spec.js.coffee +253 -185
  74. data/spec_app/spec/javascripts/up/link_spec.js.coffee +416 -270
  75. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +459 -330
  76. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +198 -153
  77. data/spec_app/spec/javascripts/up/namespace_spec.js.coffee +9 -0
  78. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +240 -175
  79. data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +38 -0
  80. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +777 -303
  81. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +24 -8
  82. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +40 -23
  83. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +80 -66
  84. data/spec_app/spec/javascripts/up/util_spec.js.coffee +227 -201
  85. data/spec_app/vendor/asset-libs/es6-promise-4.1.6/es6-promise.auto.js +1159 -0
  86. metadata +30 -7
  87. data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +0 -7
  88. data/spec_app/spec/javascripts/helpers/to_equal_url.coffee +0 -11
@@ -1,6 +1,9 @@
1
1
  describe 'up.history', ->
2
2
 
3
3
  u = up.util
4
+
5
+ beforeEach ->
6
+ up.history.config.enabled = true
4
7
 
5
8
  describe 'JavaScript functions', ->
6
9
 
@@ -10,37 +13,41 @@ describe 'up.history', ->
10
13
 
11
14
  describe 'up.history.url', ->
12
15
 
13
- it 'does not strip a trailing slash from the current URL', ->
14
- history.replaceState?({}, 'title', '/host/path/')
15
- expect(up.history.url()).toEqualUrl('/host/path/')
16
+ describeCapability 'canPushState', ->
17
+
18
+ it 'does not strip a trailing slash from the current URL', ->
19
+ history.replaceState?({}, 'title', '/host/path/')
20
+ expect(up.history.url()).toMatchUrl('/host/path/')
16
21
 
17
22
  describe 'up.history.isUrl', ->
18
23
 
19
- it 'returns true if the given path is the current URL', ->
20
- history.replaceState?({}, 'title', '/host/path/')
21
- expect(up.history.isUrl('/host/path/')).toBe(true)
24
+ describeCapability 'canPushState', ->
22
25
 
23
- it 'returns false if the given path is not the current URL', ->
24
- history.replaceState?({}, 'title', '/host/path/')
25
- expect(up.history.isUrl('/host/other-path/')).toBe(false)
26
+ it 'returns true if the given path is the current URL', ->
27
+ history.replaceState?({}, 'title', '/host/path/')
28
+ expect(up.history.isUrl('/host/path/')).toBe(true)
26
29
 
27
- it 'returns true if the given full URL is the current URL', ->
28
- history.replaceState?({}, 'title', '/host/path/')
29
- expect(up.history.isUrl("http://#{location.host}/host/path/")).toBe(true)
30
+ it 'returns false if the given path is not the current URL', ->
31
+ history.replaceState?({}, 'title', '/host/path/')
32
+ expect(up.history.isUrl('/host/other-path/')).toBe(false)
30
33
 
31
- it 'returns true if the given path is the current URL, but without a trailing slash', ->
32
- history.replaceState?({}, 'title', '/host/path/')
33
- expect(up.history.isUrl('/host/path')).toBe(true)
34
+ it 'returns true if the given full URL is the current URL', ->
35
+ history.replaceState?({}, 'title', '/host/path/')
36
+ expect(up.history.isUrl("http://#{location.host}/host/path/")).toBe(true)
34
37
 
35
- it 'returns true if the given path is the current URL, but with a trailing slash', ->
36
- history.replaceState?({}, 'title', '/host/path')
37
- expect(up.history.isUrl('/host/path/')).toBe(true)
38
+ it 'returns true if the given path is the current URL, but without a trailing slash', ->
39
+ history.replaceState?({}, 'title', '/host/path/')
40
+ expect(up.history.isUrl('/host/path')).toBe(true)
41
+
42
+ it 'returns true if the given path is the current URL, but with a trailing slash', ->
43
+ history.replaceState?({}, 'title', '/host/path')
44
+ expect(up.history.isUrl('/host/path/')).toBe(true)
38
45
 
39
46
  describe 'unobtrusive behavior', ->
40
47
 
41
48
  describe 'back button', ->
42
49
 
43
- it 'calls destructor functions when destroying compiled elements (bugfix)', (done) ->
50
+ it 'calls destructor functions when destroying compiled elements (bugfix)', asyncSpec (next) ->
44
51
  waitForBrowser = 70
45
52
 
46
53
  # By default, up.history will replace the <body> tag when
@@ -65,227 +72,267 @@ describe 'up.history', ->
65
72
  expect(constructorSpy).toHaveBeenCalled()
66
73
 
67
74
  history.back()
68
- u.setTimer waitForBrowser, =>
69
- expect(location.pathname).toEqual('/one')
70
75
 
76
+ next.after waitForBrowser, =>
77
+ expect(location.pathname).toEqual('/one')
71
78
  @respondWith "<div class='container'>restored container text</div>"
72
79
 
73
- u.nextFrame ->
74
- expect(destructorSpy).toHaveBeenCalled()
75
- done()
80
+ next =>
81
+ expect(destructorSpy).toHaveBeenCalled()
76
82
 
77
83
 
78
84
  describe '[up-back]', ->
79
85
 
80
- it 'sets an [up-href] attribute to the previous URL and sets the up-restore-scroll attribute to "true"', ->
81
- up.history.push('/one')
82
- up.history.push('/two')
83
- $element = up.hello(affix('a[href="/three"][up-back]').text('text'))
84
- expect($element.attr('href')).toEqualUrl('/three')
85
- expect($element.attr('up-href')).toEqualUrl('/one')
86
- expect($element.attr('up-restore-scroll')).toBe('')
87
- expect($element.attr('up-follow')).toBe('')
86
+ describeCapability 'canPushState', ->
87
+
88
+ it 'sets an [up-href] attribute to the previous URL and sets the up-restore-scroll attribute to "true"', ->
89
+ up.history.push('/path1')
90
+ up.history.push('/path2')
91
+ $element = up.hello(affix('a[href="/path3"][up-back]').text('text'))
92
+ expect($element.attr('href')).toMatchUrl('/path3')
93
+ expect($element.attr('up-href')).toMatchUrl('/path1')
94
+ expect($element.attr('up-restore-scroll')).toBe('')
95
+ expect($element.attr('up-follow')).toBe('')
88
96
 
89
97
  it 'does not overwrite an existing up-href or up-restore-scroll attribute'
90
98
 
91
99
  it 'does not set an up-href attribute if there is no previous URL'
92
100
 
101
+ describeFallback 'canPushState', ->
102
+
103
+ it 'does not change the element', ->
104
+ $element = up.hello(affix('a[href="/three"][up-back]').text('text'))
105
+ expect($element.attr('up-href')).toBeUndefined()
106
+
93
107
  describe 'scroll restoration', ->
94
108
 
95
- afterEach ->
96
- $('.viewport').remove()
109
+ describeCapability 'canPushState', ->
97
110
 
98
- it 'restores the scroll position of viewports when the user hits the back button', (done) ->
111
+ afterEach ->
112
+ $('.viewport').remove()
99
113
 
100
- longContentHtml = """
101
- <div class="viewport" style="width: 100px; height: 100px; overflow-y: scroll">
102
- <div class="content" style="height: 1000px"></div>
103
- </div>
104
- """
114
+ it 'restores the scroll position of viewports when the user hits the back button', asyncSpec (next) ->
115
+
116
+ longContentHtml = """
117
+ <div class="viewport" style="width: 100px; height: 100px; overflow-y: scroll">
118
+ <div class="content" style="height: 1000px"></div>
119
+ </div>
120
+ """
105
121
 
106
- respond = => @respondWith(longContentHtml)
122
+ respond = => @respondWith(longContentHtml)
107
123
 
108
- $viewport = $(longContentHtml).appendTo(document.body)
124
+ $viewport = $(longContentHtml).appendTo(document.body)
109
125
 
110
- up.layout.config.viewports = ['.viewport']
111
- up.history.config.popTargets = ['.viewport']
126
+ up.layout.config.viewports = ['.viewport']
127
+ up.history.config.popTargets = ['.viewport']
112
128
 
113
- up.replace('.content', '/one')
114
- respond()
129
+ up.replace('.content', '/one')
115
130
 
116
- $viewport.scrollTop(50)
131
+ next =>
132
+ respond()
117
133
 
118
- up.replace('.content', '/two')
119
- respond()
134
+ next =>
135
+ $viewport.scrollTop(50)
136
+ up.replace('.content', '/two')
120
137
 
121
- $('.viewport').scrollTop(150)
138
+ next =>
139
+ respond()
122
140
 
123
- up.replace('.content', '/three')
124
- respond()
125
- $('.viewport').scrollTop(250)
141
+ next =>
142
+ $('.viewport').scrollTop(150)
143
+ up.replace('.content', '/three')
126
144
 
127
- history.back()
128
- u.setTimer 50, ->
129
- respond() # we need to respond since we've never requested /two with the popTarget
130
- expect($('.viewport').scrollTop()).toBe(150)
145
+ next =>
146
+ respond()
131
147
 
132
- history.back()
133
- u.setTimer 50, ->
148
+ next =>
149
+ $('.viewport').scrollTop(250)
150
+ history.back()
151
+
152
+ next.after 50, =>
153
+ respond() # we need to respond since we've never requested /two with the popTarget
154
+
155
+ next =>
156
+ expect($('.viewport').scrollTop()).toBe(150)
157
+ history.back()
158
+
159
+ next.after 50, =>
134
160
  respond() # we need to respond since we've never requested /one with the popTarget
161
+
162
+ next =>
135
163
  expect($('.viewport').scrollTop()).toBe(50)
164
+ history.forward()
136
165
 
166
+ next.after 50, =>
167
+ # No need to respond since we requested /two with the popTarget
168
+ # when we went backwards
169
+ expect($('.viewport').scrollTop()).toBe(150)
137
170
  history.forward()
138
- u.setTimer 50, ->
139
- # No need to respond since we requested /two with the popTarget
140
- # when we went backwards
141
- expect($('.viewport').scrollTop()).toBe(150)
142
-
143
- history.forward()
144
- u.setTimer 50, ->
145
- respond() # we need to respond since we've never requested /three with the popTarget
146
- expect($('.viewport').scrollTop()).toBe(250)
147
- done()
148
-
149
- it 'restores the scroll position of two viewports marked with [up-viewport], but not configured in up.layout.config (bugfix)', (done) ->
150
- up.history.config.popTargets = ['.container']
151
171
 
152
- html = """
153
- <div class="container">
154
- <div class="viewport1" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
155
- <div class="content1" style="height: 5000px">content1</div>
156
- </div>
157
- <div class="viewport2" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
158
- <div class="content2" style="height: 5000px">content2</div>
159
- </div>
160
- </div>
161
- """
172
+ next.after 50, =>
173
+ respond() # we need to respond since we've never requested /three with the popTarget
162
174
 
163
- respond = => @respondWith(html)
175
+ next =>
176
+ expect($('.viewport').scrollTop()).toBe(250)
164
177
 
165
- $screen = affix('.screen')
166
- $screen.html(html)
178
+ it 'restores the scroll position of two viewports marked with [up-viewport], but not configured in up.layout.config (bugfix)', asyncSpec (next) ->
179
+ up.history.config.popTargets = ['.container']
167
180
 
168
- up.replace('.content1, .content2', '/one', reveal: false)
169
- respond()
181
+ html = """
182
+ <div class="container">
183
+ <div class="viewport1" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
184
+ <div class="content1" style="height: 5000px">content1</div>
185
+ </div>
186
+ <div class="viewport2" up-viewport style="width: 100px; height: 100px; overflow-y: scroll">
187
+ <div class="content2" style="height: 5000px">content2</div>
188
+ </div>
189
+ </div>
190
+ """
191
+
192
+ respond = => @respondWith(html)
170
193
 
171
- $('.viewport1').scrollTop(3000)
172
- $('.viewport2').scrollTop(3050)
194
+ $screen = affix('.screen')
195
+ $screen.html(html)
173
196
 
174
- expect('.viewport1').toBeScrolledTo(3000)
175
- expect('.viewport2').toBeScrolledTo(3050)
197
+ up.replace('.content1, .content2', '/one', reveal: false)
176
198
 
177
- up.replace('.content1, .content2', '/two', reveal: false)
178
- respond()
199
+ next =>
200
+ respond()
179
201
 
180
- u.setTimer 50, ->
202
+ next =>
203
+ $('.viewport1').scrollTop(3000)
204
+ $('.viewport2').scrollTop(3050)
205
+ expect('.viewport1').toBeScrolledTo(3000)
206
+ expect('.viewport2').toBeScrolledTo(3050)
181
207
 
182
- expect(location.href).toEqualUrl('/two')
208
+ up.replace('.content1, .content2', '/two', reveal: false)
183
209
 
184
- history.back()
210
+ next =>
211
+ respond()
185
212
 
186
- u.setTimer 50, ->
213
+ next.after 50, =>
214
+ expect(location.href).toMatchUrl('/two')
215
+ history.back()
216
+
217
+ next.after 50, =>
187
218
  # we need to respond since we've never requested the original URL with the popTarget
188
219
  respond()
189
220
 
190
- u.nextFrame ->
191
- expect('.viewport1').toBeScrolledTo(3000)
192
- expect('.viewport2').toBeScrolledTo(3050)
193
- done()
221
+ next =>
222
+ expect('.viewport1').toBeScrolledTo(3000)
223
+ expect('.viewport2').toBeScrolledTo(3050)
194
224
 
195
225
 
196
226
  describe 'events', ->
197
227
 
198
- it 'emits up:history:* events as the user goes forwards and backwards through history', (done) ->
199
- up.proxy.config.cacheSize = 0
200
- up.history.config.popTargets = ['.viewport']
228
+ describeCapability 'canPushState', ->
201
229
 
202
- affix('.viewport .content')
203
- respond = =>
204
- @respondWith """
205
- <div class="viewport">
206
- <div class="content">content</div>
207
- </div>
208
- """
230
+ it 'emits up:history:* events as the user goes forwards and backwards through history', asyncSpec (next) ->
231
+ up.proxy.config.cacheSize = 0
232
+ up.history.config.popTargets = ['.viewport']
233
+
234
+ affix('.viewport .content')
235
+ respond = =>
236
+ @respondWith """
237
+ <div class="viewport">
238
+ <div class="content">content</div>
239
+ </div>
240
+ """
209
241
 
210
- events = []
211
- u.each ['up:history:pushed', 'up:history:restored'], (eventName) ->
212
- up.on eventName, (event) ->
213
- events.push [eventName, event.url]
242
+ events = []
243
+ u.each ['up:history:pushed', 'up:history:restored'], (eventName) ->
244
+ up.on eventName, (event) ->
245
+ events.push [eventName, event.url]
214
246
 
215
- normalize = up.history.normalizeUrl
247
+ normalize = up.history.normalizeUrl
216
248
 
217
- up.replace('.content', '/one')
218
- respond()
249
+ up.replace('.content', '/foo')
219
250
 
220
- expect(events).toEqual [
221
- ['up:history:pushed', normalize('/one')]
222
- ]
251
+ next =>
252
+ respond()
253
+
254
+ next =>
255
+ expect(events).toEqual [
256
+ ['up:history:pushed', normalize('/foo')]
257
+ ]
223
258
 
224
- up.replace('.content', '/two')
225
- respond()
259
+ up.replace('.content', '/bar')
226
260
 
227
- expect(events).toEqual [
228
- ['up:history:pushed', normalize('/one')]
229
- ['up:history:pushed', normalize('/two')]
230
- ]
261
+ next =>
262
+ respond()
231
263
 
232
- up.replace('.content', '/three')
233
- respond()
264
+ next =>
265
+ expect(events).toEqual [
266
+ ['up:history:pushed', normalize('/foo')]
267
+ ['up:history:pushed', normalize('/bar')]
268
+ ]
234
269
 
235
- expect(events).toEqual [
236
- ['up:history:pushed', normalize('/one')]
237
- ['up:history:pushed', normalize('/two')]
238
- ['up:history:pushed', normalize('/three')]
239
- ]
270
+ up.replace('.content', '/baz')
240
271
 
241
- history.back()
242
- u.setTimer 50, ->
243
- respond()
244
-
245
- expect(events).toEqual [
246
- ['up:history:pushed', normalize('/one')]
247
- ['up:history:pushed', normalize('/two')]
248
- ['up:history:pushed', normalize('/three')]
249
- ['up:history:restored', normalize('/two')]
250
- ]
251
-
252
- history.back()
253
- u.setTimer 50, ->
272
+ next =>
254
273
  respond()
255
274
 
275
+ next =>
256
276
  expect(events).toEqual [
257
- ['up:history:pushed', normalize('/one')]
258
- ['up:history:pushed', normalize('/two')]
259
- ['up:history:pushed', normalize('/three')]
260
- ['up:history:restored', normalize('/two')]
261
- ['up:history:restored', normalize('/one')]
277
+ ['up:history:pushed', normalize('/foo')]
278
+ ['up:history:pushed', normalize('/bar')]
279
+ ['up:history:pushed', normalize('/baz')]
280
+ ]
281
+
282
+ history.back()
283
+
284
+ next.after 50, =>
285
+ respond()
286
+
287
+ next =>
288
+ expect(events).toEqual [
289
+ ['up:history:pushed', normalize('/foo')]
290
+ ['up:history:pushed', normalize('/bar')]
291
+ ['up:history:pushed', normalize('/baz')]
292
+ ['up:history:restored', normalize('/bar')]
293
+ ]
294
+
295
+ history.back()
296
+
297
+ next.after 50, =>
298
+ respond()
299
+
300
+ next =>
301
+ expect(events).toEqual [
302
+ ['up:history:pushed', normalize('/foo')]
303
+ ['up:history:pushed', normalize('/bar')]
304
+ ['up:history:pushed', normalize('/baz')]
305
+ ['up:history:restored', normalize('/bar')]
306
+ ['up:history:restored', normalize('/foo')]
262
307
  ]
263
308
 
264
309
  history.forward()
265
- u.setTimer 50, ->
266
- respond()
267
-
268
- expect(events).toEqual [
269
- ['up:history:pushed', normalize('/one')]
270
- ['up:history:pushed', normalize('/two')]
271
- ['up:history:pushed', normalize('/three')]
272
- ['up:history:restored', normalize('/two')]
273
- ['up:history:restored', normalize('/one')]
274
- ['up:history:restored', normalize('/two')]
275
- ]
276
-
277
- history.forward()
278
- u.setTimer 50, ->
279
- respond() # we need to respond since we've never requested /three with the popTarget
280
-
281
- expect(events).toEqual [
282
- ['up:history:pushed', normalize('/one')]
283
- ['up:history:pushed', normalize('/two')]
284
- ['up:history:pushed', normalize('/three')]
285
- ['up:history:restored', normalize('/two')]
286
- ['up:history:restored', normalize('/one')]
287
- ['up:history:restored', normalize('/two')]
288
- ['up:history:restored', normalize('/three')]
289
- ]
290
-
291
- done()
310
+
311
+ next.after 50, =>
312
+ respond()
313
+
314
+ next =>
315
+ expect(events).toEqual [
316
+ ['up:history:pushed', normalize('/foo')]
317
+ ['up:history:pushed', normalize('/bar')]
318
+ ['up:history:pushed', normalize('/baz')]
319
+ ['up:history:restored', normalize('/bar')]
320
+ ['up:history:restored', normalize('/foo')]
321
+ ['up:history:restored', normalize('/bar')]
322
+ ]
323
+
324
+ history.forward()
325
+
326
+ next.after 50, =>
327
+ respond() # we need to respond since we've never requested /baz with the popTarget
328
+
329
+ next =>
330
+ expect(events).toEqual [
331
+ ['up:history:pushed', normalize('/foo')]
332
+ ['up:history:pushed', normalize('/bar')]
333
+ ['up:history:pushed', normalize('/baz')]
334
+ ['up:history:restored', normalize('/bar')]
335
+ ['up:history:restored', normalize('/foo')]
336
+ ['up:history:restored', normalize('/bar')]
337
+ ['up:history:restored', normalize('/baz')]
338
+ ]