diff --git a/actionmailer/lib/action_mailer/test_case.rb b/actionmailer/lib/action_mailer/test_case.rb
index 97afd87840e5b..1a07d8e79242e 100644
--- a/actionmailer/lib/action_mailer/test_case.rb
+++ b/actionmailer/lib/action_mailer/test_case.rb
@@ -74,6 +74,15 @@ def determine_default_mailer(name)
end
end
+ # Reads the fixture file for the given mailer.
+ #
+ # This is useful when testing mailers by being able to write the body of
+ # an email inside a fixture. See the testing guide for a concrete example:
+ # https://guides.rubyonrails.org/testing.html#revenge-of-the-fixtures
+ def read_fixture(action)
+ IO.readlines(File.join(Rails.root, "test", "fixtures", self.class.mailer_class.name.underscore, action))
+ end
+
private
def initialize_test_deliveries
set_delivery_method :test
@@ -110,10 +119,6 @@ def charset
def encode(subject)
Mail::Encodings.q_value_encode(subject, charset)
end
-
- def read_fixture(action)
- IO.readlines(File.join(Rails.root, "test", "fixtures", self.class.mailer_class.name.underscore, action))
- end
end
include Behavior
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 444d95a6b3627..69b2181fd4a3f 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -19,10 +19,13 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
#
# \Fixtures are a way of organizing data that you want to test against; in short, sample data.
#
- # They are stored in YAML files, one file per model, which are placed in the directories
- # appointed by ActiveSupport::TestCase.fixture_paths=(path) (this is automatically
- # configured for Rails, so you can just put your files in /test/fixtures/,
- # or in the test/fixtures folder under any of your application's engines).
+ # They are stored in YAML files, one file per model, which are by default placed in either
+ # /test/fixtures/ or in the test/fixtures
+ # folder under any of your application's engines.
+ #
+ # The location can also be changed with ActiveSupport::TestCase.fixture_paths=,
+ # once you have require "rails/test_help" in your +test_helper.rb+.
+ #
# The fixture file ends with the +.yml+ file extension, for example:
# /test/fixtures/web_sites.yml).
#
@@ -42,10 +45,17 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# is followed by an indented list of key/value pairs in the "key: value" format. Records are
# separated by a blank line for your viewing pleasure.
#
- # Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
- # See https://yaml.org/type/omap.html
- # for the specification. You will need ordered fixtures when you have foreign key constraints
- # on keys in the same table. This is commonly needed for tree structures. Example:
+ # == Ordering
+ #
+ # Fixtures by default are unordered. This is because the maps in YAML are unordered.
+ #
+ # If you want ordered fixtures, use the omap YAML type.
+ # See https://yaml.org/type/omap.html for the specification.
+ #
+ # You will need ordered fixtures when you have foreign key constraints
+ # on keys in the same table. This is commonly needed for tree structures.
+ #
+ # For example:
#
# --- !omap
# - parent:
@@ -57,7 +67,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# parent_id: 1
# title: Child
#
- # = Using Fixtures in Test Cases
+ # == Using Fixtures in Test Cases
#
# Since fixtures are a testing construct, we use them in our unit and functional tests. There
# are two ways to use the fixtures, but first let's take a look at a sample unit test:
@@ -127,7 +137,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# traversed in the database to create the fixture hash and/or instance variables. This is expensive for
# large sets of fixtured data.
#
- # = Dynamic fixtures with ERB
+ # == Dynamic fixtures with \ERB
#
# Sometimes you don't care about the content of the fixtures as much as you care about the volume.
# In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
@@ -165,7 +175,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# name: kitten.png
# sha: <%= file_sha 'files/kitten.png' %>
#
- # = Transactional Tests
+ # == Transactional Tests
#
# Test cases can use begin+rollback to isolate their changes to the database instead of having to
# delete+insert for every test case.
@@ -201,7 +211,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
# Use InnoDB, MaxDB, or NDB instead.
#
- # = Advanced Fixtures
+ # == Advanced Fixtures
#
# Fixtures that don't specify an ID get some extra features:
#
@@ -215,7 +225,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# * Fixture label interpolation
# * Support for YAML defaults
#
- # == Stable, Autogenerated IDs
+ # === Stable, Autogenerated IDs
#
# Here, have a monkey fixture:
#
@@ -244,13 +254,13 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# The generated ID for a given label is constant, so we can discover
# any fixture's ID without loading anything, as long as we know the label.
#
- # == Label references for associations (+belongs_to+, +has_one+, +has_many+)
+ # === Label references for associations (+belongs_to+, +has_one+, +has_many+)
#
# Specifying foreign keys in fixtures can be very fragile, not to
# mention difficult to read. Since Active Record can figure out the ID of
# any fixture from its label, you can specify FK's by label instead of ID.
#
- # === +belongs_to+
+ # ==== +belongs_to+
#
# Let's break out some more monkeys and pirates.
#
@@ -314,9 +324,9 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
#
# Just provide the polymorphic target type and Active Record will take care of the rest.
#
- # === +has_and_belongs_to_many+ or has_many :through
+ # ==== +has_and_belongs_to_many+ or has_many :through
#
- # Time to give our monkey some fruit.
+ # \Time to give our monkey some fruit.
#
# ### in monkeys.yml
#
@@ -378,7 +388,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
# the fixture's model class and discovers the +has_and_belongs_to_many+
# associations.
#
- # == Autofilled Timestamp Columns
+ # === Autofilled \Timestamp Columns
#
# If your table/model specifies any of Active Record's
# standard timestamp columns (+created_at+, +created_on+, +updated_at+, +updated_on+),
@@ -386,7 +396,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
#
# If you've set specific values, they'll be left alone.
#
- # == Fixture label interpolation
+ # === Fixture label interpolation
#
# The label of the current fixture is always available as a column value:
#
@@ -407,7 +417,7 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError # :nodoc:
#
# ActiveRecord::FixtureSet.identify(:boaty_mcboatface, :uuid)
#
- # == Support for YAML defaults
+ # === Support for YAML defaults
#
# You can set and reuse defaults in your fixtures YAML file.
# This is the same technique used in the +database.yml+ file to specify
@@ -583,7 +593,8 @@ def create_fixtures(fixtures_directories, fixture_set_names, class_names = {}, c
end
# Returns a consistent, platform-independent identifier for +label+.
- # Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
+ #
+ # \Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
def identify(label, column_type = :integer)
if column_type == :uuid
Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
@@ -596,7 +607,8 @@ def identify(label, column_type = :integer)
# between the label and the subcomponents of the provided composite key.
#
# Example:
- # composite_identify("label", [:a, :b, :c]) => { a: hash_1, b: hash_2, c: hash_3 }
+ #
+ # composite_identify("label", [:a, :b, :c]) => { a: hash_1, b: hash_2, c: hash_3 }
def composite_identify(label, key)
key
.index_with
@@ -604,7 +616,7 @@ def composite_identify(label, key)
.with_indifferent_access
end
- # Superclass for the evaluation contexts used by ERB fixtures.
+ # Superclass for the evaluation contexts used by \ERB fixtures.
def context_class
@context_class ||= Class.new
end
diff --git a/activerecord/lib/active_record/test_fixtures.rb b/activerecord/lib/active_record/test_fixtures.rb
index e4a5c4356f70d..8173d9e895d39 100644
--- a/activerecord/lib/active_record/test_fixtures.rb
+++ b/activerecord/lib/active_record/test_fixtures.rb
@@ -17,6 +17,16 @@ def after_teardown # :nodoc:
end
included do
+ ##
+ # :singleton-method: fixture_paths
+ #
+ # Returns the ActiveRecord::FixtureSet collection
+
+ ##
+ # :singleton-method: fixture_paths=
+ #
+ # :call-seq:
+ # fixture_paths=(fixture_paths)
class_attribute :fixture_paths, instance_writer: false, default: []
class_attribute :fixture_table_names, default: []
class_attribute :fixture_class_names, default: {}
@@ -42,7 +52,7 @@ def set_fixture_class(class_names = {})
self.fixture_class_names = fixture_class_names.merge(class_names.stringify_keys)
end
- def fixture_path
+ def fixture_path # :nodoc:
ActiveRecord.deprecator.warn(<<~WARNING)
TestFixtures.fixture_path is deprecated and will be removed in Rails 7.2. Use .fixture_paths instead.
If multiple fixture paths have been configured with .fixture_paths, then .fixture_path will just return
@@ -51,7 +61,7 @@ def fixture_path
fixture_paths.first
end
- def fixture_path=(path)
+ def fixture_path=(path) # :nodoc:
ActiveRecord.deprecator.warn("TestFixtures.fixture_path= is deprecated and will be removed in Rails 7.2. Use .fixture_paths= instead.")
self.fixture_paths = Array(path)
end
@@ -99,7 +109,7 @@ def uses_transaction?(method)
end
end
- def fixture_path
+ def fixture_path # :nodoc:
ActiveRecord.deprecator.warn(<<~WARNING)
TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2. Use #fixture_paths instead.
If multiple fixture paths have been configured with #fixture_paths, then #fixture_path will just return
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index c28868bb0dd71..626d2087af1fa 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -120,6 +120,25 @@ def parallelize_setup(&block)
def parallelize_teardown(&block)
ActiveSupport::Testing::Parallelization.run_cleanup_hook(&block)
end
+
+ # :singleton-method: fixture_paths
+ #
+ # Returns the ActiveRecord::FixtureSet collection.
+ #
+ # In your +test_helper.rb+ you must have require "rails/test_help".
+
+ # :singleton-method: fixture_paths=
+ #
+ # :call-seq:
+ # fixture_paths=(fixture_paths)
+ #
+ # Sets the given path to the fixture set.
+ #
+ # Can also append multiple paths.
+ #
+ # ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
+ #
+ # In your +test_helper.rb+ you must have require "rails/test_help".
end
alias_method :method_name, :name