fixture_farm 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 728eb6b44d1deb4df01e4bc03795758f3846e169f6dc07f0f5c7a6a799881976
4
- data.tar.gz: 59fe50410c6fd317537dd653001f8bd8e7b571b2375faa97d95e6dc41e188e76
3
+ metadata.gz: af9b30c58737a261963da35795445aadfcb38efe2f3ed6d4fc8055f19399b0df
4
+ data.tar.gz: 865e73ba12d379aba2b3f48a160ce421efe7d49a958db72f19b185d4d1045175
5
5
  SHA512:
6
- metadata.gz: cd4e4c6609afbe0a09413cf19d71eec01b9366f4e2d793190b8cb9b7aa86eecded615cbeae5daf31036cd3ca6a4bfea42c3bc568236aa9c4c3357b9e81157052
7
- data.tar.gz: 2210cb7393ce70c90d3e0225ba28f9b87ee2f4b6d1d106ce029e352b475b6c1c3eed78c1af4bd15e864330101f0059a06ec2f5c65415faf1228a44e03bcf8693
6
+ metadata.gz: 9c1950bc97570624b27f2f928ec82586816429e1f7a34378f5336c83d8d420180ad65093677744a4b6efa8e3cbc2b7a298631837dbb9ffc32d0c11941d372596
7
+ data.tar.gz: 455b1430edd5fb21874e7cd906688ea55ea3e1753c0e02b13b2bcd051f2e68f17d02174f6b770cac9b15f212cef0923b52c3584f40f7b1d662957cff1a4c0cc3
data/README.md CHANGED
@@ -9,6 +9,7 @@ A few things to note:
9
9
  - generated fixture that `belongs_to` a record from an existing fixture, will reference that fixture by name.
10
10
  - models, destroyed during recording, will be removed from fixtures (if they were originally there).
11
11
  - generated `ActiveStorage::Blob` fixtures file names, will be the same as fixture names (so they can be generated multiple times, without generating new file each time).
12
+ - AR models gain `#fixture_name` method
12
13
 
13
14
  ### Limitations
14
15
 
@@ -61,82 +62,85 @@ bundle exec fixture_farm stop
61
62
 
62
63
  ### Record in tests
63
64
 
64
- To record in tests, wrap some code in `record_new_fixtures` block. For example:
65
+ To record in tests, wrap some code in `record_fixtures` block. For example:
65
66
 
66
67
  ```ruby
67
68
 
68
69
  include FixtureFarm::TestHelper
69
70
 
70
- test 'some stuff does the right thing' do
71
- record_new_fixtures do |recorder|
72
- user = User.create!(name: 'Bob')
73
- post = user.posts.create!(title: 'Stuff')
71
+ test 'parents fixtures have children' do
72
+ offending_records = Parent.where.missing(:children)
74
73
 
75
- recorder.stop!
76
-
77
- assert_difference 'user.published_posts.size' do
78
- post.publish!
74
+ if ENV['GENERATE_FIXTURES']
75
+ record_fixtures do
76
+ offending_records.each do |parent|
77
+ parent.children.create!(name: 'Bob')
78
+ end
79
79
  end
80
+ else
81
+ assert_empty offending_records.map(&:fixture_name),
82
+ "The following parents don't have children:"
80
83
  end
81
84
  end
82
85
  ```
83
86
 
84
- Running this test generates user and post fixtures. Now you can rewrite this test to use them:
85
-
86
- ```ruby
87
- test 'some stuff does the right thing' do
88
- user = users('user_1')
87
+ Assuming there was a parent fixture `dave` that didn't have any children, this test will fail. Now, running the same test with `GENERATE_FIXTURES=1` will generate one child fixture named `dave_child_1`. The test is now passing.
89
88
 
90
- assert_difference 'user.published_posts.size' do
91
- user.posts.first.publish!
92
- end
93
- end
94
- ```
89
+ `record_fixtures` accepts optional name prefix, that applies to all new fixture names.
95
90
 
96
- `record_new_fixtures` accepts optional name prefix, that applies to all new fixture names.
91
+ ### Automatic fixture naming
97
92
 
98
- A more robust approach is to have dedicated fixture tests that normally fail, but can be optionally run in "record mode" (think VCR).
93
+ Generated fixture names are based on the first `belongs_to` association of the model. E.g., if a new post fixtures belongs_to to a user fixture `bob`, the name is going to be `bob_post_1`.
99
94
 
100
- For example, let's say we have `Author` model that `has_many :posts` and we require authors to have at least one post. Here's the test to enforce `authors` fixtures to comply with this rule:
95
+ It's possible to lower the priority of given parent assiciations when it comes to naming, so that certain names are only picked when there are no other suitable parent associations. This is useful, for example, to exclude `acts_as_tenant` association:
101
96
 
102
97
  ```ruby
103
- test 'authors fixtures must have at least one post' do
104
- offending_records = Author.where.missing(:posts)
105
-
106
- assert_empty offending_records
107
- end
98
+ FixtureFarm.low_priority_parent_model_for_naming = -> { _1.is_a?(TenantModel) }
108
99
  ```
109
100
 
110
- Let's say this test is currently failing.
101
+ ### Attachment fixtures
111
102
 
112
- Now let's add the option to automatically record missing fixtures:
103
+ Rather than [manually crafting attachment fixtures](https://guides.rubyonrails.org/v8.0/active_storage_overview.html#adding-attachments-to-fixtures), we can get the gem do the leg work. Not only is this less boring, but it's also going to generate variant fixtures.
113
104
 
114
- ```ruby
115
- test 'authors fixtures must have at least one post' do
116
- offending_records = Author.where.missing(:posts)
105
+ I'd also go as far as suggesting that attachment files for generated blobs should be checked into git just as the fixtures themselves are. To share them with the development environment (e.g. `rails db:fixtures:load`), let's store test attachment files in the same `./storage` directory used in development:
117
106
 
118
- if ENV['RECORD_FIXTURES']
119
- record_new_fixtures do
120
- offending_records.each do |author|
121
- author.posts.create!(text: 'some text')
122
- end
123
- end
124
- end
125
-
126
- assert_empty offending_records
127
- end
107
+ ```ruby
108
+ # config/environments/test.rb
109
+ config.active_storage.service = :local
128
110
  ```
129
111
 
130
- Running this test with `RECORD_FIXTURES=1` will generate missing fixture entries in `test/fixtures/posts.yml`. Now re-run the test again and it's passing.
112
+ Now this test will not only generate attachments and variant fixtures, but also `git add` new attachment files. The old removed ones will show up in `git status`.
131
113
 
132
- ### Automatic fixture naming
133
-
134
- Generated fixture names are based on the first `belongs_to` association of the model. E.g., if a new post fixtures belongs_to to a user fixture `bob`, the name is going to be `bob_post_1`.
114
+ ```ruby
115
+ test "product fixtures have images" do
116
+ offending_records = Product.where.missing(:images_attachments)
117
+
118
+ if ENV["GENERATE_FIXTURES"]
119
+ # Makes generation idempotent
120
+ `git restore --staged storage`
121
+
122
+ record_fixtures do |recorder|
123
+ ActiveStorage::Attachment.where(record_type: 'Product').destroy_all
124
+
125
+ Product.find_each do |product|
126
+ product.images.attach(
127
+ io: File.open(file_fixture("products/#{product.fixture_name}.jpg")),
128
+ filename: "#{product.fixture_name}.jpg",
129
+ content_type: "image/jpeg"
130
+ )
131
+ # This generates variants
132
+ perform_enqueued_jobs
133
+ end
135
134
 
136
- It's possible to lower the priority of given parent assiciations when it comes to naming, so that certain names are only picked when there are no other suitable parent associations. This is useful, for example, to exclude `acts_as_tenant` association:
135
+ recorder.stop!
137
136
 
138
- ```ruby
139
- FixtureFarm.low_priority_parent_model_for_naming = -> { _1.is_a?(TenantModel) }
137
+ `git add -f #{recorder.new_blob_file_paths.join(' ')}`
138
+ end
139
+ else
140
+ assert_empty offending_records.map(&:fixture_name),
141
+ "Expected the following product fixtures to have images:"
142
+ end
143
+ end
140
144
  ```
141
145
 
142
146
  ## License
@@ -8,7 +8,7 @@ module FixtureFarm
8
8
  include Hook
9
9
 
10
10
  included do
11
- around_perform :record_new_fixtures, if: :record_new_fixtures?
11
+ around_perform :record_fixtures, if: :record_fixtures?
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module FixtureFarm
8
8
  include Hook
9
9
 
10
10
  included do
11
- around_action :record_new_fixtures, if: :record_new_fixtures?
11
+ around_action :record_fixtures, if: :record_fixtures?
12
12
  end
13
13
  end
14
14
  end
@@ -72,7 +72,7 @@ module FixtureFarm
72
72
  recording_session['error']
73
73
  end
74
74
 
75
- def record_new_fixtures
75
+ def record_fixtures
76
76
  @stopped = false
77
77
 
78
78
  @subscriber = ActiveSupport::Notifications.subscribe 'sql.active_record' do |event|
@@ -4,12 +4,12 @@ require 'fixture_farm/fixture_recorder'
4
4
 
5
5
  module FixtureFarm
6
6
  module Hook
7
- def record_new_fixtures(&block)
7
+ def record_fixtures(&block)
8
8
  fixture_recorder = FixtureRecorder.resume_recording_session
9
9
  return unless fixture_recorder # Bail if session was stopped due to error
10
10
 
11
11
  begin
12
- fixture_recorder.record_new_fixtures { block.call }
12
+ fixture_recorder.record_fixtures { block.call }
13
13
  ensure
14
14
  fixture_recorder.update_recording_session
15
15
  end
@@ -17,7 +17,7 @@ module FixtureFarm
17
17
 
18
18
  private
19
19
 
20
- def record_new_fixtures?
20
+ def record_fixtures?
21
21
  FixtureRecorder.recording_session_in_progress?
22
22
  end
23
23
  end
@@ -4,8 +4,8 @@ require 'fixture_farm/fixture_recorder'
4
4
 
5
5
  module FixtureFarm
6
6
  module TestHelper
7
- def record_new_fixtures(fixture_name_prefix = nil, &block)
8
- FixtureRecorder.new(fixture_name_prefix).record_new_fixtures(&block)
7
+ def record_fixtures(fixture_name_prefix = nil, &block)
8
+ FixtureRecorder.new(fixture_name_prefix).record_fixtures(&block)
9
9
  end
10
10
  end
11
11
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FixtureFarm
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixture_farm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - artemave
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-28 00:00:00.000000000 Z
11
+ date: 2025-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails