fixtury 0.3.2 → 0.4.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/fixtury.rb +35 -1
- data/lib/fixtury/definition.rb +4 -1
- data/lib/fixtury/errors/option_collision_error.rb +13 -0
- data/lib/fixtury/errors/schema_frozen_error.rb +2 -0
- data/lib/fixtury/reference.rb +7 -2
- data/lib/fixtury/schema.rb +23 -10
- data/lib/fixtury/store.rb +9 -25
- data/lib/fixtury/test_hooks.rb +28 -11
- data/lib/fixtury/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35c4db20425a837221a7c979e51371b77e00790cded54b182b31e62f7f57d8c2
|
4
|
+
data.tar.gz: cbdb024ba301b393b97604879594c1d9d53bfe1ffd4f24959824e8f41e1fe4e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4748b476b6683ac9275a0c62ebca36f346f5d2bea208d47f55dfd836b521283c383aee7847961ffc90726292fd187389fc65b650dd508f9c67288fa32ae88c6c
|
7
|
+
data.tar.gz: bc765697630a9780752ab2ab9512dbe6bd92cee4f612dfa1ba11437d1f59f3e0c58a7d5a107576704d0018507ce989bf2e8726c165f244bf8757676c301a4f4d
|
data/Gemfile.lock
CHANGED
data/lib/fixtury.rb
CHANGED
@@ -8,8 +8,18 @@ require "fixtury/schema"
|
|
8
8
|
require "fixtury/locator"
|
9
9
|
require "fixtury/store"
|
10
10
|
|
11
|
+
# Top level namespace of the gem
|
11
12
|
module Fixtury
|
12
13
|
|
14
|
+
LOG_LEVELS = {
|
15
|
+
(LOG_LEVEL_NONE = :none) => 0,
|
16
|
+
(LOG_LEVEL_INFO = :info) => 1,
|
17
|
+
(LOG_LEVEL_DEBUG = :debug) => 2,
|
18
|
+
(LOG_LEVEL_ALL = :all) => 3,
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
DEFAULT_LOG_LEVEL = LOG_LEVEL_INFO
|
22
|
+
|
13
23
|
# Shortcut for opening the top level schema.
|
14
24
|
def self.define(&block)
|
15
25
|
schema.define(&block)
|
@@ -19,7 +29,31 @@ module Fixtury
|
|
19
29
|
# The default top level schema. Fixtury::Schema instances can be completely self-contained but most
|
20
30
|
# usage would be through this shared definition.
|
21
31
|
def self.schema
|
22
|
-
@
|
32
|
+
@schema ||= ::Fixtury::Schema.new(parent: nil, name: "")
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.log_level
|
36
|
+
return @log_level if @log_level
|
37
|
+
|
38
|
+
@log_level = ENV["FIXTURY_LOG_LEVEL"]
|
39
|
+
@log_level ||= DEFAULT_LOG_LEVEL
|
40
|
+
@log_level = @log_level.to_s.to_sym
|
41
|
+
@log_level
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.log(text = nil, level: LOG_LEVEL_DEBUG, name: nil)
|
45
|
+
desired_level = LOG_LEVELS.fetch(log_level) { DEFAULT_LOG_LEVEL }
|
46
|
+
return if desired_level == LOG_LEVEL_NONE
|
47
|
+
|
48
|
+
message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
|
49
|
+
return unless desired_level >= message_level
|
50
|
+
|
51
|
+
msg = +"[fixtury"
|
52
|
+
msg << "|#{name}" if name
|
53
|
+
msg << "]"
|
54
|
+
msg << " #{text}" if text
|
55
|
+
msg << " #{yield}" if block_given?
|
56
|
+
puts msg
|
23
57
|
end
|
24
58
|
|
25
59
|
end
|
data/lib/fixtury/definition.rb
CHANGED
@@ -7,14 +7,17 @@ module Fixtury
|
|
7
7
|
|
8
8
|
attr_reader :name
|
9
9
|
attr_reader :schema
|
10
|
+
alias parent schema
|
11
|
+
attr_reader :options
|
10
12
|
|
11
13
|
attr_reader :callable
|
12
14
|
attr_reader :enhancements
|
13
15
|
|
14
|
-
def initialize(schema: nil, name:, &block)
|
16
|
+
def initialize(schema: nil, name:, options: {}, &block)
|
15
17
|
@name = name
|
16
18
|
@schema = schema
|
17
19
|
@callable = block
|
20
|
+
@options = options
|
18
21
|
@enhancements = []
|
19
22
|
end
|
20
23
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fixtury
|
4
|
+
module Errors
|
5
|
+
class OptionCollisionError < ::StandardError
|
6
|
+
|
7
|
+
def initialize(schema_name, option_key, old_value, new_value)
|
8
|
+
super("The #{schema_name.inspect} schema #{option_key.inspect} option value of #{old_value.inspect} conflicts with the new value #{new_value.inspect}.")
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/fixtury/reference.rb
CHANGED
@@ -9,12 +9,17 @@ module Fixtury
|
|
9
9
|
new(name, HOLDER_VALUE)
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
def self.create(name, value)
|
13
|
+
new(name, value)
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :name, :value, :created_at, :options
|
13
17
|
|
14
|
-
def initialize(name, value)
|
18
|
+
def initialize(name, value, options = {})
|
15
19
|
@name = name
|
16
20
|
@value = value
|
17
21
|
@created_at = Time.now.to_i
|
22
|
+
@options = options
|
18
23
|
end
|
19
24
|
|
20
25
|
def holder?
|
data/lib/fixtury/schema.rb
CHANGED
@@ -5,21 +5,33 @@ require "fixtury/path"
|
|
5
5
|
require "fixtury/errors/already_defined_error"
|
6
6
|
require "fixtury/errors/fixture_not_defined_error"
|
7
7
|
require "fixtury/errors/schema_frozen_error"
|
8
|
+
require "fixtury/errors/option_collision_error"
|
8
9
|
|
9
10
|
module Fixtury
|
10
11
|
class Schema
|
11
12
|
|
12
|
-
attr_reader :definitions, :children, :name, :parent, :relative_name, :around_fixture_definition
|
13
|
+
attr_reader :definitions, :children, :name, :parent, :relative_name, :around_fixture_definition, :options
|
13
14
|
|
14
15
|
def initialize(parent:, name:)
|
15
16
|
@name = name
|
16
17
|
@parent = parent
|
17
18
|
@relative_name = @name.split("/").last
|
18
19
|
@around_fixture_definition = nil
|
20
|
+
@options = {}
|
19
21
|
@frozen = false
|
20
22
|
reset!
|
21
23
|
end
|
22
24
|
|
25
|
+
def merge_options(opts = {})
|
26
|
+
opts.each_pair do |k, v|
|
27
|
+
if options.key?(k) && options[k] != v
|
28
|
+
raise ::Fixtury::Errors::OptionCollisionError.new(name, k, options[k], v)
|
29
|
+
end
|
30
|
+
|
31
|
+
options[k] = v
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
23
35
|
def around_fixture(&block)
|
24
36
|
@around_fixture_definition = block
|
25
37
|
end
|
@@ -83,19 +95,19 @@ module Fixtury
|
|
83
95
|
out.join("\n")
|
84
96
|
end
|
85
97
|
|
86
|
-
def namespace(name, &block)
|
98
|
+
def namespace(name, options = {}, &block)
|
87
99
|
ensure_not_frozen!
|
88
100
|
ensure_no_conflict!(name: name, definitions: true, namespaces: false)
|
89
101
|
|
90
|
-
child = find_or_create_child_schema(name: name)
|
102
|
+
child = find_or_create_child_schema(name: name, options: options)
|
91
103
|
child.instance_eval(&block) if block_given?
|
92
104
|
child
|
93
105
|
end
|
94
106
|
|
95
|
-
def fixture(name, &block)
|
107
|
+
def fixture(name, options = {}, &block)
|
96
108
|
ensure_not_frozen!
|
97
109
|
ensure_no_conflict!(name: name, definitions: true, namespaces: true)
|
98
|
-
create_child_definition(name: name, &block)
|
110
|
+
create_child_definition(name: name, options: options, &block)
|
99
111
|
end
|
100
112
|
|
101
113
|
def enhance(name, &block)
|
@@ -108,14 +120,14 @@ module Fixtury
|
|
108
120
|
def merge(other_ns)
|
109
121
|
ensure_not_frozen!
|
110
122
|
other_ns.definitions.each_pair do |name, dfn|
|
111
|
-
fixture(name, &dfn.callable)
|
123
|
+
fixture(name, dfn.options, &dfn.callable)
|
112
124
|
dfn.enhancements.each do |e|
|
113
125
|
enhance(name, &e)
|
114
126
|
end
|
115
127
|
end
|
116
128
|
|
117
129
|
other_ns.children.each_pair do |name, other_ns_child|
|
118
|
-
namespace(name) do
|
130
|
+
namespace(name, other_ns_child.options) do
|
119
131
|
merge(other_ns_child)
|
120
132
|
end
|
121
133
|
end
|
@@ -186,7 +198,7 @@ module Fixtury
|
|
186
198
|
children[name.to_s]
|
187
199
|
end
|
188
200
|
|
189
|
-
def find_or_create_child_schema(name:)
|
201
|
+
def find_or_create_child_schema(name:, options:)
|
190
202
|
name = name.to_s
|
191
203
|
child = find_child_schema(name: name)
|
192
204
|
child ||= begin
|
@@ -195,6 +207,7 @@ module Fixtury
|
|
195
207
|
self.class.new(name: child_name, parent: self)
|
196
208
|
end
|
197
209
|
end
|
210
|
+
child.merge_options(options)
|
198
211
|
child
|
199
212
|
end
|
200
213
|
|
@@ -202,9 +215,9 @@ module Fixtury
|
|
202
215
|
definitions[name.to_s]
|
203
216
|
end
|
204
217
|
|
205
|
-
def create_child_definition(name:, &block)
|
218
|
+
def create_child_definition(name:, options:, &block)
|
206
219
|
child_name = build_child_name(name: name)
|
207
|
-
definition = ::Fixtury::Definition.new(name: child_name, schema: self, &block)
|
220
|
+
definition = ::Fixtury::Definition.new(name: child_name, schema: self, options: options, &block)
|
208
221
|
definitions[name.to_s] = definition
|
209
222
|
end
|
210
223
|
|
data/lib/fixtury/store.rb
CHANGED
@@ -10,12 +10,6 @@ require "fixtury/reference"
|
|
10
10
|
module Fixtury
|
11
11
|
class Store
|
12
12
|
|
13
|
-
LOG_LEVELS = {
|
14
|
-
(LOG_LEVEL_NONE = :none) => 0,
|
15
|
-
(LOG_LEVEL_INFO = :info) => 1,
|
16
|
-
(LOG_LEVEL_DEBUG = :debug) => 2,
|
17
|
-
}.freeze
|
18
|
-
|
19
13
|
cattr_accessor :instance
|
20
14
|
|
21
15
|
attr_reader :filepath, :references, :ttl, :auto_refresh_expired
|
@@ -25,15 +19,11 @@ module Fixtury
|
|
25
19
|
def initialize(
|
26
20
|
filepath: nil,
|
27
21
|
locator: ::Fixtury::Locator.instance,
|
28
|
-
log_level: nil,
|
29
22
|
ttl: nil,
|
30
23
|
schema: nil,
|
31
24
|
auto_refresh_expired: false
|
32
25
|
)
|
33
26
|
@schema = schema || ::Fixtury.schema
|
34
|
-
@log_level = log_level.nil? ? ENV["FIXTURY_LOG_LEVEL"] : log_level
|
35
|
-
@log_level ||= LOG_LEVEL_NONE
|
36
|
-
@log_level = @log_level.to_s.to_sym
|
37
27
|
@locator = locator
|
38
28
|
@filepath = filepath
|
39
29
|
@references = @filepath && ::File.file?(@filepath) ? ::YAML.load_file(@filepath) : {}
|
@@ -59,7 +49,7 @@ module Fixtury
|
|
59
49
|
|
60
50
|
references.delete_if do |name, ref|
|
61
51
|
is_expired = ref_invalid?(ref)
|
62
|
-
log(
|
52
|
+
log("expiring #{name}", level: LOG_LEVEL_DEBUG) if is_expired
|
63
53
|
is_expired
|
64
54
|
end
|
65
55
|
end
|
@@ -81,7 +71,7 @@ module Fixtury
|
|
81
71
|
pattern = pattern[0...-1] if glob
|
82
72
|
references.delete_if do |key, _value|
|
83
73
|
hit = glob ? key.start_with?(pattern) : key == pattern
|
84
|
-
log(
|
74
|
+
log("clearing #{key}", level: LOG_LEVEL_DEBUG) if hit
|
85
75
|
hit
|
86
76
|
end
|
87
77
|
dump_to_file
|
@@ -100,7 +90,7 @@ module Fixtury
|
|
100
90
|
full_name = dfn.name
|
101
91
|
ref = references[full_name]
|
102
92
|
result = ref&.real?
|
103
|
-
log(
|
93
|
+
log(result ? "hit #{full_name}" : "miss #{full_name}", level: LOG_LEVEL_ALL)
|
104
94
|
result
|
105
95
|
end
|
106
96
|
|
@@ -114,7 +104,7 @@ module Fixtury
|
|
114
104
|
end
|
115
105
|
|
116
106
|
if ref && auto_refresh_expired && ref_invalid?(ref)
|
117
|
-
log(
|
107
|
+
log("refreshing #{full_name}", level: LOG_LEVEL_DEBUG)
|
118
108
|
clear_ref(full_name)
|
119
109
|
ref = nil
|
120
110
|
end
|
@@ -122,11 +112,11 @@ module Fixtury
|
|
122
112
|
value = nil
|
123
113
|
|
124
114
|
if ref
|
125
|
-
log(
|
115
|
+
log("hit #{full_name}", level: LOG_LEVEL_ALL)
|
126
116
|
value = load_ref(ref.value)
|
127
117
|
if value.nil?
|
128
118
|
clear_ref(full_name)
|
129
|
-
log(
|
119
|
+
log("missing #{full_name}", level: LOG_LEVEL_ALL)
|
130
120
|
end
|
131
121
|
end
|
132
122
|
|
@@ -136,7 +126,7 @@ module Fixtury
|
|
136
126
|
|
137
127
|
value = dfn.call(store: self, execution_context: execution_context)
|
138
128
|
|
139
|
-
log(
|
129
|
+
log("store #{full_name}", level: LOG_LEVEL_DEBUG)
|
140
130
|
|
141
131
|
ref = dump_ref(full_name, value)
|
142
132
|
ref = ::Fixtury::Reference.new(full_name, ref)
|
@@ -165,14 +155,8 @@ module Fixtury
|
|
165
155
|
!locator.recognize?(ref.value)
|
166
156
|
end
|
167
157
|
|
168
|
-
def log(
|
169
|
-
|
170
|
-
return if desired_level == LOG_LEVEL_NONE
|
171
|
-
|
172
|
-
message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
|
173
|
-
return unless desired_level >= message_level
|
174
|
-
|
175
|
-
puts "[fixtury|#{name}] #{yield}"
|
158
|
+
def log(msg, level:)
|
159
|
+
::Fixtury.log(msg, level: level, name: "store")
|
176
160
|
end
|
177
161
|
|
178
162
|
end
|
data/lib/fixtury/test_hooks.rb
CHANGED
@@ -33,9 +33,11 @@ module Fixtury
|
|
33
33
|
ns = ns.namespace(ns_name){}
|
34
34
|
end
|
35
35
|
|
36
|
-
names.
|
36
|
+
names.map! do |fixture_name|
|
37
37
|
ns.fixture(fixture_name, &definition)
|
38
|
-
|
38
|
+
new_name = "/#{namespace}/#{fixture_name}"
|
39
|
+
self.local_fixtury_dependencies += [new_name]
|
40
|
+
new_name
|
39
41
|
end
|
40
42
|
|
41
43
|
# otherwise, just record the dependency
|
@@ -43,12 +45,14 @@ module Fixtury
|
|
43
45
|
self.fixtury_dependencies += names.flatten.compact.map(&:to_s)
|
44
46
|
end
|
45
47
|
|
46
|
-
accessor_option = opts
|
48
|
+
accessor_option = opts[:as]
|
49
|
+
accessor_option = opts[:accessor] if accessor_option.nil? # old version, backwards compatability
|
50
|
+
accessor_option = accessor_option.nil? ? true : accessor_option
|
47
51
|
|
48
52
|
if accessor_option
|
49
53
|
|
50
54
|
if accessor_option != true && names.length > 1
|
51
|
-
raise ArgumentError, "A named :
|
55
|
+
raise ArgumentError, "A named :as option is only available when providing one fixture"
|
52
56
|
end
|
53
57
|
|
54
58
|
names.each do |fixture_name|
|
@@ -78,12 +82,15 @@ module Fixtury
|
|
78
82
|
|
79
83
|
name = name.to_s
|
80
84
|
|
81
|
-
|
82
|
-
|
83
|
-
|
85
|
+
# in the case that we're looking for a relative fixture, see if it's registered relative to the test's namespace.
|
86
|
+
unless name.include?("/")
|
87
|
+
local_name = "/#{self.class.fixtury_namespace}/#{name}"
|
88
|
+
if local_fixtury_dependencies.include?(local_name)
|
89
|
+
return fixtury_store.get(local_name, execution_context: self)
|
90
|
+
end
|
84
91
|
end
|
85
92
|
|
86
|
-
unless
|
93
|
+
unless fixtury_dependencies.include?(name) || local_fixtury_dependencies.include?(name)
|
87
94
|
raise ArgumentError, "Unrecognized fixtury dependency `#{name}` for #{self.class}"
|
88
95
|
end
|
89
96
|
|
@@ -123,7 +130,7 @@ module Fixtury
|
|
123
130
|
end
|
124
131
|
|
125
132
|
def setup_fixtury_fixtures
|
126
|
-
return unless
|
133
|
+
return unless fixtury_use_transactions?
|
127
134
|
|
128
135
|
clear_expired_fixtury_fixtures!
|
129
136
|
load_all_fixtury_fixtures!
|
@@ -134,7 +141,7 @@ module Fixtury
|
|
134
141
|
end
|
135
142
|
|
136
143
|
def teardown_fixtury_fixtures
|
137
|
-
return unless
|
144
|
+
return unless fixtury_use_transactions?
|
138
145
|
|
139
146
|
fixtury_database_connections.each(&:rollback_transaction)
|
140
147
|
end
|
@@ -147,9 +154,19 @@ module Fixtury
|
|
147
154
|
|
148
155
|
def load_all_fixtury_fixtures!
|
149
156
|
(fixtury_dependencies | local_fixtury_dependencies).each do |name|
|
150
|
-
|
157
|
+
unless fixtury_loaded?(name)
|
158
|
+
::Fixtury.log("preloading #{name.inspect}", name: "test", level: ::Fixtury::LOG_LEVEL_INFO)
|
159
|
+
fixtury(name)
|
160
|
+
end
|
151
161
|
end
|
152
162
|
end
|
153
163
|
|
164
|
+
def fixtury_use_transactions?
|
165
|
+
return use_transactional_tests if respond_to?(:use_transactional_tests)
|
166
|
+
return use_transactional_fixtures if respond_to?(:use_transactional_fixtures)
|
167
|
+
|
168
|
+
true
|
169
|
+
end
|
170
|
+
|
154
171
|
end
|
155
172
|
end
|
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.
|
4
|
+
version: 0.4.1
|
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-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: autotest
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/fixtury/errors/already_defined_error.rb
|
160
160
|
- lib/fixtury/errors/circular_dependency_error.rb
|
161
161
|
- lib/fixtury/errors/fixture_not_defined_error.rb
|
162
|
+
- lib/fixtury/errors/option_collision_error.rb
|
162
163
|
- lib/fixtury/errors/schema_frozen_error.rb
|
163
164
|
- lib/fixtury/errors/unrecognizable_locator_error.rb
|
164
165
|
- lib/fixtury/locator.rb
|