Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
describe "enum traits" do
|
|
|
|
context "when automatically_define_enum_traits is true" do
|
|
|
|
it "builds traits automatically for model enum field" do
|
|
|
|
define_model("Task", status: :integer) do
|
2020-06-05 15:15:18 -04:00
|
|
|
enum status: {queued: 0, started: 1, finished: 2}
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.statuses.each_key do |trait_name|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq(trait_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.reset_column_information
|
|
|
|
end
|
|
|
|
|
|
|
|
it "prefers user defined traits over automatically built traits" do
|
|
|
|
define_model("Task", status: :integer) do
|
2020-06-05 15:15:18 -04:00
|
|
|
enum status: {queued: 0, started: 1, finished: 2}
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task do
|
|
|
|
trait :queued do
|
|
|
|
status { :finished }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :started do
|
|
|
|
status { :finished }
|
|
|
|
end
|
|
|
|
|
|
|
|
trait :finished do
|
|
|
|
status { :finished }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.statuses.each_key do |trait_name|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq("finished")
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.reset_column_information
|
|
|
|
end
|
|
|
|
|
|
|
|
it "builds traits for each enumerated value using a provided list of values as a Hash" do
|
2020-06-05 15:15:18 -04:00
|
|
|
statuses = {queued: 0, started: 1, finished: 2}
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
|
|
|
|
define_class "Task" do
|
|
|
|
attr_accessor :status
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task do
|
|
|
|
traits_for_enum :status, statuses
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
statuses.each do |trait_name, trait_value|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq(trait_value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "builds traits for each enumerated value using a provided list of values as an Array" do
|
|
|
|
statuses = %w[queued started finished]
|
|
|
|
|
|
|
|
define_class "Task" do
|
|
|
|
attr_accessor :status
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task do
|
|
|
|
traits_for_enum :status, statuses
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
statuses.each do |trait_name|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq(trait_name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "builds traits for each enumerated value using a custom enumerable" do
|
2020-06-05 15:15:18 -04:00
|
|
|
statuses = define_class("Statuses") {
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
include Enumerable
|
|
|
|
|
|
|
|
def each(&block)
|
|
|
|
["queued", "started", "finished"].each(&block)
|
|
|
|
end
|
2020-06-05 15:15:18 -04:00
|
|
|
}.new
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
|
|
|
|
define_class "Task" do
|
|
|
|
attr_accessor :status
|
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task do
|
|
|
|
traits_for_enum :status, statuses
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
statuses.each do |trait_name|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq(trait_name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when automatically_define_enum_traits is false" do
|
|
|
|
it "raises an error for undefined traits" do
|
|
|
|
with_temporary_assignment(FactoryBot, :automatically_define_enum_traits, false) do
|
|
|
|
define_model("Task", status: :integer) do
|
2020-06-05 15:15:18 -04:00
|
|
|
enum status: {queued: 0, started: 1, finished: 2}
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.statuses.each_key do |trait_name|
|
|
|
|
expect { FactoryBot.build(:task, trait_name) }.to raise_error(
|
|
|
|
KeyError, "Trait not registered: \"#{trait_name}\""
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.reset_column_information
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "builds traits for each enumerated value when traits_for_enum are specified" do
|
|
|
|
with_temporary_assignment(FactoryBot, :automatically_define_enum_traits, false) do
|
|
|
|
define_model("Task", status: :integer) do
|
2020-06-05 15:15:18 -04:00
|
|
|
enum status: {queued: 0, started: 1, finished: 2}
|
Add functionality for enum traits (#1380)
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
FactoryBot.define do
|
|
|
|
factory :task do
|
|
|
|
traits_for_enum(:status)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.statuses.each_key do |trait_name|
|
|
|
|
task = FactoryBot.build(:task, trait_name)
|
|
|
|
|
|
|
|
expect(task.status).to eq(trait_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
Task.reset_column_information
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|