fixtury 1.0.0.beta1 → 1.0.0.beta2
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/configuration.rb +117 -0
- data/lib/fixtury/definition.rb +0 -7
- data/lib/fixtury/locator.rb +18 -0
- data/lib/fixtury/locator_backend/{globalid.rb → global_id.rb} +1 -1
- data/lib/fixtury/locator_backend/memory.rb +3 -2
- data/lib/fixtury/schema.rb +32 -6
- data/lib/fixtury/schema_node.rb +72 -10
- data/lib/fixtury/store.rb +116 -77
- data/lib/fixtury/test_hooks.rb +85 -32
- data/lib/fixtury/version.rb +1 -1
- data/lib/fixtury.rb +41 -8
- metadata +4 -4
- data/lib/fixtury/tasks.rake +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd14efe323fc1de1a2ec63805508e7fb816db30f028998e951c78e95cbe14dfe
|
4
|
+
data.tar.gz: e0a1055bf1ebfff930569a5b678b1b433c21b48e2a4305197bdeb7938e22332a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d819ff4d3096eee7a2ac3c4617f89463b28b7826f3046efbf391408b595b8758f52ac556c8e337eae396109839a148a033750b2ae5ac10ebddce27a041344be3
|
7
|
+
data.tar.gz: febce1127eceb8f3ef6e148b7212591e657dab0d62f4b57d0ab6e8b6f8ba8d9c210180f6713fe78d5de6ce35356a5c448cfd9903d60a406efe5bc835c9cbbe11
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
require "digest"
|
2
|
+
|
3
|
+
module Fixtury
|
4
|
+
# Provides an interface for managing settings and dependencies related to fixture
|
5
|
+
# generation.
|
6
|
+
class Configuration
|
7
|
+
|
8
|
+
attr_reader :filepath, :fixture_files, :dependency_files
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@filepath = nil
|
12
|
+
@fixture_files = Set.new
|
13
|
+
@dependency_files = Set.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_level
|
17
|
+
return @log_level if @log_level
|
18
|
+
|
19
|
+
@log_level = ENV["FIXTURY_LOG_LEVEL"]
|
20
|
+
@log_level ||= DEFAULT_LOG_LEVEL
|
21
|
+
@log_level = @log_level.to_s.to_sym
|
22
|
+
@log_level
|
23
|
+
end
|
24
|
+
|
25
|
+
# Delete the storage file if it exists.
|
26
|
+
def reset
|
27
|
+
File.delete(filepath) if filepath && File.file?(filepath)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Set the location of the storage file. The storage file will maintain
|
31
|
+
# checksums of all tracked files and serialized references to fixtures.
|
32
|
+
#
|
33
|
+
# @param path [String] The path to the storage file.
|
34
|
+
def filepath=(path)
|
35
|
+
@filepath = path.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add a file or glob pattern to the list of fixture files.
|
39
|
+
#
|
40
|
+
# @param path_or_globs [String, Array<String>] The file or glob pattern(s) to add.
|
41
|
+
def add_fixture_path(*path_or_globs)
|
42
|
+
@fixture_files = fixture_files | Dir[*path_or_globs]
|
43
|
+
end
|
44
|
+
alias add_fixture_paths add_fixture_path
|
45
|
+
|
46
|
+
# Add a file or glob pattern to the list of dependency files.
|
47
|
+
#
|
48
|
+
# @param path_or_globs [String, Array<String>] The file or glob pattern(s) to add.
|
49
|
+
def add_dependency_path(*path_or_globs)
|
50
|
+
@dependency_files = dependency_files | Dir[*path_or_globs]
|
51
|
+
end
|
52
|
+
alias add_dependency_paths add_dependency_path
|
53
|
+
|
54
|
+
# The references stored in the dependency file. When stores are initialized
|
55
|
+
# these will be used to bootstrap the references.
|
56
|
+
#
|
57
|
+
# @return [Hash] The references stored in the dependency file.
|
58
|
+
def stored_references
|
59
|
+
return {} if stored_data.nil?
|
60
|
+
|
61
|
+
stored_data[:references] || {}
|
62
|
+
end
|
63
|
+
|
64
|
+
# Dump the current state of the dependency manager to the storage file.
|
65
|
+
def dump_file
|
66
|
+
return unless filepath
|
67
|
+
|
68
|
+
FileUtils.mkdir_p(File.dirname(filepath))
|
69
|
+
File.binwrite(filepath, file_data.to_yaml)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def file_data
|
75
|
+
checksums = {}
|
76
|
+
calculate_checksums do |filepath, checksum|
|
77
|
+
checksums[filepath] = checksum
|
78
|
+
end
|
79
|
+
|
80
|
+
{
|
81
|
+
dependencies: checksums,
|
82
|
+
references: ::Fixtury.store.references,
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def stored_data
|
87
|
+
return nil unless filepath
|
88
|
+
return nil unless File.file?(filepath)
|
89
|
+
|
90
|
+
YAML.unsafe_load_file(filepath)
|
91
|
+
end
|
92
|
+
|
93
|
+
def files_changed?
|
94
|
+
return true if stored_data.nil?
|
95
|
+
|
96
|
+
stored_checksums = (stored_data[:dependencies] || {})
|
97
|
+
seen_filepaths = []
|
98
|
+
calculate_checksums do |filepath, checksum|
|
99
|
+
# Early return if the checksums don't match
|
100
|
+
return true unless stored_checksums[filepath] == checksum
|
101
|
+
|
102
|
+
seen_filepaths << filepath
|
103
|
+
end
|
104
|
+
|
105
|
+
# If we have a new file or a file has been removed, we need to report a change.
|
106
|
+
seen_filepaths.sort != stored_checksums.keys.sort
|
107
|
+
end
|
108
|
+
|
109
|
+
def calculate_checksums(&block)
|
110
|
+
(fixture_files.to_a | dependency_files.to_a).sort.each do |filepath|
|
111
|
+
yield filepath, Digest::MD5.file(filepath).hexdigest
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
data/lib/fixtury/definition.rb
CHANGED
@@ -28,13 +28,6 @@ module Fixtury
|
|
28
28
|
@callable = block
|
29
29
|
end
|
30
30
|
|
31
|
-
# Returns the type of the schema node.
|
32
|
-
#
|
33
|
-
# @return [String] The schema node type.
|
34
|
-
def schema_node_type
|
35
|
-
"dfn"
|
36
|
-
end
|
37
|
-
|
38
31
|
# Indicates whether the Definition acts like a Fixtury definition.
|
39
32
|
#
|
40
33
|
# @return [Boolean] `true` if it acts like a Fixtury definition, `false` otherwise.
|
data/lib/fixtury/locator.rb
CHANGED
@@ -8,6 +8,24 @@ module Fixtury
|
|
8
8
|
# The backend is expected to implement the following methods: recognizable_key?, recognized_value?, load_recognized_reference, dump_recognized_value.
|
9
9
|
class Locator
|
10
10
|
|
11
|
+
def self.from(thing)
|
12
|
+
case thing
|
13
|
+
when ::Fixtury::Locator
|
14
|
+
thing
|
15
|
+
when nil
|
16
|
+
::Fixtury::Locator.new
|
17
|
+
when Symbol
|
18
|
+
begin
|
19
|
+
require "fixtury/locator_backend/#{thing}"
|
20
|
+
rescue LoadError
|
21
|
+
end
|
22
|
+
backend = ::Fixtury::LocatorBackend.const_get(thing.to_s.camelize, false).new
|
23
|
+
::Fixtury::Locator.new(backend: backend)
|
24
|
+
else
|
25
|
+
raise ArgumentError, "Unable to create a locator from #{thing.inspect}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
11
29
|
attr_reader :backend
|
12
30
|
|
13
31
|
def initialize(backend: ::Fixtury::LocatorBackend::Memory.new)
|
@@ -8,7 +8,7 @@ module Fixtury
|
|
8
8
|
|
9
9
|
include ::Fixtury::LocatorBackend::Common
|
10
10
|
|
11
|
-
MATCHER = /^fixtury-oid-(?<object_id>[\d]+)$/.freeze
|
11
|
+
MATCHER = /^fixtury-oid-(?<process_id>[\d]+)-(?<object_id>[\d]+)$/.freeze
|
12
12
|
|
13
13
|
def recognizable_key?(locator_value)
|
14
14
|
locator_value.is_a?(String) && MATCHER.match?(locator_value)
|
@@ -21,6 +21,7 @@ module Fixtury
|
|
21
21
|
def load_reference(locator_value)
|
22
22
|
match = MATCHER.match(locator_value)
|
23
23
|
return nil unless match
|
24
|
+
return nil unless match[:process_id].to_i == Process.pid
|
24
25
|
|
25
26
|
::ObjectSpace._id2ref(match[:object_id].to_i)
|
26
27
|
rescue RangeError
|
@@ -28,7 +29,7 @@ module Fixtury
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def dump_value(stored_value)
|
31
|
-
"fixtury-oid-#{stored_value.object_id}"
|
32
|
+
"fixtury-oid-#{Process.pid}-#{stored_value.object_id}"
|
32
33
|
end
|
33
34
|
|
34
35
|
end
|
data/lib/fixtury/schema.rb
CHANGED
@@ -1,43 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Fixtury
|
4
|
+
# A Fixtury::SchemaNode implementation that represents a top-level schema
|
5
|
+
# or a namespace within a schema.
|
4
6
|
class Schema
|
5
7
|
|
6
8
|
include ::Fixtury::SchemaNode
|
7
9
|
|
10
|
+
# @param name [String] the name of the schema, defaults to "" to represent
|
11
|
+
# a new top-level schema.
|
8
12
|
def initialize(name: "", **options)
|
9
13
|
super(name: name, **options)
|
10
14
|
end
|
11
15
|
|
16
|
+
# Object#acts_like? adherence.
|
12
17
|
def acts_like_fixtury_schema?
|
13
18
|
true
|
14
19
|
end
|
15
20
|
|
21
|
+
# Open up self for child definitions.
|
22
|
+
# @param block [Proc] The block to be executed in the context of the schema.
|
23
|
+
# @return [Fixtury::Schema] self
|
16
24
|
def define(&block)
|
17
25
|
instance_eval(&block)
|
18
26
|
self
|
19
27
|
end
|
20
28
|
|
29
|
+
# Returns "schema" if top-level, otherwise returns "namespace".
|
30
|
+
# @return [String] the type of the schema node.
|
21
31
|
def schema_node_type
|
22
|
-
first_ancestor? ? "schema" : "
|
32
|
+
first_ancestor? ? "schema" : "namespace"
|
23
33
|
end
|
24
34
|
|
25
|
-
|
26
|
-
|
35
|
+
# Create a child schema at the given relative name. If a child by the name
|
36
|
+
# already exists it will be reopened as long as it's a fixtury schema.
|
37
|
+
#
|
38
|
+
# @param relative_name [String] The relative name of the child schema.
|
39
|
+
# @param options [Hash] Additional options for the child schema, applied after instantiation.
|
40
|
+
# @param block [Proc] A block of code to be executed in the context of the child schema.
|
41
|
+
# @return [Fixtury::Schema] The child schema.
|
42
|
+
# @raise [Fixtury::Errors::AlreadyDefinedError] if the child is already defined and not a fixtury schema.
|
43
|
+
def namespace(relative_name, **options, &block)
|
44
|
+
child = get("./#{relative_name}")
|
27
45
|
|
28
46
|
if child && !child.acts_like?(:fixtury_schema)
|
29
47
|
raise Errors::AlreadyDefinedError, child.pathname
|
30
48
|
end
|
31
49
|
|
32
|
-
child ||= self.class.new(name:
|
50
|
+
child ||= self.class.new(name: relative_name, parent: self)
|
33
51
|
child.apply_options!(options)
|
34
52
|
child.instance_eval(&block) if block_given?
|
35
53
|
child
|
36
54
|
end
|
37
55
|
|
38
|
-
|
56
|
+
# Create a fixture definition at the given relative name. If the name is already
|
57
|
+
# used, a Fixtury::Errors::AlreadyDefinedError will be raised.
|
58
|
+
#
|
59
|
+
# @param relative_name [String] The relative name of the fixture.
|
60
|
+
# @param options [Hash] Additional options for the fixture.
|
61
|
+
# @param block [Proc] The block representing the build function of the fixture.
|
62
|
+
# @return [Fixtury::Definition] The fixture definition.
|
63
|
+
#
|
64
|
+
def fixture(relative_name, **options, &block)
|
39
65
|
::Fixtury::Definition.new(
|
40
|
-
name:
|
66
|
+
name: relative_name,
|
41
67
|
parent: self,
|
42
68
|
**options,
|
43
69
|
&block
|
data/lib/fixtury/schema_node.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Fixtury
|
2
|
+
# This module is used to provide a common interface for all nodes in the schema tree.
|
3
|
+
# Namespaces and fixture definitions adhere to this interface and are provided with
|
4
|
+
# common behaviors for registration, traversal, inspection, etc
|
2
5
|
module SchemaNode
|
3
6
|
|
4
7
|
extend ActiveSupport::Concern
|
@@ -6,9 +9,16 @@ module Fixtury
|
|
6
9
|
VALID_NODE_NAME = /^[a-zA-Z0-9_]*$/
|
7
10
|
|
8
11
|
included do
|
9
|
-
attr_reader :name, :pathname, :parent, :children, :options
|
12
|
+
attr_reader :name, :pathname, :parent, :first_ancestor, :children, :options
|
10
13
|
end
|
11
14
|
|
15
|
+
# Constructs a new SchemaNode object.
|
16
|
+
#
|
17
|
+
# @param name [String] The relative name of the node.
|
18
|
+
# @param parent [Object] The parent node of the node.
|
19
|
+
# @param options [Hash] Additional options for the node.
|
20
|
+
# @return [Fixtury::SchemaNode] The new SchemaNode object.
|
21
|
+
# @raise [ArgumentError] if the name does not match the VALID_NODE_NAME regex.
|
12
22
|
def initialize(name:, parent: nil, **options)
|
13
23
|
name = name.to_s
|
14
24
|
raise ArgumentError, "#{name.inspect} is an invalid node name" unless name.match?(VALID_NODE_NAME)
|
@@ -19,25 +29,35 @@ module Fixtury
|
|
19
29
|
@children = {}
|
20
30
|
@options = {}
|
21
31
|
apply_options!(options)
|
22
|
-
@
|
32
|
+
@first_ancestor = @parent&.first_ancestor || self
|
33
|
+
@parent&.add_child(self)
|
23
34
|
end
|
24
35
|
|
36
|
+
# Inspect the SchemaNode object without representing the parent or children to avoid
|
37
|
+
# large prints.
|
38
|
+
#
|
39
|
+
# @return [String] The inspection string.
|
25
40
|
def inspect
|
26
41
|
"#{self.class}(pathname: #{pathname.inspect}, children: #{children.size})"
|
27
42
|
end
|
28
43
|
|
44
|
+
# An identifier used during the printing of the tree structure.
|
45
|
+
#
|
46
|
+
# @return [String] The demodularized class name.
|
29
47
|
def schema_node_type
|
30
|
-
|
48
|
+
self.class.name.demodulize.underscore
|
31
49
|
end
|
32
50
|
|
51
|
+
# Adherance to the acts_like? interface
|
33
52
|
def acts_like_fixtury_schema_node?
|
34
53
|
true
|
35
54
|
end
|
36
55
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
56
|
+
# Adds child to the node's children hash as long as another is not already defined.
|
57
|
+
#
|
58
|
+
# @param child [Fixtury::SchemaNode] The child node to add.
|
59
|
+
# @raise [Fixtury::Errors::AlreadyDefinedError] if the child is already defined and not the provided child.
|
60
|
+
# @return [Fixtury::Errors::AlreadyDefinedError] the child that was suscessfully added
|
41
61
|
def add_child(child)
|
42
62
|
if children.key?(child.name) && children[child.name] != child
|
43
63
|
raise Errors::AlreadyDefinedError, child.pathname
|
@@ -46,19 +66,35 @@ module Fixtury
|
|
46
66
|
children[child.name] = child
|
47
67
|
end
|
48
68
|
|
69
|
+
# Is the current node the first ancestor?
|
70
|
+
#
|
71
|
+
# @return [TrueClass, FalseClass] `true` if the node is the first ancestor, `false` otherwise.
|
49
72
|
def first_ancestor?
|
50
73
|
parent.nil?
|
51
74
|
end
|
52
75
|
|
76
|
+
# Determines the isolation key in a top-down manner. It first accepts an isolation key
|
77
|
+
# set by the parent, then it checks for an isolation key set by the node itself. If no
|
78
|
+
# isolation key is found, it defaults to the node's name unless default is set to falsy.
|
79
|
+
#
|
80
|
+
# @param default [TrueClass, FalseClass, String] if no isolation key is present, what should the default value be?
|
81
|
+
# @option default [true] The default value is the node's name.
|
82
|
+
# @option default [String] The default value is a custom string.
|
83
|
+
# @option default [false, nil, ""] No isolation key should be represented
|
84
|
+
# @return [String, NilClass] The isolation key.
|
53
85
|
def isolation_key(default: true)
|
54
86
|
from_parent = parent&.isolation_key(default: nil)
|
55
87
|
return from_parent if from_parent
|
56
88
|
|
57
89
|
value = options[:isolate] || default
|
58
90
|
value = (value == true ? pathname : value&.to_s).presence
|
59
|
-
value == "/" ? nil : value # special case to accommodate root nodes
|
91
|
+
value = (value == "/" ? nil : value) # special case to accommodate root nodes
|
92
|
+
value.presence
|
60
93
|
end
|
61
94
|
|
95
|
+
# Performs get() but raises if the result is nil.
|
96
|
+
# @raise [Fixtury::Errors::SchemaNodeNotDefinedError] if the search does not return a node.
|
97
|
+
# (see #get)
|
62
98
|
def get!(search)
|
63
99
|
thing = get(search)
|
64
100
|
raise Errors::SchemaNodeNotDefinedError.new(pathname, search) unless thing
|
@@ -66,6 +102,14 @@ module Fixtury
|
|
66
102
|
thing
|
67
103
|
end
|
68
104
|
|
105
|
+
# Retrieves a node in the tree relative to self. Absolute and relative searches are
|
106
|
+
# accepted. The potential absolute paths are determined by a Fixtury::PathResolver instance
|
107
|
+
# relative to this node's pathname.
|
108
|
+
#
|
109
|
+
# @param search [String] The search to be used for finding the node.
|
110
|
+
# @return [Fixtury::SchemaNode, NilClass] The node if found, `nil` otherwise.
|
111
|
+
# @raise [ArgumentError] if the search is blank.
|
112
|
+
# @alias []
|
69
113
|
def get(search)
|
70
114
|
raise ArgumentError, "`search` must be provided" if search.blank?
|
71
115
|
|
@@ -87,18 +131,36 @@ module Fixtury
|
|
87
131
|
end
|
88
132
|
alias [] get
|
89
133
|
|
90
|
-
#
|
134
|
+
# Generates a string representing the structure of the schema tree.
|
135
|
+
# The string will be in the form of "type:name[isolation_key](options)". The children
|
136
|
+
# will be on the next line and indented by two spaces.
|
137
|
+
#
|
138
|
+
# @param prefix [String] The prefix to be used for any lines produced.
|
139
|
+
# @return [String] The structure string.
|
91
140
|
def structure(prefix = "")
|
92
141
|
out = []
|
142
|
+
|
143
|
+
opts = options.except(:isolate)
|
144
|
+
opts.compact!
|
145
|
+
|
93
146
|
my_structure = +"#{prefix}#{schema_node_type}:#{name}"
|
94
|
-
|
147
|
+
iso = isolation_key(default: nil)
|
148
|
+
my_structure << "[#{iso}]" if iso
|
149
|
+
my_structure << "(#{opts.to_a.map { |k, v| "#{k}: #{v.inspect}" }.join(", ")})" if opts.present?
|
95
150
|
out << my_structure
|
151
|
+
|
96
152
|
children.each_value do |child|
|
97
153
|
out << child.structure("#{prefix} ")
|
98
154
|
end
|
99
155
|
out.join("\n")
|
100
156
|
end
|
101
157
|
|
158
|
+
# Applies options to the node and raises if a collision occurs.
|
159
|
+
# This is useful for reopening a node and ensuring options are not altered.
|
160
|
+
#
|
161
|
+
# @param opts [Hash] The options to apply to the node.
|
162
|
+
# @raise [Fixtury::Errors::OptionCollisionError] if the option is already set and the new value is different.
|
163
|
+
# @return [void]
|
102
164
|
def apply_options!(opts = {})
|
103
165
|
opts.each do |key, value|
|
104
166
|
if options.key?(key) && options[key] != value
|
data/lib/fixtury/store.rb
CHANGED
@@ -1,62 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "concurrent/atomic/thread_local_var"
|
3
4
|
require "fileutils"
|
4
5
|
require "singleton"
|
5
6
|
require "yaml"
|
6
7
|
|
7
8
|
module Fixtury
|
9
|
+
# A store is a container for built fixture references. It is responsible for loading and caching fixtures
|
10
|
+
# based on a schema and a locator.
|
8
11
|
class Store
|
9
12
|
|
10
|
-
attr_reader :filepath
|
11
|
-
attr_reader :loaded_isolation_keys
|
12
13
|
attr_reader :locator
|
13
|
-
attr_reader :log_level
|
14
|
-
attr_reader :references
|
15
14
|
attr_reader :schema
|
16
15
|
attr_reader :ttl
|
17
16
|
|
18
|
-
|
17
|
+
# Create a new store.
|
18
|
+
# @param locator [Fixtury::Locator, Symbol, NilClass] (see Fixtury::Locator#from)
|
19
|
+
# @param ttl [Integer, NilClass] The time-to-live for references in seconds.
|
20
|
+
# @param schema [Fixtury::Schema, NilClass] The schema to use for fixture definitions, defaults to the global schema.
|
21
|
+
# @return [Fixtury::Store]
|
22
|
+
def initialize(locator: nil, ttl: nil, schema: nil)
|
19
23
|
@schema = schema || ::Fixtury.schema
|
20
|
-
@locator =
|
21
|
-
@filepath = filepath
|
22
|
-
@references = load_reference_from_file || {}
|
24
|
+
@locator = ::Fixtury::Locator.from(locator)
|
23
25
|
@ttl = ttl&.to_i
|
24
|
-
|
26
|
+
self.references = ::Fixtury.configuration.stored_references
|
25
27
|
end
|
26
28
|
|
29
|
+
def references
|
30
|
+
@references ||= ::Concurrent::ThreadLocalVar.new({})
|
31
|
+
@references.value
|
32
|
+
end
|
33
|
+
|
34
|
+
def references=(value)
|
35
|
+
references.clear
|
36
|
+
@references.value = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def loaded_isolation_keys
|
40
|
+
@loaded_isolation_keys ||= ::Concurrent::ThreadLocalVar.new({})
|
41
|
+
@loaded_isolation_keys.value
|
42
|
+
end
|
43
|
+
|
44
|
+
# Empty the store of any references and loaded isolation keys.
|
45
|
+
def reset
|
46
|
+
references.clear
|
47
|
+
loaded_isolation_keys.clear
|
48
|
+
end
|
49
|
+
|
50
|
+
# Summarize the current state of the store.
|
51
|
+
#
|
52
|
+
# @return [String]
|
27
53
|
def inspect
|
28
54
|
parts = []
|
29
55
|
parts << "schema: #{schema.inspect}"
|
30
56
|
parts << "locator: #{locator.inspect}"
|
31
|
-
parts << "filepath: #{filepath.inspect}" if filepath
|
32
57
|
parts << "ttl: #{ttl.inspect}" if ttl
|
33
58
|
parts << "references: #{references.size}"
|
34
59
|
|
35
60
|
"#{self.class}(#{parts.join(", ")})"
|
36
61
|
end
|
37
62
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
::FileUtils.mkdir_p(File.dirname(filepath))
|
42
|
-
|
43
|
-
writable = references.each_with_object({}) do |(pathname, ref), h|
|
44
|
-
h[pathname] = ref if ref.real?
|
45
|
-
end
|
46
|
-
|
47
|
-
::File.binwrite(filepath, writable.to_yaml)
|
48
|
-
end
|
49
|
-
|
50
|
-
def load_reference_from_file
|
51
|
-
return unless filepath
|
52
|
-
return unless File.file?(filepath)
|
53
|
-
|
54
|
-
::YAML.unsafe_load_file(filepath)
|
55
|
-
end
|
56
|
-
|
63
|
+
# Clear any references that are beyond their ttl or are no longer recognizable by the locator.
|
64
|
+
#
|
65
|
+
# @return [void]
|
57
66
|
def clear_stale_references!
|
58
|
-
return unless ttl
|
59
|
-
|
60
67
|
references.delete_if do |name, ref|
|
61
68
|
stale = reference_stale?(ref)
|
62
69
|
log("expiring #{name}", level: LOG_LEVEL_DEBUG) if stale
|
@@ -64,6 +71,11 @@ module Fixtury
|
|
64
71
|
end
|
65
72
|
end
|
66
73
|
|
74
|
+
# Load all fixtures in the target schema, defaulting to the store's schema.
|
75
|
+
# This will load all fixtures in the schema and any child schemas.
|
76
|
+
#
|
77
|
+
# @param schema [Fixtury::Schema] The schema to load, defaults to the store's schema.
|
78
|
+
# @return [void]
|
67
79
|
def load_all(schema = self.schema)
|
68
80
|
schema.children.each_value do |item|
|
69
81
|
get(item.name) if item.acts_like?(:fixtury_definition)
|
@@ -71,19 +83,12 @@ module Fixtury
|
|
71
83
|
end
|
72
84
|
end
|
73
85
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
hit = glob ? key.start_with?(pattern) : key == pattern
|
81
|
-
log("clearing #{key}", level: LOG_LEVEL_DEBUG) if hit
|
82
|
-
hit
|
83
|
-
end
|
84
|
-
dump_to_file
|
85
|
-
end
|
86
|
-
|
86
|
+
# Temporarily set a contextual schema to use for loading fixtures. This is
|
87
|
+
# useful when evaluating dependencies of a definition while still storing the results.
|
88
|
+
#
|
89
|
+
# @param schema [Fixtury::Schema] The schema to use.
|
90
|
+
# @yield [void] The block to execute with the given schema.
|
91
|
+
# @return [Object] The result of the block
|
87
92
|
def with_relative_schema(schema)
|
88
93
|
prior = @schema
|
89
94
|
@schema = schema
|
@@ -92,53 +97,38 @@ module Fixtury
|
|
92
97
|
@schema = prior
|
93
98
|
end
|
94
99
|
|
95
|
-
|
96
|
-
|
100
|
+
# Is a fixture for the given search already loaded?
|
101
|
+
#
|
102
|
+
# @param search [String] The name of the fixture to search for.
|
103
|
+
# @return [TrueClass, FalseClass] `true` if the fixture is loaded, `false` otherwise.
|
104
|
+
def loaded?(search)
|
105
|
+
dfn = schema.get!(search)
|
97
106
|
ref = references[dfn.pathname]
|
98
107
|
result = ref&.real?
|
99
108
|
log(result ? "hit #{dfn.pathname}" : "miss #{dfn.pathname}", level: LOG_LEVEL_ALL)
|
100
109
|
result
|
101
110
|
end
|
102
111
|
|
103
|
-
def loaded_or_loading?(pathname)
|
104
|
-
!!references[pathname]
|
105
|
-
end
|
106
|
-
|
107
|
-
def maybe_load_isolation_dependencies(definition)
|
108
|
-
isolation_key = definition.isolation_key
|
109
|
-
return if loaded_isolation_keys[isolation_key]
|
110
|
-
|
111
|
-
load_isolation_dependencies(isolation_key, schema.first_ancestor)
|
112
|
-
end
|
113
|
-
|
114
|
-
def load_isolation_dependencies(isolation_key, target_schema)
|
115
|
-
loaded_isolation_keys[isolation_key] = true
|
116
|
-
target_schema.children.each_value do |child|
|
117
|
-
if child.acts_like?(:fixtury_definition)
|
118
|
-
next unless child.isolation_key == isolation_key
|
119
|
-
next if loaded_or_loading?(child.pathname)
|
120
|
-
get(child.pathname)
|
121
|
-
elsif child.acts_like?(:fixtury_schema)
|
122
|
-
load_isolation_dependencies(isolation_key, child)
|
123
|
-
else
|
124
|
-
raise NotImplementedError, "Unknown isolation loading behavior: #{child.class.name}"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
112
|
# Fetch a fixture by name. This will load the fixture if it has not been loaded yet.
|
130
113
|
# If a definition contains an isolation key, all fixtures with the same isolation key will be loaded.
|
131
|
-
|
132
|
-
|
114
|
+
#
|
115
|
+
# @param search [String] The name of the fixture to search for.
|
116
|
+
# @return [Object] The loaded fixture.
|
117
|
+
# @raise [Fixtury::Errors::CircularDependencyError] if a circular dependency is detected.
|
118
|
+
# @raise [Fixtury::Errors::SchemaNodeNotDefinedError] if the search does not return a node.
|
119
|
+
# @raise [Fixtury::Errors::UnknownDefinitionError] if the search does not return a definition.
|
120
|
+
# @raise [Fixtury::Errors::DefinitionExecutorError] if the definition executor fails.
|
121
|
+
def get(search)
|
122
|
+
log("getting #{search} relative to #{schema.pathname}", level: LOG_LEVEL_DEBUG)
|
133
123
|
|
134
124
|
# Find the definition.
|
135
|
-
dfn = schema.get!(
|
136
|
-
raise ArgumentError, "#{
|
125
|
+
dfn = schema.get!(search)
|
126
|
+
raise ArgumentError, "#{search.inspect} must refer to a definition" unless dfn.acts_like?(:fixtury_definition)
|
137
127
|
|
138
128
|
pathname = dfn.pathname
|
139
129
|
|
140
130
|
# Ensure that if we're part of an isolation group, we load all the fixtures in that group.
|
141
|
-
maybe_load_isolation_dependencies(dfn)
|
131
|
+
maybe_load_isolation_dependencies(dfn.isolation_key)
|
142
132
|
|
143
133
|
# See if we already hold a reference to the fixture.
|
144
134
|
ref = references[pathname]
|
@@ -190,16 +180,65 @@ module Fixtury
|
|
190
180
|
end
|
191
181
|
alias [] get
|
192
182
|
|
183
|
+
protected
|
184
|
+
|
185
|
+
# Determine if the given pathname is already loaded or is currently being loaded.
|
186
|
+
#
|
187
|
+
# @param pathname [String] The pathname to check.
|
188
|
+
# @return [TrueClass, FalseClass] `true` if the pathname is already loaded or is currently being loaded, `false` otherwise.
|
189
|
+
def loaded_or_loading?(pathname)
|
190
|
+
!!references[pathname]
|
191
|
+
end
|
192
|
+
|
193
|
+
# Load all fixtures with the given isolation key in the target schema
|
194
|
+
# if we're not already attempting to load them.
|
195
|
+
def maybe_load_isolation_dependencies(isolation_key)
|
196
|
+
return if loaded_isolation_keys[isolation_key]
|
197
|
+
loaded_isolation_keys[isolation_key] = true
|
198
|
+
|
199
|
+
load_isolation_dependencies(isolation_key, schema.first_ancestor)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Load all fixtures with the given isolation key in the target schema.
|
203
|
+
#
|
204
|
+
# @param isolation_key [String] The isolation key to load fixtures for.
|
205
|
+
# @param target_schema [Fixtury::Schema] The schema to search within.
|
206
|
+
# @return [void]
|
207
|
+
def load_isolation_dependencies(isolation_key, target_schema)
|
208
|
+
target_schema.children.each_value do |child|
|
209
|
+
if child.acts_like?(:fixtury_definition)
|
210
|
+
next unless child.isolation_key == isolation_key
|
211
|
+
next if loaded_or_loading?(child.pathname)
|
212
|
+
|
213
|
+
get(child.pathname)
|
214
|
+
elsif child.acts_like?(:fixtury_schema)
|
215
|
+
load_isolation_dependencies(isolation_key, child)
|
216
|
+
else
|
217
|
+
raise NotImplementedError, "Unknown isolation loading behavior: #{child.class.name}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Remove a reference at the given pathname from the stored references.
|
223
|
+
#
|
224
|
+
# @param pathname [String] The pathname to remove.
|
225
|
+
# @return [void]
|
193
226
|
def clear_reference(pathname)
|
194
227
|
references.delete(pathname)
|
195
228
|
end
|
196
229
|
|
230
|
+
# Determine if a reference is stale. A reference is stale if it is beyond its ttl or
|
231
|
+
# if it is no longer recognizable by the locator.
|
232
|
+
#
|
233
|
+
# @param ref [Fixtury::Reference] The reference to check.
|
234
|
+
# @return [TrueClass, FalseClass] `true` if the reference is stale, `false` otherwise.
|
197
235
|
def reference_stale?(ref)
|
198
236
|
return true if ttl && ref.created_at < (Time.now.to_i - ttl)
|
199
237
|
|
200
238
|
!locator.recognizable_key?(ref.locator_key)
|
201
239
|
end
|
202
240
|
|
241
|
+
# Log a contextual message using Fixtury.log
|
203
242
|
def log(msg, level:)
|
204
243
|
::Fixtury.log(msg, level: level, name: "store")
|
205
244
|
end
|
data/lib/fixtury/test_hooks.rb
CHANGED
@@ -4,6 +4,54 @@ require "fixtury"
|
|
4
4
|
require "active_support/core_ext/class/attribute"
|
5
5
|
|
6
6
|
module Fixtury
|
7
|
+
# TestHooks is a module designed to hook into a Minitest test case, and
|
8
|
+
# provide a way to load fixtures into the test case. It is designed to be
|
9
|
+
# prepended into the test case class, and will automatically load fixtures
|
10
|
+
# before the test case is setup, and rollback any changes after the test
|
11
|
+
# case is torn down.
|
12
|
+
#
|
13
|
+
# The module also provides a way to define fixture dependencies, and will
|
14
|
+
# automatically load those dependencies before the test case is setup.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# class MyTest < Minitest::Test
|
18
|
+
# prepend Fixtury::TestHooks
|
19
|
+
#
|
20
|
+
# fixtury "user"
|
21
|
+
# fixtury "post"
|
22
|
+
#
|
23
|
+
# def test_something
|
24
|
+
# user # => returns the `users` fixture
|
25
|
+
# user.do_some_mutation
|
26
|
+
# assert_equal 1, user.mutations.count
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # In the above example, the `users` and `posts` fixtures will be loaded
|
31
|
+
# # before the test case is setup, and any changes will be rolled back
|
32
|
+
# # after the test case is torn down.
|
33
|
+
#
|
34
|
+
# # The `fixtury` method also accepts a `:as` option, which can be used to
|
35
|
+
# # define a named accessor method for a fixture. This is useful when
|
36
|
+
# # defining a single fixture, and you want to access it using a different
|
37
|
+
# # name. If no `:as` option is provided, the fixture will be accessed
|
38
|
+
# # using the last segment of the fixture's pathname.
|
39
|
+
#
|
40
|
+
# class MyTest < Minitest::Test
|
41
|
+
# prepend Fixtury::TestHooks
|
42
|
+
#
|
43
|
+
# fixtury "/my/user_record", as: :user
|
44
|
+
#
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# A Set object named fixtury_dependencies is made available on the test class.
|
48
|
+
# This allows you to load all Minitest runnables and analyze what fixtures are
|
49
|
+
# needed. This is very helpful in CI pipelines when you want to prepare all fixtures
|
50
|
+
# ahead of time to share between multiple processes.
|
51
|
+
#
|
52
|
+
# The setup and teardown attempt to manage a transaction for each registered database
|
53
|
+
# connection if ActiveRecord::Base is present. If use_transaction_tests or use_transactional_fixtures
|
54
|
+
# are present, those settings will be respected. If neither are present, a transaction will be used.
|
7
55
|
module TestHooks
|
8
56
|
|
9
57
|
def self.prepended(klass)
|
@@ -18,17 +66,17 @@ module Fixtury
|
|
18
66
|
|
19
67
|
module ClassMethods
|
20
68
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
69
|
+
# Declare fixtury dependencies for this test case. This will automatically
|
70
|
+
# load the fixtures before the test case is setup, and rollback any changes
|
71
|
+
# after the test case is torn down.
|
72
|
+
#
|
73
|
+
# @param searches [Array<String>] A list of fixture names to load. These should be resolvable paths relative to Fixtury.schema (root).
|
74
|
+
# @param opts [Hash] A list of options to customize the behavior of the fixtures.
|
75
|
+
# @option opts [Symbol, String, Boolean] :as (true) The name of the accessor method to define for the fixture. If true (default), the last segment will be used.
|
76
|
+
# @return [void]
|
29
77
|
def fixtury(*searches, **opts)
|
30
78
|
pathnames = searches.map do |search|
|
31
|
-
dfn =
|
79
|
+
dfn = Fixtury.schema.get!(search)
|
32
80
|
dfn.pathname
|
33
81
|
end
|
34
82
|
|
@@ -66,41 +114,47 @@ module Fixtury
|
|
66
114
|
|
67
115
|
end
|
68
116
|
|
117
|
+
# Minitest before_setup hook. This will load the fixtures before the test.
|
69
118
|
def before_setup(...)
|
70
119
|
fixtury_setup if fixtury_dependencies.any?
|
71
120
|
super
|
72
121
|
end
|
73
122
|
|
123
|
+
# Minitest after_teardown hook. This will rollback any changes made to the fixtures after the test.
|
74
124
|
def after_teardown(...)
|
75
125
|
super
|
76
126
|
fixtury_teardown if fixtury_dependencies.any?
|
77
127
|
end
|
78
128
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
129
|
+
# Access a fixture via a search term. This will access the fixture from the Fixtury store.
|
130
|
+
# If the fixture was not declared as a dependency, an error will be raised.
|
131
|
+
#
|
132
|
+
# @param search [String] The search term to use to find the fixture.
|
133
|
+
# @return [Object] The fixture.
|
134
|
+
# @raise [Fixtury::Errors::UnknownTestDependencyError] if the search term does not result in a declared dependency.
|
135
|
+
# @raise [Fixtury::Errors::SchemaNodeNotDefinedError] if the search term does not result in a recognized fixture.
|
136
|
+
def fixtury(search)
|
137
|
+
dfn = Fixtury.schema.get!(search)
|
84
138
|
|
85
139
|
unless fixtury_dependencies.include?(dfn.pathname)
|
86
140
|
raise Errors::UnknownTestDependencyError, "Unrecognized fixtury dependency `#{dfn.pathname}` for #{self.class}"
|
87
141
|
end
|
88
142
|
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def fixtury_loaded?(name)
|
93
|
-
return false unless self.class.fixtury_store
|
94
|
-
|
95
|
-
self.class.fixtury_store.loaded?(name)
|
143
|
+
Fixtury.store.get(dfn.pathname)
|
96
144
|
end
|
97
145
|
|
146
|
+
# Retrieve all database connections that are currently registered with a writing role.
|
147
|
+
#
|
148
|
+
# @return [Array<ActiveRecord::ConnectionAdapters::AbstractAdapter>] The list of database connections.
|
98
149
|
def fixtury_database_connections
|
150
|
+
return [] unless defined?(ActiveRecord::Base)
|
151
|
+
|
99
152
|
ActiveRecord::Base.connection_handler.connection_pool_list(:writing).map(&:connection)
|
100
153
|
end
|
101
154
|
|
155
|
+
# Load all dependenct fixtures and begin a transaction for each database connection.
|
102
156
|
def fixtury_setup
|
103
|
-
|
157
|
+
Fixtury.store.clear_stale_references!
|
104
158
|
fixtury_load_all_fixtures!
|
105
159
|
return unless fixtury_use_transactions?
|
106
160
|
|
@@ -109,6 +163,7 @@ module Fixtury
|
|
109
163
|
end
|
110
164
|
end
|
111
165
|
|
166
|
+
# Rollback any changes made to the fixtures
|
112
167
|
def fixtury_teardown
|
113
168
|
return unless fixtury_use_transactions?
|
114
169
|
|
@@ -117,21 +172,19 @@ module Fixtury
|
|
117
172
|
end
|
118
173
|
end
|
119
174
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
self.class.fixtury_store.clear_stale_references!
|
124
|
-
end
|
125
|
-
|
175
|
+
# Load all fixture dependencies that have not previously been loaded into the store.
|
176
|
+
#
|
177
|
+
# @return [void]
|
126
178
|
def fixtury_load_all_fixtures!
|
127
179
|
fixtury_dependencies.each do |name|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
180
|
+
next if Fixtury.store.loaded?(name)
|
181
|
+
|
182
|
+
::Fixtury.log("preloading #{name.inspect}", name: "test", level: ::Fixtury::LOG_LEVEL_INFO)
|
183
|
+
fixtury(name)
|
132
184
|
end
|
133
185
|
end
|
134
186
|
|
187
|
+
# Adhere to common Rails test transaction settings.
|
135
188
|
def fixtury_use_transactions?
|
136
189
|
return use_transactional_tests if respond_to?(:use_transactional_tests)
|
137
190
|
return use_transactional_fixtures if respond_to?(:use_transactional_fixtures)
|
data/lib/fixtury/version.rb
CHANGED
data/lib/fixtury.rb
CHANGED
@@ -9,6 +9,7 @@ require "active_support/core_ext/object/blank"
|
|
9
9
|
|
10
10
|
require "fixtury/version"
|
11
11
|
|
12
|
+
require "fixtury/configuration"
|
12
13
|
require "fixtury/definition_executor"
|
13
14
|
require "fixtury/dependency"
|
14
15
|
require "fixtury/dependency_store"
|
@@ -38,6 +39,17 @@ module Fixtury
|
|
38
39
|
|
39
40
|
DEFAULT_LOG_LEVEL = LOG_LEVEL_INFO
|
40
41
|
|
42
|
+
def self.configuration
|
43
|
+
@configuration ||= ::Fixtury::Configuration.new
|
44
|
+
yield @configuration if block_given?
|
45
|
+
@configuration
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.configure(&block)
|
49
|
+
self.configuration(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
41
53
|
# Shortcut for opening the top level schema.
|
42
54
|
def self.define(&block)
|
43
55
|
schema.define(&block)
|
@@ -61,24 +73,45 @@ module Fixtury
|
|
61
73
|
|
62
74
|
# Default store for fixtures. This is a shared store that can be used across the application.
|
63
75
|
def self.store
|
64
|
-
@store ||= ::Fixtury::Store.new
|
76
|
+
@store ||= ::Fixtury::Store.new
|
65
77
|
end
|
66
78
|
|
67
79
|
def self.store=(store)
|
68
80
|
@store = store
|
69
81
|
end
|
70
82
|
|
71
|
-
|
72
|
-
|
83
|
+
# Require each schema file to ensure that all definitions are loaded.
|
84
|
+
def self.load_all_schemas
|
85
|
+
configuration.fixture_files.each do |filepath|
|
86
|
+
require filepath
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Ensure all definitions are loaded and then load all known fixtures.
|
91
|
+
def self.load_all_fixtures
|
92
|
+
load_all_schemas
|
93
|
+
Fixtury.store.load_all
|
94
|
+
end
|
95
|
+
|
96
|
+
# Remove all references from the active store and reset the dependency file
|
97
|
+
def self.reset
|
98
|
+
log("resetting", level: LOG_LEVEL_INFO)
|
99
|
+
|
100
|
+
configuration.reset
|
101
|
+
store.reset
|
102
|
+
end
|
73
103
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
104
|
+
# Perform a reset if any of the tracked files have changed.
|
105
|
+
def self.reset_if_changed
|
106
|
+
if configuration.files_changed?
|
107
|
+
reset
|
108
|
+
else
|
109
|
+
log("no changes, skipping reset", level: LOG_LEVEL_INFO)
|
110
|
+
end
|
78
111
|
end
|
79
112
|
|
80
113
|
def self.log(text = nil, level: LOG_LEVEL_DEBUG, name: nil, newline: true)
|
81
|
-
desired_level = LOG_LEVELS.fetch(log_level) { DEFAULT_LOG_LEVEL }
|
114
|
+
desired_level = LOG_LEVELS.fetch(configuration.log_level) { DEFAULT_LOG_LEVEL }
|
82
115
|
return if desired_level == LOG_LEVEL_NONE
|
83
116
|
|
84
117
|
message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
|
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: 1.0.0.
|
4
|
+
version: 1.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- bin/setup
|
155
155
|
- fixtury.gemspec
|
156
156
|
- lib/fixtury.rb
|
157
|
+
- lib/fixtury/configuration.rb
|
157
158
|
- lib/fixtury/definition.rb
|
158
159
|
- lib/fixtury/definition_executor.rb
|
159
160
|
- lib/fixtury/dependency.rb
|
@@ -162,7 +163,7 @@ files:
|
|
162
163
|
- lib/fixtury/hooks.rb
|
163
164
|
- lib/fixtury/locator.rb
|
164
165
|
- lib/fixtury/locator_backend/common.rb
|
165
|
-
- lib/fixtury/locator_backend/
|
166
|
+
- lib/fixtury/locator_backend/global_id.rb
|
166
167
|
- lib/fixtury/locator_backend/memory.rb
|
167
168
|
- lib/fixtury/mutation_observer.rb
|
168
169
|
- lib/fixtury/path_resolver.rb
|
@@ -171,7 +172,6 @@ files:
|
|
171
172
|
- lib/fixtury/schema.rb
|
172
173
|
- lib/fixtury/schema_node.rb
|
173
174
|
- lib/fixtury/store.rb
|
174
|
-
- lib/fixtury/tasks.rake
|
175
175
|
- lib/fixtury/test_hooks.rb
|
176
176
|
- lib/fixtury/version.rb
|
177
177
|
homepage: https://github.com/guideline-tech/fixtury
|
data/lib/fixtury/tasks.rake
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
namespace :fixtury do
|
4
|
-
task :setup
|
5
|
-
|
6
|
-
desc "Clear fixtures from your cache. Accepts a pattern or fixture name such as foo/bar or /foo/*. Default pattern is /*"
|
7
|
-
task :clear_cache, [:pattern] => :setup do |_t, args|
|
8
|
-
::Fixtury::Store.instance.clear_cache!(pattern: args[:pattern])
|
9
|
-
end
|
10
|
-
end
|