Use rspec-set to speed up examples
This commit is contained in:
parent
c7df97710b
commit
6f5b579f94
6 changed files with 58 additions and 34 deletions
1
Gemfile
1
Gemfile
|
@ -293,6 +293,7 @@ group :development, :test do
|
||||||
gem 'spinach-rails', '~> 0.2.1'
|
gem 'spinach-rails', '~> 0.2.1'
|
||||||
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
||||||
gem 'rspec_profiling', '~> 0.0.5'
|
gem 'rspec_profiling', '~> 0.0.5'
|
||||||
|
gem 'rspec-set', '~> 0.1.3'
|
||||||
|
|
||||||
# Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
|
# Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
|
||||||
gem 'minitest', '~> 5.7.0'
|
gem 'minitest', '~> 5.7.0'
|
||||||
|
|
|
@ -659,6 +659,7 @@ GEM
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-retry (0.4.5)
|
rspec-retry (0.4.5)
|
||||||
rspec-core
|
rspec-core
|
||||||
|
rspec-set (0.1.3)
|
||||||
rspec-support (3.5.0)
|
rspec-support (3.5.0)
|
||||||
rspec_profiling (0.0.5)
|
rspec_profiling (0.0.5)
|
||||||
activerecord
|
activerecord
|
||||||
|
@ -989,6 +990,7 @@ DEPENDENCIES
|
||||||
rqrcode-rails3 (~> 0.1.7)
|
rqrcode-rails3 (~> 0.1.7)
|
||||||
rspec-rails (~> 3.5.0)
|
rspec-rails (~> 3.5.0)
|
||||||
rspec-retry (~> 0.4.5)
|
rspec-retry (~> 0.4.5)
|
||||||
|
rspec-set (~> 0.1.3)
|
||||||
rspec_profiling (~> 0.0.5)
|
rspec_profiling (~> 0.0.5)
|
||||||
rubocop (~> 0.47.1)
|
rubocop (~> 0.47.1)
|
||||||
rubocop-rspec (~> 1.15.0)
|
rubocop-rspec (~> 1.15.0)
|
||||||
|
|
|
@ -202,6 +202,7 @@ Please consult the [dedicated "Frontend testing" guide](./fe_guide/testing.md).
|
||||||
- Try to follow the [Four-Phase Test][four-phase-test] pattern, using newlines
|
- Try to follow the [Four-Phase Test][four-phase-test] pattern, using newlines
|
||||||
to separate phases.
|
to separate phases.
|
||||||
- Try to use `Gitlab.config.gitlab.host` rather than hard coding `'localhost'`
|
- Try to use `Gitlab.config.gitlab.host` rather than hard coding `'localhost'`
|
||||||
|
- On `before` and `after` hooks, prefer it scoped to `:context` over `:all`
|
||||||
|
|
||||||
[four-phase-test]: https://robots.thoughtbot.com/four-phase-test
|
[four-phase-test]: https://robots.thoughtbot.com/four-phase-test
|
||||||
|
|
||||||
|
@ -225,6 +226,20 @@ so we need to set some guidelines for their use going forward:
|
||||||
|
|
||||||
[lets-not]: https://robots.thoughtbot.com/lets-not
|
[lets-not]: https://robots.thoughtbot.com/lets-not
|
||||||
|
|
||||||
|
#### `set` variables
|
||||||
|
|
||||||
|
In some cases there is no need to recreate the same object for tests again for
|
||||||
|
each example. For example, a project is needed to test issues on the same
|
||||||
|
project, one project will do for the entire file. This can be achieved by using
|
||||||
|
`set` in the same way you would use `let`.
|
||||||
|
|
||||||
|
`rspec-set` only works on ActiveRecord objects, and before new examples it
|
||||||
|
reloads or recreates the model, _only_ if needed. That is, when you changed
|
||||||
|
properties or destroyed the object.
|
||||||
|
|
||||||
|
There is one gotcha; you can't reference a model defined in a `let` block in a
|
||||||
|
`set` block.
|
||||||
|
|
||||||
### Time-sensitive tests
|
### Time-sensitive tests
|
||||||
|
|
||||||
[Timecop](https://github.com/travisjeffery/timecop) is available in our
|
[Timecop](https://github.com/travisjeffery/timecop) is available in our
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe IssuesFinder do
|
describe IssuesFinder do
|
||||||
let(:user) { create(:user) }
|
set(:user) { create(:user) }
|
||||||
let(:user2) { create(:user) }
|
set(:user2) { create(:user) }
|
||||||
let(:project1) { create(:empty_project) }
|
set(:project1) { create(:empty_project) }
|
||||||
let(:project2) { create(:empty_project) }
|
set(:project2) { create(:empty_project) }
|
||||||
let(:milestone) { create(:milestone, project: project1) }
|
set(:milestone) { create(:milestone, project: project1) }
|
||||||
let(:label) { create(:label, project: project2) }
|
set(:label) { create(:label, project: project2) }
|
||||||
let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone, title: 'gitlab') }
|
set(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone, title: 'gitlab') }
|
||||||
let(:issue2) { create(:issue, author: user, assignee: user, project: project2, description: 'gitlab') }
|
set(:issue2) { create(:issue, author: user, assignee: user, project: project2, description: 'gitlab') }
|
||||||
let(:issue3) { create(:issue, author: user2, assignee: user2, project: project2, title: 'tanuki', description: 'tanuki') }
|
set(:issue3) { create(:issue, author: user2, assignee: user2, project: project2, title: 'tanuki', description: 'tanuki') }
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
let(:closed_issue) { create(:issue, author: user2, assignee: user2, project: project2, state: 'closed') }
|
set(:closed_issue) { create(:issue, author: user2, assignee: user2, project: project2, state: 'closed') }
|
||||||
let!(:label_link) { create(:label_link, label: label, target: issue2) }
|
set(:label_link) { create(:label_link, label: label, target: issue2) }
|
||||||
let(:search_user) { user }
|
let(:search_user) { user }
|
||||||
let(:params) { {} }
|
let(:params) { {} }
|
||||||
let(:issues) { IssuesFinder.new(search_user, params.reverse_merge(scope: scope, state: 'opened')).execute }
|
let(:issues) { IssuesFinder.new(search_user, params.reverse_merge(scope: scope, state: 'opened')).execute }
|
||||||
|
|
||||||
before do
|
before(:context) do
|
||||||
project1.team << [user, :master]
|
project1.team << [user, :master]
|
||||||
project2.team << [user, :developer]
|
project2.team << [user, :developer]
|
||||||
project2.team << [user2, :developer]
|
project2.team << [user2, :developer]
|
||||||
|
|
|
@ -3,14 +3,17 @@ require 'spec_helper'
|
||||||
describe API::Issues do
|
describe API::Issues do
|
||||||
include EmailHelpers
|
include EmailHelpers
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
set(:user) { create(:user) }
|
||||||
|
set(:project) do
|
||||||
|
create(:empty_project, :public, creator_id: user.id, namespace: user.namespace)
|
||||||
|
end
|
||||||
|
|
||||||
let(:user2) { create(:user) }
|
let(:user2) { create(:user) }
|
||||||
let(:non_member) { create(:user) }
|
let(:non_member) { create(:user) }
|
||||||
let(:guest) { create(:user) }
|
set(:guest) { create(:user) }
|
||||||
let(:author) { create(:author) }
|
set(:author) { create(:author) }
|
||||||
let(:assignee) { create(:assignee) }
|
set(:assignee) { create(:assignee) }
|
||||||
let(:admin) { create(:user, :admin) }
|
let(:admin) { create(:user, :admin) }
|
||||||
let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) }
|
|
||||||
let(:issue_title) { 'foo' }
|
let(:issue_title) { 'foo' }
|
||||||
let(:issue_description) { 'closed' }
|
let(:issue_description) { 'closed' }
|
||||||
let!(:closed_issue) do
|
let!(:closed_issue) do
|
||||||
|
@ -43,19 +46,19 @@ describe API::Issues do
|
||||||
title: issue_title,
|
title: issue_title,
|
||||||
description: issue_description
|
description: issue_description
|
||||||
end
|
end
|
||||||
let!(:label) do
|
set(:label) do
|
||||||
create(:label, title: 'label', color: '#FFAABB', project: project)
|
create(:label, title: 'label', color: '#FFAABB', project: project)
|
||||||
end
|
end
|
||||||
let!(:label_link) { create(:label_link, label: label, target: issue) }
|
let!(:label_link) { create(:label_link, label: label, target: issue) }
|
||||||
let!(:milestone) { create(:milestone, title: '1.0.0', project: project) }
|
set(:milestone) { create(:milestone, title: '1.0.0', project: project) }
|
||||||
let!(:empty_milestone) do
|
set(:empty_milestone) do
|
||||||
create(:milestone, title: '2.0.0', project: project)
|
create(:milestone, title: '2.0.0', project: project)
|
||||||
end
|
end
|
||||||
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
|
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
|
||||||
|
|
||||||
let(:no_milestone_title) { URI.escape(Milestone::None.title) }
|
let(:no_milestone_title) { URI.escape(Milestone::None.title) }
|
||||||
|
|
||||||
before do
|
before(:all) do
|
||||||
project.team << [user, :reporter]
|
project.team << [user, :reporter]
|
||||||
project.team << [guest, :guest]
|
project.team << [guest, :guest]
|
||||||
end
|
end
|
||||||
|
@ -70,6 +73,8 @@ describe API::Issues do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when authenticated" do
|
context "when authenticated" do
|
||||||
|
let(:first_issue) { json_response.first }
|
||||||
|
|
||||||
it "returns an array of issues" do
|
it "returns an array of issues" do
|
||||||
get api("/issues", user)
|
get api("/issues", user)
|
||||||
|
|
||||||
|
@ -79,46 +84,46 @@ describe API::Issues do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of closed issues' do
|
it 'returns an array of closed issues' do
|
||||||
get api('/issues?state=closed', user)
|
get api('/issues', user), state: :closed
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['id']).to eq(closed_issue.id)
|
expect(first_issue['id']).to eq(closed_issue.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of opened issues' do
|
it 'returns an array of opened issues' do
|
||||||
get api('/issues?state=opened', user)
|
get api('/issues', user), state: :opened
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['id']).to eq(issue.id)
|
expect(first_issue['id']).to eq(issue.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of all issues' do
|
it 'returns an array of all issues' do
|
||||||
get api('/issues?state=all', user)
|
get api('/issues', user), state: :all
|
||||||
|
|
||||||
expect_paginated_array_response(size: 2)
|
expect_paginated_array_response(size: 2)
|
||||||
expect(json_response.first['id']).to eq(issue.id)
|
expect(first_issue['id']).to eq(issue.id)
|
||||||
expect(json_response.second['id']).to eq(closed_issue.id)
|
expect(json_response.second['id']).to eq(closed_issue.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns issues matching given search string for title' do
|
it 'returns issues matching given search string for title' do
|
||||||
get api("/issues?search=#{issue.title}", user)
|
get api("/issues", user), search: issue.title
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['id']).to eq(issue.id)
|
expect(json_response.first['id']).to eq(issue.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns issues matching given search string for description' do
|
it 'returns issues matching given search string for description' do
|
||||||
get api("/issues?search=#{issue.description}", user)
|
get api("/issues", user), search: issue.description
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['id']).to eq(issue.id)
|
expect(first_issue['id']).to eq(issue.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of labeled issues' do
|
it 'returns an array of labeled issues' do
|
||||||
get api("/issues?labels=#{label.title}", user)
|
get api("/issues", user), labels: label.title
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['labels']).to eq([label.title])
|
expect(first_issue['labels']).to eq([label.title])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of labeled issues when all labels matches' do
|
it 'returns an array of labeled issues when all labels matches' do
|
||||||
|
@ -135,13 +140,13 @@ describe API::Issues do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an empty array if no issue matches labels' do
|
it 'returns an empty array if no issue matches labels' do
|
||||||
get api('/issues?labels=foo,bar', user)
|
get api('/issues', user), labels: 'foo,bar'
|
||||||
|
|
||||||
expect_paginated_array_response(size: 0)
|
expect_paginated_array_response(size: 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an array of labeled issues matching given state' do
|
it 'returns an array of labeled issues matching given state' do
|
||||||
get api("/issues?labels=#{label.title}&state=opened", user)
|
get api("/issues", user), labels: label.title, state: :opened
|
||||||
|
|
||||||
expect_paginated_array_response(size: 1)
|
expect_paginated_array_response(size: 1)
|
||||||
expect(json_response.first['labels']).to eq([label.title])
|
expect(json_response.first['labels']).to eq([label.title])
|
||||||
|
|
|
@ -26,6 +26,7 @@ describe API::MergeRequests do
|
||||||
context "when unauthenticated" do
|
context "when unauthenticated" do
|
||||||
it "returns authentication error" do
|
it "returns authentication error" do
|
||||||
get api("/projects/#{project.id}/merge_requests")
|
get api("/projects/#{project.id}/merge_requests")
|
||||||
|
|
||||||
expect(response).to have_http_status(401)
|
expect(response).to have_http_status(401)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue