Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #36303 from gaotongfei/feature/ignore-specified-fi…
…xtures

Allow specifying fixtures to be ignored in "_fixture" section
  • Loading branch information
rafaelfranca committed Jul 28, 2019
2 parents 2e9176c + c09a4fd commit 481714d
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 5 deletions.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
* Allow specifying fixtures to be ignored by setting `ignore` in YAML file's '_fixture' section.

*Tongfei Gao*

* Make the DATABASE_URL env variable only affect the primary connection. Add new env variables for multiple databases.

*John Crepezzi*, *Eileen Uchitelle*
Expand Down
6 changes: 5 additions & 1 deletion activerecord/lib/active_record/fixture_set/file.rb
Expand Up @@ -29,6 +29,10 @@ def model_class
config_row["model_class"]
end

def ignored_fixtures
config_row["ignore"]
end

private
def rows
@rows ||= raw_rows.reject { |fixture_name, _| fixture_name == "_fixture" }
Expand All @@ -40,7 +44,7 @@ def config_row
if row
row.last
else
{ 'model_class': nil }
{ 'model_class': nil, 'ignore': nil }
end
end
end
Expand Down
45 changes: 42 additions & 3 deletions activerecord/lib/active_record/fixtures.rb
Expand Up @@ -420,6 +420,29 @@ class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
#
# Any fixture labeled "DEFAULTS" is safely ignored.
#
# Besides using "DEFAULTS", you can also specify what fixtures will
# be ignored by setting "ignore" in "_fixture" section.
#
# # users.yml
# _fixture:
# ignore:
# - base
# # or use "ignore: base" when there is only one fixture needs to be ignored.
#
# base: &base
# admin: false
# introduction: "This is a default description"
#
# admin:
# <<: *base
# admin: true
#
# visitor:
# <<: *base
#
# In the above example, 'base' will be ignored when creating fixtures.
# This can be used for common attributes inheriting.
#
# == Configure the fixture model class
#
# It's possible to set the fixture's model class directly in the YAML file.
Expand Down Expand Up @@ -614,7 +637,7 @@ def update_all_loaded_fixtures(fixtures_map) # :nodoc:
end
end

attr_reader :table_name, :name, :fixtures, :model_class, :config
attr_reader :table_name, :name, :fixtures, :model_class, :ignored_fixtures, :config

def initialize(_, name, class_name, path, config = ActiveRecord::Base)
@name = name
Expand Down Expand Up @@ -647,8 +670,8 @@ def size
# Returns a hash of rows to be inserted. The key is the table, the value is
# a list of rows to insert to that table.
def table_rows
# allow a standard key to be used for doing defaults in YAML
fixtures.delete("DEFAULTS")
# allow specifying fixtures to be ignored by setting `ignore` in `_fixture` section
fixtures.except!(*ignored_fixtures)

TableRows.new(
table_name,
Expand All @@ -667,6 +690,21 @@ def model_class=(class_name)
end
end

def ignored_fixtures=(base)
@ignored_fixtures =
case base
when Array
base
when String
[base]
else
[]
end

@ignored_fixtures << "DEFAULTS" unless @ignored_fixtures.include?("DEFAULTS")
@ignored_fixtures.compact
end

# Loads the fixtures from the YAML file at +path+.
# If the file sets the +model_class+ and current instance value is not set,
# it uses the file value.
Expand All @@ -678,6 +716,7 @@ def read_fixture_files(path)
yaml_files.each_with_object({}) do |file, fixtures|
FixtureSet::File.open(file) do |fh|
self.model_class ||= fh.model_class if fh.model_class
self.ignored_fixtures ||= fh.ignored_fixtures
fh.each do |fixture_name, row|
fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
end
Expand Down
27 changes: 27 additions & 0 deletions activerecord/test/cases/fixtures_test.rb
Expand Up @@ -1279,6 +1279,33 @@ def test_table_name_is_defined_in_the_model
end
end

class IgnoreFixturesTest < ActiveRecord::TestCase
fixtures :other_books, :parrots

test "ignores books fixtures" do
assert_raise(StandardError) { other_books(:published) }
assert_raise(StandardError) { other_books(:published_paperback) }
assert_raise(StandardError) { other_books(:published_ebook) }

assert_equal 2, Book.count
assert_equal "Agile Web Development with Rails", other_books(:awdr).name
assert_equal "published", other_books(:awdr).status
assert_equal "paperback", other_books(:awdr).format
assert_equal "english", other_books(:awdr).language

assert_equal "Ruby for Rails", other_books(:rfr).name
assert_equal "ebook", other_books(:rfr).format
assert_equal "published", other_books(:rfr).status
end

test "ignores parrots fixtures" do
assert_raise(StandardError) { parrots(:DEFAULT) }
assert_raise(StandardError) { parrots(:DEAD_PARROT) }

assert_equal "DeadParrot", parrots(:polly).parrot_sti_class
end
end

class FixturesWithDefaultScopeTest < ActiveRecord::TestCase
fixtures :bulbs

Expand Down
26 changes: 26 additions & 0 deletions activerecord/test/fixtures/other_books.yml
@@ -0,0 +1,26 @@
_fixture:
model_class: Book
ignore:
- PUBLISHED
- PUBLISHED_PAPERBACK
- PUBLISHED_EBOOK

PUBLISHED: &PUBLISHED
status: :published

PUBLISHED_PAPERBACK: &PUBLISHED_PAPERBACK
<<: *PUBLISHED
format: "paperback"
language: :english

PUBLISHED_EBOOK: &PUBLISHED_EBOOK
<<: *PUBLISHED
format: "ebook"

awdr:
<<: *PUBLISHED_PAPERBACK
name: "Agile Web Development with Rails"

rfr:
<<: *PUBLISHED_EBOOK
name: "Ruby for Rails"
8 changes: 7 additions & 1 deletion activerecord/test/fixtures/parrots.yml
@@ -1,3 +1,9 @@
_fixture:
ignore: DEAD_PARROT

DEAD_PARROT: &DEAD_PARROT
parrot_sti_class: DeadParrot

george:
name: "Curious George"
treasures: diamond, sapphire
Expand All @@ -17,7 +23,7 @@ polly:
name: $LABEL
killer: blackbeard
treasures: sapphire, ruby
parrot_sti_class: DeadParrot
<<: *DEAD_PARROT

DEFAULTS: &DEFAULTS
treasures: sapphire, ruby
Expand Down

0 comments on commit 481714d

Please sign in to comment.