Skip to content

Commit a1cce60

Browse files
committed
Add unit tests for FactoryBot::Linter
Add spec coverage for the Linter class which previously had no corresponding unit test file. Tests cover valid/invalid factory linting, error message formatting, FactoryError and FactoryTraitError message formatting including verbose backtrace.
1 parent 26f3680 commit a1cce60

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

spec/factory_bot/linter_spec.rb

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
describe FactoryBot::Linter do
2+
describe "#lint!" do
3+
it "does not raise when all factories are valid" do
4+
define_class("User") { attr_accessor :name }
5+
FactoryBot.define do
6+
factory :linter_user, class: "User" do
7+
name { "Test" }
8+
end
9+
end
10+
11+
factories = FactoryBot.factories.select { |f| f.name == :linter_user }
12+
linter = described_class.new(factories, strategy: :build)
13+
14+
expect { linter.lint! }.not_to raise_error
15+
end
16+
17+
it "raises InvalidFactoryError when a factory is invalid" do
18+
define_class("LinterFailModel") {
19+
def save!
20+
raise "validation failed"
21+
end
22+
}
23+
FactoryBot.define do
24+
factory :linter_fail_model, class: "LinterFailModel"
25+
end
26+
27+
factories = FactoryBot.factories.select { |f| f.name == :linter_fail_model }
28+
linter = described_class.new(factories, strategy: :create)
29+
30+
expect { linter.lint! }.to raise_error(FactoryBot::InvalidFactoryError)
31+
end
32+
33+
it "includes factory name in error message" do
34+
define_class("LinterBadModel") {
35+
def save!
36+
raise "cannot save"
37+
end
38+
}
39+
FactoryBot.define do
40+
factory :linter_bad_model, class: "LinterBadModel"
41+
end
42+
43+
factories = FactoryBot.factories.select { |f| f.name == :linter_bad_model }
44+
linter = described_class.new(factories, strategy: :create)
45+
46+
expect { linter.lint! }.to raise_error(/linter_bad_model/)
47+
end
48+
end
49+
50+
describe described_class::FactoryError do
51+
it "formats error message with factory name and error details" do
52+
wrapped_error = RuntimeError.new("something went wrong")
53+
factory = double("factory", name: :user)
54+
error = described_class.new(wrapped_error, factory)
55+
56+
expect(error.message).to include("user")
57+
expect(error.message).to include("something went wrong")
58+
expect(error.message).to include("RuntimeError")
59+
end
60+
61+
it "includes backtrace in verbose message" do
62+
wrapped_error = RuntimeError.new("something went wrong")
63+
wrapped_error.set_backtrace(["line1.rb:1", "line2.rb:2"])
64+
factory = double("factory", name: :user)
65+
error = described_class.new(wrapped_error, factory)
66+
67+
expect(error.verbose_message).to include("line1.rb:1")
68+
expect(error.verbose_message).to include("line2.rb:2")
69+
end
70+
end
71+
72+
describe described_class::FactoryTraitError do
73+
it "includes factory and trait name in location" do
74+
wrapped_error = RuntimeError.new("trait error")
75+
factory = double("factory", name: :user)
76+
error = described_class.new(wrapped_error, factory, :admin)
77+
78+
expect(error.message).to include("user+admin")
79+
end
80+
end
81+
end

0 commit comments

Comments
 (0)