File: enum_traits_spec.rb

package info (click to toggle)
ruby-factory-bot 6.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,372 kB
  • sloc: ruby: 7,827; makefile: 6
file content (163 lines) | stat: -rw-r--r-- 4,220 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
describe "enum traits" do
  def define_model_with_enum(class_name, field, values)
    define_model(class_name, status: :integer) do
      if ActiveRecord::VERSION::STRING >= "7.0"
        enum field, values
      else
        enum field => values
      end
    end
  end

  context "when automatically_define_enum_traits is true" do
    it "builds traits automatically for model enum field" do
      define_model_with_enum("Task", :status, {queued: 0, started: 1, finished: 2})

      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_with_enum("Task", :status, {queued: 0, started: 1, finished: 2})

      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
      statuses = {queued: 0, started: 1, finished: 2}

      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
      statuses = define_class("Statuses") {
        include Enumerable

        def each(&block)
          ["queued", "started", "finished"].each(&block)
        end
      }.new

      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_with_enum("Task", :status, {queued: 0, started: 1, finished: 2})

        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_with_enum("Task", :status, {queued: 0, started: 1, finished: 2})

        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