factory_bot_factory 1.1.0 → 1.2.0

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: 3759620bd063f6090d72c455055888f658fcd1348304983ca5c595a053d3302c
4
- data.tar.gz: aa08b76ac4326ac1157a0f1c4e8cb87a5136e4a5f6a4bbc3811bed378f051443
3
+ metadata.gz: 87990d0dd64bc2e27d69c168a55f6057336b57796d44f5e6f6a807bd4182b26d
4
+ data.tar.gz: 037046cca064e07df3b08e7dbb9216856282e93b8f57bf76fae80e2f915e9980
5
5
  SHA512:
6
- metadata.gz: 1d38b330bad4022cb2cdca6acaeed2ff38791e38d99fb5c168c0927b764a86791fae4f6c9ce8a033efbe0b12f4f51fe55e4f99bb1dbfc86478b4e31f4b2147be
7
- data.tar.gz: a4d7f9f6c9d2ec67810648aee8eaafd283a0cc324169e1b72fcf30bf04a6e5212b0b3bf2dad9f8d4a0bf6bb7b9ae45f91746caf23b913f06f6be0c355c5e97bd
6
+ metadata.gz: 0c4af2c20e34c6f3cd0b955be96f8b9b17c459266742bb77302851a96177ffc277b3b16d3e64fa2392657387f55a748b965a2f0d978e09dbe228b99f5b7d4023
7
+ data.tar.gz: 4517dea66cccabe7abe4a27cd1b7e090c309491348db5957cfcf6cadb7bb4d3255803d6b5c3333cc25f409e330ab24db9f4a5dad31e8a0fb4ab5dc32e49f59a2
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- factory_bot_factory (1.1.0)
4
+ factory_bot_factory (1.2.0)
5
+ factory_bot (>= 4.8.2)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
@@ -56,7 +57,6 @@ PLATFORMS
56
57
  DEPENDENCIES
57
58
  activerecord (> 5.0.0.1)
58
59
  bundler (>= 2.2.10)
59
- factory_bot
60
60
  factory_bot_factory!
61
61
  faker
62
62
  pry (~> 0.13.1)
data/README.md CHANGED
@@ -76,7 +76,7 @@ FactoryBot.reload
76
76
  FactoryBot.build(:hash, id: 2)
77
77
  ```
78
78
 
79
- - `factory_name` - Specifize Factory Name
79
+ - `factory_name` - Specify Factory Name
80
80
 
81
81
  ```ruby
82
82
  puts FactoryBotFactory.build({ id: 1 }, factory_name: 'order')
@@ -90,7 +90,7 @@ FactoryBot.define do
90
90
  end
91
91
  ```
92
92
 
93
- - `klass` - Specifize Output Data Structure: Hash, OpenStruct and your ActiveModel or ActiveRecord Model
93
+ - `klass` - Specify Output Data Structure: Hash, OpenStruct and your ActiveModel or ActiveRecord Model
94
94
 
95
95
  You can convert your Hash object to OpenStruct factory.
96
96
 
@@ -124,7 +124,8 @@ Converter should respond to `call` method and return single or array of executab
124
124
 
125
125
  ```ruby
126
126
  FactoryBotFactory.configure do |config|
127
- config.string_converter = Proc.new { |k, v|
127
+ config.numeric_converter = Proc.new { |k, v| 'rand(99)' }
128
+ config.string_converter = Proc.new do |k, v|
128
129
  if v.to_s.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
129
130
  'Random.uuid()'
130
131
  elsif k.to_s.include?('name')
@@ -132,9 +133,7 @@ FactoryBotFactory.configure do |config|
132
133
  else
133
134
  "'#{v}'"
134
135
  end
135
- }
136
-
137
- config.numeric_converter = Proc.new { |k, v| 'rand(99)' }
136
+ end
138
137
  end
139
138
 
140
139
  FactoryBotFactory.build({ name: 'My Name', id: "de9515ee-006e-4a28-8af3-e88a5c771b93", age: 10 })
@@ -150,7 +149,7 @@ FactoryBot.define do
150
149
  end
151
150
  ```
152
151
 
153
- See more converters [Here](https://github.com/cdragon1116/factory_bot_factory/blob/release/1.1.0/lib/factory_bot_factory/config.rb#L3-L13)
152
+ See more converters [Here](https://github.com/cdragon1116/factory_bot_factory/blob/main/lib/factory_bot_factory/config.rb#L3-L13)
154
153
 
155
154
  ## Contributing
156
155
 
@@ -23,13 +23,15 @@ Gem::Specification.new do |spec|
23
23
  spec.bindir = "exe"
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
+ spec.required_ruby_version = '>= 1.8.6'
26
27
 
27
28
  spec.add_development_dependency "bundler", ">= 2.2.10"
28
29
  spec.add_development_dependency 'rake', '>= 11.2.2'
29
30
  spec.add_development_dependency "pry", '~> 0.13.1'
30
31
  spec.add_development_dependency "rspec", "~> 3.0"
31
- spec.add_development_dependency "factory_bot"
32
32
  spec.add_development_dependency "faker"
33
33
  spec.add_development_dependency "activerecord", "> 5.0.0.1"
34
34
  spec.add_development_dependency "sqlite3"
35
+
36
+ spec.add_dependency "factory_bot", '>= 4.8.2'
35
37
  end
@@ -1,29 +1,18 @@
1
1
  module FactoryBotFactory
2
2
  class Base
3
3
  class << self
4
- def build(*args)
5
- factory_name, klass, data, options = build_args(*args)
6
- options ||= {}
4
+ def build(data, options = {})
5
+ options[:klass] ||= data.class
6
+ options[:factory_name] ||= data.class.name.downcase
7
7
 
8
- raise ArgumentError if factory_name.nil? || klass.nil? || !valid_data?(data)
8
+ raise ArgumentError, "Unsupported data type. Supported format: Hash, OpenStruct, ActiveRecord instance." unless valid_data?(data)
9
9
  raise NestedToDeepError, 'Only support 5 nested levels' if options[:nested_level].to_i > 5
10
10
 
11
- factory(klass, data).new({ factory_name: factory_name }.merge(options)).generate(data)
11
+ factory(options[:klass], data).new(options).generate(data)
12
12
  end
13
13
 
14
14
  private
15
15
 
16
- def build_args(*args)
17
- # To be deprecated
18
- if args[0].is_a?(String) || args[0].is_a?(Symbol) && args.size >= 3
19
- args
20
- else
21
- arg = args[0]
22
- options = args[1..-1].inject({}) { |h, _h| h.merge(_h) } if args[1..-1]
23
- [arg.class.name.downcase, (options[:klass] || arg.class), arg, options]
24
- end
25
- end
26
-
27
16
  def factory(klass, data)
28
17
  if active_record?(data) && klass == data.class
29
18
  Object.const_get("FactoryBotFactory::ActiveRecordFactory")
@@ -13,15 +13,20 @@ module FactoryBotFactory
13
13
  }
14
14
 
15
15
  DEFAULT_OPTIONS = {
16
- factory_path: nil
16
+ factory_path: nil,
17
+ print_output: false
17
18
  }.merge(DEFAULT_CONVERTERS)
18
19
 
19
20
  attr_accessor *DEFAULT_OPTIONS.keys
20
21
 
21
22
  def initialize(options = {})
22
23
  options = DEFAULT_OPTIONS.merge(options)
23
- options[:factory_path] = options[:factory_path][0..-2] if options[:factory_path]&.end_with?("/")
24
24
  options.each { |k, v| instance_variable_set(:"@#{k}", v) }
25
25
  end
26
+
27
+ def factory_path=(path)
28
+ path = path[0..-2] if path&.end_with?("/")
29
+ @factory_path = path
30
+ end
26
31
  end
27
32
  end
@@ -1,44 +1,57 @@
1
+ require "factory_bot_factory/file_writer"
2
+
1
3
  module FactoryBotFactory
2
4
  class BaseFactory
3
5
 
6
+ attr_reader :file_path
7
+
4
8
  def initialize(options = {})
5
9
  @factory_name = options[:factory_name]
6
- @file_path = options[:file_path]
10
+ @file_path = build_file_path(options[:file_path])
7
11
  @nested_level = [(options[:nested_level] || 1), 5].min
8
12
  @line_writer = LineWriter.new(options)
9
13
  @factory_queue = []
10
14
  end
11
15
 
12
16
  def generate(data)
13
- output = LineWriter.wrap_definition do
14
- push_to_factory_queue(@factory_name, data, @nested_level)
15
- inner_output = []
17
+ push_to_factory_queue(@factory_name, data, @nested_level)
18
+ output = []
16
19
 
17
- loop do
18
- factory_option = @factory_queue.shift
19
- inner_output += build_factory(*factory_option)
20
- break if @factory_queue.empty?
21
- inner_output << LineWriter::WHITE_SPACE
22
- end
20
+ loop do
21
+ factory_option = @factory_queue.shift
22
+ output += build_factory(*factory_option)
23
+ break if @factory_queue.empty?
24
+ output << LineWriter::WHITE_SPACE
25
+ end
23
26
 
24
- inner_output
25
- end.join(LineWriter::NEW_LINE)
27
+ if @file_path
28
+ write_file(output)
29
+ else
30
+ output = LineWriter.wrap_definition { output }
31
+ end
26
32
 
27
- write_to_file(output)
28
33
  output
34
+ ensure
35
+ FactoryBot.reload if Object.const_defined?("FactoryBot")
36
+ puts(output) if FactoryBotFactory.config.print_output
29
37
  end
30
38
 
31
39
  private
32
40
 
33
- def write_to_file(output)
34
- path = @file_path
35
- factory_path = FactoryBotFactory.config.factory_path
36
- return unless path || factory_path
37
- path ||= factory_path + "/#{@factory_name}.rb"
41
+ def build_file_path(input_path = nil)
42
+ return input_path if input_path
43
+ return if FactoryBotFactory.config.factory_path.nil?
44
+ FactoryBotFactory.config.factory_path + "/#{@factory_name}.rb"
45
+ end
38
46
 
39
- raise FileExistsError, "File already exists in #{path}" if File.file?(path)
47
+ def write_file(output)
48
+ validate_existing_factory!
49
+ FileWriter.new(@file_path).write(output)
50
+ end
40
51
 
41
- File.open(path, 'w') {|f| f.write(output) }
52
+ def validate_existing_factory!
53
+ return unless Object.const_defined?("FactoryBot") && FactoryBot.factories.registered?(@factory_name.to_s)
54
+ raise FactoryExistsError, "[FactoryBotFactory] Factory #{@factory_name} already exists. Please check your existing factories."
42
55
  end
43
56
 
44
57
  def build_factory(name, value, level, options)
@@ -46,13 +59,13 @@ module FactoryBotFactory
46
59
  end
47
60
 
48
61
  def build_nested_attribute(name, key, value, current_level, max_level)
49
- return @line_writer.build(key, value) if current_level == max_level
62
+ return @line_writer.write(key, value) if current_level == max_level
50
63
 
51
64
  if is_key_value_pair?(value)
52
65
  push_to_factory_queue("#{name}_#{key}", value, max_level - 1)
53
- @line_writer.build_nested_line(name, key)
66
+ @line_writer.write_nested_line(name, key)
54
67
  else
55
- @line_writer.build(key, value)
68
+ @line_writer.write(key, value)
56
69
  end
57
70
  end
58
71
 
@@ -4,7 +4,7 @@ module FactoryBotFactory
4
4
  output = LineWriter.wrap_factory(name, value.class.name) do
5
5
  inner_output = []
6
6
  value.attributes.each do |key, value|
7
- inner_output += build_nested_attribute(value.class.name, key, value, 1, 1)
7
+ inner_output += build_nested_attribute(name, key, value, 1, 1)
8
8
  end
9
9
  inner_output
10
10
  end
@@ -0,0 +1,31 @@
1
+ require 'factory_bot_factory/logger'
2
+
3
+ module FactoryBotFactory
4
+ class FileWriter
5
+ attr_reader :file_paht, :output
6
+
7
+ def initialize(file_path)
8
+ @file_path = file_path
9
+ end
10
+
11
+ def write(output)
12
+ if File.file?(@file_path)
13
+ output = regroup_existing_lines(output)
14
+ message = "New Factory successfully write to an existing file."
15
+ else
16
+ output = LineWriter.wrap_definition { output }
17
+ message = "New Factory successfully write to a new file."
18
+ end
19
+
20
+ FactoryBot.reload if Object.const_defined?("FactoryBot")
21
+
22
+ File.open(@file_path, 'w') {|f| f.write(output) }
23
+ Logger.alert(message + "\nPlease check your file in #{@file_path}")
24
+ output
25
+ end
26
+
27
+ def regroup_existing_lines(output)
28
+ File.read(@file_path) + LineWriter::NEW_LINE + LineWriter.wrap_definition { output }
29
+ end
30
+ end
31
+ end
@@ -10,11 +10,11 @@ module FactoryBotFactory
10
10
  @options = options
11
11
  end
12
12
 
13
- def build(key, value)
13
+ def write(key, value)
14
14
  wrap_block(key, Attribute.new(key, value, @options).build)
15
15
  end
16
16
 
17
- def build_nested_line(prefix, key)
17
+ def write_nested_line(prefix, key)
18
18
  ["#{key} { build(:#{prefix}_#{key}) }"]
19
19
  end
20
20
 
@@ -35,11 +35,19 @@ module FactoryBotFactory
35
35
  "#{WHITE_SPACE * INDENT_SPACE * level}#{value}"
36
36
  end
37
37
 
38
+ def indent_lines(level, value)
39
+ value.map { |s| indent(level, s) }
40
+ end
41
+
42
+ def join(lines)
43
+ lines.join(LineWriter::NEW_LINE)
44
+ end
45
+
38
46
  def wrap_definition(&_block)
39
47
  output = ["FactoryBot.define do"]
40
48
  output += yield.map { |s| indent(1, s) }
41
49
  output << "end"
42
- output
50
+ output.join(LineWriter::NEW_LINE)
43
51
  end
44
52
 
45
53
  def wrap_factory(name, target, &_block)
@@ -0,0 +1,41 @@
1
+ module FactoryBotFactory
2
+ class Logger
3
+ PREFIX = "[FactoryBotFactory Logger]".freeze
4
+
5
+ def self.alert(message)
6
+ message = message.split("\n").map { |m| "#{PREFIX} #{m}" }.join("\n")
7
+ puts ColorString.new(message).yellow
8
+ end
9
+ end
10
+ end
11
+
12
+ class ColorString < String
13
+ # colorization
14
+ def colorize(color_code)
15
+ "\e[#{color_code}m#{self}\e[0m"
16
+ end
17
+
18
+ def red
19
+ colorize(31)
20
+ end
21
+
22
+ def green
23
+ colorize(32)
24
+ end
25
+
26
+ def yellow
27
+ colorize(33)
28
+ end
29
+
30
+ def blue
31
+ colorize(34)
32
+ end
33
+
34
+ def pink
35
+ colorize(35)
36
+ end
37
+
38
+ def light_blue
39
+ colorize(36)
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module FactoryBotFactory
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -7,6 +7,7 @@ require "factory_bot_factory/config"
7
7
 
8
8
  require 'factory_bot_factory/base.rb'
9
9
  require 'factory_bot_factory/line_writer.rb'
10
+ require 'factory_bot_factory/file_writer.rb'
10
11
  Dir.glob("#{File.dirname(__FILE__)}/factory_bot_factory/factories/*").each { |file| require(file) }
11
12
 
12
13
 
@@ -14,11 +15,13 @@ module FactoryBotFactory
14
15
  class Error < StandardError; end
15
16
  class NestedToDeepError < Error; end
16
17
  class FileExistsError < ::FactoryBotFactory::Error; end
18
+ class FactoryExistsError < ::FactoryBotFactory::Error; end
17
19
 
18
20
  class << self
19
- def build(*args)
21
+ def build(data, options = {})
20
22
  configure
21
- Base.build(*args)
23
+
24
+ Base.build(data, options)
22
25
  end
23
26
 
24
27
  def configure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factory_bot_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cdragon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-19 00:00:00.000000000 Z
11
+ date: 2021-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: factory_bot
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: faker
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +108,20 @@ dependencies:
122
108
  - - ">="
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: factory_bot
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 4.8.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 4.8.2
125
125
  description: A Gem that generate FactoryBot's Factory file from exsiting Hash, OpenStruct
126
126
  or Models.
127
127
  email: cdragon1116@gmail.com
@@ -155,7 +155,9 @@ files:
155
155
  - lib/factory_bot_factory/factories/hash_factory.rb
156
156
  - lib/factory_bot_factory/factories/model_factory.rb
157
157
  - lib/factory_bot_factory/factories/open_struct_factory.rb
158
+ - lib/factory_bot_factory/file_writer.rb
158
159
  - lib/factory_bot_factory/line_writer.rb
160
+ - lib/factory_bot_factory/logger.rb
159
161
  - lib/factory_bot_factory/version.rb
160
162
  homepage: https://github.com/cdragon1116/factory_bot_factory
161
163
  licenses:
@@ -169,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
171
  requirements:
170
172
  - - ">="
171
173
  - !ruby/object:Gem::Version
172
- version: '0'
174
+ version: 1.8.6
173
175
  required_rubygems_version: !ruby/object:Gem::Requirement
174
176
  requirements:
175
177
  - - ">="