joosy 0.1.0.RC1 → 0.1.0.RC2
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.
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -1
- data/MIT-LICENSE +2 -2
- data/README.md +89 -0
- data/app/assets/javascripts/joosy/core/application.js.coffee +25 -5
- data/app/assets/javascripts/joosy/core/form.js.coffee +212 -22
- data/app/assets/javascripts/joosy/core/helpers.js.coffee +11 -1
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +22 -17
- data/app/assets/javascripts/joosy/core/layout.js.coffee +17 -7
- data/app/assets/javascripts/joosy/core/modules/container.js.coffee +19 -15
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +10 -9
- data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +16 -12
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +8 -5
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +31 -21
- data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +114 -51
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +10 -10
- data/app/assets/javascripts/joosy/core/page.js.coffee +31 -21
- data/app/assets/javascripts/joosy/core/preloader.js.coffee +3 -3
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +137 -0
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +178 -13
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +167 -44
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +100 -32
- data/app/assets/javascripts/joosy/core/router.js.coffee +23 -25
- data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +19 -3
- data/app/assets/javascripts/joosy/core/widget.js.coffee +7 -9
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +117 -57
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +23 -24
- data/app/helpers/joosy/sprockets_helper.rb +1 -1
- data/lib/joosy/forms.rb +2 -12
- data/lib/joosy/rails/version.rb +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +1 -1
- data/spec/javascripts/joosy/core/form_spec.js.coffee +55 -12
- data/spec/javascripts/joosy/core/layout_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +0 -1
- data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +39 -3
- data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/page_spec.js.coffee +4 -1
- data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +84 -0
- data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +86 -3
- data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +15 -22
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +27 -4
- data/spec/javascripts/joosy/core/widget_spec.js.coffee +3 -14
- metadata +21 -19
- data/README.rdoc +0 -3
@@ -3,7 +3,7 @@ describe "Joosy.Form", ->
|
|
3
3
|
beforeEach ->
|
4
4
|
@server = sinon.fakeServer.create()
|
5
5
|
@seedGround()
|
6
|
-
@nudeForm = "<form id='nude'><input name='test[foo]'/><input name='test[bar]'/></form>"
|
6
|
+
@nudeForm = "<form id='nude'><input name='test[foo]'/><input name='test[bar]'/><input name='test[bool]' type='checkbox' value='1'/></form>"
|
7
7
|
@putForm = "<form id='put' method='put'><input name='test[camel_baz]'/></form>"
|
8
8
|
@moreForm = "<form id='more' method='put'><input name='test[ololo]'/></form>"
|
9
9
|
|
@@ -20,6 +20,7 @@ describe "Joosy.Form", ->
|
|
20
20
|
foo: 'foo',
|
21
21
|
bar: 'bar'
|
22
22
|
camelBaz: 'baz'
|
23
|
+
bool: true
|
23
24
|
|
24
25
|
afterEach ->
|
25
26
|
@server.restore()
|
@@ -36,7 +37,7 @@ describe "Joosy.Form", ->
|
|
36
37
|
formWithProperties = new Joosy.Form @nudeForm, invalidationClass: 'fluffy'
|
37
38
|
expect(formWithProperties.container).toEqual @nudeForm
|
38
39
|
expect(formWithProperties.invalidationClass).toEqual 'fluffy'
|
39
|
-
expect(formWithProperties.fields.length).toEqual
|
40
|
+
expect(formWithProperties.fields.length).toEqual 3
|
40
41
|
|
41
42
|
expect(@spy.callCount).toEqual 1
|
42
43
|
|
@@ -63,12 +64,15 @@ describe "Joosy.Form", ->
|
|
63
64
|
@putForm = new Joosy.Form @putForm
|
64
65
|
@moreForm = new Joosy.Form @moreForm
|
65
66
|
|
66
|
-
it "should fill form
|
67
|
+
it "should fill form, set propert action and method and store resource", ->
|
67
68
|
@nudeForm.fill @resource
|
68
69
|
expect(@nudeForm.fields[0].value).toEqual 'foo'
|
69
70
|
expect(@nudeForm.fields[1].value).toEqual 'bar'
|
71
|
+
expect(@nudeForm.fields[2].checked).toEqual true
|
72
|
+
expect(@nudeForm.fields[2].value).toEqual '1'
|
70
73
|
expect(@nudeForm.container.attr('method').toLowerCase()).toEqual 'post'
|
71
74
|
expect(@nudeForm.container.attr 'action').toEqual '/tests/'
|
75
|
+
expect(@nudeForm.__resource).toEqual @resource
|
72
76
|
|
73
77
|
it "should fill form with camelized properties", ->
|
74
78
|
@putForm.fill @resource
|
@@ -83,6 +87,7 @@ describe "Joosy.Form", ->
|
|
83
87
|
expect(@moreForm.fields[0].value).toEqual 'baz'
|
84
88
|
|
85
89
|
describe "Callbacks", ->
|
90
|
+
|
86
91
|
beforeEach ->
|
87
92
|
@nudeForm = new Joosy.Form @nudeForm, @spy=sinon.spy()
|
88
93
|
@nudeForm.fill @resource
|
@@ -97,33 +102,33 @@ describe "Joosy.Form", ->
|
|
97
102
|
expect(@spy.args[0][0]).toEqual {form: 'works'}
|
98
103
|
|
99
104
|
it "should fill class for invalidated fields by default", ->
|
100
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
105
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
101
106
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
102
107
|
|
103
108
|
it "should trigger 'error' and complete default action if it returned true", ->
|
104
109
|
@nudeForm.error = sinon.spy ->
|
105
110
|
true
|
106
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
111
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
107
112
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
108
113
|
expect(@nudeForm.error.callCount).toEqual 1
|
109
|
-
expect(@nudeForm.error.args[0][0]).toEqual
|
110
|
-
"
|
114
|
+
expect(@nudeForm.error.args[0][0]).toEqual
|
115
|
+
"foo": "error!"
|
111
116
|
|
112
117
|
it "should trigger 'error' and skip default action if it returned false", ->
|
113
118
|
@nudeForm.error = sinon.spy ->
|
114
119
|
false
|
115
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
120
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
116
121
|
expect($(@nudeForm.fields[0]).attr 'class').toNotEqual 'field_with_errors'
|
117
122
|
expect(@nudeForm.error.callCount).toEqual 1
|
118
123
|
|
119
124
|
it "should clear fields before another submit", ->
|
120
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
125
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
121
126
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
122
127
|
@nudeForm.container.submit()
|
123
128
|
expect($(@nudeForm.fields[0]).attr 'class').toNotEqual 'field_with_errors'
|
124
129
|
|
125
130
|
it "should trigger 'before' and do default action if it returns true", ->
|
126
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
131
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
127
132
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
128
133
|
@nudeForm.before = sinon.spy ->
|
129
134
|
true
|
@@ -132,10 +137,48 @@ describe "Joosy.Form", ->
|
|
132
137
|
expect(@nudeForm.before.callCount).toEqual 1
|
133
138
|
|
134
139
|
it "should trigger 'before' and skip default action if it returns false", ->
|
135
|
-
@target.respond 422, 'Content-Type': 'application/json', '{"
|
140
|
+
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
136
141
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
137
142
|
@nudeForm.before = sinon.spy ->
|
138
143
|
false
|
139
144
|
@nudeForm.container.submit()
|
140
145
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
141
|
-
expect(@nudeForm.before.callCount).toEqual 1
|
146
|
+
expect(@nudeForm.before.callCount).toEqual 1
|
147
|
+
|
148
|
+
describe "Error response handling", ->
|
149
|
+
|
150
|
+
beforeEach ->
|
151
|
+
@nudeForm = new Joosy.Form @nudeForm, @spy=sinon.spy()
|
152
|
+
|
153
|
+
it "should prepare simple response", ->
|
154
|
+
errors = {zombie: ['suck'], puppies: ['rock']}
|
155
|
+
result = @nudeForm.__stringifyErrors(errors)
|
156
|
+
|
157
|
+
expect(result).toEqual zombie: ['suck'], puppies: ['rock']
|
158
|
+
|
159
|
+
it "should prepare inline response", ->
|
160
|
+
errors = {"zombie.in1.subin1": ['suck'], "zombie.in2": ['rock']}
|
161
|
+
result = @nudeForm.__stringifyErrors(errors)
|
162
|
+
|
163
|
+
expect(result).toEqual {"zombie[in1][subin1]": ['suck'], "zombie[in2]": ['rock']}
|
164
|
+
|
165
|
+
it "should prepare inline response with resource attached", ->
|
166
|
+
@nudeForm.fill @resource
|
167
|
+
errors = {"zombie.in1.subin1": ['suck'], "zombie.in2": ['rock']}
|
168
|
+
result = @nudeForm.__stringifyErrors(errors)
|
169
|
+
|
170
|
+
expect(result).toEqual {"test[zombie][in1][subin1]": ['suck'], "test[zombie][in2]": ['rock']}
|
171
|
+
|
172
|
+
it "should prepare simple response with resource attached", ->
|
173
|
+
@nudeForm.fill @resource
|
174
|
+
errors = {zombie: ['suck'], puppies: ['rock']}
|
175
|
+
result = @nudeForm.__stringifyErrors(errors)
|
176
|
+
|
177
|
+
expect(result).toEqual { "test[zombie]": ['suck'], "test[puppies]": ['rock'] }
|
178
|
+
|
179
|
+
it "should prepare complexe response", ->
|
180
|
+
@nudeForm.fill @resource
|
181
|
+
errors = {fluffies: {zombie: {mumbas: ['ololo']}}}
|
182
|
+
result = @nudeForm.__stringifyErrors(errors)
|
183
|
+
|
184
|
+
expect(result).toEqual { "fluffies[zombie][mumbas]": ['ololo'] }
|
@@ -32,7 +32,7 @@ describe "Joosy.Layout", ->
|
|
32
32
|
|
33
33
|
it "should unload itself", ->
|
34
34
|
spies = []
|
35
|
-
spies.push sinon.spy(@box, '
|
35
|
+
spies.push sinon.spy(@box, '__clearTime')
|
36
36
|
spies.push sinon.spy(@box, '__unloadWidgets')
|
37
37
|
spies.push sinon.spy(@box, '__runAfterUnloads')
|
38
38
|
@box.__unload()
|
@@ -30,7 +30,6 @@ describe "Joosy.Modules.Container", ->
|
|
30
30
|
new_container.trigger 'test'
|
31
31
|
expect(new_container.html()).toEqual 'new content'
|
32
32
|
expect(new_container.parent().get(0)).toBe parent.get 0
|
33
|
-
expect(old_container.parent().get(0)).toBeUndefined()
|
34
33
|
expect(callback.callCount).toEqual 1
|
35
34
|
|
36
35
|
it "should inherit element declarations", ->
|
@@ -43,5 +43,5 @@ describe "Joosy.Module", ->
|
|
43
43
|
expect(TestModule[callback].getCall(0).calledOn(Klass)).toBeTruthy()
|
44
44
|
|
45
45
|
it "should have minimal set of properties", ->
|
46
|
-
expect(Object.extended(Joosy.Module).keys()).toEqual ['__namespace__', '
|
46
|
+
expect(Object.extended(Joosy.Module).keys()).toEqual ['__namespace__', '__className', 'hasAncestor', 'merge', 'include', 'extend']
|
47
47
|
expect(Object.extended(Joosy.Module.prototype).keys()).toEqual []
|
@@ -27,7 +27,7 @@ describe "Joosy.Modules.Renderer", ->
|
|
27
27
|
template = (locals) ->
|
28
28
|
"#{locals.object.value}"
|
29
29
|
|
30
|
-
@
|
30
|
+
@renderDynamic(template, locals)
|
31
31
|
|
32
32
|
elem = $("<div></div>")
|
33
33
|
@ground.append elem
|
@@ -60,7 +60,7 @@ describe "Joosy.Modules.Renderer", ->
|
|
60
60
|
template = (locals) ->
|
61
61
|
"#{locals.zombie}"
|
62
62
|
|
63
|
-
@
|
63
|
+
@renderDynamic(template, locals)
|
64
64
|
|
65
65
|
elem = $("<div></div>")
|
66
66
|
@ground.append elem
|
@@ -80,12 +80,48 @@ describe "Joosy.Modules.Renderer", ->
|
|
80
80
|
runs ->
|
81
81
|
expect(elem.text()).toBe "suck"
|
82
82
|
|
83
|
+
it "should render collections and keep html up2date", ->
|
84
|
+
class Foo extends Joosy.Resource.Generic
|
85
|
+
@entity 'foo'
|
86
|
+
|
87
|
+
data = new Joosy.Resource.Collection(Foo)
|
88
|
+
|
89
|
+
data.reset [
|
90
|
+
{ zombie: 'rock' },
|
91
|
+
{ zombie: 'never sleep' }
|
92
|
+
]
|
93
|
+
|
94
|
+
@TestContainer.view (locals) ->
|
95
|
+
template = (locals) ->
|
96
|
+
"#{locals.data[1] 'zombie'}"
|
97
|
+
|
98
|
+
@renderDynamic(template, locals)
|
99
|
+
|
100
|
+
elem = $("<div></div>")
|
101
|
+
@ground.append elem
|
102
|
+
|
103
|
+
elem.html @dummyContainer.__renderer(data)
|
104
|
+
|
105
|
+
waits 0
|
106
|
+
|
107
|
+
runs ->
|
108
|
+
expect(elem.text()).toBe "never sleep"
|
109
|
+
|
110
|
+
runs ->
|
111
|
+
data.data[1] 'zombie', 'suck'
|
112
|
+
|
113
|
+
waits 0
|
114
|
+
|
115
|
+
runs ->
|
116
|
+
expect(elem.text()).toBe "suck"
|
117
|
+
|
118
|
+
|
83
119
|
it "should debounce morpher updates", ->
|
84
120
|
@TestContainer.view (locals) ->
|
85
121
|
template = (locals) ->
|
86
122
|
"#{locals.object.value}"
|
87
123
|
|
88
|
-
@
|
124
|
+
@renderDynamic(template, locals)
|
89
125
|
|
90
126
|
elem = $("<div></div>")
|
91
127
|
@ground.append elem
|
@@ -74,7 +74,7 @@ describe "Joosy.Page", ->
|
|
74
74
|
|
75
75
|
it "should unload itself", ->
|
76
76
|
spies = []
|
77
|
-
spies.push sinon.spy(@box, '
|
77
|
+
spies.push sinon.spy(@box, '__clearTime')
|
78
78
|
spies.push sinon.spy(@box, '__unloadWidgets')
|
79
79
|
spies.push sinon.spy(@box, '__removeMetamorphs')
|
80
80
|
spies.push sinon.spy(@box, '__runAfterUnloads')
|
@@ -163,6 +163,8 @@ describe "Joosy.Page", ->
|
|
163
163
|
|
164
164
|
it "should render layout and page", ->
|
165
165
|
spies = []
|
166
|
+
|
167
|
+
@box.params = {tested: true}
|
166
168
|
|
167
169
|
spies.push @box.__layoutClass.prototype.__renderer
|
168
170
|
spies.push @box.__renderer
|
@@ -173,3 +175,4 @@ describe "Joosy.Page", ->
|
|
173
175
|
@box.__bootstrapLayout()
|
174
176
|
expect(spies).toBeSequenced()
|
175
177
|
expect(swapContainer.callCount).toEqual 2
|
178
|
+
expect(@box.layout.params).toEqual {tested: true}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
describe "Joosy.Resource.Collection", ->
|
2
|
+
|
3
|
+
class Test extends Joosy.Resource.Generic
|
4
|
+
@entity 'test'
|
5
|
+
|
6
|
+
data = '[{"id": 1, "name": "test1"}, {"id": 2, "name": "test2"}]'
|
7
|
+
|
8
|
+
checkData = (collection) ->
|
9
|
+
expect(collection.data.length).toEqual 2
|
10
|
+
expect(collection.data[0].constructor == Test).toBeTruthy()
|
11
|
+
expect(collection.data[0].e.name).toEqual 'test1'
|
12
|
+
|
13
|
+
beforeEach ->
|
14
|
+
@collection = new Joosy.Resource.Collection(Test)
|
15
|
+
|
16
|
+
it "should initialize", ->
|
17
|
+
expect(@collection.model).toEqual Test
|
18
|
+
expect(@collection.data).toEqual []
|
19
|
+
|
20
|
+
it "should modelize", ->
|
21
|
+
result = @collection.modelize $.parseJSON(data)
|
22
|
+
expect(result[0].constructor == Test).toBeTruthy()
|
23
|
+
expect(result[0].e.name).toEqual 'test1'
|
24
|
+
|
25
|
+
it "should reset", ->
|
26
|
+
@collection.reset $.parseJSON(data)
|
27
|
+
checkData @collection
|
28
|
+
|
29
|
+
it "should trigger changes", ->
|
30
|
+
@collection.bind 'changed', callback = sinon.spy()
|
31
|
+
@collection.reset $.parseJSON(data)
|
32
|
+
expect(callback.callCount).toEqual 1
|
33
|
+
|
34
|
+
it "should not trigger changes", ->
|
35
|
+
@collection.bind 'changed', callback = sinon.spy()
|
36
|
+
@collection.reset $.parseJSON(data), false
|
37
|
+
expect(callback.callCount).toEqual 0
|
38
|
+
|
39
|
+
it "should properly handle the before filter", ->
|
40
|
+
class RC extends Joosy.Resource.Collection
|
41
|
+
@beforeLoad (data) ->
|
42
|
+
data.each (entry, i) ->
|
43
|
+
data[i].tested = true
|
44
|
+
data
|
45
|
+
|
46
|
+
collection = new RC(Test)
|
47
|
+
collection.reset $.parseJSON(data)
|
48
|
+
|
49
|
+
expect(collection.at(0)('tested')).toBeTruthy()
|
50
|
+
|
51
|
+
it "should remove item from collection", ->
|
52
|
+
@collection.reset $.parseJSON(data)
|
53
|
+
@collection.bind 'changed', callback = sinon.spy()
|
54
|
+
@collection.remove @collection.data[1]
|
55
|
+
expect(@collection.data.length).toEqual 1
|
56
|
+
@collection.remove 0
|
57
|
+
expect(@collection.data.length).toEqual 0
|
58
|
+
expect(callback.callCount).toEqual 2
|
59
|
+
|
60
|
+
it "should silently remove item from collection", ->
|
61
|
+
@collection.reset $.parseJSON(data)
|
62
|
+
@collection.bind 'changed', callback = sinon.spy()
|
63
|
+
@collection.remove @collection.data[1], false
|
64
|
+
expect(@collection.data.length).toEqual 1
|
65
|
+
@collection.remove 0, false
|
66
|
+
expect(@collection.data.length).toEqual 0
|
67
|
+
expect(callback.callCount).toEqual 0
|
68
|
+
|
69
|
+
it "should add item from collection", ->
|
70
|
+
@collection.reset $.parseJSON(data)
|
71
|
+
@collection.bind 'changed', callback = sinon.spy()
|
72
|
+
@collection.add new Test {'rocking': 'mocking'}
|
73
|
+
expect(@collection.data.length).toEqual 3
|
74
|
+
expect(@collection.at(2).e).toEqual {'rocking': 'mocking'}
|
75
|
+
@collection.add new Test({'rocking': 'mocking'}), 1
|
76
|
+
expect(@collection.data.length).toEqual 4
|
77
|
+
expect(@collection.at(1).e).toEqual {'rocking': 'mocking'}
|
78
|
+
expect(@collection.at(3).e).toEqual {'rocking': 'mocking'}
|
79
|
+
|
80
|
+
it "should find items by id", ->
|
81
|
+
@collection.reset $.parseJSON(data)
|
82
|
+
|
83
|
+
expect(@collection.findById 1).toEqual @collection.data[0]
|
84
|
+
expect(@collection.findById 2).toEqual @collection.data[1]
|
@@ -11,11 +11,11 @@ describe "Joosy.Resource.Generic", ->
|
|
11
11
|
|
12
12
|
it "should remember where it belongs", ->
|
13
13
|
resource = new Joosy.Resource.Generic foo: 'bar'
|
14
|
-
expect(resource.e).toEqual
|
14
|
+
expect(resource.e).toEqual foo: 'bar'
|
15
15
|
|
16
16
|
it "should produce magic function", ->
|
17
17
|
expect(Object.isFunction @resource).toBeTruthy()
|
18
|
-
expect(@resource.e).toEqual
|
18
|
+
expect(@resource.e).toEqual @data
|
19
19
|
|
20
20
|
it "should get values", ->
|
21
21
|
expect(@resource 'foo').toEqual 'bar'
|
@@ -32,4 +32,87 @@ describe "Joosy.Resource.Generic", ->
|
|
32
32
|
expect(@resource 'very.deep').toEqual 'banana!'
|
33
33
|
|
34
34
|
@resource 'another.deep.value', 'banana strikes back'
|
35
|
-
expect(@resource 'another.deep').toEqual value: 'banana strikes back'
|
35
|
+
expect(@resource 'another.deep').toEqual value: 'banana strikes back'
|
36
|
+
|
37
|
+
it "should handle lambdas in @source properly", ->
|
38
|
+
class Fluffy extends Joosy.Resource.Generic
|
39
|
+
@source (rumbas) -> "#{rumbas}!"
|
40
|
+
|
41
|
+
clone = Fluffy.at('rumbas')
|
42
|
+
|
43
|
+
expect(-> clone.at 'kutuzka').toThrow(new Error 'clone> should be created directly (without `at\')')
|
44
|
+
expect(clone.__source).toEqual 'rumbas!'
|
45
|
+
|
46
|
+
expect(Joosy.Module.hasAncestor clone, Fluffy).toBeTruthy()
|
47
|
+
# clone won't be instanceof Fluffy in IE
|
48
|
+
#expect(clone.create({}) instanceof Fluffy).toBeTruthy()
|
49
|
+
|
50
|
+
it "should trigger 'changed' right", ->
|
51
|
+
callback = sinon.spy()
|
52
|
+
@resource.bind 'changed', callback
|
53
|
+
@resource 'foo', 'baz'
|
54
|
+
@resource 'foo', 'baz2'
|
55
|
+
|
56
|
+
expect(callback.callCount).toEqual(2)
|
57
|
+
|
58
|
+
it "should properly handle the before filter", ->
|
59
|
+
class R extends Joosy.Resource.Generic
|
60
|
+
@beforeLoad (data) ->
|
61
|
+
data ||= {}
|
62
|
+
data.tested = true
|
63
|
+
data
|
64
|
+
|
65
|
+
resource = R.create()
|
66
|
+
|
67
|
+
expect(resource 'tested').toBeTruthy()
|
68
|
+
|
69
|
+
it "should map inlines", ->
|
70
|
+
class RumbaMumba extends Joosy.Resource.Generic
|
71
|
+
@entity 'rumba_mumba'
|
72
|
+
|
73
|
+
class R extends Joosy.Resource.Generic
|
74
|
+
@map 'rumbaMumbas', RumbaMumba
|
75
|
+
|
76
|
+
resource = R.create
|
77
|
+
rumbaMumbas: [
|
78
|
+
{foo: 'bar'},
|
79
|
+
{bar: 'baz'}
|
80
|
+
]
|
81
|
+
expect(resource.rumbaMumbas instanceof Joosy.Resource.Collection).toBeTruthy()
|
82
|
+
expect(resource.rumbaMumbas.at(0)('foo')).toEqual 'bar'
|
83
|
+
|
84
|
+
|
85
|
+
it "should use magic collections", ->
|
86
|
+
class window.RumbaMumbasCollection extends Joosy.Resource.Collection
|
87
|
+
|
88
|
+
class RumbaMumba extends Joosy.Resource.Generic
|
89
|
+
@entity 'rumba_mumba'
|
90
|
+
class R extends Joosy.Resource.Generic
|
91
|
+
@map 'rumbaMumbas', RumbaMumba
|
92
|
+
|
93
|
+
resource = R.create
|
94
|
+
rumbaMumbas: [
|
95
|
+
{foo: 'bar'},
|
96
|
+
{bar: 'baz'}
|
97
|
+
]
|
98
|
+
expect(resource.rumbaMumbas instanceof RumbaMumbasCollection).toBeTruthy()
|
99
|
+
expect(resource.rumbaMumbas.at(0)('foo')).toEqual 'bar'
|
100
|
+
|
101
|
+
window.RumbaMumbasCollection = undefined
|
102
|
+
|
103
|
+
it "should use manually set collections", ->
|
104
|
+
class OloCollection extends Joosy.Resource.Collection
|
105
|
+
|
106
|
+
class RumbaMumba extends Joosy.Resource.Generic
|
107
|
+
@entity 'rumba_mumba'
|
108
|
+
@collection OloCollection
|
109
|
+
class R extends Joosy.Resource.Generic
|
110
|
+
@map 'rumbaMumbas', RumbaMumba
|
111
|
+
|
112
|
+
resource = R.create
|
113
|
+
rumbaMumbas: [
|
114
|
+
{foo: 'bar'},
|
115
|
+
{bar: 'baz'}
|
116
|
+
]
|
117
|
+
expect(resource.rumbaMumbas instanceof OloCollection).toBeTruthy()
|
118
|
+
expect(resource.rumbaMumbas.at(0)('foo')).toEqual 'bar'
|
@@ -7,7 +7,6 @@ describe "Joosy.Resource.RESTCollection", ->
|
|
7
7
|
|
8
8
|
checkData = (collection) ->
|
9
9
|
expect(collection.data.length).toEqual 2
|
10
|
-
expect(collection.pages[1]).toEqual collection.data
|
11
10
|
expect(collection.data[0].constructor == Test).toBeTruthy()
|
12
11
|
expect(collection.data[0].e.name).toEqual 'test1'
|
13
12
|
|
@@ -24,21 +23,6 @@ describe "Joosy.Resource.RESTCollection", ->
|
|
24
23
|
afterEach ->
|
25
24
|
@server.restore()
|
26
25
|
|
27
|
-
it "should initialize", ->
|
28
|
-
expect(@collection.model).toEqual Test
|
29
|
-
expect(@collection.params).toEqual Object.extended()
|
30
|
-
expect(@collection.data).toEqual []
|
31
|
-
expect(@collection.pages).toEqual Object.extended()
|
32
|
-
|
33
|
-
it "should modelize", ->
|
34
|
-
result = @collection.modelize $.parseJSON(data)
|
35
|
-
expect(result[0].constructor == Test).toBeTruthy()
|
36
|
-
expect(result[0].e.name).toEqual 'test1'
|
37
|
-
|
38
|
-
it "should reset", ->
|
39
|
-
@collection.reset $.parseJSON(data)
|
40
|
-
checkData @collection
|
41
|
-
|
42
26
|
it "should fetch", ->
|
43
27
|
@collection.fetch()
|
44
28
|
spoofData @server
|
@@ -52,14 +36,23 @@ describe "Joosy.Resource.RESTCollection", ->
|
|
52
36
|
@collection.page 2, callback=sinon.spy()
|
53
37
|
spoofData @server
|
54
38
|
expect(callback.callCount).toEqual 1
|
55
|
-
expect(@collection.data.length).toEqual
|
56
|
-
expect(@collection.data[
|
57
|
-
expect(@collection.data[
|
39
|
+
expect(@collection.data.length).toEqual 2
|
40
|
+
expect(@collection.data[0].constructor == Test).toBeTruthy()
|
41
|
+
expect(@collection.data[0].e.name).toEqual 'test1'
|
58
42
|
|
59
43
|
# Again from cache
|
60
44
|
@collection.page 2, callback=sinon.spy()
|
61
45
|
spoofData @server
|
62
46
|
expect(callback.callCount).toEqual 1
|
63
|
-
expect(@collection.data.length).toEqual
|
64
|
-
expect(@collection.data[
|
65
|
-
expect(@collection.data[
|
47
|
+
expect(@collection.data.length).toEqual 2
|
48
|
+
expect(@collection.data[0].constructor == Test).toBeTruthy()
|
49
|
+
expect(@collection.data[0].e.name).toEqual 'test1'
|
50
|
+
|
51
|
+
it "should trigger changes", ->
|
52
|
+
@collection.bind 'changed', callback = sinon.spy()
|
53
|
+
@collection.fetch()
|
54
|
+
spoofData @server
|
55
|
+
expect(callback.callCount).toEqual 1
|
56
|
+
@collection.page 2
|
57
|
+
spoofData @server
|
58
|
+
expect(callback.callCount).toEqual 2
|
@@ -14,9 +14,8 @@ describe "Joosy.Resource.REST", ->
|
|
14
14
|
it "should have appropriate accessors", ->
|
15
15
|
@Test.entity 'tada'
|
16
16
|
expect(@Test::__entityName).toEqual 'tada'
|
17
|
-
expect(@Test.entityName()).toEqual 'tada'
|
18
17
|
@Test.source 'uri'
|
19
|
-
expect(@Test
|
18
|
+
expect(@Test.__source).toEqual 'uri'
|
20
19
|
expect(@Test.__buildSource()).toEqual 'uri/'
|
21
20
|
@Test.primary 'uid'
|
22
21
|
expect(@Test::__primaryKey).toEqual 'uid'
|
@@ -48,7 +47,7 @@ describe "Joosy.Resource.REST", ->
|
|
48
47
|
@Test.beforeLoad beforeLoadCallback = sinon.spy (data) ->
|
49
48
|
expect(data.id).toEqual 1
|
50
49
|
expect(data.name).toEqual 'test1'
|
51
|
-
Object.extended(
|
50
|
+
Object.extended(data)
|
52
51
|
@Test.find 1, callback = sinon.spy (target) ->
|
53
52
|
expect(target.id).toEqual 1
|
54
53
|
expect(target.e?.name).toEqual 'test1'
|
@@ -56,13 +55,14 @@ describe "Joosy.Resource.REST", ->
|
|
56
55
|
expect(target.method).toEqual 'GET'
|
57
56
|
expect(target.url).toMatch /^\/tests\/1\?_=\d+/
|
58
57
|
target.respond 200, 'Content-Type': 'application/json',
|
59
|
-
'{"id": 1, "name": "test1"}'
|
58
|
+
'{"test": {"id": 1, "name": "test1"}}'
|
60
59
|
expect(callback.callCount).toEqual 1
|
61
60
|
expect(beforeLoadCallback.callCount).toEqual 1
|
62
61
|
|
63
62
|
it 'should find objects collection with params', ->
|
64
63
|
callback = sinon.spy (collection) ->
|
65
64
|
i = 1
|
65
|
+
expect(collection instanceof Joosy.Resource.RESTCollection).toBeTruthy()
|
66
66
|
collection.data.each (target) ->
|
67
67
|
expect(target.id).toEqual i
|
68
68
|
expect(target.e?.name).toEqual 'test' + i
|
@@ -78,6 +78,7 @@ describe "Joosy.Resource.REST", ->
|
|
78
78
|
it 'should find all objects collection', ->
|
79
79
|
callback = sinon.spy (collection) ->
|
80
80
|
i = 1
|
81
|
+
expect(collection instanceof Joosy.Resource.RESTCollection).toBeTruthy()
|
81
82
|
collection.data.each (target) ->
|
82
83
|
expect(target.id).toEqual i
|
83
84
|
expect(target.e?.name).toEqual 'test' + i
|
@@ -106,3 +107,25 @@ describe "Joosy.Resource.REST", ->
|
|
106
107
|
expect(@Test.__isId variant).toBeTruthy()
|
107
108
|
[(->) , [], {}, null, undefined, true, false].each (variant) =>
|
108
109
|
expect(@Test.__isId variant).toBeFalsy()
|
110
|
+
|
111
|
+
it "should trigger 'changed' on fetch", ->
|
112
|
+
resource = @Test.find 1, callback = sinon.spy (target) ->
|
113
|
+
expect(target.id).toEqual 1
|
114
|
+
expect(target.e?.name).toEqual 'test1'
|
115
|
+
target = @server.requests[0]
|
116
|
+
expect(target.method).toEqual 'GET'
|
117
|
+
expect(target.url).toMatch /^\/tests\/1\?_=\d+/
|
118
|
+
target.respond 200, 'Content-Type': 'application/json',
|
119
|
+
'{"test": {"id": 1, "name": "test1"}}'
|
120
|
+
expect(callback.callCount).toEqual 1
|
121
|
+
|
122
|
+
resource.bind 'changed', callback = sinon.spy()
|
123
|
+
resource.fetch()
|
124
|
+
|
125
|
+
target = @server.requests[1]
|
126
|
+
expect(target.method).toEqual 'GET'
|
127
|
+
expect(target.url).toMatch /^\/tests\/1\?_=\d+/
|
128
|
+
target.respond 200, 'Content-Type': 'application/json',
|
129
|
+
'{"test": {"id": 1, "name": "test1"}}'
|
130
|
+
|
131
|
+
expect(callback.callCount).toEqual 1
|
@@ -11,19 +11,6 @@ describe "Joosy.Widget", ->
|
|
11
11
|
@TestWidget.view 'test'
|
12
12
|
expect(@TestWidget::__renderer instanceof Function).toBeTruthy()
|
13
13
|
|
14
|
-
it "should use parent's TimeManager", ->
|
15
|
-
@box.parent =
|
16
|
-
setInterval: sinon.spy()
|
17
|
-
setTimeout: sinon.spy()
|
18
|
-
@box.setInterval 1, 2, 3
|
19
|
-
@box.setTimeout 1, 2, 3
|
20
|
-
target = @box.parent.setInterval
|
21
|
-
expect(target.callCount).toEqual 1
|
22
|
-
expect(target.alwaysCalledWithExactly 1, 2, 3).toBeTruthy()
|
23
|
-
target = @box.parent.setTimeout
|
24
|
-
expect(target.callCount).toEqual 1
|
25
|
-
expect(target.alwaysCalledWithExactly 1, 2, 3).toBeTruthy()
|
26
|
-
|
27
14
|
it "should use Router", ->
|
28
15
|
target = sinon.stub Joosy.Router, 'navigate'
|
29
16
|
@box.navigate 'there'
|
@@ -32,6 +19,7 @@ describe "Joosy.Widget", ->
|
|
32
19
|
Joosy.Router.navigate.restore()
|
33
20
|
|
34
21
|
it "should load itself", ->
|
22
|
+
@box.data = {tested: true}
|
35
23
|
spies = [sinon.spy()]
|
36
24
|
@TestWidget.view spies[0]
|
37
25
|
@parent = new Joosy.Layout()
|
@@ -41,6 +29,7 @@ describe "Joosy.Widget", ->
|
|
41
29
|
target = @box.__load @parent, @ground
|
42
30
|
expect(target).toBe @box
|
43
31
|
expect(@box.__renderer.getCall(0).calledOn()).toBeFalsy()
|
32
|
+
expect(@box.__renderer.getCall(0).args[0]).toEqual {tested: true}
|
44
33
|
expect(spies).toBeSequenced()
|
45
34
|
|
46
35
|
it "should unload itself", ->
|
@@ -48,4 +37,4 @@ describe "Joosy.Widget", ->
|
|
48
37
|
@box.__unload()
|
49
38
|
target = @box.__runAfterUnloads
|
50
39
|
expect(target.callCount).toEqual 1
|
51
|
-
expect(target.getCall(0).calledOn()).toBeFalsy()
|
40
|
+
expect(target.getCall(0).calledOn()).toBeFalsy()
|