joosy 0.1.0.alpha → 1.0.0.RC1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/.codoopts +5 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +15 -2
  4. data/Gemfile.lock +102 -81
  5. data/Guardfile +16 -16
  6. data/LICENSE +22 -0
  7. data/MIT-LICENSE +2 -2
  8. data/README.md +118 -0
  9. data/app/assets/javascripts/joosy/core/application.js.coffee +53 -0
  10. data/app/assets/javascripts/joosy/core/form.js.coffee +338 -0
  11. data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +72 -0
  12. data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +42 -0
  13. data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +14 -0
  14. data/app/assets/javascripts/joosy/core/joosy.js.coffee +184 -0
  15. data/app/assets/javascripts/joosy/core/layout.js.coffee +168 -0
  16. data/app/assets/javascripts/joosy/core/modules/container.js.coffee +124 -0
  17. data/app/assets/javascripts/joosy/core/modules/events.js.coffee +122 -0
  18. data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +39 -0
  19. data/app/assets/javascripts/joosy/core/modules/log.js.coffee +36 -0
  20. data/app/assets/javascripts/joosy/core/modules/module.js.coffee +117 -0
  21. data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +200 -0
  22. data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +46 -0
  23. data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +87 -0
  24. data/app/assets/javascripts/joosy/core/page.js.coffee +387 -0
  25. data/app/assets/javascripts/joosy/core/preloader.js.coffee +13 -0
  26. data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +175 -0
  27. data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +303 -0
  28. data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +244 -0
  29. data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +24 -0
  30. data/app/assets/javascripts/joosy/core/router.js.coffee +201 -0
  31. data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +37 -0
  32. data/app/assets/javascripts/joosy/core/widget.js.coffee +85 -0
  33. data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +169 -0
  34. data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +56 -0
  35. data/{vendor → app}/assets/javascripts/joosy.js.coffee +0 -1
  36. data/app/helpers/joosy/sprockets_helper.rb +39 -12
  37. data/joosy.gemspec +4 -3
  38. data/lib/joosy/rails/engine.rb +12 -1
  39. data/lib/joosy/rails/version.rb +2 -2
  40. data/lib/joosy.rb +9 -0
  41. data/lib/rails/generators/joosy/application_generator.rb +15 -3
  42. data/lib/rails/generators/joosy/joosy_base.rb +2 -2
  43. data/lib/rails/generators/joosy/layout_generator.rb +8 -1
  44. data/lib/rails/generators/joosy/page_generator.rb +21 -6
  45. data/lib/rails/generators/joosy/preloader_generator.rb +14 -7
  46. data/lib/rails/generators/joosy/resource_generator.rb +29 -0
  47. data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +4 -0
  48. data/lib/rails/generators/joosy/templates/app/layouts/application.js.coffee +1 -0
  49. data/lib/rails/generators/joosy/templates/app/layouts/template.js.coffee +1 -1
  50. data/lib/rails/generators/joosy/templates/app/pages/application.js.coffee +1 -1
  51. data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +3 -3
  52. data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +22 -0
  53. data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +2 -0
  54. data/lib/rails/generators/joosy/templates/app/routes.js.coffee +7 -1
  55. data/lib/rails/generators/joosy/templates/app/templates/layouts/application.jst.hamlc +2 -0
  56. data/lib/rails/generators/joosy/templates/app/templates/pages/welcome/index.jst.hamlc +7 -0
  57. data/lib/rails/generators/joosy/templates/app/widgets/template.js.coffee +2 -2
  58. data/lib/rails/generators/joosy/templates/app.js.coffee +4 -0
  59. data/lib/rails/generators/joosy/templates/app_preloader.js.coffee.erb +9 -12
  60. data/lib/rails/generators/joosy/templates/app_resources_predefiner.js.coffee.erb +11 -0
  61. data/lib/rails/generators/joosy/templates/preload.html.erb +5 -6
  62. data/lib/rails/generators/joosy/templates/preload.html.haml +3 -5
  63. data/lib/rails/generators/joosy/widget_generator.rb +8 -1
  64. data/lib/rails/resources_with_joosy.rb +11 -0
  65. data/spec/javascripts/helpers/spec_helper.js.coffee +25 -0
  66. data/spec/javascripts/joosy/core/application_spec.js.coffee +40 -0
  67. data/spec/javascripts/joosy/core/form_spec.js.coffee +200 -0
  68. data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +103 -0
  69. data/spec/javascripts/joosy/core/helpers/view_spec.js.coffee +10 -0
  70. data/spec/javascripts/joosy/core/joosy_spec.js.coffee +97 -0
  71. data/spec/javascripts/joosy/core/layout_spec.js.coffee +50 -0
  72. data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +32 -27
  73. data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +55 -18
  74. data/spec/javascripts/joosy/core/modules/filters_spec.js.coffee +28 -27
  75. data/spec/javascripts/joosy/core/modules/log_spec.js.coffee +3 -3
  76. data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +6 -15
  77. data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +203 -0
  78. data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +12 -7
  79. data/spec/javascripts/joosy/core/modules/widget_manager_spec.js.coffee +31 -17
  80. data/spec/javascripts/joosy/core/page_spec.js.coffee +178 -0
  81. data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +84 -0
  82. data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +149 -0
  83. data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +31 -0
  84. data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +171 -0
  85. data/spec/javascripts/joosy/core/router_spec.js.coffee +143 -0
  86. data/spec/javascripts/joosy/core/templaters/rails_jst_spec.js.coffee +25 -0
  87. data/spec/javascripts/joosy/core/widget_spec.js.coffee +40 -0
  88. data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +36 -0
  89. data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +16 -0
  90. data/spec/javascripts/support/assets/coolface.jpg +0 -0
  91. data/spec/javascripts/support/assets/okay.jpg +0 -0
  92. data/spec/javascripts/support/assets/test.js +1 -0
  93. data/spec/javascripts/support/sinon-ie-1.3.1.js +82 -0
  94. data/vendor/assets/javascripts/jquery.form.js +978 -963
  95. data/vendor/assets/javascripts/metamorph.js +409 -0
  96. data/vendor/assets/javascripts/sugar.js +1057 -366
  97. metadata +95 -50
  98. data/README.rdoc +0 -3
  99. data/lib/joosy/forms.rb +0 -47
  100. data/lib/joosy-rails.rb +0 -5
  101. data/lib/rails/generators/joosy/templates/preload.html.slim +0 -21
  102. data/tmp/javascripts/.gitignore +0 -1
  103. data/tmp/spec/javascripts/helpers/.gitignore +0 -1
  104. data/vendor/assets/javascripts/base64.js +0 -135
  105. data/vendor/assets/javascripts/inflection.js +0 -656
  106. data/vendor/assets/javascripts/joosy/core/application.js.coffee +0 -26
  107. data/vendor/assets/javascripts/joosy/core/form.js.coffee +0 -87
  108. data/vendor/assets/javascripts/joosy/core/joosy.js.coffee +0 -62
  109. data/vendor/assets/javascripts/joosy/core/layout.js.coffee +0 -38
  110. data/vendor/assets/javascripts/joosy/core/modules/container.js.coffee +0 -51
  111. data/vendor/assets/javascripts/joosy/core/modules/events.js.coffee +0 -17
  112. data/vendor/assets/javascripts/joosy/core/modules/filters.js.coffee +0 -39
  113. data/vendor/assets/javascripts/joosy/core/modules/log.js.coffee +0 -12
  114. data/vendor/assets/javascripts/joosy/core/modules/module.js.coffee +0 -28
  115. data/vendor/assets/javascripts/joosy/core/modules/time_manager.js.coffee +0 -23
  116. data/vendor/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +0 -45
  117. data/vendor/assets/javascripts/joosy/core/page.js.coffee +0 -136
  118. data/vendor/assets/javascripts/joosy/core/resource/rest.js.coffee +0 -69
  119. data/vendor/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +0 -42
  120. data/vendor/assets/javascripts/joosy/core/router.js.coffee +0 -75
  121. data/vendor/assets/javascripts/joosy/core/widget.js.coffee +0 -35
  122. data/vendor/assets/javascripts/joosy/preloader/development.js.coffee +0 -27
  123. data/vendor/assets/javascripts/joosy/preloader/production.js.coffee +0 -84
@@ -15,23 +15,22 @@ describe "Joosy.Modules.Container", ->
15
15
  it "should have property named per declared element in container", ->
16
16
  @ground.prepend('<div class="footer" />') # out of container
17
17
  @box.refreshElements()
18
- target = @box.footer.get(0)
18
+ target = @box.footer.get 0
19
19
  expect(target).toBeTruthy()
20
- expect(target).toBe($('.footer', @box.container).get(0))
21
- expect(target).toBe(@box.$('.footer').get(0))
20
+ expect(target).toBe $('.footer', @box.container).get 0
21
+ expect(target).toBe @box.$('.footer').get 0
22
22
 
23
23
  it "should reinitialize container", ->
24
24
  old_container = @box.container
25
25
  parent = old_container.parent()
26
26
  callback = sinon.spy()
27
- old_container.bind('test', callback)
28
- old_container.trigger('test')
29
- new_container = Joosy.Modules.Container.swapContainer(old_container, 'new content')
30
- new_container.trigger('test')
31
- expect(new_container.html()).toEqual('new content')
32
- expect(new_container.parent().get(0)).toBe(parent.get(0))
33
- expect(old_container.parent().get(0)).toBeUndefined()
34
- expect(callback.callCount).toEqual(1)
27
+ old_container.bind 'test', callback
28
+ old_container.trigger 'test'
29
+ new_container = Joosy.Modules.Container.swapContainer old_container, 'new content'
30
+ new_container.trigger 'test'
31
+ expect(new_container.html()).toEqual 'new content'
32
+ expect(new_container.parent().get(0)).toBe parent.get 0
33
+ expect(callback.callCount).toEqual 1
35
34
 
36
35
  it "should inherit element declarations", ->
37
36
  class SubContainerA extends @TestContainer
@@ -44,18 +43,17 @@ describe "Joosy.Modules.Container", ->
44
43
  third: 'third'
45
44
  subBox = new SubContainerB()
46
45
  target = subBox.__collectElements()
47
- expect(target).toEqual(
46
+ expect(target).toEqual Object.extended
48
47
  first: 'overrided'
49
48
  second: 'second'
50
49
  third: 'third'
51
50
  footer: '.footer'
52
- )
53
51
  target = (new @TestContainer()).__collectElements()
54
- expect(target).toEqual(footer: '.footer')
52
+ expect(target).toEqual Object.extended(footer: '.footer')
55
53
 
56
54
  it "should resolve element selector", ->
57
- target = @box.__extractSelector('$footer')
58
- expect(target).toEqual('.footer')
55
+ target = @box.__extractSelector '$footer'
56
+ expect(target).toEqual '.footer'
59
57
 
60
58
  it "should inherit event declarations", ->
61
59
  class SubContainerA extends @TestContainer
@@ -68,27 +66,34 @@ describe "Joosy.Modules.Container", ->
68
66
  'custom' : 'overrided'
69
67
  subBox = new SubContainerB()
70
68
  target = subBox.__collectEvents()
71
- expect(target).toEqual(
69
+ expect(target).toEqual Object.extended
72
70
  'test': 'onContainerTest'
73
71
  'test .post': 'callback2'
74
72
  'test $footer': 'onFooterTest'
75
73
  'custom' : 'overrided'
76
- )
77
74
  target = (new @TestContainer()).__collectEvents()
78
- expect(target).toEqual('test': 'onContainerTest')
75
+ expect(target).toEqual Object.extended('test': 'onContainerTest')
79
76
 
80
77
  it "should delegate events", ->
81
78
  callback = 1.upto(3).map -> sinon.spy()
82
- @box.events = Object.extended(@box.events).merge(
79
+ @box.events = Object.extended(@box.events).merge
83
80
  'test .post': callback[2]
84
81
  'test $footer': 'onFooterTest'
85
- )
82
+
86
83
  @box.onContainerTest = callback[0]
87
84
  @box.onFooterTest = callback[1]
88
85
  @box.__delegateEvents()
89
- @box.container.trigger('test')
90
- $('.footer', @box.container).trigger('test')
91
- $('.post', @box.container).trigger('test')
92
- expect(callback[0].callCount).toEqual(5)
93
- expect(callback[1].callCount).toEqual(1)
94
- expect(callback[2].callCount).toEqual(3)
86
+ @box.container.trigger 'test'
87
+ $('.footer', @box.container).trigger 'test'
88
+ $('.post', @box.container).trigger 'test'
89
+ expect(callback[0].callCount).toEqual 5
90
+ expect(callback[1].callCount).toEqual 1
91
+ expect(callback[2].callCount).toEqual 3
92
+
93
+ it "calls afterRefreshes", ->
94
+ callback = sinon.spy()
95
+ @box.onRefresh -> callback()
96
+
97
+ @box.refreshElements()
98
+ @box.refreshElements()
99
+ expect(callback.callCount).toEqual 1
@@ -3,27 +3,64 @@ describe "Joosy.Modules.Events", ->
3
3
  beforeEach ->
4
4
  class @TestEvents extends Joosy.Module
5
5
  @include Joosy.Modules.Events
6
+ class @SubTestEvents extends @TestEvents
7
+ @include Joosy.Modules.Events
6
8
  @box = new @TestEvents()
9
+ @sub = new @SubTestEvents()
10
+
11
+ it "should run callback once when the all listed events have occurred", ->
12
+ callback = sinon.spy()
7
13
 
14
+ @box.wait 'events list', callback
8
15
 
9
- it "should create the events waiters list", ->
10
- expect(@box.__eventWaiters).toBeUndefined()
16
+ @box.trigger 'events'
17
+ expect(callback.callCount).toEqual 0
18
+ @box.trigger 'list'
19
+ expect(callback.callCount).toEqual 1
20
+
21
+ @box.trigger 'events'
22
+ expect(callback.callCount).toEqual 1
23
+ @box.trigger 'list'
24
+ expect(callback.callCount).toEqual 1
25
+
26
+ it "should allow for binding and unbinding to events", ->
11
27
  callback = sinon.spy()
12
- @box.wait('events list', callback)
13
- expect(@box.__eventWaiters).toEqual([[['events', '', 'list'], callback]])
14
- expect(callback.callCount).toEqual(0)
15
28
 
16
- it "should run callback once when the all listed events have occurred", ->
29
+ @box.bind 'event', callback
30
+
31
+ @box.trigger 'other-event'
32
+ expect(callback.callCount).toEqual 0
33
+ @box.trigger 'event'
34
+ expect(callback.callCount).toEqual 1
35
+ @box.trigger 'event'
36
+ expect(callback.callCount).toEqual 2
37
+
38
+ @box.unbind 'other-event'
39
+
40
+ @box.trigger 'event'
41
+ expect(callback.callCount).toEqual 3
42
+
43
+ @box.unbind callback
44
+
45
+ @box.trigger 'event'
46
+ expect(callback.callCount).toEqual 3
47
+
48
+ it "should handle inheritance well", ->
17
49
  callback = sinon.spy()
18
- @box.wait('events list', callback)
19
- @box.trigger('events')
20
- expect(callback.callCount).toEqual(0)
21
- @box.trigger('list')
22
- expect(callback.callCount).toEqual(0)
23
- @box.trigger('')
24
- expect(callback.callCount).toEqual(0)
25
- @box.trigger('')
26
- expect(callback.callCount).toEqual(1)
27
- expect(@box.__eventWaiters).toEqual([])
28
- @box.trigger('events')
29
- expect(callback.callCount).toEqual(1)
50
+ @sub.wait 'foo', callback
51
+
52
+ expect(@sub.__oneShotEvents).toEqual [[['foo'], callback]]
53
+ expect(@box.__oneShotEvents).toBeUndefined()
54
+
55
+ it "should be safe for concurrent usage", ->
56
+ Joosy.synchronize (context) ->
57
+ context.do (done) ->
58
+ window.setTimeout ->
59
+ expect(-> done()).not.toThrow()
60
+ , 1
61
+ Joosy.synchronize (context) ->
62
+ context.do (done) ->
63
+ window.setTimeout ->
64
+ expect(-> done()).not.toThrow()
65
+ , 2
66
+ waits 3
@@ -16,13 +16,13 @@ describe "Joosy.Modules.Filters", ->
16
16
  @afterLoad 'filter5'
17
17
  @afterUnload 'filter6'
18
18
  target = new SubFiltersB()
19
- expect(target.__beforeLoads).toEqual(['filter1', 'filter4'])
20
- expect(target.__afterLoads).toEqual(['filter2', 'filter5'])
21
- expect(target.__afterUnloads).toEqual(['filter3', 'filter6'])
19
+ expect(target.__beforeLoads).toEqual ['filter1', 'filter4']
20
+ expect(target.__afterLoads).toEqual ['filter2', 'filter5']
21
+ expect(target.__afterUnloads).toEqual ['filter3', 'filter6']
22
22
  target = new SubFiltersA()
23
- expect(target.__beforeLoads).toEqual(['filter1'])
24
- expect(target.__afterLoads).toEqual(['filter2'])
25
- expect(target.__afterUnloads).toEqual(['filter3'])
23
+ expect(target.__beforeLoads).toEqual ['filter1']
24
+ expect(target.__afterLoads).toEqual ['filter2']
25
+ expect(target.__afterUnloads).toEqual ['filter3']
26
26
  target = new @TestFilters()
27
27
  expect(target.__beforeLoads).toBeUndefined()
28
28
  expect(target.__afterLoads).toBeUndefined()
@@ -30,42 +30,43 @@ describe "Joosy.Modules.Filters", ->
30
30
 
31
31
  it "should run callbacks", ->
32
32
  callback = 0.upto(2).map -> sinon.spy()
33
- @box.constructor.beforeLoad(callback[0])
34
- @box.constructor.afterLoad(callback[1])
35
- @box.constructor.afterUnload(callback[2])
36
- @box.__runBeforeLoads(1, 2)
37
- @box.__runAfterLoads(1, 2)
38
- @box.__runAfterUnloads(1, 2)
33
+ @box.constructor.beforeLoad callback[0]
34
+ @box.constructor.afterLoad callback[1]
35
+ @box.constructor.afterUnload callback[2]
36
+ @box.__runBeforeLoads 1, 2
37
+ @box.__runAfterLoads 1, 2
38
+ @box.__runAfterUnloads 1, 2
39
39
  for i in 0.upto(2)
40
- expect(callback[i].callCount).toEqual(1)
41
- expect(callback[i].alwaysCalledWithExactly(1, 2)).toBeTruthy()
40
+ expect(callback[i].callCount).toEqual 1
41
+ expect(callback[i].alwaysCalledWithExactly 1, 2).toBeTruthy()
42
42
 
43
43
  it "should chain beforeLoad filters", ->
44
44
  callback = 0.upto(2).map -> sinon.stub()
45
- callback[0].returns(true)
46
- @box.constructor.beforeLoad(callback[i]) for i in 0.upto(2)
45
+ callback[0].returns true
46
+ callback[1].returns false
47
+ @box.constructor.beforeLoad(callback[i]) for i in 0.upto 2
47
48
  expect(@box.__runBeforeLoads()).toBeFalsy()
48
- expect(callback[0].callCount).toEqual(1)
49
- expect(callback[1].callCount).toEqual(1)
50
- expect(callback[2].callCount).toEqual(0)
49
+ expect(callback[0].callCount).toEqual 1
50
+ expect(callback[1].callCount).toEqual 1
51
+ expect(callback[2].callCount).toEqual 0
51
52
 
52
53
  it "should chain beforeLoad filters", ->
53
54
  callback = 0.upto(1).map -> sinon.stub()
54
- callback[0].returns(true)
55
- callback[1].returns(true)
55
+ callback[0].returns true
56
+ callback[1].returns true
56
57
  @box.constructor.beforeLoad(callback[i]) for i in 0.upto(1)
57
58
  expect(@box.__runBeforeLoads()).toBeTruthy()
58
- expect(callback[0].callCount).toEqual(1)
59
- expect(callback[1].callCount).toEqual(1)
59
+ expect(callback[0].callCount).toEqual 1
60
+ expect(callback[1].callCount).toEqual 1
60
61
 
61
62
  it "should accept callback names", ->
62
- @box.constructor.beforeLoad('callback0')
63
- @box.constructor.afterLoad('callback1')
64
- @box.constructor.afterUnload('callback2')
63
+ @box.constructor.beforeLoad 'callback0'
64
+ @box.constructor.afterLoad 'callback1'
65
+ @box.constructor.afterUnload 'callback2'
65
66
  for i in 0.upto(2)
66
67
  @box['callback' + i] = sinon.spy()
67
68
  @box.__runBeforeLoads()
68
69
  @box.__runAfterLoads()
69
70
  @box.__runAfterUnloads()
70
71
  for i in 0.upto(2)
71
- expect(@box['callback' + i].callCount).toEqual(1)
72
+ expect(@box['callback' + i].callCount).toEqual 1
@@ -6,10 +6,10 @@ describe "Joosy.Modules.Log", ->
6
6
  @box = new @TestLog()
7
7
 
8
8
  it "should log into console", ->
9
- @box.log('message', 'appendix')
9
+ @box.log 'message', 'appendix'
10
10
 
11
11
  it "should log debug messages into console", ->
12
12
  Joosy.debug = true
13
- @box.debug('debug message')
13
+ @box.debug 'debug message'
14
14
  Joosy.debug = false
15
- @box.debug('unseen debug message')
15
+ @box.debug 'unseen debug message'
@@ -19,15 +19,15 @@ describe "Joosy.Module", ->
19
19
  property: 'value'
20
20
  class Klass extends Joosy.Module
21
21
  @include TestModule
22
- expect(Klass::property).toEqual('value')
23
- expect((new Klass()).property).toEqual('value')
22
+ expect(Klass::property).toEqual 'value'
23
+ expect((new Klass()).property).toEqual 'value'
24
24
 
25
25
  it "should extend object", ->
26
26
  TestModule =
27
27
  property: 'value'
28
28
  class Klass extends Joosy.Module
29
29
  @extend TestModule
30
- expect(Klass.property).toEqual('value')
30
+ expect(Klass.property).toEqual 'value'
31
31
  expect((new Klass()).property).toBeUndefined()
32
32
 
33
33
  it "should run callbacks on include and extend", ->
@@ -39,18 +39,9 @@ describe "Joosy.Module", ->
39
39
  @include TestModule
40
40
  @extend TestModule
41
41
  for callback in ['included', 'extended']
42
- expect(TestModule[callback].callCount).toEqual(1)
42
+ expect(TestModule[callback].callCount).toEqual 1
43
43
  expect(TestModule[callback].getCall(0).calledOn(Klass)).toBeTruthy()
44
44
 
45
- it "should run init hook", ->
46
- class Klass extends Joosy.Module
47
- init: sinon.spy()
48
- target = (new Klass(1, 2)).init
49
- expect(target.callCount).toEqual(1)
50
- expect(target.alwaysCalledWithExactly(1, 2)).toBeTruthy()
51
-
52
45
  it "should have minimal set of properties", ->
53
- expect(Object.extended(Joosy.Module).keys())
54
- .toEqual(['hasAncestor', 'include', 'extend'])
55
- expect(Object.extended(Joosy.Module.prototype).keys())
56
- .toEqual([])
46
+ expect(Object.extended(Joosy.Module).keys()).toEqual ['__namespace__', '__className', 'hasAncestor', 'merge', 'include', 'extend']
47
+ expect(Object.extended(Joosy.Module.prototype).keys()).toEqual []
@@ -0,0 +1,203 @@
1
+ describe "Joosy.Modules.Renderer", ->
2
+
3
+ beforeEach ->
4
+ @seedGround()
5
+
6
+ class @TestContainer extends Joosy.Module
7
+ @include Joosy.Modules.Renderer
8
+
9
+ @dummyContainer = new @TestContainer
10
+
11
+ class @TestObject extends Joosy.Module
12
+ @include Joosy.Modules.Events
13
+
14
+ constructor: (@value) ->
15
+
16
+ update: (@value) ->
17
+ @trigger 'changed'
18
+
19
+ @dummyObject = new @TestObject("initial")
20
+
21
+ Joosy.namespace 'Joosy.Helpers.Hoge', ->
22
+ @multiplier = (value) ->
23
+ "#{value * 5}"
24
+
25
+ it "updates contents, but only while it is bound to DOM", ->
26
+ @TestContainer.view (locals) ->
27
+ template = (locals) ->
28
+ "#{locals.object.value}"
29
+
30
+ @renderDynamic(template, locals)
31
+
32
+ elem = $("<div></div>")
33
+ @ground.append elem
34
+
35
+ elem.html @dummyContainer.__renderer({ object: @dummyObject })
36
+ expect(elem.text()).toBe "initial"
37
+
38
+ @dummyObject.update "new"
39
+
40
+ waits 0
41
+
42
+ runs ->
43
+ expect(elem.text()).toBe "new"
44
+
45
+ waits 0
46
+
47
+ runs ->
48
+ @dummyContainer.__removeMetamorphs()
49
+ @dummyObject.update "afterwards"
50
+
51
+ waits 0
52
+
53
+ runs ->
54
+ expect(elem.text()).toBe "new"
55
+
56
+ it "renders resources and keep html up2date", ->
57
+ data = Joosy.Resource.Generic.build zombie: 'rock'
58
+
59
+ @TestContainer.view (locals) ->
60
+ template = (locals) ->
61
+ "#{locals.zombie}"
62
+
63
+ @renderDynamic(template, locals)
64
+
65
+ elem = $("<div></div>")
66
+ @ground.append elem
67
+
68
+ elem.html @dummyContainer.__renderer(data)
69
+
70
+ waits 0
71
+
72
+ runs ->
73
+ expect(elem.text()).toBe "rock"
74
+
75
+ runs ->
76
+ data 'zombie', 'suck'
77
+
78
+ waits 0
79
+
80
+ runs ->
81
+ expect(elem.text()).toBe "suck"
82
+
83
+ it "renders 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.load [
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
+
119
+ it "debounces morpher updates", ->
120
+ @TestContainer.view (locals) ->
121
+ template = (locals) ->
122
+ "#{locals.object.value}"
123
+
124
+ @renderDynamic(template, locals)
125
+
126
+ elem = $("<div></div>")
127
+ @ground.append elem
128
+
129
+ sinon.spy window, 'Metamorph'
130
+
131
+ elem.html @dummyContainer.__renderer({ object: @dummyObject })
132
+ expect(elem.text()).toBe "initial"
133
+
134
+ updater = sinon.spy window.Metamorph.returnValues[0], 'html'
135
+
136
+ @dummyObject.update "new"
137
+
138
+ waits 0
139
+
140
+ runs ->
141
+ expect(elem.text()).toBe "new"
142
+ expect(updater.callCount).toEqual 1
143
+
144
+ runs ->
145
+ @dummyObject.update "don't make"
146
+ @dummyObject.update "me evil"
147
+
148
+ waits 0
149
+
150
+ runs ->
151
+ expect(elem.text()).toBe "me evil"
152
+ expect(updater.callCount).toEqual 2
153
+
154
+ it "includes rendering helpers in locals", ->
155
+ @TestContainer.helpers "Hoge"
156
+
157
+ @TestContainer.view (locals) ->
158
+ template = (locals) ->
159
+ "#{locals.multiplier(10)}"
160
+
161
+ @render(template, locals)
162
+
163
+ elem = $("<div></div>")
164
+ @ground.append elem
165
+
166
+ elem.html @dummyContainer.__renderer({ })
167
+
168
+ expect(elem.text()).toBe "50"
169
+
170
+ it "includes global rendering helpers in locals", ->
171
+ Joosy.Helpers.Application.globalMultiplier = (value) ->
172
+ value * 6
173
+
174
+ @TestContainer.view (locals) ->
175
+ template = (locals) ->
176
+ "#{locals.globalMultiplier(10)}"
177
+
178
+ @render(template, locals)
179
+
180
+ elem = $("<div></div>")
181
+ @ground.append elem
182
+
183
+ elem.html @dummyContainer.__renderer({ })
184
+
185
+ expect(elem.text()).toBe "60"
186
+
187
+ it "proxies onRefresh for containers", ->
188
+ class Box extends Joosy.Module
189
+ @include Joosy.Modules.Renderer
190
+ @include Joosy.Modules.Container
191
+
192
+ callback = sinon.spy()
193
+
194
+ Box.view (locals) ->
195
+ template = (locals) -> locals.onRefresh -> callback()
196
+ @render(template, locals)
197
+
198
+ box = new Box
199
+
200
+ box.__renderer({ })
201
+ box.refreshElements()
202
+
203
+ expect(callback.callCount).toEqual 1
@@ -7,14 +7,19 @@ describe "Joosy.Modules.TimeManager", ->
7
7
 
8
8
 
9
9
  it "should keep timeouts list", ->
10
- timer = @box.setTimeout(10000, (->))
11
- expect(@box.__timeouts).toEqual([timer])
12
- window.clearTimeout(timer)
10
+ timer = @box.setTimeout 10000, ->
11
+ expect(@box.__timeouts).toEqual [timer]
12
+ window.clearTimeout timer
13
13
 
14
14
  it "should keep intervals list", ->
15
- timer = @box.setInterval(10000, (->))
16
- expect(@box.__intervals).toEqual([timer])
17
- window.clearInterval(timer)
15
+ timer = @box.setInterval 10000, ->
16
+ expect(@box.__intervals).toEqual [timer]
17
+ window.clearInterval timer
18
18
 
19
19
  it "should stop intervals and timeouts", ->
20
- @box.clearTime()
20
+ callback = sinon.spy()
21
+ runs ->
22
+ @box.setTimeout 10, callback
23
+ @box.__clearTime()
24
+ waits(10)
25
+ runs -> expect(callback.callCount).toEqual(0)
@@ -4,27 +4,26 @@ describe "Joosy.Modules.WidgetsManager", ->
4
4
  class @TestWidgetManager extends Joosy.Module
5
5
  @include Joosy.Modules.WidgetsManager
6
6
  @box = new @TestWidgetManager()
7
- @widget_mock = Object.extended(
7
+ @widgetMock = Object.extended(
8
8
  __load: sinon.stub()
9
9
  __unload: sinon.spy()
10
10
  )
11
- @widget_mock.__load.returns(@widget_mock)
11
+ @widgetMock.__load.returns @widgetMock
12
12
 
13
13
 
14
14
  it "should register and unregister widget", ->
15
- expect(@box.registerWidget(@ground, @widget_mock)).toBe(@widget_mock)
16
- expect(@box.__activeWidgets).toEqual([@widget_mock])
17
- expect(@widget_mock.__load.callCount).toEqual(1)
15
+ expect(@box.registerWidget @ground, @widgetMock).toBe @widgetMock
16
+ expect(@box.__activeWidgets).toEqual [@widgetMock]
17
+ expect(@widgetMock.__load.callCount).toEqual 1
18
18
 
19
- expect(@box.unregisterWidget(@widget_mock)).toBeTruthy()
20
- expect(@box.__activeWidgets).toEqual([undefined])
21
- expect(@widget_mock.__unload.callCount).toEqual(1)
19
+ expect(@box.unregisterWidget @widgetMock).toBeTruthy()
20
+ expect(@box.__activeWidgets).toEqual []
21
+ expect(@widgetMock.__unload.callCount).toEqual 1
22
22
 
23
23
  it "should unload all widgets", ->
24
- 0.upto(2).each =>
25
- @box.registerWidget(@ground, @widget_mock)
24
+ 0.upto(2).each => @box.registerWidget(@ground, @widgetMock)
26
25
  @box.__unloadWidgets()
27
- expect(@widget_mock.__unload.callCount).toEqual(3)
26
+ expect(@widgetMock.__unload.callCount).toEqual 3
28
27
 
29
28
  it "should inherit widget declarations", ->
30
29
  @box.container = @ground
@@ -39,11 +38,10 @@ describe "Joosy.Modules.WidgetsManager", ->
39
38
  'selector': 'overriden'
40
39
  subBox = new SubWidgetManagerB()
41
40
  target = subBox.__collectWidgets()
42
- expect(target).toEqual(
41
+ expect(target).toEqual Object.extended
43
42
  'test': 'widget'
44
43
  'widgets': 'widget'
45
44
  'selector': 'overriden'
46
- )
47
45
 
48
46
  it "should register widgets per declaration", ->
49
47
  @seedGround()
@@ -53,9 +51,25 @@ describe "Joosy.Modules.WidgetsManager", ->
53
51
  '$container': Joosy.Widget
54
52
  '$footer': Joosy.Widget
55
53
  '.post': sinon.stub()
56
- @box.widgets['.post'].returns(@widget_mock)
54
+ @box.widgets['.post'].returns @widgetMock
55
+ @box.__setupWidgets()
56
+ expect(@box.__activeWidgets.length).toEqual 5
57
+ expect(@box.widgets['.post'].callCount).toEqual 3
58
+ expect(@box.widgets['.post'].getCall(0).calledOn @box).toBeTruthy()
59
+
60
+ it "should bootstrap widget properly", ->
61
+ class TextWidget extends Joosy.Widget
62
+ @view -> 'fluffy'
63
+ constructor: (@tester) ->
64
+
65
+ @seedGround()
66
+ @box.container = $('#application')
67
+ @box.widgets =
68
+ '.post:first': TextWidget
69
+ '.widget:first': (i) -> new TextWidget i
57
70
  @box.__setupWidgets()
58
- expect(@box.__activeWidgets.length).toEqual(5)
59
- expect(@box.widgets['.post'].callCount).toEqual(3)
60
- expect(@box.widgets['.post'].getCall(0).calledOn(@box))
61
71
 
72
+ expect(@ground.find('.post').html()).toEqual 'fluffy'
73
+ expect(@ground.find('.widget').html()).toEqual 'fluffy'
74
+ expect(@box.__activeWidgets[0].tester).toBeUndefined()
75
+ expect(@box.__activeWidgets[1].tester).toEqual 0