1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
describe "callbacks" do
before do
define_model("User", first_name: :string, last_name: :string)
FactoryBot.define do
factory :user_with_callbacks, class: :user do
after(:stub) { |user| user.first_name = "Stubby" }
after(:build) { |user| user.first_name = "Buildy" }
after(:create) { |user| user.last_name = "Createy" }
end
factory :user_with_inherited_callbacks, parent: :user_with_callbacks do
after(:stub) { |user| user.last_name = "Double-Stubby" }
after(:build) { |user| user.first_name = "Child-Buildy" }
end
end
end
it "runs the after(:stub) callback when stubbing" do
user = FactoryBot.build_stubbed(:user_with_callbacks)
expect(user.first_name).to eq "Stubby"
end
it "runs the after(:build) callback when building" do
user = FactoryBot.build(:user_with_callbacks)
expect(user.first_name).to eq "Buildy"
end
it "runs both the after(:build) and after(:create) callbacks when creating" do
user = FactoryBot.create(:user_with_callbacks)
expect(user.first_name).to eq "Buildy"
expect(user.last_name).to eq "Createy"
end
it "runs both the after(:stub) callback on the factory and the inherited after(:stub) callback" do
user = FactoryBot.build_stubbed(:user_with_inherited_callbacks)
expect(user.first_name).to eq "Stubby"
expect(user.last_name).to eq "Double-Stubby"
end
it "runs child callback after parent callback" do
user = FactoryBot.build(:user_with_inherited_callbacks)
expect(user.first_name).to eq "Child-Buildy"
end
end
describe "callbacks using Symbol#to_proc" do
before do
define_model("User") do
def confirmed?
!!@confirmed
end
def confirm!
@confirmed = true
end
end
FactoryBot.define do
factory :user do
after :build, &:confirm!
end
end
end
it "runs the callback correctly" do
user = FactoryBot.build(:user)
expect(user).to be_confirmed
end
end
describe "callbacks using syntax methods without referencing FactoryBot explicitly" do
before do
define_model("User", first_number: :integer, last_number: :integer)
FactoryBot.define do
sequence(:sequence_1)
sequence(:sequence_2)
sequence(:sequence_3)
factory :user do
after(:stub) { generate(:sequence_3) }
after(:build) { |user| user.first_number = generate(:sequence_1) }
after(:create) { |user, _evaluator| user.last_number = generate(:sequence_2) }
end
end
end
it "works when the callback has no variables" do
FactoryBot.build_stubbed(:user)
expect(FactoryBot.generate(:sequence_3)).to eq 2
end
it "works when the callback has one variable" do
expect(FactoryBot.build(:user).first_number).to eq 1
end
it "works when the callback has two variables" do
expect(FactoryBot.create(:user).last_number).to eq 1
end
end
describe "custom callbacks" do
let(:custom_before) do
Class.new do
def result(evaluation)
evaluation.object.tap do |instance|
evaluation.notify(:before_custom, instance)
end
end
end
end
let(:custom_after) do
Class.new do
def result(evaluation)
evaluation.object.tap do |instance|
evaluation.notify(:after_custom, instance)
end
end
end
end
let(:totally_custom) do
Class.new do
def result(evaluation)
evaluation.object.tap do |instance|
evaluation.notify(:totally_custom, instance)
end
end
end
end
before do
define_model("User", first_name: :string, last_name: :string) do
def name
[first_name, last_name].join(" ")
end
end
FactoryBot.register_strategy(:custom_before, custom_before)
FactoryBot.register_strategy(:custom_after, custom_after)
FactoryBot.register_strategy(:totally_custom, totally_custom)
FactoryBot.define do
factory :user do
first_name { "John" }
last_name { "Doe" }
before(:custom) { |instance| instance.first_name = "Overridden First" }
after(:custom) { |instance| instance.last_name = "Overridden Last" }
callback(:totally_custom) do |instance|
instance.first_name = "Totally"
instance.last_name = "Custom"
end
end
end
end
it "runs a custom before callback when the proper strategy executes" do
expect(FactoryBot.build(:user).name).to eq "John Doe"
expect(FactoryBot.custom_before(:user).name).to eq "Overridden First Doe"
end
it "runs a custom after callback when the proper strategy executes" do
expect(FactoryBot.build(:user).name).to eq "John Doe"
expect(FactoryBot.custom_after(:user).name).to eq "John Overridden Last"
end
it "runs a custom callback without prepending before or after when the proper strategy executes" do
expect(FactoryBot.build(:user).name).to eq "John Doe"
expect(FactoryBot.totally_custom(:user).name).to eq "Totally Custom"
end
end
describe "binding a callback to multiple callbacks" do
before do
define_model("User", name: :string)
FactoryBot.define do
factory :user do
callback(:before_create, :after_stub) do |instance|
instance.name = instance.name.upcase
end
end
end
end
it "binds the callback to creation" do
expect(FactoryBot.create(:user, name: "John Doe").name).to eq "JOHN DOE"
end
it "does not bind the callback to building" do
expect(FactoryBot.build(:user, name: "John Doe").name).to eq "John Doe"
end
it "binds the callback to stubbing" do
expect(FactoryBot.build_stubbed(:user, name: "John Doe").name).to eq "JOHN DOE"
end
end
describe "global callbacks" do
include FactoryBot::Syntax::Methods
before do
define_model("User", name: :string)
define_model("Company", name: :string)
FactoryBot.define do
after :build do |object|
object.name = case object.class.to_s
when "User" then "John Doe"
when "Company" then "Acme Suppliers"
end
end
after :create do |object|
object.name = "#{object.name}!!!"
end
trait :awesome do
after :build do |object|
object.name = "___#{object.name}___"
end
after :create do |object|
object.name = "A#{object.name}Z"
end
end
factory :user do
after :build do |user|
user.name = user.name.downcase
end
end
factory :company do
after :build do |company|
company.name = company.name.upcase
end
end
end
end
it "triggers after build callbacks for all factories" do
expect(build(:user).name).to eq "john doe"
expect(create(:user).name).to eq "john doe!!!"
expect(create(:user, :awesome).name).to eq "A___john doe___!!!Z"
expect(build(:company).name).to eq "ACME SUPPLIERS"
end
end
|