diff options
author | Rémy Coutable <remy@rymai.me> | 2017-07-18 15:09:47 +0300 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2017-07-18 15:09:47 +0300 |
commit | f3e682c03fa84adea99d55ac74e32d53164cd99b (patch) | |
tree | 695c197151fe0ee2330db86328440fa6b390a49d /spec | |
parent | f48264555563a906472795bc9fbccd09be4b6a47 (diff) | |
parent | f69c0f801f3db8cc534bc9652fbdb01bb15a5340 (diff) |
Merge branch 'request-store-wrap' into 'master'
Add RequestCache to cache via RequestStore
See merge request !12920
Diffstat (limited to 'spec')
-rw-r--r-- | spec/factories/commits.rb | 9 | ||||
-rw-r--r-- | spec/features/participants_autocomplete_spec.rb | 3 | ||||
-rw-r--r-- | spec/lib/gitlab/cache/request_cache_spec.rb | 133 | ||||
-rw-r--r-- | spec/models/commit_spec.rb | 8 | ||||
-rw-r--r-- | spec/services/notification_service_spec.rb | 2 |
5 files changed, 146 insertions, 9 deletions
diff --git a/spec/factories/commits.rb b/spec/factories/commits.rb index 36b9645438a..89e260cf65b 100644 --- a/spec/factories/commits.rb +++ b/spec/factories/commits.rb @@ -4,14 +4,19 @@ FactoryGirl.define do factory :commit do git_commit RepoHelpers.sample_commit project factory: :empty_project - author { build(:author) } initialize_with do new(git_commit, project) end + after(:build) do |commit| + allow(commit).to receive(:author).and_return build(:author) + end + trait :without_author do - author nil + after(:build) do |commit| + allow(commit).to receive(:author).and_return nil + end end end end diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index 382d83ca051..81b0a2f541b 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -54,7 +54,8 @@ feature 'Member autocomplete', :js do let(:note) { create(:note_on_commit, project: project, commit_id: project.commit.id) } before do - allow_any_instance_of(Commit).to receive(:author).and_return(author) + allow(User).to receive(:find_by_any_email) + .with(noteable.author_email.downcase).and_return(author) visit project_commit_path(project, noteable) end diff --git a/spec/lib/gitlab/cache/request_cache_spec.rb b/spec/lib/gitlab/cache/request_cache_spec.rb new file mode 100644 index 00000000000..5b82c216a13 --- /dev/null +++ b/spec/lib/gitlab/cache/request_cache_spec.rb @@ -0,0 +1,133 @@ +require 'spec_helper' + +describe Gitlab::Cache::RequestCache do + let(:klass) do + Class.new do + extend Gitlab::Cache::RequestCache + + attr_accessor :id, :name, :result, :extra + + def self.name + 'ExpensiveAlgorithm' + end + + def initialize(id, name, result, extra = nil) + self.id = id + self.name = name + self.result = result + self.extra = nil + end + + request_cache def compute(arg) + result << arg + end + + request_cache def repute(arg) + result << arg + end + + def dispute(arg) + result << arg + end + request_cache(:dispute) { extra } + end + end + + let(:algorithm) { klass.new('id', 'name', []) } + + shared_examples 'cache for the same instance' do + it 'does not compute twice for the same argument' do + algorithm.compute(true) + result = algorithm.compute(true) + + expect(result).to eq([true]) + end + + it 'computes twice for the different argument' do + algorithm.compute(true) + result = algorithm.compute(false) + + expect(result).to eq([true, false]) + end + + it 'computes twice for the different class name' do + algorithm.compute(true) + allow(klass).to receive(:name).and_return('CheapAlgo') + result = algorithm.compute(true) + + expect(result).to eq([true, true]) + end + + it 'computes twice for the different method' do + algorithm.compute(true) + result = algorithm.repute(true) + + expect(result).to eq([true, true]) + end + + context 'when request_cache_key is provided' do + before do + klass.request_cache_key do + [id, name] + end + end + + it 'computes twice for the different keys, id' do + algorithm.compute(true) + algorithm.id = 'ad' + result = algorithm.compute(true) + + expect(result).to eq([true, true]) + end + + it 'computes twice for the different keys, name' do + algorithm.compute(true) + algorithm.name = 'same' + result = algorithm.compute(true) + + expect(result).to eq([true, true]) + end + + it 'uses extra method cache key if provided' do + algorithm.dispute(true) # miss + algorithm.extra = true + algorithm.dispute(true) # miss + result = algorithm.dispute(true) # hit + + expect(result).to eq([true, true]) + end + end + end + + context 'when RequestStore is active', :request_store do + it_behaves_like 'cache for the same instance' + + it 'computes once for different instances when keys are the same' do + algorithm.compute(true) + result = klass.new('id', 'name', algorithm.result).compute(true) + + expect(result).to eq([true]) + end + + it 'computes twice if RequestStore starts over' do + algorithm.compute(true) + RequestStore.end! + RequestStore.clear! + RequestStore.begin! + result = algorithm.compute(true) + + expect(result).to eq([true, true]) + end + end + + context 'when RequestStore is inactive' do + it_behaves_like 'cache for the same instance' + + it 'computes twice for different instances even if keys are the same' do + algorithm.compute(true) + result = klass.new('id', 'name', algorithm.result).compute(true) + + expect(result).to eq([true, true]) + end + end +end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 6056d78da4e..528b211c9d6 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -19,17 +19,15 @@ describe Commit, models: true do expect(commit.author).to eq(user) end - it 'caches the author' do - allow(RequestStore).to receive(:active?).and_return(true) + it 'caches the author', :request_store do user = create(:user, email: commit.author_email) - expect_any_instance_of(Commit).to receive(:find_author_by_any_email).and_call_original + expect(User).to receive(:find_by_any_email).and_call_original expect(commit.author).to eq(user) - key = "commit_author:#{commit.author_email}" + key = "Commit:author:#{commit.author_email.downcase}" expect(RequestStore.store[key]).to eq(user) expect(commit.author).to eq(user) - RequestStore.store.clear end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index f1e00c1163b..4fc5eb0a527 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -383,7 +383,7 @@ describe NotificationService, services: true do before do build_team(note.project) reset_delivered_emails! - allow_any_instance_of(Commit).to receive(:author).and_return(@u_committer) + allow(note.noteable).to receive(:author).and_return(@u_committer) update_custom_notification(:new_note, @u_guest_custom, resource: project) update_custom_notification(:new_note, @u_custom_global) end |