fortitude 0.9.4-java → 0.9.5-java

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.fix_bundler_for_jruby_17 +26 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +33 -40
  5. data/CHANGES.md +44 -0
  6. data/CONTRIBUTORS.md +26 -0
  7. data/Rakefile +1 -1
  8. data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +45 -33
  9. data/ext/fortitude_native_ext/fortitude_native_ext.c +23 -23
  10. data/fortitude.gemspec +25 -8
  11. data/lib/fortitude/erector.rb +26 -18
  12. data/lib/fortitude/errors.rb +15 -4
  13. data/lib/fortitude/extensions/fortitude_ruby_ext.rb +35 -10
  14. data/lib/fortitude/rails/helpers.rb +59 -2
  15. data/lib/fortitude/rails/railtie.rb +238 -157
  16. data/lib/fortitude/rails/renderer.rb +15 -0
  17. data/lib/fortitude/rails/rendering_methods.rb +46 -33
  18. data/lib/fortitude/rails/template_handler.rb +49 -18
  19. data/lib/fortitude/rails/yielded_object_outputter.rb +3 -2
  20. data/lib/fortitude/rendering_context.rb +14 -5
  21. data/lib/fortitude/support/method_overriding.rb +90 -0
  22. data/lib/fortitude/support/staticized_method.rb +12 -0
  23. data/lib/fortitude/version.rb +1 -1
  24. data/lib/fortitude/widget/content.rb +4 -2
  25. data/lib/fortitude/widget/files.rb +17 -11
  26. data/lib/fortitude/widget/helpers.rb +7 -1
  27. data/lib/fortitude/widget/integration.rb +4 -0
  28. data/lib/fortitude/widget/localization.rb +63 -4
  29. data/lib/fortitude/widget/rendering.rb +17 -10
  30. data/lib/fortitude_jruby_native_ext.jar +0 -0
  31. data/spec/helpers/fortitude_rails_helpers.rb +26 -4
  32. data/spec/rails/capture_system_spec.rb +1 -1
  33. data/spec/rails/class_loading_system_spec.rb +16 -2
  34. data/spec/rails/complex_helpers_system_spec.rb +29 -0
  35. data/spec/rails/data_passing_system_spec.rb +2 -2
  36. data/spec/rails/development_mode_system_spec.rb +1 -1
  37. data/spec/rails/erector_coexistence_system_spec.rb +1 -1
  38. data/spec/rails/helpers_system_spec.rb +20 -2
  39. data/spec/rails/layouts_system_spec.rb +1 -1
  40. data/spec/rails/rendering_system_spec.rb +4 -4
  41. data/spec/rails/rules_system_spec.rb +2 -2
  42. data/spec/rails/templates/class_loading_system_spec/app/views/some_namespace/some_other_namespace/placeholder.rb +5 -0
  43. data/spec/rails/templates/complex_helpers_system_spec/app/controllers/complex_helpers_system_spec_controller.rb +4 -0
  44. data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/label_block_test.rb +9 -0
  45. data/spec/rails/templates/helpers_system_spec/app/controllers/helpers_system_spec_controller.rb +4 -0
  46. data/spec/rails/templates/helpers_system_spec/app/controllers/home_controller.rb +9 -0
  47. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/rails_helpers_without_automatic_helper_access.rb +37 -0
  48. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/url_helpers_without_automatic_helper_access.rb +45 -0
  49. data/spec/rails/templates/helpers_system_spec/config/initializers/host.rb +1 -0
  50. data/spec/rails/templates/helpers_system_spec/config/routes.rb +7 -0
  51. data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/localization.rb +1 -1
  52. data/spec/rails/templates/view_paths_system_spec/app/controllers/view_paths_system_spec_controller.rb +15 -0
  53. data/spec/rails/templates/view_paths_system_spec/config/application.rb +30 -0
  54. data/spec/rails/templates/view_paths_system_spec/view_path_one/baseone/basetwo/base_class_one.rb +5 -0
  55. data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/added_view_path.html.rb +5 -0
  56. data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/autoloading_from_added_view_path.html.rb +5 -0
  57. data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller.html.rb +5 -0
  58. 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
  59. data/spec/rails/view_paths_system_spec.rb +19 -0
  60. data/spec/system/escaping_system_spec.rb +10 -2
  61. data/spec/system/helpers_system_spec.rb +37 -6
  62. data/spec/system/inline_system_spec.rb +19 -0
  63. data/spec/system/static_method_system_spec.rb +16 -0
  64. data/spec/system/tag_rendering_system_spec.rb +4 -4
  65. data/spec/system/widget_class_from_spec.rb +39 -0
  66. data/spec/system/yield_system_spec.rb +53 -1
  67. metadata +90 -58
@@ -11,6 +11,10 @@ class ComplexHelpersSystemSpecController < ApplicationController
11
11
  # nothing here
12
12
  end
13
13
 
14
+ def label_block_test
15
+ # nothing here
16
+ end
17
+
14
18
  def cache_test
15
19
  @a = params[:a]
16
20
  @b = params[:b]
@@ -0,0 +1,9 @@
1
+ class Views::ComplexHelpersSystemSpec::LabelBlockTest < Fortitude::Widgets::Html5
2
+ def content
3
+ form_for :person do |f|
4
+ f.label(:name) do
5
+ text 'Foo'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -83,4 +83,8 @@ class HelpersSystemSpecController < ApplicationController
83
83
  def helpers_that_output_when_refined
84
84
  # nothing here
85
85
  end
86
+
87
+ def default_url_options
88
+ { :host => 'example.com' }
89
+ end
86
90
  end
@@ -0,0 +1,9 @@
1
+ class HomeController < ApplicationController
2
+ def index
3
+ # nothing here
4
+ end
5
+
6
+ def foo
7
+ # nothing here
8
+ end
9
+ end
@@ -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,7 @@
1
+ app_class = "#{File.basename(Rails.root).camelize}::Application".constantize
2
+ app_class.routes.draw do
3
+ get ':controller/:action'
4
+
5
+ root :to => 'home#index'
6
+ get '/foo', :to => 'home#foo'
7
+ end
@@ -3,5 +3,5 @@ class Views::StaticMethodSystemSpec::Localization < Fortitude::Widgets::Html5
3
3
  text "hello is: #{t('.hello')}"
4
4
  end
5
5
 
6
- # static :content
6
+ static :content
7
7
  end
@@ -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,5 @@
1
+ class Views::Baseone::Basetwo::BaseClassOne < Fortitude::Widgets::Html5
2
+ def base_class_one_method_one
3
+ "this is base class one method one!"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Views::ViewPathsSystemSpec::AddedViewPath < Fortitude::Widgets::Html5
2
+ def content
3
+ p "from an added view path"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Views::ViewPathsSystemSpec::AutoloadingFromAddedViewPath < Views::Baseone::Basetwo::BaseClassOne
2
+ def content
3
+ p "helper method: #{base_class_one_method_one}: there it is!"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Views::ViewPathsSystemSpec::AddedViewPathFromController < Fortitude::Widgets::Html5
2
+ def content
3
+ p "from an added view path from the controller"
4
+ end
5
+ 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&lt;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<b' })).to eq("<p foo=\"a&lt;b\"></p>")
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&quot;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&amp;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
- text "helper1: #{helper1_value}, helper2: #{helper2_value}, helper3: #{helper3_value}"
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')}, done"
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 &lt;&amp;&quot;&gt;=\"foo\">") { hr '<&">' => "foo" }
254
254
  end
255
255
 
256
- it "should escape attribute values" do
257
- should_render_to("<hr class=\"&lt;&amp;&quot;&gt;\">") { hr :class => "<&\">" }
256
+ it "should escape attribute values, but only the necessary characters" do
257
+ should_render_to("<hr class=\"<&amp;&quot;>\">") { 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&amp;&lt;&gt;&quot;this=\"bar\"></p>") { p foo => "bar" }
337
337
  end
338
338
 
339
- it "should render an arbitrary object as an attribute value, escaping it" do
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&amp;&lt;&gt;&quot;this\"></p>") { p :foo => foo }
341
+ should_render_to("<p foo=\"and&amp;<>&quot;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