ettu 0.0.5 → 0.0.6
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.
- data/.rspec +0 -1
- data/ettu.gemspec +1 -0
- data/lib/ettu/configuration.rb +30 -0
- data/lib/ettu/fresh_when.rb +8 -11
- data/lib/ettu/version.rb +1 -1
- data/lib/ettu.rb +26 -21
- data/spec/ettu_spec.rb +81 -24
- data/spec/fixtures.rb +49 -0
- data/spec/fresh_when_spec.rb +42 -4
- data/spec/spec_helper.rb +7 -1
- metadata +20 -1
data/.rspec
CHANGED
data/ettu.gemspec
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
class Ettu
|
2
|
+
class Configuration < ActiveSupport::OrderedOptions
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
set_defaults
|
6
|
+
end
|
7
|
+
|
8
|
+
def reset
|
9
|
+
set_defaults
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def set_defaults
|
15
|
+
self.js = 'application.js'
|
16
|
+
self.css = 'application.css'
|
17
|
+
self.assets = []
|
18
|
+
|
19
|
+
# Don't actually set view by default.
|
20
|
+
# This'll allow #fetch to return the real default
|
21
|
+
# at runtime.
|
22
|
+
# self.view = "#{controller_name}/#{action_name}"
|
23
|
+
delete :view if key? :view
|
24
|
+
|
25
|
+
if defined? ActionView::Digestor
|
26
|
+
self.template_digestor = ActionView::Digestor
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/ettu/fresh_when.rb
CHANGED
@@ -5,22 +5,19 @@ class Ettu
|
|
5
5
|
included do
|
6
6
|
alias_method :old_fresh_when, :fresh_when
|
7
7
|
|
8
|
-
def fresh_when(record_or_options, additional_options
|
9
|
-
ettu =
|
8
|
+
def fresh_when(record_or_options, additional_options)
|
9
|
+
ettu = ettu_instance(record_or_options, additional_options, self)
|
10
10
|
|
11
|
-
|
12
|
-
etags << ettu.view_etag
|
13
|
-
if request.format.try(:html?)
|
14
|
-
etags << ettu.js_etag
|
15
|
-
etags << ettu.css_etag
|
16
|
-
end
|
17
|
-
etags.concat ettu.asset_etags
|
18
|
-
|
19
|
-
ettu_params = {etag: etags, last_modified: ettu.last_modified}
|
11
|
+
ettu_params = {etag: ettu.etags, last_modified: ettu.last_modified}
|
20
12
|
|
21
13
|
old_fresh_when nil, ettu.options.merge(ettu_params)
|
22
14
|
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
23
18
|
|
19
|
+
def ettu_instance(record_or_options, additional_options, controller)
|
20
|
+
Ettu.new record_or_options, additional_options, controller
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
data/lib/ettu/version.rb
CHANGED
data/lib/ettu.rb
CHANGED
@@ -4,22 +4,15 @@ require 'active_support/core_ext/object/blank'
|
|
4
4
|
require 'active_support/core_ext/object/try'
|
5
5
|
|
6
6
|
require 'ettu/version'
|
7
|
+
require 'ettu/configuration'
|
7
8
|
require 'ettu/fresh_when'
|
8
|
-
require 'ettu/railtie' if defined? Rails
|
9
|
+
require 'ettu/railtie' if defined? Rails::Railtie
|
9
10
|
|
10
11
|
class Ettu
|
11
12
|
attr_reader :options
|
12
13
|
|
13
14
|
class << self
|
14
|
-
@@config =
|
15
|
-
@@config.js = 'application.js'
|
16
|
-
@@config.css = 'application.css'
|
17
|
-
@@config.assets = []
|
18
|
-
@@config.template_digestor = if defined? ActionView::Digestor
|
19
|
-
ActionView::Digestor
|
20
|
-
else
|
21
|
-
nil
|
22
|
-
end
|
15
|
+
@@config = Configuration.new
|
23
16
|
|
24
17
|
def configure
|
25
18
|
yield @@config
|
@@ -27,27 +20,36 @@ class Ettu
|
|
27
20
|
end
|
28
21
|
|
29
22
|
def initialize(record_or_options = nil, additional_options = {}, controller = nil)
|
30
|
-
@controller = controller
|
31
|
-
@asset_etags = {}
|
23
|
+
@controller, @asset_etags = controller, {}
|
32
24
|
if record_or_options.is_a? Hash
|
33
|
-
@record = nil
|
34
|
-
@options = record_or_options
|
25
|
+
@record, @options = nil, record_or_options
|
35
26
|
else
|
36
|
-
@record = record_or_options
|
37
|
-
@options = additional_options
|
27
|
+
@record, @options = record_or_options, additional_options
|
38
28
|
end
|
39
29
|
end
|
40
30
|
|
41
|
-
def
|
42
|
-
|
31
|
+
def etags
|
32
|
+
etags = [*response_etag]
|
33
|
+
etags << view_etag
|
34
|
+
if @controller.request.format.try(:html?)
|
35
|
+
etags << js_etag
|
36
|
+
etags << css_etag
|
37
|
+
end
|
38
|
+
etags.concat asset_etags
|
43
39
|
end
|
44
40
|
|
45
41
|
def last_modified
|
46
42
|
@options.fetch(:last_modified, @record.try(:updated_at))
|
47
43
|
end
|
48
44
|
|
45
|
+
def response_etag
|
46
|
+
@options.fetch(:etag, @record)
|
47
|
+
end
|
48
|
+
|
49
49
|
def view_etag
|
50
|
-
|
50
|
+
default_view = @@config.fetch(:view, "#{@controller.controller_name}/#{@controller.action_name}")
|
51
|
+
view = @options.fetch(:view, default_view)
|
52
|
+
@view_etag ||= view_digest(view)
|
51
53
|
end
|
52
54
|
|
53
55
|
def js_etag
|
@@ -73,9 +75,10 @@ class Ettu
|
|
73
75
|
|
74
76
|
# Jeremy Kemper
|
75
77
|
# https://gist.github.com/jeremy/4211803
|
76
|
-
def view_digest
|
78
|
+
def view_digest(view)
|
79
|
+
return nil unless view.present?
|
77
80
|
@@config.template_digestor.digest(
|
78
|
-
|
81
|
+
view,
|
79
82
|
@controller.request.format.try(:to_sym),
|
80
83
|
@controller.lookup_context
|
81
84
|
)
|
@@ -86,6 +89,8 @@ class Ettu
|
|
86
89
|
# Check precompiled asset manifest (production) or compute the digest (dev).
|
87
90
|
def asset_digest(asset)
|
88
91
|
return nil unless asset.present?
|
92
|
+
# Is Rails.application.config.assets.digests needed?
|
93
|
+
# Seems to always be nil...
|
89
94
|
if manifest = Rails.application.config.assets.digests
|
90
95
|
manifest[asset]
|
91
96
|
else
|
data/spec/ettu_spec.rb
CHANGED
@@ -1,41 +1,98 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
return self
|
3
|
+
describe Ettu do
|
4
|
+
let(:controller) { Controller.new }
|
5
|
+
let(:record) { Record.new(DateTime.now) }
|
6
|
+
let(:hash) { { etag: record, last_modified: DateTime.now } }
|
7
|
+
before(:all) do
|
8
|
+
Ettu.configure { |config| config.template_digestor = Digestor }
|
10
9
|
end
|
11
|
-
end
|
12
|
-
module Rails
|
13
|
-
module Railtie; end
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
11
|
+
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) }
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
it 'will use :js option over default' do
|
16
|
+
expect(ettu.js_etag).to eq('custom.js.digest')
|
17
|
+
end
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
it 'will use :css option over default' do
|
20
|
+
expect(ettu.css_etag).to eq('custom.css.digest')
|
21
|
+
end
|
27
22
|
|
28
|
-
|
29
|
-
|
23
|
+
it 'will use :asset option over default' do
|
24
|
+
expect(ettu.asset_etags).to eq(['first.ext.digest'])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'will use :view option over default' do
|
28
|
+
expect(ettu.view_etag).to eq('custom/action.digest')
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
describe '.configure' do
|
33
|
+
subject(:ettu) { Ettu.new(nil, {}, controller) }
|
33
34
|
|
35
|
+
context 'when no options are specified' do
|
36
|
+
before(:all) do
|
37
|
+
Ettu.configure do |config|
|
38
|
+
config.js = 'custom.js'
|
39
|
+
config.css = 'custom.css'
|
40
|
+
config.assets = ['first.ext', 'second.ext']
|
41
|
+
config.view = 'custom/view'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
after(:all) { Ettu.configure { |config| config.reset } }
|
34
45
|
|
35
|
-
|
46
|
+
it 'will use the default js file' do
|
47
|
+
expect(ettu.js_etag).to eq('custom.js.digest')
|
48
|
+
end
|
36
49
|
|
50
|
+
it 'will use the default css file' do
|
51
|
+
expect(ettu.css_etag).to eq('custom.css.digest')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'will use the default asset files' do
|
55
|
+
expect(ettu.asset_etags).to eq(['first.ext.digest', 'second.ext.digest'])
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'will use the default view file' do
|
59
|
+
expect(ettu.view_etag).to eq('custom/view.digest')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when setting default to false' do
|
64
|
+
before(:all) do
|
65
|
+
Ettu.configure do |config|
|
66
|
+
config.js = false
|
67
|
+
config.css = false
|
68
|
+
config.view = false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
after(:all) { Ettu.configure { |config| config.reset } }
|
72
|
+
|
73
|
+
it 'will disable js etag' do
|
74
|
+
expect(ettu.js_etag).to eq(nil)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'will disable css etag' do
|
78
|
+
expect(ettu.css_etag).to eq(nil)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'will disable view etags' do
|
82
|
+
expect(ettu.view_etag).to eq(nil)
|
83
|
+
end
|
84
|
+
end
|
37
85
|
end
|
38
86
|
|
87
|
+
describe '#etags' do
|
88
|
+
let(:ettu) { Ettu.new(record, {}, controller) }
|
89
|
+
it 'will collect all etags' do
|
90
|
+
expected = [record, 'controller_name/action_name.digest', 'application.js.digest', 'application.css.digest']
|
91
|
+
result = ettu.etags
|
92
|
+
expect(ettu.etags).to include(*expected)
|
93
|
+
expect(expected).to include(*result)
|
94
|
+
end
|
95
|
+
end
|
39
96
|
|
40
97
|
context 'when given only a record' do
|
41
98
|
subject(:ettu) { Ettu.new(record) }
|
data/spec/fixtures.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class Nester < ActiveSupport::OrderedOptions
|
2
|
+
def initialize
|
3
|
+
super { |h, k| h[k] = Nester.new }
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class Controller < Nester
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
|
11
|
+
self.request.format['html?'] = true
|
12
|
+
self.controller_name = 'controller_name'
|
13
|
+
self.action_name = 'action_name'
|
14
|
+
end
|
15
|
+
|
16
|
+
def fresh_when(*args)
|
17
|
+
:old_fresh_when
|
18
|
+
end
|
19
|
+
|
20
|
+
include ::Ettu::FreshWhen
|
21
|
+
end
|
22
|
+
|
23
|
+
class Digestor
|
24
|
+
def self.method_missing(name, *args, &block)
|
25
|
+
args.first.to_s + '.digest'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Record
|
30
|
+
attr_accessor :updated_at
|
31
|
+
|
32
|
+
def initialize(updated_at)
|
33
|
+
@updated_at = updated_at
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Rails
|
38
|
+
def self.application
|
39
|
+
@nested ||= Nester.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
Rails.application.assets['application.js'].digest = 'application.js.digest'
|
43
|
+
Rails.application.assets['application.css'].digest = 'application.css.digest'
|
44
|
+
Rails.application.assets['custom.js'].digest = 'custom.js.digest'
|
45
|
+
Rails.application.assets['custom.css'].digest = 'custom.css.digest'
|
46
|
+
Rails.application.assets['first.ext'].digest = 'first.ext.digest'
|
47
|
+
Rails.application.assets['second.ext'].digest = 'second.ext.digest'
|
48
|
+
Rails.application.config.assets.digests = nil
|
49
|
+
|
data/spec/fresh_when_spec.rb
CHANGED
@@ -1,8 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
1
4
|
describe Ettu::FreshWhen do
|
2
|
-
|
3
|
-
|
5
|
+
before(:all) do
|
6
|
+
Ettu.configure { |config| config.template_digestor = Digestor }
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:ettu) { double }
|
10
|
+
let(:record) { Record.new(DateTime.now) }
|
11
|
+
let(:hash) { { random: true, options: true } }
|
12
|
+
subject(:controller) { Controller.new }
|
13
|
+
|
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
|
+
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
|
36
|
+
end
|
4
37
|
|
5
|
-
|
6
|
-
|
38
|
+
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
|
7
45
|
end
|
8
46
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,8 +5,14 @@
|
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
7
|
|
8
|
-
require 'ettu'
|
9
8
|
require 'date'
|
9
|
+
require 'active_support/ordered_options'
|
10
|
+
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start { add_filter '/spec/' }
|
13
|
+
|
14
|
+
require 'ettu'
|
15
|
+
require 'fixtures'
|
10
16
|
|
11
17
|
RSpec.configure do |config|
|
12
18
|
config.run_all_when_everything_filtered = true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ettu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
78
94
|
description: Account for js, css, and views when using ETags.
|
79
95
|
email:
|
80
96
|
- jridgewell@cloudspace.com
|
@@ -91,10 +107,12 @@ files:
|
|
91
107
|
- Rakefile
|
92
108
|
- ettu.gemspec
|
93
109
|
- lib/ettu.rb
|
110
|
+
- lib/ettu/configuration.rb
|
94
111
|
- lib/ettu/fresh_when.rb
|
95
112
|
- lib/ettu/railtie.rb
|
96
113
|
- lib/ettu/version.rb
|
97
114
|
- spec/ettu_spec.rb
|
115
|
+
- spec/fixtures.rb
|
98
116
|
- spec/fresh_when_spec.rb
|
99
117
|
- spec/spec_helper.rb
|
100
118
|
homepage: http://github.com/cloudspace/ettu
|
@@ -124,5 +142,6 @@ specification_version: 3
|
|
124
142
|
summary: Account for view code when using ETags.
|
125
143
|
test_files:
|
126
144
|
- spec/ettu_spec.rb
|
145
|
+
- spec/fixtures.rb
|
127
146
|
- spec/fresh_when_spec.rb
|
128
147
|
- spec/spec_helper.rb
|