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 CHANGED
@@ -1,2 +1 @@
1
1
  --color
2
- --profile
data/ettu.gemspec CHANGED
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'bundler', '~> 1.3'
23
23
  spec.add_development_dependency 'rake'
24
24
  spec.add_development_dependency 'rspec'
25
+ spec.add_development_dependency 'simplecov'
25
26
  end
@@ -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
@@ -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 = Ettu.new(record_or_options, additional_options, self)
8
+ def fresh_when(record_or_options, additional_options)
9
+ ettu = ettu_instance(record_or_options, additional_options, self)
10
10
 
11
- etags = [*ettu.response_etag]
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
@@ -1,3 +1,3 @@
1
1
  class Ettu
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
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 = ActiveSupport::OrderedOptions.new
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 response_etag
42
- @options.fetch(:etag, @record)
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
- @view_etag ||= view_digest
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
- "#{@controller.controller_name}/#{@controller.action_name}",
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
- Record = Struct.new(:updated_at)
4
- Nested = Struct.new(:nil) do
5
- def [](name)
6
- nil
7
- end
8
- def method_missing(name, *args, &block)
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
- def self.application
16
- Nested.new(nil)
17
- end
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
- describe Ettu do
21
- let(:record) { Record.new(DateTime.now) }
22
- let(:hash) { { etag: record, last_modified: DateTime.now, public: false, random: true } }
15
+ it 'will use :js option over default' do
16
+ expect(ettu.js_etag).to eq('custom.js.digest')
17
+ end
23
18
 
24
- context 'when supplied with :js option' do
25
- xit "returns hash[:js]'s fingerprint as #js_etag"
26
- end
19
+ it 'will use :css option over default' do
20
+ expect(ettu.css_etag).to eq('custom.css.digest')
21
+ end
27
22
 
28
- context 'when supplied with :css option' do
29
- xit "returns hash[:css]'s fingerprint as #css_etag"
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
- xit '#view_etag'
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
- context '.configure' do
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
+
@@ -1,8 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+
1
4
  describe Ettu::FreshWhen do
2
- context 'when given extra options' do
3
- subject(:ettu) { Ettu.new(record) }
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
- it "passes those options to Rails' fresh_when"
6
- it "calls #old_fresh_when"
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.5
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