joosy 1.0.0.RC4 → 1.0.0.RC5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +99 -82
- data/README.md +1 -1
- data/app/assets/javascripts/joosy/core/application.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/form.js.coffee +35 -22
- data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +38 -9
- data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +10 -4
- data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +6 -1
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +5 -3
- data/app/assets/javascripts/joosy/core/layout.js.coffee +5 -5
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +28 -10
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +1 -1
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +1 -1
- data/app/assets/javascripts/joosy/core/page.js.coffee +1 -1
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +18 -18
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +21 -19
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +26 -14
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/router.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/widget.js.coffee +3 -0
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +7 -7
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +5 -5
- data/lib/joosy/rails/version.rb +1 -1
- data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +2 -2
- data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +5 -5
- data/lib/rails/generators/joosy/templates/app/routes.js.coffee +2 -2
- data/lib/rails/generators/joosy/templates/preload.html.slim +19 -0
- data/lib/rails/resources_with_joosy.rb +2 -2
- data/spec/javascripts/helpers/spec_helper.js.coffee +19 -0
- data/spec/javascripts/joosy/core/form_spec.js.coffee +36 -16
- data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +28 -23
- data/spec/javascripts/joosy/core/helpers/widgets_spec.js.coffee +17 -0
- data/spec/javascripts/joosy/core/joosy_spec.js.coffee +2 -0
- data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +35 -1
- data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +29 -29
- data/spec/javascripts/joosy/core/page_spec.js.coffee +2 -2
- data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +14 -9
- data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +19 -19
- data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +0 -1
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +9 -3
- data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +7 -7
- data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +5 -5
- data/spec/javascripts/support/sinon-1.3.1.js +6 -6
- data/spec/javascripts/support/sinon-ie-1.3.1.js +5 -5
- metadata +22 -20
@@ -3,12 +3,12 @@ Joosy.namespace 'Welcome', ->
|
|
3
3
|
class @IndexPage extends ApplicationPage
|
4
4
|
@layout ApplicationLayout
|
5
5
|
@view 'index'
|
6
|
-
|
6
|
+
|
7
7
|
@afterLoad ->
|
8
8
|
@startHeartbeat()
|
9
|
-
@content.css
|
9
|
+
@content.css
|
10
10
|
'padding-top': "#{$(window).height() / 2 - 160}px"
|
11
|
-
|
11
|
+
|
12
12
|
elements:
|
13
13
|
content: '#content'
|
14
14
|
joosy: '.joosy'
|
@@ -16,7 +16,7 @@ Joosy.namespace 'Welcome', ->
|
|
16
16
|
events:
|
17
17
|
'mouseover $joosy': -> clearInterval @heartbeat
|
18
18
|
'mouseout $joosy': 'startHeartbeat'
|
19
|
-
|
19
|
+
|
20
20
|
startHeartbeat: ->
|
21
21
|
@heartbeat = @setInterval 1500, =>
|
22
|
-
@joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
|
22
|
+
@joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title = file_path
|
5
|
+
|
6
|
+
:javascript
|
7
|
+
window.joosy = {
|
8
|
+
libraries: #{extract_sources_and_sizes_from_include_tag('<%= file_path %>')}
|
9
|
+
};
|
10
|
+
|
11
|
+
= stylesheet_link_tag 'application'
|
12
|
+
= csrf_meta_tags
|
13
|
+
|
14
|
+
body
|
15
|
+
= javascript_include_tag '<%= file_path %>_preloader'
|
16
|
+
#application
|
17
|
+
#preloader
|
18
|
+
Loading application...
|
19
|
+
span#percents 0%
|
@@ -3,8 +3,8 @@ require 'action_dispatch/routing/mapper'
|
|
3
3
|
module ActionDispatch::Routing::Mapper::Resources
|
4
4
|
def resources_with_joosy(*resources, &block)
|
5
5
|
resources_without_joosy(*resources, &block).tap do
|
6
|
-
namespace = Joosy::Rails::Engine.resources[@scope[:module]] ||= {}
|
7
|
-
namespace[resources[0].to_s.singularize] = "#{@scope[:
|
6
|
+
namespace = Joosy::Rails::Engine.resources[@scope[:module].to_s] ||= {}
|
7
|
+
namespace[resources[0].to_s.singularize] = "#{@scope[:path]}/#{resources[0]}"
|
8
8
|
end
|
9
9
|
end
|
10
10
|
alias_method_chain :resources, :joosy
|
@@ -45,5 +45,24 @@ beforeEach ->
|
|
45
45
|
return false
|
46
46
|
return true
|
47
47
|
|
48
|
+
toBeTag: (tagName, content, attrs) ->
|
49
|
+
@message = =>
|
50
|
+
"Expected #{@actual} to be a tag #{tagName} with attributes #{JSON.stringify attrs} and content #{content}"
|
51
|
+
|
52
|
+
tag = $ @actual
|
53
|
+
flag = true
|
54
|
+
|
55
|
+
flag = flag && tag.length == 1
|
56
|
+
flag = flag && tag[0].nodeName == tagName.toUpperCase()
|
57
|
+
if content != false
|
58
|
+
flag = flag && tag.html() == content
|
59
|
+
|
60
|
+
for name, val of attrs
|
61
|
+
flag = flag && !!(if val.constructor == RegExp then tag.attr(name).match(val) else tag.attr(name) == val)
|
62
|
+
|
63
|
+
flag = flag && tag[0].attributes.length == Object.keys(attrs).length
|
64
|
+
|
65
|
+
flag
|
66
|
+
|
48
67
|
afterEach ->
|
49
68
|
@ground.remove() unless @polluteGround
|
@@ -3,30 +3,34 @@ 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]'/><input name='test[bool]' type='checkbox' value='1'/></form>"
|
6
|
+
@nudeForm = "<form id='nude'><input name='test[foo]'/><input name='test[bar]'/><input name='test[bool]' type='checkbox' value='1'/><input name='test[set]' type='radio' value='qwe' /><input name='test[set]' type='radio' value='zxc' /></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
|
@nestedForm = "<form id='nested'><input name='test[zee][capped][test]'/><input name='test[items_attributes][0][attr]'/><input name='test[items_attributes][1][attr]'/><input name='test[single_attributes][0][attr]'/></form>"
|
10
10
|
@exactForm = "<form id='exact'><input name='test[EXact][MATCH]'/></form>"
|
11
|
+
@arrayForm = "<form id='array'><input name='test[arr][1][0][1]'/></form>"
|
11
12
|
|
12
|
-
@ground.find('#sidebar').after(@nudeForm).after(@putForm).after(@moreForm).after(@nestedForm).after(@exactForm)
|
13
|
+
@ground.find('#sidebar').after(@nudeForm).after(@putForm).after(@moreForm).after(@nestedForm).after(@exactForm).after(@arrayForm)
|
13
14
|
|
14
15
|
@nudeForm = $('#nude')
|
15
16
|
@putForm = $('#put')
|
16
17
|
@moreForm = $('#more')
|
17
18
|
@nestedForm = $('#nested')
|
18
19
|
@exactForm = $('#exact')
|
20
|
+
@arrayForm = $('#array')
|
19
21
|
|
20
22
|
class Test extends Joosy.Resource.REST
|
21
23
|
@entity 'test'
|
22
24
|
@Test = Test
|
23
25
|
|
24
26
|
@resource = Test.build
|
27
|
+
arr: [null, [[null, 'here']]]
|
25
28
|
id: 1,
|
26
29
|
foo: 'foo',
|
27
30
|
bar: 'bar'
|
28
31
|
camelBaz: 'baz'
|
29
32
|
bool: true
|
33
|
+
set: 'zxc'
|
30
34
|
zee:
|
31
35
|
capped:
|
32
36
|
test: 'test'
|
@@ -50,7 +54,7 @@ describe "Joosy.Form", ->
|
|
50
54
|
formWithProperties = new Joosy.Form @nudeForm, invalidationClass: 'fluffy'
|
51
55
|
expect(formWithProperties.container).toEqual @nudeForm
|
52
56
|
expect(formWithProperties.invalidationClass).toEqual 'fluffy'
|
53
|
-
expect(formWithProperties.fields.length).toEqual
|
57
|
+
expect(formWithProperties.fields.length).toEqual 5
|
54
58
|
|
55
59
|
expect(@spy.callCount).toEqual 1
|
56
60
|
|
@@ -78,6 +82,7 @@ describe "Joosy.Form", ->
|
|
78
82
|
@moreForm = new Joosy.Form @moreForm
|
79
83
|
@nestedForm = new Joosy.Form @nestedForm
|
80
84
|
@exactForm = new Joosy.Form @exactForm
|
85
|
+
@arrayForm = new Joosy.Form @arrayForm
|
81
86
|
|
82
87
|
it "should fill form, set proper action and method and store resource", ->
|
83
88
|
@nudeForm.fill @resource
|
@@ -85,6 +90,10 @@ describe "Joosy.Form", ->
|
|
85
90
|
expect(@nudeForm.fields[1].value).toEqual 'bar'
|
86
91
|
expect(@nudeForm.fields[2].checked).toEqual true
|
87
92
|
expect(@nudeForm.fields[2].value).toEqual '1'
|
93
|
+
expect(@nudeForm.fields[3].value).toEqual 'qwe'
|
94
|
+
expect(@nudeForm.fields[3].checked).toEqual false
|
95
|
+
expect(@nudeForm.fields[4].value).toEqual 'zxc'
|
96
|
+
expect(@nudeForm.fields[4].checked).toEqual true
|
88
97
|
expect(@nudeForm.container.attr('method').toLowerCase()).toEqual 'post'
|
89
98
|
expect(@nudeForm.container.attr 'action').toEqual '/tests/1'
|
90
99
|
expect(@nudeForm.__resource).toEqual @resource
|
@@ -100,14 +109,14 @@ describe "Joosy.Form", ->
|
|
100
109
|
expect(@exactForm.fields[0].value).toEqual 'works'
|
101
110
|
|
102
111
|
it "should fill form with decorator", ->
|
103
|
-
@moreForm.fill @resource,
|
112
|
+
@moreForm.fill @resource,
|
104
113
|
decorator: (e) ->
|
105
114
|
e.ololo = e.camelBaz
|
106
115
|
e
|
107
116
|
expect(@moreForm.fields[0].value).toEqual 'baz'
|
108
117
|
|
109
118
|
it "should fill form with extended action", ->
|
110
|
-
@nudeForm.fill @resource,
|
119
|
+
@nudeForm.fill @resource,
|
111
120
|
action: @resource.memberPath(from: 'calculate')
|
112
121
|
expect(@nudeForm.fields[0].value).toEqual 'foo'
|
113
122
|
expect(@nudeForm.fields[1].value).toEqual 'bar'
|
@@ -115,7 +124,7 @@ describe "Joosy.Form", ->
|
|
115
124
|
|
116
125
|
resource = @Test.build 'someId'
|
117
126
|
|
118
|
-
@nudeForm.fill resource,
|
127
|
+
@nudeForm.fill resource,
|
119
128
|
action: resource.memberPath(from: 'calculate')
|
120
129
|
expect(@nudeForm.container.attr 'action').toEqual '/tests/someId/calculate'
|
121
130
|
|
@@ -141,6 +150,10 @@ describe "Joosy.Form", ->
|
|
141
150
|
expect(@nestedForm.fields[2].value).toEqual 'two'
|
142
151
|
expect(@nestedForm.fields[3].value).toEqual 'sin'
|
143
152
|
|
153
|
+
it 'should fill array-like attributes', ->
|
154
|
+
@arrayForm.fill @resource
|
155
|
+
expect(@arrayForm.fields[0].value).toEqual 'here'
|
156
|
+
|
144
157
|
it "should break cross-references", ->
|
145
158
|
@resource('single')('trololo', @resource)
|
146
159
|
@nestedForm.fill @resource
|
@@ -204,41 +217,48 @@ describe "Joosy.Form", ->
|
|
204
217
|
@nudeForm.container.submit()
|
205
218
|
expect($(@nudeForm.fields[0]).attr 'class').toEqual 'field_with_errors'
|
206
219
|
expect(@nudeForm.before.callCount).toEqual 1
|
207
|
-
|
220
|
+
|
208
221
|
describe "Error response handling", ->
|
209
|
-
|
222
|
+
|
210
223
|
beforeEach ->
|
211
224
|
@nudeForm = new Joosy.Form @nudeForm, @spy=sinon.spy()
|
212
|
-
|
225
|
+
|
213
226
|
it "should prepare simple response", ->
|
214
227
|
errors = {zombie: ['suck'], puppies: ['rock']}
|
215
228
|
result = @nudeForm.__stringifyErrors(errors)
|
216
|
-
|
229
|
+
|
217
230
|
expect(result).toEqual zombie: ['suck'], puppies: ['rock']
|
218
|
-
|
231
|
+
|
219
232
|
it "should prepare inline response", ->
|
220
233
|
errors = {"zombie.in1.subin1": ['suck'], "zombie.in2": ['rock']}
|
221
234
|
result = @nudeForm.__stringifyErrors(errors)
|
222
|
-
|
235
|
+
|
223
236
|
expect(result).toEqual {"zombie[in1][subin1]": ['suck'], "zombie[in2]": ['rock']}
|
224
|
-
|
237
|
+
|
225
238
|
it "should prepare inline response with resource attached", ->
|
226
239
|
@nudeForm.fill @resource
|
227
240
|
errors = {"zombie.in1.subin1": ['suck'], "zombie.in2": ['rock']}
|
228
241
|
result = @nudeForm.__stringifyErrors(errors)
|
229
242
|
|
230
243
|
expect(result).toEqual {"test[zombie][in1][subin1]": ['suck'], "test[zombie][in2]": ['rock']}
|
231
|
-
|
244
|
+
|
232
245
|
it "should prepare simple response with resource attached", ->
|
233
246
|
@nudeForm.fill @resource
|
234
247
|
errors = {zombie: ['suck'], puppies: ['rock']}
|
235
248
|
result = @nudeForm.__stringifyErrors(errors)
|
236
249
|
|
237
250
|
expect(result).toEqual { "test[zombie]": ['suck'], "test[puppies]": ['rock'] }
|
238
|
-
|
251
|
+
|
239
252
|
it "should prepare complexe response", ->
|
240
253
|
@nudeForm.fill @resource
|
241
254
|
errors = {fluffies: {zombie: {mumbas: ['ololo']}}}
|
242
255
|
result = @nudeForm.__stringifyErrors(errors)
|
243
256
|
|
244
|
-
expect(result).toEqual { "fluffies[zombie][mumbas]": ['ololo'] }
|
257
|
+
expect(result).toEqual { "fluffies[zombie][mumbas]": ['ololo'] }
|
258
|
+
|
259
|
+
it "should prepare nested response", ->
|
260
|
+
@nestedForm = new Joosy.Form @nestedForm
|
261
|
+
@nestedForm.fill @resource
|
262
|
+
errors = {test: {items_attributes: [{attr: ['first']}, {attr: ['second']}]}}
|
263
|
+
result = @nestedForm.__stringifyErrors(errors)
|
264
|
+
expect(result).toEqual { "test[items_attributes][0][attr]": ['first'], "test[items_attributes][1][attr]": ['second'] }
|
@@ -1,23 +1,4 @@
|
|
1
1
|
describe "Joosy.Helpers.Form", ->
|
2
|
-
beforeEach ->
|
3
|
-
@addMatchers toBeTag: (tagName, content, attrs) ->
|
4
|
-
@message = =>
|
5
|
-
"Expected #{@actual} to be a tag #{tagName} with attributes #{JSON.stringify attrs} and content #{content}"
|
6
|
-
|
7
|
-
tag = $ @actual
|
8
|
-
flag = true
|
9
|
-
|
10
|
-
flag = flag && tag.length == 1
|
11
|
-
flag = flag && tag[0].nodeName == tagName.toUpperCase()
|
12
|
-
flag = flag && tag.html() == content
|
13
|
-
|
14
|
-
for name, val of attrs
|
15
|
-
flag = flag && tag.attr(name) == val
|
16
|
-
|
17
|
-
flag = flag && tag[0].attributes.length == Object.keys(attrs).length
|
18
|
-
|
19
|
-
flag
|
20
|
-
|
21
2
|
class Test extends Joosy.Resource.Generic
|
22
3
|
@entity 'test'
|
23
4
|
|
@@ -34,6 +15,7 @@ describe "Joosy.Helpers.Form", ->
|
|
34
15
|
expect(h.textField 'a', '[b][c]', {a: 'b'}).toBeTag 'input', '', id: 'a_b_c', name: 'a[b][c]', a: 'b', type: 'text'
|
35
16
|
|
36
17
|
it "renders label", ->
|
18
|
+
expect(h.label 'a', 'b', 'test').toBeTag 'label', 'test', for: 'a_b'
|
37
19
|
expect(h.label 'a', 'b', {a: 'b'}, 'test').toBeTag 'label', 'test', for: 'a_b', a: 'b'
|
38
20
|
|
39
21
|
it "renders checkBox", ->
|
@@ -43,11 +25,26 @@ describe "Joosy.Helpers.Form", ->
|
|
43
25
|
expect(tags[1]).toBeTag 'input', '', value: '1', id: 'a_b', name: 'a[b]', type: 'checkbox', a: 'b'
|
44
26
|
|
45
27
|
it "renders radioButton", ->
|
46
|
-
expect(h.radioButton 'a', 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: '
|
28
|
+
expect(h.radioButton 'a', 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: 'a_b_test', name: 'a[b]', type: 'radio', a: 'b'
|
47
29
|
|
48
30
|
it "renders textArea", ->
|
49
31
|
expect(h.textArea 'a', 'b', {a: 'b', value: 'foo'}).toBeTag 'textarea', 'foo', id: 'a_b', name: 'a[b]', a: 'b'
|
50
32
|
|
33
|
+
it "renders select with options object", ->
|
34
|
+
expect(tag = h.select 'a', 'b', {a: 'b', c: 'd'}, {a: 'b', value: 'c', includeBlank: true}).toBeTag 'select', false, id: 'a_b', name: 'a[b]', a: 'b'
|
35
|
+
opts = $ $(tag).html()
|
36
|
+
expect(opts.length).toEqual 3
|
37
|
+
expect(opts[0]).toBeTag 'option', '', value: ''
|
38
|
+
expect(opts[1]).toBeTag 'option', 'b', value: 'a'
|
39
|
+
expect(opts[2]).toBeTag 'option', 'd', value: 'c', selected: 'selected'
|
40
|
+
|
41
|
+
it "renders select with options array", ->
|
42
|
+
expect(tag = h.select 'a', 'b', [['b', 'a'], ['d', 'c']], {a: 'b'}).toBeTag 'select', false, id: 'a_b', name: 'a[b]', a: 'b'
|
43
|
+
opts = $ $(tag).html()
|
44
|
+
expect(opts.length).toEqual 2
|
45
|
+
expect(opts[0]).toBeTag 'option', 'b', value: 'a'
|
46
|
+
expect(opts[1]).toBeTag 'option', 'd', value: 'c'
|
47
|
+
|
51
48
|
it "renders formFor", ->
|
52
49
|
callback = sinon.spy()
|
53
50
|
expect(h.formFor resource, callback).toMatch /<form id=".*"><\/form>/
|
@@ -64,6 +61,7 @@ describe "Joosy.Helpers.Form", ->
|
|
64
61
|
expect(form["#{type}Field"] 'b', {a: 'b'}).toBeTag 'input', '', id: 'test_b', name: 'test[b]', a: 'b', type: type
|
65
62
|
|
66
63
|
it "renders label", ->
|
64
|
+
expect(form.label 'b', 'test').toBeTag 'label', 'test', for: 'test_b'
|
67
65
|
expect(form.label 'b', {a: 'b'}, 'test').toBeTag 'label', 'test', for: 'test_b', a: 'b'
|
68
66
|
|
69
67
|
it "renders checkBox", ->
|
@@ -73,11 +71,14 @@ describe "Joosy.Helpers.Form", ->
|
|
73
71
|
expect(tags[1]).toBeTag 'input', '', value: '1', id: 'test_b', name: 'test[b]', type: 'checkbox', a: 'b'
|
74
72
|
|
75
73
|
it "renders radioButton", ->
|
76
|
-
expect(form.radioButton 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: '
|
74
|
+
expect(form.radioButton 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: 'test_b_test', name: 'test[b]', type: 'radio', a: 'b'
|
77
75
|
|
78
76
|
it "renders textArea", ->
|
79
77
|
expect(form.textArea 'b', {a: 'b', value: 'foo'}).toBeTag 'textarea', 'foo', id: 'test_b', name: 'test[b]', a: 'b'
|
80
78
|
|
79
|
+
it "renders select", ->
|
80
|
+
expect(form.select 'b', {a: 'b', c: 'd'}, {a: 'b'}).toBeTag 'select', false, id: 'test_b', name: 'test[b]', a: 'b'
|
81
|
+
|
81
82
|
describe "resource with extendIds", ->
|
82
83
|
callback = sinon.spy()
|
83
84
|
h.formFor(resource, extendIds: true, callback)
|
@@ -88,6 +89,7 @@ describe "Joosy.Helpers.Form", ->
|
|
88
89
|
expect(form["#{type}Field"] 'b', {a: 'b'}).toBeTag 'input', '', id: 'test_1_b', name: 'test[b]', a: 'b', type: type
|
89
90
|
|
90
91
|
it "renders label", ->
|
92
|
+
expect(form.label 'b', 'test').toBeTag 'label', 'test', for: 'test_1_b'
|
91
93
|
expect(form.label 'b', {a: 'b'}, 'test').toBeTag 'label', 'test', for: 'test_1_b', a: 'b'
|
92
94
|
|
93
95
|
it "renders checkBox", ->
|
@@ -97,7 +99,10 @@ describe "Joosy.Helpers.Form", ->
|
|
97
99
|
expect(tags[1]).toBeTag 'input', '', value: '1', id: 'test_1_b', name: 'test[b]', type: 'checkbox', a: 'b'
|
98
100
|
|
99
101
|
it "renders radioButton", ->
|
100
|
-
expect(form.radioButton 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: '
|
102
|
+
expect(form.radioButton 'b', 'test', {a: 'b'}).toBeTag 'input', '', value: 'test', id: 'test_1_b_test', name: 'test[b]', type: 'radio', a: 'b'
|
101
103
|
|
102
104
|
it "renders textArea", ->
|
103
|
-
expect(form.textArea 'b', {a: 'b', value: 'foo'}).toBeTag 'textarea', 'foo', id: 'test_1_b', name: 'test[b]', a: 'b'
|
105
|
+
expect(form.textArea 'b', {a: 'b', value: 'foo'}).toBeTag 'textarea', 'foo', id: 'test_1_b', name: 'test[b]', a: 'b'
|
106
|
+
|
107
|
+
it "renders select", ->
|
108
|
+
expect(form.select 'b', {a: 'b', c: 'd'}, {a: 'b'}).toBeTag 'select', false, id: 'test_1_b', name: 'test[b]', a: 'b'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe "Joosy.Helpers.Widgets", ->
|
2
|
+
|
3
|
+
h = Joosy.Helpers.Application
|
4
|
+
|
5
|
+
beforeEach ->
|
6
|
+
h.onRefresh = sinon.spy()
|
7
|
+
|
8
|
+
afterEach ->
|
9
|
+
delete h.onRefresh
|
10
|
+
|
11
|
+
it "renders widget tag", ->
|
12
|
+
expect(h.widget 'div', (->)).toBeTag 'div', '', id: /\S{36}/
|
13
|
+
expect(h.onRefresh.callCount).toEqual 1
|
14
|
+
|
15
|
+
it "renders widget tag with given classes", ->
|
16
|
+
expect(h.widget 'div.class1.class2', (->)).toBeTag 'div', '', id: /\S{36}/, class: 'class1 class2'
|
17
|
+
expect(h.onRefresh.callCount).toEqual 1
|
@@ -76,9 +76,11 @@ describe "Joosy", ->
|
|
76
76
|
Joosy.defineResource 'foo', '', container
|
77
77
|
expect(Object.isFunction container.Foo).toBeTruthy()
|
78
78
|
expect(Object.isFunction container.FoosCollection).toBeTruthy()
|
79
|
+
expect(container.Foo::__collection()).toEqual container.FoosCollection
|
79
80
|
Joosy.defineResource 'boo'
|
80
81
|
expect(Object.isFunction Boo).toBeTruthy()
|
81
82
|
expect(Object.isFunction BoosCollection).toBeTruthy()
|
83
|
+
expect(Boo::__collection()).toEqual BoosCollection
|
82
84
|
|
83
85
|
it "should define resource", ->
|
84
86
|
window.Defined = 'this'
|
@@ -11,7 +11,7 @@ describe "Joosy.Modules.Events", ->
|
|
11
11
|
it "should run callback once when the all listed events have occurred", ->
|
12
12
|
callback = sinon.spy()
|
13
13
|
|
14
|
-
@box.wait 'events list', callback
|
14
|
+
@box.wait ' events list ', callback
|
15
15
|
|
16
16
|
@box.trigger 'events'
|
17
17
|
expect(callback.callCount).toEqual 0
|
@@ -23,6 +23,15 @@ describe "Joosy.Modules.Events", ->
|
|
23
23
|
@box.trigger 'list'
|
24
24
|
expect(callback.callCount).toEqual 1
|
25
25
|
|
26
|
+
expect(=> @box.wait '', callback).toThrow()
|
27
|
+
expect(callback.callCount).toEqual 1
|
28
|
+
|
29
|
+
expect(=> @box.wait ' ', callback).toThrow()
|
30
|
+
expect(callback.callCount).toEqual 1
|
31
|
+
|
32
|
+
expect(=> @box.wait [], callback).toThrow()
|
33
|
+
expect(callback.callCount).toEqual 1
|
34
|
+
|
26
35
|
it "should allow for binding and unbinding to events", ->
|
27
36
|
callback = sinon.spy()
|
28
37
|
|
@@ -64,3 +73,28 @@ describe "Joosy.Modules.Events", ->
|
|
64
73
|
expect(-> done()).not.toThrow()
|
65
74
|
, 2
|
66
75
|
waits 3
|
76
|
+
|
77
|
+
it "should call finalizer", ->
|
78
|
+
callback = sinon.spy()
|
79
|
+
|
80
|
+
Joosy.synchronize (context) ->
|
81
|
+
context.do (done) ->
|
82
|
+
callback()
|
83
|
+
done()
|
84
|
+
context.after ->
|
85
|
+
expect(callback.callCount).toEqual 1
|
86
|
+
callback()
|
87
|
+
|
88
|
+
waits 1
|
89
|
+
expect(callback.callCount).toEqual 2
|
90
|
+
|
91
|
+
it "should call finalizer even if context.do hasn't been called", ->
|
92
|
+
callback = sinon.spy()
|
93
|
+
|
94
|
+
Joosy.synchronize (context) ->
|
95
|
+
context.after ->
|
96
|
+
expect(callback.callCount).toEqual 0
|
97
|
+
callback()
|
98
|
+
|
99
|
+
waits 1
|
100
|
+
expect(callback.callCount).toEqual 1
|
@@ -37,21 +37,21 @@ describe "Joosy.Modules.Renderer", ->
|
|
37
37
|
@dummyObject.update "new"
|
38
38
|
|
39
39
|
waits 0
|
40
|
-
|
40
|
+
|
41
41
|
runs ->
|
42
42
|
expect(elem.text()).toBe "new"
|
43
|
-
|
43
|
+
|
44
44
|
waits 0
|
45
|
-
|
45
|
+
|
46
46
|
runs ->
|
47
47
|
@dummyContainer.__removeMetamorphs()
|
48
48
|
@dummyObject.update "afterwards"
|
49
|
-
|
49
|
+
|
50
50
|
waits 0
|
51
|
-
|
51
|
+
|
52
52
|
runs ->
|
53
53
|
expect(elem.text()).toBe "new"
|
54
|
-
|
54
|
+
|
55
55
|
it "renders resources and keep html up2date", ->
|
56
56
|
data = Joosy.Resource.Generic.build zombie: 'rock'
|
57
57
|
|
@@ -62,18 +62,18 @@ describe "Joosy.Modules.Renderer", ->
|
|
62
62
|
|
63
63
|
elem = $("<div></div>")
|
64
64
|
@ground.append elem
|
65
|
-
|
65
|
+
|
66
66
|
elem.html @dummyContainer.__renderer(data)
|
67
|
-
|
67
|
+
|
68
68
|
waits 0
|
69
69
|
|
70
|
-
runs ->
|
70
|
+
runs ->
|
71
71
|
expect(elem.text()).toBe "rock"
|
72
|
-
|
72
|
+
|
73
73
|
runs ->
|
74
74
|
data 'zombie', 'suck'
|
75
|
-
|
76
|
-
waits 0
|
75
|
+
|
76
|
+
waits 0
|
77
77
|
|
78
78
|
runs ->
|
79
79
|
expect(elem.text()).toBe "suck"
|
@@ -83,7 +83,7 @@ describe "Joosy.Modules.Renderer", ->
|
|
83
83
|
@entity 'foo'
|
84
84
|
|
85
85
|
data = new Joosy.Resource.Collection(Foo)
|
86
|
-
|
86
|
+
|
87
87
|
data.load [
|
88
88
|
{ zombie: 'rock' },
|
89
89
|
{ zombie: 'never sleep' }
|
@@ -101,14 +101,14 @@ describe "Joosy.Modules.Renderer", ->
|
|
101
101
|
|
102
102
|
waits 0
|
103
103
|
|
104
|
-
runs ->
|
104
|
+
runs ->
|
105
105
|
expect(elem.text()).toBe "never sleep"
|
106
106
|
|
107
107
|
runs ->
|
108
108
|
data.data[1] 'zombie', 'suck'
|
109
|
-
|
110
|
-
waits 0
|
111
|
-
|
109
|
+
|
110
|
+
waits 0
|
111
|
+
|
112
112
|
runs ->
|
113
113
|
expect(elem.text()).toBe "suck"
|
114
114
|
|
@@ -116,33 +116,33 @@ describe "Joosy.Modules.Renderer", ->
|
|
116
116
|
it "debounces morpher updates", ->
|
117
117
|
@TestContainer.view (locals) ->
|
118
118
|
template = -> @object.value
|
119
|
-
|
119
|
+
|
120
120
|
@renderDynamic(template, locals)
|
121
|
-
|
121
|
+
|
122
122
|
elem = $("<div></div>")
|
123
123
|
@ground.append elem
|
124
|
-
|
124
|
+
|
125
125
|
sinon.spy window, 'Metamorph'
|
126
|
-
|
126
|
+
|
127
127
|
elem.html @dummyContainer.__renderer({ object: @dummyObject })
|
128
128
|
expect(elem.text()).toBe "initial"
|
129
|
-
|
129
|
+
|
130
130
|
updater = sinon.spy window.Metamorph.returnValues[0], 'html'
|
131
|
-
|
131
|
+
|
132
132
|
@dummyObject.update "new"
|
133
|
-
|
133
|
+
|
134
134
|
waits 0
|
135
|
-
|
135
|
+
|
136
136
|
runs ->
|
137
137
|
expect(elem.text()).toBe "new"
|
138
138
|
expect(updater.callCount).toEqual 1
|
139
|
-
|
139
|
+
|
140
140
|
runs ->
|
141
141
|
@dummyObject.update "don't make"
|
142
142
|
@dummyObject.update "me evil"
|
143
|
-
|
143
|
+
|
144
144
|
waits 0
|
145
|
-
|
145
|
+
|
146
146
|
runs ->
|
147
147
|
expect(elem.text()).toBe "me evil"
|
148
148
|
expect(updater.callCount).toEqual 2
|
@@ -194,4 +194,4 @@ describe "Joosy.Modules.Renderer", ->
|
|
194
194
|
box.__renderer({ })
|
195
195
|
box.refreshElements()
|
196
196
|
|
197
|
-
expect(callback.callCount).toEqual 1
|
197
|
+
expect(callback.callCount).toEqual 1
|
@@ -163,7 +163,7 @@ describe "Joosy.Page", ->
|
|
163
163
|
|
164
164
|
it "should render layout and page", ->
|
165
165
|
spies = []
|
166
|
-
|
166
|
+
|
167
167
|
@box.params = {tested: true}
|
168
168
|
|
169
169
|
spies.push @box.__layoutClass.prototype.__renderer
|
@@ -175,4 +175,4 @@ describe "Joosy.Page", ->
|
|
175
175
|
@box.__bootstrapLayout()
|
176
176
|
expect(spies).toBeSequenced()
|
177
177
|
expect(swapContainer.callCount).toEqual 2
|
178
|
-
expect(@box.layout.params).toEqual {tested: true}
|
178
|
+
expect(@box.layout.params).toEqual {tested: true}
|
@@ -25,7 +25,7 @@ describe "Joosy.Resource.Collection", ->
|
|
25
25
|
it "should load", ->
|
26
26
|
@collection.load $.parseJSON(data)
|
27
27
|
checkData @collection
|
28
|
-
|
28
|
+
|
29
29
|
it "should trigger changes", ->
|
30
30
|
@collection.bind 'changed', callback = sinon.spy()
|
31
31
|
@collection.load $.parseJSON(data)
|
@@ -42,7 +42,7 @@ describe "Joosy.Resource.Collection", ->
|
|
42
42
|
data.each (entry, i) ->
|
43
43
|
data[i].tested = true
|
44
44
|
data
|
45
|
-
|
45
|
+
|
46
46
|
collection = new RC(Test)
|
47
47
|
collection.load $.parseJSON(data)
|
48
48
|
|
@@ -65,20 +65,25 @@ describe "Joosy.Resource.Collection", ->
|
|
65
65
|
@collection.remove 0, false
|
66
66
|
expect(@collection.data.length).toEqual 0
|
67
67
|
expect(callback.callCount).toEqual 0
|
68
|
-
|
69
|
-
it "should add item
|
68
|
+
|
69
|
+
it "should add item to collection", ->
|
70
70
|
@collection.load $.parseJSON(data)
|
71
71
|
@collection.bind 'changed', callback = sinon.spy()
|
72
72
|
@collection.add new Test {'rocking': 'mocking'}
|
73
73
|
expect(@collection.data.length).toEqual 3
|
74
74
|
expect(@collection.at(2).data).toEqual {'rocking': 'mocking'}
|
75
|
-
@collection.add new Test({'
|
75
|
+
@collection.add new Test({'happy': 'stubbing'}), 0
|
76
76
|
expect(@collection.data.length).toEqual 4
|
77
|
-
expect(@collection.at(
|
77
|
+
expect(@collection.at(0).data).toEqual {'happy': 'stubbing'}
|
78
78
|
expect(@collection.at(3).data).toEqual {'rocking': 'mocking'}
|
79
|
-
|
79
|
+
@collection.add new Test({'nerdy': 'coding'}), 1
|
80
|
+
expect(@collection.data.length).toEqual 5
|
81
|
+
expect(@collection.at(0).data).toEqual {'happy': 'stubbing'}
|
82
|
+
expect(@collection.at(1).data).toEqual {'nerdy': 'coding'}
|
83
|
+
expect(@collection.at(4).data).toEqual {'rocking': 'mocking'}
|
84
|
+
|
80
85
|
it "should find items by id", ->
|
81
86
|
@collection.load $.parseJSON(data)
|
82
|
-
|
87
|
+
|
83
88
|
expect(@collection.findById 1).toEqual @collection.data[0]
|
84
|
-
expect(@collection.findById 2).toEqual @collection.data[1]
|
89
|
+
expect(@collection.findById 2).toEqual @collection.data[1]
|