factory_bot_factory 1.0.0 → 1.1.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: 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