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 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
  - - ">="