joosy 1.2.0.beta.1 → 1.2.0.beta.2
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.
- checksums.yaml +4 -4
- data/README.md +17 -11
- data/bower.json +1 -1
- data/build/joosy.js +2 -2
- data/build/joosy/resources.js +1 -1
- data/package.json +1 -1
- data/source/joosy/module.coffee +2 -29
- data/source/joosy/modules/resources/cacher.coffee +2 -2
- data/source/joosy/modules/resources/function.coffee +41 -0
- data/source/joosy/modules/resources/identity_map.coffee +4 -3
- data/source/joosy/modules/resources/model.coffee +10 -6
- data/source/joosy/resources/array.coffee +9 -8
- data/source/joosy/resources/hash.coffee +21 -19
- data/source/joosy/resources/rest.coffee +21 -82
- data/source/joosy/resources/scalar.coffee +13 -14
- data/source/joosy/router.coffee +4 -2
- data/spec/helpers/matchers.coffee +16 -2
- data/spec/joosy/core/helpers/view_spec.coffee +2 -2
- data/spec/joosy/core/router_spec.coffee +99 -98
- data/spec/joosy/core/templaters/jst_spec.coffee +2 -2
- data/spec/joosy/form/form_spec.coffee +1 -1
- data/spec/joosy/resources/array_spec.coffee +4 -8
- data/spec/joosy/resources/hash_spec.coffee +15 -15
- data/spec/joosy/resources/modules/cacher_spec.coffee +2 -2
- data/spec/joosy/resources/modules/function_spec.coffee +32 -0
- data/spec/joosy/resources/modules/identity_map_spec.coffee +3 -3
- data/spec/joosy/resources/modules/model_spec.coffee +40 -29
- data/spec/joosy/resources/rest_spec.coffee +9 -9
- data/spec/joosy/resources/scalar_spec.coffee +9 -14
- metadata +5 -4
@@ -1,32 +1,31 @@
|
|
1
|
-
class Joosy.Resources.Scalar extends Joosy.
|
1
|
+
class Joosy.Resources.Scalar extends Joosy.Module
|
2
2
|
|
3
3
|
@include Joosy.Modules.Events
|
4
4
|
@include Joosy.Modules.Filters
|
5
5
|
|
6
6
|
@registerPlainFilters 'beforeLoad'
|
7
7
|
|
8
|
+
@build: ->
|
9
|
+
new @ arguments...
|
10
|
+
|
11
|
+
__call: ->
|
12
|
+
if arguments.length > 0
|
13
|
+
@set arguments[0]
|
14
|
+
else
|
15
|
+
@get()
|
16
|
+
|
8
17
|
constructor: (value) ->
|
9
|
-
|
10
|
-
@load value
|
18
|
+
@load value
|
11
19
|
|
12
20
|
load: (value) ->
|
13
21
|
@value = @__applyBeforeLoads(value)
|
14
22
|
@trigger 'changed'
|
15
23
|
@value
|
16
24
|
|
17
|
-
|
18
|
-
new @constructor @value
|
19
|
-
|
20
|
-
__call: ->
|
21
|
-
if arguments.length > 0
|
22
|
-
@__set arguments[0]
|
23
|
-
else
|
24
|
-
@__get()
|
25
|
-
|
26
|
-
__get: ->
|
25
|
+
get: ->
|
27
26
|
@value
|
28
27
|
|
29
|
-
|
28
|
+
set: (@value) ->
|
30
29
|
@trigger 'changed'
|
31
30
|
|
32
31
|
valueOf: ->
|
data/source/joosy/router.coffee
CHANGED
@@ -290,10 +290,12 @@ class Joosy.Router extends Joosy.Module
|
|
290
290
|
@["#{as}Path"] = helper
|
291
291
|
|
292
292
|
@["#{as}Url"] = (options) ->
|
293
|
+
origin = "#{location.protocol}//#{location.host}"
|
294
|
+
|
293
295
|
if Joosy.Router.config.html5
|
294
|
-
"#{
|
296
|
+
"#{origin}#{helper(options)}"
|
295
297
|
else
|
296
|
-
"#{
|
298
|
+
"#{origin}#{location.pathname}#{helper(options)}"
|
297
299
|
|
298
300
|
@__grabParams: (query, route=null, match=[]) ->
|
299
301
|
params = {}
|
@@ -30,7 +30,8 @@ beforeEach ->
|
|
30
30
|
return true
|
31
31
|
|
32
32
|
toEqualHTML: (string) ->
|
33
|
-
html = @actual.replace(/>\s+</g, '><')
|
33
|
+
html = @actual.replace(/>\s+</g, '><').toLowerCase().replace(/\"/g, '')
|
34
|
+
string = string.toLowerCase().replace(/\"/g, '')
|
34
35
|
@message = -> "Expected '#{html}' to equal '#{string}'"
|
35
36
|
|
36
37
|
html == string
|
@@ -44,23 +45,36 @@ beforeEach ->
|
|
44
45
|
# tag.toBeTag 'div', 'foo', class: 'foo', id: /\S+/
|
45
46
|
#
|
46
47
|
toBeTag: (tagName, content, attrs) ->
|
48
|
+
reason = ''
|
47
49
|
@message = =>
|
48
50
|
actual = $('<div>').append(@actual).html()
|
49
|
-
"Expected '#{actual}' to be a tag #{tagName} with attributes #{JSON.stringify attrs} and content '#{content}'"
|
51
|
+
"Expected '#{actual}' to be a tag #{tagName} with attributes #{JSON.stringify attrs} and content '#{content}': #{reason}"
|
50
52
|
|
51
53
|
tag = $ @actual
|
52
54
|
|
53
55
|
# Is it alone?
|
54
56
|
flag = tag.length == 1
|
57
|
+
if !flag
|
58
|
+
reason = 'not alone'
|
59
|
+
return false
|
55
60
|
|
56
61
|
# Tag name matches?
|
57
62
|
flag &&= tag[0].nodeName == tagName.toUpperCase()
|
63
|
+
if !flag
|
64
|
+
reason = 'tag name mismatch'
|
65
|
+
return false
|
58
66
|
|
59
67
|
# Content matches?
|
60
68
|
flag &&= tag.html() == content if content != false
|
69
|
+
if !flag
|
70
|
+
reason = 'content mismatch'
|
71
|
+
return false
|
61
72
|
|
62
73
|
# Same number of attributes?
|
63
74
|
flag &&= tag[0].attributes.length == Object.keys(attrs).length
|
75
|
+
if !flag
|
76
|
+
reason = 'attributes count mismatch'
|
77
|
+
return false
|
64
78
|
|
65
79
|
# Attributes match?
|
66
80
|
for name, val of attrs
|
@@ -5,10 +5,10 @@ describe "Joosy.Helpers.View", ->
|
|
5
5
|
|
6
6
|
it "renders tag with string content", ->
|
7
7
|
tag = h.contentTag 'div', 'content', {id: 'id'}
|
8
|
-
expect(tag).
|
8
|
+
expect(tag).toBeTag 'div', 'content', id: 'id'
|
9
9
|
|
10
10
|
it "renders tag with lambda content", ->
|
11
11
|
tag = h.contentTag 'div', {id: 'id'}, ->
|
12
12
|
h.contentTag 'div', 'content', {id: 'id2'}
|
13
13
|
|
14
|
-
expect(tag).
|
14
|
+
expect(tag.toLowerCase()).toEqualHTML '<div id="id"><div id="id2">content</div></div>'
|
@@ -190,127 +190,128 @@ describe "Joosy.Router", ->
|
|
190
190
|
expect(Joosy.Helpers.Routes.sectionPagePath(id: 1)).toEqual '#section/page/1'
|
191
191
|
expect(Joosy.Helpers.Routes.sectionPageUrl(id: 1)).toEqual "http://#{location.host}#{pathname}#section/page/1"
|
192
192
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
afterEach ->
|
199
|
-
Joosy.Router.reset()
|
200
|
-
history.pushState {}, '', pathname
|
201
|
-
waits 0
|
193
|
+
if history.pushState?
|
194
|
+
describe 'html5 based', ->
|
195
|
+
beforeEach ->
|
196
|
+
Joosy.Router.setup {html5: true}, @spies.responder, false
|
197
|
+
Joosy.Router.map @map
|
202
198
|
|
203
|
-
|
204
|
-
runs -> Joosy.Router.navigate '/page'
|
205
|
-
waits 0
|
206
|
-
runs ->
|
199
|
+
afterEach ->
|
207
200
|
Joosy.Router.reset()
|
208
|
-
|
209
|
-
|
210
|
-
runs ->
|
211
|
-
expect(@spies.responder.callCount).toEqual 1
|
212
|
-
|
213
|
-
it 'boots pages', ->
|
214
|
-
runs -> Joosy.Router.navigate '/page'
|
215
|
-
waits 0
|
216
|
-
runs ->
|
217
|
-
expect(@spies.responder.callCount).toEqual 1
|
218
|
-
expect(@spies.responder.args[0][0]).toEqual @Page
|
219
|
-
|
220
|
-
it 'runs lamdas', ->
|
221
|
-
runs -> Joosy.Router.navigate '/base'
|
222
|
-
waits 0
|
223
|
-
runs ->
|
224
|
-
expect(@spies.responder.callCount).toEqual 1
|
225
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.base
|
226
|
-
|
227
|
-
it 'responds namespaced routes', ->
|
228
|
-
runs -> Joosy.Router.navigate '/section/page/1'
|
229
|
-
waits 0
|
230
|
-
runs ->
|
231
|
-
expect(@spies.responder.callCount).toEqual 1
|
232
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.section
|
233
|
-
|
234
|
-
it 'parses query parametrs', ->
|
235
|
-
runs -> Joosy.Router.navigate '/?test=test&foo=bar'
|
236
|
-
waits 0
|
237
|
-
runs ->
|
238
|
-
expect(@spies.responder.callCount).toEqual 1
|
239
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.root
|
240
|
-
expect(@spies.responder.args[0][1]).toEqual {test: 'test', foo: 'bar'}
|
241
|
-
|
242
|
-
it 'parses route placeholders', ->
|
243
|
-
runs -> Joosy.Router.navigate '/section/page/1'
|
244
|
-
waits 0
|
245
|
-
runs ->
|
246
|
-
expect(@spies.responder.callCount).toEqual 1
|
247
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.section
|
248
|
-
expect(@spies.responder.args[0][1]).toEqual {id: '1'}
|
249
|
-
|
250
|
-
it 'ignores restricted routes', ->
|
251
|
-
Joosy.Router.restrict /^base/
|
201
|
+
history.pushState {}, '', pathname
|
202
|
+
waits 0
|
252
203
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
204
|
+
it 'resets', ->
|
205
|
+
runs -> Joosy.Router.navigate '/page'
|
206
|
+
waits 0
|
207
|
+
runs ->
|
208
|
+
Joosy.Router.reset()
|
209
|
+
Joosy.Router.navigate '/'
|
210
|
+
waits 0
|
211
|
+
runs ->
|
212
|
+
expect(@spies.responder.callCount).toEqual 1
|
257
213
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
214
|
+
it 'boots pages', ->
|
215
|
+
runs -> Joosy.Router.navigate '/page'
|
216
|
+
waits 0
|
217
|
+
runs ->
|
218
|
+
expect(@spies.responder.callCount).toEqual 1
|
219
|
+
expect(@spies.responder.args[0][0]).toEqual @Page
|
264
220
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
221
|
+
it 'runs lamdas', ->
|
222
|
+
runs -> Joosy.Router.navigate '/base'
|
223
|
+
waits 0
|
224
|
+
runs ->
|
225
|
+
expect(@spies.responder.callCount).toEqual 1
|
226
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.base
|
271
227
|
|
272
|
-
|
273
|
-
|
274
|
-
|
228
|
+
it 'responds namespaced routes', ->
|
229
|
+
runs -> Joosy.Router.navigate '/section/page/1'
|
230
|
+
waits 0
|
231
|
+
runs ->
|
232
|
+
expect(@spies.responder.callCount).toEqual 1
|
233
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.section
|
275
234
|
|
276
|
-
|
277
|
-
|
278
|
-
|
235
|
+
it 'parses query parametrs', ->
|
236
|
+
runs -> Joosy.Router.navigate '/?test=test&foo=bar'
|
237
|
+
waits 0
|
238
|
+
runs ->
|
239
|
+
expect(@spies.responder.callCount).toEqual 1
|
240
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.root
|
241
|
+
expect(@spies.responder.args[0][1]).toEqual {test: 'test', foo: 'bar'}
|
279
242
|
|
280
|
-
|
281
|
-
|
282
|
-
describe "#{name} prefix", ->
|
283
|
-
afterEach ->
|
284
|
-
Joosy.Router.reset()
|
285
|
-
location.hash = ''
|
286
|
-
history.pushState {}, '', pathname
|
243
|
+
it 'parses route placeholders', ->
|
244
|
+
runs -> Joosy.Router.navigate '/section/page/1'
|
287
245
|
waits 0
|
246
|
+
runs ->
|
247
|
+
expect(@spies.responder.callCount).toEqual 1
|
248
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.section
|
249
|
+
expect(@spies.responder.args[0][1]).toEqual {id: '1'}
|
288
250
|
|
289
|
-
|
290
|
-
Joosy.Router.
|
291
|
-
Joosy.Router.map @map
|
251
|
+
it 'ignores restricted routes', ->
|
252
|
+
Joosy.Router.restrict /^base/
|
292
253
|
|
293
|
-
it "is considered in path without prefix", ->
|
294
254
|
runs -> Joosy.Router.navigate '/base'
|
295
255
|
waits 0
|
296
256
|
runs ->
|
297
|
-
expect(@spies.responder.callCount).toEqual
|
298
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.base
|
257
|
+
expect(@spies.responder.callCount).toEqual 0
|
299
258
|
|
300
|
-
it
|
301
|
-
runs -> Joosy.Router.navigate '/
|
259
|
+
it 'defaults to wildcard route', ->
|
260
|
+
runs -> Joosy.Router.navigate '/trololo'
|
302
261
|
waits 0
|
303
262
|
runs ->
|
304
263
|
expect(@spies.responder.callCount).toEqual 1
|
305
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.
|
264
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.wildcard
|
306
265
|
|
307
|
-
it
|
308
|
-
runs -> Joosy.Router.navigate '/
|
266
|
+
it 'navigates', ->
|
267
|
+
runs -> Joosy.Router.navigate '/base'
|
309
268
|
waits 0
|
310
269
|
runs ->
|
270
|
+
location.pathname == '/base'
|
311
271
|
expect(@spies.responder.callCount).toEqual 1
|
312
|
-
expect(@spies.responder.args[0][0]).toEqual @spies.root
|
313
272
|
|
273
|
+
it 'defines plain helper', ->
|
274
|
+
expect(Joosy.Helpers.Routes.rootPath()).toEqual '/'
|
275
|
+
expect(Joosy.Helpers.Routes.rootUrl()).toEqual "http://#{location.host}/"
|
276
|
+
|
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"
|
280
|
+
|
281
|
+
for name, val of { html5: true, hash: false }
|
282
|
+
do (name, val) ->
|
283
|
+
if name != 'html5' || history.pushState
|
284
|
+
describe "#{name} prefix", ->
|
285
|
+
afterEach ->
|
286
|
+
Joosy.Router.reset()
|
287
|
+
location.hash = ''
|
288
|
+
history.pushState?({}, '', pathname)
|
289
|
+
waits 0
|
290
|
+
|
291
|
+
beforeEach ->
|
292
|
+
Joosy.Router.setup {html5: val, prefix: 'admin', hashSuffix: 'admin'}, @spies.responder, false
|
293
|
+
Joosy.Router.map @map
|
294
|
+
|
295
|
+
it "is considered in path without prefix", ->
|
296
|
+
runs -> Joosy.Router.navigate '/base'
|
297
|
+
waits 0
|
298
|
+
runs ->
|
299
|
+
expect(@spies.responder.callCount).toEqual 1
|
300
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.base
|
301
|
+
|
302
|
+
it "is considered in path with prefix", ->
|
303
|
+
runs -> Joosy.Router.navigate '/admin/base'
|
304
|
+
waits 0
|
305
|
+
runs ->
|
306
|
+
expect(@spies.responder.callCount).toEqual 1
|
307
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.base
|
308
|
+
|
309
|
+
it "is considered in root path", ->
|
310
|
+
runs -> Joosy.Router.navigate '/admin'
|
311
|
+
waits 0
|
312
|
+
runs ->
|
313
|
+
expect(@spies.responder.callCount).toEqual 1
|
314
|
+
expect(@spies.responder.args[0][0]).toEqual @spies.root
|
314
315
|
|
315
316
|
describe 'linker', ->
|
316
317
|
it 'defines helper', ->
|
@@ -165,7 +165,7 @@ describe "Joosy.Form", ->
|
|
165
165
|
expect(@arrayForm.$fields()[0].value).toEqual 'here'
|
166
166
|
|
167
167
|
it "should break cross-references", ->
|
168
|
-
@resource('single')('trololo', @resource)
|
168
|
+
@resource.get('single').get('trololo', @resource)
|
169
169
|
@nestedForm.fill @resource
|
170
170
|
# expect(you).toBeAlive(), lol
|
171
171
|
|
@@ -11,14 +11,10 @@ describe 'Joosy.Resources.Array', ->
|
|
11
11
|
expect(@array[1]).toEqual 2
|
12
12
|
expect(@array[2]).toEqual 3
|
13
13
|
|
14
|
-
it '
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
expect(@array.length).toEqual 3
|
19
|
-
expect(@array[0]).toEqual 1
|
20
|
-
expect(@array[1]).toEqual 2
|
21
|
-
expect(@array[2]).toEqual 3
|
14
|
+
it 'modifies', ->
|
15
|
+
@array.push 4
|
16
|
+
@array.push 5
|
17
|
+
expect(@array.length).toEqual 5
|
22
18
|
|
23
19
|
it 'triggers', ->
|
24
20
|
spy = sinon.spy()
|
@@ -2,40 +2,40 @@ describe "Joosy.Resources.Hash", ->
|
|
2
2
|
|
3
3
|
describe 'in general', ->
|
4
4
|
beforeEach ->
|
5
|
-
@hash =
|
5
|
+
@hash = Joosy.Resources.Hash.build({foo: 'bar', bar: {baz: 'yummy!'}})
|
6
6
|
|
7
7
|
it 'wraps', ->
|
8
|
-
expect(typeof(@hash)).toEqual '
|
9
|
-
expect(@hash 'foo').toEqual 'bar'
|
10
|
-
expect(@hash 'bar').toEqual {baz: 'yummy!'}
|
11
|
-
expect(@hash 'bar.baz').toEqual 'yummy!'
|
8
|
+
expect(typeof(@hash)).toEqual 'object'
|
9
|
+
expect(@hash.get 'foo').toEqual 'bar'
|
10
|
+
expect(@hash.get 'bar').toEqual {baz: 'yummy!'}
|
11
|
+
expect(@hash.get 'bar.baz').toEqual 'yummy!'
|
12
12
|
|
13
13
|
it 'sets', ->
|
14
|
-
@hash('bar.baz', 'the ignition')
|
14
|
+
@hash.set('bar.baz', 'the ignition')
|
15
15
|
expect(@hash.data.bar.baz).toEqual 'the ignition'
|
16
|
-
expect(@hash 'bar.baz').toEqual 'the ignition'
|
16
|
+
expect(@hash.get 'bar.baz').toEqual 'the ignition'
|
17
17
|
|
18
18
|
it 'gets', ->
|
19
|
-
expect(@hash 'foo.bar.baz').toBeUndefined()
|
19
|
+
expect(@hash.get 'foo.bar.baz').toBeUndefined()
|
20
20
|
expect(@hash.data.foo.bar).toBeUndefined()
|
21
21
|
|
22
22
|
it 'triggers', ->
|
23
23
|
spy = sinon.spy()
|
24
24
|
@hash.bind 'changed', spy
|
25
25
|
|
26
|
-
@hash 'bar.baz', 'rocking'
|
26
|
+
@hash.set 'bar.baz', 'rocking'
|
27
27
|
expect(spy.callCount)
|
28
28
|
|
29
29
|
describe 'nested hash', ->
|
30
30
|
beforeEach ->
|
31
|
-
@nested =
|
32
|
-
@hash =
|
31
|
+
@nested = Joosy.Resources.Hash.build(trolo: 'lo')
|
32
|
+
@hash = Joosy.Resources.Hash.build({foo: 'bar', bar: @nested})
|
33
33
|
|
34
34
|
it 'gets', ->
|
35
|
-
expect(@hash 'bar.trolo').toEqual 'lo'
|
35
|
+
expect(@hash.get 'bar.trolo').toEqual 'lo'
|
36
36
|
|
37
37
|
it 'sets', ->
|
38
|
-
@hash 'bar.trolo', 'lolo'
|
38
|
+
@hash.set 'bar.trolo', 'lolo'
|
39
39
|
expect(@nested.data.trolo).toEqual 'lolo'
|
40
40
|
|
41
41
|
describe 'filters', ->
|
@@ -45,6 +45,6 @@ describe "Joosy.Resources.Hash", ->
|
|
45
45
|
data.test = true
|
46
46
|
data
|
47
47
|
|
48
|
-
hash =
|
48
|
+
hash = Hash.build(foo: 'bar')
|
49
49
|
expect(hash.data.test).toBeTruthy()
|
50
|
-
expect(hash 'test').toBeTruthy()
|
50
|
+
expect(hash.get 'test').toBeTruthy()
|