erector-rails4 0.1.3 → 0.2.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -1
  3. data/.travis.yml +1 -1
  4. data/Appraisals +4 -1
  5. data/Guardfile +23 -0
  6. data/README.md +6 -1
  7. data/erector-rails4.gemspec +10 -3
  8. data/gemfiles/rails_3.gemfile +1 -0
  9. data/gemfiles/rails_4.0.gemfile +1 -0
  10. data/gemfiles/rails_4.1.gemfile +2 -1
  11. data/lib/erector-rails4.rb +1 -0
  12. data/lib/erector.rb +1 -4
  13. data/lib/erector/abstract_widget.rb +1 -12
  14. data/lib/erector/after_initialize.rb +7 -7
  15. data/lib/erector/caching.rb +35 -71
  16. data/lib/erector/element.rb +4 -4
  17. data/lib/erector/externals.rb +0 -8
  18. data/lib/erector/html_widget.rb +0 -11
  19. data/lib/erector/needs.rb +20 -9
  20. data/lib/erector/output.rb +2 -4
  21. data/lib/erector/promise.rb +4 -4
  22. data/lib/erector/rails.rb +6 -1
  23. data/lib/erector/rails/autoload_monkeypatch.rb +1 -1
  24. data/lib/erector/rails/railtie.rb +15 -8
  25. data/lib/erector/rails/template_handler.rb +2 -1
  26. data/lib/erector/text.rb +4 -8
  27. data/lib/erector/version.rb +1 -1
  28. data/lib/erector/widget.rb +2 -11
  29. data/lib/erector/xml_widget.rb +14 -18
  30. data/script/bootstrap +30 -0
  31. data/script/cibuild +3 -0
  32. data/script/performance +3 -0
  33. data/script/release +38 -0
  34. data/spec/dummy/app/views/test/_partial_with_rails_helpers.rb +7 -0
  35. data/spec/dummy/app/views/test/_user.rb +7 -0
  36. data/spec/dummy/app/views/test/_virtual_path_partial.rb +5 -0
  37. data/spec/dummy/app/views/test/erb_from_erector.html.rb +1 -1
  38. data/spec/dummy/app/views/test/erector_with_helpers_from_erb.html.erb +1 -0
  39. data/spec/dummy/app/views/test/{needs.html.rb → needs.rb} +0 -0
  40. data/spec/dummy/app/views/test/{needs_subclass.html.rb → needs_subclass.rb} +0 -0
  41. data/spec/dummy/app/views/test/render_partial.html.rb +1 -1
  42. data/spec/dummy/app/views/test/render_virtual_path.rb +7 -0
  43. data/spec/dummy/app/views/test/users.rb +9 -0
  44. data/spec/dummy/app/views/test_caching/_foos.rb +7 -0
  45. data/spec/dummy/app/views/test_caching/_partial.rb +9 -0
  46. data/spec/dummy/app/views/test_caching/cache_helper.rb +9 -0
  47. data/spec/dummy/app/views/test_caching/cache_helper_with_explicit_dependencies.rb +7 -0
  48. data/spec/dummy/app/views/test_caching/cache_helper_with_implicit_dependencies.rb +7 -0
  49. data/spec/dummy/app/views/test_caching/cache_helper_with_partial.rb +10 -0
  50. data/spec/dummy/app/views/test_caching/cache_helper_with_skip_digest.rb +9 -0
  51. data/spec/dummy/app/views/test_caching/cacheable_widget_with_dynamic_keys.rb +13 -0
  52. data/spec/dummy/app/views/test_caching/cacheable_widget_with_needs.rb +11 -0
  53. data/spec/dummy/app/views/test_caching/cacheable_widget_with_needs_keys.rb +11 -0
  54. data/spec/dummy/app/views/test_caching/cacheable_widget_with_skip_digest.rb +9 -0
  55. data/spec/dummy/app/views/test_caching/cacheable_widget_with_static_keys.rb +9 -0
  56. data/spec/dummy/config/application.rb +1 -1
  57. data/spec/dummy/spec/autoload_spec.rb +2 -2
  58. data/spec/dummy/spec/caching_spec.rb +180 -0
  59. data/spec/dummy/spec/form_builder_spec.rb +1 -1
  60. data/spec/dummy/spec/rails_helpers_spec.rb +21 -13
  61. data/spec/dummy/spec/rails_widget_spec.rb +1 -1
  62. data/spec/dummy/spec/render_spec.rb +23 -42
  63. data/spec/erector/dependency_spec.rb +0 -1
  64. data/spec/erector/html_spec.rb +4 -4
  65. data/spec/erector/indentation_spec.rb +2 -2
  66. data/spec/erector/needs_spec.rb +33 -0
  67. data/spec/erector/output_spec.rb +0 -2
  68. data/spec/erector/promise_spec.rb +2 -2
  69. data/spec/erector/widget_spec.rb +2 -2
  70. data/spec/performance/allocation_spec.rb +19 -0
  71. data/spec/performance/ruby_prof_spec.rb +23 -0
  72. data/spec/performance/widget_to_html_spec.rb +11 -5
  73. data/spec/spec_helper.rb +1 -10
  74. data/spec/support/capturing_output.rb +8 -0
  75. metadata +116 -17
  76. data/lib/erector/cache.rb +0 -41
  77. data/lib/erector/raw_string.rb +0 -12
  78. data/spec/dummy/spec/rails_spec_helper.rb +0 -10
  79. data/spec/erector/cache_spec.rb +0 -133
  80. data/spec/erector/caching_spec.rb +0 -202
@@ -1,41 +0,0 @@
1
- require 'singleton'
2
-
3
- module Erector
4
- class Cache
5
- CACHE_NAMESPACE = 'erector'
6
- include Singleton
7
-
8
- def []=(*args)
9
- value = args.pop
10
- ::Rails.cache.write(transform_key(args), value.to_s)
11
- end
12
-
13
- def [](*args)
14
- ::Rails.cache.read(transform_key(args))
15
- end
16
-
17
- def delete(*args)
18
- ::Rails.cache.delete(transform_key(args))
19
- end
20
-
21
- def transform_key(args)
22
- key = args.reject { |x| x.nil? }
23
-
24
- # If we're on Rails 3, coerce cache keys to array.
25
- # See changes to the retrieve_cache_key method here:
26
- # http://apidock.com/rails/v4.0.2/ActiveSupport/Cache/retrieve_cache_key/class
27
- if Gem::Version.new(::Rails.version) < Gem::Version.new('4.0.0')
28
- key = key.map do |x|
29
- if !x.respond_to?(:cache_key) && !x.is_a?(Array) && x.respond_to?(:to_a)
30
- x.to_a
31
- else
32
- x
33
- end
34
- end
35
- end
36
-
37
- ActiveSupport::Cache.expand_cache_key(key, CACHE_NAMESPACE)
38
- end
39
-
40
- end
41
- end
@@ -1,12 +0,0 @@
1
- module Erector
2
- # A string that has a special type so Erector knows to render it directly, not HTML-escaped
3
- class RawString < String
4
- def html_safe?
5
- true
6
- end
7
-
8
- def to_s
9
- self
10
- end
11
- end
12
- end
@@ -1,10 +0,0 @@
1
- ENV["RAILS_ENV"] ||= "test"
2
- ENV["BUNDLE_GEMFILE"] ||= "#{File.dirname(__FILE__)}/../Gemfile"
3
-
4
- here = File.expand_path(File.dirname(__FILE__))
5
- require File.expand_path("#{here}/../../spec_helper", __FILE__)
6
- require File.expand_path("#{here}/../config/environment", __FILE__)
7
-
8
- Bundler.require(:test)
9
-
10
- require "erector/rails"
@@ -1,133 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # todo: figure out why "include Caching" only works when it's on Widget
4
- describe Erector::Cache do
5
- before do
6
- ::Rails.cache.clear
7
- @cache = Erector::Cache.instance
8
- end
9
-
10
- class Johnny < Erector::Widget
11
- end
12
-
13
- class June < Erector::Widget
14
- end
15
-
16
- it 'caches a class with no parameters' do
17
- @cache[Johnny] = "ring of fire"
18
- @cache[Johnny].should == "ring of fire"
19
- end
20
-
21
- it 'caches two classes with no parameters' do
22
- @cache[Johnny] = "ring of fire"
23
- @cache[June] = "wildwood flower"
24
- @cache[Johnny].should == "ring of fire"
25
- @cache[June].should == "wildwood flower"
26
- end
27
-
28
- it "stores different slots for the same class with different parameters" do
29
- @cache[Johnny, {:flames => "higher"}] = "ring of fire"
30
- @cache[Johnny, {:working => "in a coal mine"}] = "my daddy died young"
31
-
32
- @cache[Johnny, {:flames => "higher"}].should == "ring of fire"
33
- @cache[Johnny, {:working => "in a coal mine"}].should == "my daddy died young"
34
- end
35
-
36
- it "stores different slots for the same class with same parameters and different content methods" do
37
- @cache[Johnny, {}, :foo] = "ring of fire"
38
- @cache[Johnny, {}, :bar] = "my daddy died young"
39
-
40
- @cache[Johnny, {}, :foo].should == "ring of fire"
41
- @cache[Johnny, {}, :bar].should == "my daddy died young"
42
- end
43
-
44
- describe 'after storing a widget with one parameter' do
45
- before do
46
- @cache[Johnny, {:flames => "higher"}] = "ring of fire"
47
- end
48
-
49
- it 'doesn\'t get it when passed the class alone' do
50
- @cache[Johnny].should be_nil
51
- end
52
-
53
- it 'doesn\'t get it when passed a different class' do
54
- @cache[June].should be_nil
55
- end
56
-
57
- it 'gets it' do
58
- @cache[Johnny, {:flames => "higher"}].should == "ring of fire"
59
- end
60
-
61
- it 'doesn\'t get it when passed a different parameter key' do
62
- @cache[Johnny, {:working => "coal mine"}].should be_nil
63
- end
64
-
65
- it 'doesn\'t get it when passed a different parameter value' do
66
- @cache[Johnny, {:flames => "lower"}].should be_nil
67
- end
68
-
69
- it 'doesn\'t get it when passed an extra parameter key' do
70
- @cache[Johnny, {:flames => "higher", :working => "coal mine"}].should be_nil
71
- end
72
- end
73
-
74
- describe 'after storing a widget with more than one parameter' do
75
- before do
76
- @cache[Johnny, {:flames => "higher", :working => "coal mine"}] = "ring of fire"
77
- end
78
-
79
- it "gets it" do
80
- @cache[Johnny, {:flames => "higher", :working => "coal mine"}].should == "ring of fire"
81
- end
82
-
83
- it 'doesn\'t get it when passed the class alone' do
84
- @cache[Johnny].should be_nil
85
- end
86
-
87
- it "doesn't get it when passed a partial parameter set" do
88
- @cache[Johnny, {:flames => "higher"}].should be_nil
89
- end
90
-
91
- it 'doesn\'t get it when passed a different class' do
92
- @cache[June].should be_nil
93
- end
94
-
95
- it 'doesn\'t get it when passed different a parameter value' do
96
- @cache[Johnny, {:flames => "lower", :working => "coal mine"}].should be_nil
97
- end
98
-
99
- it 'doesn\'t get it when passed an extra parameter key' do
100
- @cache[Johnny, {:flames => "higher", :working => "coal mine", :hear => "train a' comin'"}].should be_nil
101
- end
102
- end
103
-
104
- describe "expires" do
105
- it 'a class with no parameters' do
106
- @cache[Johnny] = "ring of fire"
107
- @cache.delete(Johnny)
108
- @cache[Johnny].should be_nil
109
- end
110
-
111
- it 'all versions of a class' do
112
- @cache[Johnny] = "i fell in"
113
- @cache[Johnny, {:flames => "higher"}] = "ring of fire"
114
- @cache[Johnny, {:working => "in a coal mine"}] = "my daddy died young"
115
-
116
- ::Rails.cache.clear
117
-
118
- @cache[Johnny].should be_nil
119
- @cache[Johnny, {:flames => "higher"}].should be_nil
120
- @cache[Johnny, {:working => "in a coal mine"}].should be_nil
121
- end
122
-
123
- it '...but not other cached values' do
124
- @cache[Johnny] = "ring of fire"
125
- @cache[Johnny, {:flames => 'higher'}] = "higher fire"
126
- @cache[June] = "wildwood flower"
127
- @cache.delete(Johnny)
128
- @cache[Johnny].should be_nil
129
- @cache[Johnny, {:flames => 'higher'}].should == "higher fire"
130
- @cache[June].should == "wildwood flower"
131
- end
132
- end
133
- end
@@ -1,202 +0,0 @@
1
- require 'ostruct'
2
- require 'spec_helper'
3
-
4
- describe Erector::Caching do
5
- include Erector::Mixin
6
-
7
- class Cash < Erector::Widget
8
- needs :name
9
- cachable # this is correct, just an alias
10
-
11
- def content
12
- p do
13
- text @name
14
- text " Cash"
15
- end
16
- end
17
- end
18
-
19
- class CashWithVersion < Erector::Widget
20
- needs :name
21
- cachable 'v2'
22
-
23
- def content
24
- p do
25
- text @name
26
- text " Cash 2"
27
- end
28
- end
29
- end
30
-
31
- class CashWithComplexKey < Erector::Widget
32
- needs :sites
33
- cachable
34
-
35
- def content
36
- text @sites.first.name
37
- end
38
- end
39
-
40
- class CashWithCacheOpts < Erector::Widget
41
- needs :name, :occupation
42
- cachable 'v3', only_keys: [:occupation]
43
-
44
- def content
45
- text "#{@name} is a #{@occupation}"
46
- end
47
- end
48
-
49
- class Family < Erector::Widget
50
- cacheable
51
-
52
- def content
53
- widget Cash, :name => "Johnny"
54
- widget Cash, :name => "June"
55
- end
56
- end
57
-
58
- class ModelCash < Erector::Widget
59
- cacheable
60
-
61
- def content
62
- text @model.name
63
- end
64
- end
65
-
66
- class NotCachable < Erector::Widget
67
- def content
68
- text "CONTENT"
69
- end
70
- end
71
-
72
- before do
73
- ::Rails.configuration.action_controller.cache_store = :memory_store
74
- ::Rails.cache.clear
75
- @cache = Erector::Cache.instance
76
- end
77
-
78
- it "has a global cache" do
79
- Erector::Widget.cache.should == @cache
80
- end
81
-
82
- it '-- a widget is not cachable by default' do
83
- Erector::Widget.cachable?.should be_false
84
- end
85
-
86
- it '-- a widget is cachable if you say so in the class definition' do
87
- Cash.cachable?.should be_true
88
- end
89
-
90
- it '-- can be declared cachable using the alternate spelling "cacheable"' do
91
- Family.cachable?.should be_true
92
- end
93
-
94
- describe '#to_html' do
95
-
96
- it "caches a rendered widget" do
97
- Cash.new(:name => "Johnny").to_html
98
- @cache[Cash, {:name => "Johnny"}].should == "<p>Johnny Cash</p>"
99
- end
100
-
101
- it "uses a cache version for the class" do
102
- CashWithVersion.new(:name => "Johnny").to_html
103
- @cache[CashWithVersion, 'v2', {:name => "Johnny"}].should == "<p>Johnny Cash 2</p>"
104
- end
105
-
106
- it "handles complex keys" do
107
- site1 = OpenStruct.new(name: 'site one name')
108
- site2 = OpenStruct.new(name: 'site two name')
109
- site3 = OpenStruct.new(name: 'site three name')
110
- CashWithComplexKey.new(sites: [site1, site2]).to_html
111
- @cache[CashWithComplexKey, sites: [site1, site2]].should == "site one name"
112
- CashWithComplexKey.new(sites: [site3, site1, site2]).to_html.should == "site three name"
113
- end
114
-
115
- it "calls :cache_key" do
116
- model = OpenStruct.new(name: 'Myname', cache_key: 'two')
117
- ModelCash.new(:model => model).to_html
118
- @cache[ModelCash, { model: 'two' }].should == "Myname"
119
- end
120
-
121
- it "uses the cached value" do
122
- @cache[Cash, {:name => "Johnny"}] = "CACHED"
123
- Cash.new(:name => "Johnny").to_html.should == "CACHED"
124
- end
125
-
126
- it "uses the only_keys option" do
127
- CashWithCacheOpts.new(name: "Adam", occupation: "Hairdresser").to_html
128
- @cache[CashWithCacheOpts, 'v3', {occupation: "Hairdresser"}].should == "Adam is a Hairdresser"
129
- CashWithCacheOpts.new(name: "Foobar", occupation: "Hairdresser").to_html.should == "Adam is a Hairdresser"
130
- CashWithCacheOpts.new(name: "Foobar", occupation: "Hairdressr").to_html.should == "Foobar is a Hairdressr"
131
- end
132
-
133
- it "doesn't use the cached value for widgets not declared cachable" do
134
- @cache[NotCachable] = "CACHED"
135
- NotCachable.new.to_html.should == "CONTENT"
136
- end
137
-
138
- it "doesn't cache widgets not declared cachable" do
139
- NotCachable.new.to_html
140
- @cache[NotCachable].should be_nil
141
- end
142
-
143
- it "doesn't cache widgets initialized with a block (yet)" do
144
- Cash.new(:name => "June") do
145
- text "whatever"
146
- end.to_html
147
- @cache[Cash, {:name => "June"}].should be_nil
148
- end
149
-
150
- it "caches distinct values when using :content_method_name" do
151
- widget = Class.new(Erector::Widget) do
152
- cacheable
153
-
154
- def foo
155
- text "foo"
156
- end
157
-
158
- def bar
159
- text "bar"
160
- end
161
- end
162
-
163
- widget.new.to_html(:content_method_name => :foo).should == "foo"
164
- widget.new.to_html(:content_method_name => :bar).should == "bar"
165
- end
166
-
167
- it "works when passing an existing output as a parameter to to_html" do
168
- pending
169
- end
170
- end
171
-
172
- describe '#widget' do
173
-
174
- it "caches rendered widgets" do
175
- Family.new.to_html
176
- @cache[Cash, {:name => "Johnny"}].to_s.should == "<p>Johnny Cash</p>"
177
- @cache[Cash, {:name => "June"}].to_s.should == "<p>June Cash</p>"
178
- end
179
-
180
- it "uses the cached value" do
181
- @cache[Cash, {:name => "Johnny"}] = "JOHNNY CACHED"
182
- Family.new.to_html.should == "JOHNNY CACHED<p>June Cash</p>"
183
- end
184
-
185
- class WidgetWithBlock < Erector::Widget
186
- def content
187
- call_block
188
- end
189
- end
190
-
191
- it "doesn't cache widgets initialized with a block (yet)" do
192
- erector {
193
- w = WidgetWithBlock.new do
194
- text "in block"
195
- end
196
- widget w
197
- }.should == "in block"
198
- @cache[WidgetWithBlock].should be_nil
199
- end
200
-
201
- end
202
- end