factory_bot_factory 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +6 -7
- data/factory_bot_factory.gemspec +3 -1
- data/lib/factory_bot_factory/base.rb +5 -16
- data/lib/factory_bot_factory/config.rb +7 -2
- data/lib/factory_bot_factory/factories/base_factory.rb +36 -23
- data/lib/factory_bot_factory/factories/model_factory.rb +1 -1
- data/lib/factory_bot_factory/file_writer.rb +31 -0
- data/lib/factory_bot_factory/line_writer.rb +11 -3
- data/lib/factory_bot_factory/logger.rb +41 -0
- data/lib/factory_bot_factory/version.rb +1 -1
- data/lib/factory_bot_factory.rb +5 -2
- metadata +19 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87990d0dd64bc2e27d69c168a55f6057336b57796d44f5e6f6a807bd4182b26d
|
4
|
+
data.tar.gz: 037046cca064e07df3b08e7dbb9216856282e93b8f57bf76fae80e2f915e9980
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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` -
|
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` -
|
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.
|
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/
|
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
|
|
data/factory_bot_factory.gemspec
CHANGED
@@ -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(
|
5
|
-
|
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
|
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(
|
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
|
-
|
14
|
-
|
15
|
-
inner_output = []
|
17
|
+
push_to_factory_queue(@factory_name, data, @nested_level)
|
18
|
+
output = []
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
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
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
47
|
+
def write_file(output)
|
48
|
+
validate_existing_factory!
|
49
|
+
FileWriter.new(@file_path).write(output)
|
50
|
+
end
|
40
51
|
|
41
|
-
|
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.
|
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.
|
66
|
+
@line_writer.write_nested_line(name, key)
|
54
67
|
else
|
55
|
-
@line_writer.
|
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(
|
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
|
13
|
+
def write(key, value)
|
14
14
|
wrap_block(key, Attribute.new(key, value, @options).build)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
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
|
data/lib/factory_bot_factory.rb
CHANGED
@@ -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(
|
21
|
+
def build(data, options = {})
|
20
22
|
configure
|
21
|
-
|
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.
|
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-
|
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:
|
174
|
+
version: 1.8.6
|
173
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
176
|
requirements:
|
175
177
|
- - ">="
|