joosy 1.2.0.alpha.38 → 1.2.0.alpha.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.coffee +15 -7
  3. data/bower.json +4 -3
  4. data/lib/extensions/resources.js +11 -3
  5. data/lib/joosy.js +235 -300
  6. data/package.json +3 -3
  7. data/spec/helpers/ground.coffee +33 -0
  8. data/spec/helpers/matchers.coffee +65 -0
  9. data/spec/joosy/core/application_spec.coffee +8 -8
  10. data/spec/joosy/core/helpers/view_spec.coffee +9 -5
  11. data/spec/joosy/core/helpers/widgets_spec.coffee +43 -10
  12. data/spec/joosy/core/joosy_spec.coffee +42 -50
  13. data/spec/joosy/core/layout_spec.coffee +30 -34
  14. data/spec/joosy/core/modules/container_spec.coffee +79 -76
  15. data/spec/joosy/core/modules/events_spec.coffee +148 -81
  16. data/spec/joosy/core/modules/filters_spec.coffee +68 -49
  17. data/spec/joosy/core/modules/log_spec.coffee +13 -5
  18. data/spec/joosy/core/modules/module_spec.coffee +24 -14
  19. data/spec/joosy/core/modules/renderer_spec.coffee +95 -89
  20. data/spec/joosy/core/modules/time_manager_spec.coffee +11 -16
  21. data/spec/joosy/core/modules/widget_manager_spec.coffee +89 -71
  22. data/spec/joosy/core/page_spec.coffee +201 -137
  23. data/spec/joosy/core/templaters/jst_spec.coffee +62 -0
  24. data/spec/joosy/core/widget_spec.coffee +25 -29
  25. data/spec/joosy/extensions/form/form_spec.coffee +3 -1
  26. data/spec/joosy/extensions/resources/base_spec.coffee +3 -0
  27. data/spec/joosy/extensions/resources/collection_spec.coffee +3 -0
  28. data/spec/joosy/extensions/resources/rest_collection_spec.coffee +3 -0
  29. data/spec/joosy/extensions/resources/rest_spec.coffee +3 -0
  30. data/src/joosy/core/application.coffee +1 -7
  31. data/src/joosy/core/helpers/view.coffee +12 -0
  32. data/src/joosy/core/helpers/widgets.coffee +19 -9
  33. data/src/joosy/core/joosy.coffee +0 -23
  34. data/src/joosy/core/layout.coffee +7 -5
  35. data/src/joosy/core/module.coffee +24 -4
  36. data/src/joosy/core/modules/container.coffee +29 -28
  37. data/src/joosy/core/modules/events.coffee +85 -72
  38. data/src/joosy/core/modules/filters.coffee +3 -1
  39. data/src/joosy/core/modules/renderer.coffee +91 -74
  40. data/src/joosy/core/modules/widgets_manager.coffee +12 -9
  41. data/src/joosy/core/page.coffee +7 -14
  42. data/src/joosy/core/templaters/{rails_jst.coffee → jst.coffee} +21 -19
  43. data/src/joosy/core/widget.coffee +3 -3
  44. data/src/joosy/extensions/resources/base.coffee +8 -3
  45. data/src/joosy/extensions/resources/rest.coffee +8 -0
  46. data/src/joosy/extensions/resources/rest_collection.coffee +1 -0
  47. data/tasks/joosy.coffee +46 -17
  48. data/templates/application/base/pages/welcome/index.coffee +5 -5
  49. data/templates/application/base/templates/layouts/application.jst.hamlc +2 -2
  50. data/templates/application/base/templates/pages/welcome/index.jst.hamlc +2 -2
  51. data/templates/application/standalone/Gruntfile.coffee +3 -1
  52. metadata +6 -5
  53. data/spec/helpers/helper.coffee +0 -68
  54. data/spec/joosy/core/templaters/rails_jst_spec.coffee +0 -25
@@ -1,57 +1,62 @@
1
1
  describe "Joosy.Modules.Container", ->
2
2
 
3
3
  beforeEach ->
4
- @seedGround()
4
+ @$ground.seed()
5
+ container = @$ground.find('#application')
5
6
 
6
- class @TestContainer extends Joosy.Module
7
+ class @Container extends Joosy.Module
7
8
  @include Joosy.Modules.Container
9
+
8
10
  @mapElements
9
11
  posts: '.post'
10
12
  content:
11
13
  post1: '#post1'
12
14
  post2: '#post2'
13
15
  footer: '.footer'
16
+
14
17
  @mapEvents
15
18
  'test': 'onContainerTest'
16
- container: $('#application', @ground)
17
19
 
18
- @box = new @TestContainer()
20
+ container: container
21
+
22
+ it "swaps container", ->
23
+ initial = (new @Container).container
24
+ parent = initial.parent()
25
+ event = sinon.spy()
26
+
27
+ # Binded events trigger
28
+ initial.bind 'test', event
29
+ initial.trigger 'test'
30
+ expect(event.callCount).toEqual 1
19
31
 
20
- it "reinitializes container", ->
21
- oldContainer = @box.container
22
- parent = oldContainer.parent()
23
- callback = sinon.spy()
32
+ swapped = Joosy.Modules.Container.swapContainer initial, 'new content'
24
33
 
25
- oldContainer.bind 'test', callback
26
- oldContainer.trigger 'test'
27
- expect(callback.callCount).toEqual 1
34
+ # Injects into DOM properly
35
+ expect(swapped.html()).toEqual 'new content'
36
+ expect(swapped.parent().get 0).toEqual parent.get 0
28
37
 
29
- newContainer = Joosy.Modules.Container.swapContainer oldContainer, 'new content'
30
- newContainer.trigger 'test'
31
- expect(newContainer.html()).toEqual 'new content'
32
- expect(newContainer.parent().get(0)).toBe parent.get 0
33
- expect(callback.callCount).toEqual 1
38
+ # Binded events disappear
39
+ swapped.trigger 'test'
40
+ expect(event.callCount).toEqual 1
34
41
 
35
- it "calls afterRefreshes", ->
36
- callback = sinon.spy()
37
- @box.onRefresh -> callback()
42
+ describe "elements assigner", ->
38
43
 
39
- @box.refreshElements()
40
- @box.refreshElements()
41
- expect(callback.callCount).toEqual 1
44
+ beforeEach ->
45
+ @container = new @Container
46
+ @container.__assignElements()
42
47
 
43
- describe "elements", ->
44
48
  it "declares", ->
45
- class SubContainerA extends @TestContainer
49
+ class A extends @Container
46
50
  @mapElements
47
51
  first: 'first'
48
52
  second: 'second'
49
- class SubContainerB extends SubContainerA
53
+
54
+ class B extends A
50
55
  @mapElements
51
56
  first: 'overrided'
52
57
  third: 'third'
53
58
 
54
- expect((new SubContainerB()).__elements).toEqual Object.extended
59
+ expect((new B).__elements).toEqual Object.extended
55
60
  posts: '.post'
56
61
  content:
57
62
  post1: '#post1'
@@ -61,90 +66,88 @@ describe "Joosy.Modules.Container", ->
61
66
  third: 'third'
62
67
  footer: '.footer'
63
68
 
64
- expect((new @TestContainer()).__elements).toEqual Object.extended
69
+ expect((new @Container).__elements).toEqual Object.extended
65
70
  posts: '.post'
66
71
  footer: '.footer'
67
72
  content:
68
73
  post1: '#post1'
69
74
  post2: '#post2'
70
75
 
71
- console.log (new @TestContainer)
72
-
73
- it "resolve selector", ->
74
- @box.__assignElements()
75
-
76
- target = @box.__extractSelector '$footer'
77
- expect(target).toEqual '.footer'
78
-
79
- target = @box.__extractSelector '$content.$post1'
80
- expect(target).toEqual '#post1'
76
+ describe "selector resolvance", ->
81
77
 
82
- target = @box.__extractSelector '$footer tr'
83
- expect(target).toEqual '.footer tr'
78
+ it "works for plane selectors", ->
79
+ expect(@container.__extractSelector '$footer').toEqual '.footer'
84
80
 
85
- target = @box.__extractSelector '$footer $content.$post1'
86
- expect(target).toEqual '.footer #post1'
81
+ it "works for deep selectors", ->
82
+ expect(@container.__extractSelector '$content.$post1').toEqual '#post1'
87
83
 
88
- it "nesteds get assigned", ->
89
- @box.__assignElements()
90
- expect(@box.$content.$post1().get 0).toBe $('#post1').get 0
84
+ it "works for plane extended selectors", ->
85
+ expect(@container.__extractSelector '$footer tr').toEqual '.footer tr'
91
86
 
92
- it "get assigned", ->
93
- @box.__assignElements()
87
+ it "works for deep extended selectors", ->
88
+ expect(@container.__extractSelector '$footer $content.$post1').toEqual '.footer #post1'
94
89
 
95
- target = @box.$footer().get 0
90
+ it "assigns", ->
91
+ target = @container.$footer().get 0
96
92
  expect(target).toBeTruthy()
97
- expect(target).toBe $('.footer', @box.container).get 0
98
- expect(target).toBe @box.$('.footer').get 0
93
+ expect(target).toBe $('.footer', @container.container).get 0
94
+ expect(target).toBe @container.$('.footer').get 0
99
95
 
100
- it "allow to filter", ->
101
- @box.__assignElements()
96
+ it "assigns nesteds", ->
97
+ expect(@container.$content.$post1().get 0).toBe $('#post1').get 0
102
98
 
103
- target = @box.$posts('#post1').get 0
99
+ it "filters assignation", ->
100
+ target = @container.$posts('#post1').get 0
104
101
  expect(target).toBeTruthy()
105
- expect(target).toBe $('#post1', @box.container).get 0
102
+ expect(target).toBe $('#post1', @container.container).get 0
106
103
 
107
- it "respect container boundaries", ->
108
- @box.__assignElements()
104
+ it "respects container boundaries", ->
105
+ @$ground.prepend('<div class="footer" />') # out of container
109
106
 
110
- @ground.prepend('<div class="footer" />') # out of container
111
- target = @box.$footer().get 0
107
+ target = @container.$footer().get 0
112
108
  expect(target).toBeTruthy()
113
- expect(target).toBe $('.footer', @box.container).get 0
114
- expect(target).toBe @box.$('.footer').get 0
109
+ expect(target).toBe $('.footer', @container.container).get 0
110
+ expect(target).toBe @container.$('.footer').get 0
111
+
112
+ describe "events delegator", ->
115
113
 
116
- describe "events", ->
117
114
  it "declares", ->
118
- class SubContainerA extends @TestContainer
115
+ class A extends @Container
119
116
  @mapEvents
120
117
  'test .post': 'callback2'
121
118
  'custom' : 'method'
122
- class SubContainerB extends SubContainerA
119
+
120
+ class B extends A
123
121
  @mapEvents
124
122
  'test $footer': 'onFooterTest'
125
123
  'custom' : 'overrided'
126
- target = (new SubContainerB()).__events
127
- expect(target).toEqual Object.extended
124
+
125
+ expect((new B).__events).toEqual Object.extended
128
126
  'test': 'onContainerTest'
129
127
  'test .post': 'callback2'
130
128
  'test $footer': 'onFooterTest'
131
129
  'custom' : 'overrided'
132
- target = (new @TestContainer()).__events
133
- expect(target).toEqual Object.extended('test': 'onContainerTest')
134
130
 
135
- it "delegate", ->
136
- @box.__assignElements()
131
+ expect((new @Container).__events).toEqual Object.extended
132
+ 'test': 'onContainerTest'
133
+
134
+ it "delegates", ->
137
135
  callbacks = 1.upto(3).map -> sinon.spy()
138
- @box.__events = Object.extended(@box.__events).merge
136
+
137
+ @Container.mapEvents
139
138
  'test .post': callbacks[2]
140
139
  'test $footer': 'onFooterTest'
140
+ @Container::onContainerTest = callbacks[0]
141
+ @Container::onFooterTest = callbacks[1]
142
+
143
+ container = new @Container
144
+ container.__assignElements()
145
+ container.__delegateEvents()
146
+
147
+ container.container.trigger 'test'
148
+ $('.footer', container.container).trigger 'test'
149
+ $('.post', container.container).trigger 'test'
141
150
 
142
- @box.onContainerTest = callbacks[0]
143
- @box.onFooterTest = callbacks[1]
144
- @box.__delegateEvents()
145
- @box.container.trigger 'test'
146
- $('.footer', @box.container).trigger 'test'
147
- $('.post', @box.container).trigger 'test'
148
151
  expect(callbacks[0].callCount).toEqual 5
149
152
  expect(callbacks[1].callCount).toEqual 1
150
- expect(callbacks[2].callCount).toEqual 3
153
+ expect(callbacks[2].callCount).toEqual 3
@@ -1,111 +1,178 @@
1
1
  describe "Joosy.Modules.Events", ->
2
2
 
3
3
  beforeEach ->
4
- class @TestEvents extends Joosy.Module
4
+ class @Eventer extends Joosy.Module
5
5
  @include Joosy.Modules.Events
6
- class @SubTestEvents extends @TestEvents
7
- @include Joosy.Modules.Events
8
- @box = new @TestEvents()
9
- @sub = new @SubTestEvents()
10
6
 
11
- it "should run callback once when the all listed events have occurred", ->
12
- callback = sinon.spy()
7
+ describe "base", ->
8
+
9
+ beforeEach ->
10
+ @callback = sinon.spy()
11
+ @eventer = new @Eventer
12
+
13
+ describe "waiter", ->
14
+
15
+ it "fires", ->
16
+ @eventer.wait 'events list', @callback
17
+
18
+ @eventer.trigger 'events'
19
+ expect(@callback.callCount).toEqual 0
20
+
21
+ @eventer.trigger 'list'
22
+ expect(@callback.callCount).toEqual 1
23
+
24
+ it "fires just once", ->
25
+ @eventer.wait 'events list', @callback
26
+
27
+ @eventer.trigger 'events'
28
+ @eventer.trigger 'list'
29
+ @eventer.trigger 'events'
30
+ @eventer.trigger 'list'
31
+
32
+ expect(@callback.callCount).toEqual 1
33
+
34
+ it "unbinds", ->
35
+ binding = @eventer.wait 'events list', @callback
36
+ @eventer.unwait binding
37
+
38
+ @eventer.trigger 'events'
39
+ @eventer.trigger 'list'
40
+
41
+ expect(@callback.callCount).toEqual 0
42
+
43
+ it "recognizes invalid arguments", ->
44
+ expect(=> @eventer.wait '', @callback).toThrow()
45
+ expect(=> @eventer.wait ' ', @callback).toThrow()
46
+ expect(=> @eventer.wait [], @callback).toThrow()
47
+
48
+ describe "binder", ->
49
+
50
+ it "fires", ->
51
+ @eventer.bind 'events list', @callback
52
+
53
+ @eventer.trigger 'events'
54
+ expect(@callback.callCount).toEqual 1
55
+
56
+ @eventer.trigger 'list'
57
+ expect(@callback.callCount).toEqual 2
58
+
59
+ it "fires multiple times", ->
60
+ @eventer.bind 'events list', @callback
61
+
62
+ @eventer.trigger 'events'
63
+ @eventer.trigger 'list'
64
+ @eventer.trigger 'events'
65
+ @eventer.trigger 'list'
66
+
67
+ expect(@callback.callCount).toEqual 4
68
+
69
+ it "unbinds", ->
70
+ binding = @eventer.bind 'events list', @callback
71
+ @eventer.unbind binding
72
+
73
+ @eventer.trigger 'events'
74
+ @eventer.trigger 'list'
75
+
76
+ expect(@callback.callCount).toEqual 0
77
+
78
+ it "recognizes invalid arguments", ->
79
+ expect(=> @eventer.bind '', @callback).toThrow()
80
+ expect(=> @eventer.bind ' ', @callback).toThrow()
81
+ expect(=> @eventer.bind [], @callback).toThrow()
82
+
83
+ it "allows simultaneous usage", ->
84
+ 3.times (i) => @eventer.bind "event#{i}", @callback
85
+ 3.times (i) => @eventer.wait "event#{i}", @callback
86
+
87
+ @eventer.trigger 'event2'
88
+
89
+ expect(@callback.callCount).toEqual 2
90
+
91
+ it "handles inheritance well", ->
92
+ class A extends @Eventer
93
+ a = new A
94
+
95
+ a.wait 'event', @callback
13
96
 
14
- @box.wait ' events list ', callback
97
+ expect(a.__oneShotEvents).toEqual 0: [['event'], @callback]
98
+ expect(@eventer.__oneShotEvents).toBeUndefined()
15
99
 
16
- @box.trigger 'events'
17
- expect(callback.callCount).toEqual 0
18
- @box.trigger 'list'
19
- expect(callback.callCount).toEqual 1
100
+ describe "synchronizer", ->
20
101
 
21
- @box.trigger 'events'
22
- expect(callback.callCount).toEqual 1
23
- @box.trigger 'list'
24
- expect(callback.callCount).toEqual 1
102
+ it "finalizes", ->
103
+ callback = sinon.spy()
25
104
 
26
- expect(=> @box.wait '', callback).toThrow()
27
- expect(callback.callCount).toEqual 1
105
+ Joosy.Modules.Events.synchronize (context) ->
106
+ context.do (done) ->
107
+ callback()
108
+ done()
109
+ context.after ->
110
+ expect(callback.callCount).toEqual 1
111
+ callback()
28
112
 
29
- expect(=> @box.wait ' ', callback).toThrow()
30
- expect(callback.callCount).toEqual 1
113
+ waits 1
114
+ expect(callback.callCount).toEqual 2
31
115
 
32
- expect(=> @box.wait [], callback).toThrow()
33
- expect(callback.callCount).toEqual 1
116
+ it "finalizes with no dependencies defined", ->
117
+ callback = sinon.spy()
34
118
 
35
- it "should allow for binding and unbinding to events", ->
36
- callback = sinon.spy()
119
+ Joosy.Modules.Events.synchronize (context) ->
120
+ context.after ->
121
+ expect(callback.callCount).toEqual 0
122
+ callback()
37
123
 
38
- @box.bind 'event', callback
124
+ waits 1
125
+ expect(callback.callCount).toEqual 1
39
126
 
40
- @box.trigger 'other-event'
41
- expect(callback.callCount).toEqual 0
42
- @box.trigger 'event'
43
- expect(callback.callCount).toEqual 1
44
- @box.trigger 'event'
45
- expect(callback.callCount).toEqual 2
127
+ it "gets called in proper context", ->
128
+ eventer = new @Eventer
46
129
 
47
- @box.unbind 'other-event'
130
+ eventer.synchronize (context) ->
131
+ context.do (done) ->
132
+ expect(@).toEqual eventer
133
+ context.after ->
48
134
 
49
- @box.trigger 'event'
50
- expect(callback.callCount).toEqual 3
135
+ it "is safe for concurrent usage", ->
136
+ test = (method) ->
137
+ expect(-> method()).not.toThrow()
51
138
 
52
- @box.unbind callback
139
+ Joosy.Modules.Events.synchronize (context) ->
140
+ context.do (done) ->
141
+ window.setTimeout (-> test done), 1
53
142
 
54
- @box.trigger 'event'
55
- expect(callback.callCount).toEqual 3
143
+ Joosy.Modules.Events.synchronize (context) ->
144
+ context.do (done) ->
145
+ window.setTimeout (-> test done), 2
56
146
 
57
- it "should allow multiple binding", ->
58
- callback = ->
147
+ waits 3
59
148
 
60
- 3.times =>
61
- @box.bind 'event', callback
62
- expect(@box.__boundEvents).toEqual 0: [['event'], callback], 1: [['event'], callback], 2: [['event'], callback]
149
+ describe "namespece", ->
63
150
 
64
- 3.times =>
65
- @box.wait 'event', callback
66
- expect(@box.__oneShotEvents).toEqual 0: [['event'], callback], 1: [['event'], callback], 2: [['event'], callback]
151
+ beforeEach ->
152
+ @callback = sinon.spy()
67
153
 
68
- it "should handle inheritance well", ->
69
- callback = sinon.spy()
70
- @sub.wait 'foo', callback
154
+ it "proxies events", ->
155
+ eventer = new @Eventer
156
+ namespace = new Joosy.Events.Namespace(eventer)
71
157
 
72
- expect(@sub.__oneShotEvents).toEqual 0: [['foo'], callback]
73
- expect(@box.__oneShotEvents).toBeUndefined()
158
+ namespace.bind 'event1', @callback
159
+ namespace.bind 'event2', @callback
74
160
 
75
- it "should be safe for concurrent usage", ->
76
- Joosy.synchronize (context) ->
77
- context.do (done) ->
78
- window.setTimeout ->
79
- expect(-> done()).not.toThrow()
80
- , 1
81
- Joosy.synchronize (context) ->
82
- context.do (done) ->
83
- window.setTimeout ->
84
- expect(-> done()).not.toThrow()
85
- , 2
86
- waits 3
161
+ eventer.trigger 'event1'
162
+ eventer.trigger 'event2'
87
163
 
88
- it "should call finalizer", ->
89
- callback = sinon.spy()
164
+ expect(@callback.callCount).toEqual 2
90
165
 
91
- Joosy.synchronize (context) ->
92
- context.do (done) ->
93
- callback()
94
- done()
95
- context.after ->
96
- expect(callback.callCount).toEqual 1
97
- callback()
166
+ it "unbinds events", ->
167
+ eventer = new @Eventer
168
+ namespace = new Joosy.Events.Namespace(eventer)
98
169
 
99
- waits 1
100
- expect(callback.callCount).toEqual 2
170
+ namespace.bind 'event1', @callback
171
+ namespace.bind 'event2', @callback
101
172
 
102
- it "should call finalizer even if context.do hasn't been called", ->
103
- callback = sinon.spy()
173
+ namespace.unbind()
104
174
 
105
- Joosy.synchronize (context) ->
106
- context.after ->
107
- expect(callback.callCount).toEqual 0
108
- callback()
175
+ eventer.trigger 'event1'
176
+ eventer.trigger 'event2'
109
177
 
110
- waits 1
111
- expect(callback.callCount).toEqual 1
178
+ expect(@callback.callCount).toEqual 0
@@ -1,72 +1,91 @@
1
1
  describe "Joosy.Modules.Filters", ->
2
2
 
3
3
  beforeEach ->
4
- class @TestFilters extends Joosy.Module
4
+ class @Filters extends Joosy.Module
5
5
  @include Joosy.Modules.Filters
6
- @box = new @TestFilters()
7
6
 
7
+ @filters = new @Filters
8
8
 
9
- it "should inherit filters by copying them", ->
10
- class SubFiltersA extends @TestFilters
9
+ it "inherits filters by copying them", ->
10
+ class A extends @Filters
11
11
  @beforeLoad 'filter1'
12
12
  @afterLoad 'filter2'
13
13
  @afterUnload 'filter3'
14
- class SubFiltersB extends SubFiltersA
14
+
15
+ class B extends A
15
16
  @beforeLoad 'filter4'
16
17
  @afterLoad 'filter5'
17
18
  @afterUnload 'filter6'
18
- target = new SubFiltersB()
19
+
20
+ target = new B
19
21
  expect(target.__beforeLoads).toEqual ['filter1', 'filter4']
20
22
  expect(target.__afterLoads).toEqual ['filter2', 'filter5']
21
23
  expect(target.__afterUnloads).toEqual ['filter3', 'filter6']
22
- target = new SubFiltersA()
24
+
25
+ target = new A
23
26
  expect(target.__beforeLoads).toEqual ['filter1']
24
27
  expect(target.__afterLoads).toEqual ['filter2']
25
28
  expect(target.__afterUnloads).toEqual ['filter3']
26
- target = new @TestFilters()
29
+
30
+ target = new @Filters
27
31
  expect(target.__beforeLoads).toBeUndefined()
28
32
  expect(target.__afterLoads).toBeUndefined()
29
33
  expect(target.__afterUnloads).toBeUndefined()
30
34
 
31
- it "should run callbacks", ->
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
39
- for i in 0.upto(2)
40
- expect(callback[i].callCount).toEqual 1
41
- expect(callback[i].alwaysCalledWithExactly 1, 2).toBeTruthy()
42
-
43
- it "should chain beforeLoad filters", ->
44
- callback = 0.upto(2).map -> sinon.stub()
45
- callback[0].returns true
46
- callback[1].returns false
47
- @box.constructor.beforeLoad(callback[i]) for i in 0.upto 2
48
- expect(@box.__runBeforeLoads()).toBeFalsy()
49
- expect(callback[0].callCount).toEqual 1
50
- expect(callback[1].callCount).toEqual 1
51
- expect(callback[2].callCount).toEqual 0
52
-
53
- it "should chain beforeLoad filters", ->
54
- callback = 0.upto(1).map -> sinon.stub()
55
- callback[0].returns true
56
- callback[1].returns true
57
- @box.constructor.beforeLoad(callback[i]) for i in 0.upto(1)
58
- expect(@box.__runBeforeLoads()).toBeTruthy()
59
- expect(callback[0].callCount).toEqual 1
60
- expect(callback[1].callCount).toEqual 1
61
-
62
- it "should accept callback names", ->
63
- @box.constructor.beforeLoad 'callback0'
64
- @box.constructor.afterLoad 'callback1'
65
- @box.constructor.afterUnload 'callback2'
66
- for i in 0.upto(2)
67
- @box['callback' + i] = sinon.spy()
68
- @box.__runBeforeLoads()
69
- @box.__runAfterLoads()
70
- @box.__runAfterUnloads()
35
+ it "runs callbacks", ->
36
+ callbacks = 0.upto(2).map -> sinon.spy()
37
+ @Filters.beforeLoad callbacks[0]
38
+ @Filters.afterLoad callbacks[1]
39
+ @Filters.afterUnload callbacks[2]
40
+
41
+ @filters.__runBeforeLoads 1, 2
42
+ @filters.__runAfterLoads 1, 2
43
+ @filters.__runAfterUnloads 1, 2
44
+
71
45
  for i in 0.upto(2)
72
- expect(@box['callback' + i].callCount).toEqual 1
46
+ expect(callbacks[i].callCount).toEqual 1
47
+ expect(callbacks[i].alwaysCalledWithExactly 1, 2).toBeTruthy()
48
+
49
+ describe "chaining", ->
50
+
51
+ it "evaluates", ->
52
+ callbacks = 0.upto(1).map =>
53
+ callback = sinon.stub()
54
+ @Filters.beforeLoad callback
55
+ callback
56
+
57
+ callbacks[0].returns true
58
+ callbacks[1].returns true
59
+
60
+ expect(@filters.__runBeforeLoads()).toBeTruthy()
61
+
62
+ expect(callbacks[0].callCount).toEqual 1
63
+ expect(callbacks[1].callCount).toEqual 1
64
+
65
+ it "breaks on false", ->
66
+ callbacks = 0.upto(2).map =>
67
+ callback = sinon.stub()
68
+ @Filters.beforeLoad callback
69
+ callback
70
+
71
+ callbacks[0].returns true
72
+ callbacks[1].returns false
73
+
74
+ expect(@filters.__runBeforeLoads()).toBeFalsy()
75
+
76
+ expect(callbacks[0].callCount).toEqual 1
77
+ expect(callbacks[1].callCount).toEqual 1
78
+ expect(callbacks[2].callCount).toEqual 0
79
+
80
+ it "accepts method names as callbacks", ->
81
+ @filters['callback' + i] = sinon.spy() for i in 0.upto(2)
82
+
83
+ @Filters.beforeLoad 'callback0'
84
+ @Filters.afterLoad 'callback1'
85
+ @Filters.afterUnload 'callback2'
86
+
87
+ @filters.__runBeforeLoads()
88
+ @filters.__runAfterLoads()
89
+ @filters.__runAfterUnloads()
90
+
91
+ expect(@filters['callback' + i].callCount).toEqual 1 for i in 0.upto(2)
@@ -1,15 +1,23 @@
1
1
  describe "Joosy.Modules.Log", ->
2
2
 
3
3
  beforeEach ->
4
- class @TestLog extends Joosy.Module
4
+ class @Logger extends Joosy.Module
5
5
  @include Joosy.Modules.Log
6
- @box = new @TestLog()
6
+
7
+ @logger = new @Logger
8
+ @stub = sinon.stub console, 'log'
9
+
10
+ afterEach ->
11
+ console.log.restore()
7
12
 
8
13
  it "should log into console", ->
9
- @box.log 'message', 'appendix'
14
+ @logger.log 'message', 'appendix'
15
+ expect(@stub.callCount).toEqual 1
10
16
 
11
17
  it "should log debug messages into console", ->
12
18
  Joosy.Application.config.debug = true
13
- @box.debug 'debug message'
19
+ @logger.debug 'debug message'
14
20
  Joosy.Application.config.debug = false
15
- @box.debug 'unseen debug message'
21
+ @logger.debug 'unseen debug message'
22
+
23
+ expect(@stub.callCount).toEqual 1