shway 3.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 (43) hide show
  1. data/CHANGELOG +11 -0
  2. data/Manifest +41 -0
  3. data/README +14 -0
  4. data/Rakefile +47 -0
  5. data/init.rb +2 -0
  6. data/install.rb +0 -0
  7. data/install_files/javascripts/iepngfix.htc +193 -0
  8. data/install_files/javascripts/iepngfix_tilebg.js +155 -0
  9. data/install_files/stylesheets/reset.css +47 -0
  10. data/install_files/templates/example_presenter.rb +12 -0
  11. data/install_files/templates/example_stylesheet.css.rb +20 -0
  12. data/lib/rubygems/commands/shway_init_command.rb +112 -0
  13. data/lib/rubygems_plugin.rb +3 -0
  14. data/lib/shway/controllers/shway_controller.rb +22 -0
  15. data/lib/shway/css/css_helper.rb +221 -0
  16. data/lib/shway/css/css_parser.rb +155 -0
  17. data/lib/shway/css/css_styles.rb +368 -0
  18. data/lib/shway/extensions/routing_extensions.rb +22 -0
  19. data/lib/shway/helpers/html_helper.rb +54 -0
  20. data/lib/shway/helpers/shway_controller_helper.rb +51 -0
  21. data/lib/shway/helpers/shway_helper.rb +187 -0
  22. data/lib/shway/presenters/shway_model_presenter.rb +10 -0
  23. data/lib/shway/presenters/shway_presenter.rb +184 -0
  24. data/lib/shway/test/shway_test_helper.rb +78 -0
  25. data/lib/shway.rb +129 -0
  26. data/shway.gemspec +31 -0
  27. data/templates/css.html.erb +3 -0
  28. data/templates/css.rhtml +3 -0
  29. data/test/shway_core/css_config_test.rb +186 -0
  30. data/test/shway_core/css_helper_test.rb +655 -0
  31. data/test/shway_core/css_parser_test.rb +219 -0
  32. data/test/shway_core/html_helper_test.rb +32 -0
  33. data/test/shway_core/shway_controller_test.rb +44 -0
  34. data/test/shway_core/shway_core_test_helper.rb +45 -0
  35. data/test/shway_core/shway_helper_test.rb +280 -0
  36. data/test/shway_core/shway_presenter_test.rb +173 -0
  37. data/test/shway_core/shway_routes_test.rb +31 -0
  38. data/test/shway_core/views/mock_foos/_list_header.html.erb +1 -0
  39. data/test/shway_core/views/mock_foos/_list_item.html.erb +5 -0
  40. data/test/shway_core/views/model_list/list_for_action.html.erb +1 -0
  41. data/test/shway_core/views/model_list/list_item_for_action.html.erb +1 -0
  42. data/test/shway_core/views/shway_helper_test.html.erb +24 -0
  43. metadata +123 -0
@@ -0,0 +1,219 @@
1
+ require File.join(File.dirname(__FILE__), 'shway_test_helper')
2
+
3
+ class CssParserTest < Test::Unit::TestCase
4
+
5
+ include Shway::Css
6
+
7
+ def test_can_parse_css_style
8
+ rules = parse_simple_css_style
9
+ verify_matches_simple_css_rule rules.first
10
+ end
11
+
12
+ def test_can_parse_css_rules
13
+ rules = parse_simple_css_rules
14
+ verify_matches_simple_css_rule rules.first
15
+ end
16
+
17
+ def test_can_parse_css_rule
18
+ rule = parse_simple_css_rule
19
+ verify_matches_simple_css_rule rule
20
+ end
21
+
22
+ def test_css_rule_to_s_returns_css_string
23
+ assert_equal_ignoring_whitespace simple_css_rule, parse_simple_css_rule.to_s
24
+ end
25
+
26
+ def test_can_parse_css_selector
27
+ assert_equal simple_css_selector, parse_simple_css_selector.pattern
28
+ end
29
+
30
+ def test_css_selector_to_s_returns_css_string
31
+ assert_equal simple_css_selector, parse_simple_css_selector.to_s
32
+ end
33
+
34
+ def test_parsing_invalid_css_selector_raises
35
+ assert_raises RuntimeError do
36
+ CssSelector.parse '.special,H3'
37
+ end
38
+ assert_raises RuntimeError do
39
+ CssSelector.parse '.special;H3'
40
+ end
41
+ assert_raises RuntimeError do
42
+ CssSelector.parse simple_css_rule
43
+ end
44
+ end
45
+
46
+ def test_can_parse_css_declaration
47
+ declaration = parse_simple_css_declaration
48
+ assert_equal simple_css_property, declaration.property.name
49
+ assert_equal simple_css_value, declaration.value.value
50
+ end
51
+
52
+ def test_css_declaration_to_s_returns_css_string
53
+ assert_equal simple_css_declaration, parse_simple_css_declaration.to_s
54
+ end
55
+
56
+ def test_can_parse_css_value
57
+ assert_equal simple_css_value, parse_simple_css_value.value
58
+ end
59
+
60
+ def test_css_value_to_s_returns_css_string
61
+ assert_equal simple_css_value, parse_simple_css_value.to_s
62
+ end
63
+
64
+ def test_can_parse_css_property
65
+ assert_equal simple_css_property, parse_simple_css_property.name
66
+ end
67
+
68
+ def test_css_property_to_s_returns_css_string
69
+ assert_equal simple_css_property, parse_simple_css_property.to_s
70
+ end
71
+
72
+ def test_parsing_invalid_css_property_raises
73
+ assert_raises RuntimeError do
74
+ CssProperty.parse 'font_size'
75
+ end
76
+ assert_raises RuntimeError do
77
+ CssProperty.parse simple_css_declaration
78
+ end
79
+ assert_raises RuntimeError do
80
+ CssProperty.parse ''
81
+ end
82
+ end
83
+
84
+ def test_parsing_symbol_with_css_property_raises
85
+ assert_raises RuntimeError do
86
+ CssProperty.parse :font_size
87
+ end
88
+ end
89
+
90
+ # def test_can_parse_simple_css
91
+ # css_styles = CssParser.css_styles_for(simple_css)
92
+ # css_styles.each do |selector,styles|
93
+ # puts "**SELECTOR: #{selector}"
94
+ # if styles
95
+ # styles.each do |property,value|
96
+ # puts " *#{property}:#{value}"
97
+ # end
98
+ # else
99
+ # puts " *NO STYLES"
100
+ # end
101
+ # end
102
+ # end
103
+
104
+ private
105
+
106
+ def parse_simple_css_style
107
+ CssRule.parse_all simple_css_rules
108
+ end
109
+
110
+ def simple_css_style
111
+ %{
112
+ <style>
113
+ #{simple_css_rules}
114
+ </style>
115
+ <!--[if lt IE 7]><style>
116
+ .test_ie6 {
117
+ background-color:red;
118
+ }
119
+ </style><![endif]-->
120
+ <!--[if IE 7]><style>
121
+ .test_ie7 {
122
+ background-color:green;
123
+ }
124
+ </style><![endif]-->
125
+ }
126
+ end
127
+
128
+ # <!--[if lt IE 7]><style>.image_wrapper_1_e {
129
+ # background-color:#DDD;
130
+ # background-position:100% -25px;
131
+ # }
132
+ # </style><![endif]-->
133
+
134
+
135
+ def parse_simple_css_rules
136
+ CssRule.parse_all simple_css_rules
137
+ end
138
+
139
+ def simple_css_rules
140
+ %{
141
+ #{simple_css_rule}
142
+ .box, .other_box {
143
+ border:1px solid #000;
144
+ width:204px;
145
+ padding:3px 10px;
146
+ padding-right:0px;
147
+ }
148
+ h3 {
149
+ font-family:Helvetica, Verdana, Arial, Sans-Serif;
150
+ font-size:14px;
151
+ font-weight:normal;
152
+ line-height:18px;
153
+ margin-top:2px;
154
+ padding:2px;
155
+ }
156
+ }
157
+ end
158
+
159
+ def parse_simple_css_rule
160
+ CssRule.parse simple_css_rule
161
+ end
162
+
163
+ def simple_css_rule
164
+ %{
165
+ #{simple_css_selector} {
166
+ #{simple_css_declaration};
167
+ }
168
+ }
169
+ end
170
+
171
+ def parse_simple_css_selector
172
+ CssSelector.parse simple_css_selector
173
+ end
174
+
175
+ def simple_css_selector
176
+ ".special h3"
177
+ end
178
+
179
+ def parse_simple_css_declaration
180
+ CssDeclaration.parse simple_css_declaration
181
+ end
182
+
183
+ def simple_css_declaration
184
+ "#{simple_css_property}:#{simple_css_value}"
185
+ end
186
+
187
+ def parse_simple_css_property
188
+ CssProperty.parse simple_css_property
189
+ end
190
+
191
+ def simple_css_property
192
+ 'font-size'
193
+ end
194
+
195
+ def parse_simple_css_value
196
+ CssValue.parse simple_css_value
197
+ end
198
+
199
+ def simple_css_value
200
+ '10px'
201
+ end
202
+
203
+ def assert_equal_ignoring_whitespace(one, two)
204
+ assert_equal remove_whitespace(one), remove_whitespace(two)
205
+ end
206
+
207
+ def remove_whitespace(string)
208
+ string.gsub(' ', '').gsub("\n", '')
209
+ end
210
+
211
+ def verify_matches_simple_css_rule(rule)
212
+ assert_equal simple_css_selector, rule.selectors.first.to_s
213
+ assert_equal simple_css_declaration, rule.declarations.first.to_s
214
+ assert_equal simple_css_property, rule.declarations.first.property.to_s
215
+ assert_equal simple_css_value, rule.declarations.first.value.to_s
216
+ end
217
+
218
+ end
219
+
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), 'shway_test_helper')
2
+
3
+ class HtmlHelperTest < Test::Unit::TestCase
4
+
5
+ include Shway::Helpers::HtmlHelper
6
+ include ActionView::Helpers::AssetTagHelper
7
+ include ActionView::Helpers::TagHelper
8
+ include ActionView::Helpers::JavaScriptHelper
9
+
10
+ def test_html_attribute_generates_expected_html
11
+ html = html_attribute(:id, :test_id)
12
+ assert_equal 'id="test_id"', html
13
+
14
+ html = html_attribute(:id, nil)
15
+ assert_equal '', html
16
+ end
17
+
18
+ def test_default_head_contents_includes_stylesheets_and_javascripts
19
+ html = default_head_contents
20
+ assert_not_nil html.index('global-main')
21
+ assert_not_nil html.index('global-ie7')
22
+ assert_not_nil html.index('global-ie6')
23
+ assert_not_nil html.index('global-safari')
24
+ assert_not_nil html.index('prototype')
25
+ end
26
+
27
+ def test_namespaced_stylesheet_names_are_constructed_correctly
28
+ assert_equal "main", css_namespace_stylesheet("main")
29
+ assert_equal "main-safari", css_namespace_stylesheet("main", "safari")
30
+ end
31
+
32
+ end
@@ -0,0 +1,44 @@
1
+ require File.join(File.dirname(__FILE__), 'shway_test_helper')
2
+
3
+ class ShwayControllerTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ super
7
+ @controller = ShwayController.new
8
+ @request = ActionController::TestRequest.new
9
+ @response = ActionController::TestResponse.new
10
+ end
11
+
12
+ #TODO make this actually test something
13
+ def test_css_action
14
+ get_css
15
+ assert_response :success
16
+ end
17
+
18
+ #TODO make this actually test something
19
+ # def test_css_style_reload
20
+ # get :css_style_reload
21
+ # assert_response :success
22
+ # end
23
+
24
+ #got this test tip from http://mikenaberezny.com/2007/09/08/keep-the-flash-and-test-it-too/
25
+ #TODO not sure this test actually works. :(
26
+ def test_css_action_keeps_flash
27
+ @request.session['flash'] = make_flash_hash(:foo => 'bar')
28
+ get_css
29
+ assert_equal 'bar', @response.flash[:foo]
30
+ end
31
+
32
+ private
33
+
34
+ def get_css
35
+ get :css, :css => 'global-main'
36
+ end
37
+
38
+ def make_flash_hash(with_contents = {})
39
+ returning ActionController::Flash::FlashHash.new do |flash_hash|
40
+ flash_hash.update with_contents
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,45 @@
1
+ #FINALLY! found a fix for the VERY annoying Textmate Builder errors: http://ticket.macromates.com/show?ticket_id=F4DA8B03
2
+ # $:.reject! { |e| e.include? 'TextMate' }
3
+
4
+ ENV["RAILS_ENV"] = "test"
5
+ #note: $: is the load path
6
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
7
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../../config/environment")
8
+ require File.expand_path(File.dirname(__FILE__) + "/../../lib/shway/test/shway_test_helper")
9
+ require 'test_help'
10
+ require 'test/unit'
11
+ require 'flexmock/test_unit'
12
+ require 'ruby-debug'
13
+ require 'pp'
14
+
15
+ class MockFoo
16
+ attr_accessor :name
17
+ def initialize(*args)
18
+ @name = args.first ? args.first[:name] : nil
19
+ super()
20
+ end
21
+ end
22
+
23
+ class MockBar
24
+ end
25
+
26
+ class Test::Unit::TestCase
27
+
28
+ def set_response_body(html)
29
+ @response = ActionController::TestResponse.new
30
+ @response.body = html
31
+ end
32
+
33
+ def new_test_presenter
34
+ ShwayPresenter.new(new_test_controller)
35
+ end
36
+
37
+ def new_test_controller(controller_class=ActionController::Base)
38
+ controller = controller_class.new
39
+ # request = ActionController::TestRequest.new
40
+ controller.response = ActionController::TestResponse.new
41
+ controller.response.template = ActionView::Base.new
42
+ controller.response.template.controller = controller
43
+ end
44
+
45
+ end
@@ -0,0 +1,280 @@
1
+ require File.join(File.dirname(__FILE__), 'shway_test_helper')
2
+
3
+ class ShwayHelperTest < Test::Unit::TestCase
4
+
5
+ include Shway::Css::CssHelper
6
+ include Shway::Helpers::ShwayHelper
7
+
8
+ #TODO figure out how to test this correctly, then remove the test below
9
+ # def test_setting_partial_in_div_includes_partial
10
+ # @controller = ApplicationController.new
11
+ # div :partial => 'whatever'
12
+ # end
13
+
14
+ def test_tag_rendering_is_not_destructive_to_options
15
+ original_options = {
16
+ :partial => 'whatever partial',
17
+ :id => 'whatever id',
18
+ :onclick => 'whatever onclick',
19
+ # :text => 'whatever text',
20
+ :close => 'whatever close',
21
+ :style => 'whatever style',
22
+ :class => 'whatever class',
23
+ }
24
+ passed_options = original_options.clone
25
+ div passed_options
26
+ assert_equal original_options, passed_options
27
+ end
28
+
29
+ def test_setting_partial_in_div_does_not_raise
30
+ assert_nothing_raised do
31
+ div :partial => 'whatever'
32
+ end
33
+ end
34
+
35
+ def test_close_form
36
+ assert_equal _form, '</form>'
37
+ end
38
+
39
+ def test_br
40
+ assert_equal _br, '<BR />'
41
+ end
42
+
43
+ def test_css_class_for_model
44
+ assert_equal 'person', css_class_for(Person.new)
45
+ assert_equal 'some_model', css_class_for(some_model_with_id)
46
+ end
47
+
48
+ def test_css_id_for_model
49
+ model = some_model_with_id
50
+ assert_equal "some_model_#{model.id}", css_id_for(model)
51
+ end
52
+
53
+ def test_css_id_for_model_with_css_class
54
+ css_class = :my_class
55
+ model = some_model_with_id
56
+ assert_equal "#{css_class}_some_model_#{model.id}", css_id_for(model, css_class)
57
+ end
58
+
59
+ def test_div_for_model
60
+ Shway::Css::CssStyles.include_style(:some_model)
61
+ model = some_model_with_id
62
+ html = div(:for => model)
63
+ assert_not_nil html.index(%{id="some_model_99"})
64
+ assert_not_nil html.index('<div ')
65
+ end
66
+
67
+ def test_div_for_model_with_style_name
68
+ Shway::Css::CssStyles.include_style(:my_style)
69
+ Shway::Css::CssStyles.include_style(:some_model)
70
+ model = some_model_with_id
71
+ html = div(:my_style, :for => model)
72
+ assert_not_nil html.index(%{id="my_style_some_model_99"})
73
+ assert_not_nil html.index('<div ')
74
+ assert_not_nil html.index(%{class="my_style"})
75
+ end
76
+
77
+ #TODO add actual errors (not RuntimeError) so we can be checking for the right thing here.
78
+ def test_div_for_model_raises_when_style_is_not_defined
79
+ assert_raises RuntimeError do
80
+ Shway::Css::CssStyles.remove_style(:some_model)
81
+ html = div(:for => some_model_with_id)
82
+ end
83
+ end
84
+
85
+ #TODO add actual errors (not RuntimeError) so we can be checking for the right thing here.
86
+ def test_div_for_model_raises_when_object_passed_is_not_a_model
87
+ assert_raises RuntimeError do
88
+ Shway::Css::CssStyles.include_style(:some_model)
89
+ html = div(:for => SomeModel.new)
90
+ end
91
+ end
92
+
93
+ def test_setting_partial_and_text_in_div_raises
94
+ assert_raises RuntimeError do
95
+ div :partial => 'whatever', :text => :whatever
96
+ end
97
+ end
98
+
99
+ def test_can_set_and_get_css_value
100
+ set_valid_value
101
+ retreived_value = get_css_value valid_value_name
102
+ assert_equal valid_value_value, retreived_value
103
+ end
104
+
105
+ def test_arrange_args_assigns_values_with_hash_always_last
106
+ hash_arg = {:key => :value}
107
+ arg_1 = "1"
108
+ arg_2 = "2"
109
+ arg_3 = "3"
110
+
111
+ args_0 = [hash_arg]
112
+ args_1 = [arg_1, hash_arg]
113
+ args_2 = [arg_1, arg_2, hash_arg]
114
+ args_3 = [arg_1, arg_2, arg_3, hash_arg]
115
+
116
+ value_one,value_two,value_three,hash = arrange_args 4, *args_0
117
+ assert_nil value_one
118
+ assert_nil value_two
119
+ assert_nil value_three
120
+ assert_equal hash_arg, hash
121
+
122
+ value_one,value_two,value_three,hash = arrange_args 4, *args_1
123
+ assert_equal arg_1, value_one
124
+ assert_nil value_two
125
+ assert_nil value_three
126
+ assert_equal hash_arg, hash
127
+
128
+ value_one,value_two,value_three,hash = arrange_args 4, *args_2
129
+ assert_equal arg_1, value_one
130
+ assert_equal arg_2, value_two
131
+ assert_nil value_three
132
+ assert_equal hash_arg, hash
133
+
134
+ value_one,value_two,value_three,hash = arrange_args 4, *args_3
135
+ assert_equal arg_1, value_one
136
+ assert_equal arg_2, value_two
137
+ assert_equal arg_3, value_three
138
+ assert_equal hash_arg, hash
139
+ end
140
+
141
+ def test_can_count_collections
142
+ assert_equal simple_collection_count, count_for_collection_or_count(simple_collection)
143
+ end
144
+
145
+ def test_can_count_arrays
146
+ assert_equal 4, count_for_collection_or_count([0,1,2,3])
147
+ end
148
+
149
+ def test_can_count_numbers
150
+ assert_equal 5, count_for_collection_or_count(5)
151
+ end
152
+
153
+ def test_can_select_string_by_count
154
+ assert_equal simple_value_for_one, simple_select_string_by_count(1)
155
+ assert_equal simple_value_for_anything_other_than_one, simple_select_string_by_count(0)
156
+ assert_equal simple_value_for_anything_other_than_one, simple_select_string_by_count(2)
157
+ assert_equal simple_value_for_anything_other_than_one, simple_select_string_by_count(-1)
158
+ end
159
+
160
+ def test_can_select_was_or_were_for_count
161
+ assert_equal "was", was_or_were_for(1)
162
+ assert_equal "were", was_or_were_for(0)
163
+ assert_equal "were", was_or_were_for(2)
164
+ assert_equal "were", was_or_were_for(-1)
165
+ end
166
+
167
+ def test_can_pluralize_for_count
168
+ singular_form = "form"
169
+ plural_form = "forms"
170
+ assert_equal singular_form, pluralize_for(plural_form, 1)
171
+ assert_equal plural_form, pluralize_for(plural_form, 0)
172
+ assert_equal plural_form, pluralize_for(plural_form, 2)
173
+ assert_equal plural_form, pluralize_for(plural_form, -1)
174
+ end
175
+
176
+ def test_can_pluralize_for_count_from_active_record_model
177
+ singular_form = "Person"
178
+ plural_form = "People"
179
+ flexmock(Person).should_receive(:table_name).and_return(plural_form)
180
+ assert_equal singular_form, pluralize_for(Person, 1)
181
+ assert_equal plural_form, pluralize_for(plural_form, 0)
182
+ assert_equal plural_form, pluralize_for(plural_form, 2)
183
+ assert_equal plural_form, pluralize_for(plural_form, -1)
184
+ end
185
+
186
+ def test_can_get_count_description_for_count
187
+ plural_form = "forms"
188
+ assert_equal "1 form", count_for(1, plural_form)
189
+ assert_equal "0 forms", count_for(0, plural_form)
190
+ assert_equal "2 forms", count_for(2, plural_form)
191
+ assert_equal "-1 forms", count_for(-1, plural_form)
192
+ end
193
+
194
+ def test_can_use_render_partial_to_string_in_a_controller
195
+ rendered_string = simple_controller.render_shway_test_partial_to_string
196
+ assert_equal simple_controller.partial_string, rendered_string
197
+ end
198
+
199
+ private
200
+
201
+ class FooController < ActionController::Base
202
+
203
+ include Shway::Helpers::ShwayHelper
204
+
205
+ def render_shway_test_partial_to_string
206
+ #TODO add :locals to this call
207
+ render_partial_to_string :partial => partial_string
208
+ end
209
+
210
+ def render_to_string(args)
211
+ return args[:partial]
212
+ end
213
+
214
+ def partial_string
215
+ 'test/shway_test_partial'
216
+ end
217
+
218
+ end
219
+
220
+ def some_model_with_id
221
+ model_id = 99
222
+ model = SomeModel.new
223
+ flexmock(model).should_receive(:id).and_return(model_id)
224
+ flexmock(model).should_receive(:kind_of?).and_return(true)
225
+ model
226
+ end
227
+
228
+ def simple_controller
229
+ @simple_controller ||= FooController.new
230
+ end
231
+
232
+ class FooCollection
233
+ def count
234
+ 7
235
+ end
236
+ end
237
+
238
+ def simple_collection
239
+ FooCollection.new
240
+ end
241
+
242
+ def simple_collection_count
243
+ FooCollection.new.count
244
+ end
245
+
246
+ def simple_select_string_by_count(count)
247
+ select_string_by_count simple_value_for_one, simple_value_for_anything_other_than_one, count
248
+ end
249
+
250
+ def simple_value_for_one
251
+ "one"
252
+ end
253
+
254
+ def simple_value_for_anything_other_than_one
255
+ "not one"
256
+ end
257
+
258
+ def set_valid_value
259
+ CssStyles.value valid_value_name => valid_value_value
260
+ end
261
+
262
+ def valid_value_name
263
+ :valid_value_name
264
+ end
265
+
266
+ def valid_value_value
267
+ "**valid_value_value**"
268
+ end
269
+
270
+ def render(args)
271
+ #this is a stub for what would be there on a controller or view
272
+ end
273
+
274
+ end
275
+
276
+ class Person < ActiveRecord::Base
277
+ end
278
+
279
+ class SomeModel# < ActiveRecord::Base NOTE: can't make this extend ARBase without a bunch of errors happening, so we mock up top.
280
+ end