cartilage 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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"