Skip to content

Commit a7de26f

Browse files
committed
Generate fixture mixin without accessors
Remove the accessor-dependent early return so the DSL RBI always records the Rails test mixin. Combine the no-fixture output and typechecking coverage, and clarify why the runtime `include` is otherwise missing.
1 parent d457ab8 commit a7de26f

3 files changed

Lines changed: 45 additions & 13 deletions

File tree

lib/tapioca/dsl/compilers/active_record_fixtures.rb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ module Compilers
3737
# ~~~
3838
#
3939
# The `include` is generated because Rails mixes `ActiveRecord::TestFixtures` into
40-
# `ActiveSupport::TestCase` from a `:active_support_test_case` load hook in `rails/test_help.rb`,
41-
# which is only required from an app's `test_helper.rb` and therefore never runs during RBI
42-
# generation. Without it, Sorbet does not see the class methods the module contributes via
43-
# `mixes_in_class_methods`, such as `fixtures`.
40+
# `ActiveSupport::TestCase` through the `:active_support_test_case` load hook in
41+
# `rails/test_help.rb`. Since RBI generation does not load an app's test helper, this runtime
42+
# include is not captured. Without it, Sorbet does not see the class methods the module
43+
# contributes via `mixes_in_class_methods`, such as `fixtures`.
4444
#: [ConstantType = singleton(ActiveSupport::TestCase)]
4545
class ActiveRecordFixtures < Compiler
4646
MISSING = Object.new
@@ -54,8 +54,6 @@ def decorate
5454
method_names_from_eager_fixture_loader
5555
end
5656

57-
return if method_names.empty?
58-
5957
method_names.select! { |name| fixture_class_mapping_from_fixture_files[name] != MISSING }
6058

6159
root.create_path(constant) do |mod|

manual/compiler_activerecordfixtures.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ end
2929
~~~
3030

3131
The `include` is generated because Rails mixes `ActiveRecord::TestFixtures` into
32-
`ActiveSupport::TestCase` from a `:active_support_test_case` load hook in `rails/test_help.rb`,
33-
which is only required from an app's `test_helper.rb` and therefore never runs during RBI
34-
generation. Without it, Sorbet does not see the class methods the module contributes via
35-
`mixes_in_class_methods`, such as `fixtures`.
32+
`ActiveSupport::TestCase` through the `:active_support_test_case` load hook in
33+
`rails/test_help.rb`. Since RBI generation does not load an app's test helper, this runtime
34+
include is not captured. Without it, Sorbet does not see the class methods the module
35+
contributes via `mixes_in_class_methods`, such as `fixtures`.

spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,42 @@ class User
4747
assert_equal(["ActiveSupport::TestCase"], gathered_constants)
4848
end
4949

50-
it "does nothing if there are no fixtures" do
50+
it "makes fixture class methods available when there are no fixtures" do
5151
expected = <<~RBI
5252
# typed: strong
53+
54+
class ActiveSupport::TestCase
55+
include ActiveRecord::TestFixtures
56+
end
5357
RBI
5458

55-
assert_equal(expected, rbi_for("ActiveSupport::TestCase"))
59+
generated_rbi = rbi_for("ActiveSupport::TestCase")
60+
dependencies_rbi = add_content_file("dependencies.rbi", <<~RBI)
61+
# typed: true
62+
63+
module ActiveRecord::TestFixtures
64+
mixes_in_class_methods ::ActiveRecord::TestFixtures::ClassMethods
65+
end
66+
67+
module ActiveRecord::TestFixtures::ClassMethods
68+
def fixtures(*fixture_set_names); end
69+
end
70+
71+
class ActiveSupport::TestCase; end
72+
RBI
73+
generated_rbi_file = add_content_file("generated.rbi", generated_rbi)
74+
test_file = add_content_file("test_case.rb", <<~RUBY)
75+
# typed: true
76+
77+
class PostTest < ActiveSupport::TestCase
78+
fixtures :all
79+
end
80+
RUBY
81+
82+
result = context.sorbet("--no-config", dependencies_rbi, generated_rbi_file, test_file)
83+
84+
assert(result.status, result.err)
85+
assert_equal(expected, generated_rbi)
5686
end
5787

5888
it "ignores fixtures that do not have an associated model" do
@@ -242,7 +272,7 @@ def posts(fixture_name = nil, *other_fixtures); end
242272
assert_equal(expected, rbi_for("ActiveSupport::TestCase"))
243273
end
244274

245-
it "generates no methods for file fixtures" do
275+
it "generates only the include for file fixtures" do
246276
add_content_file("test/fixtures/files/posts.yml", <<~YAML)
247277
super_post:
248278
title: An incredible Ruby post
@@ -253,6 +283,10 @@ def posts(fixture_name = nil, *other_fixtures); end
253283

254284
expected = <<~RBI
255285
# typed: strong
286+
287+
class ActiveSupport::TestCase
288+
include ActiveRecord::TestFixtures
289+
end
256290
RBI
257291

258292
assert_equal(expected, rbi_for("ActiveSupport::TestCase"))

0 commit comments

Comments
 (0)