fixture_kit 0.19.0 → 0.20.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 +25 -1
- data/lib/fixture_kit/definition.rb +11 -0
- data/lib/fixture_kit/fixture.rb +2 -0
- data/lib/fixture_kit/registry.rb +18 -0
- 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: 90cf1c283943f0ec2cf0c82b5f5b6b65de810a1e4e5ed8d15fd12c4b2ba64879
|
|
4
|
+
data.tar.gz: 2eb935b512b373c399220ed60a6250b3d32349aa9dc5e4c31801d3db45a94b94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a4f49bf2e6422be97e8a316acfd623c9e27c861bc63c29465dc6d8fb331ddbff85a84aeede77d654e4e544096061b62c8aa9daa3bfac23ec5ae7d6dfc8db957
|
|
7
|
+
data.tar.gz: a799c0b665d6396837fb82ee50d6e193e3adde8114f0edb63d3f3ed5540205b486587a5ff1065ea5811c2b61fa0ed9cb10f0c43fba18da9b15eb0a913b76f660
|
data/lib/fixture_kit/cache.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "digest"
|
|
4
|
+
|
|
3
5
|
module FixtureKit
|
|
4
6
|
class Cache
|
|
5
7
|
ANONYMOUS_DIRECTORY = "_anonymous"
|
|
8
|
+
DIGEST_LENGTH = 12
|
|
6
9
|
|
|
7
10
|
include ConfigurationHelper
|
|
8
11
|
|
|
@@ -22,7 +25,8 @@ module FixtureKit
|
|
|
22
25
|
if raw_identifier.is_a?(String)
|
|
23
26
|
raw_identifier
|
|
24
27
|
else
|
|
25
|
-
|
|
28
|
+
normalized_scope = FixtureKit.runner.adapter.identifier_for(raw_identifier)
|
|
29
|
+
File.join(ANONYMOUS_DIRECTORY, "#{normalized_scope}.#{definition_digest}")
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
end
|
|
@@ -62,6 +66,26 @@ module FixtureKit
|
|
|
62
66
|
|
|
63
67
|
private
|
|
64
68
|
|
|
69
|
+
# The scope name alone does not identify a declaration site. Test
|
|
70
|
+
# frameworks derive it from the group description, which is lossy -- RSpec
|
|
71
|
+
# strips every non-alphanumeric character, so `Foo::Bar` and `"Foo Bar"`
|
|
72
|
+
# both become `FooBar` -- and, worse, not even unique within a process:
|
|
73
|
+
# test runners that load specs in batches call RSpec::Core::World#reset
|
|
74
|
+
# between them, which drops the constants RSpec disambiguates against, so
|
|
75
|
+
# the first group of a given description in *every* batch takes the
|
|
76
|
+
# unsuffixed name. The cache directory is cleared once per process, so
|
|
77
|
+
# without the digest two spec files sharing a top-level description share
|
|
78
|
+
# this entry, and the second fixture to generate silently mounts the
|
|
79
|
+
# first's records.
|
|
80
|
+
#
|
|
81
|
+
# Joined to the scope with a dot rather than an underscore: scope names are
|
|
82
|
+
# snake_case, so an underscore leaves no boundary between the two, while a
|
|
83
|
+
# dot cannot appear in one -- RSpec strips non-alphanumerics from the group
|
|
84
|
+
# description before it is underscored.
|
|
85
|
+
def definition_digest
|
|
86
|
+
Digest::SHA256.hexdigest(fixture.definition.fingerprint)[0, DIGEST_LENGTH]
|
|
87
|
+
end
|
|
88
|
+
|
|
65
89
|
def evaluate(coders, context, data = {}, &block)
|
|
66
90
|
if coders.empty?
|
|
67
91
|
fixture.definition.evaluate(context, parent: fixture.parent&.mount)
|
|
@@ -14,6 +14,17 @@ module FixtureKit
|
|
|
14
14
|
@definition.source_location.first
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def location
|
|
18
|
+
file, line = @definition.source_location
|
|
19
|
+
"#{file}:#{line}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Two definitions sharing a fingerprint evaluate the same block against the
|
|
23
|
+
# same parent, so they are interchangeable and may share a cache entry.
|
|
24
|
+
def fingerprint
|
|
25
|
+
"#{location}:#{extends}"
|
|
26
|
+
end
|
|
27
|
+
|
|
17
28
|
def evaluate(context, parent: nil)
|
|
18
29
|
context.singleton_class.prepend(mixin(parent))
|
|
19
30
|
context.instance_exec(&@definition)
|
data/lib/fixture_kit/fixture.rb
CHANGED
data/lib/fixture_kit/registry.rb
CHANGED
|
@@ -8,6 +8,7 @@ module FixtureKit
|
|
|
8
8
|
@declarations = {}
|
|
9
9
|
@fixtures = {}
|
|
10
10
|
@resolving = []
|
|
11
|
+
@cache_owners = {}
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def add(name_or_definition, scope = nil)
|
|
@@ -34,6 +35,23 @@ module FixtureKit
|
|
|
34
35
|
@fixtures.values
|
|
35
36
|
end
|
|
36
37
|
|
|
38
|
+
# Fixtures sharing a cache identifier share a cache file: the second one to
|
|
39
|
+
# generate finds the file already written, skips generation, and mounts the
|
|
40
|
+
# other's records. That is only safe when both declarations are the same, so
|
|
41
|
+
# anything else has to fail here -- otherwise it surfaces as a confusing
|
|
42
|
+
# NoMethodError on Repository, or not at all when both expose the same names.
|
|
43
|
+
# Identifiers are derived from the declaration site, so this is a backstop
|
|
44
|
+
# against a digest collision or a regression in that derivation.
|
|
45
|
+
def claim_cache_identifier(fixture)
|
|
46
|
+
owner = (@cache_owners[fixture.cache.identifier] ||= fixture)
|
|
47
|
+
return if owner.equal?(fixture)
|
|
48
|
+
return if owner.definition.fingerprint == fixture.definition.fingerprint
|
|
49
|
+
|
|
50
|
+
raise FixtureKit::CacheIdentifierCollision,
|
|
51
|
+
"fixtures declared at #{owner.definition.location} and #{fixture.definition.location} " \
|
|
52
|
+
"both resolve to the cache identifier '#{fixture.cache.identifier}'"
|
|
53
|
+
end
|
|
54
|
+
|
|
37
55
|
private
|
|
38
56
|
|
|
39
57
|
def fetch_named_fixture(name)
|
data/lib/fixture_kit/version.rb
CHANGED
data/lib/fixture_kit.rb
CHANGED
|
@@ -6,6 +6,7 @@ module FixtureKit
|
|
|
6
6
|
class InvalidFixtureDeclaration < Error; end
|
|
7
7
|
class MultipleFixtures < Error; end
|
|
8
8
|
class CacheMissingError < Error; end
|
|
9
|
+
class CacheIdentifierCollision < Error; end
|
|
9
10
|
class FixtureDefinitionNotFound < Error; end
|
|
10
11
|
class RunnerAlreadyStartedError < Error; end
|
|
11
12
|
class CircularFixtureInheritance < Error; 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.
|
|
4
|
+
version: 0.20.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-08-
|
|
11
|
+
date: 2026-08-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|