fixtury 0.1.0.alpha → 0.1.0

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