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.
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