Introduce rspec helper to improve performance

Use `shared_association_default` to create default values to be used for
factory associations in rspec. They get created only once.

For instance, when creating work packages with `create(:work_package)`,
a new user gets created for each create work package. To reuse the same
user for all created work packages, add this in your example group:

    shared_association_default(:user) { create(:user) }
pull/10878/head
Christophe Bliard 2 years ago
parent 74494e2c8c
commit c0132aabca
No known key found for this signature in database
GPG Key ID: 2BC07603210C3FA4
  1. 14
      spec/services/work_packages/schedule_dependency/dependency_spec.rb
  2. 15
      spec/services/work_packages/set_schedule_service_spec.rb
  3. 32
      spec/support/shared_let.rb

@ -36,9 +36,9 @@ require 'rails_helper'
RSpec.describe WorkPackages::ScheduleDependency::Dependency do
subject(:dependency) { dependency_for(work_package_used_in_dependency) }
shared_let(:author) { create(:user, firstname: 'Dummy user to reduce number of created users') }
shared_let(:project) { create(:project_with_types, name: 'Dummy project to reduce number of created projects') }
shared_let(:work_package) { create(:work_package, subject: 'moved', author:, project:) }
create_shared_association_defaults_for_work_package_factory
shared_let(:work_package) { create(:work_package, subject: 'moved') }
let(:schedule_dependency) { WorkPackages::ScheduleDependency.new(work_package) }
@ -54,25 +54,25 @@ RSpec.describe WorkPackages::ScheduleDependency::Dependency do
end
def create_predecessor_of(work_package, **attributes)
create(:work_package, subject: "predecessor of #{work_package.subject}", author:, project:, **attributes).tap do |predecessor|
create(:work_package, subject: "predecessor of #{work_package.subject}", **attributes).tap do |predecessor|
create(:follows_relation, from: work_package, to: predecessor)
end
end
def create_follower_of(work_package)
create(:work_package, subject: "follower of #{work_package.subject}", author:, project:).tap do |follower|
create(:work_package, subject: "follower of #{work_package.subject}").tap do |follower|
create(:follows_relation, from: follower, to: work_package)
end
end
def create_parent_of(work_package)
create(:work_package, subject: "parent of #{work_package.subject}", author:, project:).tap do |parent|
create(:work_package, subject: "parent of #{work_package.subject}").tap do |parent|
work_package.update(parent:)
end
end
def create_child_of(work_package)
create(:work_package, subject: "child of #{work_package.subject}", author:, project:, parent: work_package)
create(:work_package, subject: "child of #{work_package.subject}", parent: work_package)
end
describe '#dependent_ids' do

@ -29,14 +29,11 @@
require 'spec_helper'
describe WorkPackages::SetScheduleService do
shared_let(:project) { create(:project) }
shared_let(:user) { create(:user) }
shared_let(:type) { create(:type) }
create_shared_association_defaults_for_work_package_factory
let(:work_package) do
create(:work_package,
subject: 'subject',
project:,
start_date: work_package_start_date,
due_date: work_package_due_date)
end
@ -98,12 +95,9 @@ describe WorkPackages::SetScheduleService do
def create_follower(start_date, due_date, predecessors, parent: nil)
work_package = create(:work_package,
subject: "follower of #{predecessors.keys.map(&:subject).to_sentence}",
type:,
start_date:,
due_date:,
parent:,
project:,
author: user)
parent:)
predecessors.map do |predecessor, delay|
create(:follows_relation,
@ -311,7 +305,6 @@ describe WorkPackages::SetScheduleService do
context 'when moving backwards with the follower having another relation limiting movement' do
let!(:other_work_package) do
create(:work_package,
type:,
start_date: follower1_start_date - 8.days,
due_date: follower1_start_date - 5.days).tap do |wp|
create(:follows_relation,
@ -627,9 +620,6 @@ describe WorkPackages::SetScheduleService do
context 'when moving backwards with the parent having another relation limiting movement' do
let!(:other_work_package) do
create(:work_package,
type:,
project:,
author: user,
start_date: Time.zone.today - 8.days,
due_date: Time.zone.today - 4.days).tap do |wp|
create(:follows_relation,
@ -654,7 +644,6 @@ describe WorkPackages::SetScheduleService do
context 'when moving backwards with the parent having another relation not limiting movement' do
let(:other_work_package) do
create(:work_package,
type:,
start_date: Time.zone.today - 10.days,
due_date: Time.zone.today - 9.days)
end

@ -33,7 +33,7 @@
# and the creation is rolled back in an after_all hook.
#
# Caveats: Set +reload: true+ if you plan to modify this value, otherwise Rails may still
# have cached the local value. This will perform a database update, but is much faster
# have cached the local value. This will perform a database select, but is much faster
# than creating new records (especially, work packages).
#
# Since test-prof added `let_it_be` this is only a wrapper for it
@ -41,3 +41,33 @@
def shared_let(key, reload: true, refind: false, &block)
let_it_be(key, reload:, refind:, &block)
end
# Defines an object to be used by default for all FactoryBot association
# matching they key name.
#
# The object is created only once in the example group, and reused for each
# example. Under the hood, it uses +let_it_be+ and +FactoryDefault+ from the
# test_prof gem.
#
# For instance, when creating work packages with +create(:work_package)+, a new
# user gets created for each create work package. To reuse the same user for all
# created work packages, in your example group add:
#
# shared_association_default(:user) { create(:user) }
#
def shared_association_default(key, factory_name: key, &block)
# unique let identifier to prevent clashes
let_it_be(key, reload: true, &block)
before do
set_factory_default(factory_name, send(key))
end
end
# Use this to boost performance in tests creating lots of work packages.
def create_shared_association_defaults_for_work_package_factory
shared_association_default(:priority) { create(:priority) }
shared_association_default(:project_with_types) { create(:project_with_types) }
shared_association_default(:status) { create(:status) }
shared_association_default(:user) { create(:user) }
end

Loading…
Cancel
Save