cartilage 0.1.1

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 (115) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +57 -0
  3. data/Rakefile +84 -0
  4. data/app/assets/images/cartilage/patterns/background.dark.png +0 -0
  5. data/app/assets/images/cartilage/patterns/background.dark.psd +0 -0
  6. data/app/assets/images/cartilage/patterns/background.light.png +0 -0
  7. data/app/assets/images/cartilage/patterns/background.light.psd +0 -0
  8. data/app/assets/images/cartilage/patterns/background.medium.png +0 -0
  9. data/app/assets/images/cartilage/patterns/background.medium.psd +0 -0
  10. data/app/assets/images/cartilage/patterns/background.png +0 -0
  11. data/app/assets/images/cartilage/patterns/background.psd +0 -0
  12. data/app/assets/javascripts/cartilage/application.js.coffee +45 -0
  13. data/app/assets/javascripts/cartilage/collections/segments.js.coffee +4 -0
  14. data/app/assets/javascripts/cartilage/core.js.coffee +8 -0
  15. data/app/assets/javascripts/cartilage/models/model.js.coffee +2 -0
  16. data/app/assets/javascripts/cartilage/models/segment.js.coffee +2 -0
  17. data/app/assets/javascripts/cartilage/views/bar_segment_view.js.coffee +58 -0
  18. data/app/assets/javascripts/cartilage/views/bar_view.js.coffee +85 -0
  19. data/app/assets/javascripts/cartilage/views/content_view.js.coffee +16 -0
  20. data/app/assets/javascripts/cartilage/views/image_view.js.coffee +76 -0
  21. data/app/assets/javascripts/cartilage/views/list_view.js.coffee +515 -0
  22. data/app/assets/javascripts/cartilage/views/list_view_item.js.coffee +85 -0
  23. data/app/assets/javascripts/cartilage/views/loading_indicator_view.js.coffee +147 -0
  24. data/app/assets/javascripts/cartilage/views/matrix_view.js.coffee +253 -0
  25. data/app/assets/javascripts/cartilage/views/matrix_view_item.js.coffee +5 -0
  26. data/app/assets/javascripts/cartilage/views/modal_view.js.coffee +26 -0
  27. data/app/assets/javascripts/cartilage/views/popover_view.js.coffee +212 -0
  28. data/app/assets/javascripts/cartilage/views/source_list_view.js.coffee +69 -0
  29. data/app/assets/javascripts/cartilage/views/source_list_view_item.js.coffee +5 -0
  30. data/app/assets/javascripts/cartilage/views/split_view.js.coffee +175 -0
  31. data/app/assets/javascripts/cartilage/views/usage_bar_view.js.coffee +5 -0
  32. data/app/assets/javascripts/cartilage/views/view.js.coffee +232 -0
  33. data/app/assets/javascripts/cartilage.js.coffee +18 -0
  34. data/app/assets/javascripts/extensions/console.js.coffee +9 -0
  35. data/app/assets/javascripts/extensions/constructor_name.js.coffee +10 -0
  36. data/app/assets/javascripts/extensions/properties.js.coffee +45 -0
  37. data/app/assets/javascripts/extensions/underscore.js.coffee +71 -0
  38. data/app/assets/stylesheets/cartilage/core.css.scss +432 -0
  39. data/app/assets/stylesheets/cartilage/mixins.css.scss +19 -0
  40. data/app/assets/stylesheets/cartilage/responsive.css.scss +192 -0
  41. data/app/assets/stylesheets/cartilage/variables.css.scss +113 -0
  42. data/app/assets/stylesheets/cartilage/views/list_view.css.scss +41 -0
  43. data/app/assets/stylesheets/cartilage/views/list_view_item.css.scss +47 -0
  44. data/app/assets/stylesheets/cartilage/views/loading_indicator_view.css.scss +50 -0
  45. data/app/assets/stylesheets/cartilage/views/matrix_view.css.scss +87 -0
  46. data/app/assets/stylesheets/cartilage/views/popover_view.css.scss +124 -0
  47. data/app/assets/stylesheets/cartilage/views/segmented_view.css.scss +98 -0
  48. data/app/assets/stylesheets/cartilage/views/source_list_view.css.scss +65 -0
  49. data/app/assets/stylesheets/cartilage/views/split_view.css.scss +80 -0
  50. data/app/assets/stylesheets/cartilage/views/usage_bar_view.css.scss +101 -0
  51. data/app/assets/stylesheets/cartilage/views/view.css.scss +13 -0
  52. data/app/assets/stylesheets/cartilage.css.scss +5 -0
  53. data/lib/cartilage/engine.rb +14 -0
  54. data/lib/cartilage/version.rb +3 -0
  55. data/lib/cartilage.rb +5 -0
  56. data/lib/tasks/cartilage_tasks.rake +4 -0
  57. data/test/cartilage_test.rb +7 -0
  58. data/test/dummy/Rakefile +7 -0
  59. data/test/dummy/app/assets/javascripts/application.js +9 -0
  60. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  61. data/test/dummy/app/controllers/application_controller.rb +3 -0
  62. data/test/dummy/app/helpers/application_helper.rb +2 -0
  63. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  64. data/test/dummy/config/application.rb +45 -0
  65. data/test/dummy/config/boot.rb +10 -0
  66. data/test/dummy/config/database.yml +25 -0
  67. data/test/dummy/config/environment.rb +5 -0
  68. data/test/dummy/config/environments/development.rb +30 -0
  69. data/test/dummy/config/environments/production.rb +60 -0
  70. data/test/dummy/config/environments/test.rb +42 -0
  71. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/test/dummy/config/initializers/inflections.rb +10 -0
  73. data/test/dummy/config/initializers/mime_types.rb +5 -0
  74. data/test/dummy/config/initializers/secret_token.rb +7 -0
  75. data/test/dummy/config/initializers/session_store.rb +8 -0
  76. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/test/dummy/config/locales/en.yml +5 -0
  78. data/test/dummy/config/routes.rb +58 -0
  79. data/test/dummy/config.ru +4 -0
  80. data/test/dummy/db/readme +6 -0
  81. data/test/dummy/public/404.html +26 -0
  82. data/test/dummy/public/422.html +26 -0
  83. data/test/dummy/public/500.html +26 -0
  84. data/test/dummy/public/favicon.ico +0 -0
  85. data/test/dummy/script/rails +6 -0
  86. data/test/framework/cartilage/application_test.js.coffee +14 -0
  87. data/test/framework/cartilage/views/bar_segment_view_test.js.coffee +5 -0
  88. data/test/framework/cartilage/views/bar_view_test.js.coffee +30 -0
  89. data/test/framework/cartilage/views/image_view_test.js.coffee +27 -0
  90. data/test/framework/cartilage/views/list_view_item_test.js.coffee +17 -0
  91. data/test/framework/cartilage/views/list_view_test.js.coffee +190 -0
  92. data/test/framework/cartilage/views/loading_indicator_view_test.js.coffee +5 -0
  93. data/test/framework/cartilage/views/matrix_view_item_test.js.coffee +5 -0
  94. data/test/framework/cartilage/views/matrix_view_test.js.coffee +5 -0
  95. data/test/framework/cartilage/views/popover_view_test.js.coffee +5 -0
  96. data/test/framework/cartilage/views/source_list_view_item_test.js.coffee +5 -0
  97. data/test/framework/cartilage/views/source_list_view_test.js.coffee +5 -0
  98. data/test/framework/cartilage/views/split_view_test.js.coffee +5 -0
  99. data/test/framework/cartilage/views/usage_bar_view_test.js.coffee +5 -0
  100. data/test/framework/cartilage/views/view_test.js.coffee +85 -0
  101. data/test/framework/extensions/properties_test.js.coffee +82 -0
  102. data/test/framework/extensions/underscore_test.js.coffee +73 -0
  103. data/test/framework/index.html +72 -0
  104. data/test/framework/vendor/backbone.js +1431 -0
  105. data/test/framework/vendor/coffee-script.js +8 -0
  106. data/test/framework/vendor/jquery.js +9440 -0
  107. data/test/framework/vendor/phantomjs-runner.js +196 -0
  108. data/test/framework/vendor/qunit.css +235 -0
  109. data/test/framework/vendor/qunit.js +1977 -0
  110. data/test/framework/vendor/run-qunit.js +81 -0
  111. data/test/framework/vendor/sinon-1.5.0.js +4142 -0
  112. data/test/framework/vendor/sinon-qunit-1.0.0.js +62 -0
  113. data/test/framework/vendor/underscore.js +1059 -0
  114. data/test/test_helper.rb +10 -0
  115. metadata +373 -0
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,14 @@
1
+
2
+ module "Cartilage.Application"
3
+
4
+ test "should initialize and launch application", ->
5
+ class TestApplication extends Cartilage.Application
6
+ initialize: ->
7
+ new Backbone.Router
8
+ routes:
9
+ "": "showMainView"
10
+ showMainView: ->
11
+ "mainView"
12
+ Backbone.history.start({ pushState: true })
13
+ TestApplication.launch()
14
+ ok not _.isNull(TestApplication.sharedInstance), "sharedInstance should not be null"
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.BarSegmentView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,30 @@
1
+
2
+ module "Cartilage.Views.BarView"
3
+
4
+ setup: ->
5
+ @testView = new Cartilage.Views.BarView
6
+ segments: new Cartilage.Collections.Segments([
7
+ new Cartilage.Models.Segment({ maximum: 20 }),
8
+ new Cartilage.Models.Segment({ maximum: 40 }),
9
+ new Cartilage.Models.Segment({ maximum: 60 }),
10
+ new Cartilage.Models.Segment({ maximum: 80 }),
11
+ new Cartilage.Models.Segment({ maximum: 100 })
12
+ ])
13
+ value: 54
14
+
15
+ @testView.prepare()
16
+
17
+ test "should calculate correct widths", 5, ->
18
+
19
+ _.each(@testView.subviews, (subview) ->
20
+ # treat 0.19999999999999996 as 0.20
21
+ equal subview.width.toFixed(2), 0.20, "correct width"
22
+ )
23
+
24
+ test "should calculate correct fillWidths", 5, ->
25
+
26
+ equal @testView.subviews[0].fillWidth, 1, "correct fillWidth"
27
+ equal @testView.subviews[1].fillWidth, 1, "correct fillWidth"
28
+ equal @testView.subviews[2].fillWidth, 0.7,"correct fillWidth" # 70% (14/20)of 3rd segment
29
+ equal @testView.subviews[3].fillWidth, 0, "correct fillWidth"
30
+ equal @testView.subviews[4].fillWidth, 0, "correct fillWidth"
@@ -0,0 +1,27 @@
1
+ module "Cartilage.Views.ImageView"
2
+ setup: ->
3
+ @imageView = new Cartilage.Views.ImageView
4
+
5
+ test "isLoaded property should be read-only", 1, ->
6
+ @imageView.isLoaded = true
7
+ ok @imageView.isLoaded == false, "isLoaded should be false"
8
+
9
+ test "isError property should be read-only", 1, ->
10
+ @imageView.isError = true
11
+ ok @imageView.isError == false, "isError should be false"
12
+
13
+ asyncTest "should fire load event upon successful load", 1, ->
14
+ @imageView.on "load", ->
15
+ ok true, 'load called'
16
+ start()
17
+
18
+ @imageView.imageAddress = "http://www.placehold.it/500x500"
19
+ $('#testElement').html @imageView.render().el
20
+
21
+ asyncTest "should fire error event upon unsuccessful load attempt", 1, ->
22
+ @imageView.on "error", ->
23
+ ok true, 'error called'
24
+ start()
25
+
26
+ @imageView.imageAddress = '404'
27
+ $('#testElement').html @imageView.render().el
@@ -0,0 +1,17 @@
1
+
2
+ module "Cartilage.Views.ListViewItem"
3
+
4
+ setup: ->
5
+ @testCollection = new Backbone.Collection([ {id: 1, name: "one"},
6
+ {id: 2, name: "two"},
7
+ {id: 3, name: "three"} ],
8
+ model: Backbone.Model)
9
+
10
+ @testListView = new Cartilage.Views.ListView
11
+ collection: @testCollection
12
+ allowsDragToReorder: yes
13
+
14
+ test "should contain data-model-id on list items", 3, ->
15
+ @testListView.prepare()
16
+ $('#testElement').html @testListView.render().el
17
+ _.each([1,2,3], (itemId) => ok $("*[data-model-id='" + itemId + "']").length > 0)
@@ -0,0 +1,190 @@
1
+ module "Cartilage.Views.BasicListView"
2
+ setup: ->
3
+ @testCollection = new Backbone.Collection([ {id: 1, name: "one"},
4
+ {id: 2, name: "two"},
5
+ {id: 3, name: "three"} ],
6
+ model: Backbone.Model)
7
+
8
+ @testListView = new Cartilage.Views.ListView
9
+ collection: @testCollection
10
+
11
+ test "should render collection correctly", 3, ->
12
+ @testListView.prepare()
13
+ $('#testElement').html @testListView.render().el
14
+ ok $('.list-view').length, "ListView container was created."
15
+ equal $('.list-view-items-container > li').length, 3, "testListView should have 3 items."
16
+ equal @testListView.selected.length, 0, "testListView should have 0 selected items."
17
+
18
+ test "should add an item to the list view", 3, ->
19
+ @testListView.prepare()
20
+ $('#testElement').html @testListView.render().el
21
+ ok $('.list-view').length, "ListView container was created."
22
+ equal $('.list-view-items-container > li').length, 3, "testListView should have 3 items."
23
+ @testCollection.add({id: 4, name: "four"})
24
+ equal $('.list-view-items-container > li').length, 4, "testListView should now have 4 items."
25
+
26
+ test "should remove an item from the list view", 3, ->
27
+ @testListView.prepare()
28
+ $('#testElement').html @testListView.render().el
29
+ ok $('.list-view').length, "ListView container was created."
30
+ equal $('.list-view-items-container > li').length, 3, "testListView should have 3 items."
31
+ @testCollection.remove(@testCollection.get(3))
32
+ equal $('.list-view-items-container > li').length, 2, "testListView should now have 2 items."
33
+
34
+ asyncTest "should trigger select event for single-select ListView", 1, ->
35
+ @testListView.prepare()
36
+ $('#testElement').html @testListView.render().el
37
+
38
+ @testListView.on "select", ->
39
+ ok true, "Select event should have been triggered."
40
+ start()
41
+ @testListView.selectFirst()
42
+
43
+ asyncTest "should trigger deselect event for single-select ListView", 1, ->
44
+ @testListView.prepare()
45
+ $('#testElement').html @testListView.render().el
46
+
47
+ @testListView.on "deselect", ->
48
+ ok true, "Deselect event should have been triggered."
49
+ start()
50
+ @testListView.selectFirst()
51
+ @testListView.deselect($('.list-view > ul.list-view-items-container > li').first())
52
+
53
+ module "Cartilage.Views.ListView.AllowsMultipleSelection"
54
+ setup: ->
55
+ @testListView = null
56
+ testCollection = new Backbone.Collection([ {id: 1, name: "one"},
57
+ {id: 2, name: "two"},
58
+ {id: 3, name: "three"} ],
59
+ model: Backbone.Model)
60
+
61
+ @testListView = new Cartilage.Views.ListView
62
+ collection: testCollection
63
+ allowsMultipleSelection: yes
64
+
65
+ asyncTest "should trigger add event on @selected collection for multi-select ListView", 2, ->
66
+ @testListView.prepare()
67
+ $('#testElement').html @testListView.render().el
68
+
69
+ @testListView.selected.on "add", ->
70
+ ok true, "add was called on multi-select"
71
+ start()
72
+
73
+ @testListView.selectFirst() #select($('.list-view > ul.list-view-items-container > li').first())
74
+ equal @testListView.selected.length, 1, "One element should have been selected"
75
+
76
+ asyncTest "should trigger remove event on @selected collection for multi-select ListView", 3, ->
77
+ @testListView.prepare()
78
+ $('#testElement').html @testListView.render().el
79
+
80
+ @testListView.selected.on "remove", ->
81
+ ok true, "remove was called on multi-select"
82
+ start()
83
+
84
+ @testListView.select($('.list-view > ul.list-view-items-container > li').first())
85
+ @testListView.selectAnother($('.list-view > ul.list-view-items-container > li').last())
86
+ equal @testListView.selected.length, 2, "Two elements should have been selected"
87
+ @testListView.deselect($('.list-view > ul.list-view-items-container > li').first())
88
+ equal @testListView.selected.length, 1, "Only one element should have been selected after deselect"
89
+
90
+ asyncTest "should trigger reset event on @selected collection for multi-select ListView", 3, ->
91
+ @testListView.prepare()
92
+ $('#testElement').html @testListView.render().el
93
+
94
+ @testListView.selected.on "reset", =>
95
+ ok true, "reset was called"
96
+ start()
97
+
98
+ @testListView.select($('.list-view > ul.list-view-items-container > li').first())
99
+ @testListView.selectAnother($('.list-view > ul.list-view-items-container > li').last())
100
+ equal @testListView.selected.length, 2, "Two elements should have been selected"
101
+ @testListView.clearSelection()
102
+ equal @testListView.selected.length, 0, "No elements should have been selected"
103
+
104
+ test "should keep selected items collection in the same order as collection passed to the view", 5, ->
105
+ @testListView.prepare()
106
+ $('#testElement').html @testListView.render().el
107
+
108
+ @testListView.select($('.list-view > ul.list-view-items-container > li').first())
109
+ @testListView.selectAnother($('.list-view > ul.list-view-items-container > li').last())
110
+
111
+ equal @testListView.collection.at(0), @testListView.selected.at(0)
112
+ equal @testListView.collection.at(2), @testListView.selected.at(1)
113
+
114
+ @testListView.selectAnother($('.list-view > ul.list-view-items-container > li')[1])
115
+
116
+ equal @testListView.collection.at(0), @testListView.selected.at(0)
117
+ equal @testListView.collection.at(1), @testListView.selected.at(1)
118
+ equal @testListView.collection.at(2), @testListView.selected.at(2)
119
+
120
+ module "Cartilage.Views.ListView.Ordered"
121
+ setup: ->
122
+ @testListView = null
123
+ @testCollection = new Backbone.Collection( [],
124
+ model: Backbone.Model,
125
+ comparator: (item) -> item.get("name")
126
+ )
127
+ @testListView = new Cartilage.Views.ListView
128
+ collection: @testCollection
129
+ ordered: yes
130
+
131
+ test "should render items inserted into the collection in the proper order on the screen", 9, ->
132
+ @testListView.prepare()
133
+ $('#testElement').html @testListView.render().el
134
+ equal $('#testElement li').length, 0, "No elements should have been rendered"
135
+ @testCollection.add({id: "charlie", name: "charlie"})
136
+ equal $('#testElement li').length, 1, "One element should have been rendered"
137
+ @testCollection.add({id: "alpha", name: "alpha"})
138
+ equal $('#testElement li').length, 2, "Two elements should have been rendered"
139
+ equal $('#testElement li').first().data('model'), @testCollection.get("alpha"), "alpha should have been rendered first"
140
+ equal $('#testElement li').last().data('model'), @testCollection.get("charlie"), "charlie should have been rendered last"
141
+ @testCollection.add({id: "bravo", name: "bravo"})
142
+ equal $('#testElement li').length, 3, "Three elements should have been rendered"
143
+ equal $('#testElement li').first().data('model'), @testCollection.get("alpha"), "alpha should have been rendered first"
144
+ equal $('#testElement li').eq(1).data('model'), @testCollection.get("bravo"), "bravo should have been rendered second"
145
+ equal $('#testElement li').last().data('model'), @testCollection.get("charlie"), "charlie should have been rendered last"
146
+
147
+ test "should render removed items back into the proper position", 4, ->
148
+ @testCollection.add([{id: "alpha", name: "alpha"}, {id: "bravo", name: "bravo"}, {id: "charlie", name: "charlie"}])
149
+ @testListView.prepare()
150
+ $('#testElement').html @testListView.render().el
151
+ equal $('#testElement li').length, 3, "Three elements should have been rendered"
152
+ @bravo = @testCollection.get("bravo")
153
+ @testCollection.remove(@bravo)
154
+ equal $('#testElement li').length, 2, "Two elements should have been rendered"
155
+ @testCollection.add(@bravo)
156
+ equal $('#testElement li').length, 3, "Three elements should have been rendered"
157
+ equal $('#testElement li').eq(1).data('model'), @testCollection.get("bravo"), "bravo should have been reinserted second"
158
+
159
+
160
+ # This is how I'd like to test to make sure clicks get passed through to links contained
161
+ # in the ListViewItem, but there's no way to simulate a click at coordinates in pure JS.
162
+ #
163
+ # module "Cartilage.Views.ListView.SelectionDisabled"
164
+ # setup: ->
165
+ # @testListView = null
166
+
167
+ # class window.TestModel extends Backbone.Model
168
+ # @testCollection = new Backbone.Collection([ {id: 1, name: "one"},
169
+ # {id: 2, name: "two"},
170
+ # {id: 3, name: "three"} ],
171
+ # model: TestModel)
172
+
173
+ # class window.TestListViewItem extends Cartilage.Views.ListViewItem
174
+ # window.JST = { "test_list_view_item": _.template('<a href="<%= testModel.get(\'name\') %>" id="link-<%= testModel.get(\'id\') %>">Link</a>')}
175
+
176
+ # @testListView = new Cartilage.Views.ListView
177
+ # collection: @testCollection
178
+ # allowsSelection: no
179
+ # allowsDeselction: no
180
+ # itemView: TestListViewItem
181
+
182
+ # asyncTest "should pass a click in the listview through to the underlying element", 1, ->
183
+ # @testListView.prepare()
184
+ # $('#testElement').html @testListView.render().el
185
+ # $('#testElement a#link-1').click (e) ->
186
+ # ok true, "Click was received"
187
+ # start()
188
+ # e.preventDefault();
189
+ # offset = $('#testElement a#link-1').offset();
190
+ # $("#testElement a#link-1").simulate("click", {screenX: offset.left + 5, screenY: offset.top + 5})
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.LoadingIndicatorView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.MatrixViewItem"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.MatrixView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.PopoverView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.SourceListViewItem"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.SourceListView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.SplitView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,5 @@
1
+
2
+ module "Cartilage.Views.UsageBarView"
3
+
4
+ test "Should Implement Tests", ->
5
+ ok(false, "No Tests!")
@@ -0,0 +1,85 @@
1
+
2
+ module "Cartilage.View"
3
+
4
+ setup: ->
5
+ window.TestView = null
6
+
7
+ test "superview property should be read-only", ->
8
+ testView = new Cartilage.View
9
+ testView.superview = "foobar"
10
+ ok _.isNull(testView.superview), "superview should be null"
11
+
12
+ test "subviews property should be read-only", ->
13
+ testView = new Cartilage.View
14
+ testView.subviews = "foobar"
15
+ deepEqual testView.subviews, [], "subviews should be an empty array"
16
+
17
+ test "observers property should be read-only", ->
18
+ testView = new Cartilage.View
19
+ testView.observers = "foobar"
20
+ deepEqual testView.observers, [], "observers should be an empty array"
21
+
22
+ test "addSubview method should add the view to subviews array", ->
23
+ class TestView extends Cartilage.View
24
+ class TestSubview extends Cartilage.View
25
+ testView = new TestView
26
+ testSubview = new TestSubview
27
+ testView.addSubview(testSubview)
28
+ deepEqual testView.subviews, [ testSubview ], "testSubview should be in the subviews array"
29
+
30
+ test "addSubview should add subview's element to its element", ->
31
+ class TestView extends Cartilage.View
32
+ class TestSubview extends Cartilage.View
33
+ testView = new TestView
34
+ testSubview = new TestSubview
35
+ testView.addSubview(testSubview)
36
+ equal testSubview.outerHTML, testView.innerHTML, "innerHTML of testView's element should match testSubview's outerHTML"
37
+
38
+ test "addSubview should set the superview of the added subview to itself", ->
39
+ class TestView extends Cartilage.View
40
+ class TestSubview extends Cartilage.View
41
+ testView = new TestView
42
+ testSubview = new TestSubview
43
+ testView.addSubview(testSubview)
44
+ equal testSubview.superview, testView, "testSubview's superview should be equal to testView"
45
+
46
+ test "removeFromSuperview method remove the view from its parent view's subviews array", ->
47
+ class TestView extends Cartilage.View
48
+ class TestSubview extends Cartilage.View
49
+ testView = new TestView
50
+ testSubview = new TestSubview
51
+ testView.addSubview(testSubview)
52
+ deepEqual testView.subviews, [ testSubview ], "testSubview should be in the subviews array"
53
+ testSubview.removeFromSuperview()
54
+ deepEqual testView.subviews, [], "testView.subviews should be an empty array"
55
+
56
+ test "removeFromSuperview should clear the superview property", ->
57
+ class TestView extends Cartilage.View
58
+ class TestSubview extends Cartilage.View
59
+ testView = new TestView
60
+ testSubview = new TestSubview
61
+ testView.addSubview(testSubview)
62
+ equal testSubview.superview, testView, "testSubview's superview should be equal to testView"
63
+ testSubview.removeFromSuperview()
64
+ equal testSubview.superview, null, "testSubview's superview should be null"
65
+
66
+ test "should determine template name automatically", ->
67
+ window.JST = { "test_view": -> "TestView Template" }
68
+ class TestView extends Cartilage.View
69
+ testView = new TestView
70
+ equal testView.template(), "TestView Template", "template() should return 'TestView Template'"
71
+
72
+ test "should determine CSS class names from the inheritance chain", ->
73
+ class TestViewOne extends Cartilage.View
74
+ class TestViewTwo extends TestViewOne
75
+ class TestViewThree extends TestViewTwo
76
+ testView = new TestViewThree
77
+ className = testView.determineClassName()
78
+ equal className, "view test-view-one test-view-two test-view-three", "Class names array should include names for each parent in the inheritance chain"
79
+
80
+ test "should append custom CSS class names to the view's class names", ->
81
+ class TestView extends Cartilage.View
82
+ className: "extra-class-one extra-class-two"
83
+ testView = new TestView
84
+ className = testView.determineClassName()
85
+ equal className, "view test-view extra-class-one extra-class-two", "Class names should include both automatically determined names and custom names"
@@ -0,0 +1,82 @@
1
+
2
+ module "Extensions.Properties"
3
+
4
+ setup: ->
5
+
6
+ test "should initialize property", ->
7
+
8
+ class TestView extends Cartilage.View
9
+ @property "testProperty"
10
+ testView = new TestView
11
+
12
+ ok not _.isUndefined(testView._testProperty), "_testProperty should not be undefined"
13
+ ok _.isNull(testView._testProperty), "_testProperty should be null"
14
+
15
+ test "should initialize property with default value", ->
16
+
17
+ class TestView extends Cartilage.View
18
+ @property "testProperty", default: "foo"
19
+ testView = new TestView
20
+
21
+ equal testView.testProperty, "foo", "testProperty should equal 'foo'"
22
+
23
+ test "should disallow changes to read-only properties", ->
24
+
25
+ class TestView extends Cartilage.View
26
+ @property "testProperty", access: READONLY
27
+ testView = new TestView
28
+
29
+ testView.testProperty = "foobar"
30
+ ok _.isNull(testView.testProperty), "testProperty should be null"
31
+
32
+ test "should initialize read-only property with default value", ->
33
+
34
+ class TestView extends Cartilage.View
35
+ @property "testProperty", access: READONLY, default: "foobar"
36
+ testView = new TestView
37
+
38
+ equal testView.testProperty, "foobar", "testProperty should equal 'foobar'"
39
+
40
+ test "should initialize property with custom getter", ->
41
+
42
+ class TestView extends Cartilage.View
43
+ @property "testProperty",
44
+ get: -> "customGetter"
45
+ testView = new TestView
46
+
47
+ equal testView.testProperty, "customGetter", "testProperty should equal 'customGetter'"
48
+
49
+ test "should initialize property with custom setter", ->
50
+
51
+ class TestView extends Cartilage.View
52
+ @property "testProperty",
53
+ set: (value) -> @__testProperty = "customSetter"
54
+ testView = new TestView
55
+ testView.testProperty = "foo"
56
+
57
+ equal testView.testProperty, "customSetter", "testProperty should equal 'customSetter'"
58
+
59
+ test "should initialize property via super()", ->
60
+
61
+ class TestView extends Cartilage.View
62
+ @property "testProperty"
63
+
64
+ initialize: (options = {}) ->
65
+ options.testProperty = "bar"
66
+ super(options)
67
+
68
+ testView = new TestView
69
+ equal testView.testProperty, "bar"
70
+
71
+ test "should clone default instead of returning directly when it is an object", ->
72
+
73
+ class TestView extends Cartilage.View
74
+ @property "testProperty", default: {foo: "bar"}
75
+
76
+ testView1 = new TestView
77
+ testView2 = new TestView
78
+
79
+ testView1.testProperty.foo = "baz"
80
+
81
+ equal testView1.testProperty.foo, "baz"
82
+ equal testView2.testProperty.foo, "bar"
@@ -0,0 +1,73 @@
1
+
2
+ module "Extensions.Underscore"
3
+
4
+ # _.sum ----------------------------------------------------------------------
5
+
6
+ test "_.sum should sum arrays of numbers", ->
7
+ testArray = [ 1, 2, 3 ]
8
+ equal _.sum(testArray), 6, "Value expected to be 6 (1 + 2 + 3)"
9
+
10
+ test "_.sum should return NaN for non-numeric array entries", ->
11
+ testArray = [ 1, 2, "Foo" ]
12
+ ok _.isNaN(_.sum(testArray)), "Value expected to be NaN"
13
+
14
+ # _.dasherize ----------------------------------------------------------------
15
+
16
+ test "_.dasherize should convert title-cased string to dasherized string", ->
17
+ testString = "FooBarView"
18
+ equal _.dasherize(testString), "foo-bar-view", "Value for '#{testString}' expected to be 'foo-bar-view'"
19
+
20
+ test "_.dasherize should convert camel-cased string to dasherized string", ->
21
+ testString = "fooBarView"
22
+ equal _.dasherize(testString), "foo-bar-view", "Value for '#{testString}' expected to be 'foo-bar-view'"
23
+
24
+ test "_.dasherize should convert underscored string to dasherized string", ->
25
+ testString = "foo_bar_view"
26
+ equal _.dasherize(testString), "foo-bar-view", "Value for '#{testString}' expected to be 'foo-bar-view'"
27
+
28
+ test "_.dasherize should leave dashed strings alone", ->
29
+ testString = "foo-bar-view"
30
+ equal _.dasherize(testString), "foo-bar-view", "Value for '#{testString}' expected to be 'foo-bar-view'"
31
+
32
+ # _.camelize -----------------------------------------------------------------
33
+
34
+ test "_.camelize should convert title-cased string to camel-cased string", ->
35
+ testString = "FooBarView"
36
+ equal _.camelize(testString), "fooBarView", "Value for '#{testString}' expected to be 'fooBarView'"
37
+
38
+ test "_.camelize should convert dashed string to camel-cased string", ->
39
+ testString = "foo-bar-view"
40
+ equal _.camelize(testString), "fooBarView", "Value for '#{testString}' expected to be 'fooBarView'"
41
+
42
+ test "_.camelize should convert underscored string to camel-cased string", ->
43
+ testString = "foo_bar_view"
44
+ equal _.camelize(testString), "fooBarView", "Value for '#{testString}' expected to be 'fooBarView'"
45
+
46
+ test "_.camelize should leave camel-cased strings alone", ->
47
+ testString = "fooBarView"
48
+ equal _.camelize(testString), "fooBarView", "Value for '#{testString}' expected to be 'fooBarView'"
49
+
50
+ # _.underscore ---------------------------------------------------------------
51
+
52
+ test "_.underscore should convert title-cased string to underscored string", ->
53
+ testString = "FooBarView"
54
+ equal _.underscore(testString), "foo_bar_view", "Value for '#{testString}' expected to be 'foo_bar_view'"
55
+
56
+ test "_.underscore should convert camel-cased string to underscored string", ->
57
+ testString = "fooBarView"
58
+ equal _.underscore(testString), "foo_bar_view", "Value for '#{testString}' expected to be 'foo_bar_view'"
59
+
60
+ test "_.underscore should convert dashed string to underscored string", ->
61
+ testString = "foo-bar-view"
62
+ equal _.underscore(testString), "foo_bar_view", "Value for '#{testString}' expected to be 'foo_bar_view'"
63
+
64
+ test "_.underscore should leave underscored strings alone", ->
65
+ testString = "foo_bar_view"
66
+ equal _.underscore(testString), "foo_bar_view", "Value for '#{testString}' expected to be 'foo_bar_view'"
67
+
68
+ # _.remove -------------------------------------------------------------------
69
+
70
+ test "_.remove should remove value from array", ->
71
+ testArray = [ "A", "B", "C" ]
72
+ _.remove(testArray, "B")
73
+ deepEqual testArray, [ "A", "C" ], "foo"