joosy 1.0.0.RC4 → 1.0.0.RC5

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