fixtury 0.1.0.beta → 0.2.1

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: 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