ettu 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28eeeb019730fdbde0370f53b31ee30dade06adb
4
- data.tar.gz: 7b925784197f8e7d9c8009b57563e0d85ce1f49a
3
+ metadata.gz: 2d25ab552acd13252c6c5b916e118e4fb84fe99f
4
+ data.tar.gz: 2235cc55e58233893a321d28b308d51e94a41655
5
5
  SHA512:
6
- metadata.gz: 0c41c23a43c47b53764dbfb531248c6cce4c026461e4277de4c4905ad0928be4de9ac291db68999054c0aa9c3260140a6f86909fc01959f7251db36f092cb29d
7
- data.tar.gz: 40f849ff897c470f6af3f8ccef53795cb0263a5c9f7710e2c1f9a03ad28bfaafee3ede974bde2cb5d3db2e7af4339f38d6e7a9a982305d8cd35c6e68f4e60cf0
6
+ metadata.gz: 65087d66aa1735063f863232f47e18fb97816b9ce894edcd1f04b732f548d470c3e4a7087a26b93d4eedead50927f5223c60c515be033675a8be9e0df592ed2e
7
+ data.tar.gz: 01e1259d72f51e4a37c3ae90996a872c72ac7ef2875cddee04ba38cea974b2831aaba5728e61b27203d73880469d9eb3d2ed46fc3d5b73b25a3610311777738f
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Ettu
2
2
  ====
3
3
 
4
+ [![Build Status](https://travis-ci.org/cloudspace/ettu.png?branch=v3)](https://travis-ci.org/cloudspace/ettu)
5
+
4
6
  Using Rails 3's `stale?` or `fresh_when`? Are your users seeing old view
5
7
  code even after new deploys? The Rails way `fresh_when(@product)`
6
8
  doesn't account for changes in your view code, you have to do it
@@ -46,10 +48,9 @@ end
46
48
  ```
47
49
 
48
50
  Ettu wants you to keep using either syntax, and let it worry about the
49
- view code. By default, it will add in the asset fingerprints of
50
- `application.js` and `application.css` along with the cache digest of
51
- the current action into the calculation for the final ETag sent to the
52
- browser.
51
+ view code. By default, it will add in the fingerprints of your
52
+ precompiled assets along with the cache digest of the current action
53
+ into the calculation for the final ETag sent to the browser.
53
54
 
54
55
  ### Configuring
55
56
 
@@ -68,34 +69,24 @@ Of course, you can override Ettu's default behavior:
68
69
  ```ruby
69
70
  # config/initializers/ettu.rb
70
71
  Ettu.configure do |config|
71
- # Set the default js file
72
- config.js = 'app.js'
73
- # Or don't account for javascript
74
- # config.js = false
75
-
76
- # Set the default css file
77
- config.css = 'style.css'
78
- # Or don't account for css
79
- # config.css = false
80
-
81
72
  # Add in extra assets to account for
82
- config.assets = ['first.js', 'second.css']
73
+ config.assets += ['first.js', 'second.css']
83
74
  end
84
75
  ```
85
76
 
86
77
  Or each can be passed on an individual basis:
87
78
 
88
- fresh_when @product, js: 'app.js', css: 'style.css', assets: 'super.css'
79
+ fresh_when @product, assets: 'super.css'
89
80
 
90
81
  Additionally, you can specify a different template to calculate with the
91
82
  `view` option:
92
83
 
93
- fresh_when @product, view: "products/index"
84
+ fresh_when @product, view: 'products/index'
94
85
 
95
86
  You can even stop Ettu from accounting for any of them by setting the
96
87
  value to `false`:
97
88
 
98
- fresh_when @product, js: false, css: false, view: false
89
+ fresh_when @product, assets: false, view: false
99
90
 
100
91
  ### What about Rails' default `fresh_when`?
101
92
 
data/ROADMAP.md CHANGED
@@ -1,9 +1,9 @@
1
1
  Ettu Roadmap
2
2
  ============
3
3
 
4
- 1. [x] Decouple Ettu and Configuration
5
- 2. [ ] Remove Rails Version checking
4
+ - [x] Decouple Ettu and Configuration
5
+ - [x] Remove Rails Version checking
6
6
  - Separate gem into branches
7
7
  - v3 branch will track Rails 3
8
8
  - v4 branch will track Rails 4
9
- 3. [ ] Default assets to those set in Rails.application.config.assets.precompile
9
+ - [x] Default assets to those set in Rails.application.config.assets
@@ -13,9 +13,7 @@ class Ettu
13
13
  private
14
14
 
15
15
  def set_defaults
16
- self.js = 'application.js'
17
- self.css = 'application.css'
18
- self.assets = []
16
+ self.assets = LateLoadAssets.new(self, :assets)
19
17
 
20
18
  # Don't actually set view by default.
21
19
  # This'll allow #fetch to return the real default
@@ -23,32 +21,40 @@ class Ettu
23
21
  # self.view = "#{controller_name}/#{action_name}"
24
22
  delete :view if key? :view
25
23
 
26
- # Don't attempt to reset the template_digestor
27
- # if one has already been found
28
- unless self.template_digestor
29
- self.template_digestor = LateLoadTemplateDigestor.new(self)
30
- end
24
+ self.template_digestor = LateLoadTemplateDigestor.new(self, :template_digestor)
31
25
  end
32
26
 
33
- class LateLoadTemplateDigestor
34
- def initialize(config)
27
+ class LateLoad
28
+ def initialize(config, name)
35
29
  @config = config
30
+ @name = name
31
+ end
32
+
33
+ def method_missing(method, *args, &block)
34
+ late_load = defaults
35
+ @config[@name] = late_load
36
+ late_load.send method, *args, &block
36
37
  end
38
+ end
37
39
 
38
- def digest(*args)
39
- digestor = attempt_late_template_digestor_set
40
- digestor.digest(*args)
40
+ class LateLoadAssets < LateLoad
41
+ def to_a
42
+ super
41
43
  end
42
44
 
43
- private
45
+ def defaults
46
+ ::Rails.application.config.assets.digests.keys
47
+ end
48
+ end
44
49
 
45
- def attempt_late_template_digestor_set
50
+ class LateLoadTemplateDigestor < LateLoad
51
+ def defaults
46
52
  unless defined? CacheDigests::TemplateDigestor
47
53
  # Attempt to load cache_digets
48
54
  require 'cache_digests'
49
55
  end
50
56
  # Attempt to use CacheDigests::TemplateDigestor on Rails 3
51
- @config.template_digestor = CacheDigests::TemplateDigestor
57
+ ::CacheDigests::TemplateDigestor
52
58
  rescue LoadError
53
59
  raise "Ettu requires the cache_digests gem in Rails v#{Rails::VERSION::STRING}"
54
60
  end
@@ -2,22 +2,12 @@ class Ettu
2
2
  module FreshWhen
3
3
  extend ActiveSupport::Concern
4
4
 
5
- included do
6
- alias_method :old_fresh_when, :fresh_when
5
+ def fresh_when(record_or_options, additional_options = {})
6
+ ettu = Ettu.new record_or_options, additional_options, self
7
7
 
8
- def fresh_when(record_or_options, additional_options = {})
9
- ettu = ettu_instance(record_or_options, additional_options, self)
8
+ ettu_params = {etag: ettu.etags, last_modified: ettu.last_modified}
10
9
 
11
- ettu_params = {etag: ettu.etags, last_modified: ettu.last_modified}
12
-
13
- old_fresh_when nil, ettu.options.merge(ettu_params)
14
- end
15
- end
16
-
17
- private
18
-
19
- def ettu_instance(record_or_options, additional_options, controller)
20
- Ettu.new record_or_options, additional_options, controller
10
+ super nil, ettu.options.merge(ettu_params)
21
11
  end
22
12
  end
23
13
  end
data/lib/ettu/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Ettu
2
- VERSION = '3.0.0'
2
+ VERSION = '3.1.0'
3
3
  end
data/lib/ettu.rb CHANGED
@@ -32,11 +32,8 @@ class Ettu
32
32
  def etags
33
33
  etags = [*response_etag]
34
34
  etags << view_etag
35
- if @controller.request.format.try(:html?)
36
- etags << js_etag
37
- etags << css_etag
38
- end
39
35
  etags.concat asset_etags
36
+ etags.compact
40
37
  end
41
38
 
42
39
  def last_modified
@@ -53,16 +50,6 @@ class Ettu
53
50
  @view_etag ||= view_digest(view)
54
51
  end
55
52
 
56
- def js_etag
57
- js = @options.fetch(:js, @@config.js)
58
- asset_etag js
59
- end
60
-
61
- def css_etag
62
- css = @options.fetch(:css, @@config.css)
63
- asset_etag css
64
- end
65
-
66
53
  def asset_etags
67
54
  assets = @options.fetch(:assets, @@config.assets)
68
55
  [*assets].map { |asset| asset_etag(asset) }
data/spec/ettu_spec.rb CHANGED
@@ -4,24 +4,16 @@ describe Ettu do
4
4
  let(:controller) { Controller.new }
5
5
  let(:record) { Record.new(DateTime.now) }
6
6
  let(:hash) { { etag: record, last_modified: DateTime.now } }
7
- before(:all) do
8
- Ettu.configure { |config| config.template_digestor = Digestor }
9
- end
10
7
 
11
8
  context 'when supplied with options' do
12
- let(:hash) { { js: 'custom.js', css: 'custom.css', assets: 'first.ext', view: 'custom/action' } }
13
- subject(:ettu) { Ettu.new(hash, {}, controller) }
14
-
15
- it 'will use :js option over default' do
16
- expect(ettu.js_etag).to eq('custom.js.digest')
17
- end
18
-
19
- it 'will use :css option over default' do
20
- expect(ettu.css_etag).to eq('custom.css.digest')
9
+ before(:all) do
10
+ Ettu.configure { |config| config.template_digestor = Digestor }
21
11
  end
12
+ let(:hash) { { assets: 'first.ext', view: 'custom/action' } }
13
+ subject(:ettu) { Ettu.new(hash, {}, controller) }
22
14
 
23
15
  it 'will use :asset option over default' do
24
- expect(ettu.asset_etags).to eq(['first.ext.digest'])
16
+ expect(ettu.asset_etags).to eq(['first.ext.manifest'])
25
17
  end
26
18
 
27
19
  it 'will use :view option over default' do
@@ -31,50 +23,53 @@ describe Ettu do
31
23
 
32
24
  describe '.configure' do
33
25
  subject(:ettu) { Ettu.new(nil, {}, controller) }
26
+ before(:all) do
27
+ Ettu.configure { |config| config.template_digestor = Digestor }
28
+ end
34
29
  after(:all) { Ettu.configure { |config| config.reset } }
35
30
 
36
31
  context 'when no options are specified' do
37
32
  before(:all) do
38
33
  Ettu.configure do |config|
39
- config.js = 'custom.js'
40
- config.css = 'custom.css'
41
34
  config.assets = ['first.ext', 'second.ext']
42
35
  config.view = 'custom/view'
43
36
  end
44
37
  end
45
38
 
46
- it 'will use the default js file' do
47
- expect(ettu.js_etag).to eq('custom.js.digest')
39
+ it 'will use the default asset files' do
40
+ expect(ettu.asset_etags).to eq(['first.ext.manifest', 'second.ext.manifest'])
48
41
  end
49
42
 
50
- it 'will use the default css file' do
51
- expect(ettu.css_etag).to eq('custom.css.digest')
43
+ it 'will use the default view file' do
44
+ expect(ettu.view_etag).to eq('custom/view.digest')
52
45
  end
46
+ end
53
47
 
54
- it 'will use the default asset files' do
55
- expect(ettu.asset_etags).to eq(['first.ext.digest', 'second.ext.digest'])
48
+ context 'can append additional assets' do
49
+ let(:configuration) { Ettu::Configuration.new }
50
+ let(:random_string) { SecureRandom.hex }
51
+
52
+ it 'with +=' do
53
+ configuration.assets += [random_string]
54
+ expect(configuration.assets).to include(random_string)
56
55
  end
57
56
 
58
- it 'will use the default view file' do
59
- expect(ettu.view_etag).to eq('custom/view.digest')
57
+ it 'with <<' do
58
+ configuration.assets << random_string
59
+ expect(configuration.assets).to include(random_string)
60
60
  end
61
61
  end
62
62
 
63
63
  context 'when setting default to false' do
64
64
  before(:all) do
65
65
  Ettu.configure do |config|
66
- config.js = false
67
- config.css = false
66
+ config.assets = false
68
67
  config.view = false
69
68
  end
70
69
  end
71
70
 
72
- it 'will disable js etag' do
73
- expect(ettu.js_etag).to eq(nil)
74
- end
75
-
76
- it 'will disable css etag' do
77
- expect(ettu.css_etag).to eq(nil)
71
+ it 'will disable asset etags' do
72
+ expect(ettu.asset_etags).to eq([nil])
78
73
  end
79
74
 
80
75
  it 'will disable view etags' do
@@ -84,13 +79,27 @@ describe Ettu do
84
79
  end
85
80
 
86
81
  describe '#etags' do
82
+ before(:all) do
83
+ Ettu.configure { |config| config.template_digestor = Digestor }
84
+ end
87
85
  let(:ettu) { Ettu.new(record, {}, controller) }
86
+
88
87
  it 'will collect all etags' do
89
- expected = [record, 'controller_name/action_name.digest', 'application.js.digest', 'application.css.digest']
88
+ expected = [
89
+ record, 'controller_name/action_name.digest',
90
+ 'application.js.manifest', 'application.css.manifest',
91
+ 'custom.js.manifest', 'custom.css.manifest',
92
+ 'first.ext.manifest', 'second.ext.manifest'
93
+ ]
90
94
  result = ettu.etags
91
- expect(ettu.etags).to include(*expected)
95
+ expect(result).to include(*expected)
92
96
  expect(expected).to include(*result)
93
97
  end
98
+
99
+ it 'will not allow nils' do
100
+ ettu = Ettu.new(nil, {assets: [nil, nil, nil]}, controller )
101
+ expect(ettu.etags).not_to include(nil)
102
+ end
94
103
  end
95
104
 
96
105
  context 'when given only a record' do
data/spec/fixtures.rb CHANGED
@@ -13,9 +13,12 @@ class Controller < Nester
13
13
  self.action_name = 'action_name'
14
14
  end
15
15
 
16
- def fresh_when(*args)
17
- :old_fresh_when
16
+ module Freshness
17
+ def fresh_when(*args)
18
+ [*args]
19
+ end
18
20
  end
21
+ include Freshness
19
22
 
20
23
  include ::Ettu::FreshWhen
21
24
  end
@@ -48,5 +51,7 @@ Rails.application.assets['custom.js'].digest = 'custom.js.digest'
48
51
  Rails.application.assets['custom.css'].digest = 'custom.css.digest'
49
52
  Rails.application.assets['first.ext'].digest = 'first.ext.digest'
50
53
  Rails.application.assets['second.ext'].digest = 'second.ext.digest'
51
- Rails.application.config.assets.digests = nil
52
-
54
+ Rails.application.config.assets.digests = Rails.application.assets.keys.reduce({}) do |hash, asset|
55
+ hash[asset.to_s] = asset.to_s + '.manifest'
56
+ hash
57
+ end
@@ -6,41 +6,19 @@ describe Ettu::FreshWhen do
6
6
  Ettu.configure { |config| config.template_digestor = Digestor }
7
7
  end
8
8
 
9
- let(:ettu) { double }
10
9
  let(:record) { Record.new(DateTime.now) }
11
10
  let(:hash) { { random: true, options: true } }
12
11
  subject(:controller) { Controller.new }
13
12
 
14
- before(:each) do
15
- controller.stub(ettu_instance: ettu)
16
- ettu.stub(:etags)
17
- ettu.stub(:last_modified)
18
- ettu.stub(options: {})
19
- end
20
-
21
- it 'calls Ettu#etags' do
22
- ettu.should_receive(:etags)
23
- controller.fresh_when record, hash
24
- end
25
-
26
- it 'calls Ettu#last_modified' do
27
- ettu.should_receive(:last_modified)
28
- controller.fresh_when record, hash
29
- end
30
-
31
13
  it 'passes nil as the first argument to original fresh_when' do
32
- controller.should_receive(:old_fresh_when) do |r, h|
33
- r.nil?
34
- end
35
- controller.fresh_when record, hash
14
+ ret = controller.fresh_when record, hash
15
+
16
+ expect(ret[0]).to equal(nil)
36
17
  end
37
18
 
38
19
  it 'passes extra options to original fresh_when' do
39
- controller.should_receive(:old_fresh_when) do |r, h|
40
- hash.each_pair.all? do |k, v|
41
- h[k] == v
42
- end
43
- end
44
- controller.fresh_when record, hash
20
+ ret = controller.fresh_when record, hash
21
+
22
+ expect(ret[1]).to include_hash(hash)
45
23
  end
46
24
  end
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,14 @@
7
7
 
8
8
  require 'date'
9
9
  require 'active_support/ordered_options'
10
+ require 'securerandom'
11
+ RSpec::Matchers.define :include_hash do |expected|
12
+ match do |actual|
13
+ !actual.nil? &&
14
+ !actual.empty? &&
15
+ (actual.to_a & expected.to_a) == expected.to_a
16
+ end
17
+ end
10
18
 
11
19
  require 'simplecov'
12
20
  SimpleCov.start { add_filter '/spec/' }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ettu
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Ridgewell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-01 00:00:00.000000000 Z
11
+ date: 2013-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails