From 77a47741b108a07901b2c151aa67b46d440bc743 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Thu, 13 Jun 2024 11:24:09 -0400 Subject: [PATCH] Handle fixtures with no associated model --- .../dsl/compilers/active_record_fixtures.rb | 24 +++++++++---- .../compilers/active_record_fixtures_spec.rb | 34 +++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/tapioca/dsl/compilers/active_record_fixtures.rb b/lib/tapioca/dsl/compilers/active_record_fixtures.rb index 5443d7ec6..b52bcd9a0 100644 --- a/lib/tapioca/dsl/compilers/active_record_fixtures.rb +++ b/lib/tapioca/dsl/compilers/active_record_fixtures.rb @@ -40,12 +40,6 @@ class ActiveRecordFixtures < Compiler sig { override.void } def decorate - method_names = if fixture_loader.respond_to?(:fixture_sets) - method_names_from_lazy_fixture_loader - else - method_names_from_eager_fixture_loader - end - return if method_names.empty? root.create_path(constant) do |mod| @@ -68,6 +62,18 @@ def gather_constants private + sig { returns(T::Array[T.any(String, Symbol)]) } + def method_names + @method_names ||= T.let( + if fixture_loader.respond_to?(:fixture_sets) + method_names_from_lazy_fixture_loader + else + method_names_from_eager_fixture_loader + end, + T.nilable(T::Array[T.any(String, Symbol)]), + ) + end + sig { returns(T::Class[ActiveRecord::TestFixtures]) } def fixture_loader @fixture_loader ||= T.let( @@ -190,10 +196,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 + method_names.delete(T.must(fixture_name)) end end end diff --git a/spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb b/spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb index 51246fb97..fb9cacbe0 100644 --- a/spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb +++ b/spec/tapioca/dsl/compilers/active_record_fixtures_spec.rb @@ -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 + 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: