fortitude 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +28 -22
- data/CHANGES.md +50 -0
- data/CONTRIBUTORS.md +1 -0
- data/doc/.gitignore +18 -0
- data/doc/Gemfile +21 -0
- data/doc/config.rb +92 -0
- data/doc/source/images/background.png +0 -0
- data/doc/source/images/middleman.png +0 -0
- data/doc/source/images/why/icon_button.png +0 -0
- data/doc/source/images/why/icon_button@2x.png +0 -0
- data/doc/source/images/why/modal_dialog@2x.png +0 -0
- data/doc/source/index.html.pcss +96 -0
- data/doc/source/index.html.rb +66 -0
- data/doc/source/javascripts/all.js +1 -0
- data/doc/source/javascripts/highlight.pack.js +1 -0
- data/doc/source/layouts/layout.rb +55 -0
- data/doc/source/portable/fortitude-bootstrap.rb +53 -0
- data/doc/source/shared/base.pcss +62 -0
- data/doc/source/shared/base.rb +30 -0
- data/doc/source/shared/common.rb +55 -0
- data/doc/source/shared/standard_page.rb +40 -0
- data/doc/source/stylesheets/_shared_prefix.scss +25 -0
- data/doc/source/stylesheets/all.css.scss +7 -0
- data/doc/source/stylesheets/basics.css.scss +20 -0
- data/doc/source/stylesheets/bootstrap_importer.css.scss +1 -0
- data/doc/source/stylesheets/highlight/arta.css +140 -0
- data/doc/source/stylesheets/highlight/ascetic.css +52 -0
- data/doc/source/stylesheets/highlight/atelier-dune.dark.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-dune.light.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-forest.dark.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-forest.light.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-heath.dark.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-heath.light.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-lakeside.dark.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-lakeside.light.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-seaside.dark.css +95 -0
- data/doc/source/stylesheets/highlight/atelier-seaside.light.css +95 -0
- data/doc/source/stylesheets/highlight/brown_paper.css +104 -0
- data/doc/source/stylesheets/highlight/brown_papersq.png +0 -0
- data/doc/source/stylesheets/highlight/codepen-embed.css +108 -0
- data/doc/source/stylesheets/highlight/color-brewer.css +168 -0
- data/doc/source/stylesheets/highlight/dark.css +104 -0
- data/doc/source/stylesheets/highlight/default.css +152 -0
- data/doc/source/stylesheets/highlight/docco.css +135 -0
- data/doc/source/stylesheets/highlight/far.css +111 -0
- data/doc/source/stylesheets/highlight/foundation.css +136 -0
- data/doc/source/stylesheets/highlight/github.css +124 -0
- data/doc/source/stylesheets/highlight/googlecode.css +147 -0
- data/doc/source/stylesheets/highlight/hybrid.css +170 -0
- data/doc/source/stylesheets/highlight/idea.css +125 -0
- data/doc/source/stylesheets/highlight/ir_black.css +109 -0
- data/doc/source/stylesheets/highlight/kimbie.dark.css +96 -0
- data/doc/source/stylesheets/highlight/kimbie.light.css +96 -0
- data/doc/source/stylesheets/highlight/magula.css +121 -0
- data/doc/source/stylesheets/highlight/mono-blue.css +69 -0
- data/doc/source/stylesheets/highlight/monokai.css +127 -0
- data/doc/source/stylesheets/highlight/monokai_sublime.css +154 -0
- data/doc/source/stylesheets/highlight/obsidian.css +153 -0
- data/doc/source/stylesheets/highlight/paraiso.dark.css +95 -0
- data/doc/source/stylesheets/highlight/paraiso.light.css +95 -0
- data/doc/source/stylesheets/highlight/pojoaque.css +107 -0
- data/doc/source/stylesheets/highlight/pojoaque.jpg +0 -0
- data/doc/source/stylesheets/highlight/railscasts.css +187 -0
- data/doc/source/stylesheets/highlight/rainbow.css +108 -0
- data/doc/source/stylesheets/highlight/school_book.css +112 -0
- data/doc/source/stylesheets/highlight/school_book.png +0 -0
- data/doc/source/stylesheets/highlight/solarized_dark.css +108 -0
- data/doc/source/stylesheets/highlight/solarized_light.css +108 -0
- data/doc/source/stylesheets/highlight/sunburst.css +164 -0
- data/doc/source/stylesheets/highlight/tomorrow-night-blue.css +95 -0
- data/doc/source/stylesheets/highlight/tomorrow-night-bright.css +94 -0
- data/doc/source/stylesheets/highlight/tomorrow-night-eighties.css +94 -0
- data/doc/source/stylesheets/highlight/tomorrow-night.css +95 -0
- data/doc/source/stylesheets/highlight/tomorrow.css +92 -0
- data/doc/source/stylesheets/highlight/vs.css +93 -0
- data/doc/source/stylesheets/highlight/xcode.css +158 -0
- data/doc/source/stylesheets/highlight/zenburn.css +118 -0
- data/doc/source/why/a_larger_view.html.rb +774 -0
- data/doc/source/why/a_simple_helper.html.rb +332 -0
- data/doc/source/why/building_a_rich_modal_dialog.html.rb +156 -0
- data/doc/source/why/commonality_and_inheritance.html.rb +564 -0
- data/doc/source/why/example_list.rb +60 -0
- data/doc/source/why/example_page.rb +116 -0
- data/doc/source/why/index.html.rb +86 -0
- data/doc/source/why/other_benefits.html.rb +110 -0
- data/fortitude.gemspec +6 -1
- data/lib/fortitude/doctypes/html4_tags_strict.rb +1 -0
- data/lib/fortitude/doctypes/html5.rb +1 -0
- data/lib/fortitude/method_templates/tag_method_template.rb.smpl +27 -14
- data/lib/fortitude/rails/helpers.rb +2 -2
- data/lib/fortitude/rendering_context.rb +10 -1
- data/lib/fortitude/tags/tag.rb +3 -2
- data/lib/fortitude/tags/tag_support.rb +8 -3
- data/lib/fortitude/tilt/fortitude_template.rb +6 -2
- data/lib/fortitude/version.rb +1 -1
- data/lib/fortitude/widget.rb +2 -0
- data/lib/fortitude/widget/convenience.rb +30 -0
- data/lib/fortitude/widget/files.rb +22 -11
- data/lib/fortitude/widget/needs.rb +5 -3
- data/spec/helpers/system_helpers.rb +1 -0
- data/spec/rails/development_mode_system_spec.rb +0 -1
- data/spec/rails/rendering_system_spec.rb +20 -1
- data/spec/rails/templates/rendering_system_spec/app/controllers/rendering_system_spec_controller.rb +13 -0
- data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_hash_subclass.rb +18 -0
- data/spec/rails/templates/rendering_system_spec/lib/my_hash.rb +5 -0
- data/spec/system/convenience_methods_system_spec.rb +166 -0
- data/spec/system/formatting_system_spec.rb +25 -1
- data/spec/system/tag_rendering_system_spec.rb +73 -0
- data/spec/system/tilt_system_spec.rb +31 -0
- data/spec/system/widget_class_from_spec.rb +20 -4
- metadata +92 -4
@@ -59,9 +59,9 @@ module Fortitude
|
|
59
59
|
# form_helper
|
60
60
|
FORM_FOR_YIELDED_METHODS_TO_OUTPUT =
|
61
61
|
# Directly from form_helper
|
62
|
-
%w{check_box color_field date_field datetime_field datetime_local_field} +
|
62
|
+
%w{button check_box color_field date_field datetime_field datetime_local_field} +
|
63
63
|
%w{email_field file_field hidden_field label month_field number_field password_field phone_field} +
|
64
|
-
%w{radio_button range_field search_field telephone_field text_area text_field time_field url_field} +
|
64
|
+
%w{radio_button range_field search_field submit telephone_field text_area text_field time_field url_field} +
|
65
65
|
%w{week_field} +
|
66
66
|
|
67
67
|
# From form_options_helper
|
@@ -140,6 +140,15 @@ module Fortitude
|
|
140
140
|
@newline_needed = true
|
141
141
|
end
|
142
142
|
|
143
|
+
def suppress_formatting!
|
144
|
+
@suppress_formatting_level ||= 0
|
145
|
+
@suppress_formatting_level += 1
|
146
|
+
end
|
147
|
+
|
148
|
+
def desuppress_formatting!
|
149
|
+
@suppress_formatting_level -= 1
|
150
|
+
end
|
151
|
+
|
143
152
|
def current_indent
|
144
153
|
(" " * @indent).freeze
|
145
154
|
end
|
@@ -155,7 +164,7 @@ module Fortitude
|
|
155
164
|
end
|
156
165
|
|
157
166
|
def about_to_output_non_whitespace!
|
158
|
-
if @newline_needed
|
167
|
+
if @newline_needed && ((@suppress_formatting_level ||= 0) == 0)
|
159
168
|
if @have_output
|
160
169
|
o = @output_buffer_holder.output_buffer
|
161
170
|
o.original_concat(NEWLINE)
|
data/lib/fortitude/tags/tag.rb
CHANGED
@@ -31,7 +31,7 @@ module Fortitude
|
|
31
31
|
|
32
32
|
def initialize(name, options = { })
|
33
33
|
options.assert_valid_keys(:valid_attributes, :newline_before, :content_allowed, :can_enclose,
|
34
|
-
:allow_data_attributes, :allow_aria_attributes, :spec, :escape_direct_content)
|
34
|
+
:allow_data_attributes, :allow_aria_attributes, :spec, :escape_direct_content, :suppress_formatting_inside)
|
35
35
|
|
36
36
|
@name = self.class.normalize_tag_name(name)
|
37
37
|
|
@@ -42,6 +42,7 @@ module Fortitude
|
|
42
42
|
@allow_data_attributes = true unless options.has_key?(:allow_data_attributes) && (! options[:allow_data_attributes])
|
43
43
|
@allow_aria_attributes = true unless options.has_key?(:allow_aria_attributes) && (! options[:allow_aria_attributes])
|
44
44
|
@escape_direct_content = true unless options.has_key?(:escape_direct_content) && (! options[:escape_direct_content])
|
45
|
+
@suppress_formatting_inside = !! options[:suppress_formatting_inside]
|
45
46
|
@spec = options[:spec]
|
46
47
|
end
|
47
48
|
|
@@ -141,7 +142,7 @@ module Fortitude
|
|
141
142
|
needs_formatting = !! options[:enable_formatting]
|
142
143
|
|
143
144
|
if needs_formatting && @newline_before
|
144
|
-
yield_call = "_fortitude_formatted_output_tag_yield(:#{name}) { yield }"
|
145
|
+
yield_call = "_fortitude_formatted_output_tag_yield(:#{name}, #{@suppress_formatting_inside.inspect}) { yield }"
|
145
146
|
elsif needs_formatting
|
146
147
|
yield_call = "yield; rc.about_to_output_non_whitespace!"
|
147
148
|
else
|
@@ -18,17 +18,22 @@ module Fortitude
|
|
18
18
|
|
19
19
|
FORTITUDE_TAG_PARTIAL_OPEN_END = ">".freeze
|
20
20
|
|
21
|
-
def _fortitude_formatted_output_tag_yield(tag_name)
|
21
|
+
def _fortitude_formatted_output_tag_yield(tag_name, suppress_formatting_inside)
|
22
22
|
rc = @_fortitude_rendering_context
|
23
23
|
if rc.format_output?
|
24
24
|
rc.needs_newline!
|
25
25
|
rc.increase_indent!
|
26
26
|
begin
|
27
|
+
rc.suppress_formatting! if suppress_formatting_inside
|
27
28
|
yield
|
28
29
|
ensure
|
29
30
|
rc.decrease_indent!
|
30
|
-
|
31
|
-
|
31
|
+
if suppress_formatting_inside
|
32
|
+
rc.desuppress_formatting!
|
33
|
+
else
|
34
|
+
rc.needs_newline!
|
35
|
+
rc.about_to_output_non_whitespace!
|
36
|
+
end
|
32
37
|
end
|
33
38
|
else
|
34
39
|
yield
|
@@ -7,7 +7,11 @@ module Fortitude
|
|
7
7
|
module Tilt
|
8
8
|
class FortitudeTemplate < ::Tilt::Template
|
9
9
|
def prepare
|
10
|
-
|
10
|
+
if file && line
|
11
|
+
::Object.class_eval(data, file, line)
|
12
|
+
else
|
13
|
+
::Object.class_eval(data)
|
14
|
+
end
|
11
15
|
|
12
16
|
# 2014-06-19 ageweke -- Earlier versions of Tilt try to instantiate the engine with an empty tempate as a way
|
13
17
|
# of making sure it can be created, so we have to support this case.
|
@@ -26,7 +30,7 @@ module Fortitude
|
|
26
30
|
:yield_block => block, :render_yield_result => false,
|
27
31
|
:helpers_object => scope, :instance_variables_object => scope })
|
28
32
|
|
29
|
-
widget_assigns = { }
|
33
|
+
widget_assigns = { }
|
30
34
|
|
31
35
|
scope.instance_variables.each do |instance_variable_name|
|
32
36
|
if instance_variable_name.to_s =~ /^\@(.*)$/
|
data/lib/fortitude/version.rb
CHANGED
data/lib/fortitude/widget.rb
CHANGED
@@ -15,6 +15,7 @@ require 'fortitude/widget/capturing'
|
|
15
15
|
require 'fortitude/widget/rendering'
|
16
16
|
require 'fortitude/widget/temporary_overrides'
|
17
17
|
require 'fortitude/widget/files'
|
18
|
+
require 'fortitude/widget/convenience'
|
18
19
|
|
19
20
|
require 'fortitude/doctypes'
|
20
21
|
|
@@ -40,6 +41,7 @@ module Fortitude
|
|
40
41
|
include Fortitude::Widget::Rendering
|
41
42
|
include Fortitude::Widget::TemporaryOverrides
|
42
43
|
include Fortitude::Widget::Files
|
44
|
+
include Fortitude::Widget::Convenience
|
43
45
|
|
44
46
|
if defined?(::Rails)
|
45
47
|
require 'fortitude/rails/widget_methods'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Fortitude
|
4
|
+
class Widget
|
5
|
+
module Convenience
|
6
|
+
def content_and_attributes_from_tag_arguments(content_or_attributes = nil, attributes = nil)
|
7
|
+
if (! attributes) && content_or_attributes.kind_of?(Hash)
|
8
|
+
[ nil, (content_or_attributes || { }) ]
|
9
|
+
else
|
10
|
+
[ content_or_attributes, (attributes || { }) ]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_css_classes(classes_to_add, a = nil, b = nil)
|
15
|
+
classes_to_add = Array(classes_to_add)
|
16
|
+
content, attributes = content_and_attributes_from_tag_arguments(a, b)
|
17
|
+
|
18
|
+
attributes = if attributes.has_key?('class')
|
19
|
+
attributes.merge('class' => (Array(attributes['class'] || [ ]) + classes_to_add))
|
20
|
+
else
|
21
|
+
attributes.merge(:class => (Array(attributes[:class] || [ ]) + classes_to_add))
|
22
|
+
end
|
23
|
+
|
24
|
+
[ content, attributes ]
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :add_css_class, :add_css_classes
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -7,14 +7,16 @@ module Fortitude
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
class CannotDetermineWidgetClassNameError < StandardError
|
10
|
-
attr_reader :tried_class_names, :filename, :magic_comment_texts
|
10
|
+
attr_reader :tried_class_names, :filename, :magic_comment_texts, :resulting_objects, :class_names_to_try
|
11
11
|
|
12
12
|
def initialize(tried_class_names, options = { })
|
13
|
-
options.assert_valid_keys(:filename, :magic_comment_texts)
|
13
|
+
options.assert_valid_keys(:filename, :magic_comment_texts, :resulting_objects, :class_names_to_try)
|
14
14
|
|
15
15
|
@tried_class_names = tried_class_names
|
16
16
|
@filename = options[:filename]
|
17
17
|
@magic_comment_texts = options[:magic_comment_texts]
|
18
|
+
@resulting_objects = options[:resulting_objects]
|
19
|
+
@class_names_to_try = options[:class_names_to_try]
|
18
20
|
from_what = filename ? "from the file '#{filename}'" : "from some Fortitude source code"
|
19
21
|
|
20
22
|
super %{You asked for a Fortitude widget class #{from_what},
|
@@ -25,9 +27,10 @@ We tried the following class names, in order:
|
|
25
27
|
#{tried_class_names.join("\n")}
|
26
28
|
|
27
29
|
...but none of them both existed and were a class that eventually inherits from
|
28
|
-
::Fortitude::Widget.
|
30
|
+
::Fortitude::Widget. (We got back resulting objects: #{resulting_objects.inspect})
|
29
31
|
|
30
|
-
You can either pass the class name into this method via the :class_names_to_try option
|
32
|
+
You can either pass the class name into this method via the :class_names_to_try option
|
33
|
+
(we were passed #{class_names_to_try.inspect}),
|
31
34
|
or add a "magic comment" to the source code of this widget that looks like this:
|
32
35
|
|
33
36
|
#!<token>: <class_name>
|
@@ -70,8 +73,9 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
70
73
|
scan_source_for_possible_class_names(source)
|
71
74
|
|
72
75
|
out = widget_class_from_class_names(all_class_names)
|
76
|
+
resulting_objects = out[:resulting_objects]
|
73
77
|
|
74
|
-
unless out
|
78
|
+
unless out[:widget_class]
|
75
79
|
if options[:filename]
|
76
80
|
require options[:filename]
|
77
81
|
else
|
@@ -79,11 +83,13 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
79
83
|
end
|
80
84
|
|
81
85
|
out = widget_class_from_class_names(all_class_names)
|
86
|
+
resulting_objects += out[:resulting_objects]
|
82
87
|
end
|
83
88
|
|
84
|
-
out || (
|
89
|
+
out[:widget_class] || (
|
85
90
|
raise CannotDetermineWidgetClassNameError.new(all_class_names, :magic_comment_texts => magic_comment_texts,
|
86
|
-
:filename => options[:filename]
|
91
|
+
:filename => options[:filename], :resulting_objects => resulting_objects,
|
92
|
+
:class_names_to_try => options[:class_names_to_try]))
|
87
93
|
end
|
88
94
|
|
89
95
|
private
|
@@ -118,8 +124,9 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
118
124
|
while module_nesting.length > 0
|
119
125
|
possible_module_name = module_nesting.join("::")
|
120
126
|
out.reverse.each do |class_name|
|
121
|
-
out.
|
127
|
+
out.push("#{possible_module_name}::#{class_name}")
|
122
128
|
end
|
129
|
+
out.push(possible_module_name)
|
123
130
|
module_nesting.pop
|
124
131
|
end
|
125
132
|
|
@@ -127,7 +134,10 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
127
134
|
end
|
128
135
|
|
129
136
|
def widget_class_from_class_names(class_names)
|
130
|
-
out =
|
137
|
+
out = {
|
138
|
+
:widget_class => nil,
|
139
|
+
:resulting_objects => [ ]
|
140
|
+
}
|
131
141
|
|
132
142
|
class_names.each do |class_name|
|
133
143
|
class_name = $1 if class_name =~ /^:+(.*)$/i
|
@@ -138,11 +148,12 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
138
148
|
end
|
139
149
|
|
140
150
|
if is_widget_class?(klass)
|
141
|
-
out = klass
|
151
|
+
out[:widget_class] = klass
|
142
152
|
break
|
153
|
+
elsif klass
|
154
|
+
out[:resulting_objects] << klass
|
143
155
|
end
|
144
156
|
end
|
145
|
-
|
146
157
|
out
|
147
158
|
end
|
148
159
|
|
@@ -80,11 +80,13 @@ module Fortitude
|
|
80
80
|
|
81
81
|
# PUBLIC API
|
82
82
|
def extract_needed_assigns_from(input)
|
83
|
-
input = input.with_indifferent_access
|
84
|
-
|
85
83
|
out = { }
|
86
84
|
needs_as_hash.keys.each do |name|
|
87
|
-
|
85
|
+
if input.has_key?(name)
|
86
|
+
out[name] = input[name]
|
87
|
+
elsif input.has_key?(name.to_s)
|
88
|
+
out[name] = input[name.to_s]
|
89
|
+
end
|
88
90
|
end
|
89
91
|
out
|
90
92
|
end
|
@@ -66,6 +66,7 @@ module SystemHelpers
|
|
66
66
|
tag :script, :newline_before => true, :escape_direct_content => false
|
67
67
|
tag :head, :newline_before => true
|
68
68
|
tag :style, :newline_before => true, :escape_direct_content => false
|
69
|
+
tag :pre, :newline_before => true, :suppress_formatting_inside => true
|
69
70
|
end
|
70
71
|
|
71
72
|
class TestWidgetClass < Fortitude::Widget
|
@@ -97,7 +97,6 @@ describe "Rails development-mode support", :type => :rails do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
sleep 1
|
100
|
-
$stderr.puts "checking for #{current_form.inspect}"
|
101
100
|
expect_match("edit", /#{Regexp.escape(current_form.to_s)}/i)
|
102
101
|
|
103
102
|
current_form = if current_form == :full_reference
|
@@ -52,10 +52,16 @@ describe "Rails rendering support", :type => :rails do
|
|
52
52
|
expect(response.header['Content-Type']).to match(%r{text/html}i)
|
53
53
|
end
|
54
54
|
|
55
|
-
it "should let you render a widget with 'render \"foo\"'" do
|
55
|
+
it "should let you render a widget with 'render \"foo\" and the full path'" do
|
56
|
+
skip "Rails 4.2 makes this mean something different (render :template, vs. render :file)" unless rails_server.rails_version =~ /^(3\.|4\.[01]\.)/
|
56
57
|
expect_match("render_widget_via_file_path", /hello from a widget named Fred/)
|
57
58
|
end
|
58
59
|
|
60
|
+
it "should let you render a widget with 'render \"foo\"' and the template path" do
|
61
|
+
skip "Rails 4.2 enables this" if rails_server.rails_version =~ /^(3\.|4\.[01]\.)/
|
62
|
+
expect_match("render_widget_via_template_path", /hello, world/)
|
63
|
+
end
|
64
|
+
|
59
65
|
it "should let you render a widget with 'render :file =>'" do
|
60
66
|
expect_match("render_widget_via_colon_file", /hello from a widget named Fred/)
|
61
67
|
end
|
@@ -67,6 +73,19 @@ describe "Rails rendering support", :type => :rails do
|
|
67
73
|
it "should let you render a widget inline, and use all instance and local variables, with locals overriding instance variables" do
|
68
74
|
expect_match("render_widget_via_inline_with_var_access", /this is an inline widget named Fred, and it is 27 years old, and friends with Mary/)
|
69
75
|
end
|
76
|
+
|
77
|
+
it "should let you pass a subclass of Hash, and not accidentally get rid of it via #with_indifferent_access" do
|
78
|
+
expect_match("render_hash_subclass", /the_hash class: MyHash/,
|
79
|
+
/the_hash\[:foo\] "bar"/,
|
80
|
+
/the_hash\["foo"\] nil/,
|
81
|
+
/the_hash\[:bar\] nil/,
|
82
|
+
/the_hash\["bar"\] :baz/,
|
83
|
+
/other_hash class: Hash/,
|
84
|
+
/other_hash\[:quux\] nil/,
|
85
|
+
/other_hash\["quux"\] "bazzle"/,
|
86
|
+
/other_hash\[:marph\] :bar/,
|
87
|
+
/other_hash\["marph"\] nil/)
|
88
|
+
end
|
70
89
|
end
|
71
90
|
|
72
91
|
describe "rendering in a widget" do
|
data/spec/rails/templates/rendering_system_spec/app/controllers/rendering_system_spec_controller.rb
CHANGED
@@ -37,6 +37,10 @@ class RenderingSystemSpecController < ApplicationController
|
|
37
37
|
render File.join(Rails.root, 'app', 'views', 'widget_to_render')
|
38
38
|
end
|
39
39
|
|
40
|
+
def render_widget_via_template_path
|
41
|
+
render "rendering_system_spec/trivial_widget"
|
42
|
+
end
|
43
|
+
|
40
44
|
def render_widget_via_colon_file
|
41
45
|
@name = "Fred"
|
42
46
|
render :file => File.join(Rails.root, 'app', 'views', 'widget_to_render')
|
@@ -125,4 +129,13 @@ class RenderingSystemSpecController < ApplicationController
|
|
125
129
|
@d = "quux<marph"
|
126
130
|
@e = "marph>foo".html_safe
|
127
131
|
end
|
132
|
+
|
133
|
+
def render_hash_subclass
|
134
|
+
require 'my_hash'
|
135
|
+
|
136
|
+
@the_hash = MyHash.new
|
137
|
+
@the_hash[:foo] = 'bar'
|
138
|
+
@the_hash['bar'] = :baz
|
139
|
+
@other_hash = { 'quux' => 'bazzle', :marph => :bar }
|
140
|
+
end
|
128
141
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Views::RenderingSystemSpec::RenderHashSubclass < Fortitude::Widgets::Html5
|
2
|
+
needs :the_hash, :other_hash
|
3
|
+
|
4
|
+
def content
|
5
|
+
text "the_hash class: #{the_hash.class.name}\n"
|
6
|
+
# text "is_my_hash? #{the_hash.is_my_hash?.inspect}\n"
|
7
|
+
text "the_hash[:foo] #{the_hash[:foo].inspect}\n"
|
8
|
+
text "the_hash[\"foo\"] #{the_hash['foo'].inspect}\n"
|
9
|
+
text "the_hash[:bar] #{the_hash[:bar].inspect}\n"
|
10
|
+
text "the_hash[\"bar\"] #{the_hash['bar'].inspect}\n"
|
11
|
+
|
12
|
+
text "other_hash class: #{other_hash.class.name}\n"
|
13
|
+
text "other_hash[:quux] #{other_hash[:quux].inspect}\n"
|
14
|
+
text "other_hash[\"quux\"] #{other_hash['quux'].inspect}\n"
|
15
|
+
text "other_hash[:marph] #{other_hash[:marph].inspect}\n"
|
16
|
+
text "other_hash[\"marph\"] #{other_hash['marph'].inspect}\n"
|
17
|
+
end
|
18
|
+
end
|
@@ -49,4 +49,170 @@ hi, there
|
|
49
49
|
</div>})
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
describe "#content_and_attributes_from_tag_arguments" do
|
54
|
+
let(:test_widget_instance) { widget_class.new }
|
55
|
+
|
56
|
+
def caafta(*args)
|
57
|
+
test_widget_instance.content_and_attributes_from_tag_arguments(*args)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return nil and empty-hash for passing nothing" do
|
61
|
+
expect(caafta()).to eq([ nil, { } ])
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return text if passed just text" do
|
65
|
+
expect(caafta("foo")).to eq([ "foo", { } ])
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return attributes if passed just that" do
|
69
|
+
expect(caafta(:class => :bar)).to eq([ nil, { :class => :bar }])
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return text and attributes if passed that" do
|
73
|
+
expect(caafta("foo", :class => :bar)).to eq([ "foo", { :class => :bar }])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#add_css_classes" do
|
78
|
+
let(:widget_class_with_p_added_base) {
|
79
|
+
widget_class do
|
80
|
+
def classes_to_add
|
81
|
+
[ :foo, :bar ]
|
82
|
+
end
|
83
|
+
|
84
|
+
def call_add_css_classes(*args)
|
85
|
+
add_css_classes(classes_to_add, *args)
|
86
|
+
end
|
87
|
+
|
88
|
+
def p_added(*args, &block)
|
89
|
+
p(*call_add_css_classes(*args), &block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
}
|
93
|
+
|
94
|
+
def widget_class_with_p_added(&block)
|
95
|
+
widget_class(:superclass => widget_class_with_p_added_base, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def widget_class_with_p_added_content(&block)
|
99
|
+
widget_class_with_content(:superclass => widget_class_with_p_added_base, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should correctly add classes if passed nothing at all" do
|
103
|
+
expect(render(widget_class_with_p_added_content { p_added })).to eq(%{<p class="foo bar"></p>})
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should correctly add classes if passed just text" do
|
107
|
+
expect(render(widget_class_with_p_added_content { p_added "hello" })).to eq(%{<p class="foo bar">hello</p>})
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should correctly add classes if passed just other attributes" do
|
111
|
+
output = render(widget_class_with_p_added_content { p_added :id => :whatever })
|
112
|
+
expect(output).to match(%r{<p [^>]*></p>})
|
113
|
+
expect(output).to match(%r{id="whatever"})
|
114
|
+
expect(output).to match(%r{class="foo bar"})
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should correctly add classes if passed text, then attributes" do
|
118
|
+
output = render(widget_class_with_p_added_content { p_added "hello", :id => :whatever })
|
119
|
+
expect(output).to match(%r{<p [^>]*>hello</p>})
|
120
|
+
expect(output).to match(%r{id="whatever"})
|
121
|
+
expect(output).to match(%r{class="foo bar"})
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should correctly add classes if passed nil, then attributes" do
|
125
|
+
output = render(widget_class_with_p_added_content { p_added nil, :id => :whatever })
|
126
|
+
expect(output).to match(%r{<p [^>]*></p>})
|
127
|
+
expect(output).to match(%r{id="whatever"})
|
128
|
+
expect(output).to match(%r{class="foo bar"})
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should correctly add classes if passed text, then explicitly-nil attributes" do
|
132
|
+
output = render(widget_class_with_p_added_content { p_added "hello", nil })
|
133
|
+
expect(output).to match(%r{<p class="foo bar">hello</p>})
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should correctly add classes if passed nil and nil" do
|
137
|
+
expect(render(widget_class_with_p_added_content { p_added nil, nil })).to eq(%{<p class="foo bar"></p>})
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should correctly add just a single class" do
|
141
|
+
wc = widget_class_with_p_added do
|
142
|
+
def classes_to_add
|
143
|
+
:foo
|
144
|
+
end
|
145
|
+
|
146
|
+
def content
|
147
|
+
p_added "hello"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
expect(render(wc)).to eq(%{<p class="foo">hello</p>})
|
151
|
+
end
|
152
|
+
|
153
|
+
def render_and_extract_classes(class_or_widget)
|
154
|
+
output = render(class_or_widget)
|
155
|
+
|
156
|
+
if output =~ %r{^<p class="(.*)"></p>}
|
157
|
+
$1.split(" ")
|
158
|
+
else
|
159
|
+
raise "Unexpected content: #{output.inspect}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def expect_classes_transform(original_hash, expected_classes)
|
164
|
+
expect(render_and_extract_classes(widget_class_with_p_added_content { p_added(original_hash) }).sort).to eq(
|
165
|
+
expected_classes.sort)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should correctly add classes if the base has classes specified with a symbol" do
|
169
|
+
expect_classes_transform({ :class => 'orig' }, %w{orig foo bar})
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should correctly add classes if the base has classes specified with a string" do
|
173
|
+
expect_classes_transform({ 'class' => 'orig' }, %w{orig foo bar})
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should correctly add classes if the base has multiple classes" do
|
177
|
+
expect_classes_transform({ :class => [ 'orig1', 'orig2', 'orig3' ] }, %w{orig1 orig2 orig3 foo bar})
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should correctly add classes if the base has just one class" do
|
181
|
+
expect_classes_transform({ :class => 'orig' }, %w{orig foo bar})
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should correctly add classes if the base has explicit nil for :class" do
|
185
|
+
expect_classes_transform({ 'class' => nil }, %w{foo bar})
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should correctly add classes if the base has explicit empty-string for :class" do
|
189
|
+
expect_classes_transform({ 'class' => '' }, %w{foo bar})
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should correctly add classes if the base has explicit false for :class" do
|
193
|
+
expect_classes_transform({ :class => false }, %w{foo bar})
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should correctly add classes if the base has an array for :class" do
|
197
|
+
expect_classes_transform({ :class => [ 'orig1', 'orig2', 'orig3' ] }, %w{orig1 orig2 orig3 foo bar})
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should correctly add classes if the base has a whitespace-separated array of classes for :class" do
|
201
|
+
expect_classes_transform({ 'class' => 'orig1 orig2 orig3' }, %w{foo bar orig1 orig2 orig3})
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should allow being called as #add_css_class" do
|
205
|
+
add_css_class_class = widget_class do
|
206
|
+
def p_added(*args, &block)
|
207
|
+
p(*add_css_class('foo', *args), &block)
|
208
|
+
end
|
209
|
+
|
210
|
+
def content
|
211
|
+
p_added "hello"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
expect(render(add_css_class_class)).to eq('<p class="foo">hello</p>')
|
216
|
+
end
|
217
|
+
end
|
52
218
|
end
|