Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle fixtures with no associated model #1921

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions lib/tapioca/dsl/compilers/active_record_fixtures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ActiveRecordFixtures < Compiler
extend T::Sig

ConstantType = type_member { { fixed: T.class_of(ActiveSupport::TestCase) } }
MISSING = Object.new

sig { override.void }
def decorate
Expand All @@ -46,6 +47,7 @@ def decorate
method_names_from_eager_fixture_loader
end

method_names.select! { |name| fixture_class_mapping_from_fixture_files[name] != MISSING }
return if method_names.empty?

root.create_path(constant) do |mod|
Expand Down Expand Up @@ -96,15 +98,14 @@ def method_names_from_lazy_fixture_loader
T.unsafe(fixture_loader).fixture_sets.keys
end

sig { returns(T::Array[Symbol]) }
sig { returns(T::Array[String]) }
def method_names_from_eager_fixture_loader
fixture_loader.ancestors # get all ancestors from class that includes AR fixtures
.drop(1) # drop the anonymous class itself from the array
.reject(&:name) # only collect anonymous ancestors because fixture methods are always on an anonymous module
.map! do |mod|
[mod.private_instance_methods(false), mod.instance_methods(false)]
.flat_map do |mod|
mod.private_instance_methods(false).map(&:to_s) + mod.instance_methods(false).map(&:to_s)
end
.flatten # merge methods into a single list
end

sig { params(mod: RBI::Scope, name: String).void }
Expand Down Expand Up @@ -190,10 +191,14 @@ def fixture_class_mapping_from_fixture_files
next unless ::File.file?(file)

ActiveRecord::FixtureSet::File.open(file) do |fh|
fixture_name = file.delete_prefix(path.to_s).delete_prefix("/").delete_suffix(".yml")
next unless fh.model_class

fixture_name = file.delete_prefix(path.to_s).delete_prefix("/").delete_suffix(".yml")
mapping[fixture_name] = fh.model_class
rescue ActiveRecord::Fixture::FormatError
# For fixtures that are not associated to any models and just contain raw data or fixtures that
# contain invalid formatting, we want to skip them and avoid crashing
mapping[fixture_name] = MISSING
end
end
end
Expand Down
34 changes: 34 additions & 0 deletions spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,40 @@ class User
assert_equal(expected, rbi_for("ActiveSupport::TestCase"))
end

it "ignores fixtures that do not have an associated model" do
add_content_file("test/fixtures/serialized_data.yml", <<~YAML)
---
field1: 123
name: Hello
YAML

add_content_file("test/fixtures/posts.yml", <<~YAML)
super_post:
title: An incredible Ruby post
author: Johnny Developer
vinistock marked this conversation as resolved.
Show resolved Hide resolved
created_at: 2021-09-08 11:00:00
updated_at: 2021-09-08 11:00:00
YAML

add_ruby_file("test_models.rb", <<~RUBY)
class Post < ActiveRecord::Base
end
RUBY

expected = <<~RBI
# typed: strong

class ActiveSupport::TestCase
sig { params(fixture_name: NilClass, other_fixtures: NilClass).returns(T::Array[Post]) }
sig { params(fixture_name: T.any(String, Symbol), other_fixtures: NilClass).returns(Post) }
sig { params(fixture_name: T.any(String, Symbol), other_fixtures: T.any(String, Symbol)).returns(T::Array[Post]) }
def posts(fixture_name = nil, *other_fixtures); end
end
RBI

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

it "generates methods for fixtures" do
add_content_file("test/fixtures/posts.yml", <<~YAML)
super_post:
Expand Down
Loading