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.
Files changed (46) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +99 -82
  3. data/README.md +1 -1
  4. data/app/assets/javascripts/joosy/core/application.js.coffee +2 -2
  5. data/app/assets/javascripts/joosy/core/form.js.coffee +35 -22
  6. data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +38 -9
  7. data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +10 -4
  8. data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +6 -1
  9. data/app/assets/javascripts/joosy/core/joosy.js.coffee +5 -3
  10. data/app/assets/javascripts/joosy/core/layout.js.coffee +5 -5
  11. data/app/assets/javascripts/joosy/core/modules/events.js.coffee +28 -10
  12. data/app/assets/javascripts/joosy/core/modules/log.js.coffee +1 -1
  13. data/app/assets/javascripts/joosy/core/modules/module.js.coffee +2 -2
  14. data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +1 -1
  15. data/app/assets/javascripts/joosy/core/page.js.coffee +1 -1
  16. data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +18 -18
  17. data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +21 -19
  18. data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +26 -14
  19. data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +2 -2
  20. data/app/assets/javascripts/joosy/core/router.js.coffee +2 -2
  21. data/app/assets/javascripts/joosy/core/widget.js.coffee +3 -0
  22. data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +7 -7
  23. data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +5 -5
  24. data/lib/joosy/rails/version.rb +1 -1
  25. data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +2 -2
  26. data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +5 -5
  27. data/lib/rails/generators/joosy/templates/app/routes.js.coffee +2 -2
  28. data/lib/rails/generators/joosy/templates/preload.html.slim +19 -0
  29. data/lib/rails/resources_with_joosy.rb +2 -2
  30. data/spec/javascripts/helpers/spec_helper.js.coffee +19 -0
  31. data/spec/javascripts/joosy/core/form_spec.js.coffee +36 -16
  32. data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +28 -23
  33. data/spec/javascripts/joosy/core/helpers/widgets_spec.js.coffee +17 -0
  34. data/spec/javascripts/joosy/core/joosy_spec.js.coffee +2 -0
  35. data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +35 -1
  36. data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +29 -29
  37. data/spec/javascripts/joosy/core/page_spec.js.coffee +2 -2
  38. data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +14 -9
  39. data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +19 -19
  40. data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +0 -1
  41. data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +9 -3
  42. data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +7 -7
  43. data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +5 -5
  44. data/spec/javascripts/support/sinon-1.3.1.js +6 -6
  45. data/spec/javascripts/support/sinon-ie-1.3.1.js +5 -5
  46. 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)
@@ -3,6 +3,6 @@ Joosy.Router.map
3
3
  '/' : Welcome.IndexPage
4
4
  # '/resources' :
5
5
  # '/' : Resource.IndexPage
6
+ # '/new' : Resource.NewPage
6
7
  # '/:id' : Resource.ShowPage
7
- # '/:id/edit' : Resource.EditPage
8
- # '/new' : Resource.EditPage
8
+ # '/:id/edit' : Resource.EditPage
@@ -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[:shallow_path]}/#{resources[0]}"
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 3
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: 'a_b', name: 'a[b]', type: 'radio', a: 'b'
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: 'test_b', name: 'test[b]', type: 'radio', a: 'b'
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: 'test_1_b', name: 'test[b]', type: 'radio', a: 'b'
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 from collection", ->
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({'rocking': 'mocking'}), 1
75
+ @collection.add new Test({'happy': 'stubbing'}), 0
76
76
  expect(@collection.data.length).toEqual 4
77
- expect(@collection.at(1).data).toEqual {'rocking': 'mocking'}
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]