Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
rubyconvict committed Apr 15, 2016
2 parents cbbca94 + 68a9ef6 commit 21dd381
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 1,172 deletions.
1,156 changes: 7 additions & 1,149 deletions .rubocop.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
cache_key_for (0.1.1)
cache_key_for (0.1.2)

GEM
remote: https://rubygems.org/
Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ It should be run as a gem and included in your `Gemfile`:
### \#cache_key_for

Features:
* locale
* pagination
* scoped collections
* ORM agnostic
* works with arrays and Plain Old Ruby Objects (POROs) (just provide: #id, #updated_at)
* supports locale
* recognizes subdomains
* deletion from and addition to collections sorted in ascending order (via embedded `count` in the key)
* accepts `cache_owner_cache_key` for personalized cache, eg. current_company.cache_key, current_user.cache_key etc.
* all params (including other than GET's query params) with proper non-utf8 data handling for key generation
* filters params with proper non-utf8 data handling for key generation
* recognizes pagination via params (performs well for less than 100 objects per page)
* includes all params, not only GET's `query` params, which enables submitting of complex forms via POST,
which - otherwise - would have query string longer than 2048 characters (Microsoft Internet Explorer)
* optional whitelist of first level parameters to prevent accidentally generating duplicated cache
* strips utm_* params
* optional suffix for:
* expiry tags (unlike :expires_in cache option, this offers full :file_store storage compatibility)
* any edge cases
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_4.1.0.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ../
specs:
cache_key_for (0.1.1)
cache_key_for (0.1.2)

GEM
remote: https://rubygems.org/
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/rails_4.2.0.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ../
specs:
cache_key_for (0.1.1)
cache_key_for (0.1.2)

GEM
remote: https://rubygems.org/
Expand Down
2 changes: 1 addition & 1 deletion lib/cache_key_for/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module CacheKeyFor
VERSION = '0.1.1'.freeze
VERSION = '0.1.2'.freeze
end
96 changes: 92 additions & 4 deletions spec/helpers/cache_key_for_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,122 @@ class ApplicationController < ActionController::Base
describe ApplicationController, :type => :helper do
# stub Rails.env.production?
let(:string_inquirer) { ActiveSupport::StringInquirer.new('production') }
let(:time_now) { Time.utc(2016,4,2,12,0).localtime('+05:30') }
let(:time_yesterday) { Time.utc(2016,4,1,12,0).localtime('+05:30') }
before(:each) do
allow(Rails).to receive(:env).and_return(string_inquirer)
allow(Time).to receive(:now).and_return(time_now)
end
describe "#cache_key_for" do
let(:record_template) { Struct.new(:id, :updated_at, :cache_key) }
let(:fake_record1) { record_template.new(1, Time.current - 1.day) }
let(:fake_record2) { record_template.new(1, Time.current) }
let(:fake_related_record) { record_template.new(1, Time.current, 'other_key') }
let(:fake_record1) { record_template.new(1, time_yesterday) }
let(:fake_record2) { record_template.new(1, time_now) }
let(:fake_related_record) { record_template.new(1, time_now, 'other_key') }
let(:scoped_collection) { [fake_record1, fake_record2] }
let(:collection_prefix) { 'fake_records' }
let(:cache_owner_cache_key) { fake_related_record.cache_key }
let(:suffix) { Time.now.utc.to_date.to_s }
let(:suffix) { time_now.utc.to_date.to_s }
let(:required_properties) { [scoped_collection, collection_prefix] }
let(:optional_properties) { [scoped_collection, collection_prefix, cache_owner_cache_key, suffix] }
# TODO: write deterministic test
context 'when `cache_owner_cache_key` and `suffix` are empty' do
subject { helper.cache_key_for(*required_properties) }
it { is_expected.to match(/\Aen\/fake_records\/([a-zA-Z0-9]+)\/\/\z/) }
end
# TODO: write deterministic test
context 'when `cache_owner_cache_key` and `suffix` are not empty' do
subject { helper.cache_key_for(*optional_properties) }
it { is_expected.to match(/\Aen\/fake_records\/([a-zA-Z0-9]+)\/other_key\/\d{,4}-\d{,2}-\d{,2}\z/) }
end
context 'when there are params' do
context 'when `whitelist_params` is empty' do
context 'when `request.params` do not include utm parameters' do
let(:request) { double('request', path: '/some-path', params: { a: '1', b: '1', c: [1, 2, 3] }, subdomains: ['www']) }
before { allow(helper).to receive(:request).and_return(request) }
subject do
helper.cache_key_for(*optional_properties)
end
it { is_expected.to eq('en/fake_records/90a09a166bd263f286bea1b830863af67549ef19/other_key/2016-04-02') }
end
context 'when `request.params` include utm parameters (key should not change)' do
let(:request) { double('request', path: '/some-path', params: { a: '1', b: '1', c: [1, 2, 3], utm_medium: 'cpc' }, subdomains: ['www']) }
before { allow(helper).to receive(:request).and_return(request) }
subject do
helper.cache_key_for(*optional_properties)
end
it { is_expected.to eq('en/fake_records/90a09a166bd263f286bea1b830863af67549ef19/other_key/2016-04-02') }
end
end
context 'when `whitelist_params` is not empty (key should change)' do
let(:whitelist_params) { [:c] }
let(:request) { double('request', path: '/some-path', params: { a: '1', b: '1', c: [1, 2, 3] }, subdomains: ['www']) }
before { allow(helper).to receive(:request).and_return(request) }
subject do
properties = optional_properties.push(whitelist_params)
helper.cache_key_for(*properties)
end
it { is_expected.to eq('en/fake_records/4d640ca8ea873c4dbacb9472ff2f4bf620c07c63/other_key/2016-04-02') }
end
end
context 'when params is empty' do
context 'when in time zone' do
let(:utc_offset) { '+05:30' }
let(:time_now) { Time.utc(2016, 4, 2, 12, 0).localtime(utc_offset) }
let(:time_yesterday) { Time.utc(2016, 4, 1, 12, 0).localtime(utc_offset) }
let(:fake_record1) { record_template.new(1, time_yesterday) }
let(:fake_record2) { record_template.new(1, time_now) }
let(:fake_related_record) { record_template.new(1, time_now, 'other_key') }
let(:scoped_collection) { [fake_record1, fake_record2] }
let(:cache_owner_cache_key) { fake_related_record.cache_key }
let(:suffix) { time_now.utc.to_date.to_s }
let(:optional_properties) { [scoped_collection, collection_prefix, cache_owner_cache_key, suffix] }
let(:request) { double('request', path: '/some-path', params: {}, subdomains: ['www']) }
before { allow(helper).to receive(:request).and_return(request) }
subject do
properties = optional_properties
helper.cache_key_for(*properties)
end
it { is_expected.to eq('en/fake_records/4d640ca8ea873c4dbacb9472ff2f4bf620c07c63/other_key/2016-04-02') }
end
context 'when in different time zone (key should not change)' do
let(:utc_offset) { '+02:00' }
let(:time_now) { Time.utc(2016, 4, 2, 12, 0).localtime(utc_offset) }
let(:time_yesterday) { Time.utc(2016, 4, 1, 12, 0).localtime(utc_offset) }
let(:fake_record1) { record_template.new(1, time_yesterday) }
let(:fake_record2) { record_template.new(1, time_now) }
let(:fake_related_record) { record_template.new(1, time_now, 'other_key') }
let(:scoped_collection) { [fake_record1, fake_record2] }
let(:cache_owner_cache_key) { fake_related_record.cache_key }
let(:suffix) { time_now.utc.to_date.to_s }
let(:optional_properties) { [scoped_collection, collection_prefix, cache_owner_cache_key, suffix] }
let(:request) { double('request', path: '/some-path', params: {}, subdomains: ['www']) }
before { allow(helper).to receive(:request).and_return(request) }
subject do
properties = optional_properties
helper.cache_key_for(*properties)
end
it { is_expected.to eq('en/fake_records/4d640ca8ea873c4dbacb9472ff2f4bf620c07c63/other_key/2016-04-02') }
end
end
end
end
=end
10 changes: 0 additions & 10 deletions spec/helpers/cache_key_for_view_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@
let(:required_properties) { [file, scoped_collection, collection_prefix] }
let(:optional_properties) { [file, scoped_collection, collection_prefix, cache_owner_cache_key, suffix] }
context 'when `cache_owner_cache_key` and `suffix` are empty' do
subject { helper.cache_key_for_view(*required_properties) }
it { is_expected.to match(/\Aen\/fake_records\/([a-zA-Z0-9]+)\/\/\/app\/views\/fake_records\/index\.html\.haml\z/) }
end
context 'when `cache_owner_cache_key` and `suffix` are not empty' do
subject { helper.cache_key_for_view(*optional_properties) }
it { is_expected.to match(/\Aen\/fake_records\/([a-zA-Z0-9]+)\/dbe13b0b975c7ce95665f019aa2ba0d77eb0f2c8\/\d{,4}-\d{,2}-\d{,2}\/app\/views\/fake_records\/index\.html\.haml\z/) }
end
context "when `cache_key_for_view` is used with a normal controller" do
before do
controller = double('controller', controller_path: 'some_controller', action_name: 'some_action')
Expand Down
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Configure Rails Envinronment
ENV['RAILS_ENV'] = 'test'

# FIXME: `<top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead.
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
SimpleCov::Formatter::HTMLFormatter,
CodeClimate::TestReporter::Formatter,
Expand Down
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
mocks.verify_partial_doubles = true
mocks.syntax = :expect
end
config.order = :random
config.order = :alphabetical #:random
config.infer_spec_type_from_file_location!
config.include ActionView::Helpers
# config.include ControllerHelpers, :type => :controller
Expand Down

0 comments on commit 21dd381

Please sign in to comment.