fixture_kit 0.9.1 → 0.10.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 +4 -4
- data/lib/fixture_kit/cache.rb +49 -25
- data/lib/fixture_kit/definition.rb +10 -6
- data/lib/fixture_kit/fixture.rb +8 -2
- data/lib/fixture_kit/minitest.rb +5 -3
- data/lib/fixture_kit/registry.rb +30 -13
- data/lib/fixture_kit/repository.rb +2 -3
- data/lib/fixture_kit/rspec.rb +4 -3
- data/lib/fixture_kit/runner.rb +2 -13
- data/lib/fixture_kit/singleton.rb +2 -2
- data/lib/fixture_kit/version.rb +1 -1
- data/lib/fixture_kit.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41dfc0a3fb06edb02068d8127c89708ec7e2c5792b40fb031ee553716a7c54ca
|
|
4
|
+
data.tar.gz: 4193bec6652924d99a7f564212087afa7f678b1f7995fca67f883dcfb1a45d24
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9d7108cd6bda22319c02ea76384772210bdbea00f3ac93c6f6263dd72f5d7475f4cb0087f57f2d316dd17bc2fe36ad3597e87a417dae8149b0404f9196e6a0f
|
|
7
|
+
data.tar.gz: 25c72f2db8d0c93e06e244acc12d224ec36a0cbb85cbbd65c9a4a9d92268b76847c9fb0150508f78d2a1446a7c66587b3c5d479b701c2f072d97e6df92ec289d
|
data/lib/fixture_kit/cache.rb
CHANGED
|
@@ -8,10 +8,11 @@ require "active_support/inflector"
|
|
|
8
8
|
module FixtureKit
|
|
9
9
|
class Cache
|
|
10
10
|
ANONYMOUS_DIRECTORY = "_anonymous"
|
|
11
|
+
MemoryData = Data.define(:records, :exposed)
|
|
11
12
|
|
|
12
13
|
include ConfigurationHelper
|
|
13
14
|
|
|
14
|
-
attr_reader :fixture
|
|
15
|
+
attr_reader :fixture, :data
|
|
15
16
|
|
|
16
17
|
def initialize(fixture)
|
|
17
18
|
@fixture = fixture
|
|
@@ -33,7 +34,7 @@ module FixtureKit
|
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
def exists?
|
|
36
|
-
|
|
37
|
+
data || File.exist?(path)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
def load
|
|
@@ -41,8 +42,8 @@ module FixtureKit
|
|
|
41
42
|
raise FixtureKit::CacheMissingError, "Cache does not exist for fixture '#{fixture.identifier}'"
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
@data ||=
|
|
45
|
-
statements_by_connection(
|
|
45
|
+
@data ||= load_memory_data
|
|
46
|
+
statements_by_connection(data.records).each do |connection, statements|
|
|
46
47
|
connection.disable_referential_integrity do
|
|
47
48
|
# execute_batch is private in current supported Rails versions.
|
|
48
49
|
# This should be revisited when Rails 8.2 makes it public.
|
|
@@ -50,31 +51,32 @@ module FixtureKit
|
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
|
|
53
|
-
Repository.new(
|
|
54
|
+
Repository.new(data.exposed)
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
def save
|
|
57
58
|
FixtureKit.runner.adapter.execute do |context|
|
|
58
|
-
|
|
59
|
-
fixture.definition.evaluate(context)
|
|
59
|
+
captured_models = SqlSubscriber.capture do
|
|
60
|
+
fixture.definition.evaluate(context, parent: fixture.parent&.mount)
|
|
60
61
|
end
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if fixture.parent
|
|
64
|
+
captured_models.concat(fixture.parent.cache.data.records.keys)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
@data = MemoryData.new(
|
|
68
|
+
records: generate_statements(captured_models),
|
|
69
|
+
exposed: build_exposed_mapping(fixture.definition.exposed)
|
|
70
|
+
)
|
|
66
71
|
end
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
File.write(path, JSON.pretty_generate(@data))
|
|
73
|
+
save_file_data
|
|
70
74
|
end
|
|
71
75
|
|
|
72
76
|
private
|
|
73
77
|
|
|
74
78
|
def generate_statements(models)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
models.each do |model|
|
|
79
|
+
models.uniq.each_with_object({}) do |model, statements|
|
|
78
80
|
columns = model.column_names
|
|
79
81
|
|
|
80
82
|
rows = []
|
|
@@ -87,10 +89,8 @@ module FixtureKit
|
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
sql = rows.empty? ? nil : build_insert_sql(model.table_name, columns, rows, model.connection)
|
|
90
|
-
|
|
92
|
+
statements[model] = sql
|
|
91
93
|
end
|
|
92
|
-
|
|
93
|
-
statements_by_model
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
def build_delete_sql(model)
|
|
@@ -105,17 +105,19 @@ module FixtureKit
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
def build_exposed_mapping(exposed)
|
|
108
|
-
exposed.each_with_object({}) do |(name,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
exposed.each_with_object({}) do |(name, record), hash|
|
|
109
|
+
if record.is_a?(Array)
|
|
110
|
+
hash[name] = record.map { |record| { record.class => record.id } }
|
|
111
|
+
else
|
|
112
|
+
hash[name] = { record.class => record.id }
|
|
113
|
+
end
|
|
112
114
|
end
|
|
113
115
|
end
|
|
114
116
|
|
|
115
117
|
def statements_by_connection(records)
|
|
116
118
|
deleted_tables = Set.new
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
|
|
120
|
+
records.each_with_object({}) do |(model, sql), grouped|
|
|
119
121
|
connection = model.connection
|
|
120
122
|
grouped[connection] ||= []
|
|
121
123
|
|
|
@@ -127,5 +129,27 @@ module FixtureKit
|
|
|
127
129
|
grouped[connection] << sql if sql
|
|
128
130
|
end
|
|
129
131
|
end
|
|
132
|
+
|
|
133
|
+
def load_memory_data
|
|
134
|
+
file_data = JSON.parse(File.read(path))
|
|
135
|
+
records = file_data.fetch("records").transform_keys do |model_name|
|
|
136
|
+
ActiveSupport::Inflector.constantize(model_name)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
exposed = file_data.fetch("exposed").each_with_object({}) do |(name, value), hash|
|
|
140
|
+
if value.is_a?(Array)
|
|
141
|
+
hash[name.to_sym] = value.map { |r| { ActiveSupport::Inflector.constantize(r.keys.first) => r.values.first } }
|
|
142
|
+
else
|
|
143
|
+
hash[name.to_sym] = { ActiveSupport::Inflector.constantize(value.keys.first) => value.values.first }
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
MemoryData.new(records: records, exposed: exposed)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def save_file_data
|
|
151
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
152
|
+
File.write(path, JSON.pretty_generate(data.to_h))
|
|
153
|
+
end
|
|
130
154
|
end
|
|
131
155
|
end
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module FixtureKit
|
|
4
4
|
class Definition
|
|
5
|
-
attr_reader :exposed, :
|
|
5
|
+
attr_reader :exposed, :extends
|
|
6
6
|
|
|
7
|
-
def initialize(&definition)
|
|
7
|
+
def initialize(extends: nil, &definition)
|
|
8
8
|
@definition = definition
|
|
9
|
-
@source_location = definition.source_location
|
|
10
9
|
@exposed = {}
|
|
10
|
+
@extends = extends
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def evaluate(context)
|
|
14
|
-
context.singleton_class.prepend(mixin)
|
|
13
|
+
def evaluate(context, parent: nil)
|
|
14
|
+
context.singleton_class.prepend(mixin(parent))
|
|
15
15
|
context.instance_exec(&@definition)
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -27,13 +27,17 @@ module FixtureKit
|
|
|
27
27
|
|
|
28
28
|
private
|
|
29
29
|
|
|
30
|
-
def mixin
|
|
30
|
+
def mixin(parent)
|
|
31
31
|
definition = self
|
|
32
32
|
|
|
33
33
|
Module.new do
|
|
34
34
|
define_method(:expose) do |**records|
|
|
35
35
|
definition.expose(**records)
|
|
36
36
|
end
|
|
37
|
+
|
|
38
|
+
define_method(:parent) do
|
|
39
|
+
parent
|
|
40
|
+
end
|
|
37
41
|
end
|
|
38
42
|
end
|
|
39
43
|
end
|
data/lib/fixture_kit/fixture.rb
CHANGED
|
@@ -6,17 +6,23 @@ module FixtureKit
|
|
|
6
6
|
class Fixture
|
|
7
7
|
include ConfigurationHelper
|
|
8
8
|
|
|
9
|
-
attr_reader :identifier, :definition
|
|
9
|
+
attr_reader :identifier, :definition, :parent, :cache
|
|
10
10
|
|
|
11
11
|
def initialize(identifier, definition)
|
|
12
12
|
@identifier = identifier
|
|
13
13
|
@definition = definition
|
|
14
14
|
@cache = Cache.new(self)
|
|
15
|
+
|
|
16
|
+
if definition.extends
|
|
17
|
+
@parent = FixtureKit.runner.registry.add(definition.extends)
|
|
18
|
+
end
|
|
15
19
|
end
|
|
16
20
|
|
|
17
|
-
def
|
|
21
|
+
def generate(force: false)
|
|
18
22
|
return if @cache.exists? && !force
|
|
19
23
|
|
|
24
|
+
parent&.generate
|
|
25
|
+
|
|
20
26
|
emit(:cache_save)
|
|
21
27
|
emit(:cache_saved) { @cache.save }
|
|
22
28
|
end
|
data/lib/fixture_kit/minitest.rb
CHANGED
|
@@ -8,8 +8,10 @@ module FixtureKit
|
|
|
8
8
|
DECLARATION_CLASS_ATTRIBUTE = :fixture_kit_declaration
|
|
9
9
|
|
|
10
10
|
module ClassMethods
|
|
11
|
-
def fixture(name = nil, &
|
|
12
|
-
|
|
11
|
+
def fixture(name = nil, extends: nil, &block)
|
|
12
|
+
definition = Definition.new(extends: extends, &block) if block_given?
|
|
13
|
+
declaration = FixtureKit.runner.register(name || definition, self)
|
|
14
|
+
self.fixture_kit_declaration = declaration
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def run_suite(reporter, options = {})
|
|
@@ -17,7 +19,7 @@ module FixtureKit
|
|
|
17
19
|
if declaration && !filter_runnable_methods(options).empty?
|
|
18
20
|
runner = FixtureKit.runner
|
|
19
21
|
runner.start unless runner.started?
|
|
20
|
-
declaration.
|
|
22
|
+
declaration.generate
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
super
|
data/lib/fixture_kit/registry.rb
CHANGED
|
@@ -7,22 +7,27 @@ module FixtureKit
|
|
|
7
7
|
def initialize
|
|
8
8
|
@declarations = {}
|
|
9
9
|
@fixtures = {}
|
|
10
|
+
@resolving = []
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def add(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
@declarations[scope] =
|
|
18
|
-
case name_or_block
|
|
13
|
+
def add(name_or_definition, scope = nil)
|
|
14
|
+
fixture =
|
|
15
|
+
case name_or_definition
|
|
19
16
|
when String
|
|
20
|
-
fetch_named_fixture(
|
|
21
|
-
when
|
|
22
|
-
|
|
17
|
+
fetch_named_fixture(name_or_definition)
|
|
18
|
+
when Definition
|
|
19
|
+
raise ArgumentError, "scope is required for anonymous fixture declarations" unless scope
|
|
20
|
+
fetch_anonymous_fixture(scope, name_or_definition)
|
|
23
21
|
else
|
|
24
|
-
raise FixtureKit::InvalidFixtureDeclaration, "unsupported fixture declaration type: #{
|
|
22
|
+
raise FixtureKit::InvalidFixtureDeclaration, "unsupported fixture declaration type: #{name_or_definition.class}"
|
|
25
23
|
end
|
|
24
|
+
|
|
25
|
+
if scope
|
|
26
|
+
raise FixtureKit::MultipleFixtures, "cannot load multiple fixtures in the same context" if @declarations.key?(scope)
|
|
27
|
+
@declarations[scope] = fixture
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
fixture
|
|
26
31
|
end
|
|
27
32
|
|
|
28
33
|
def fixtures
|
|
@@ -32,11 +37,23 @@ module FixtureKit
|
|
|
32
37
|
private
|
|
33
38
|
|
|
34
39
|
def fetch_named_fixture(name)
|
|
35
|
-
@fixtures[name]
|
|
40
|
+
return @fixtures[name] if @fixtures.key?(name)
|
|
41
|
+
|
|
42
|
+
if @resolving.include?(name)
|
|
43
|
+
chain = @resolving + [name]
|
|
44
|
+
start = chain.index(name)
|
|
45
|
+
raise FixtureKit::CircularFixtureInheritance,
|
|
46
|
+
"circular fixture inheritance detected: #{chain[start..].join(" -> ")}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
@resolving.push(name)
|
|
50
|
+
@fixtures[name] = Fixture.new(name, load_named_definition(name))
|
|
51
|
+
@resolving.pop
|
|
52
|
+
@fixtures[name]
|
|
36
53
|
end
|
|
37
54
|
|
|
38
55
|
def fetch_anonymous_fixture(scope, definition)
|
|
39
|
-
@fixtures[scope] ||= Fixture.new(scope,
|
|
56
|
+
@fixtures[scope] ||= Fixture.new(scope, definition)
|
|
40
57
|
end
|
|
41
58
|
|
|
42
59
|
def load_named_definition(name)
|
|
@@ -5,7 +5,7 @@ require "active_support/inflector"
|
|
|
5
5
|
module FixtureKit
|
|
6
6
|
class Repository
|
|
7
7
|
def initialize(exposed_records)
|
|
8
|
-
@records = exposed_records
|
|
8
|
+
@records = exposed_records
|
|
9
9
|
@loaded_records = {}
|
|
10
10
|
define_readers
|
|
11
11
|
end
|
|
@@ -33,8 +33,7 @@ module FixtureKit
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def load_record(record_info)
|
|
36
|
-
|
|
37
|
-
model.find_by(id: record_info.fetch("id"))
|
|
36
|
+
record_info.keys.first.find_by(id: record_info.values.first)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
data/lib/fixture_kit/rspec.rb
CHANGED
|
@@ -27,12 +27,13 @@ module FixtureKit
|
|
|
27
27
|
# end
|
|
28
28
|
# end
|
|
29
29
|
# end
|
|
30
|
-
def fixture(name = nil, &
|
|
31
|
-
|
|
30
|
+
def fixture(name = nil, extends: nil, &block)
|
|
31
|
+
definition = Definition.new(extends: extends, &block) if block_given?
|
|
32
|
+
declaration = ::RSpec.configuration.fixture_kit.register(name || definition, self)
|
|
32
33
|
metadata[DECLARATION_METADATA_KEY] = declaration
|
|
33
34
|
|
|
34
35
|
prepend_before(:context) do
|
|
35
|
-
self.class.metadata[DECLARATION_METADATA_KEY].
|
|
36
|
+
self.class.metadata[DECLARATION_METADATA_KEY].generate
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
end
|
data/lib/fixture_kit/runner.rb
CHANGED
|
@@ -15,8 +15,8 @@ module FixtureKit
|
|
|
15
15
|
@started = false
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def register(
|
|
19
|
-
registry.add(
|
|
18
|
+
def register(name_or_definition, scope)
|
|
19
|
+
registry.add(name_or_definition, scope)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def start
|
|
@@ -43,16 +43,5 @@ module FixtureKit
|
|
|
43
43
|
def preserve_cache?
|
|
44
44
|
ENV[PRESERVE_CACHE_ENV_KEY].to_s.match?(/\A(1|true|yes)\z/i)
|
|
45
45
|
end
|
|
46
|
-
|
|
47
|
-
def normalize_registration(name, definition_block)
|
|
48
|
-
if name && definition_block
|
|
49
|
-
raise FixtureKit::InvalidFixtureDeclaration, "cannot provide both fixture name and definition block"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
name_or_block = name || definition_block
|
|
53
|
-
return name_or_block if name_or_block
|
|
54
|
-
|
|
55
|
-
raise FixtureKit::InvalidFixtureDeclaration, "must provide fixture name or definition block"
|
|
56
|
-
end
|
|
57
46
|
end
|
|
58
47
|
end
|
data/lib/fixture_kit/version.rb
CHANGED
data/lib/fixture_kit.rb
CHANGED
|
@@ -8,6 +8,7 @@ module FixtureKit
|
|
|
8
8
|
class CacheMissingError < Error; end
|
|
9
9
|
class FixtureDefinitionNotFound < Error; end
|
|
10
10
|
class RunnerAlreadyStartedError < Error; end
|
|
11
|
+
class CircularFixtureInheritance < Error; end
|
|
11
12
|
|
|
12
13
|
autoload :VERSION, File.expand_path("fixture_kit/version", __dir__)
|
|
13
14
|
autoload :Configuration, File.expand_path("fixture_kit/configuration", __dir__)
|
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.
|
|
4
|
+
version: 0.10.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-
|
|
11
|
+
date: 2026-02-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|