luca 0.9.6 → 0.9.7

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 (76) hide show
  1. data/CHANGELOG +37 -14
  2. data/lib/luca/rails/version.rb +1 -1
  3. data/spec/components/collection_view_spec.coffee +24 -2
  4. data/spec/components/pagination_control_spec.coffee +0 -0
  5. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  6. data/spec/concerns/filterable_spec.coffee +25 -0
  7. data/spec/concerns/model_presenter_spec.coffee +31 -0
  8. data/spec/concerns/paginatable_spec.coffee +0 -0
  9. data/spec/concerns/state_model_spec.coffee +0 -0
  10. data/spec/concerns_spec.coffee +88 -0
  11. data/spec/core/container_spec.coffee +74 -12
  12. data/spec/core/model_spec.coffee +6 -1
  13. data/spec/define_spec.coffee +0 -6
  14. data/spec/util_spec.coffee +24 -0
  15. data/src/components/application.coffee +32 -30
  16. data/src/components/base_toolbar.coffee +6 -4
  17. data/src/components/collection_loader_view.coffee +3 -1
  18. data/src/components/collection_view.coffee +42 -21
  19. data/src/components/controller.coffee +3 -1
  20. data/src/components/fields/button_field.coffee +19 -12
  21. data/src/components/fields/checkbox_array.coffee +8 -2
  22. data/src/components/fields/checkbox_field.coffee +18 -9
  23. data/src/components/fields/file_upload_field.coffee +5 -1
  24. data/src/components/fields/hidden_field.coffee +3 -1
  25. data/src/components/fields/label_field.coffee +4 -3
  26. data/src/components/fields/select_field.coffee +7 -8
  27. data/src/components/fields/text_field.coffee +3 -1
  28. data/src/components/fields/type_ahead_field.coffee +4 -2
  29. data/src/components/form_button_toolbar.coffee +4 -1
  30. data/src/components/form_view.coffee +49 -44
  31. data/src/components/grid_view.coffee +1 -1
  32. data/src/components/multi_collection_view.coffee +49 -22
  33. data/src/components/pagination_control.coffee +17 -13
  34. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  35. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  36. data/src/{modules → concerns}/deferrable.coffee +1 -1
  37. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  38. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  39. data/src/concerns/filterable.coffee +82 -0
  40. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  41. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  42. data/src/{modules → concerns}/local_storage.coffee +0 -0
  43. data/src/{modules → concerns}/modal_view.coffee +1 -1
  44. data/src/concerns/model_presenter.coffee +23 -0
  45. data/src/concerns/paginatable.coffee +87 -0
  46. data/src/{modules → concerns}/state_model.coffee +1 -1
  47. data/src/{modules → concerns}/templating.coffee +1 -1
  48. data/src/concerns.coffee +70 -0
  49. data/src/containers/tab_view.coffee +7 -10
  50. data/src/core/collection.coffee +17 -1
  51. data/src/core/container.coffee +56 -31
  52. data/src/core/field.coffee +39 -38
  53. data/src/core/meta_data.coffee +37 -0
  54. data/src/core/model.coffee +18 -1
  55. data/src/core/view.coffee +25 -29
  56. data/src/define.coffee +54 -66
  57. data/src/framework.coffee +23 -18
  58. data/src/index.coffee +3 -1
  59. data/src/stylesheets/components/checkbox_array.scss +1 -1
  60. data/src/stylesheets/components/form_view.scss +5 -5
  61. data/src/stylesheets/components/viewport.scss +2 -1
  62. data/src/stylesheets/containers/container.scss +0 -5
  63. data/src/stylesheets/containers/tab_view.scss +5 -5
  64. data/src/tools/console.coffee +5 -5
  65. data/src/util.coffee +47 -0
  66. data/vendor/assets/javascripts/luca-ui-development-tools.js +5 -5
  67. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  68. data/vendor/assets/javascripts/luca-ui-full.js +905 -416
  69. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  70. data/vendor/assets/javascripts/luca-ui.js +905 -416
  71. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  72. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  73. metadata +27 -17
  74. data/spec/mixin_spec.coffee +0 -49
  75. data/src/modules/filterable.coffee +0 -60
  76. data/src/modules/paginatable.coffee +0 -79
data/CHANGELOG CHANGED
@@ -85,26 +85,26 @@
85
85
  0.9.1
86
86
  - Bugfix Release
87
87
 
88
- 0.9.2
88
+ 0.9.2
89
89
  - FormView has errorMessage, successMessage methods which use twitter bootstrap alerts as flash message
90
90
  - FormView toolbar accepts new options: true, both, bottom, or top
91
91
  - Luca.Collection has a property @remoteFiltering which makes applyFilter always use remote fetch
92
92
  - Bugfix in GridView collection change handler
93
93
  - Added Luca.isViewPrototype, Luca.isModelPrototype, Luca.isCollectionPrototype helpers
94
94
  - Added configuration option to control auto registration of components with the registry
95
- - Added Luca.parentClass and Luca.inheritanceChain methods for inspecting a component or prototype
95
+ - Added Luca.parentClass and Luca.inheritanceChain methods for inspecting a component or prototype
96
96
  - Changed single instance tracking mechanism on CollectionManager. Will throw an error if more than one
97
97
  is created without specifying a name.
98
98
  - Added Luca.getCollectionManager() helper as an Alias for Luca.CollectionManager.get()
99
99
  - Luca.getApplication() and Luca.getCollectionManager() accept a name argument
100
100
  - Classes like Luca.Application and Luca.CollectionManager which normally are singletons
101
- can have more than one instance if a unique name is given
101
+ can have more than one instance if a unique name is given
102
102
 
103
103
  0.9.3
104
104
  - CardViews and Controllers set data attributes on their elements for the active card / page
105
105
  - Added convenience methods to container 'pluck', 'invoke'
106
106
  - Added methods to Controller for ease of autogenerating routes
107
- - Added beforeInitialize hook on Luca.View
107
+ - Added beforeInitialize hook on Luca.View
108
108
  - Luca.View can now automatically configure state machine models by passing `stateful:true`
109
109
  in your view definition.
110
110
  - Containers will respond to getter attributes set on their components, by defining a getter
@@ -118,9 +118,9 @@
118
118
  - adding a Luca.PageController component as an alias for Controller
119
119
 
120
120
  0.9.33
121
- - added gridSpan property to Luca.View. This will automatically add the span class for you to snap your view to the grid.
121
+ - added gridSpan property to Luca.View. This will automatically add the span class for you to snap your view to the grid.
122
122
  Accepts a number 0-12.
123
- - fixed a bug in CardView.componentElements method with bodyClassName being present
123
+ - fixed a bug in CardView.componentElements method with bodyClassName being present
124
124
  - Added LabelView component. A form field which just displays a value.
125
125
 
126
126
  0.9.35
@@ -134,14 +134,14 @@
134
134
 
135
135
  0.9.4
136
136
  - Luca::Template can now configure its namespace, removing duplicate sprockets class
137
- - Luca.Application triggers page:change and sub:page:change events
137
+ - Luca.Application triggers page:change and sub:page:change events
138
138
  - Luca.Viewport gets enable / disable method for fluid and fullscreen mode
139
139
  - Add configurability to fullscreen behavior on viewport
140
140
 
141
141
  0.9.41
142
142
  - Changed asset pipeline payload so that luca-ui uses the index convention
143
143
 
144
- 0.9.42
144
+ 0.9.42
145
145
  - Added TableView component, which inherits from Luca.components.CollectionView
146
146
  - Expose ways of customizing Luca.View internals.
147
147
  - Added support for @template property on Luca.View. Behaves the same as @bodyTemplate
@@ -151,7 +151,7 @@
151
151
  - View mixins use _initializer methods
152
152
  - FilterableView mixin for CollectionView classes
153
153
  - Added Rails Generator for Luca.Application skeleton. ( thanks @nick-desteffen )
154
- - Adds ability to pass a function reference as a component. The container will call the function, in
154
+ - Adds ability to pass a function reference as a component. The container will call the function, in
155
155
  the context of the container, and use the returned object as the component definition template
156
156
  - Adds a defaults property to containers. This will apply the values as defaults to each component.
157
157
  - Adds Luca.EventsExt an optional core extension which provides additional event binding sugar
@@ -160,20 +160,43 @@
160
160
  - bugfixes in CardView
161
161
 
162
162
  0.9.5
163
- - Luca.Model gets a 'read' method which will a getter function,
163
+ - Luca.Model gets a 'read' method which will a getter function,
164
164
  or get an attribute for the given property you are trying to 'read'
165
165
  - CollectionView is modifiable through several mixins:
166
166
  - Filterable
167
167
  - Paginatable
168
168
  - Loadmaskable
169
- - Introduces component definition helpers: extends,
170
- behavesAs, triggers, defaultsTo which allow for a more
169
+ - Introduces component definition helpers: extends,
170
+ behavesAs, triggers, defaultsTo which allow for a more
171
171
  "literate" component definiton style
172
172
  - View helpers moved into mixins:
173
173
  - StateModel
174
174
  - EnhancedProperties
175
175
  - CollectionEventBindings
176
- - ApplicationEventBindings
176
+ - ApplicationEventBindings
177
177
  - Changed syntax for @componentEvents configuration on Luca.core.Container.
178
- - now accepts role, name, or getter method
178
+ - now accepts role, name, or getter method
179
179
  - now accepts * for component, to bind to the same event on all components
180
+
181
+ 0.9.65
182
+ - Luca.core.Container components can now be configured with a @container property
183
+ which accepts any valid CSS selector so long as it is scoped within that container view's @$el.
184
+ Previously required an element with a specific ID which made it harder to build extendable components
185
+ with specific render targets
186
+
187
+ 0.9.66
188
+ - Luca.core.Container components can now be extended by subclasses by specifying an @extensions property.
189
+ @extensions work by applying the hash to the component in the same index'd position as that component
190
+ configuration in the superclass.
191
+ - Luca.components.CollectionView now has a @loadModels() method which resets the collection with the passed models.
192
+ - Added @componentMetaData() method which is going to replace the trickery done behind the scenes in Luca.extend
193
+ - Luca.config.autoApplyCssClassHierarchy if set to true, will add css class names to your luca components to make inheritance based styling easier.
194
+
195
+ 0.9.7
196
+ - Introduced publicInterface, publicConfiguration, privateInterface, and privateConfiguration as component registry methods.
197
+ These methods are intended to offer finer grain control over the component definition process for the purposes of building
198
+ our auto-generated documentation tool.
199
+ - Added Luca.concern support on Collection and Model
200
+ - Renaming 'mixin' and 'module' functionality to 'concern'
201
+ - Luca.concerns now follow the active support concern in spirit, with __included hooks, ClassMethods handling, etc
202
+ - Introducing an optional Concern for Luca.Model classes, called ModelPresenter.
@@ -1,6 +1,6 @@
1
1
  module Luca
2
2
  module Rails
3
- VERSION = "0.9.6"
3
+ VERSION = "0.9.7"
4
4
  end
5
5
  end
6
6
 
@@ -1,9 +1,9 @@
1
1
  describe 'The Collection View', ->
2
2
  beforeEach ->
3
3
  @collection = new Luca.Collection([
4
- id: 1, attr: "value_one"
4
+ id: 1, attr: "value_one", filter: "value"
5
5
  ,
6
- id: 2, attr: "value_two"
6
+ id: 2, attr: "value_two", filter: "value"
7
7
  ],
8
8
  model: Luca.Model)
9
9
 
@@ -12,9 +12,31 @@ describe 'The Collection View', ->
12
12
  itemClassName: "custom-class"
13
13
  itemProperty: 'attr'
14
14
  collection: @collection
15
+ filterable:
16
+ query:
17
+ filter: "value"
18
+ options:
19
+ sortBy: "filter"
15
20
 
16
21
  @view.render()
17
22
 
23
+ it "should provide access to the query", ->
24
+ expect( @view.getQuery() ).toBeDefined()
25
+
26
+ it "should provide access to the query options", ->
27
+ expect( @view.getQueryOptions() ).toBeDefined()
28
+
29
+ it "should combine filter and pagination in the options hash", ->
30
+ @view.setPage(5)
31
+ @view.applyFilter({filter:"value"},{sortBy:'filter'})
32
+
33
+ options = @view.getQueryOptions()
34
+ query = @view.getQuery()
35
+
36
+ expect( options.page ).toEqual 5
37
+ expect( options.sortBy ).toEqual 'filter'
38
+ expect( query.filter ).toEqual 'value'
39
+
18
40
  it "should render the attributes in the specified list elements", ->
19
41
  expect( @view.$html() ).toContain('value_one')
20
42
 
File without changes
@@ -0,0 +1,16 @@
1
+ describe 'The DOM Helpers module', ->
2
+ describe "The Wrapping Helper", ->
3
+ it "should accept a space delimited list", ->
4
+ v = new Luca.View(wrapperClass: "class-one class-two")
5
+ expect( v.$el.parent().is(".class-one.class-two") ).toEqual(true)
6
+
7
+ describe "Auto Assigning Class Names", ->
8
+ it "should apply the class of the component all the way up its hierarchy", ->
9
+ c = new Luca.core.Container()
10
+ expect( c.$el.is(".luca-container") ).toBeTruthy()
11
+ expect( c.$el.is(".luca-panel") ).toBeTruthy()
12
+
13
+ it "should leave out backbone and luca view classes", ->
14
+ c = new Luca.core.Container()
15
+ expect( c.$el.is(".luca-view") ).not.toBeTruthy()
16
+ expect( c.$el.is(".backbone-view") ).not.toBeTruthy()
@@ -0,0 +1,25 @@
1
+ describe 'The Filterable Plugin', ->
2
+ describe 'Through the CollectionView', ->
3
+ beforeEach ->
4
+ @collection = new Luca.Collection [{name:"name"},{name:"filterable"}]
5
+
6
+ @view = new Luca.components.TableView
7
+ collection:@collection
8
+ columns:[reader:"name"]
9
+
10
+ it 'should generate a Backbone.QueryCollection query payload', ->
11
+ expect( @view.getFilterState().toQuery() ).toBeDefined()
12
+
13
+ it "should have a toRemote method which merges params", ->
14
+ expect( @view.getFilterState().toRemote() ).toBeDefined()
15
+
16
+ it 'should apply filter values', ->
17
+ @view.applyFilter(filter:"value")
18
+ expect( @view.getFilterState().toQuery().filter ).toEqual('value')
19
+
20
+ it 'should generate a Backbone.QueryCollection options payload', ->
21
+ expect( @view.getFilterState().toOptions() ).toBeDefined()
22
+
23
+ it "should trigger a refresh event on filter change", ->
24
+ @view.applyFilter(filter:"value")
25
+ expect( @view ).toHaveTriggered("refresh")
@@ -0,0 +1,31 @@
1
+ describe 'The Presenter Mixin', ->
2
+ presenterModel = Luca.register("Luca.models.PresenterModel").extends("Luca.Model")
3
+ presenterModel.mixesIn("ModelPresenter")
4
+ presenterModel.defines
5
+ randomProperty: "chocolate"
6
+ fullName: ()->
7
+ @get("first_name") + ' ' + @get("last_name")
8
+ defaults:
9
+ first_name: "Jonathan"
10
+ last_name: "Soeder"
11
+
12
+ it "should respond to presentAs", ->
13
+ expect( Luca.models.PresenterModel::presentAs ).toBeDefined()
14
+
15
+ it "should define the presenter class methods on the model class", ->
16
+ expect( Luca.models.PresenterModel.registerPresenter ).toBeDefined()
17
+
18
+ it "should define the presenter class methods on the model class", ->
19
+ expect( Luca.models.PresenterModel.getPresenter ).toBeDefined()
20
+
21
+ it "should register a presenter format", ->
22
+ Luca.models.PresenterModel.registerPresenter "names", ["first_name", "last_name", "fullName"]
23
+ expect( Luca.models.PresenterModel.getPresenter("names") ).toBeDefined()
24
+
25
+ it "should present a model in the desired format", ->
26
+ model = new Luca.models.PresenterModel()
27
+ presented = model.presentAs('names')
28
+ expect( _.isObject(presented) ).toEqual true
29
+ expect( presented ).toBeDefined()
30
+ expect( _( presented ).keys()... ).toEqual "first_name", "last_name", "fullName"
31
+ expect( presented.fullName ).toEqual 'Jonathan Soeder'
File without changes
File without changes
@@ -0,0 +1,88 @@
1
+ describe 'The Concern System', ->
2
+
3
+ window.Luca ||= {}
4
+
5
+ Luca.concern.namespace 'Luca.test_concerns'
6
+
7
+ Luca.test_concerns =
8
+ CollectionMixin:
9
+ __initializer: ()->
10
+ @trigger "collection:mixin"
11
+ SecondMixin:
12
+ __included: ()->
13
+ window.secondMixinIncluded = true
14
+ __initializer: ()->
15
+ @trigger "second:mixin"
16
+ FirstMixin:
17
+ __initializer: ()->
18
+ @trigger "first:mixin"
19
+ __privateMethod: ()->
20
+ true
21
+ publicMethod: ()->
22
+ true
23
+
24
+ sampleView = Luca.register('Luca.components.FirstView')
25
+
26
+ sampleView.mixesIn 'FirstMixin'
27
+
28
+ sampleView.defines
29
+ sampleMethod: ()->
30
+ "sample"
31
+
32
+ secondView = Luca.register("Luca.components.SecondView")
33
+ secondView.extends 'Luca.components.FirstView'
34
+ secondView.mixesIn 'SecondMixin'
35
+ secondView.defines
36
+ version: 2
37
+
38
+ collection = Luca.register("Luca.components.MixinCollection")
39
+ collection.mixesIn "CollectionMixin"
40
+ collection.defines version: 2
41
+
42
+ model = Luca.register("Luca.components.MixinModel")
43
+ model.mixesIn "CollectionMixin"
44
+ model.defines version: 2
45
+
46
+ it "should work on models", ->
47
+ model = new Luca.components.MixinModel()
48
+ expect( model ).toHaveTriggered("collection:mixin")
49
+
50
+ it "should work on collections", ->
51
+ collection = new Luca.components.MixinCollection()
52
+ expect( collection ).toHaveTriggered("collection:mixin")
53
+
54
+ it "should work on views", ->
55
+ secondView = new Luca.components.SecondView
56
+ expect( secondView ).toHaveTriggered("second:mixin")
57
+
58
+ it "should omit methods prefixed with the double underscore", ->
59
+ sampleView = new Luca.components.FirstView
60
+ expect( sampleView.__privateMethod ).not.toBeDefined()
61
+
62
+
63
+ it "should extend the prototype with the concern definition", ->
64
+ sampleView = new Luca.components.FirstView
65
+ expect( sampleView.publicMethod ).toBeDefined()
66
+
67
+ it "should call the initializers up the prototype chain", ->
68
+ secondView = new Luca.components.SecondView
69
+ expect( secondView ).toHaveTriggered("first:mixin")
70
+ expect( secondView ).toHaveTriggered("second:mixin")
71
+
72
+ describe "Class Methods on the concern", ->
73
+ Luca.test_concerns.ExampleConcern =
74
+ instanceMethod: ()-> "instanceMethod"
75
+ classMethods:
76
+ classMethod: ()-> "classMethod"
77
+
78
+ v = Luca.register("Luca.components.ClassMethodView").mixesIn("ExampleConcern")
79
+
80
+ v.defines(version:1)
81
+
82
+ it "should distinguish between instance methods and class methods", ->
83
+ value = Luca.components.ClassMethodView::instanceMethod.call(@)
84
+ expect( value ).toEqual 'instanceMethod'
85
+
86
+ it "should distinguish between instance methods and class methods", ->
87
+ value = Luca.components.ClassMethodView.classMethod.call(@)
88
+ expect( value ).toEqual 'classMethod'
@@ -3,6 +3,13 @@ describe 'The Luca Container', ->
3
3
  c = @container = new Luca.core.Container
4
4
  defaults:
5
5
  defaultProperty: 'it_works'
6
+ extensions:[
7
+ extension: 1
8
+ ,
9
+ extension: 2
10
+ ,
11
+ extension: 3
12
+ ]
6
13
  components:[
7
14
  name: "component_one"
8
15
  ctype: "view"
@@ -47,6 +54,10 @@ describe 'The Luca Container', ->
47
54
  it "should create a getter function on the container", ->
48
55
  expect( @container.getOne().name ).toEqual 'component_one'
49
56
 
57
+ it "should apply extensions to the components", ->
58
+ expect( @container.getRoleOne().extension ).toEqual 1
59
+ expect( @container.getRoleTwo().extension ).toEqual 2
60
+
50
61
  it "should apply default properties to components", ->
51
62
  defaults = @container.selectByAttribute('defaultProperty','it_works')
52
63
  custom = @container.selectByAttribute('defaultProperty','oh_yeah')
@@ -85,31 +96,70 @@ describe 'The Luca Container', ->
85
96
  @container.eachComponent (c)-> c.spy()
86
97
  expect( Luca.cache("component_four").spy ).toHaveBeenCalled()
87
98
 
99
+ describe 'Component Inheritance and Customization', ->
100
+ it "should accept an array for extensions configuration and join on position/index", ->
101
+ container = new Luca.core.Container
102
+ extensions:[
103
+ undefined
104
+ ,
105
+ name: "custom_two"
106
+ ]
107
+ components:[
108
+ role: "component_one"
109
+ name: "component_one"
110
+ ,
111
+ role: "component_two"
112
+ name: "component_two"
113
+ ]
114
+
115
+ container.render()
116
+
117
+ expect( container.getComponentTwo().name ).toEqual "custom_two"
118
+
119
+ it "should accept an object for extensions configuration and join using role", ->
120
+ container = new Luca.core.Container
121
+ extensions:
122
+ component_one:
123
+ name: "custom_one"
124
+ components:[
125
+ role: "component_one"
126
+ name: "component_one"
127
+ ,
128
+ role: "component_two"
129
+ name: "component_two"
130
+ ]
131
+
132
+ container.render()
133
+
134
+ expect( container.getComponentOne().name ).toEqual "custom_one"
88
135
 
89
136
  describe 'Component Event Binding', ->
90
137
  beforeEach ->
91
138
  @container = new Luca.core.Container
92
139
  componentEvents:
93
- "component_alpha trigger:one" : "one"
140
+ "haha trigger:one" : "one"
94
141
  "alpha trigger:two" : "two"
95
142
  "getAlphaComponent trigger:three" : "three"
96
143
  "* trigger:four" : "four"
97
144
  "beta trigger:five" : "five"
98
145
 
99
146
  one: ()->
100
- @trigger "one"
147
+ @trigger "one"
101
148
 
102
149
  two: ()->
103
- @trigger "two"
150
+ @trigger "two"
104
151
 
105
152
  three: ()->
106
- @trigger "three"
153
+ @trigger "three"
107
154
 
108
155
  four: ()->
109
- @trigger "four"
156
+ @trigger "four"
110
157
 
111
158
  five: ()->
112
- @trigger "five"
159
+ @trigger "five"
160
+
161
+ afterRender: ()->
162
+ @getGamma().trigger("after:render:gamma")
113
163
 
114
164
  registerComponentEvents: ()->
115
165
  Luca.core.Container::registerComponentEvents.apply(@, arguments)
@@ -124,6 +174,10 @@ describe 'Component Event Binding', ->
124
174
  components:[
125
175
  name: "beta_view"
126
176
  role: "beta"
177
+ components:[
178
+ role: "gamma"
179
+ name: "haha"
180
+ ]
127
181
  ]
128
182
  ]
129
183
 
@@ -131,27 +185,35 @@ describe 'Component Event Binding', ->
131
185
 
132
186
  it "should give me all of the components", ->
133
187
  names = _( @container.allChildren() ).pluck('name')
134
- expect( names ).toEqual ['component_alpha','container_tester','beta_view']
188
+ expect( names ).toEqual ['component_alpha','container_tester','beta_view','haha']
135
189
 
136
190
  it "should drill down into nested components", ->
137
191
  expect( @container.getBeta ).toBeDefined()
138
192
  expect( @container.getBeta().name ).toEqual 'beta_view'
139
193
 
194
+ it "should observe the right rendering order", ->
195
+ expect( @container.getGamma() ).toHaveTriggered("after:render:gamma")
196
+
140
197
  it "should pick up events on nested components", ->
141
198
  @container.getBeta().trigger("trigger:five")
142
199
  expect( @container ).toHaveTriggered("five")
143
200
 
144
- it "should define a role based getter", ->
201
+ it "should recursively define role based getters", ->
145
202
  expect( @container.getAlpha ).toBeDefined()
203
+ expect( @container.getBeta ).toBeDefined()
204
+ expect( @container.getGamma ).toBeDefined()
146
205
 
147
206
  it "should define a getter", ->
148
207
  expect( @container.getAlphaComponent ).toBeDefined()
149
208
 
150
- it "should find the component by its role", ->
151
- expect( @container.findComponentByRole("alpha") ).toBeDefined()
209
+ it "should find a nested component by name", ->
210
+ expect( @container.findComponentByName('haha') ).toBeDefined()
152
211
 
153
212
  it "should find the component by its name", ->
154
- expect( @container.findComponentByName('component_alpha') ).toBeDefined()
213
+ expect( @container.findComponentByName("beta_view") ).toBeDefined()
214
+
215
+ it "should find the component by its role", ->
216
+ expect( @container.findComponentByRole("alpha") ).toBeDefined()
155
217
 
156
218
  it "should find the component by its getter", ->
157
219
  expect( @container.findComponentByGetter('getAlphaComponent') ).toBeDefined()
@@ -161,7 +223,7 @@ describe 'Component Event Binding', ->
161
223
  expect( @container ).toHaveTriggered("four")
162
224
 
163
225
  it "should accept component events with a component name", ->
164
- @container.getAlphaComponent().trigger "trigger:one"
226
+ @container.getGamma().trigger "trigger:one"
165
227
  expect(@container).toHaveTriggered("one")
166
228
 
167
229
  it "should accept component events with a component role", ->
@@ -50,13 +50,14 @@ describe "Luca.Model with computed attribute", ->
50
50
  expect(model.get("fullName")).toEqual('Nickolay Schwarz')
51
51
 
52
52
 
53
- describe 'The Read Method', ->
54
53
 
54
+ describe 'The Read Method', ->
55
55
  ModelClass = Luca.Model.extend
56
56
  defaults:
57
57
  attribute: "attribute"
58
58
  reader: ()->
59
59
  "reader"
60
+ property: true
60
61
 
61
62
  it "should read an attribute", ->
62
63
  model = new ModelClass()
@@ -66,3 +67,7 @@ describe 'The Read Method', ->
66
67
  model = new ModelClass()
67
68
  expect( model.read('attribute') ).toEqual "attribute"
68
69
  expect( model.read('reader') ).toEqual 'reader'
70
+
71
+ it "should read model object attributes as a fallback", ->
72
+ model = new ModelClass()
73
+ expect( model.read('property') ).toEqual true
@@ -10,10 +10,4 @@ describe 'The Component Definition System', ->
10
10
  Luca.register("Luca.components.SampleComponentDefinition").defines(version: 1)
11
11
  expect( Luca.parentClasses(Luca.components.SampleComponentDefinition) ).toContain 'Luca.View'
12
12
 
13
- it "should track the parent classes", ->
14
- Luca.register("Luca.components.SampleComponentDefinition").defines(version: 1)
15
- expect( Luca.parentClasses(Luca.components.SampleComponentDefinition) ).toEqual ['Luca.View','Backbone.View']
16
-
17
- xit "should defer component extension until dependencies are defined", ->
18
-
19
13
 
@@ -0,0 +1,24 @@
1
+ describe 'The Luca Utilities', ->
2
+ describe "Converting from component class to css class", ->
3
+ it "should produce a css class from the component class name", ->
4
+ component = "Luca.core.Container"
5
+ cssClass = Luca.util.toCssClass(component)
6
+ expect( cssClass ).toEqual 'luca-core-container'
7
+
8
+ it "should produce a css class from the component class name", ->
9
+ component = "Luca.components.MultiCollectionView"
10
+ cssClass = Luca.util.toCssClass(component)
11
+ expect( cssClass ).toEqual 'luca-components-multi-collection-view'
12
+
13
+ it "should produce a css class from the component class name", ->
14
+ component = "Luca.View"
15
+ cssClass = Luca.util.toCssClass(component)
16
+ expect( cssClass ).toEqual 'luca-view'
17
+
18
+ it "should exclude parts", ->
19
+ component = "Luca.components.MultiCollectionView"
20
+ cssClass = Luca.util.toCssClass(component, 'components')
21
+ expect( cssClass ).toEqual "luca-multi-collection-view"
22
+
23
+
24
+