joosy 1.2.0.beta.4 → 1.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.codoopts +1 -1
  3. data/Gruntfile.coffee +3 -3
  4. data/README.md +4 -0
  5. data/bower.json +1 -1
  6. data/build/joosy.js +2 -2
  7. data/build/joosy/form.js +1 -1
  8. data/build/joosy/resources.js +1 -1
  9. data/package.json +2 -2
  10. data/source/joosy/application.coffee +2 -2
  11. data/source/joosy/form.coffee +4 -4
  12. data/source/joosy/helpers/form.coffee +12 -3
  13. data/source/joosy/helpers/index.coffee +0 -1
  14. data/source/joosy/helpers/view.coffee +16 -3
  15. data/source/joosy/layout.coffee +0 -4
  16. data/source/joosy/module.coffee +16 -1
  17. data/source/joosy/modules/dom.coffee +106 -101
  18. data/source/joosy/modules/events.coffee +44 -10
  19. data/source/joosy/modules/filters.coffee +64 -60
  20. data/source/joosy/modules/page.coffee +3 -0
  21. data/source/joosy/modules/page/scrolling.coffee +46 -29
  22. data/source/joosy/modules/page/title.coffee +14 -0
  23. data/source/joosy/modules/renderer.coffee +219 -190
  24. data/source/joosy/modules/resources.coffee +3 -0
  25. data/source/joosy/modules/resources/cacher.coffee +81 -10
  26. data/source/joosy/modules/resources/function.coffee +26 -29
  27. data/source/joosy/modules/resources/identity_map.coffee +64 -42
  28. data/source/joosy/modules/resources/model.coffee +127 -73
  29. data/source/joosy/modules/time_manager.coffee +2 -0
  30. data/source/joosy/page.coffee +3 -6
  31. data/source/joosy/resources/array.coffee +87 -2
  32. data/source/joosy/resources/hash.coffee +53 -1
  33. data/source/joosy/resources/rest.coffee +59 -3
  34. data/source/joosy/resources/scalar.coffee +47 -1
  35. data/source/joosy/router.coffee +63 -21
  36. data/source/joosy/templaters/jst.coffee +3 -0
  37. data/source/joosy/widget.coffee +17 -11
  38. data/spec/joosy/core/helpers/view_spec.coffee +14 -0
  39. data/spec/joosy/core/modules/dom_spec.coffee +1 -1
  40. data/spec/joosy/core/modules/filters_spec.coffee +2 -2
  41. data/spec/joosy/core/modules/module_spec.coffee +1 -1
  42. data/spec/joosy/core/modules/renderer_spec.coffee +19 -1
  43. data/spec/joosy/core/router_spec.coffee +80 -45
  44. data/spec/joosy/core/widget_spec.coffee +9 -0
  45. data/spec/joosy/resources/modules/cacher_spec.coffee +3 -3
  46. data/spec/joosy/resources/modules/function_spec.coffee +2 -2
  47. data/spec/joosy/resources/modules/identity_map_spec.coffee +2 -2
  48. data/spec/joosy/resources/modules/model_spec.coffee +1 -1
  49. metadata +2 -5
  50. data/source/joosy/helpers/routes.coffee +0 -17
  51. data/source/joosy/modules/widgets_manager.coffee +0 -90
  52. data/spec/joosy/core/helpers/routes_spec.coffee +0 -15
@@ -1,7 +1,6 @@
1
1
  #= require joosy/joosy
2
2
  #= require joosy/modules/events
3
3
  #= require joosy/page
4
- #= require joosy/helpers/routes
5
4
 
6
5
  #
7
6
  # Router. Reacts on URI change event and loads proper pages
@@ -25,21 +24,18 @@
25
24
  class Joosy.Router extends Joosy.Module
26
25
  @extend Joosy.Modules.Events
27
26
 
28
- # We need to be constantly subscribed to popstate event to filter
29
- # the first event that always happens on the initial load
30
27
  $(window).bind 'popstate', (event) =>
31
- if window.history.loaded?
32
- @trigger 'popstate', event
33
- else
34
- window.history.loaded = true
28
+ @trigger 'popstate', event
35
29
 
30
+ # Comfortable links for the views
36
31
  $(document).on 'click', 'a[data-joosy]', (event) ->
37
32
  event.preventDefault()
38
33
  Joosy.Router.navigate @getAttribute('href')
39
34
 
40
35
  #
41
36
  # Rails-like wrapper around internal raw routes representation
42
- # @private
37
+ #
38
+ # @nodoc
43
39
  #
44
40
  class Drawer
45
41
  @run: (block, namespace='', alias='') ->
@@ -98,7 +94,15 @@ class Joosy.Router extends Joosy.Module
98
94
  block = options
99
95
  options = {}
100
96
 
101
- Drawer.run block, @__namespace+name, options.as?.toString()
97
+ alias = if options.as
98
+ if @__alias
99
+ @__alias + options.as.charAt(0).toUpperCase() + options.as.slice(1)
100
+ else
101
+ options.as
102
+ else
103
+ @__alias
104
+
105
+ Drawer.run block, @__namespace+name, alias
102
106
 
103
107
  #
104
108
  # Registers a set of raw routes
@@ -142,14 +146,29 @@ class Joosy.Router extends Joosy.Module
142
146
  # Canonical form of HTML5 prefix is '/any/thing/'
143
147
  @config.prefix = ('/'+@config.prefix+'/').replace /\/{2,}/g, '/'
144
148
 
145
- @listener = @bind 'popstate pushstate', =>
149
+ @suppressPopstate = true
150
+ @initialPath = location.pathname
151
+
152
+ @popstateListener = @bind 'popstate', =>
153
+ isInitialPop = @suppressPopstate && location.pathname == @initialPath
154
+ @suppressPopstate = false
155
+ if isInitialPop
156
+ Joosy.Modules.Log.debug "Router> Suppressed initial popstate"
157
+ else
158
+ @respond @canonizeLocation()
159
+
160
+ @pushstateListener = @bind 'pushstate', =>
161
+ @suppressPopstate = false
146
162
  @respond @canonizeLocation()
147
163
  else
148
164
  # Canonical form of hash suffix is 'any/thing'
149
165
  @config.prefix = @config.prefix.replace(/^\#?\/?/, '').replace /\/?$/, ''
150
166
 
151
167
  $(window).bind 'hashchange.JoosyRouter', =>
152
- @respond @canonizeLocation()
168
+ if @__skipHashChange? && @__skipHashChange > 0
169
+ @__skipHashChange -= 1
170
+ else
171
+ @respond @canonizeLocation()
153
172
 
154
173
  @respond @canonizeLocation() if respond
155
174
 
@@ -157,7 +176,12 @@ class Joosy.Router extends Joosy.Module
157
176
  # Clears current map of routes and deactivates bindings
158
177
  #
159
178
  @reset: ->
160
- @unbind @listener
179
+ if Joosy.Helpers.Routes?
180
+ delete Joosy.Widget::[key] for key, method of Joosy.Helpers.Routes
181
+ Joosy.Helpers.Routes = {}
182
+
183
+ @unbind @popstateListener
184
+ @unbind @pushstateListener
161
185
  $(window).unbind '.JoosyRouter'
162
186
  @restriction = false
163
187
  @routes = {}
@@ -175,22 +199,31 @@ class Joosy.Router extends Joosy.Module
175
199
  # Changes current URI and therefore triggers route loading
176
200
  #
177
201
  # @param [String] to Route to navigate to
178
- #
202
+ # @param [Object] options
179
203
  # @option options [Boolean] respond If false just changes route without responding
180
- # @option options [Boolean] replaceState If true replaces history entry instead of adding. Works only in browsers supporting history.pushState
204
+ # @option options [Boolean] replace If true replaces history entry instead of adding (HTML5 mode only)
181
205
  #
182
- @navigate: (to, options={}) ->
183
- path = to
206
+ @navigate: (path, options={}) ->
207
+ method = if options.replace then 'replaceState' else 'pushState'
208
+ respond = options.respond ? true
184
209
 
185
210
  if @config.html5
186
211
  # omit html5 relative links
187
212
  if @config.prefix && path[0] == '/' && !path.match(RegExp("^#{@config.prefix.replace(/\/$/, '')}(/|$)"))
188
213
  path = path.replace /^\//, @config.prefix
189
- history.pushState {}, '', path
190
- @trigger 'pushstate'
214
+
215
+ history[method] {}, '', path
216
+
217
+ @trigger('pushstate') if respond
191
218
  else
219
+ # remove prefix
192
220
  if @config.prefix && !path.match(RegExp("^#?/?#{@config.prefix}(/|$)"))
193
221
  path = path.replace /^\#?\/?/, "#{@config.prefix}/"
222
+
223
+ unless respond
224
+ @__skipHashChange ?= 0
225
+ @__skipHashChange += 1
226
+
194
227
  location.hash = path
195
228
 
196
229
  return
@@ -224,13 +257,14 @@ class Joosy.Router extends Joosy.Module
224
257
  result = {}
225
258
 
226
259
  # Full RegExp matcher for the route
227
- matcher = matcher.replace(/\/:([^\/]+)/g, '/([^/]+)') # Turning :params into regexp section
260
+ matcher = matcher.replace(/\/?:([^\/]+)/g, '/([^/]+)') # Turning :params into regexp section
228
261
  matcher = matcher.replace(/^\/?/, '^/?') # Making leading slash optional
229
262
  matcher = matcher.replace(/\/?$/, '/?$') # Making trailing slash optional
230
263
 
231
264
  # Array of parameter names
232
- params = (path.match(/\/:[^\/]+/g) || []).map (str) ->
233
- str.substr 2
265
+ params = (path.match(/\/?:[^\/]+/g) || []).map (str) ->
266
+ str = str.substr(1) if str[0] == '/'
267
+ str.substr(1)
234
268
 
235
269
  @routes ||= {}
236
270
  @routes[matcher] =
@@ -297,6 +331,14 @@ class Joosy.Router extends Joosy.Module
297
331
  else
298
332
  "#{origin}#{location.pathname}#{helper(options)}"
299
333
 
334
+ Joosy.Widget::["#{as}Path"] = @["#{as}Path"]
335
+ Joosy.Widget::["#{as}Url"] = @["#{as}Url"]
336
+
337
+ #
338
+ # Parses parameters from both, current URL and route placeholders
339
+ #
340
+ # @private
341
+ #
300
342
  @__grabParams: (query, route=null, match=[]) ->
301
343
  params = {}
302
344
 
@@ -4,6 +4,9 @@
4
4
  # JST template precompilation binding
5
5
  #
6
6
  class Joosy.Templaters.JST
7
+ #
8
+ # Initializes JST templater
9
+ #
7
10
  constructor: (@config={}) ->
8
11
  @prefix = @config.prefix if @config.prefix? && @config.prefix.length > 0
9
12
 
@@ -105,18 +105,18 @@
105
105
  #
106
106
  # @include Joosy.Modules.Log
107
107
  # @include Joosy.Modules.Events
108
- # @include Joosy.Modules.DOM
109
- # @include Joosy.Modules.Renderer
108
+ # @concern Joosy.Modules.DOM
109
+ # @concern Joosy.Modules.Renderer
110
110
  # @include Joosy.Modules.TimeManager
111
- # @include Joosy.Modules.Filters
111
+ # @extend Joosy.Modules.Filters
112
112
  #
113
113
  class Joosy.Widget extends Joosy.Module
114
114
  @include Joosy.Modules.Log
115
115
  @include Joosy.Modules.Events
116
- @include Joosy.Modules.DOM
117
- @include Joosy.Modules.Renderer
116
+ @concern Joosy.Modules.DOM
117
+ @concern Joosy.Modules.Renderer
118
118
  @include Joosy.Modules.TimeManager
119
- @include Joosy.Modules.Filters
119
+ @extend Joosy.Modules.Filters
120
120
 
121
121
  #
122
122
  # Extends widgets mapping
@@ -139,7 +139,7 @@ class Joosy.Widget extends Joosy.Module
139
139
  @independent: ->
140
140
  @::__independent = true
141
141
 
142
- @registerPlainFilters 'beforeLoad', 'afterLoad', 'afterUnload'
142
+ @registerPlainFilters 'beforeLoad', 'beforeUnload', 'afterLoad', 'afterUnload'
143
143
 
144
144
  @registerSequencedFilters 'beforePaint', 'paint', 'erase', 'fetch'
145
145
 
@@ -172,6 +172,10 @@ class Joosy.Widget extends Joosy.Module
172
172
  unregisterWidget: (widget) ->
173
173
  widget.__unload()
174
174
 
175
+ #
176
+ # Unloads the previous widget and inject the new one inplace saving
177
+ # the continuity
178
+ #
175
179
  replaceWidget: (widget, replacement) ->
176
180
  replacement = @__normalizeWidget(replacement)
177
181
  replacement.previous = widget
@@ -286,8 +290,6 @@ class Joosy.Widget extends Joosy.Module
286
290
  @__nestedSections = []
287
291
  @$container.html @__renderDefault?(@data || {})
288
292
 
289
- @__load()
290
-
291
293
  for selector, section of nestingMap
292
294
  do (selector, section) =>
293
295
  $container = @__normalizeSelector(selector)
@@ -297,6 +299,8 @@ class Joosy.Widget extends Joosy.Module
297
299
  else
298
300
  section.instance.__bootstrap @, section.nested, $container, false
299
301
 
302
+ @__load()
303
+
300
304
  #
301
305
  # Initializes section that was injected into DOM
302
306
  #
@@ -313,6 +317,8 @@ class Joosy.Widget extends Joosy.Module
313
317
  # Deinitializes section that is preparing to be removed from DOM
314
318
  #
315
319
  __unload: (modifyParent=true) ->
320
+ @__runBeforeUnloads()
321
+
316
322
  if @__nestedSections
317
323
  section.__unload(false) for section in @__nestedSections
318
324
  delete @__nestedSections
@@ -329,7 +335,7 @@ class Joosy.Widget extends Joosy.Module
329
335
  delete @parent
330
336
 
331
337
  #
332
- # Normalizes selector and returns jQuery wrap
338
+ # Normalizes selector and returns jQuery wrap.
333
339
  #
334
340
  # Selector can be one of:
335
341
  #
@@ -344,7 +350,7 @@ class Joosy.Widget extends Joosy.Module
344
350
  $(@__extractSelector(selector), @$container)
345
351
 
346
352
  #
347
- # Normalizes widget descrpition to its instance
353
+ # Normalizes widget descrpition to its instance.
348
354
  #
349
355
  # Besides already being instance it cann be either class or lambda
350
356
  #
@@ -12,3 +12,17 @@ describe "Joosy.Helpers.View", ->
12
12
  h.contentTag 'div', 'content', {id: 'id2'}
13
13
 
14
14
  expect(tag.toLowerCase()).toEqualHTML '<div id="id"><div id="id2">content</div></div>'
15
+
16
+ it "renders data-joosy links", ->
17
+ link = Joosy.Helpers.Application.linkTo 'test', '/app/link', nice: true
18
+ expect(link).toBeTag 'a', 'test',
19
+ 'data-joosy': 'true'
20
+ nice: 'true'
21
+ href: '/app/link'
22
+
23
+ it "renders data-joosy links yielding block", ->
24
+ link = Joosy.Helpers.Application.linkTo '/app/link', nice: true, -> 'test'
25
+ expect(link).toBeTag 'a', 'test',
26
+ 'data-joosy': 'true'
27
+ nice: 'true'
28
+ href: '/app/link'
@@ -5,7 +5,7 @@ describe "Joosy.Modules.DOM", ->
5
5
  container = @$ground.find('#application')
6
6
 
7
7
  class @DOM extends Joosy.Module
8
- @include Joosy.Modules.DOM
8
+ @concern Joosy.Modules.DOM
9
9
 
10
10
  @mapElements
11
11
  posts: '.post'
@@ -4,7 +4,7 @@ describe "Joosy.Modules.Filters", ->
4
4
 
5
5
  beforeEach ->
6
6
  class @Filters extends Joosy.Module
7
- @include Joosy.Modules.Filters
7
+ @extend Joosy.Modules.Filters
8
8
  @registerPlainFilters 'beforeLoad', 'afterLoad', 'afterUnload'
9
9
 
10
10
  @filters = new @Filters
@@ -96,7 +96,7 @@ describe "Joosy.Modules.Filters", ->
96
96
 
97
97
  beforeEach ->
98
98
  class @Filters extends Joosy.Module
99
- @include Joosy.Modules.Filters
99
+ @extend Joosy.Modules.Filters
100
100
  @registerSequencedFilters 'beforeLoad', 'afterLoad', 'afterUnload'
101
101
 
102
102
  @filters = new @Filters
@@ -19,7 +19,7 @@ describe "Joosy.Module", ->
19
19
  it "has minimal set of properties", ->
20
20
  class Klass extends Joosy.Module
21
21
 
22
- expect(Object.keys Klass).toEqual ['__namespace__', '__className', 'hasAncestor', 'aliasMethodChain', 'aliasStaticMethodChain', 'merge', 'include', 'extend', '__super__']
22
+ expect(Object.keys Klass).toEqual ['__namespace__', '__className', 'hasAncestor', 'aliasMethodChain', 'aliasStaticMethodChain', 'merge', 'include', 'extend', 'concern', '__super__']
23
23
  expect(Object.keys Klass.prototype).toEqual ['constructor']
24
24
 
25
25
  it "includes", ->
@@ -2,7 +2,7 @@ describe "Joosy.Modules.Renderer", ->
2
2
 
3
3
  beforeEach ->
4
4
  class @Renderer extends Joosy.Module
5
- @include Joosy.Modules.Renderer
5
+ @concern Joosy.Modules.Renderer
6
6
 
7
7
  @renderer = new @Renderer
8
8
 
@@ -66,6 +66,24 @@ describe "Joosy.Modules.Renderer", ->
66
66
  runs ->
67
67
  expect(@$ground.text()).toBe "new"
68
68
 
69
+ it "runs callback during update", ->
70
+ template = (locals) -> locals.entity.value
71
+ callback = sinon.spy()
72
+
73
+ runs ->
74
+ @$ground.html @renderer.renderDynamic(template, {entity: @entity}, callback)
75
+ expect(@$ground.text()).toBe "initial"
76
+ expect(callback.callCount).toEqual 0
77
+
78
+ runs ->
79
+ @entity.update "new"
80
+
81
+ waits 0
82
+
83
+ runs ->
84
+ expect(@$ground.text()).toBe "new"
85
+ expect(callback.callCount).toEqual 1
86
+
69
87
  it "does not update unloaded content", ->
70
88
  template = (locals) -> locals.entity.value
71
89
 
@@ -25,38 +25,65 @@ describe "Joosy.Router", ->
25
25
  afterEach ->
26
26
  Joosy.Router.reset()
27
27
 
28
- it 'draws', ->
29
- spies = @spies
30
- Page = @Page
31
-
32
- Joosy.Router.draw ->
33
- @root to: spies.root
34
- @match '/base', to: spies.base
35
- @match '/page', to: Page
36
- @namespace '/section', {as: 'section'}, ->
37
- @match '/page/:id', to: spies.section, as: 'page'
38
- @match '/page2/:more', to: Page
39
- @notFound to: spies.wildcard
28
+ describe 'drawer', ->
29
+ beforeEach ->
30
+ spies = @spies
31
+ Page = @Page
32
+
33
+ Joosy.Router.setup {html5: true}, (-> ), false
34
+
35
+ Joosy.Router.draw ->
36
+ @root to: spies.root
37
+ @match '/base', to: spies.base
38
+ @match '/page', to: Page
39
+ @namespace '/test', ->
40
+ @match '/page', to: spies.section, as: 'test'
41
+ @namespace '/section', {as: 'section'}, ->
42
+ @match '/page/:id', to: spies.section, as: 'page'
43
+ @match '/page2/:more', to: Page
44
+ @notFound to: spies.wildcard
45
+
46
+ it 'registeres routes', ->
47
+ expect(Joosy.Router.routes).toEqual
48
+ '^/?/?$':
49
+ to: @spies.root
50
+ as: 'root'
51
+ capture: []
52
+ '^/?base/?$':
53
+ to: @spies.base
54
+ capture: []
55
+ '^/?page/?$':
56
+ to: @Page, capture : []
57
+ '^/?test/page/?$':
58
+ to: @spies.section
59
+ capture: []
60
+ as: 'test'
61
+ '^/?section/page/([^/]+)/?$':
62
+ to: @spies.section
63
+ as: 'sectionPage'
64
+ capture: ['id']
65
+ '^/?section/page2/([^/]+)/?$':
66
+ to: @Page
67
+ capture: ['more']
68
+
69
+ expect(Joosy.Router.wildcardAction).toEqual @spies.wildcard
40
70
 
41
- expect(Joosy.Router.routes).toEqual
42
- '^/?/?$':
43
- to: spies.root
44
- as: 'root'
45
- capture: []
46
- '^/?base/?$':
47
- to: spies.base,
48
- capture: [],
49
- '^/?page/?$':
50
- to: Page, capture : []
51
- '^/?section/page/([^/]+)/?$':
52
- to: spies.section,
53
- as: 'sectionPage'
54
- capture: ['id']
55
- '^/?section/page2/([^/]+)/?$':
56
- to: Page
57
- capture: ['more']
71
+ it 'defines plain helper', ->
72
+ expect(Joosy.Helpers.Routes.rootPath()).toEqual '/'
73
+ expect(Joosy.Helpers.Routes.rootUrl()).toEqual "http://#{location.host}/"
74
+ expect(Joosy.Helpers.Routes.testPath()).toEqual '/test/page'
58
75
 
59
- expect(Joosy.Router.wildcardAction).toEqual spies.wildcard
76
+ it 'defines namespaced parameterized helpers', ->
77
+ expect(Joosy.Helpers.Routes.sectionPagePath(id: 1)).toEqual '/section/page/1'
78
+ expect(Joosy.Helpers.Routes.sectionPageUrl(id: 1)).toEqual "http://#{location.host}/section/page/1"
79
+
80
+ it 'adds helper to widgets', ->
81
+ class A extends Joosy.Widget
82
+ test: ->
83
+ expect(@rootPath()).toEqual '/'
84
+ expect(@rootUrl()).toEqual "http://#{location.host}/"
85
+
86
+ (new A).test()
60
87
 
61
88
  it 'maps', ->
62
89
  Joosy.Router.map @map
@@ -179,16 +206,15 @@ describe "Joosy.Router", ->
179
206
  runs -> Joosy.Router.navigate '/base'
180
207
  waits 0
181
208
  runs ->
182
- location.hash == '#/base'
209
+ expect(location.hash).toEqual '#/base'
183
210
  expect(@spies.responder.callCount).toEqual 1
184
211
 
185
- it 'defines plain helper', ->
186
- expect(Joosy.Helpers.Routes.rootPath()).toEqual '#'
187
- expect(Joosy.Helpers.Routes.rootUrl()).toEqual "http://#{location.host}#{pathname}#"
188
-
189
- it 'defines namespaced parameterized helpers', ->
190
- expect(Joosy.Helpers.Routes.sectionPagePath(id: 1)).toEqual '#section/page/1'
191
- expect(Joosy.Helpers.Routes.sectionPageUrl(id: 1)).toEqual "http://#{location.host}#{pathname}#section/page/1"
212
+ it 'stubs', ->
213
+ runs -> Joosy.Router.navigate '/base', respond: false
214
+ waits 0
215
+ runs ->
216
+ expect(location.hash).toEqual '#/base'
217
+ expect(@spies.responder.callCount).toEqual 0
192
218
 
193
219
  if history.pushState?
194
220
  describe 'html5 based', ->
@@ -270,13 +296,22 @@ describe "Joosy.Router", ->
270
296
  location.pathname == '/base'
271
297
  expect(@spies.responder.callCount).toEqual 1
272
298
 
273
- it 'defines plain helper', ->
274
- expect(Joosy.Helpers.Routes.rootPath()).toEqual '/'
275
- expect(Joosy.Helpers.Routes.rootUrl()).toEqual "http://#{location.host}/"
299
+ it 'stubs', ->
300
+ runs -> Joosy.Router.navigate '/base', respond: false
301
+ waits 0
302
+ runs ->
303
+ location.pathname == '/base'
304
+ expect(@spies.responder.callCount).toEqual 0
305
+
306
+ it 'replaces', ->
307
+ length = history.length
276
308
 
277
- it 'defines namespaced parameterized helpers', ->
278
- expect(Joosy.Helpers.Routes.sectionPagePath(id: 1)).toEqual '/section/page/1'
279
- expect(Joosy.Helpers.Routes.sectionPageUrl(id: 1)).toEqual "http://#{location.host}/section/page/1"
309
+ runs -> Joosy.Router.navigate '/base', replace: true
310
+ waits 0
311
+ runs ->
312
+ location.pathname == '/base'
313
+ expect(@spies.responder.callCount).toEqual 1
314
+ expect(history.length).toEqual length
280
315
 
281
316
  for name, val of { html5: true, hash: false }
282
317
  do (name, val) ->
@@ -315,7 +350,7 @@ describe "Joosy.Router", ->
315
350
 
316
351
  describe 'linker', ->
317
352
  it 'defines helper', ->
318
- tag = Joosy.Helpers.Routes.linkTo 'test', '/base', class: 'zomg!'
353
+ tag = Joosy.Helpers.Application.linkTo 'test', '/base', class: 'zomg!'
319
354
 
320
355
  expect(tag).toBeTag 'a', 'test',
321
356
  'data-joosy': 'true'