fixture_kit 0.3.0 → 0.4.0

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: 23151d16a20be7d13a1c4a15ce4dca10a2c742ba68a1d43af339bdad65490679
4
- data.tar.gz: 1c9da63eae90bbe6843d204d138fafbf3b933f0ea4fd9f42c4108331509f472b
3
+ metadata.gz: b9c12d67129c3c71b587913a62cea49c41f55a7ab9c0f4308961906517f7b6f7
4
+ data.tar.gz: 92e5dec6ccdb3084d5b699fd1f462fb145667dd46caeb7f65aba8d782244bdbd
5
5
  SHA512:
6
- metadata.gz: 3b75d5d28b153bb082f8097309c39c6d350633faac76e1b30e5ea7413cf3bccfa9b93a3941f6eff607306f43cd53a7bc5420fd1d331fc99c66ede324f82e3902
7
- data.tar.gz: 92d48a55f2a92f4f1673a890e9bba8ce6695204b7a020e3240a9db21217747c3d0f7446297706cc634a15ea3246e29d0b0adcad870152cd449056c67b75cae45
6
+ metadata.gz: 75484ce7d299f78263f0c268a39eacb4c33896075b90138ed6741e253b95d312144ced9481ae2e7e6328a4b8817bf8e566c7d56df86975e236b2f2a248643376
7
+ data.tar.gz: c7644edbec83c88df2d5cc24a206ccabd4d3f1077a199fd2317c81e7e128801a58ed86738b229ed679b6ca3c1b979fe0f2b5adbf2334ed4ab16dbd2fa04b3ccf
data/README.md CHANGED
@@ -119,22 +119,39 @@ end
119
119
 
120
120
  When you call `fixture "name"` in an example group, FixtureKit registers that fixture with its runner.
121
121
 
122
+ ### 4. Configure Minitest
123
+
124
+ ```ruby
125
+ # test/test_helper.rb
126
+ require "fixture_kit/minitest"
127
+
128
+ class ActiveSupport::TestCase
129
+ self.use_transactional_tests = true
130
+ end
131
+ ```
132
+
133
+ When you call `fixture "name"` in a test class, FixtureKit registers that fixture with its runner and mounts it during test setup.
134
+
122
135
  ## Configuration
123
136
 
124
137
  ```ruby
125
138
  # spec/support/fixture_kit.rb
126
139
  FixtureKit.configure do |config|
127
- # Where fixture definitions live (default: spec/fixture_kit)
140
+ # Where fixture definitions live (default: fixture_kit).
141
+ # Framework entrypoints set a framework-specific default:
142
+ # - fixture_kit/rspec -> spec/fixture_kit
143
+ # - fixture_kit/minitest -> test/fixture_kit
128
144
  config.fixture_path = Rails.root.join("spec/fixture_kit").to_s
129
145
 
130
146
  # Where cache files are stored (default: tmp/cache/fixture_kit)
131
147
  config.cache_path = Rails.root.join("tmp/cache/fixture_kit").to_s
132
148
 
133
- # Wrapper used to isolate generation work (default: FixtureKit::TestCase::Isolator)
134
- # config.isolator = FixtureKit::TestCase::Isolator
135
- # config.isolator = FixtureKit::RSpec::Isolator
149
+ # Wrapper used to isolate generation work (default: FixtureKit::MinitestIsolator)
150
+ # config.isolator = FixtureKit::MinitestIsolator
151
+ # config.isolator = FixtureKit::RSpecIsolator
136
152
 
137
- # Optional callback, called once when a fixture cache is first generated.
153
+ # Optional callback, called right before a fixture cache is generated.
154
+ # Called on first generation and forced regeneration.
138
155
  # Receives the fixture name as a String.
139
156
  # config.on_cache = ->(fixture_name) { puts "cached #{fixture_name}" }
140
157
  end
@@ -143,26 +160,29 @@ end
143
160
  Custom isolators should subclass `FixtureKit::Isolator` and implement `#run`.
144
161
  `#run` receives the generation block and should execute it in whatever lifecycle you need.
145
162
 
146
- By default, FixtureKit uses `FixtureKit::TestCase::Isolator`, which runs generation inside an internal `ActiveSupport::TestCase` and removes that harness case from minitest runnables.
163
+ By default, FixtureKit uses `FixtureKit::MinitestIsolator`, which runs generation inside an internal `ActiveSupport::TestCase` and removes that harness case from minitest runnables.
147
164
 
148
- When using `fixture_kit/rspec`, FixtureKit sets `FixtureKit::RSpec::Isolator`. It runs generation inside an internal RSpec example, and uses a null reporter so harness runs do not count toward suite example totals.
165
+ When using `fixture_kit/rspec`, FixtureKit sets `FixtureKit::RSpecIsolator`. It runs generation inside an internal RSpec example, and uses a null reporter so harness runs do not count toward suite example totals.
149
166
 
150
167
  ## Lifecycle
151
168
 
152
169
  Fixture generation is managed by `FixtureKit::Runner`.
153
170
 
154
- With `fixture_kit/rspec`:
155
-
156
- 1. `fixture "name"` registers the fixture with the runner during spec file load.
157
- 2. In `before(:suite)`, runner `start`:
171
+ 1. Calling `fixture "name"` registers the fixture with the runner.
172
+ 2. Runner `start`:
158
173
  - clears `cache_path` (unless preserve-cache is enabled),
159
174
  - generates caches for all already-registered fixtures.
160
- 3. If new spec files are loaded later (for example, queue-mode CI runners), newly registered fixtures are generated immediately because the runner has already started.
161
- 4. At example runtime, fixture mounting loads from cache.
175
+ 3. If new tests are loaded after start (for example, queue-mode CI runners), newly registered fixtures are cached immediately.
176
+ 4. At test runtime, `fixture` mounts from cache and returns a `Repository`.
177
+
178
+ When runner start happens:
179
+
180
+ - `fixture_kit/rspec`: in `before(:suite)`.
181
+ - `fixture_kit/minitest`: lazily during test setup for the first test class that declares `fixture`.
162
182
 
163
183
  ### Preserving Cache Locally
164
184
 
165
- If you want to skip cache clearing at suite start (e.g., to reuse caches across test runs during local development), set the `FIXTURE_KIT_PRESERVE_CACHE` environment variable:
185
+ If you want to skip cache clearing when the runner starts (e.g., to reuse caches across test runs during local development), set the `FIXTURE_KIT_PRESERVE_CACHE` environment variable:
166
186
 
167
187
  ```bash
168
188
  FIXTURE_KIT_PRESERVE_CACHE=1 bundle exec rspec
@@ -189,13 +209,13 @@ fixture "teams/sales"
189
209
 
190
210
  ## How It Works
191
211
 
192
- 1. **Cache generation**: FixtureKit executes your definition block inside the configured isolator, subscribes to `sql.active_record` notifications to track inserted models, queries those model tables, and generates batch INSERT statements with conflict handling (`INSERT OR IGNORE` for SQLite, `ON CONFLICT DO NOTHING` for PostgreSQL, `INSERT IGNORE` for MySQL).
212
+ 1. **Cache generation**: FixtureKit executes your definition block inside the configured isolator, subscribes to `sql.active_record` notifications to track created/updated/deleted models, queries those model tables, and caches INSERT statements for current table contents.
193
213
 
194
- 2. **Mounting**: FixtureKit loads the cached JSON file and executes the raw SQL INSERT statements directly. No ORM instantiation, no callbacks.
214
+ 2. **Mounting**: FixtureKit loads the cached JSON file, clears each tracked table, and executes the raw SQL INSERT statements directly. No ORM instantiation, no callbacks.
195
215
 
196
216
  3. **Repository build**: FixtureKit resolves exposed records by model + id and returns a `Repository` for method-based access.
197
217
 
198
- 4. **Transaction isolation**: RSpec's `use_transactional_fixtures` wraps each test in a transaction that rolls back, so data doesn't persist between tests.
218
+ 4. **Transaction isolation**: Use framework transactions (`use_transactional_fixtures` in RSpec, `use_transactional_tests` in Minitest) so test writes roll back and cached data can be reused safely between tests.
199
219
 
200
220
  ### Cache Format
201
221
 
@@ -7,6 +7,8 @@ require "active_support/inflector"
7
7
 
8
8
  module FixtureKit
9
9
  class Cache
10
+ include ConfigurationHelper
11
+
10
12
  attr_reader :fixture
11
13
 
12
14
  def initialize(fixture, definition)
@@ -15,7 +17,7 @@ module FixtureKit
15
17
  end
16
18
 
17
19
  def path
18
- File.join(FixtureKit.configuration.cache_path, "#{fixture.name}.json")
20
+ File.join(configuration.cache_path, "#{fixture.name}.json")
19
21
  end
20
22
 
21
23
  def exists?
@@ -30,14 +32,19 @@ module FixtureKit
30
32
  @data ||= JSON.parse(File.read(path))
31
33
  @data.fetch("records").each do |model_name, sql|
32
34
  model = ActiveSupport::Inflector.constantize(model_name)
33
- model.connection.execute(sql)
35
+ connection = model.connection
36
+ connection.disable_referential_integrity do
37
+ # execute_batch is private in current supported Rails versions.
38
+ # This should be revisited when Rails 8.2 makes it public.
39
+ connection.__send__(:execute_batch, [build_delete_sql(model), sql].compact, "FixtureKit Load")
40
+ end
34
41
  end
35
42
 
36
43
  build_repository(@data.fetch("exposed"))
37
44
  end
38
45
 
39
46
  def save
40
- FixtureKit.configuration.isolator.run do
47
+ FixtureKit.runner.isolator.run do
41
48
  models = SqlSubscriber.capture do
42
49
  @definition.evaluate
43
50
  end
@@ -88,37 +95,22 @@ module FixtureKit
88
95
  rows << "(#{row_values.join(", ")})"
89
96
  end
90
97
 
91
- next if rows.empty?
92
-
93
- sql = build_insert_sql(model.table_name, columns, rows, model.connection)
98
+ sql = rows.empty? ? nil : build_insert_sql(model.table_name, columns, rows, model.connection)
94
99
  statements_by_model[model.name] = sql
95
100
  end
96
101
 
97
102
  statements_by_model
98
103
  end
99
104
 
105
+ def build_delete_sql(model)
106
+ "DELETE FROM #{model.quoted_table_name}"
107
+ end
108
+
100
109
  def build_insert_sql(table_name, columns, rows, connection)
101
110
  quoted_table = connection.quote_table_name(table_name)
102
111
  quoted_columns = columns.map { |c| connection.quote_column_name(c) }
103
112
 
104
- sql = "INSERT INTO #{quoted_table} (#{quoted_columns.join(", ")}) VALUES #{rows.join(", ")}"
105
-
106
- add_conflict_handling(sql, connection)
107
- end
108
-
109
- def add_conflict_handling(sql, connection)
110
- adapter_name = connection.adapter_name.downcase
111
-
112
- case adapter_name
113
- when /sqlite/
114
- sql.sub(/\AINSERT INTO/i, "INSERT OR IGNORE INTO")
115
- when /postgresql/, /postgis/
116
- "#{sql} ON CONFLICT DO NOTHING"
117
- when /mysql/, /trilogy/
118
- sql.sub(/\AINSERT INTO/i, "INSERT IGNORE INTO")
119
- else
120
- sql
121
- end
113
+ "INSERT INTO #{quoted_table} (#{quoted_columns.join(", ")}) VALUES #{rows.join(", ")}"
122
114
  end
123
115
 
124
116
  def build_exposed_mapping(exposed)
@@ -8,14 +8,14 @@ module FixtureKit
8
8
  attr_accessor :on_cache
9
9
 
10
10
  def initialize
11
- @fixture_path = nil
11
+ @fixture_path = "fixture_kit"
12
12
  @cache_path = nil
13
- @isolator = FixtureKit::TestCase::Isolator
13
+ @isolator = FixtureKit::MinitestIsolator
14
14
  @on_cache = nil
15
15
  end
16
16
 
17
17
  def fixture_path
18
- @fixture_path ||= detect_fixture_path
18
+ @fixture_path
19
19
  end
20
20
 
21
21
  def cache_path
@@ -24,20 +24,6 @@ module FixtureKit
24
24
 
25
25
  private
26
26
 
27
- def detect_fixture_path
28
- if defined?(RSpec)
29
- "spec/fixture_kit"
30
- elsif defined?(Minitest)
31
- "test/fixture_kit"
32
- elsif Dir.exist?("spec")
33
- "spec/fixture_kit"
34
- elsif Dir.exist?("test")
35
- "test/fixture_kit"
36
- else
37
- "spec/fixture_kit"
38
- end
39
- end
40
-
41
27
  def detect_cache_path
42
28
  "tmp/cache/fixture_kit"
43
29
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FixtureKit
4
+ module ConfigurationHelper
5
+ private
6
+
7
+ def configuration
8
+ FixtureKit.runner.configuration
9
+ end
10
+ end
11
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module FixtureKit
4
4
  class Fixture
5
+ include ConfigurationHelper
6
+
5
7
  attr_reader :name, :path
6
8
 
7
9
  def initialize(name, path)
@@ -11,11 +13,10 @@ module FixtureKit
11
13
  end
12
14
 
13
15
  def cache(force: false)
14
- already_cached = @cache.exists?
15
- return if already_cached && !force
16
+ return if @cache.exists? && !force
16
17
 
18
+ configuration.on_cache&.call(name)
17
19
  @cache.save
18
- FixtureKit.configuration.on_cache&.call(name) unless already_cached
19
20
  end
20
21
 
21
22
  def mount
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/test_case"
4
+ require "active_record/fixtures"
5
+
6
+ module FixtureKit
7
+ class MinitestIsolator < FixtureKit::Isolator
8
+ TEST_NAME = "fixture kit cache pregeneration"
9
+
10
+ def run(&block)
11
+ test_class = build_test_class
12
+ test_method = test_class.test(TEST_NAME) do
13
+ block.call
14
+ pass
15
+ end
16
+
17
+ result = test_class.new(test_method).run
18
+ return if result.passed?
19
+
20
+ raise result.failures.first.error
21
+ end
22
+
23
+ private
24
+
25
+ def build_test_class
26
+ Class.new(ActiveSupport::TestCase) do
27
+ ::Minitest::Runnable.runnables.delete(self)
28
+ include(::ActiveRecord::TestFixtures)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FixtureKit
4
+ class RSpecIsolator < FixtureKit::Isolator
5
+ def run(&block)
6
+ previous_example = ::RSpec.current_example
7
+ previous_scope = ::RSpec.current_scope
8
+ example_group = build_example_group
9
+ example = example_group.example { block.call }
10
+ instance = example_group.new
11
+ succeeded =
12
+ begin
13
+ example.run(instance, ::RSpec::Core::NullReporter)
14
+ ensure
15
+ ::RSpec.current_example = previous_example
16
+ ::RSpec.current_scope = previous_scope
17
+ end
18
+
19
+ raise example.exception unless succeeded
20
+ end
21
+
22
+ private
23
+
24
+ def build_example_group
25
+ ::RSpec::Core::ExampleGroup.subclass(
26
+ ::RSpec::Core::ExampleGroup,
27
+ "FixtureKit",
28
+ [],
29
+ []
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fixture_kit"
4
+ require "active_support/lazy_load_hooks"
5
+
6
+ module FixtureKit
7
+ module Minitest
8
+ DECLARATION_CLASS_ATTRIBUTE = :fixture_kit_declaration
9
+
10
+ module ClassMethods
11
+ def fixture(name)
12
+ self.fixture_kit_declaration = FixtureKit.runner.register(name)
13
+ end
14
+ end
15
+
16
+ module InstanceMethods
17
+ def fixture
18
+ @_fixture_kit_repository || raise("No fixture declared for this test class. Use `fixture \"name\"` in your test class.")
19
+ end
20
+ end
21
+
22
+ def self.configure!(test_case)
23
+ FixtureKit.runner.configuration.fixture_path = "test/fixture_kit"
24
+ FixtureKit.runner.configuration.isolator = FixtureKit::MinitestIsolator
25
+
26
+ test_case.class_attribute DECLARATION_CLASS_ATTRIBUTE, instance_accessor: false
27
+ test_case.extend ClassMethods
28
+ test_case.include InstanceMethods
29
+
30
+ test_case.setup do
31
+ declaration = self.class.fixture_kit_declaration
32
+ next unless declaration
33
+
34
+ FixtureKit.runner.start unless FixtureKit.runner.started?
35
+ @_fixture_kit_repository = declaration.mount
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ActiveSupport.on_load(:active_support_test_case) do
42
+ FixtureKit::Minitest.configure!(self)
43
+ end
@@ -4,8 +4,9 @@ require "pathname"
4
4
 
5
5
  module FixtureKit
6
6
  class Registry
7
- def initialize(configuration)
8
- @configuration = configuration
7
+ include ConfigurationHelper
8
+
9
+ def initialize
9
10
  @registry = {}
10
11
  end
11
12
 
@@ -28,7 +29,7 @@ module FixtureKit
28
29
  private
29
30
 
30
31
  def fixture_file_path(name)
31
- File.expand_path(File.join(@configuration.fixture_path, "#{name}.rb"))
32
+ File.expand_path(File.join(configuration.fixture_path, "#{name}.rb"))
32
33
  end
33
34
  end
34
35
  end
@@ -4,8 +4,6 @@ require "fixture_kit"
4
4
 
5
5
  module FixtureKit
6
6
  module RSpec
7
- autoload :Isolator, File.expand_path("rspec/isolator", __dir__)
8
-
9
7
  DECLARATION_METADATA_KEY = :fixture_kit_declaration
10
8
 
11
9
  # Class methods (extended via config.extend)
@@ -39,13 +37,14 @@ module FixtureKit
39
37
  # Returns the Repository for the current example's fixture.
40
38
  # Access exposed records as methods: fixture.alice, fixture.posts
41
39
  def fixture
42
- @_fixture_kit_fixture_set || raise("No fixture declared for this example group. Use `fixture \"name\"` in your describe/context block.")
40
+ @_fixture_kit_repository || raise("No fixture declared for this example group. Use `fixture \"name\"` in your describe/context block.")
43
41
  end
44
42
  end
45
43
 
46
44
  def self.configure!(config)
45
+ FixtureKit.runner.configuration.fixture_path = "spec/fixture_kit"
47
46
  config.add_setting(:fixture_kit, default: FixtureKit.runner)
48
- FixtureKit.configuration.isolator = Isolator
47
+ FixtureKit.runner.configuration.isolator = FixtureKit::RSpecIsolator
49
48
 
50
49
  config.extend ClassMethods
51
50
  config.include InstanceMethods, DECLARATION_METADATA_KEY
@@ -53,7 +52,7 @@ module FixtureKit
53
52
  # Load declared fixtures at the beginning of each example.
54
53
  # Runs inside transactional fixtures and before user-defined before hooks.
55
54
  config.prepend_before(:example, DECLARATION_METADATA_KEY) do |example|
56
- @_fixture_kit_fixture_set = example.metadata[DECLARATION_METADATA_KEY].mount
55
+ @_fixture_kit_repository = example.metadata[DECLARATION_METADATA_KEY].mount
57
56
  end
58
57
 
59
58
  config.append_before(:suite) do
@@ -10,7 +10,8 @@ module FixtureKit
10
10
 
11
11
  def initialize
12
12
  @configuration = Configuration.new
13
- @registry = Registry.new(configuration)
13
+ @registry = Registry.new
14
+ @isolator = nil
14
15
  @started = false
15
16
  end
16
17
 
@@ -28,6 +29,10 @@ module FixtureKit
28
29
  registry.fixtures.each(&:cache)
29
30
  end
30
31
 
32
+ def isolator
33
+ @isolator ||= configuration.isolator.new
34
+ end
35
+
31
36
  def started?
32
37
  @started
33
38
  end
@@ -7,10 +7,6 @@ module FixtureKit
7
7
  self
8
8
  end
9
9
 
10
- def configuration
11
- runner.configuration
12
- end
13
-
14
10
  def runner
15
11
  @runner ||= Runner.new
16
12
  end
@@ -6,18 +6,15 @@ require "active_support/inflector"
6
6
  module FixtureKit
7
7
  class SqlSubscriber
8
8
  EVENT = "sql.active_record"
9
+ NAME_PATTERN = /\A(?<model_name>.+?) (?:(?:Bulk )?(?:Insert|Upsert)|Create|Destroy|(?:Update|Delete)(?: All)?)\z/
9
10
 
10
11
  def self.capture(&block)
11
12
  models = Set.new
12
13
  subscriber = lambda do |_event_name, _start, _finish, _id, payload|
13
- sql = payload[:sql]
14
- next unless sql =~ /\AINSERT INTO/i
14
+ name = payload[:name].to_s
15
+ model_name = name[NAME_PATTERN, :model_name]
16
+ next unless model_name
15
17
 
16
- # payload[:name] is like "User Create" - extract model name
17
- name = payload[:name]
18
- next unless name&.end_with?(" Create")
19
-
20
- model_name = name.sub(/ Create\z/, "")
21
18
  models.add(ActiveSupport::Inflector.constantize(model_name))
22
19
  end
23
20
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FixtureKit
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/fixture_kit.rb CHANGED
@@ -2,26 +2,26 @@
2
2
 
3
3
  module FixtureKit
4
4
  class Error < StandardError; end
5
- class DuplicateFixtureError < Error; end
6
5
  class DuplicateNameError < Error; end
7
6
  class CacheMissingError < Error; end
8
- class PregenerationError < Error; end
9
7
  class FixtureDefinitionNotFound < Error; end
10
8
  class ExposedRecordNotFound < Error; end
11
9
  class RunnerAlreadyStartedError < Error; end
12
10
 
13
- autoload :VERSION, File.expand_path("fixture_kit/version", __dir__)
14
- autoload :Configuration, File.expand_path("fixture_kit/configuration", __dir__)
15
- autoload :Singleton, File.expand_path("fixture_kit/singleton", __dir__)
16
- autoload :Fixture, File.expand_path("fixture_kit/fixture", __dir__)
17
- autoload :Definition, File.expand_path("fixture_kit/definition", __dir__)
18
- autoload :Registry, File.expand_path("fixture_kit/registry", __dir__)
19
- autoload :Repository, File.expand_path("fixture_kit/repository", __dir__)
20
- autoload :SqlSubscriber, File.expand_path("fixture_kit/sql_subscriber", __dir__)
21
- autoload :Cache, File.expand_path("fixture_kit/cache", __dir__)
22
- autoload :Runner, File.expand_path("fixture_kit/runner", __dir__)
23
- autoload :Isolator, File.expand_path("fixture_kit/isolator", __dir__)
24
- autoload :TestCase, File.expand_path("fixture_kit/test_case", __dir__)
11
+ autoload :VERSION, File.expand_path("fixture_kit/version", __dir__)
12
+ autoload :Configuration, File.expand_path("fixture_kit/configuration", __dir__)
13
+ autoload :ConfigurationHelper, File.expand_path("fixture_kit/configuration_helper", __dir__)
14
+ autoload :Singleton, File.expand_path("fixture_kit/singleton", __dir__)
15
+ autoload :Fixture, File.expand_path("fixture_kit/fixture", __dir__)
16
+ autoload :Definition, File.expand_path("fixture_kit/definition", __dir__)
17
+ autoload :Registry, File.expand_path("fixture_kit/registry", __dir__)
18
+ autoload :Repository, File.expand_path("fixture_kit/repository", __dir__)
19
+ autoload :SqlSubscriber, File.expand_path("fixture_kit/sql_subscriber", __dir__)
20
+ autoload :Cache, File.expand_path("fixture_kit/cache", __dir__)
21
+ autoload :Runner, File.expand_path("fixture_kit/runner", __dir__)
22
+ autoload :Isolator, File.expand_path("fixture_kit/isolator", __dir__)
23
+ autoload :MinitestIsolator, File.expand_path("fixture_kit/isolators/minitest_isolator", __dir__)
24
+ autoload :RSpecIsolator, File.expand_path("fixture_kit/isolators/rspec_isolator", __dir__)
25
25
 
26
26
  extend Singleton
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixture_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ngan Pham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-22 00:00:00.000000000 Z
11
+ date: 2026-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -136,18 +136,19 @@ files:
136
136
  - lib/fixture_kit.rb
137
137
  - lib/fixture_kit/cache.rb
138
138
  - lib/fixture_kit/configuration.rb
139
+ - lib/fixture_kit/configuration_helper.rb
139
140
  - lib/fixture_kit/definition.rb
140
141
  - lib/fixture_kit/fixture.rb
141
142
  - lib/fixture_kit/isolator.rb
143
+ - lib/fixture_kit/isolators/minitest_isolator.rb
144
+ - lib/fixture_kit/isolators/rspec_isolator.rb
145
+ - lib/fixture_kit/minitest.rb
142
146
  - lib/fixture_kit/registry.rb
143
147
  - lib/fixture_kit/repository.rb
144
148
  - lib/fixture_kit/rspec.rb
145
- - lib/fixture_kit/rspec/isolator.rb
146
149
  - lib/fixture_kit/runner.rb
147
150
  - lib/fixture_kit/singleton.rb
148
151
  - lib/fixture_kit/sql_subscriber.rb
149
- - lib/fixture_kit/test_case.rb
150
- - lib/fixture_kit/test_case/isolator.rb
151
152
  - lib/fixture_kit/version.rb
152
153
  homepage: https://github.com/Gusto/fixture_kit
153
154
  licenses:
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FixtureKit
4
- module RSpec
5
- class Isolator < FixtureKit::Isolator
6
- def run(&block)
7
- previous_example = ::RSpec.current_example
8
- previous_scope = ::RSpec.current_scope
9
- example_group = build_example_group
10
- example = build_example(example_group, &block)
11
- instance = example_group.new(example.inspect_output)
12
- succeeded =
13
- begin
14
- example.run(instance, ::RSpec::Core::NullReporter)
15
- ensure
16
- example_group.remove_example(example)
17
- ::RSpec.current_example = previous_example
18
- ::RSpec.current_scope = previous_scope
19
- end
20
-
21
- unless succeeded
22
- raise example.exception if example.exception
23
- raise FixtureKit::PregenerationError, "FixtureKit pregeneration failed"
24
- end
25
- end
26
-
27
- private
28
-
29
- def build_example(example_group, &block)
30
- example_group.example(
31
- "FixtureKit cache pregeneration"
32
- ) { block.call }
33
- end
34
-
35
- def build_example_group
36
- ::RSpec::Core::ExampleGroup.subclass(
37
- ::RSpec::Core::ExampleGroup,
38
- "FixtureKit::RSpec::Isolator",
39
- [],
40
- []
41
- )
42
- end
43
- end
44
- end
45
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_support/test_case"
4
- require "active_record/fixtures"
5
-
6
- module FixtureKit
7
- module TestCase
8
- class Isolator < FixtureKit::Isolator
9
- TEST_METHOD_NAME = "test_fixture_kit_cache_pregeneration"
10
-
11
- def run(&block)
12
- result = build_test_class(&block).run
13
- return if result.passed?
14
-
15
- failure = result.failures.first
16
- raise failure.error if failure.respond_to?(:error)
17
- raise failure if failure
18
-
19
- raise FixtureKit::PregenerationError, "FixtureKit pregeneration failed"
20
- end
21
-
22
- private
23
-
24
- def build_test_class(&block)
25
- Class.new(ActiveSupport::TestCase) do
26
- ::Minitest::Runnable.runnables.delete(self)
27
- include(::ActiveRecord::TestFixtures)
28
-
29
- define_method(TEST_METHOD_NAME) do
30
- block.call
31
- pass
32
- end
33
- end.new(TEST_METHOD_NAME)
34
- end
35
- end
36
- end
37
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FixtureKit
4
- module TestCase
5
- autoload :Isolator, File.expand_path("test_case/isolator", __dir__)
6
- end
7
- end