fixtury 0.1.0.alpha → 0.1.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/Gemfile.lock +2 -2
- data/lib/fixtury/definition.rb +18 -5
- data/lib/fixtury/errors/circular_dependency_error.rb +1 -1
- data/lib/fixtury/execution_context.rb +8 -0
- data/lib/fixtury/locator.rb +6 -0
- data/lib/fixtury/reference.rb +16 -0
- data/lib/fixtury/schema.rb +1 -1
- data/lib/fixtury/store.rb +47 -29
- data/lib/fixtury/{hooks.rb → test_hooks.rb} +34 -2
- data/lib/fixtury/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a4447982d6e785c9158850f3d158b07e1226f6a05d85917d41307c5455d41d9
|
4
|
+
data.tar.gz: c7fac4726892a1851ca7b7f0d3ff8abfe2bbedf4d2706b2c3ae6443d6be863f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c5858894f02eb54b555df7ee182e81e3741cbd278e37bbd0a3250b9cfea62a00341d3ff95a75adb0d5f56cfd3abcdb036877bee28601b87ff060c3e9bf6f43c
|
7
|
+
data.tar.gz: 0e99678f39920cd68026905ddd202ea8b9f9648c3bef9e941e7fd084fb2daa1ed843b5d2839fc10cbf13f1cc27c224ac212d7cd01173b2f3f8692706cadde2cb
|
data/Gemfile.lock
CHANGED
data/lib/fixtury/definition.rb
CHANGED
@@ -25,6 +25,8 @@ module Fixtury
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def call(store: nil, execution_context: nil)
|
28
|
+
execution_context ||= ::Fixtury::ExecutionContext.new
|
29
|
+
|
28
30
|
maybe_set_store_context(store: store) do
|
29
31
|
value = run_callable(store: store, callable: callable, execution_context: execution_context, value: nil)
|
30
32
|
enhancements.each do |e|
|
@@ -45,8 +47,6 @@ module Fixtury
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def run_callable(store:, callable:, execution_context:, value:)
|
48
|
-
execution_context ||= self
|
49
|
-
|
50
50
|
args = []
|
51
51
|
args << value unless value.nil?
|
52
52
|
if callable.arity > args.length
|
@@ -55,11 +55,24 @@ module Fixtury
|
|
55
55
|
args << store
|
56
56
|
end
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
execution_context_hooks(execution_context) do
|
59
|
+
if args.length.positive?
|
60
|
+
execution_context.instance_exec(*args, &callable)
|
61
|
+
else
|
62
|
+
execution_context.instance_eval(&callable)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def execution_context_hooks(execution_context)
|
68
|
+
execution_context.before_fixture(self) if execution_context.respond_to?(:before_fixture)
|
69
|
+
value = if execution_context.respond_to?(:around_fixture)
|
70
|
+
execution_context.around_fixture(self) { yield }
|
60
71
|
else
|
61
|
-
|
72
|
+
yield
|
62
73
|
end
|
74
|
+
execution_context.after_fixture(self, value) if execution_context.respond_to?(:after_fixture)
|
75
|
+
value
|
63
76
|
end
|
64
77
|
|
65
78
|
end
|
data/lib/fixtury/locator.rb
CHANGED
@@ -24,6 +24,12 @@ module Fixtury
|
|
24
24
|
@backend = backend
|
25
25
|
end
|
26
26
|
|
27
|
+
def recognize?(ref)
|
28
|
+
raise ArgumentError, "Unable to recognize a nil ref" if ref.nil?
|
29
|
+
|
30
|
+
backend.recognized_reference?(ref)
|
31
|
+
end
|
32
|
+
|
27
33
|
def load(ref)
|
28
34
|
raise ArgumentError, "Unable to load a nil ref" if ref.nil?
|
29
35
|
|
data/lib/fixtury/reference.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Fixtury
|
2
4
|
class Reference
|
3
5
|
|
6
|
+
HOLDER_VALUE = "__BUILDING_FIXTURE__"
|
7
|
+
|
8
|
+
def self.holder(name)
|
9
|
+
new(name, HOLDER_VALUE)
|
10
|
+
end
|
11
|
+
|
4
12
|
attr_reader :name, :value, :created_at
|
5
13
|
|
6
14
|
def initialize(name, value)
|
@@ -9,5 +17,13 @@ module Fixtury
|
|
9
17
|
@created_at = Time.now.to_i
|
10
18
|
end
|
11
19
|
|
20
|
+
def holder?
|
21
|
+
value == HOLDER_VALUE
|
22
|
+
end
|
23
|
+
|
24
|
+
def real?
|
25
|
+
!holder?
|
26
|
+
end
|
27
|
+
|
12
28
|
end
|
13
29
|
end
|
data/lib/fixtury/schema.rb
CHANGED
data/lib/fixtury/store.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "fileutils"
|
3
4
|
require "singleton"
|
4
5
|
require "yaml"
|
5
6
|
require "fixtury/locator"
|
@@ -10,29 +11,36 @@ require "fixtury/reference"
|
|
10
11
|
module Fixtury
|
11
12
|
class Store
|
12
13
|
|
13
|
-
|
14
|
+
LOG_LEVELS = {
|
15
|
+
(LOG_LEVEL_NONE = :none) => 0,
|
16
|
+
(LOG_LEVEL_INFO = :info) => 1,
|
17
|
+
(LOG_LEVEL_DEBUG = :debug) => 2,
|
18
|
+
}.freeze
|
14
19
|
|
15
|
-
|
20
|
+
cattr_accessor :instance
|
16
21
|
|
17
22
|
attr_reader :filepath, :references, :ttl, :auto_refresh_expired
|
18
23
|
attr_reader :schema, :locator
|
19
|
-
attr_reader :
|
24
|
+
attr_reader :log_level
|
20
25
|
attr_reader :execution_context
|
21
26
|
|
22
27
|
def initialize(
|
23
28
|
filepath: nil,
|
24
29
|
locator: ::Fixtury::Locator.instance,
|
25
|
-
|
30
|
+
log_level: nil,
|
26
31
|
ttl: nil,
|
27
32
|
schema: nil,
|
33
|
+
execution_context: nil,
|
28
34
|
auto_refresh_expired: false
|
29
35
|
)
|
30
36
|
@schema = schema || ::Fixtury.schema
|
31
|
-
@
|
37
|
+
@log_level = log_level.nil? ? ENV["FIXTURY_LOG_LEVEL"] : log_level
|
38
|
+
@log_level ||= LOG_LEVEL_NONE
|
39
|
+
@log_level = @log_level.to_s.to_sym
|
32
40
|
@locator = locator
|
33
41
|
@filepath = filepath
|
34
42
|
@references = @filepath && ::File.file?(@filepath) ? ::YAML.load_file(@filepath) : {}
|
35
|
-
@execution_context = ::Fixtury::ExecutionContext.new
|
43
|
+
@execution_context = execution_context || ::Fixtury::ExecutionContext.new
|
36
44
|
@ttl = ttl ? ttl.to_i : ttl
|
37
45
|
@auto_refresh_expired = !!auto_refresh_expired
|
38
46
|
self.class.instance ||= self
|
@@ -41,15 +49,21 @@ module Fixtury
|
|
41
49
|
def dump_to_file
|
42
50
|
return unless filepath
|
43
51
|
|
44
|
-
::File.
|
52
|
+
::FileUtils.mkdir_p(File.dirname(filepath))
|
53
|
+
|
54
|
+
writable = references.each_with_object({}) do |(full_name, ref), h|
|
55
|
+
h[full_name] = ref if ref.real?
|
56
|
+
end
|
57
|
+
|
58
|
+
::File.open(filepath, "wb") { |io| io.write(writable.to_yaml) }
|
45
59
|
end
|
46
60
|
|
47
61
|
def clear_expired_references!
|
48
62
|
return unless ttl
|
49
63
|
|
50
64
|
references.delete_if do |name, ref|
|
51
|
-
is_expired =
|
52
|
-
log { "expiring #{name}" } if is_expired
|
65
|
+
is_expired = ref_invalid?(ref)
|
66
|
+
log(level: LOG_LEVEL_INFO) { "expiring #{name}" } if is_expired
|
53
67
|
is_expired
|
54
68
|
end
|
55
69
|
end
|
@@ -59,7 +73,7 @@ module Fixtury
|
|
59
73
|
get(dfn.name)
|
60
74
|
end
|
61
75
|
|
62
|
-
schema.
|
76
|
+
schema.children.each_pair do |_key, ns|
|
63
77
|
load_all(ns)
|
64
78
|
end
|
65
79
|
end
|
@@ -71,7 +85,7 @@ module Fixtury
|
|
71
85
|
pattern = pattern[0...-1] if glob
|
72
86
|
references.delete_if do |key, _value|
|
73
87
|
hit = glob ? key.start_with?(pattern) : key == pattern
|
74
|
-
log(
|
88
|
+
log(level: LOG_LEVEL_INFO) { "clearing #{key}" } if hit
|
75
89
|
hit
|
76
90
|
end
|
77
91
|
dump_to_file
|
@@ -89,8 +103,8 @@ module Fixtury
|
|
89
103
|
dfn = schema.get_definition!(name)
|
90
104
|
full_name = dfn.name
|
91
105
|
ref = references[full_name]
|
92
|
-
result = ref
|
93
|
-
log { result ? "hit #{full_name}" : "miss #{full_name}" }
|
106
|
+
result = ref&.real?
|
107
|
+
log(level: LOG_LEVEL_DEBUG) { result ? "hit #{full_name}" : "miss #{full_name}" }
|
94
108
|
result
|
95
109
|
end
|
96
110
|
|
@@ -99,34 +113,34 @@ module Fixtury
|
|
99
113
|
full_name = dfn.name
|
100
114
|
ref = references[full_name]
|
101
115
|
|
102
|
-
if ref
|
116
|
+
if ref&.holder?
|
103
117
|
raise ::Fixtury::Errors::CircularDependencyError, full_name
|
104
118
|
end
|
105
119
|
|
106
|
-
if ref && auto_refresh_expired &&
|
107
|
-
log { "refreshing #{full_name}" }
|
108
|
-
clear_ref(
|
120
|
+
if ref && auto_refresh_expired && ref_invalid?(ref)
|
121
|
+
log(level: LOG_LEVEL_INFO) { "refreshing #{full_name}" }
|
122
|
+
clear_ref(full_name)
|
109
123
|
ref = nil
|
110
124
|
end
|
111
125
|
|
112
126
|
value = nil
|
113
127
|
|
114
128
|
if ref
|
115
|
-
log { "hit #{full_name}" }
|
129
|
+
log(level: LOG_LEVEL_DEBUG) { "hit #{full_name}" }
|
116
130
|
value = load_ref(ref.value)
|
117
|
-
|
131
|
+
if value.nil?
|
118
132
|
clear_ref(full_name)
|
119
|
-
log { "missing #{full_name}" }
|
133
|
+
log(level: LOG_LEVEL_DEBUG) { "missing #{full_name}" }
|
120
134
|
end
|
121
135
|
end
|
122
136
|
|
123
137
|
if value.nil?
|
124
|
-
# set the references to
|
125
|
-
references[full_name] =
|
138
|
+
# set the references to a holder value so any recursive behavior ends up hitting a circular dependency error if the same fixture load is attempted
|
139
|
+
references[full_name] = ::Fixtury::Reference.holder(full_name)
|
126
140
|
|
127
141
|
value = dfn.call(store: self, execution_context: execution_context)
|
128
142
|
|
129
|
-
log { "store #{full_name}" }
|
143
|
+
log(level: LOG_LEVEL_INFO) { "store #{full_name}" }
|
130
144
|
|
131
145
|
ref = dump_ref(full_name, value)
|
132
146
|
ref = ::Fixtury::Reference.new(full_name, ref)
|
@@ -149,16 +163,20 @@ module Fixtury
|
|
149
163
|
references.delete(name)
|
150
164
|
end
|
151
165
|
|
152
|
-
def
|
153
|
-
return
|
166
|
+
def ref_invalid?(ref)
|
167
|
+
return true if ttl && ref.created_at < (Time.now.to_i - ttl)
|
154
168
|
|
155
|
-
|
169
|
+
!locator.recognize?(ref.value)
|
156
170
|
end
|
157
171
|
|
158
|
-
def log(
|
159
|
-
|
172
|
+
def log(level: LOG_LEVEL_DEBUG, name: "store")
|
173
|
+
desired_level = LOG_LEVELS.fetch(log_level) { LOG_LEVEL_NONE }
|
174
|
+
return if desired_level == LOG_LEVEL_NONE
|
175
|
+
|
176
|
+
message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
|
177
|
+
return unless desired_level >= message_level
|
160
178
|
|
161
|
-
puts "[fixtury
|
179
|
+
puts "[fixtury|#{name}] #{yield}"
|
162
180
|
end
|
163
181
|
|
164
182
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "fixtury/store"
|
4
4
|
|
5
5
|
module Fixtury
|
6
|
-
module
|
6
|
+
module TestHooks
|
7
7
|
|
8
8
|
extend ::ActiveSupport::Concern
|
9
9
|
|
@@ -18,15 +18,45 @@ module Fixtury
|
|
18
18
|
self.fixtury_dependencies += names.flatten.compact.map(&:to_s)
|
19
19
|
end
|
20
20
|
|
21
|
+
def define_fixture(name, &block)
|
22
|
+
fixture_name = name
|
23
|
+
namespace_names = self.name.underscore.split("/")
|
24
|
+
|
25
|
+
ns = ::Fixtury.schema
|
26
|
+
|
27
|
+
namespace_names.each do |ns_name|
|
28
|
+
ns = ns.namespace(ns_name){}
|
29
|
+
end
|
30
|
+
|
31
|
+
ns.fixture(fixture_name, &block)
|
32
|
+
|
33
|
+
fixtury("#{namespace_names.join("/")}/#{fixture_name}")
|
34
|
+
end
|
35
|
+
|
21
36
|
end
|
22
37
|
|
23
38
|
def fixtury(name)
|
24
|
-
|
39
|
+
return nil unless ::Fixtury::Store.instance
|
40
|
+
|
41
|
+
name = name.to_s
|
42
|
+
|
43
|
+
unless name.include?("/")
|
44
|
+
local_name = "#{self.class.name.underscore}/#{name}"
|
45
|
+
if self.fixtury_dependencies.include?(local_name)
|
46
|
+
return ::Fixtury::Store.instance.get(local_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
unless self.fixtury_dependencies.include?(name)
|
51
|
+
raise ArgumentError, "Unrecognized fixtury dependency `#{name}` for #{self.class}"
|
52
|
+
end
|
25
53
|
|
26
54
|
::Fixtury::Store.instance.get(name)
|
27
55
|
end
|
28
56
|
|
29
57
|
def fixtury_loaded?(name)
|
58
|
+
return false unless ::Fixtury::Store.instance
|
59
|
+
|
30
60
|
::Fixtury::Store.instance.loaded?(name)
|
31
61
|
end
|
32
62
|
|
@@ -70,6 +100,8 @@ module Fixtury
|
|
70
100
|
end
|
71
101
|
|
72
102
|
def clear_expired_fixtury_fixtures!
|
103
|
+
return unless ::Fixtury::Store.instance
|
104
|
+
|
73
105
|
::Fixtury::Store.instance.clear_expired_references!
|
74
106
|
end
|
75
107
|
|
data/lib/fixtury/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fixtury
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: autotest
|
@@ -161,7 +161,6 @@ files:
|
|
161
161
|
- lib/fixtury/errors/schema_frozen_error.rb
|
162
162
|
- lib/fixtury/errors/unrecognizable_locator_error.rb
|
163
163
|
- lib/fixtury/execution_context.rb
|
164
|
-
- lib/fixtury/hooks.rb
|
165
164
|
- lib/fixtury/locator.rb
|
166
165
|
- lib/fixtury/locator_backend/common.rb
|
167
166
|
- lib/fixtury/locator_backend/globalid.rb
|
@@ -172,6 +171,7 @@ files:
|
|
172
171
|
- lib/fixtury/schema.rb
|
173
172
|
- lib/fixtury/store.rb
|
174
173
|
- lib/fixtury/tasks.rake
|
174
|
+
- lib/fixtury/test_hooks.rb
|
175
175
|
- lib/fixtury/version.rb
|
176
176
|
homepage: https://github.com/guideline-tech/fixtury
|
177
177
|
licenses: []
|
@@ -191,9 +191,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
191
|
version: '0'
|
192
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
193
|
requirements:
|
194
|
-
- - "
|
194
|
+
- - ">="
|
195
195
|
- !ruby/object:Gem::Version
|
196
|
-
version:
|
196
|
+
version: '0'
|
197
197
|
requirements: []
|
198
198
|
rubygems_version: 3.0.6
|
199
199
|
signing_key:
|