presenting 1.0.0

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 (89) hide show
  1. data/LICENSE +20 -0
  2. data/README +10 -0
  3. data/Rakefile +22 -0
  4. data/app/assets/javascript/grid.js +0 -0
  5. data/app/assets/javascript/search.js +13 -0
  6. data/app/assets/stylesheets/details-color.css +7 -0
  7. data/app/assets/stylesheets/details.css +10 -0
  8. data/app/assets/stylesheets/form.css +1 -0
  9. data/app/assets/stylesheets/grid-color.css +71 -0
  10. data/app/assets/stylesheets/grid.css +64 -0
  11. data/app/assets/stylesheets/search-color.css +16 -0
  12. data/app/assets/stylesheets/search.css +45 -0
  13. data/app/controllers/presentation/assets_controller.rb +42 -0
  14. data/app/views/presentations/_details.erb +11 -0
  15. data/app/views/presentations/_field_search.erb +14 -0
  16. data/app/views/presentations/_form.erb +20 -0
  17. data/app/views/presentations/_grid.erb +70 -0
  18. data/app/views/presentations/_search.erb +7 -0
  19. data/config/routes.rb +3 -0
  20. data/lib/presentation/base.rb +48 -0
  21. data/lib/presentation/details.rb +19 -0
  22. data/lib/presentation/field_search.rb +65 -0
  23. data/lib/presentation/form.rb +149 -0
  24. data/lib/presentation/grid.rb +160 -0
  25. data/lib/presentation/search.rb +9 -0
  26. data/lib/presenting/attribute.rb +51 -0
  27. data/lib/presenting/configurable.rb +10 -0
  28. data/lib/presenting/defaults.rb +10 -0
  29. data/lib/presenting/field_set.rb +26 -0
  30. data/lib/presenting/form_helpers.rb +51 -0
  31. data/lib/presenting/helpers.rb +110 -0
  32. data/lib/presenting/sanitize.rb +19 -0
  33. data/lib/presenting/search.rb +185 -0
  34. data/lib/presenting/sorting.rb +87 -0
  35. data/lib/presenting/view.rb +3 -0
  36. data/lib/presenting.rb +9 -0
  37. data/rails/init.rb +12 -0
  38. data/test/assets_test.rb +58 -0
  39. data/test/attribute_test.rb +61 -0
  40. data/test/configurable_test.rb +20 -0
  41. data/test/details_test.rb +68 -0
  42. data/test/field_search_test.rb +102 -0
  43. data/test/field_set_test.rb +46 -0
  44. data/test/form_test.rb +287 -0
  45. data/test/grid_test.rb +219 -0
  46. data/test/helpers_test.rb +72 -0
  47. data/test/presenting_test.rb +15 -0
  48. data/test/rails/app/controllers/application_controller.rb +15 -0
  49. data/test/rails/app/controllers/users_controller.rb +36 -0
  50. data/test/rails/app/helpers/application_helper.rb +3 -0
  51. data/test/rails/app/helpers/users_helper.rb +2 -0
  52. data/test/rails/app/models/user.rb +2 -0
  53. data/test/rails/app/views/layouts/application.html.erb +15 -0
  54. data/test/rails/app/views/users/index.html.erb +10 -0
  55. data/test/rails/app/views/users/new.html.erb +2 -0
  56. data/test/rails/app/views/users/show.html.erb +1 -0
  57. data/test/rails/config/boot.rb +109 -0
  58. data/test/rails/config/database.yml +17 -0
  59. data/test/rails/config/environment.rb +13 -0
  60. data/test/rails/config/environments/development.rb +17 -0
  61. data/test/rails/config/environments/production.rb +24 -0
  62. data/test/rails/config/environments/test.rb +22 -0
  63. data/test/rails/config/locales/en.yml +5 -0
  64. data/test/rails/config/routes.rb +5 -0
  65. data/test/rails/db/development.sqlite3 +0 -0
  66. data/test/rails/db/migrate/20090213085444_create_users.rb +13 -0
  67. data/test/rails/db/migrate/20090213085607_populate_users.rb +13 -0
  68. data/test/rails/db/schema.rb +23 -0
  69. data/test/rails/db/test.sqlite3 +0 -0
  70. data/test/rails/log/development.log +858 -0
  71. data/test/rails/public/404.html +30 -0
  72. data/test/rails/public/422.html +30 -0
  73. data/test/rails/public/500.html +33 -0
  74. data/test/rails/public/javascripts/application.js +2 -0
  75. data/test/rails/public/javascripts/jquery.livequery.min.js +11 -0
  76. data/test/rails/public/javascripts/prototype.js +4320 -0
  77. data/test/rails/script/console +3 -0
  78. data/test/rails/script/dbconsole +3 -0
  79. data/test/rails/script/destroy +3 -0
  80. data/test/rails/script/generate +3 -0
  81. data/test/rails/script/plugin +3 -0
  82. data/test/rails/script/runner +3 -0
  83. data/test/rails/script/server +3 -0
  84. data/test/sanitize_test.rb +15 -0
  85. data/test/search_conditions_test.rb +137 -0
  86. data/test/search_test.rb +30 -0
  87. data/test/sorting_test.rb +63 -0
  88. data/test/test_helper.rb +66 -0
  89. metadata +217 -0
data/test/form_test.rb ADDED
@@ -0,0 +1,287 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class FormTest < Presenting::Test
4
+ def setup
5
+ @f = Presentation::Form.new
6
+ end
7
+
8
+ def test_method_for_new_record
9
+ @f.presentable = stub('record', :new_record? => true)
10
+ assert_equal :post, @f.method
11
+ end
12
+
13
+ def test_method_for_existing_record
14
+ @f.presentable = stub('record', :new_record? => false)
15
+ assert_equal :put, @f.method
16
+ end
17
+
18
+ def test_button_for_new_record
19
+ @f.presentable = stub('record', :new_record? => true)
20
+ assert_equal 'Create', @f.button
21
+ end
22
+
23
+ def test_button_for_existing_record
24
+ @f.presentable = stub('record', :new_record? => false)
25
+ assert_equal 'Update', @f.button
26
+ end
27
+
28
+ def test_adding_a_field_by_name
29
+ @f.fields = [:a]
30
+
31
+ assert_equal :a, @f.fields.first.name
32
+ assert_equal 'A', @f.fields.first.label
33
+ assert_equal :string, @f.fields.first.type
34
+ end
35
+
36
+ def test_adding_a_field_by_name_and_type
37
+ @f.fields = [{:b => :boolean}]
38
+
39
+ assert_equal :b, @f.fields.first.name
40
+ assert_equal 'B', @f.fields.first.label
41
+ assert_equal :boolean, @f.fields.first.type
42
+ end
43
+
44
+ def test_adding_a_field_by_name_and_options
45
+ @f.fields = [{:foo => {:label => "Foo Bar", :type => :select}}]
46
+
47
+ assert_equal :foo, @f.fields.first.name
48
+ assert_equal 'Foo Bar', @f.fields.first.label
49
+ assert_equal :select, @f.fields.first.type
50
+ end
51
+
52
+ def test_fields_accessors_are_shortcuts_to_first_group
53
+ @f.fields = [:a]
54
+ assert_equal :a, @f.groups.first.fields.first.name
55
+ assert_equal @f.fields, @f.groups.first.fields
56
+ end
57
+
58
+ def test_adding_an_unnamed_group_of_fields
59
+ @f.groups = [[:a]]
60
+
61
+ assert_nil @f.groups.first.name
62
+ assert_equal :a, @f.groups.first.fields.first.name
63
+ end
64
+
65
+ def test_adding_a_named_group_of_fields
66
+ @f.groups = [{"foo" => [:a]}]
67
+
68
+ assert_equal "foo", @f.groups.first.name
69
+ assert_equal :a, @f.groups.first.fields.first.name
70
+ end
71
+ end
72
+
73
+ class FormFieldTest < Presenting::Test
74
+ def setup
75
+ @f = Presentation::Form::Field.new
76
+ end
77
+
78
+ def test_default_value
79
+ @f.name = 'foo'
80
+ assert_equal :foo, @f.value
81
+ end
82
+
83
+ def test_symbol_value
84
+ @f.value = :foo
85
+ assert_equal 'bar', @f.value_from(stub('record', :foo => 'bar'))
86
+ end
87
+
88
+ def test_string_value
89
+ @f.value = 'foo'
90
+ assert_equal 'foo', @f.value_from(stub('record', :foo => 'bar'))
91
+ end
92
+
93
+ def test_proc_value
94
+ @f.value = proc{|r| r.foo }
95
+ assert_equal 'bar', @f.value_from(stub('record', :foo => 'bar'))
96
+ end
97
+ end
98
+
99
+ class FormRenderingTest < Presentation::RenderTest
100
+ def setup
101
+ @presentation = Presentation::Form.new
102
+ @presentation.controller = TestController.new
103
+ end
104
+
105
+ def test_rendering_a_string_field
106
+ @presentation.presentable = User.new(:name => 'bob smith')
107
+ @presentation.fields = [:name]
108
+
109
+ assert_select 'form div.field' do
110
+ assert_select 'label', 'Name'
111
+ assert_select "input[type=text][name='user[name]'][value='bob smith']"
112
+ end
113
+ end
114
+
115
+ def test_rendering_a_string_field_with_a_custom_value
116
+ @presentation.presentable = User.new(:name => 'bob smith')
117
+ @presentation.fields << {:name => {:value => 'test'}}
118
+
119
+ assert_select 'form div.field' do
120
+ assert_select "input[type=text][name='user[name]'][value='test']"
121
+ end
122
+ end
123
+
124
+ def test_rendering_a_text_field
125
+ @presentation.presentable = User.new(:name => 'bob smith')
126
+ @presentation.fields = [{:name => :text}]
127
+
128
+ assert_select 'form div.field' do
129
+ assert_select 'label', 'Name'
130
+ assert_select "textarea[name='user[name]']", 'bob smith'
131
+ end
132
+ end
133
+
134
+ def test_rendering_a_text_field_with_a_custom_value
135
+ @presentation.presentable = User.new(:name => 'bob smith')
136
+ @presentation.fields << {:name => {:type => :text, :value => 'test'}}
137
+
138
+ assert_select 'form div.field' do
139
+ assert_select "textarea[name='user[name]']", 'test'
140
+ end
141
+ end
142
+
143
+ def test_rendering_a_readonly_field
144
+ @presentation.presentable = User.new(:name => 'bob smith')
145
+ @presentation.fields = [{:name => :readonly}]
146
+
147
+ assert_select 'form div.field' do
148
+ assert_select 'label', 'Name'
149
+ assert_select "input[type=text][disabled=disabled][name='user[name]'][value='bob smith']"
150
+ end
151
+ end
152
+
153
+ def test_rendering_a_readonly_field_with_a_custom_value
154
+ @presentation.presentable = User.new(:name => 'bob smith')
155
+ @presentation.fields << {:name => {:type => :readonly, :value => 'test'}}
156
+
157
+ assert_select 'form div.field' do
158
+ assert_select "input[type=text][disabled=disabled][name='user[name]'][value='test']"
159
+ end
160
+ end
161
+
162
+ def test_rendering_a_password_field
163
+ @presentation.presentable = User.new(:name => 'bob smith')
164
+ @presentation.fields = [{:name => :password}]
165
+
166
+ assert_select 'form div.field' do
167
+ assert_select 'label', 'Name'
168
+ assert_select "input[type=password][name='user[name]'][value='bob smith']"
169
+ end
170
+ end
171
+
172
+ def test_rendering_a_boolean_field
173
+ @presentation.presentable = User.new(:suspended => false, :registered => true)
174
+ @presentation.fields = [{:suspended => :boolean}, {:registered => :boolean}]
175
+
176
+ assert_select 'form div.field:nth-of-type(1)' do
177
+ assert_select 'label', 'Suspended'
178
+ assert_select "input[type=checkbox][name='user[suspended]']"
179
+ end
180
+ assert_select 'form div.field:nth-of-type(2)' do
181
+ assert_select 'label', 'Registered'
182
+ assert_select "input[type=checkbox][name='user[registered]'][checked=checked]"
183
+ end
184
+ end
185
+
186
+ def test_rendering_a_hidden_field
187
+ @presentation.presentable = User.new(:suspended => false)
188
+ @presentation.fields = [{:suspended => :hidden}]
189
+
190
+ assert_select 'form' do
191
+ assert_select 'label', {:text => 'Suspended', :count => 0}
192
+ assert_select "input[type=hidden][name='user[suspended]']"
193
+ end
194
+ end
195
+
196
+ def test_rendering_a_dropdown_field
197
+ @presentation.presentable = User.new(:prefix => 'mr')
198
+ @presentation.fields = [{:prefix => {:type => :dropdown, :type_options => [['Mr.', 'mr'], ['Mrs.', 'mrs']]}}]
199
+
200
+ assert_select 'form div.field' do
201
+ assert_select 'label', 'Prefix'
202
+ assert_select "select[name='user[prefix]']" do
203
+ assert_select "option[value=mr][selected=selected]", "Mr."
204
+ assert_select "option[value=mrs]", "Mrs."
205
+ end
206
+ end
207
+ end
208
+
209
+ def test_rendering_a_radios_field
210
+ @presentation.presentable = User.new(:prefix => 'mr')
211
+ @presentation.fields = [{:prefix => {:type => :radios, :type_options => [['Mr.', 'mr'], ['Mrs.', 'mrs']]}}]
212
+
213
+ assert_select 'form div.field' do
214
+ assert_select 'label', 'Prefix'
215
+ assert_select "label[for=user_prefix_mr]", "Mr."
216
+ assert_select "input[type=radio][name='user[prefix]'][value=mr][checked=checked]"
217
+ assert_select "label[for=user_prefix_mrs]", "Mrs."
218
+ assert_select "input[type=radio][name='user[prefix]'][value=mrs]"
219
+ end
220
+ end
221
+
222
+ def test_rendering_a_multi_select_field
223
+ @presentation.presentable = User.new(:role_ids => [1,3])
224
+ @presentation.fields = [{:role_ids => {:type => :multi_select, :type_options => [['A', 1], ['B', 2], ['C', 3]], :label => "Roles"}}]
225
+
226
+ assert_select 'form div.field' do
227
+ assert_select 'label', 'Roles'
228
+ assert_select "select[name='user[role_ids][]'][multiple=multiple]" do
229
+ assert_select "option[value=1][selected=selected]", "A"
230
+ assert_select "option[value=2]", "B"
231
+ assert_select "option[value=3][selected=selected]", "C"
232
+ end
233
+ end
234
+ end
235
+
236
+ def test_rendering_a_group_of_fields
237
+ @presentation.presentable = User.new
238
+ @presentation.groups = [
239
+ [:name, :email],
240
+ {"flags" => [:registered, :suspended]}
241
+ ]
242
+
243
+ assert_select "form fieldset:nth-of-type(1)" do
244
+ assert_select "legend", false
245
+ assert_select "div.field input[name='user[name]']"
246
+ assert_select "div.field input[name='user[email]']"
247
+ end
248
+ assert_select "form fieldset:nth-of-type(2)" do
249
+ assert_select "legend", "flags"
250
+ assert_select "div.field input[name='user[registered]']"
251
+ assert_select "div.field input[name='user[suspended]']"
252
+ end
253
+ end
254
+
255
+ class User
256
+ include Presenting::Configurable
257
+
258
+ attr_accessor :prefix
259
+ attr_accessor :name
260
+ attr_accessor :email
261
+ attr_accessor :registered
262
+ attr_accessor :suspended
263
+ attr_accessor :role_ids
264
+
265
+ ##
266
+ ## duck typing
267
+ ##
268
+
269
+ def new_record=(val)
270
+ @new_record = val
271
+ end
272
+
273
+ def new_record?
274
+ !! @new_record
275
+ end
276
+
277
+ def id
278
+ @id ||= new_record? ? nil : '12345'
279
+ end
280
+
281
+ def to_param
282
+ id
283
+ end
284
+
285
+ def self.name; 'User' end
286
+ end
287
+ end
data/test/grid_test.rb ADDED
@@ -0,0 +1,219 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class GridTest < Presenting::Test
4
+ def setup
5
+ @g = Presentation::Grid.new
6
+ end
7
+
8
+ def test_default_title
9
+ @g.id = "something_or_other"
10
+ assert_equal "Something Or Other", @g.title
11
+ end
12
+
13
+ def test_adding_a_field_by_name
14
+ @g.fields = ["foo"]
15
+ assert_equal "foo", @g.fields.first.name, "name is stringified"
16
+ assert_equal "foo", @g.fields.first.value, "value is assumed to be a method"
17
+ end
18
+
19
+ def test_adding_a_field_by_name_and_value
20
+ @g.fields = [{"foo" => :bar}]
21
+ assert_equal "foo", @g.fields.first.name, "key is name"
22
+ assert_equal :bar, @g.fields.first.value, "value is value"
23
+ end
24
+
25
+ def test_adding_a_field_by_name_and_options
26
+ @g.fields = [{"foo" => {:value => :bar}}]
27
+ assert_equal "foo", @g.fields.first.name, "key is name"
28
+ assert_equal :bar, @g.fields.first.value, "value is found and saved"
29
+ end
30
+
31
+ def test_adding_links_as_strings
32
+ @g.links = ['<a href="/foo">foo</a>']
33
+ assert_equal 1, @g.links.size
34
+ end
35
+
36
+ def test_adding_links_as_procs
37
+ assert_raises ArgumentError do
38
+ @g.links = [proc{|record| link_to(record.name, record)}]
39
+ end
40
+ end
41
+
42
+ def test_adding_record_links_as_procs
43
+ @g.record_links = [proc{|record| link_to(record.name, record)}]
44
+ assert_equal 1, @g.record_links.size
45
+ end
46
+
47
+ def test_adding_nil_record_links
48
+ assert_nothing_raised do
49
+ # this would happen if a link sometimes did not appear
50
+ @g.record_links = [nil]
51
+ end
52
+ assert @g.record_links.empty?
53
+ end
54
+
55
+ def test_adding_record_links_as_strings
56
+ assert_raises ArgumentError do
57
+ @g.record_links = ['<a href="/foo">foo</a>']
58
+ end
59
+ end
60
+
61
+ def test_arrays_do_not_paginate
62
+ @g.presentable = []
63
+ assert !@g.paginate?
64
+ end
65
+
66
+ def test_paginated_collections_will_paginate
67
+ @g.presentable = WillPaginate::Collection.new(1, 1)
68
+ assert @g.paginate?
69
+ end
70
+ end
71
+
72
+ class GridFieldTest < Presenting::Test
73
+ def setup
74
+ @f = Presentation::Grid::Field.new
75
+ end
76
+
77
+ def test_default_sorting_for_field
78
+ @f.name = "First Name"
79
+ assert @f.sortable?
80
+ assert_equal "first_name", @f.sort_name
81
+ end
82
+
83
+ def test_sortable_field
84
+ @f.name = "First Name"
85
+ @f.sortable = true
86
+ assert @f.sortable?
87
+ assert_equal "first_name", @f.sort_name
88
+ end
89
+
90
+ def test_specified_sort_name
91
+ @f.name = "First Name"
92
+ @f.sortable = "foo"
93
+ assert @f.sortable?
94
+ assert_equal "foo", @f.sort_name
95
+ end
96
+
97
+ def test_unsortable_field
98
+ @f.sortable = false
99
+ assert !@f.sortable?
100
+ end
101
+ end
102
+
103
+ class GridRenderTest < Presentation::RenderTest
104
+ def setup
105
+ @presentation = Presentation::Grid.new(:id => "users", :fields => [:name, :email])
106
+ @records = [
107
+ stub('user', :name => 'foo', :email => 'foo@example.com'),
108
+ stub('user', :name => 'bar', :email => 'bar@example.com')
109
+ ]
110
+ @presentation.presentable = @records
111
+ @presentation.controller = TestController.new
112
+ @presentation.controller.params = {:controller => 'users', :action => 'index'} # WillPaginate reuses existing params
113
+ end
114
+
115
+ def test_rendering_the_title
116
+ assert_select "#users table caption", 'Users'
117
+ end
118
+
119
+ def test_rendering_links
120
+ @presentation.links = ['<a href="/foo" class="foo">bar</a>']
121
+
122
+ assert_select '#users caption ul.actions' do
123
+ assert_select 'li a.foo', 'bar'
124
+ end
125
+ end
126
+
127
+ def test_rendering_record_links
128
+ @presentation.record_links = [proc{|r| "<a href='/foo' class='record-link'>#{r.name}</a>"}]
129
+
130
+ assert_select '#users tbody tr td ul.actions' do
131
+ assert_select 'li a.record-link', 'foo'
132
+ assert_select 'li a.record-link', 'bar'
133
+ end
134
+ end
135
+
136
+ def test_rendering_column_headers
137
+ assert_select "#users" do
138
+ assert_select "thead" do
139
+ assert_select "th.name", "Name"
140
+ assert_select "th.email", "Email"
141
+ end
142
+ end
143
+ end
144
+
145
+ def test_rendering_rows
146
+ assert_select "#users tbody" do
147
+ assert_select "tr:nth-child(1)" do
148
+ assert_select 'td.name', 'foo'
149
+ assert_select 'td.email', 'foo@example.com'
150
+ end
151
+ assert_select "tr:nth-child(2)" do
152
+ assert_select 'td.name', 'bar'
153
+ assert_select 'td.email', 'bar@example.com'
154
+ end
155
+ end
156
+ end
157
+
158
+ def test_rendering_no_rows
159
+ @presentation.presentable = []
160
+ assert_select "#users tbody" do
161
+ assert_select "tr", 1
162
+ assert_select "tr td", "No records found."
163
+ end
164
+ end
165
+
166
+ def test_rendering_sanitized_data
167
+ @presentation.fields['Name'].sanitize = true
168
+ @presentation.fields['Email'].sanitize = false
169
+ @records << stub('row', :name => '&', :email => '&')
170
+
171
+ assert_select "#users tbody tr" do
172
+ assert_select 'td.name', '&amp;'
173
+ assert_select 'td.email', '&'
174
+ end
175
+ end
176
+
177
+ def test_rendering_sanitized_arrays
178
+ @records << stub('row', :name => ['bob', '&', 'lucy'], :email => '')
179
+
180
+ assert_select "#users tbody tr" do
181
+ assert_select 'td.name' do
182
+ assert_select 'ol li:nth-child(2)', '&amp;'
183
+ end
184
+ end
185
+ end
186
+
187
+ def test_rendering_with_pagination
188
+ @presentation.presentable = WillPaginate::Collection.new(1, 1, 2)
189
+ assert_select '#users tfoot .pagination'
190
+ end
191
+
192
+ def test_rendering_sortable_columns
193
+ @presentation.fields.each{|f| f.sortable = true}
194
+
195
+ assert_select "#users thead" do
196
+ assert_select "th a.sortable", "Name"
197
+ assert_select "th a.sortable", "Email"
198
+ end
199
+ end
200
+
201
+ def test_rendering_unsortable_columns
202
+ @presentation.fields.each{|f| f.sortable = false}
203
+
204
+ assert_select "#users thead" do
205
+ assert_select "th", "Name"
206
+ assert_select "th", "Email"
207
+ end
208
+ end
209
+
210
+ def test_rendering_a_sorted_column
211
+ @presentation.fields.each{|f| f.sortable = true}
212
+ @presentation.controller.request.query_parameters = {"sort" => {'name' => 'desc'}}
213
+
214
+ assert_select "#users thead" do
215
+ assert_select "th a.sortable[href='/?sort%5Bname%5D=asc']", "Name"
216
+ end
217
+ end
218
+ end
219
+
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'action_view/test_case'
3
+
4
+ class Presenting::HelpersTest < ActionView::TestCase
5
+
6
+ def test_presenting_a_boolean
7
+ assert_equal 'False', present(false)
8
+ assert_equal 'True', present(true)
9
+ end
10
+
11
+ def test_presenting_a_nil
12
+ assert_equal "", present(nil)
13
+ end
14
+
15
+ def test_presenting_an_array_creates_an_ordered_list
16
+ assert present(['hello', 'world']) =~ %r|^<ol>.*</ol>$|
17
+ end
18
+
19
+ def test_presenting_an_array_presents_the_members
20
+ assert present([true]).include?("<li>True</li>")
21
+ end
22
+
23
+ def test_presenting_a_hash_creates_a_definition_list
24
+ assert present({1 => 'a'}) =~ %r|^<dl>.*</dl>$|
25
+ end
26
+
27
+ def test_presenting_a_hash_sorts_by_hash_keys
28
+ assert present({1 => 'a', 4 => 'd', 3 => 'c', 2 => 'b'}) =~ /^.*a.*b.*c.*d.*$/
29
+ end
30
+
31
+ def test_presenting_a_hash_presents_the_values
32
+ assert present({1 => true}).include?("<dd>True</dd>")
33
+ end
34
+
35
+ def test_presenting_a_time
36
+ assert_equal 'Fri, 13 Feb 2009 02:31:00 -0800', present(Time.parse('02/13/2009 02:31 AM').to_time)
37
+ end
38
+
39
+ def test_presenting_a_date
40
+ assert_equal '2009-02-13', present(Time.parse('02/13/2009 02:31 AM').to_date)
41
+ end
42
+
43
+ def test_presenting_a_string
44
+ assert_equal "hello world", present("hello world")
45
+ end
46
+
47
+ def test_presenting_a_named_method
48
+ assert_equal "<span>hello world</span>", present('hello world', :in_a_span)
49
+ end
50
+
51
+ def test_presenting_a_symbol
52
+ assert_equal "<span></span>", present(:in_a_span)
53
+ end
54
+
55
+ def test_presenting_a_named_presentation
56
+ self.expects(:controller).returns(TestController.new)
57
+ Presentation::Grid.any_instance.expects(:render)
58
+ present('hello', :grid)
59
+ end
60
+
61
+ def test_presenting_an_unknown_presentation
62
+ assert_raises ArgumentError do
63
+ present(@users, :unknown)
64
+ end
65
+ end
66
+
67
+ protected
68
+
69
+ def present_in_a_span(str, options = {})
70
+ "<span>#{str}</span>"
71
+ end
72
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class PresentationTest < Test::Unit::TestCase
4
+
5
+ def test_rendering
6
+ # TODO: create a "hello world" test-only setup so i can test rendering
7
+ @p = Presentation::Grid.new(:id => "hello_world")
8
+ @p.presentable = []
9
+ @p.controller = TestController.new
10
+ assert_nothing_raised do
11
+ assert @p.render
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+
7
+ # See ActionController::RequestForgeryProtection for details
8
+ # Uncomment the :secret if you're not using the cookie session store
9
+ protect_from_forgery # :secret => '0ede37e7d2f6d8445f151b0a38ee0539'
10
+
11
+ # See ActionController::Base for details
12
+ # Uncomment this to filter the contents of submitted sensitive data parameters
13
+ # from your application log (in this case, all fields with names like "password").
14
+ # filter_parameter_logging :password
15
+ end
@@ -0,0 +1,36 @@
1
+ class UsersController < ApplicationController
2
+ def index
3
+ @users = User.paginate(
4
+ :page => params[:page],
5
+ :per_page => 2,
6
+ :conditions => Presenting::Search.new(:fields => {
7
+ 'first_name' => :equals,
8
+ 'last_name' => :begins_with,
9
+ 'email' => :not_null
10
+ }).to_sql(params[:search], :field),
11
+ :order => Presenting::Sorting.new(:fields => [
12
+ :prefix,
13
+ :first_name,
14
+ :last_name,
15
+ :email
16
+ ]).to_sql(params[:sort])
17
+ )
18
+ end
19
+
20
+ def new
21
+ @user = User.new
22
+ end
23
+
24
+ def create
25
+ @user = User.new(params[:user])
26
+ @user.save!
27
+
28
+ redirect_to users_path
29
+ rescue ActiveRecord::RecordInvalid
30
+ render :action => :new
31
+ end
32
+
33
+ def show
34
+ @user = User.find(params[:id])
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <title>Demo Application</title>
6
+ <%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" %>
7
+ <%= javascript_include_tag 'jquery.livequery.min' %>
8
+ <%= presentation_stylesheets('grid', 'search', 'details', 'grid-color', 'search-color', 'details-color') %>
9
+ <%= presentation_javascript('search') %>
10
+ <head>
11
+ <body>
12
+ <%= yield %>
13
+ </body>
14
+ </html>
15
+
@@ -0,0 +1,10 @@
1
+ <%= present :field_search, :fields => [:first_name, :last_name, {:email => :checkbox}] %>
2
+ <%= present @users, :grid, :id => "users",
3
+ :fields => [:prefix, :first_name, :last_name, :email],
4
+ :links => [link_to('add', new_user_path)],
5
+ :record_links => [
6
+ proc{|r| link_to 'edit', edit_user_path(r)},
7
+ proc{|r| link_to 'delete', user_path(r), :method => :destroy},
8
+ proc{|r| link_to 'show', user_path(r)}
9
+ ]
10
+ %>
@@ -0,0 +1,2 @@
1
+ <h2>New User</h2>
2
+ <%= present @user, :form, :groups => [{"Name" => [:prefix, :first_name, :last_name]}, [:email]] %>
@@ -0,0 +1 @@
1
+ <%= present @user, :details, :title => "User ##{@user.id}", :fields => [:prefix, :first_name, :last_name, :email] %>