factory_bot_factory 1.0.0 → 1.1.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: 683013489cb5caa6aedb9dd6f5aeea5e961e79fb78647f11b984629b8e5edea5
4
- data.tar.gz: c31acd1032b0b136f6f29263a7910b2a943f85df96411aaa7c66a4f5d36b64e0
3
+ metadata.gz: 3759620bd063f6090d72c455055888f658fcd1348304983ca5c595a053d3302c
4
+ data.tar.gz: aa08b76ac4326ac1157a0f1c4e8cb87a5136e4a5f6a4bbc3811bed378f051443
5
5
  SHA512:
6
- metadata.gz: c20d1624c1dcf7b845718361526938901236061891691c9978161763f4aad965867caaee1ee29ff52434df6918a9ac6c9f38eb0e17353ce2d927d85c51344bc8
7
- data.tar.gz: a6eff9d1210bd3e288a46309208b69faeae0c7c2c55b313afaff43d1423368dc8f31cef02df02657391f7d3b7bcfb5083a849d015de0fae7fea6cf91d4e46f47
6
+ metadata.gz: 1d38b330bad4022cb2cdca6acaeed2ff38791e38d99fb5c168c0927b764a86791fae4f6c9ce8a033efbe0b12f4f51fe55e4f99bb1dbfc86478b4e31f4b2147be
7
+ data.tar.gz: a4d7f9f6c9d2ec67810648aee8eaafd283a0cc324169e1b72fcf30bf04a6e5212b0b3bf2dad9f8d4a0bf6bb7b9ae45f91746caf23b913f06f6be0c355c5e97bd
data/Gemfile.lock CHANGED
@@ -1,11 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- factory_bot_factory (1.0.0)
4
+ factory_bot_factory (1.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activemodel (6.1.4.1)
10
+ activesupport (= 6.1.4.1)
11
+ activerecord (6.1.4.1)
12
+ activemodel (= 6.1.4.1)
13
+ activesupport (= 6.1.4.1)
9
14
  activesupport (6.1.4.1)
10
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
11
16
  i18n (>= 1.6, < 2)
@@ -40,6 +45,7 @@ GEM
40
45
  diff-lcs (>= 1.2.0, < 2.0)
41
46
  rspec-support (~> 3.10.0)
42
47
  rspec-support (3.10.2)
48
+ sqlite3 (1.4.2)
43
49
  tzinfo (2.0.4)
44
50
  concurrent-ruby (~> 1.0)
45
51
  zeitwerk (2.4.2)
@@ -48,6 +54,7 @@ PLATFORMS
48
54
  ruby
49
55
 
50
56
  DEPENDENCIES
57
+ activerecord (> 5.0.0.1)
51
58
  bundler (>= 2.2.10)
52
59
  factory_bot
53
60
  factory_bot_factory!
@@ -55,6 +62,7 @@ DEPENDENCIES
55
62
  pry (~> 0.13.1)
56
63
  rake (>= 11.2.2)
57
64
  rspec (~> 3.0)
65
+ sqlite3
58
66
 
59
67
  BUNDLED WITH
60
68
  2.2.27
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A Gem that helps you generate FactoryBot's Factory file from exsiting Hash, OpenStruct or ActiveModels.
6
6
 
7
- The main purpose is to speed up the process of building big factory.
7
+ ![factory_bot_factory_speed_demo](https://user-images.githubusercontent.com/39395058/133921801-e6c2b61d-71f1-4b99-b096-a0304fdbce87.gif)
8
8
 
9
9
  ## Installation
10
10
 
@@ -14,53 +14,32 @@ gem 'factory_bot_factory'
14
14
 
15
15
  And then execute:
16
16
 
17
- $ bundle
17
+ ```
18
+ $ bundle
19
+ ```
18
20
 
19
21
  Or install it yourself as:
20
22
 
21
- $ gem install factory_bot_factory
22
-
23
-
24
- ## Qucik Usage
25
-
26
- ```ruby
27
- FactoryBotFactory.build({ id: 1 })
28
- FactoryBotFactory.build(OpenStruct.new(id: 1))
29
- FactoryBotFactory.build(User.last)
23
+ ```
24
+ $ gem install factory_bot_factory
30
25
  ```
31
26
 
32
27
 
33
- ## More Options
34
-
35
- - Build a Hash Factory
28
+ ## Quick Demo
36
29
 
37
30
  ```ruby
38
31
  require 'factory_bot_factory'
39
32
 
40
- data = { id: 1, tags: ["tag1", "tag2"], address: { country: "US" } }
41
- puts FactoryBotFactory.build(data)
42
-
43
- # output
44
- FactoryBot.define do
45
- factory :hash, class: Hash do
46
- id { 1 }
47
- tags do
48
- [
49
- "tag1",
50
- "tag2"
51
- ]
52
- end
53
- address do
54
- {
55
- "country": "US"
56
- }
57
- end
58
- initialize_with { attributes }
59
- end
60
- end
33
+ puts FactoryBotFactory.build({ id: 1 })
34
+ puts FactoryBotFactory.build(OpenStruct.new(id: 1))
35
+ puts FactoryBotFactory.build(User.last)
36
+ puts FactoryBotFactory.build(User.new)
61
37
  ```
62
38
 
63
- - Nested Hash Factory
39
+
40
+ ## More Options
41
+
42
+ - `nested_level` - Build Nested Hash Factory (only support Hash and OpenStruct)
64
43
 
65
44
  ```ruby
66
45
  data = { id: 1, tags: ["tag1", "tag2"], address: { country: "US" } }
@@ -87,17 +66,17 @@ FactoryBot.define do
87
66
  end
88
67
  ```
89
68
 
90
- - Export the file somewhere
69
+ - `file_path` - Export output as file somewhere
91
70
 
92
71
  ```ruby
93
- FactoryBotFactory.build(data, file_path: "spec/factories/order_hash.rb")
72
+ FactoryBotFactory.build(data, file_path: "spec/factories/hash.rb")
94
73
 
95
74
  require 'factory_bot'
96
75
  FactoryBot.reload
97
- FactoryBot.build(:order_hash, id: 2)
76
+ FactoryBot.build(:hash, id: 2)
98
77
  ```
99
78
 
100
- - Specifize Factory Name
79
+ - `factory_name` - Specifize Factory Name
101
80
 
102
81
  ```ruby
103
82
  puts FactoryBotFactory.build({ id: 1 }, factory_name: 'order')
@@ -111,27 +90,41 @@ FactoryBot.define do
111
90
  end
112
91
  ```
113
92
 
114
- - Specifize Output Data Structure: Hash, OpenStruct and your ActiveModel or ActiveRecord Model
93
+ - `klass` - Specifize Output Data Structure: Hash, OpenStruct and your ActiveModel or ActiveRecord Model
94
+
95
+ You can convert your Hash object to OpenStruct factory.
115
96
 
116
97
  ```ruby
117
- puts FactoryBotFactory.build({ id: 1 }, klass: OpenStruct)
98
+ puts FactoryBotFactory.build({ id: 1 }, factory_name: 'order', klass: OpenStruct)
118
99
 
119
100
  # output
120
101
  FactoryBot.define do
121
- factory :hash, class: OpenStruct do
102
+ factory :order, class: OpenStruct do
122
103
  id { 1 }
123
104
  to_create {}
124
105
  end
125
106
  end
126
107
  ```
127
108
 
128
- ## Configure your own converter
109
+ ## Configuration
110
+
111
+ - Default factory path
112
+
113
+ By configuring `factory_path`, it allows file auto-generation without specifying `file_path`.
114
+
115
+ ```ruby
116
+ FactoryBotFactory.configure do |config|
117
+ config.factory_path = 'spec/factories'
118
+ end
119
+ ```
120
+
121
+ - Customize your own converter:
129
122
 
130
- - Configuration
123
+ Converter should respond to `call` method and return single or array of executable values.
131
124
 
132
125
  ```ruby
133
126
  FactoryBotFactory.configure do |config|
134
- config.string_converter = Proc.new do |k, v|
127
+ config.string_converter = Proc.new { |k, v|
135
128
  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}$/)
136
129
  'Random.uuid()'
137
130
  elsif k.to_s.include?('name')
@@ -139,25 +132,25 @@ FactoryBotFactory.configure do |config|
139
132
  else
140
133
  "'#{v}'"
141
134
  end
142
- end
135
+ }
136
+
137
+ config.numeric_converter = Proc.new { |k, v| 'rand(99)' }
143
138
  end
144
- ```
145
139
 
146
- - Output
147
- ```ruby
148
- FactoryBotFactory.build({ name: 'My Name', id: "de9515ee-006e-4a28-8af3-e88a5c771b93" })
140
+ FactoryBotFactory.build({ name: 'My Name', id: "de9515ee-006e-4a28-8af3-e88a5c771b93", age: 10 })
149
141
 
150
142
  # output
151
143
  FactoryBot.define do
152
144
  factory :hash, class: Hash do
153
145
  name { Faker::Name.name }
154
146
  id { Random.uuid() }
147
+ age { rand(99) }
155
148
  initialize_with { attributes }
156
149
  end
157
150
  end
158
151
  ```
159
152
 
160
- See more converters [Here](https://github.com/cdragon1116/factory_bot_factory/blob/master/lib/factory_bot_factory/config.rb#L3-L9)
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)
161
154
 
162
155
  ## Contributing
163
156
 
@@ -30,4 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "rspec", "~> 3.0"
31
31
  spec.add_development_dependency "factory_bot"
32
32
  spec.add_development_dependency "faker"
33
+ spec.add_development_dependency "activerecord", "> 5.0.0.1"
34
+ spec.add_development_dependency "sqlite3"
33
35
  end
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  module FactoryBotFactory
2
4
  class Attribute
3
5
  attr_reader :key, :value, :options
@@ -13,12 +15,20 @@ module FactoryBotFactory
13
15
 
14
16
  values = if value.nil? || value == "null"
15
17
  FactoryBotFactory.config.nil_converter.call(*options)
18
+ elsif value.is_a?(DateTime) || value.is_a?(Time)
19
+ FactoryBotFactory.config.date_time_converter.call(*options)
20
+ elsif value.is_a?(Date)
21
+ FactoryBotFactory.config.date_converter.call(*options)
16
22
  elsif value.is_a?(String) || value.is_a?(Symbol)
17
23
  FactoryBotFactory.config.string_converter.call(*options)
18
24
  elsif value.is_a?(Numeric)
19
- FactoryBotFactory.config.numertic_converter.call(*options)
20
- elsif value.is_a?(Hash) || value.is_a?(Array)
25
+ FactoryBotFactory.config.numeric_converter.call(*options)
26
+ elsif value.is_a?(BigDecimal)
27
+ FactoryBotFactory.config.big_decimal_converter.call(*options)
28
+ elsif value.is_a?(Hash)
21
29
  FactoryBotFactory.config.hash_converter.call(*options)
30
+ elsif value.is_a?(Array)
31
+ FactoryBotFactory.config.array_converter.call(*options)
22
32
  else value.is_a?(OpenStruct)
23
33
  FactoryBotFactory.config.open_struct_converter.call(*options)
24
34
  end
@@ -24,17 +24,23 @@ module FactoryBotFactory
24
24
  end
25
25
  end
26
26
 
27
- def valid_data?(data)
28
- data.is_a?(Hash) || data.is_a?(OpenStruct) || data.respond_to?(:attributes)
29
- end
30
-
31
27
  def factory(klass, data)
32
- if data.respond_to?(:attributes) && klass == data.class
28
+ if active_record?(data) && klass == data.class
29
+ Object.const_get("FactoryBotFactory::ActiveRecordFactory")
30
+ elsif data.respond_to?(:attributes) && klass == data.class
33
31
  Object.const_get("FactoryBotFactory::ModelFactory")
34
32
  else
35
33
  Object.const_get("FactoryBotFactory::#{klass}Factory")
36
34
  end
37
35
  end
36
+
37
+ def valid_data?(data)
38
+ data.is_a?(Hash) || data.is_a?(OpenStruct) || data.respond_to?(:attributes)
39
+ end
40
+
41
+ def active_record?(data)
42
+ Object.const_defined?("ActiveRecord::Base") && data.class.is_a?(ActiveRecord::Base)
43
+ end
38
44
  end
39
45
  end
40
46
  end
@@ -3,15 +3,24 @@ module FactoryBotFactory
3
3
  DEFAULT_CONVERTERS = {
4
4
  hash_converter: Converters::HashConverter,
5
5
  string_converter: Converters::StringConverter,
6
- numertic_converter: Converters::NumericConverter,
6
+ numeric_converter: Converters::NumericConverter,
7
+ big_decimal_converter: Converters::NumericConverter,
7
8
  open_struct_converter: Converters::HashConverter,
8
- nil_converter: Converters::NilConverter
9
+ nil_converter: Converters::NilConverter,
10
+ date_time_converter: Converters::DateTimeConverter,
11
+ date_converter: Converters::StringConverter,
12
+ array_converter: Converters::HashConverter
9
13
  }
10
14
 
11
- attr_accessor :hash_converter, :string_converter, :numertic_converter, :open_struct_converter, :nil_converter
15
+ DEFAULT_OPTIONS = {
16
+ factory_path: nil
17
+ }.merge(DEFAULT_CONVERTERS)
18
+
19
+ attr_accessor *DEFAULT_OPTIONS.keys
12
20
 
13
21
  def initialize(options = {})
14
- options = DEFAULT_CONVERTERS.merge(options)
22
+ options = DEFAULT_OPTIONS.merge(options)
23
+ options[:factory_path] = options[:factory_path][0..-2] if options[:factory_path]&.end_with?("/")
15
24
  options.each { |k, v| instance_variable_set(:"@#{k}", v) }
16
25
  end
17
26
  end
@@ -0,0 +1,9 @@
1
+ module FactoryBotFactory
2
+ module Converters
3
+ class DateTimeConverter
4
+ def self.call(key, value, options = {})
5
+ "\"#{value}\""
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'factory_bot_factory/factories/model_factory'
2
+
3
+ module FactoryBotFactory
4
+ class ActiveRecordFactory < ModelFactory
5
+ def build_factory(name, value, level, _options = {})
6
+ super
7
+ end
8
+ end
9
+ end
@@ -11,7 +11,7 @@ module FactoryBotFactory
11
11
 
12
12
  def generate(data)
13
13
  output = LineWriter.wrap_definition do
14
- @factory_queue << [@factory_name, data, @nested_level]
14
+ push_to_factory_queue(@factory_name, data, @nested_level)
15
15
  inner_output = []
16
16
 
17
17
  loop do
@@ -22,21 +22,26 @@ module FactoryBotFactory
22
22
  end
23
23
 
24
24
  inner_output
25
- end
25
+ end.join(LineWriter::NEW_LINE)
26
26
 
27
- output = output.join(LineWriter::NEW_LINE)
28
- write_to_file(output) if @file_path
27
+ write_to_file(output)
29
28
  output
30
29
  end
31
30
 
32
31
  private
33
32
 
34
33
  def write_to_file(output)
35
- raise FileExistsError, "File already exists in #{@file_path}" if File.file?(@file_path)
36
- File.open(@file_path, 'w') {|f| f.write(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"
38
+
39
+ raise FileExistsError, "File already exists in #{path}" if File.file?(path)
40
+
41
+ File.open(path, 'w') {|f| f.write(output) }
37
42
  end
38
43
 
39
- def build_factory(name, value, level)
44
+ def build_factory(name, value, level, options)
40
45
  raise "This method should be implemented in a subclass"
41
46
  end
42
47
 
@@ -44,15 +49,15 @@ module FactoryBotFactory
44
49
  return @line_writer.build(key, value) if current_level == max_level
45
50
 
46
51
  if is_key_value_pair?(value)
47
- push_to_factory_queue(name, key, value, max_level)
52
+ push_to_factory_queue("#{name}_#{key}", value, max_level - 1)
48
53
  @line_writer.build_nested_line(name, key)
49
54
  else
50
55
  @line_writer.build(key, value)
51
56
  end
52
57
  end
53
58
 
54
- def push_to_factory_queue(name, key, value, max_level)
55
- @factory_queue.push(["#{name}_#{key}", value, max_level - 1])
59
+ def push_to_factory_queue(name, value, max_level, options = {})
60
+ @factory_queue.push([name, value, max_level, options])
56
61
  end
57
62
 
58
63
  def is_key_value_pair?(value)
@@ -2,7 +2,7 @@ require 'factory_bot_factory/factories/base_factory.rb'
2
2
 
3
3
  module FactoryBotFactory
4
4
  class HashFactory < BaseFactory
5
- def build_factory(name, value, level)
5
+ def build_factory(name, value, level, _options = {})
6
6
  output = LineWriter.wrap_factory(name, 'Hash') do
7
7
  inner_output = []
8
8
  value = value.attributes if value.respond_to?(:attributes)
@@ -1,6 +1,6 @@
1
1
  module FactoryBotFactory
2
2
  class ModelFactory < BaseFactory
3
- def build_factory(name, value, level)
3
+ def build_factory(name, value, level, _options = {})
4
4
  output = LineWriter.wrap_factory(name, value.class.name) do
5
5
  inner_output = []
6
6
  value.attributes.each do |key, value|
@@ -2,7 +2,7 @@ require 'factory_bot_factory/factories/base_factory.rb'
2
2
 
3
3
  module FactoryBotFactory
4
4
  class OpenStructFactory < BaseFactory
5
- def build_factory(name, value, level)
5
+ def build_factory(name, value, level, _options = {})
6
6
  output = LineWriter.wrap_factory(name, 'OpenStruct') do
7
7
  inner_output = []
8
8
  value = value.attributes if value.respond_to?(:attributes)
@@ -1,3 +1,3 @@
1
1
  module FactoryBotFactory
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factory_bot_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cdragon
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: 5.0.0.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: 5.0.0.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: sqlite3
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description: A Gem that generate FactoryBot's Factory file from exsiting Hash, OpenStruct
98
126
  or Models.
99
127
  email: cdragon1116@gmail.com
@@ -117,10 +145,12 @@ files:
117
145
  - lib/factory_bot_factory/attribute.rb
118
146
  - lib/factory_bot_factory/base.rb
119
147
  - lib/factory_bot_factory/config.rb
148
+ - lib/factory_bot_factory/converters/data_time_converter.rb
120
149
  - lib/factory_bot_factory/converters/hash_converter.rb
121
150
  - lib/factory_bot_factory/converters/nil_converter.rb
122
151
  - lib/factory_bot_factory/converters/numeric_converter.rb
123
152
  - lib/factory_bot_factory/converters/string_converter.rb
153
+ - lib/factory_bot_factory/factories/active_record_factory.rb
124
154
  - lib/factory_bot_factory/factories/base_factory.rb
125
155
  - lib/factory_bot_factory/factories/hash_factory.rb
126
156
  - lib/factory_bot_factory/factories/model_factory.rb