fortitude 0.9.4-java → 0.9.5-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.fix_bundler_for_jruby_17 +26 -0
- data/.gitignore +1 -0
- data/.travis.yml +33 -40
- data/CHANGES.md +44 -0
- data/CONTRIBUTORS.md +26 -0
- data/Rakefile +1 -1
- data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +45 -33
- data/ext/fortitude_native_ext/fortitude_native_ext.c +23 -23
- data/fortitude.gemspec +25 -8
- data/lib/fortitude/erector.rb +26 -18
- data/lib/fortitude/errors.rb +15 -4
- data/lib/fortitude/extensions/fortitude_ruby_ext.rb +35 -10
- data/lib/fortitude/rails/helpers.rb +59 -2
- data/lib/fortitude/rails/railtie.rb +238 -157
- data/lib/fortitude/rails/renderer.rb +15 -0
- data/lib/fortitude/rails/rendering_methods.rb +46 -33
- data/lib/fortitude/rails/template_handler.rb +49 -18
- data/lib/fortitude/rails/yielded_object_outputter.rb +3 -2
- data/lib/fortitude/rendering_context.rb +14 -5
- data/lib/fortitude/support/method_overriding.rb +90 -0
- data/lib/fortitude/support/staticized_method.rb +12 -0
- data/lib/fortitude/version.rb +1 -1
- data/lib/fortitude/widget/content.rb +4 -2
- data/lib/fortitude/widget/files.rb +17 -11
- data/lib/fortitude/widget/helpers.rb +7 -1
- data/lib/fortitude/widget/integration.rb +4 -0
- data/lib/fortitude/widget/localization.rb +63 -4
- data/lib/fortitude/widget/rendering.rb +17 -10
- data/lib/fortitude_jruby_native_ext.jar +0 -0
- data/spec/helpers/fortitude_rails_helpers.rb +26 -4
- data/spec/rails/capture_system_spec.rb +1 -1
- data/spec/rails/class_loading_system_spec.rb +16 -2
- data/spec/rails/complex_helpers_system_spec.rb +29 -0
- data/spec/rails/data_passing_system_spec.rb +2 -2
- data/spec/rails/development_mode_system_spec.rb +1 -1
- data/spec/rails/erector_coexistence_system_spec.rb +1 -1
- data/spec/rails/helpers_system_spec.rb +20 -2
- data/spec/rails/layouts_system_spec.rb +1 -1
- data/spec/rails/rendering_system_spec.rb +4 -4
- data/spec/rails/rules_system_spec.rb +2 -2
- data/spec/rails/templates/class_loading_system_spec/app/views/some_namespace/some_other_namespace/placeholder.rb +5 -0
- data/spec/rails/templates/complex_helpers_system_spec/app/controllers/complex_helpers_system_spec_controller.rb +4 -0
- data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/label_block_test.rb +9 -0
- data/spec/rails/templates/helpers_system_spec/app/controllers/helpers_system_spec_controller.rb +4 -0
- data/spec/rails/templates/helpers_system_spec/app/controllers/home_controller.rb +9 -0
- data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/rails_helpers_without_automatic_helper_access.rb +37 -0
- data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/url_helpers_without_automatic_helper_access.rb +45 -0
- data/spec/rails/templates/helpers_system_spec/config/initializers/host.rb +1 -0
- data/spec/rails/templates/helpers_system_spec/config/routes.rb +7 -0
- data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/localization.rb +1 -1
- data/spec/rails/templates/view_paths_system_spec/app/controllers/view_paths_system_spec_controller.rb +15 -0
- data/spec/rails/templates/view_paths_system_spec/config/application.rb +30 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/baseone/basetwo/base_class_one.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/added_view_path.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/autoloading_from_added_view_path.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller_with_impossible_to_guess_name.html.rb +14 -0
- data/spec/rails/view_paths_system_spec.rb +19 -0
- data/spec/system/escaping_system_spec.rb +10 -2
- data/spec/system/helpers_system_spec.rb +37 -6
- data/spec/system/inline_system_spec.rb +19 -0
- data/spec/system/static_method_system_spec.rb +16 -0
- data/spec/system/tag_rendering_system_spec.rb +4 -4
- data/spec/system/widget_class_from_spec.rb +39 -0
- data/spec/system/yield_system_spec.rb +53 -1
- metadata +90 -58
@@ -0,0 +1,37 @@
|
|
1
|
+
class Views::HelpersSystemSpec::RailsHelpersWithoutAutomaticHelperAccess < Fortitude::Widgets::Html5
|
2
|
+
automatic_helper_access false
|
3
|
+
|
4
|
+
def content
|
5
|
+
excitedly_value = begin
|
6
|
+
excitedly("great")
|
7
|
+
rescue => e
|
8
|
+
e.class.name
|
9
|
+
end
|
10
|
+
|
11
|
+
three_months_value = begin
|
12
|
+
distance_of_time_in_words_to_now(3.months.ago)
|
13
|
+
rescue => e
|
14
|
+
e.class.name
|
15
|
+
end
|
16
|
+
|
17
|
+
million_dollars_value = begin
|
18
|
+
number_to_currency(1_000_000.00)
|
19
|
+
rescue => e
|
20
|
+
e.class.name
|
21
|
+
end
|
22
|
+
|
23
|
+
debug_value = begin
|
24
|
+
debug(Object.new)
|
25
|
+
rescue => e
|
26
|
+
e.class.name
|
27
|
+
end
|
28
|
+
|
29
|
+
p "Excitedly: #{excitedly_value}"
|
30
|
+
|
31
|
+
p "Three months ago: #{three_months_value}"
|
32
|
+
|
33
|
+
p "A million dollars: #{million_dollars_value}"
|
34
|
+
|
35
|
+
p "debug: #{debug_value}"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Views::HelpersSystemSpec::UrlHelpersWithoutAutomaticHelperAccess < Fortitude::Widgets::Html5
|
2
|
+
automatic_helper_access false
|
3
|
+
|
4
|
+
def content
|
5
|
+
excitedly_value = begin
|
6
|
+
excitedly("great")
|
7
|
+
rescue => e
|
8
|
+
e.class.name
|
9
|
+
end
|
10
|
+
|
11
|
+
root_path_value = begin
|
12
|
+
root_path
|
13
|
+
rescue => e
|
14
|
+
e.class.name
|
15
|
+
end
|
16
|
+
|
17
|
+
foo_path_value = begin
|
18
|
+
foo_path
|
19
|
+
rescue => e
|
20
|
+
e.class.name
|
21
|
+
end
|
22
|
+
|
23
|
+
foo_url_value = begin
|
24
|
+
foo_url
|
25
|
+
rescue => e
|
26
|
+
e.class.name
|
27
|
+
end
|
28
|
+
|
29
|
+
foo_url_with_host_override_value = begin
|
30
|
+
foo_url(:host => 'override.com')
|
31
|
+
rescue => e
|
32
|
+
e.class.name
|
33
|
+
end
|
34
|
+
|
35
|
+
p "Excitedly: #{excitedly_value}"
|
36
|
+
|
37
|
+
p "Root Path: #{root_path_value}"
|
38
|
+
|
39
|
+
p "Foo Path: #{foo_path_value}"
|
40
|
+
|
41
|
+
p "Foo Url: #{foo_url_value}"
|
42
|
+
|
43
|
+
p "Foo Url with host override: #{foo_url_with_host_override_value}"
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Rails.application.routes.default_url_options[:host] = 'example.com'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ViewPathsSystemSpecController < ApplicationController
|
2
|
+
def added_view_path
|
3
|
+
end
|
4
|
+
|
5
|
+
def autoloading_from_added_view_path
|
6
|
+
end
|
7
|
+
|
8
|
+
def added_view_path_from_controller
|
9
|
+
append_view_path(File.join(File.expand_path(::Rails.root), 'view_path_two'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def added_view_path_from_controller_with_impossible_to_guess_name
|
13
|
+
append_view_path(File.join(File.expand_path(::Rails.root), 'view_path_two'))
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require 'rails/all'
|
4
|
+
|
5
|
+
# Require the gems listed in Gemfile, including any gems
|
6
|
+
# you've limited to :test, :development, or :production.
|
7
|
+
Bundler.require(:default, Rails.env)
|
8
|
+
|
9
|
+
module ViewPathsSystemSpec
|
10
|
+
class Application < Rails::Application
|
11
|
+
# Settings in config/environments/* take precedence over those specified here.
|
12
|
+
# Application configuration should go into files in config/initializers
|
13
|
+
# -- all .rb files in that directory are automatically loaded.
|
14
|
+
|
15
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
16
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
17
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
18
|
+
|
19
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
20
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
21
|
+
# config.i18n.default_locale = :de
|
22
|
+
|
23
|
+
new_path = Rails.root.join('view_path_one')
|
24
|
+
if ::Rails.version =~ /^3\.0\./
|
25
|
+
config.paths.app.views.unshift(new_path)
|
26
|
+
else
|
27
|
+
config.paths['app/views'].unshift(new_path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
$stderr.puts "LOADED AT:\n #{caller.join("\n ")}"
|
2
|
+
|
3
|
+
initial = "class ViewPathsSystemSpec::AddedViewPathFromControllerWithImposs"
|
4
|
+
|
5
|
+
rest = <<-EOS
|
6
|
+
ibleToGuessName < Fortitude::Widgets::Html5
|
7
|
+
def content
|
8
|
+
p "from an added view path from the controller with an impossible-to-guess name"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
EOS
|
12
|
+
|
13
|
+
total = initial.strip + rest.strip
|
14
|
+
eval(total)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
describe "Rails view-path support", :type => :rails do
|
2
|
+
uses_rails_with_template :view_paths_system_spec
|
3
|
+
|
4
|
+
it "should be able to render a view from an added view path" do
|
5
|
+
expect_match("added_view_path", /from an added view path/)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be able to autoload classes from an added view path" do
|
9
|
+
expect_match("autoloading_from_added_view_path", /helper method: this is base class one method one!: there it is!/)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to render a view from an added view path from the controller" do
|
13
|
+
expect_match("added_view_path_from_controller", /from an added view path from the controller/)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be able to render a view from an added view path from the controller with an impossible-to-guess name" do
|
17
|
+
expect_match("added_view_path_from_controller_with_impossible_to_guess_name", /from an added view path from the controller with an impossible-to-guess name/)
|
18
|
+
end
|
19
|
+
end
|
@@ -23,8 +23,16 @@ describe "Fortitude escaping behavior", :type => :system do
|
|
23
23
|
expect(render(widget_class_with_content { p 'a<b' => 123 })).to eq("<p a<b=\"123\"></p>")
|
24
24
|
end
|
25
25
|
|
26
|
-
it "should escape attribute values" do
|
27
|
-
expect(render(widget_class_with_content { p :foo => 'a
|
26
|
+
it "should escape double quotes inside attribute values" do
|
27
|
+
expect(render(widget_class_with_content { p :foo => 'a"b' })).to eq("<p foo=\"a"b\"></p>")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should escape ampersands inside attribute values" do
|
31
|
+
expect(render(widget_class_with_content { p :foo => 'a&b' })).to eq("<p foo=\"a&b\"></p>")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not escape less than signs, greater than signs, or single quotes inside attribute values" do
|
35
|
+
expect(render(widget_class_with_content { p :foo => 'a<b>c\'d' })).to eq("<p foo=\"a<b>c'd\"></p>")
|
28
36
|
end
|
29
37
|
|
30
38
|
it "should escape direct arguments to tags" do
|
@@ -27,6 +27,14 @@ describe "Fortitude helper support", :type => :system do
|
|
27
27
|
"foo #{result} bar"
|
28
28
|
end
|
29
29
|
|
30
|
+
def helper5=(arg)
|
31
|
+
@helper5 = arg
|
32
|
+
end
|
33
|
+
|
34
|
+
def helper5
|
35
|
+
"aa#{@helper5}bb"
|
36
|
+
end
|
37
|
+
|
30
38
|
def p(input)
|
31
39
|
"pp#{input}pp"
|
32
40
|
end
|
@@ -85,18 +93,25 @@ describe "Fortitude helper support", :type => :system do
|
|
85
93
|
it "should allow calling a method that's overridden on Widget" do
|
86
94
|
expect(render(widget_class_with_content { text invoke_helper(:p, "a") })).to eq("ppapp")
|
87
95
|
end
|
96
|
+
|
97
|
+
it "should allow calling a helper method that uses a setter" do
|
98
|
+
expect(render(widget_class_with_content { invoke_helper(:helper5=, "ccc"); text invoke_helper(:helper5) })).to eq("aacccbb")
|
99
|
+
end
|
88
100
|
end
|
89
101
|
|
90
102
|
it "should, by default, allow automatic access to helpers" do
|
91
103
|
expect(render(widget_class_with_content { text "helper1: #{helper1}" })).to eq("helper1: this is helper1")
|
92
104
|
expect(render(widget_class_with_content { text "helper2: #{helper2("yo")}" })).to eq("helper2: this is yo helper2")
|
93
105
|
expect(render(widget_class_with_content { helper3("ho") })).to eq("this is ho helper3")
|
106
|
+
expect(render(widget_class_with_content { self.helper5 = "ccc"; text helper5 })).to eq("aacccbb")
|
94
107
|
end
|
95
108
|
|
96
109
|
it "should indicate that it responds to helpers using respond_to? for automatic helper methods" do
|
97
110
|
expect(render(widget_class_with_content { text "respond_to helper1: #{respond_to?(:helper1)}" } )).to eq("respond_to helper1: true")
|
98
111
|
expect(render(widget_class_with_content { text "respond_to helper2: #{respond_to?(:helper2)}" } )).to eq("respond_to helper2: true")
|
99
112
|
expect(render(widget_class_with_content { text "respond_to helper3: #{respond_to?(:helper3)}" } )).to eq("respond_to helper3: true")
|
113
|
+
expect(render(widget_class_with_content { text "respond_to helper5=: #{respond_to?(:helper5=)}" } )).to eq("respond_to helper5=: true")
|
114
|
+
expect(render(widget_class_with_content { text "respond_to helper5: #{respond_to?(:helper5)}" } )).to eq("respond_to helper5: true")
|
100
115
|
end
|
101
116
|
|
102
117
|
it "should not allow automatic access to helpers if we say not to" do
|
@@ -121,17 +136,23 @@ describe "Fortitude helper support", :type => :system do
|
|
121
136
|
e.class.name
|
122
137
|
end
|
123
138
|
|
124
|
-
|
139
|
+
helper5equal_value = begin
|
140
|
+
self.helper5 = 'ccc'
|
141
|
+
rescue => e
|
142
|
+
e.class.name
|
143
|
+
end
|
144
|
+
|
145
|
+
text "helper1: #{helper1_value}, helper2: #{helper2_value}, helper3: #{helper3_value}; helper5equal: #{helper5equal_value}"
|
125
146
|
end
|
126
147
|
end
|
127
148
|
|
128
|
-
expect(render(wc)).to eq("helper1: NameError, helper2: NoMethodError, helper3: NoMethodError")
|
149
|
+
expect(render(wc)).to eq("helper1: NameError, helper2: NoMethodError, helper3: NoMethodError; helper5equal: NoMethodError")
|
129
150
|
end
|
130
151
|
|
131
152
|
it "should allow manually declaring helpers" do
|
132
153
|
wc = widget_class do
|
133
154
|
automatic_helper_access false
|
134
|
-
helper :helper1, :helper3
|
155
|
+
helper :helper1, :helper3, :helper5=, :helper5
|
135
156
|
def content
|
136
157
|
helper2_value = begin
|
137
158
|
helper2("foo")
|
@@ -141,10 +162,12 @@ describe "Fortitude helper support", :type => :system do
|
|
141
162
|
|
142
163
|
text "helper1: #{helper1}, helper2: #{helper2_value}, helper3: "
|
143
164
|
helper3("hi")
|
165
|
+
self.helper5 = 'ccc'
|
166
|
+
text ", helper5: #{helper5}"
|
144
167
|
end
|
145
168
|
end
|
146
169
|
|
147
|
-
expect(render(wc)).to eq("helper1: this is helper1, helper2: NoMethodError, helper3: this is hi helper3")
|
170
|
+
expect(render(wc)).to eq("helper1: this is helper1, helper2: NoMethodError, helper3: this is hi helper3, helper5: aacccbb")
|
148
171
|
end
|
149
172
|
|
150
173
|
it "should allow overriding a manually-declared helper, and allow use of #super" do
|
@@ -208,14 +231,22 @@ describe "Fortitude helper support", :type => :system do
|
|
208
231
|
wc = widget_class do
|
209
232
|
helper :h2a, :call => :helper2
|
210
233
|
helper :h2b, :call => :helper2, :transform => :output_return_value
|
234
|
+
helper :h5a, :call => :helper5=
|
235
|
+
helper :h5b=, :call => :helper5=
|
236
|
+
helper :helper5
|
211
237
|
|
212
238
|
def content
|
213
239
|
h2b("yo")
|
214
|
-
text ", h2a: #{h2a('xx')}
|
240
|
+
text ", h2a: #{h2a('xx')}"
|
241
|
+
self.h5a('ccc')
|
242
|
+
text ", h5a: #{helper5}"
|
243
|
+
self.h5b = 'ddd'
|
244
|
+
text ", h5b: #{helper5}"
|
245
|
+
text ", done"
|
215
246
|
end
|
216
247
|
end
|
217
248
|
|
218
|
-
expect(render(wc)).to eq("this is yo helper2, h2a: this is xx helper2, done")
|
249
|
+
expect(render(wc)).to eq("this is yo helper2, h2a: this is xx helper2, h5a: aacccbb, h5b: aadddbb, done")
|
219
250
|
end
|
220
251
|
|
221
252
|
it "should allow declaring helpers with :transform = nil, false, or none" do
|
@@ -35,6 +35,25 @@ describe "Fortitude inline-code support", :type => :system do
|
|
35
35
|
expect(data).to eq("<p>hello, world</p>")
|
36
36
|
end
|
37
37
|
|
38
|
+
it "should let you get rendered content back with .inline_html, passing assigns and a helpers object" do
|
39
|
+
my_helpers = Object.new
|
40
|
+
class << my_helpers
|
41
|
+
def nameify(x)
|
42
|
+
"_#{x}_!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
rc = ::Fortitude::RenderingContext.new(:helpers_object => my_helpers)
|
47
|
+
wc = widget_class do
|
48
|
+
needs :name
|
49
|
+
end
|
50
|
+
|
51
|
+
content = wc.inline_html({ :name => 'julia' }, rc) do
|
52
|
+
p "hello, #{nameify(name)}"
|
53
|
+
end
|
54
|
+
expect(content).to eq("<p>hello, _julia_!</p>")
|
55
|
+
end
|
56
|
+
|
38
57
|
it "should let you pass assigns to the new widget with .inline_html, and inherit settings of the parent" do
|
39
58
|
wc = widget_class do
|
40
59
|
start_and_end_comments true
|
@@ -38,6 +38,22 @@ describe "Fortitude staticization behavior", :type => :system do
|
|
38
38
|
expect(render(wc)).to eq('<p class="foo">bar: 12345</p><p>baz</p>')
|
39
39
|
end
|
40
40
|
|
41
|
+
it "should give you a good error if you try to make a method static before it's defined" do
|
42
|
+
expect do
|
43
|
+
widget_class do
|
44
|
+
def content
|
45
|
+
foo
|
46
|
+
end
|
47
|
+
|
48
|
+
static :foo
|
49
|
+
|
50
|
+
def foo
|
51
|
+
p "bar"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end.to raise_error(NameError, /no method declared on this class with that name/mi)
|
55
|
+
end
|
56
|
+
|
41
57
|
it "should update the static definition of a method if static is called again" do
|
42
58
|
$global_value = 12345
|
43
59
|
wc = widget_class do
|
@@ -253,8 +253,8 @@ describe "Fortitude tag rendering", :type => :system do
|
|
253
253
|
should_render_to("<hr <&">=\"foo\">") { hr '<&">' => "foo" }
|
254
254
|
end
|
255
255
|
|
256
|
-
it "should escape attribute values" do
|
257
|
-
should_render_to("<hr class=\"
|
256
|
+
it "should escape attribute values, but only the necessary characters" do
|
257
|
+
should_render_to("<hr class=\"<&">\">") { hr :class => "<&\">" }
|
258
258
|
end
|
259
259
|
|
260
260
|
it "should separate multiple attributes with spaces" do
|
@@ -336,9 +336,9 @@ describe "Fortitude tag rendering", :type => :system do
|
|
336
336
|
should_render_to("<p and&<>"this=\"bar\"></p>") { p foo => "bar" }
|
337
337
|
end
|
338
338
|
|
339
|
-
it "should render an arbitrary object as an attribute value, escaping
|
339
|
+
it "should render an arbitrary object as an attribute value, escaping the necessary characters" do
|
340
340
|
foo = arbitrary_object_with_to_s("and&<>\"this")
|
341
|
-
should_render_to("<p foo=\"and&
|
341
|
+
should_render_to("<p foo=\"and&<>"this\"></p>") { p :foo => foo }
|
342
342
|
end
|
343
343
|
|
344
344
|
it "should render an arbitrary object as an attribute key nested in a hash, escaping it" do
|