fixtury 1.0.0.beta1 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|