fixtury 0.3.2 → 0.4.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: 11c65dc0db10367bf67f7d421ccc76e7b647a5bf73357431bc85dbd788667b00
4
- data.tar.gz: 7042ed9b891e4fd0e2bdcade6cc0145160e5fb1dd6394d2bcd8de612ecceb1f8
3
+ metadata.gz: 35c4db20425a837221a7c979e51371b77e00790cded54b182b31e62f7f57d8c2
4
+ data.tar.gz: cbdb024ba301b393b97604879594c1d9d53bfe1ffd4f24959824e8f41e1fe4e2
5
5
  SHA512:
6
- metadata.gz: ed2b328ac82a6506a9c0d4fb26e049ee249cae994dd4406d2896c0b4be8e270dc54fef1a5f94a887077abc5a9a964a6412bea23bccce7ead21c600c70c2f4374
7
- data.tar.gz: 18888bd37fdd508552353f5aa4d076f5bedd4ccf4420d7fc914450dcbaf5ea0c1cb29b428af3c94c3c617fd64359831f43594f65e3e9d300166329e0155e3b11
6
+ metadata.gz: 4748b476b6683ac9275a0c62ebca36f346f5d2bea208d47f55dfd836b521283c383aee7847961ffc90726292fd187389fc65b650dd508f9c67288fa32ae88c6c
7
+ data.tar.gz: bc765697630a9780752ab2ab9512dbe6bd92cee4f612dfa1ba11437d1f59f3e0c58a7d5a107576704d0018507ce989bf2e8726c165f244bf8757676c301a4f4d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fixtury (0.3.2)
4
+ fixtury (0.4.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -8,8 +8,18 @@ require "fixtury/schema"
8
8
  require "fixtury/locator"
9
9
  require "fixtury/store"
10
10
 
11
+ # Top level namespace of the gem
11
12
  module Fixtury
12
13
 
14
+ LOG_LEVELS = {
15
+ (LOG_LEVEL_NONE = :none) => 0,
16
+ (LOG_LEVEL_INFO = :info) => 1,
17
+ (LOG_LEVEL_DEBUG = :debug) => 2,
18
+ (LOG_LEVEL_ALL = :all) => 3,
19
+ }.freeze
20
+
21
+ DEFAULT_LOG_LEVEL = LOG_LEVEL_INFO
22
+
13
23
  # Shortcut for opening the top level schema.
14
24
  def self.define(&block)
15
25
  schema.define(&block)
@@ -19,7 +29,31 @@ module Fixtury
19
29
  # The default top level schema. Fixtury::Schema instances can be completely self-contained but most
20
30
  # usage would be through this shared definition.
21
31
  def self.schema
22
- @top_level_schema ||= ::Fixtury::Schema.new(parent: nil, name: "")
32
+ @schema ||= ::Fixtury::Schema.new(parent: nil, name: "")
33
+ end
34
+
35
+ def self.log_level
36
+ return @log_level if @log_level
37
+
38
+ @log_level = ENV["FIXTURY_LOG_LEVEL"]
39
+ @log_level ||= DEFAULT_LOG_LEVEL
40
+ @log_level = @log_level.to_s.to_sym
41
+ @log_level
42
+ end
43
+
44
+ def self.log(text = nil, level: LOG_LEVEL_DEBUG, name: nil)
45
+ desired_level = LOG_LEVELS.fetch(log_level) { DEFAULT_LOG_LEVEL }
46
+ return if desired_level == LOG_LEVEL_NONE
47
+
48
+ message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
49
+ return unless desired_level >= message_level
50
+
51
+ msg = +"[fixtury"
52
+ msg << "|#{name}" if name
53
+ msg << "]"
54
+ msg << " #{text}" if text
55
+ msg << " #{yield}" if block_given?
56
+ puts msg
23
57
  end
24
58
 
25
59
  end
@@ -7,14 +7,17 @@ module Fixtury
7
7
 
8
8
  attr_reader :name
9
9
  attr_reader :schema
10
+ alias parent schema
11
+ attr_reader :options
10
12
 
11
13
  attr_reader :callable
12
14
  attr_reader :enhancements
13
15
 
14
- def initialize(schema: nil, name:, &block)
16
+ def initialize(schema: nil, name:, options: {}, &block)
15
17
  @name = name
16
18
  @schema = schema
17
19
  @callable = block
20
+ @options = options
18
21
  @enhancements = []
19
22
  end
20
23
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fixtury
4
+ module Errors
5
+ class OptionCollisionError < ::StandardError
6
+
7
+ def initialize(schema_name, option_key, old_value, new_value)
8
+ super("The #{schema_name.inspect} schema #{option_key.inspect} option value of #{old_value.inspect} conflicts with the new value #{new_value.inspect}.")
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Fixtury
2
4
  module Errors
3
5
  class SchemaFrozenError < ::StandardError
@@ -9,12 +9,17 @@ module Fixtury
9
9
  new(name, HOLDER_VALUE)
10
10
  end
11
11
 
12
- attr_reader :name, :value, :created_at
12
+ def self.create(name, value)
13
+ new(name, value)
14
+ end
15
+
16
+ attr_reader :name, :value, :created_at, :options
13
17
 
14
- def initialize(name, value)
18
+ def initialize(name, value, options = {})
15
19
  @name = name
16
20
  @value = value
17
21
  @created_at = Time.now.to_i
22
+ @options = options
18
23
  end
19
24
 
20
25
  def holder?
@@ -5,21 +5,33 @@ require "fixtury/path"
5
5
  require "fixtury/errors/already_defined_error"
6
6
  require "fixtury/errors/fixture_not_defined_error"
7
7
  require "fixtury/errors/schema_frozen_error"
8
+ require "fixtury/errors/option_collision_error"
8
9
 
9
10
  module Fixtury
10
11
  class Schema
11
12
 
12
- attr_reader :definitions, :children, :name, :parent, :relative_name, :around_fixture_definition
13
+ attr_reader :definitions, :children, :name, :parent, :relative_name, :around_fixture_definition, :options
13
14
 
14
15
  def initialize(parent:, name:)
15
16
  @name = name
16
17
  @parent = parent
17
18
  @relative_name = @name.split("/").last
18
19
  @around_fixture_definition = nil
20
+ @options = {}
19
21
  @frozen = false
20
22
  reset!
21
23
  end
22
24
 
25
+ def merge_options(opts = {})
26
+ opts.each_pair do |k, v|
27
+ if options.key?(k) && options[k] != v
28
+ raise ::Fixtury::Errors::OptionCollisionError.new(name, k, options[k], v)
29
+ end
30
+
31
+ options[k] = v
32
+ end
33
+ end
34
+
23
35
  def around_fixture(&block)
24
36
  @around_fixture_definition = block
25
37
  end
@@ -83,19 +95,19 @@ module Fixtury
83
95
  out.join("\n")
84
96
  end
85
97
 
86
- def namespace(name, &block)
98
+ def namespace(name, options = {}, &block)
87
99
  ensure_not_frozen!
88
100
  ensure_no_conflict!(name: name, definitions: true, namespaces: false)
89
101
 
90
- child = find_or_create_child_schema(name: name)
102
+ child = find_or_create_child_schema(name: name, options: options)
91
103
  child.instance_eval(&block) if block_given?
92
104
  child
93
105
  end
94
106
 
95
- def fixture(name, &block)
107
+ def fixture(name, options = {}, &block)
96
108
  ensure_not_frozen!
97
109
  ensure_no_conflict!(name: name, definitions: true, namespaces: true)
98
- create_child_definition(name: name, &block)
110
+ create_child_definition(name: name, options: options, &block)
99
111
  end
100
112
 
101
113
  def enhance(name, &block)
@@ -108,14 +120,14 @@ module Fixtury
108
120
  def merge(other_ns)
109
121
  ensure_not_frozen!
110
122
  other_ns.definitions.each_pair do |name, dfn|
111
- fixture(name, &dfn.callable)
123
+ fixture(name, dfn.options, &dfn.callable)
112
124
  dfn.enhancements.each do |e|
113
125
  enhance(name, &e)
114
126
  end
115
127
  end
116
128
 
117
129
  other_ns.children.each_pair do |name, other_ns_child|
118
- namespace(name) do
130
+ namespace(name, other_ns_child.options) do
119
131
  merge(other_ns_child)
120
132
  end
121
133
  end
@@ -186,7 +198,7 @@ module Fixtury
186
198
  children[name.to_s]
187
199
  end
188
200
 
189
- def find_or_create_child_schema(name:)
201
+ def find_or_create_child_schema(name:, options:)
190
202
  name = name.to_s
191
203
  child = find_child_schema(name: name)
192
204
  child ||= begin
@@ -195,6 +207,7 @@ module Fixtury
195
207
  self.class.new(name: child_name, parent: self)
196
208
  end
197
209
  end
210
+ child.merge_options(options)
198
211
  child
199
212
  end
200
213
 
@@ -202,9 +215,9 @@ module Fixtury
202
215
  definitions[name.to_s]
203
216
  end
204
217
 
205
- def create_child_definition(name:, &block)
218
+ def create_child_definition(name:, options:, &block)
206
219
  child_name = build_child_name(name: name)
207
- definition = ::Fixtury::Definition.new(name: child_name, schema: self, &block)
220
+ definition = ::Fixtury::Definition.new(name: child_name, schema: self, options: options, &block)
208
221
  definitions[name.to_s] = definition
209
222
  end
210
223
 
@@ -10,12 +10,6 @@ require "fixtury/reference"
10
10
  module Fixtury
11
11
  class Store
12
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
-
19
13
  cattr_accessor :instance
20
14
 
21
15
  attr_reader :filepath, :references, :ttl, :auto_refresh_expired
@@ -25,15 +19,11 @@ module Fixtury
25
19
  def initialize(
26
20
  filepath: nil,
27
21
  locator: ::Fixtury::Locator.instance,
28
- log_level: nil,
29
22
  ttl: nil,
30
23
  schema: nil,
31
24
  auto_refresh_expired: false
32
25
  )
33
26
  @schema = schema || ::Fixtury.schema
34
- @log_level = log_level.nil? ? ENV["FIXTURY_LOG_LEVEL"] : log_level
35
- @log_level ||= LOG_LEVEL_NONE
36
- @log_level = @log_level.to_s.to_sym
37
27
  @locator = locator
38
28
  @filepath = filepath
39
29
  @references = @filepath && ::File.file?(@filepath) ? ::YAML.load_file(@filepath) : {}
@@ -59,7 +49,7 @@ module Fixtury
59
49
 
60
50
  references.delete_if do |name, ref|
61
51
  is_expired = ref_invalid?(ref)
62
- log(level: LOG_LEVEL_INFO) { "expiring #{name}" } if is_expired
52
+ log("expiring #{name}", level: LOG_LEVEL_DEBUG) if is_expired
63
53
  is_expired
64
54
  end
65
55
  end
@@ -81,7 +71,7 @@ module Fixtury
81
71
  pattern = pattern[0...-1] if glob
82
72
  references.delete_if do |key, _value|
83
73
  hit = glob ? key.start_with?(pattern) : key == pattern
84
- log(level: LOG_LEVEL_INFO) { "clearing #{key}" } if hit
74
+ log("clearing #{key}", level: LOG_LEVEL_DEBUG) if hit
85
75
  hit
86
76
  end
87
77
  dump_to_file
@@ -100,7 +90,7 @@ module Fixtury
100
90
  full_name = dfn.name
101
91
  ref = references[full_name]
102
92
  result = ref&.real?
103
- log(level: LOG_LEVEL_DEBUG) { result ? "hit #{full_name}" : "miss #{full_name}" }
93
+ log(result ? "hit #{full_name}" : "miss #{full_name}", level: LOG_LEVEL_ALL)
104
94
  result
105
95
  end
106
96
 
@@ -114,7 +104,7 @@ module Fixtury
114
104
  end
115
105
 
116
106
  if ref && auto_refresh_expired && ref_invalid?(ref)
117
- log(level: LOG_LEVEL_INFO) { "refreshing #{full_name}" }
107
+ log("refreshing #{full_name}", level: LOG_LEVEL_DEBUG)
118
108
  clear_ref(full_name)
119
109
  ref = nil
120
110
  end
@@ -122,11 +112,11 @@ module Fixtury
122
112
  value = nil
123
113
 
124
114
  if ref
125
- log(level: LOG_LEVEL_DEBUG) { "hit #{full_name}" }
115
+ log("hit #{full_name}", level: LOG_LEVEL_ALL)
126
116
  value = load_ref(ref.value)
127
117
  if value.nil?
128
118
  clear_ref(full_name)
129
- log(level: LOG_LEVEL_DEBUG) { "missing #{full_name}" }
119
+ log("missing #{full_name}", level: LOG_LEVEL_ALL)
130
120
  end
131
121
  end
132
122
 
@@ -136,7 +126,7 @@ module Fixtury
136
126
 
137
127
  value = dfn.call(store: self, execution_context: execution_context)
138
128
 
139
- log(level: LOG_LEVEL_INFO) { "store #{full_name}" }
129
+ log("store #{full_name}", level: LOG_LEVEL_DEBUG)
140
130
 
141
131
  ref = dump_ref(full_name, value)
142
132
  ref = ::Fixtury::Reference.new(full_name, ref)
@@ -165,14 +155,8 @@ module Fixtury
165
155
  !locator.recognize?(ref.value)
166
156
  end
167
157
 
168
- def log(level: LOG_LEVEL_DEBUG, name: "store")
169
- desired_level = LOG_LEVELS.fetch(log_level) { LOG_LEVEL_NONE }
170
- return if desired_level == LOG_LEVEL_NONE
171
-
172
- message_level = LOG_LEVELS.fetch(level) { LOG_LEVEL_DEBUG }
173
- return unless desired_level >= message_level
174
-
175
- puts "[fixtury|#{name}] #{yield}"
158
+ def log(msg, level:)
159
+ ::Fixtury.log(msg, level: level, name: "store")
176
160
  end
177
161
 
178
162
  end
@@ -33,9 +33,11 @@ module Fixtury
33
33
  ns = ns.namespace(ns_name){}
34
34
  end
35
35
 
36
- names.each do |fixture_name|
36
+ names.map! do |fixture_name|
37
37
  ns.fixture(fixture_name, &definition)
38
- self.local_fixtury_dependencies += ["/#{namespace}/#{fixture_name}"]
38
+ new_name = "/#{namespace}/#{fixture_name}"
39
+ self.local_fixtury_dependencies += [new_name]
40
+ new_name
39
41
  end
40
42
 
41
43
  # otherwise, just record the dependency
@@ -43,12 +45,14 @@ module Fixtury
43
45
  self.fixtury_dependencies += names.flatten.compact.map(&:to_s)
44
46
  end
45
47
 
46
- accessor_option = opts.key?(:accessor) ? opts[:accessor] : true
48
+ accessor_option = opts[:as]
49
+ accessor_option = opts[:accessor] if accessor_option.nil? # old version, backwards compatability
50
+ accessor_option = accessor_option.nil? ? true : accessor_option
47
51
 
48
52
  if accessor_option
49
53
 
50
54
  if accessor_option != true && names.length > 1
51
- raise ArgumentError, "A named :accessor option is only available when providing one fixture"
55
+ raise ArgumentError, "A named :as option is only available when providing one fixture"
52
56
  end
53
57
 
54
58
  names.each do |fixture_name|
@@ -78,12 +82,15 @@ module Fixtury
78
82
 
79
83
  name = name.to_s
80
84
 
81
- local_alias = "/#{self.class.fixtury_namespace}/#{name}"
82
- if self.local_fixtury_dependencies.include?(local_alias)
83
- return fixtury_store.get(local_alias, execution_context: self)
85
+ # in the case that we're looking for a relative fixture, see if it's registered relative to the test's namespace.
86
+ unless name.include?("/")
87
+ local_name = "/#{self.class.fixtury_namespace}/#{name}"
88
+ if local_fixtury_dependencies.include?(local_name)
89
+ return fixtury_store.get(local_name, execution_context: self)
90
+ end
84
91
  end
85
92
 
86
- unless self.fixtury_dependencies.include?(name)
93
+ unless fixtury_dependencies.include?(name) || local_fixtury_dependencies.include?(name)
87
94
  raise ArgumentError, "Unrecognized fixtury dependency `#{name}` for #{self.class}"
88
95
  end
89
96
 
@@ -123,7 +130,7 @@ module Fixtury
123
130
  end
124
131
 
125
132
  def setup_fixtury_fixtures
126
- return unless use_transactional_fixtures
133
+ return unless fixtury_use_transactions?
127
134
 
128
135
  clear_expired_fixtury_fixtures!
129
136
  load_all_fixtury_fixtures!
@@ -134,7 +141,7 @@ module Fixtury
134
141
  end
135
142
 
136
143
  def teardown_fixtury_fixtures
137
- return unless use_transactional_fixtures
144
+ return unless fixtury_use_transactions?
138
145
 
139
146
  fixtury_database_connections.each(&:rollback_transaction)
140
147
  end
@@ -147,9 +154,19 @@ module Fixtury
147
154
 
148
155
  def load_all_fixtury_fixtures!
149
156
  (fixtury_dependencies | local_fixtury_dependencies).each do |name|
150
- fixtury(name) unless fixtury_loaded?(name)
157
+ unless fixtury_loaded?(name)
158
+ ::Fixtury.log("preloading #{name.inspect}", name: "test", level: ::Fixtury::LOG_LEVEL_INFO)
159
+ fixtury(name)
160
+ end
151
161
  end
152
162
  end
153
163
 
164
+ def fixtury_use_transactions?
165
+ return use_transactional_tests if respond_to?(:use_transactional_tests)
166
+ return use_transactional_fixtures if respond_to?(:use_transactional_fixtures)
167
+
168
+ true
169
+ end
170
+
154
171
  end
155
172
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fixtury
4
4
 
5
- VERSION = "0.3.2"
5
+ VERSION = "0.4.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.3.2
4
+ version: 0.4.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-10-21 00:00:00.000000000 Z
11
+ date: 2020-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: autotest
@@ -159,6 +159,7 @@ files:
159
159
  - lib/fixtury/errors/already_defined_error.rb
160
160
  - lib/fixtury/errors/circular_dependency_error.rb
161
161
  - lib/fixtury/errors/fixture_not_defined_error.rb
162
+ - lib/fixtury/errors/option_collision_error.rb
162
163
  - lib/fixtury/errors/schema_frozen_error.rb
163
164
  - lib/fixtury/errors/unrecognizable_locator_error.rb
164
165
  - lib/fixtury/locator.rb