fabrication 2.27.0 → 2.30.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: 96b935d9bd47864641229df13dda6eda91c99ffdf692495edf1c71703d8edc0b
4
- data.tar.gz: 6b7c6d1c90ecb94b06b8464ea0bcf2127ba5cf28d1a1adac8cad483cb2a8c4f4
3
+ metadata.gz: 38d9550f8e85412ca21c540ad7f850a61f9f511dce7048487c8cfc49f965922d
4
+ data.tar.gz: a2e732f74342b3342584483af9b2a446f4bf42fea8af50edbf1d792203e4d16b
5
5
  SHA512:
6
- metadata.gz: cb0b172c07aeb2922312926e2fe62cd55f406c098d4b4d4e1c5e19bf38ea965022c1c4aa06a1c16898aa4abf443bef327bf9e48aa177a9e73a446bb568b5b3d9
7
- data.tar.gz: 45328d26eb07c9be1f95eb0648535233680379a6c014878202cdfd3707eb6fa522cea77d9d2317bd4418458ce58c846e74105300f5f244e8cab95d4001abe85a
6
+ metadata.gz: bc4ed3c24fcd1d18ffff850a98d35fafe5408e2b166d234944a82d34e272a9a1fa1da1dff5df6677f7d083ac7cade969f10dcdc95e2fe8cb2b45d3f1719096e8
7
+ data.tar.gz: 28ad7426b1426f3b1f284bf1cf172397b83734b3865f91d64e755995da846f5bf4efc4629e90ee7a800c309e9f39898fac5ff3c87ab2607e7c0a6290d57490f8
@@ -1,3 +1,5 @@
1
+ require 'logger'
2
+
1
3
  module Fabrication
2
4
  module Config
3
5
  extend self
@@ -14,14 +16,22 @@ module Fabrication
14
16
  nil
15
17
  end
16
18
 
19
+ attr_writer :logger, :sequence_start
20
+
21
+ def logger
22
+ @logger ||= Logger.new($stdout).tap do |logger|
23
+ logger.level = Logger::WARN
24
+ end
25
+ end
26
+
17
27
  def fabricator_path
18
28
  @fabricator_path ||= ['test/fabricators', 'spec/fabricators']
19
29
  end
20
30
  alias fabricator_paths fabricator_path
21
31
 
22
32
  def fabricator_dir
23
- puts 'DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been ' \
24
- 'replaced by Fabrication::Config.fabricator_path'
33
+ Support.log_deprecation('Fabrication::Config.fabricator_dir has been ' \
34
+ 'replaced by Fabrication::Config.fabricator_path')
25
35
  fabricator_path
26
36
  end
27
37
 
@@ -30,13 +40,11 @@ module Fabrication
30
40
  end
31
41
 
32
42
  def fabricator_dir=(folders)
33
- puts 'DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been ' \
34
- 'replaced by Fabrication::Config.fabricator_path'
43
+ Support.log_deprecation('Fabrication::Config.fabricator_dir has been ' \
44
+ 'replaced by Fabrication::Config.fabricator_path')
35
45
  self.fabricator_path = folders
36
46
  end
37
47
 
38
- attr_writer :sequence_start
39
-
40
48
  def sequence_start
41
49
  @sequence_start ||= 0
42
50
  end
@@ -67,8 +75,10 @@ module Fabrication
67
75
  end
68
76
 
69
77
  def register_with_steps=(value)
70
- puts 'DEPRECATION WARNING: Fabrication::Config.register_with_steps has been ' \
71
- 'deprecated. Please regenerate your cucumber steps with `rails g fabrication:cucumber_steps'
78
+ Support.log_deprecation(
79
+ 'Fabrication::Config.register_with_steps has been deprecated. ' \
80
+ 'Please regenerate your cucumber steps with `rails g fabrication:cucumber_steps'
81
+ )
72
82
 
73
83
  return unless value
74
84
 
@@ -1,3 +1,5 @@
1
+ require 'singleton'
2
+
1
3
  module Fabrication
2
4
  module Cucumber
3
5
  class StepFabricator
@@ -85,17 +87,23 @@ module Fabrication
85
87
  end
86
88
  end
87
89
 
88
- module Fabrications
90
+ class Fabrications
91
+ include Singleton
92
+
89
93
  def self.fabrications
90
- @fabrications ||= {}
94
+ instance.fabrications
91
95
  end
92
96
 
93
97
  def self.[](fabricator)
94
- fabrications[fabricator.to_sym]
98
+ instance.fabrications[fabricator.to_sym]
95
99
  end
96
100
 
97
101
  def self.[]=(fabricator, fabrication)
98
- fabrications[fabricator.to_sym] = fabrication
102
+ instance.fabrications[fabricator.to_sym] = fabrication
103
+ end
104
+
105
+ def fabrications
106
+ @fabrications ||= {}
99
107
  end
100
108
  end
101
109
  end
@@ -11,10 +11,10 @@ module Fabrication
11
11
  end
12
12
 
13
13
  def build_instance
14
- self._instance = if _klass.respond_to?(:protected_attributes)
15
- _klass.new(_attributes, without_protection: true)
14
+ self._instance = if resolved_class.respond_to?(:protected_attributes)
15
+ resolved_class.new(_attributes, without_protection: true)
16
16
  else
17
- _klass.new(_attributes)
17
+ resolved_class.new(_attributes)
18
18
  end
19
19
  end
20
20
  end
@@ -1,7 +1,7 @@
1
1
  module Fabrication
2
2
  module Generator
3
3
  class Base
4
- def self.supports?(_klass)
4
+ def self.supports?(_resolved_class)
5
5
  true
6
6
  end
7
7
 
@@ -11,6 +11,9 @@ module Fabrication
11
11
  if callbacks[:initialize_with]
12
12
  build_instance_with_constructor_override(callbacks[:initialize_with])
13
13
  elsif callbacks[:on_init]
14
+ Fabrication::Support.log_deprecation(
15
+ 'The on_init callback has been replaced by initialize_with. Please see the documentation for usage'
16
+ )
14
17
  build_instance_with_init_callback(callbacks[:on_init])
15
18
  else
16
19
  build_instance
@@ -19,18 +22,29 @@ module Fabrication
19
22
  _instance
20
23
  end
21
24
 
22
- def create(attributes = [], callbacks = [])
25
+ def create(attributes = [], callbacks = {})
23
26
  build(attributes, callbacks)
24
- execute_callbacks(callbacks[:before_validation])
25
- execute_callbacks(callbacks[:after_validation])
26
- execute_callbacks(callbacks[:before_save])
27
+ execute_deprecated_callbacks(callbacks, :before_validation, :before_create)
28
+ execute_deprecated_callbacks(callbacks, :after_validation, :before_create)
29
+ execute_deprecated_callbacks(callbacks, :before_save, :before_create)
27
30
  execute_callbacks(callbacks[:before_create])
28
31
  persist
29
32
  execute_callbacks(callbacks[:after_create])
30
- execute_callbacks(callbacks[:after_save])
33
+ execute_deprecated_callbacks(callbacks, :after_save, :after_create)
31
34
  _instance
32
35
  end
33
36
 
37
+ def execute_deprecated_callbacks(callbacks, callback_type, replacement_callback)
38
+ if callbacks[callback_type]
39
+ Fabrication::Support.log_deprecation(
40
+ "Using #{callback_type} is deprecated but you can replace it " \
41
+ "with #{replacement_callback} with the same result."
42
+ )
43
+ end
44
+
45
+ execute_callbacks(callbacks[callback_type])
46
+ end
47
+
34
48
  def execute_callbacks(callbacks)
35
49
  callbacks&.each { |callback| _instance.instance_exec(_instance, _transient_attributes, &callback) }
36
50
  end
@@ -59,12 +73,12 @@ module Fabrication
59
73
  end
60
74
 
61
75
  def build_instance_with_init_callback(callback)
62
- self._instance = _klass.new(*callback.call(_transient_attributes))
76
+ self._instance = resolved_class.new(*callback.call(_transient_attributes))
63
77
  set_attributes
64
78
  end
65
79
 
66
80
  def build_instance
67
- self._instance = _klass.new
81
+ self._instance = resolved_class.new
68
82
  set_attributes
69
83
  end
70
84
 
@@ -74,8 +88,8 @@ module Fabrication
74
88
  end
75
89
  end
76
90
 
77
- def initialize(klass)
78
- self._klass = klass
91
+ def initialize(resolved_class)
92
+ self.resolved_class = resolved_class
79
93
  end
80
94
 
81
95
  def respond_to_missing?(method_name, _include_private = false)
@@ -86,20 +100,31 @@ module Fabrication
86
100
  _attributes.fetch(method_name) { super }
87
101
  end
88
102
 
103
+ def _klass
104
+ Fabrication::Support.log_deprecation(
105
+ 'The `_klass` method in fabricator definitions has been replaced by `resolved_class`'
106
+ )
107
+
108
+ resolved_class
109
+ end
110
+
89
111
  protected
90
112
 
91
- attr_accessor :_klass, :_instance, :_transient_attributes
113
+ attr_accessor :resolved_class, :_instance
92
114
 
93
115
  def _attributes
94
116
  @_attributes ||= {}
95
117
  end
96
118
 
119
+ def _transient_attributes
120
+ @_transient_attributes ||= {}
121
+ end
122
+
97
123
  def persist
98
124
  _instance.save! if _instance.respond_to?(:save!)
99
125
  end
100
126
 
101
127
  def process_attributes(attributes)
102
- self._transient_attributes = ({})
103
128
  attributes.each do |attribute|
104
129
  _attributes[attribute.name] = attribute.processed_value(_attributes)
105
130
  _transient_attributes[attribute.name] = _attributes[attribute.name] if attribute.transient?
@@ -6,7 +6,7 @@ module Fabrication
6
6
  end
7
7
 
8
8
  def build_instance
9
- self._instance = _klass.new(_attributes)
9
+ self._instance = resolved_class.new(_attributes)
10
10
  end
11
11
 
12
12
  protected
@@ -6,10 +6,10 @@ module Fabrication
6
6
  end
7
7
 
8
8
  def build_instance
9
- self._instance = if _klass.respond_to?(:protected_attributes)
10
- _klass.new(_attributes, without_protection: true)
9
+ self._instance = if resolved_class.respond_to?(:protected_attributes)
10
+ resolved_class.new(_attributes, without_protection: true)
11
11
  else
12
- _klass.new(_attributes)
12
+ resolved_class.new(_attributes)
13
13
  end
14
14
  end
15
15
  end
@@ -11,14 +11,11 @@ module Fabrication
11
11
  end
12
12
 
13
13
  def set_attributes
14
- _attributes.each do |key, value|
15
- if (reflection = _klass.association_reflections[key]) && value.is_a?(Array)
16
- _instance.associations[key] = value
17
- _instance.after_save_hook do
18
- value.each { |o| _instance.send(reflection.add_method, o) }
19
- end
14
+ _attributes.each do |field_name, value|
15
+ if value.is_a?(Array) && (association = association_for(field_name))
16
+ set_association(association, field_name, value)
20
17
  else
21
- _instance.send("#{key}=", value)
18
+ set_attribute(field_name, value)
22
19
  end
23
20
  end
24
21
  end
@@ -29,8 +26,23 @@ module Fabrication
29
26
 
30
27
  private
31
28
 
29
+ def association_for(field_name)
30
+ resolved_class.association_reflections[field_name]
31
+ end
32
+
33
+ def set_attribute(field_name, value)
34
+ _instance.send("#{field_name}=", value)
35
+ end
36
+
37
+ def set_association(association, field_name, value)
38
+ _instance.associations[field_name] = value
39
+ _instance.after_save_hook do
40
+ value.each { |o| _instance.send(association.add_method, o) }
41
+ end
42
+ end
43
+
32
44
  def load_instance_hooks
33
- klass = _klass.respond_to?(:cti_base_model) ? _klass.cti_models.first : _klass
45
+ klass = resolved_class.respond_to?(:cti_base_model) ? resolved_class.cti_models.first : resolved_class
34
46
  klass.plugin :instance_hooks unless klass.new.respond_to? :after_save_hook
35
47
  end
36
48
  end
@@ -43,8 +43,8 @@ module Fabrication
43
43
 
44
44
  private
45
45
 
46
- def execute(*args, &block)
47
- Fabrication::Schematic::Runner.new(klass).instance_exec(*args, &block)
46
+ def execute(...)
47
+ Fabrication::Schematic::Runner.new(klass).instance_exec(...)
48
48
  end
49
49
 
50
50
  def process_count
@@ -1,8 +1,21 @@
1
+ require 'singleton'
2
+
1
3
  module Fabrication
2
4
  class Sequencer
5
+ include Singleton
6
+
3
7
  DEFAULT = :_default
4
8
 
5
9
  def self.sequence(name = DEFAULT, start = nil, &block)
10
+ instance.sequence(name, start, &block)
11
+ end
12
+
13
+ def self.clear
14
+ instance.sequences.clear
15
+ instance.sequence_blocks.clear
16
+ end
17
+
18
+ def sequence(name = DEFAULT, start = nil, &block)
6
19
  idx = sequences[name] ||= start || Fabrication::Config.sequence_start
7
20
  if block
8
21
  sequence_blocks[name] = block.to_proc
@@ -13,15 +26,15 @@ module Fabrication
13
26
  end
14
27
  end
15
28
 
16
- def self.sequences
29
+ def sequences
17
30
  @sequences ||= {}
18
31
  end
19
32
 
20
- def self.sequence_blocks
33
+ def sequence_blocks
21
34
  @sequence_blocks ||= {}
22
35
  end
23
36
 
24
- def self.reset
37
+ def reset
25
38
  Fabrication::Config.sequence_start = nil
26
39
  @sequences = nil
27
40
  @sequence_blocks = nil
@@ -1,79 +1,68 @@
1
1
  module Fabrication
2
- class Support
3
- class << self
4
- def fabricatable?(name)
5
- Fabrication.manager[name] || class_for(name)
6
- end
2
+ module Support
3
+ extend self
7
4
 
8
- def class_for(class_or_to_s)
9
- class_name = variable_name_to_class_name(class_or_to_s)
10
- constantize(class_name)
11
- rescue NameError => e
12
- raise Fabrication::UnfabricatableError.new(class_or_to_s, e)
13
- end
5
+ def fabricatable?(name)
6
+ Fabrication.manager[name] || class_for(name)
7
+ end
14
8
 
15
- def constantize(camel_cased_word)
16
- names = camel_cased_word.split('::')
17
- Object.const_get(camel_cased_word) if names.empty?
18
- names.shift if names.size > 1 && names.first.empty?
19
- names.inject(Object) do |constant, name|
20
- if constant == Object
21
- constant.const_get(name)
22
- else
23
- candidate = constant.const_get(name)
24
- next candidate if constant.const_defined?(name, false)
25
- next candidate unless Object.const_defined?(name)
9
+ def log_deprecation(message)
10
+ Config.logger.warn("[DEPRECATION][fabrication] #{message}")
11
+ end
26
12
 
27
- constant = constant.ancestors.inject do |const, ancestor|
28
- break const if ancestor == Object
29
- break ancestor if ancestor.const_defined?(name, false)
13
+ def class_for(class_or_to_s)
14
+ constantize(variable_name_to_class_name(class_or_to_s))
15
+ rescue NameError => e
16
+ raise Fabrication::UnfabricatableError.new(class_or_to_s, e)
17
+ end
30
18
 
31
- const
32
- end
33
- constant.const_get(name, false)
34
- end
35
- end
36
- end
19
+ def constantize(camel_cased_word)
20
+ return camel_cased_word if camel_cased_word.is_a?(Class)
37
21
 
38
- def extract_options!(args)
39
- args.last.is_a?(::Hash) ? args.pop : {}
22
+ camel_cased_word.to_s.split('::').reduce(Object) do |resolved_class, class_part|
23
+ resolved_class.const_get(class_part)
40
24
  end
25
+ end
41
26
 
42
- def variable_name_to_class_name(name)
43
- name_string = name.to_s
27
+ def extract_options!(args)
28
+ args.last.is_a?(::Hash) ? args.pop : {}
29
+ end
44
30
 
45
- if name_string.respond_to?(:camelize)
46
- name_string.camelize
47
- else
48
- name_string.gsub(%r{/(.?)}) do
49
- "::#{Regexp.last_match(1).upcase}"
50
- end.gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase }
51
- end
52
- end
31
+ def variable_name_to_class_name(name)
32
+ name_string = name.to_s
53
33
 
54
- def find_definitions
55
- puts 'DEPRECATION WARNING: Fabrication::Support.find_definitions has been replaced ' \
56
- 'by Fabrication.manager.load_definitions and will be removed in 3.0.0.'
57
- Fabrication.manager.load_definitions
34
+ if name_string.respond_to?(:camelize)
35
+ name_string.camelize
36
+ else
37
+ name_string
38
+ .gsub(%r{/(.?)}) { "::#{Regexp.last_match(1).upcase}" }
39
+ .gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase }
58
40
  end
41
+ end
59
42
 
60
- def hash_class
61
- @hash_class ||= defined?(HashWithIndifferentAccess) ? HashWithIndifferentAccess : Hash
62
- end
43
+ def find_definitions
44
+ log_deprecation('Fabrication::Support.find_definitions has been replaced by ' \
45
+ 'Fabrication.manager.load_definitions and will be removed in 3.0.0.')
63
46
 
64
- def singularize(string)
65
- string.singularize
66
- rescue StandardError
67
- string.end_with?('s') ? string[0..-2] : string
68
- end
47
+ Fabrication.manager.load_definitions
48
+ end
69
49
 
70
- def underscore(string)
71
- string.gsub(/::/, '/')
72
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
73
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
74
- .tr('-', '_')
75
- .downcase
76
- end
50
+ def hash_class
51
+ @hash_class ||= defined?(HashWithIndifferentAccess) ? HashWithIndifferentAccess : Hash
52
+ end
53
+
54
+ def singularize(string)
55
+ string.singularize
56
+ rescue StandardError
57
+ string.end_with?('s') ? string[0..-2] : string
58
+ end
59
+
60
+ def underscore(string)
61
+ string.gsub(/::/, '/')
62
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
63
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
64
+ .tr('-', '_')
65
+ .downcase
77
66
  end
78
67
  end
79
68
  end
@@ -1,37 +1,39 @@
1
+ require 'singleton'
2
+
1
3
  module Fabrication
2
4
  class Transform
5
+ include Singleton
6
+
3
7
  class << self
4
8
  def apply_to(schematic, attributes_hash)
5
9
  Fabrication.manager.load_definitions if Fabrication.manager.empty?
6
- attributes_hash.inject({}) { |h, (k, v)| h.update(k => apply_transform(schematic, k, v)) }
10
+ attributes_hash.inject({}) { |h, (k, v)| h.update(k => instance.apply_transform(schematic, k, v)) }
7
11
  end
8
12
 
9
13
  def clear_all
10
- @transforms = nil
11
- @overrides = nil
14
+ instance.transforms.clear
15
+ instance.overrides.clear
12
16
  end
13
17
 
14
18
  def define(attribute, transform)
15
- transforms[attribute] = transform
19
+ instance.transforms[attribute] = transform
16
20
  end
17
21
 
18
22
  def only_for(schematic, attribute, transform)
19
- overrides[schematic] = (overrides[schematic] || {}).merge!(attribute => transform)
23
+ instance.overrides[schematic] = (instance.overrides[schematic] || {}).merge!(attribute => transform)
20
24
  end
25
+ end
21
26
 
22
- private
23
-
24
- def overrides
25
- @overrides ||= {}
26
- end
27
+ def overrides
28
+ @overrides ||= {}
29
+ end
27
30
 
28
- def apply_transform(schematic, attribute, value)
29
- overrides.fetch(schematic, transforms)[attribute].call(value)
30
- end
31
+ def apply_transform(schematic, attribute, value)
32
+ overrides.fetch(schematic, transforms)[attribute].call(value)
33
+ end
31
34
 
32
- def transforms
33
- @transforms ||= Hash.new(->(value) { value })
34
- end
35
+ def transforms
36
+ @transforms ||= Hash.new(->(value) { value })
35
37
  end
36
38
  end
37
39
  end
@@ -1,3 +1,3 @@
1
1
  module Fabrication
2
- VERSION = '2.27.0'.freeze
2
+ VERSION = '2.30.0'.freeze
3
3
  end
data/lib/fabrication.rb CHANGED
@@ -31,7 +31,6 @@ module Fabrication
31
31
 
32
32
  module Generator
33
33
  autoload :ActiveRecord, 'fabrication/generator/active_record'
34
- autoload :ActiveRecord4, 'fabrication/generator/active_record_4'
35
34
  autoload :DataMapper, 'fabrication/generator/data_mapper'
36
35
  autoload :Mongoid, 'fabrication/generator/mongoid'
37
36
  autoload :Sequel, 'fabrication/generator/sequel'
@@ -40,7 +39,7 @@ module Fabrication
40
39
 
41
40
  def self.clear_definitions
42
41
  manager.clear
43
- Sequencer.sequences.clear
42
+ Sequencer.clear
44
43
  end
45
44
 
46
45
  def self.configure(&block)
@@ -48,12 +47,12 @@ module Fabrication
48
47
  end
49
48
 
50
49
  def self.manager
51
- @manager ||= Fabrication::Schematic::Manager.instance
50
+ Fabrication::Schematic::Manager.instance
52
51
  end
53
52
 
54
53
  def self.schematics
55
- puts 'DEPRECATION WARNING: Fabrication.schematics has been replaced by '\
56
- 'Fabrication.manager and will be removed in 3.0.0.'
54
+ Support.log_deprecation('Fabrication.schematics has been replaced by ' \
55
+ 'Fabrication.manager and will be removed in 3.0.0.')
57
56
  manager
58
57
  end
59
58
  end
@@ -8,7 +8,7 @@ module Fabrication
8
8
  end
9
9
 
10
10
  def self.source_root
11
- @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
11
+ File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
12
12
  end
13
13
  end
14
14
  end
@@ -19,7 +19,7 @@ module Fabrication
19
19
  end
20
20
 
21
21
  def self.source_root
22
- @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
22
+ File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
23
23
  end
24
24
 
25
25
  private
@@ -33,6 +33,8 @@ module Fabrication
33
33
  end
34
34
  rescue StandardError
35
35
  # no table? no problem!
36
+ rescue LoadError
37
+ # cannot find model file. This means it was already destroyed, so just continue.
36
38
  end
37
39
  end
38
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fabrication
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.27.0
4
+ version: 2.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Elliott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-03 00:00:00.000000000 Z
11
+ date: 2022-07-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Fabrication is an object generation framework for ActiveRecord, Mongoid,
14
14
  DataMapper, Sequel, or any other Ruby object.
@@ -70,14 +70,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - ">="
72
72
  - !ruby/object:Gem::Version
73
- version: 2.6.0
73
+ version: 2.7.0
74
74
  required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  requirements:
76
76
  - - ">="
77
77
  - !ruby/object:Gem::Version
78
78
  version: '0'
79
79
  requirements: []
80
- rubygems_version: 3.2.32
80
+ rubygems_version: 3.3.7
81
81
  signing_key:
82
82
  specification_version: 4
83
83
  summary: Generates object instances for test suites, seed files, etc.