erector-rails4 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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