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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'