fixtury 0.1.0.beta → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c10251ee2040482092e648cbc213a75973795905fb754997cfb20976cc38e27
4
- data.tar.gz: 8df04d1c19509a793a8450959672cce0c8fcb5c80d50ea868fcb6a77c400a822
3
+ metadata.gz: 9090092db55914068c6478939047d638ee8bb678ee53a41f0d36380bf2df7dea
4
+ data.tar.gz: 4e58164635a72d63e059a5622b1c867556235ba09537e127b5498f94a3bf8e60
5
5
  SHA512:
6
- metadata.gz: 27632388a2ad2432b194f8241986f3d2f4aaf7a6fb4c902be2341ffbec8522abe77485b8d2fed4ab0f70f302158ab29d9d110987a496ce151a021623e49f85b3
7
- data.tar.gz: cbd8e9dda57f5d2d6243d171fd25e6a207b4a5ede455dab3230593a1a525b6ee3596090d36d6da9809c007264651a7f53e278a05e05b1806bb7f0d7611532103
6
+ metadata.gz: 05e1ddd158beafe83cbe9e9d32abf10a49dcdb59709cc372f31a29a1a52c3eafe0b802eba8015ccdb429444678d94941db42dedb6202396b958c8d53d2e6f9d2
7
+ data.tar.gz: 70e2abc1abc6324e3523631a6f2caf936d0b0859eeb14b41fec843b766bf648d047b1e09e9d9bb6da60131f06be23e7e02c1adcf86be30910387581b7e191d3e
@@ -1,26 +1,26 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fixtury (0.1.0.alpha2)
4
+ fixtury (0.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- activesupport (6.0.1)
9
+ activesupport (6.0.3.1)
10
10
  concurrent-ruby (~> 1.0, >= 1.0.2)
11
11
  i18n (>= 0.7, < 2)
12
12
  minitest (~> 5.1)
13
13
  tzinfo (~> 1.1)
14
- zeitwerk (~> 2.2)
14
+ zeitwerk (~> 2.2, >= 2.2.2)
15
15
  ansi (1.5.0)
16
16
  autotest (5.0.0)
17
17
  minitest-autotest (~> 1.0)
18
18
  builder (3.2.3)
19
19
  byebug (11.0.1)
20
- concurrent-ruby (1.1.5)
20
+ concurrent-ruby (1.1.6)
21
21
  globalid (0.4.2)
22
22
  activesupport (>= 4.2.0)
23
- i18n (1.7.0)
23
+ i18n (1.8.2)
24
24
  concurrent-ruby (~> 1.0)
25
25
  metaclass (0.0.4)
26
26
  minitest (5.13.0)
@@ -37,13 +37,13 @@ GEM
37
37
  mocha (1.8.0)
38
38
  metaclass (~> 0.0.1)
39
39
  path_expander (1.1.0)
40
- rake (10.5.0)
40
+ rake (13.0.1)
41
41
  ruby-progressbar (1.10.1)
42
42
  sqlite (1.0.2)
43
43
  thread_safe (0.3.6)
44
- tzinfo (1.2.5)
44
+ tzinfo (1.2.7)
45
45
  thread_safe (~> 0.1)
46
- zeitwerk (2.2.2)
46
+ zeitwerk (2.3.0)
47
47
 
48
48
  PLATFORMS
49
49
  ruby
@@ -57,7 +57,7 @@ DEPENDENCIES
57
57
  minitest (~> 5.0)
58
58
  minitest-reporters
59
59
  mocha
60
- rake (~> 10.0)
60
+ rake (~> 13.0)
61
61
  sqlite
62
62
 
63
63
  BUNDLED WITH
@@ -34,6 +34,6 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "minitest", "~> 5.0"
35
35
  spec.add_development_dependency "minitest-reporters"
36
36
  spec.add_development_dependency "mocha"
37
- spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rake", "~> 13.0"
38
38
  spec.add_development_dependency "sqlite"
39
39
  end
@@ -7,7 +7,6 @@ require "fixtury/version"
7
7
  require "fixtury/schema"
8
8
  require "fixtury/locator"
9
9
  require "fixtury/store"
10
- require "fixtury/execution_context"
11
10
 
12
11
  module Fixtury
13
12
 
@@ -44,9 +44,7 @@ module Fixtury
44
44
  end
45
45
  end
46
46
 
47
- def run_callable(store:, callable:, execution_context:, value:)
48
- execution_context ||= self
49
-
47
+ def run_callable(store:, callable:, execution_context: nil, value:)
50
48
  args = []
51
49
  args << value unless value.nil?
52
50
  if callable.arity > args.length
@@ -55,11 +53,26 @@ module Fixtury
55
53
  args << store
56
54
  end
57
55
 
58
- if args.length.positive?
59
- execution_context.instance_exec(*args, &callable)
56
+ provide_execution_context_hooks(execution_context) do |ctxt|
57
+ if args.length.positive?
58
+ ctxt.instance_exec(*args, &callable)
59
+ else
60
+ ctxt.instance_eval(&callable)
61
+ end
62
+ end
63
+ end
64
+
65
+ def provide_execution_context_hooks(execution_context)
66
+ return yield self unless execution_context
67
+
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 execution_context }
60
71
  else
61
- execution_context.instance_eval(&callable)
72
+ yield execution_context
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
@@ -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
 
@@ -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
 
@@ -5,33 +5,41 @@ require "singleton"
5
5
  require "yaml"
6
6
  require "fixtury/locator"
7
7
  require "fixtury/errors/circular_dependency_error"
8
- require "fixtury/execution_context"
9
8
  require "fixtury/reference"
10
9
 
11
10
  module Fixtury
12
11
  class Store
13
12
 
13
+ LOG_LEVELS = {
14
+ (LOG_LEVEL_NONE = :none) => 0,
15
+ (LOG_LEVEL_INFO = :info) => 1,
16
+ (LOG_LEVEL_DEBUG = :debug) => 2,
17
+ }.freeze
18
+
14
19
  cattr_accessor :instance
15
20
 
16
21
  attr_reader :filepath, :references, :ttl, :auto_refresh_expired
17
22
  attr_reader :schema, :locator
18
- attr_reader :verbose
23
+ attr_reader :log_level
19
24
  attr_reader :execution_context
20
25
 
21
26
  def initialize(
22
27
  filepath: nil,
23
28
  locator: ::Fixtury::Locator.instance,
24
- verbose: false,
29
+ log_level: nil,
25
30
  ttl: nil,
26
31
  schema: nil,
32
+ execution_context: nil,
27
33
  auto_refresh_expired: false
28
34
  )
29
35
  @schema = schema || ::Fixtury.schema
30
- @verbose = verbose
36
+ @log_level = log_level.nil? ? ENV["FIXTURY_LOG_LEVEL"] : log_level
37
+ @log_level ||= LOG_LEVEL_NONE
38
+ @log_level = @log_level.to_s.to_sym
31
39
  @locator = locator
32
40
  @filepath = filepath
33
41
  @references = @filepath && ::File.file?(@filepath) ? ::YAML.load_file(@filepath) : {}
34
- @execution_context = ::Fixtury::ExecutionContext.new
42
+ @execution_context = execution_context
35
43
  @ttl = ttl ? ttl.to_i : ttl
36
44
  @auto_refresh_expired = !!auto_refresh_expired
37
45
  self.class.instance ||= self
@@ -53,8 +61,8 @@ module Fixtury
53
61
  return unless ttl
54
62
 
55
63
  references.delete_if do |name, ref|
56
- is_expired = ref_expired?(ref)
57
- log { "expiring #{name}" } if is_expired
64
+ is_expired = ref_invalid?(ref)
65
+ log(level: LOG_LEVEL_INFO) { "expiring #{name}" } if is_expired
58
66
  is_expired
59
67
  end
60
68
  end
@@ -72,11 +80,11 @@ module Fixtury
72
80
  def clear_cache!(pattern: nil)
73
81
  pattern ||= "*"
74
82
  pattern = "/" + pattern unless pattern.start_with?("/")
75
- glob = pattern.ends_with?("*")
83
+ glob = pattern.end_with?("*")
76
84
  pattern = pattern[0...-1] if glob
77
85
  references.delete_if do |key, _value|
78
86
  hit = glob ? key.start_with?(pattern) : key == pattern
79
- log(true) { "clearing #{key}" } if hit
87
+ log(level: LOG_LEVEL_INFO) { "clearing #{key}" } if hit
80
88
  hit
81
89
  end
82
90
  dump_to_file
@@ -95,7 +103,7 @@ module Fixtury
95
103
  full_name = dfn.name
96
104
  ref = references[full_name]
97
105
  result = ref&.real?
98
- log { result ? "hit #{full_name}" : "miss #{full_name}" }
106
+ log(level: LOG_LEVEL_DEBUG) { result ? "hit #{full_name}" : "miss #{full_name}" }
99
107
  result
100
108
  end
101
109
 
@@ -108,8 +116,8 @@ module Fixtury
108
116
  raise ::Fixtury::Errors::CircularDependencyError, full_name
109
117
  end
110
118
 
111
- if ref && auto_refresh_expired && ref_expired?(ref)
112
- log { "refreshing #{full_name}" }
119
+ if ref && auto_refresh_expired && ref_invalid?(ref)
120
+ log(level: LOG_LEVEL_INFO) { "refreshing #{full_name}" }
113
121
  clear_ref(full_name)
114
122
  ref = nil
115
123
  end
@@ -117,11 +125,11 @@ module Fixtury
117
125
  value = nil
118
126
 
119
127
  if ref
120
- log { "hit #{full_name}" }
128
+ log(level: LOG_LEVEL_DEBUG) { "hit #{full_name}" }
121
129
  value = load_ref(ref.value)
122
130
  if value.nil?
123
131
  clear_ref(full_name)
124
- log { "missing #{full_name}" }
132
+ log(level: LOG_LEVEL_DEBUG) { "missing #{full_name}" }
125
133
  end
126
134
  end
127
135
 
@@ -131,7 +139,7 @@ module Fixtury
131
139
 
132
140
  value = dfn.call(store: self, execution_context: execution_context)
133
141
 
134
- log { "store #{full_name}" }
142
+ log(level: LOG_LEVEL_INFO) { "store #{full_name}" }
135
143
 
136
144
  ref = dump_ref(full_name, value)
137
145
  ref = ::Fixtury::Reference.new(full_name, ref)
@@ -154,16 +162,20 @@ module Fixtury
154
162
  references.delete(name)
155
163
  end
156
164
 
157
- def ref_expired?(ref)
158
- return false unless ttl
165
+ def ref_invalid?(ref)
166
+ return true if ttl && ref.created_at < (Time.now.to_i - ttl)
159
167
 
160
- ref.created_at < (Time.now.to_i - ttl)
168
+ !locator.recognize?(ref.value)
161
169
  end
162
170
 
163
- def log(local_verbose = false, &block)
164
- return unless verbose || local_verbose
171
+ def log(level: LOG_LEVEL_DEBUG, name: "store")
172
+ desired_level = LOG_LEVELS.fetch(log_level) { LOG_LEVEL_NONE }
173
+ return if desired_level == LOG_LEVEL_NONE
174
+
175
+ message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
176
+ return unless desired_level >= message_level
165
177
 
166
- puts "[fixtury|store] #{block.call}"
178
+ puts "[fixtury|#{name}] #{yield}"
167
179
  end
168
180
 
169
181
  end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fixtury/store"
4
+ require "active_support/core_ext/class/attribute"
5
+
6
+ module Fixtury
7
+ module TestHooks
8
+
9
+ extend ::ActiveSupport::Concern
10
+
11
+ included do
12
+ class_attribute :fixtury_dependencies
13
+ self.fixtury_dependencies = Set.new
14
+ end
15
+
16
+ module ClassMethods
17
+
18
+ def fixtury(*names, &definition)
19
+ opts = names.extract_options!
20
+
21
+ # define fixtures if blocks are given
22
+ if block_given?
23
+ raise ArgumentError, "A fixture cannot be defined in an anonymous class" if name.nil?
24
+
25
+ namespace = name.underscore
26
+
27
+ ns = ::Fixtury.schema
28
+
29
+ namespace.split("/").each do |ns_name|
30
+ ns = ns.namespace(ns_name){}
31
+ end
32
+
33
+ names.each do |fixture_name|
34
+ ns.fixture(fixture_name, &definition)
35
+ self.fixtury_dependencies += ["#{namespace}/#{fixture_name}"]
36
+ end
37
+
38
+ # otherwise, just record the dependency
39
+ else
40
+ self.fixtury_dependencies += names.flatten.compact.map(&:to_s)
41
+ end
42
+
43
+ if opts[:accessor]
44
+
45
+ if opts[:accessor] != true && names.length > 1
46
+ raise ArgumentError, "A named :accessor option is only available when providing one fixture"
47
+ end
48
+
49
+ names.each do |fixture_name|
50
+ method_name = opts[:accessor] == true ? fixture_name.split("/").last : opts[:accessor]
51
+ ivar = :"@#{method_name}"
52
+
53
+ class_eval <<-EV, __FILE__, __LINE__ + 1
54
+ def #{method_name}
55
+ return #{ivar} if defined?(#{ivar})
56
+
57
+ value = fixtury("#{fixture_name}")
58
+ #{ivar} = value
59
+ end
60
+ EV
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ def fixtury(name)
68
+ return nil unless fixtury_store
69
+
70
+ name = name.to_s
71
+
72
+ unless name.include?("/")
73
+ local_name = "#{self.class.name.underscore}/#{name}"
74
+ if self.fixtury_dependencies.include?(local_name)
75
+ return fixtury_store.get(local_name)
76
+ end
77
+ end
78
+
79
+ unless self.fixtury_dependencies.include?(name)
80
+ raise ArgumentError, "Unrecognized fixtury dependency `#{name}` for #{self.class}"
81
+ end
82
+
83
+ fixtury_store.get(name)
84
+ end
85
+
86
+ def fixtury_store
87
+ ::Fixtury::Store.instance
88
+ end
89
+
90
+ def fixtury_loaded?(name)
91
+ return false unless fixtury_store
92
+
93
+ fixtury_store.loaded?(name)
94
+ end
95
+
96
+ def fixtury_database_connections
97
+ ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
98
+ end
99
+
100
+ # piggybacking activerecord fixture setup for now.
101
+ def setup_fixtures(*args)
102
+ if fixtury_dependencies.any?
103
+ setup_fixtury_fixtures
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ # piggybacking activerecord fixture setup for now.
110
+ def teardown_fixtures(*args)
111
+ if fixtury_dependencies.any?
112
+ teardown_fixtury_fixtures
113
+ else
114
+ super
115
+ end
116
+ end
117
+
118
+ def setup_fixtury_fixtures
119
+ return unless use_transactional_fixtures
120
+
121
+ clear_expired_fixtury_fixtures!
122
+ load_all_fixtury_fixtures!
123
+
124
+ fixtury_database_connections.each do |conn|
125
+ conn.begin_transaction joinable: false
126
+ end
127
+ end
128
+
129
+ def teardown_fixtury_fixtures
130
+ return unless use_transactional_fixtures
131
+
132
+ fixtury_database_connections.each(&:rollback_transaction)
133
+ end
134
+
135
+ def clear_expired_fixtury_fixtures!
136
+ return unless fixtury_store
137
+
138
+ fixtury_store.clear_expired_references!
139
+ end
140
+
141
+ def load_all_fixtury_fixtures!
142
+ fixtury_dependencies.each do |name|
143
+ fixtury(name) unless fixtury_loaded?(name)
144
+ end
145
+ end
146
+
147
+ end
148
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fixtury
4
4
 
5
- VERSION = "0.1.0.beta"
5
+ VERSION = "0.2.1"
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.beta
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nelson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2020-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: autotest
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '10.0'
117
+ version: '13.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '10.0'
124
+ version: '13.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: sqlite
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -160,8 +160,6 @@ files:
160
160
  - lib/fixtury/errors/fixture_not_defined_error.rb
161
161
  - lib/fixtury/errors/schema_frozen_error.rb
162
162
  - lib/fixtury/errors/unrecognizable_locator_error.rb
163
- - lib/fixtury/execution_context.rb
164
- - lib/fixtury/hooks.rb
165
163
  - lib/fixtury/locator.rb
166
164
  - lib/fixtury/locator_backend/common.rb
167
165
  - lib/fixtury/locator_backend/globalid.rb
@@ -172,6 +170,7 @@ files:
172
170
  - lib/fixtury/schema.rb
173
171
  - lib/fixtury/store.rb
174
172
  - lib/fixtury/tasks.rake
173
+ - lib/fixtury/test_hooks.rb
175
174
  - lib/fixtury/version.rb
176
175
  homepage: https://github.com/guideline-tech/fixtury
177
176
  licenses: []
@@ -191,9 +190,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
190
  version: '0'
192
191
  required_rubygems_version: !ruby/object:Gem::Requirement
193
192
  requirements:
194
- - - ">"
193
+ - - ">="
195
194
  - !ruby/object:Gem::Version
196
- version: 1.3.1
195
+ version: '0'
197
196
  requirements: []
198
197
  rubygems_version: 3.0.6
199
198
  signing_key:
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # a class made available so helper methods can be provided within the fixture dsl
4
- module Fixtury
5
- class ExecutionContext
6
-
7
- end
8
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fixtury/store"
4
-
5
- module Fixtury
6
- module Hooks
7
-
8
- extend ::ActiveSupport::Concern
9
-
10
- included do
11
- class_attribute :fixtury_dependencies
12
- self.fixtury_dependencies = Set.new
13
- end
14
-
15
- module ClassMethods
16
-
17
- def fixtury(*names)
18
- self.fixtury_dependencies += names.flatten.compact.map(&:to_s)
19
- end
20
-
21
- end
22
-
23
- def fixtury(name)
24
- raise ArgumentError unless self.fixtury_dependencies.include?(name.to_s)
25
-
26
- ::Fixtury::Store.instance.get(name)
27
- end
28
-
29
- def fixtury_loaded?(name)
30
- ::Fixtury::Store.instance.loaded?(name)
31
- end
32
-
33
- def fixtury_database_connections
34
- ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
35
- end
36
-
37
- # piggybacking activerecord fixture setup for now.
38
- def setup_fixtures(*args)
39
- if fixtury_dependencies.any?
40
- setup_fixtury_fixtures
41
- else
42
- super
43
- end
44
- end
45
-
46
- # piggybacking activerecord fixture setup for now.
47
- def teardown_fixtures(*args)
48
- if fixtury_dependencies.any?
49
- teardown_fixtury_fixtures
50
- else
51
- super
52
- end
53
- end
54
-
55
- def setup_fixtury_fixtures
56
- return unless use_transactional_fixtures
57
-
58
- clear_expired_fixtury_fixtures!
59
- load_all_fixtury_fixtures!
60
-
61
- fixtury_database_connections.each do |conn|
62
- conn.begin_transaction joinable: false
63
- end
64
- end
65
-
66
- def teardown_fixtury_fixtures
67
- return unless use_transactional_fixtures
68
-
69
- fixtury_database_connections.each(&:rollback_transaction)
70
- end
71
-
72
- def clear_expired_fixtury_fixtures!
73
- ::Fixtury::Store.instance.clear_expired_references!
74
- end
75
-
76
- def load_all_fixtury_fixtures!
77
- fixtury_dependencies.each do |name|
78
- fixtury(name) unless fixtury_loaded?(name)
79
- end
80
- end
81
-
82
- end
83
- end