affairs_of_state 0.6.0 → 0.7.2

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: 2757335e832c9809fa86e7c365dda4d6fe31b49ab837665ecbd80ec2f3b27ac2
4
- data.tar.gz: 18c9e1b16df324170b4af93859379540e56aafa27068490a743bd155b3a9c83a
3
+ metadata.gz: 37d765f3c10fc68d7888ecde5f4b71736e70a85ccb77311f110f22772a5bfad3
4
+ data.tar.gz: 0b7a6965aad1f602356640b5d2c666bfcc60566e90fc54fd9c11cbd2394d92ea
5
5
  SHA512:
6
- metadata.gz: 6e9b37707ae931a4a9231b4b453b075db2d0c1e16c4bddf1696f20adcf26bd5b23744e6f185602d50e036465d1cf060dd2b4951857d252d387a5c140b4a18029
7
- data.tar.gz: 03c8db3940a2c167922048afecfa75d1ad4f28fcb386e16fc57bbbe6101c2f8416fece5ba12bba7af21407746149ec0252d46a7ce407b618b7db9af1f535ad7b
6
+ metadata.gz: 41dc25892417048d6de1ba7e6927ea335e7ce46819e834943358f5bf03b1397dad3e6aa846ea725a5eec162f5c7bc63e2b6ef8c1812e751683eeec255f868031
7
+ data.tar.gz: f28c08bebd42bf3c3a8b0a49308cc6f01161d5ad6840774ad4fb00f391e5d02e2d4730f6090acea7d274ade88b3eaf5e60eb651218da0563f1e4d21ac688a4f3
@@ -10,6 +10,7 @@ jobs:
10
10
  gemfile:
11
11
  - "activerecord-6.0.gemfile"
12
12
  - "activerecord-6.1.gemfile"
13
+ - "activerecord-7.0.gemfile"
13
14
  - "activerecord-latest.gemfile"
14
15
  runs-on: ubuntu-latest
15
16
  env:
data/.ruby_version ADDED
@@ -0,0 +1 @@
1
+ 3.0.2
data/README.md CHANGED
@@ -38,6 +38,12 @@ If you'd like to use another column, lets say `state`, pass it in as a configura
38
38
  affairs_of_state :active, :inactive, column: :state
39
39
  ```
40
40
 
41
+ You can scope the helper and scope methods by a prefix:
42
+
43
+ ```ruby
44
+ affairs_of_state :active, :inactive, prefix: :admin
45
+ ```
46
+
41
47
  You can also turn off validation:
42
48
 
43
49
  ```ruby
@@ -60,7 +66,7 @@ or
60
66
  affairs_of_state :active, :inactive, if: :only_validate_if_this_method_returns_true
61
67
  ```
62
68
 
63
- Currently it is limited only be called once per model.
69
+ It can be called multiple times per model, provided as each time is with a different column, and that none of the statuses overlap. If either of these are not true it will raise on load.
64
70
 
65
71
 
66
72
  ## Methods
@@ -72,23 +78,35 @@ widget = Widget.first
72
78
  widget.cancelled! if widget.active?
73
79
  ```
74
80
 
75
- You can also access all your statuses on the model like so:
81
+ These methods are scoped by the prefix if one is set:
82
+ ```ruby
83
+ widget = Widget.first
84
+ widget.admin_cancelled! if widget.admin_active?
85
+ ```
86
+
87
+ You can also access all your statuses on the model. If only one is defined it is default, otherwise the column name needs to be passed in:
76
88
 
77
89
  ```ruby
78
- Widget::STATUSES # -> ["active", "cancelled"]
90
+ Widget.statuses # -> ["active", "cancelled"]
91
+ Widget.statuses(:status) # -> ["active", "cancelled"]
79
92
  ```
80
93
 
81
- It also provides scopes automagically:
94
+ It also provides scopes automagically, scoped by prefix if one is set:
82
95
 
83
96
  ```ruby
84
97
  Widget.active
85
98
  Widget.cancelled
86
99
  ```
100
+ ```ruby
101
+ Widget.admin_active
102
+ Widget.admin_cancelled
103
+ ```
87
104
 
88
- For select inputs in forms there is a convenience method that returns all states in the format expected by `options_for_select`
105
+ For select inputs in forms there is a convenience method that returns all states in the format expected by `options_for_select`. Again if only one is defined on the model it returns as default, if multiple are defined the column name needs to be passed in:
89
106
 
90
107
  ```ruby
91
108
  <%= f.select :status, options_for_select(Widget.statuses_for_select) %>
109
+ <%= f.select :status, options_for_select(Widget.statuses_for_select(:status)) %>
92
110
  ```
93
111
 
94
112
 
@@ -19,9 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency "activerecord", ">= 6.0"
20
20
  gem.add_dependency "activesupport", ">= 6.0"
21
21
 
22
- gem.add_development_dependency "rspec"
23
- gem.add_development_dependency "sqlite3", "~> 1.4.0"
24
- gem.add_development_dependency "pry"
25
- gem.add_development_dependency "rake"
26
-
22
+ gem.add_development_dependency "rspec", ">= 3.0"
23
+ gem.add_development_dependency "sqlite3", ">= 1.4.0"
24
+ gem.add_development_dependency "rake", ">= 12"
27
25
  end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'activerecord', '~> 7.0'
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+ module AffairsOfState
3
+ module ActiveRecordExtension
4
+ extend ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ def affairs_of_state(*statuses, column: :status, allow_blank: false, scopes: true, if: nil, prefix: nil)
8
+ # config object that defines behaviour
9
+ config = AffairsOfState::Config.new(
10
+ statuses: statuses,
11
+ prefix: prefix,
12
+ column: column,
13
+ allow_blank: !!allow_blank,
14
+ scopes: scopes,
15
+ if: binding.local_variable_get(:if)
16
+ )
17
+
18
+ # check for conflicts with existing calls
19
+ raise ArgumentError, "Affairs of State: #{ self } has already been called on `#{ config.column }`" if affairs_of_state_configs[config.column]
20
+ statuses_and_methods = affairs_of_state_configs.values.map(&:methods_for_statuses).map { |m| m.map{ |(k, v)| [k, v] } }.flatten
21
+ overlapping_statuses = statuses_and_methods & config.methods_for_statuses.map{ |k, v| [k, v] }.flatten
22
+ raise ArgumentError, "Affairs of State: #{ self } already has a status #{ overlapping_statuses }" if overlapping_statuses.any?
23
+
24
+ # status methods
25
+ config.methods_for_statuses.each do |status, method_name|
26
+ define_method("#{ method_name }?") do
27
+ self.send(config.column) == status
28
+ end
29
+
30
+ define_method("#{ method_name }!") do
31
+ self.send("#{ config.column }=", status)
32
+ self.save
33
+ end
34
+ end
35
+
36
+ # scopes
37
+ if config.scopes
38
+ config.methods_for_statuses.each do |status, method_name|
39
+ self.scope(method_name.to_sym, -> { where(config.column => status) })
40
+ end
41
+ end
42
+
43
+ # column validation
44
+ validates(config.column, inclusion: { in: config.statuses, allow_blank: config.allow_blank }, if: config.if)
45
+
46
+ # cache the config on the object
47
+ affairs_of_state_configs[config.column] = config
48
+
49
+ include InstanceMethods
50
+ extend SingletonMethods
51
+
52
+ true
53
+ end
54
+
55
+ def affairs_of_state_configs
56
+ @affairs_of_state_configs ||= {}
57
+ end
58
+ end
59
+
60
+ module InstanceMethods
61
+ end
62
+
63
+ module SingletonMethods
64
+ def statuses_for_select(column=nil)
65
+ statuses(column).map{ |s| [s.humanize, s] }
66
+ end
67
+
68
+ def statuses(column=nil)
69
+ if !column && affairs_of_state_configs.length == 1
70
+ affairs_of_state_configs.values.first.statuses
71
+ elsif !column && affairs_of_state_configs.length > 1
72
+ raise ArgumentError, "column is required"
73
+ elsif column
74
+ affairs_of_state_configs[column.to_sym]&.statuses
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,16 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  module AffairsOfState
2
3
  class Config
3
- attr_accessor :column, :allow_blank, :scopes, :if
4
- attr_reader :statuses
4
+ attr_reader :statuses, :column, :allow_blank, :scopes, :if, :methods_for_statuses
5
5
 
6
- def statuses=(val)
7
- @statuses = val.flatten.map(&:to_s)
6
+ DISALLOWED_STATUSES = [ "new" ].freeze
8
7
 
8
+ def initialize(statuses:, column:, allow_blank:, scopes:, if:, prefix:)
9
+ @column = column
10
+ @allow_blank = !!allow_blank
11
+ @scopes = !!scopes
12
+ @if = binding.local_variable_get(:if)
13
+ @prefix = prefix.presence
14
+ @statuses = statuses.flatten.map(&:to_s)
15
+ @methods_for_statuses = @statuses.to_h do |s|
16
+ if @prefix
17
+ [s.to_s, "#{ prefix }_#{ s }"]
18
+ else
19
+ [s.to_s, s.to_s]
20
+ end
21
+ end
9
22
  @statuses.each do |status|
10
- raise ArgumentError.new("Affairs of State: '#{ status }' is not a valid status") if ["new"].include?(status)
23
+ raise ArgumentError.new("Affairs of State: '#{ status }' is not a valid status") if DISALLOWED_STATUSES.include?(status)
11
24
  end
12
-
13
- @statuses
14
25
  end
15
26
  end
16
27
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module AffairsOfState
2
- VERSION = "0.6.0"
3
+ VERSION = "0.7.2"
3
4
  end
@@ -1,65 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  require "active_support"
2
3
  require "active_support/concern"
3
4
  require "active_record"
4
5
 
5
6
  require "affairs_of_state/version"
6
7
  require "affairs_of_state/config"
7
-
8
- module AffairsOfState
9
- extend ActiveSupport::Concern
10
-
11
- class_methods do
12
- def affairs_of_state(*statuses, column: :status, allow_blank: false, scopes: true, if: nil)
13
- raise ArgumentError.new("Affairs of State: cannot be invoked multiple times on the same model") if @affairs_of_state_config
14
-
15
- affairs_of_state_config.statuses = statuses
16
- affairs_of_state_config.column = column
17
- affairs_of_state_config.allow_blank = allow_blank
18
- affairs_of_state_config.scopes = scopes
19
- affairs_of_state_config.if = binding.local_variable_get(:if)
20
-
21
- const_set(:STATUSES, affairs_of_state_config.statuses)
22
-
23
- affairs_of_state_config.statuses.each do |status|
24
- define_method("#{ status }?") do
25
- self.send(self.class.affairs_of_state_config.column) == status
26
- end
27
-
28
- define_method("#{ status }!") do
29
- self.send("#{ self.class.affairs_of_state_config.column }=", status)
30
- self.save
31
- end
32
- end
33
-
34
- validates(affairs_of_state_config.column, inclusion: { in: affairs_of_state_config.statuses, allow_blank: affairs_of_state_config.allow_blank }, if: affairs_of_state_config.if)
35
-
36
- if affairs_of_state_config.scopes
37
- affairs_of_state_config.statuses.each do |status|
38
- self.scope(status.to_sym, -> { where(affairs_of_state_config.column => status) })
39
- end
40
- end
41
-
42
- include InstanceMethods
43
- extend SingletonMethods
44
-
45
- true
46
- end
47
-
48
- def affairs_of_state_config
49
- @affairs_of_state_config ||= AffairsOfState::Config.new
50
- end
51
- end
52
-
53
- module InstanceMethods
54
- end
55
-
56
- module SingletonMethods
57
- def statuses_for_select
58
- affairs_of_state_config.statuses.map{ |s| [s.humanize, s] }
59
- end
60
- end
61
- end
8
+ require "affairs_of_state/active_record_extension"
62
9
 
63
10
  ActiveSupport.on_load(:active_record) do
64
- ::ActiveRecord::Base.send :include, AffairsOfState
11
+ ::ActiveRecord::Base.send :include, AffairsOfState::ActiveRecordExtension
65
12
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe AffairsOfState do
@@ -6,57 +7,63 @@ describe AffairsOfState do
6
7
  affairs_of_state :active, :inactive, :cancelled
7
8
  end
8
9
 
9
- it "should set the constant" do
10
- expect(Pie::STATUSES).to eq(["active", "inactive", "cancelled"])
11
- end
10
+ subject { Pie }
12
11
 
13
12
  it "should validate the column is set" do
14
- expect(Pie.new(status: nil)).to_not be_valid
13
+ expect(subject.new(status: nil)).to_not be_valid
15
14
  end
16
15
 
17
16
  it "should validate that we're not setting it to something stupid" do
18
- expect(Pie.new(status: "delicious_pie")).to_not be_valid
17
+ expect(subject.new(status: "delicious_pie")).to_not be_valid
19
18
  end
20
19
 
21
20
  describe "boolean methods" do
22
21
  it "should find the set status" do
23
- p = Pie.new status: "active"
22
+ p = subject.new status: "active"
24
23
  expect(p.active?).to be_truthy
25
24
  end
26
25
 
27
26
  it "should not find if a different status is set" do
28
- p = Pie.new status: "inactive"
27
+ p = subject.new status: "inactive"
29
28
  expect(p.cancelled?).to be_falsy
30
29
  end
31
30
  end
32
31
 
33
32
  describe "update methods" do
34
33
  it "should set the value" do
35
- p = Pie.create! status: "active"
34
+ p = subject.create! status: "active"
36
35
  expect(p.inactive!).to be_truthy
37
36
  expect(p.status).to eq("inactive")
38
37
  end
39
38
  end
40
39
 
40
+ it "should have the statuses method with the nil default" do
41
+ expect(subject.statuses).to eq(["active", "inactive", "cancelled"])
42
+ end
43
+
44
+ it "should have the statuses method" do
45
+ expect(subject.statuses(:status)).to eq(["active", "inactive", "cancelled"])
46
+ end
47
+
41
48
  it "should provide a method to pass to dropdowns" do
42
- expect(Pie.statuses_for_select).to eq([["Active", "active"], ["Inactive", "inactive"], ["Cancelled", "cancelled"]])
49
+ expect(subject.statuses_for_select).to eq([["Active", "active"], ["Inactive", "inactive"], ["Cancelled", "cancelled"]])
43
50
  end
44
51
 
45
52
  describe "scopes" do
46
53
  it "should have a finder to match the status name" do
47
- Pie.create! status: "active"
48
- Pie.create! status: "inactive"
49
- Pie.create! status: "active"
50
- Pie.create! status: "cancelled"
51
-
52
- expect(Pie.active.size).to eq(2)
53
- expect(Pie.inactive.size).to eq(1)
54
- expect(Pie.cancelled.size).to eq(1)
54
+ subject.create! status: "active"
55
+ subject.create! status: "inactive"
56
+ subject.create! status: "active"
57
+ subject.create! status: "cancelled"
58
+
59
+ expect(subject.active.size).to eq(2)
60
+ expect(subject.inactive.size).to eq(1)
61
+ expect(subject.cancelled.size).to eq(1)
55
62
  end
56
63
  end
57
64
 
58
65
  after(:each) do
59
- Pie.destroy_all
66
+ subject.destroy_all
60
67
  end
61
68
  end
62
69
 
@@ -67,16 +74,18 @@ describe AffairsOfState do
67
74
  affairs_of_state :active, :inactive, column: :super_status
68
75
  end
69
76
 
77
+ subject { Pie2 }
78
+
70
79
  it "should validate the column is set" do
71
- expect(Pie2.new(status: nil, super_status: "active")).to be_valid
80
+ expect(subject.new(status: nil, super_status: "active")).to be_valid
72
81
  end
73
82
 
74
83
  it "should know the accessors" do
75
- expect(Pie2.new(status: nil, super_status: "inactive").inactive?).to be(true)
84
+ expect(subject.new(status: nil, super_status: "inactive").inactive?).to be(true)
76
85
  end
77
86
 
78
87
  it "should know the setters" do
79
- instance = Pie2.create!(status: nil, super_status: "inactive")
88
+ instance = subject.create!(status: nil, super_status: "inactive")
80
89
  expect(instance.active!).to be(true)
81
90
  expect(instance.super_status).to eq("active")
82
91
  end
@@ -89,8 +98,10 @@ describe AffairsOfState do
89
98
  affairs_of_state :active, :inactive, allow_blank: true
90
99
  end
91
100
 
101
+ subject { Pie3 }
102
+
92
103
  it "should validate the column is set" do
93
- expect(Pie3.new(status: nil)).to be_valid
104
+ expect(subject.new(status: nil)).to be_valid
94
105
  end
95
106
  end
96
107
 
@@ -101,8 +112,10 @@ describe AffairsOfState do
101
112
  affairs_of_state [:on, :off]
102
113
  end
103
114
 
115
+ subject { Pie4 }
116
+
104
117
  it "should work too if that's what floats your boat" do
105
- expect(Pie4::STATUSES).to eq(["on", "off"])
118
+ expect(subject.statuses).to eq(["on", "off"])
106
119
  end
107
120
  end
108
121
 
@@ -113,8 +126,10 @@ describe AffairsOfState do
113
126
  affairs_of_state :active, :inactive, scopes: false
114
127
  end
115
128
 
116
- it "should work too if that's what floats your boat" do
117
- expect(Pie5).to_not respond_to(:active)
129
+ subject { Pie5 }
130
+
131
+ it "should not respond if the scopes are not needed" do
132
+ expect(subject).to_not respond_to(:active)
118
133
  end
119
134
  end
120
135
 
@@ -127,15 +142,17 @@ describe AffairsOfState do
127
142
  attr_accessor :is_going_to_validate
128
143
  end
129
144
 
145
+ subject { Pie6 }
146
+
130
147
  it "should enforce the validation if the :if param is true" do
131
- p = Pie6.new
148
+ p = subject.new
132
149
  p.is_going_to_validate = true
133
150
  p.status = "pie"
134
151
  expect(p).to_not be_valid
135
152
  end
136
153
 
137
154
  it "should not enforce the validation if the :if param evaluates to false" do
138
- p = Pie6.new
155
+ p = subject.new
139
156
  p.is_going_to_validate = false
140
157
  p.status = "pie"
141
158
  expect(p).to be_valid
@@ -155,15 +172,17 @@ describe AffairsOfState do
155
172
  end
156
173
  end
157
174
 
175
+ subject { Pie7 }
176
+
158
177
  it "should enforce the validation if the :if param is true" do
159
- p = Pie7.new
178
+ p = subject.new
160
179
  p.is_going_to_validate = true
161
180
  p.status = "pie"
162
181
  expect(p).to_not be_valid
163
182
  end
164
183
 
165
184
  it "should not enforce the validation if the :if param evaluates to false" do
166
- p = Pie7.new
185
+ p = subject.new
167
186
  p.is_going_to_validate = false
168
187
  p.status = "pie"
169
188
  expect(p).to be_valid
@@ -172,18 +191,113 @@ describe AffairsOfState do
172
191
 
173
192
  describe "invalid status name" do
174
193
  it "should raise a good warning" do
175
- expect(->{ class Pie8 < ActiveRecord::Base ; affairs_of_state :new ; end }).to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
194
+ expect{ class Pie8 < ActiveRecord::Base ; affairs_of_state :new ; end }.to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
176
195
  end
177
196
  end
178
197
 
179
198
  describe "multiple invocations" do
180
- it "raises an error" do
181
- expect(->{
182
- class Pie9 < ActiveRecord::Base
183
- affairs_of_state :not_important
184
- affairs_of_state :something
199
+ class Pie9 < ActiveRecord::Base
200
+ self.table_name = "pies"
201
+
202
+ affairs_of_state :active, :inactive
203
+ affairs_of_state :moderated, :unmoderated, column: :super_status
204
+ end
205
+
206
+ subject { Pie9 }
207
+
208
+ it "declares two status columns" do
209
+ p = subject.new
210
+ p.inactive!
211
+ p.unmoderated!
212
+ expect(p).to be_inactive
213
+ expect(p).to be_unmoderated
214
+ end
215
+
216
+ it "raises if called twice on the same column" do
217
+ expect {
218
+ class Pie10 < ActiveRecord::Base
219
+ self.table_name = "pies"
220
+
221
+ affairs_of_state :active, :inactive
222
+ affairs_of_state :moderated, :unmoderated
223
+ end
224
+ }.to raise_error(ArgumentError)
225
+ end
226
+
227
+ it "raises if called twice with the same status in both" do
228
+ expect {
229
+ class Pie11 < ActiveRecord::Base
230
+ self.table_name = "pies"
231
+
232
+ affairs_of_state :active, :inactive
233
+ affairs_of_state :dormant, :active, column: :super_status
185
234
  end
186
- }).to raise_error(ArgumentError, "Affairs of State: cannot be invoked multiple times on the same model")
235
+ }.to raise_error(ArgumentError)
236
+ end
237
+
238
+ it "raises if collision between prefixes" do
239
+ expect {
240
+ class Pie12 < ActiveRecord::Base
241
+ self.table_name = "pies"
242
+
243
+ affairs_of_state :admin_active, :admin_inactive
244
+ affairs_of_state :dormant, :active, column: :super_status, prefix: :admin
245
+ end
246
+ }.to raise_error(ArgumentError)
247
+ end
248
+
249
+ it "raises if statuses is called with no argument" do
250
+ expect {
251
+ subject.statuses
252
+ }.to raise_error(ArgumentError)
253
+ end
254
+
255
+ it "returns the statuses for the column" do
256
+ expect(subject.statuses(:status)).to eq(["active", "inactive"])
257
+ expect(subject.statuses("super_status")).to eq(["moderated", "unmoderated"])
258
+ end
259
+
260
+ it "raises if statuses_for_select is called with no argument" do
261
+ expect {
262
+ subject.statuses_for_select
263
+ }.to raise_error(ArgumentError)
264
+ end
265
+
266
+ it "returns the statuses_for_select for the column" do
267
+ expect(subject.statuses_for_select(:status)).to eq([["Active", "active"], ["Inactive", "inactive"]])
268
+ expect(subject.statuses_for_select("super_status")).to eq([["Moderated", "moderated"], ["Unmoderated", "unmoderated"]])
269
+ end
270
+ end
271
+
272
+ describe "multiple invocations with prefix" do
273
+ class Pie13 < ActiveRecord::Base
274
+ self.table_name = "pies"
275
+
276
+ affairs_of_state :active, :inactive
277
+ affairs_of_state :moderated, :unmoderated, column: :super_status
278
+ affairs_of_state :positive, :mixed, :negative, column: :sentiment, prefix: :sentiment
279
+ end
280
+
281
+ subject { Pie13 }
282
+
283
+ it "returns the statuses" do
284
+ expect(subject.statuses(:sentiment)).to eq([ "positive", "mixed", "negative" ])
285
+ end
286
+
287
+ it "adds the setter and getter methods with the prefix" do
288
+ p = subject.new
289
+ expect(p).to_not be_sentiment_positive
290
+ expect(p).to_not be_sentiment_mixed
291
+ expect(p).to_not be_sentiment_negative
292
+ p.sentiment_mixed!
293
+ expect(p).to be_sentiment_mixed
294
+ end
295
+
296
+ it "adds the scopes with the prefix" do
297
+ p = subject.create! sentiment: "positive", status: "active", super_status: "unmoderated"
298
+ subject.create! sentiment: "mixed", status: "active", super_status: "unmoderated"
299
+ subject.create! sentiment: "negative", status: "active", super_status: "unmoderated"
300
+ expect(subject.sentiment_positive).to eq([p])
187
301
  end
188
302
  end
189
303
  end
data/spec/config_spec.rb CHANGED
@@ -1,47 +1,69 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe AffairsOfState::Config do
4
- subject{ AffairsOfState::Config.new }
5
+ let(:config) do
6
+ AffairsOfState::Config.new(
7
+ statuses: statuses,
8
+ column: column,
9
+ allow_blank: allow_blank,
10
+ scopes: scopes,
11
+ if: if_condition,
12
+ prefix: prefix
13
+ )
14
+ end
15
+ let(:column) { "state" }
16
+ let(:statuses) { [ :created, [ :destroyed ] ] }
17
+ let(:allow_blank) { "sure" }
18
+ let(:scopes) { nil }
19
+ let(:if_condition) { "false" }
20
+ let(:prefix) { nil }
5
21
 
6
- describe "accessors" do
7
- let(:expected){ double }
22
+ subject { config }
8
23
 
24
+ describe "accessors" do
9
25
  it "has :column" do
10
- subject.column = expected
11
- expect(subject.column).to eq(expected)
26
+ expect(subject.column).to eq(column)
12
27
  end
13
28
 
14
29
  it "has :allow_blank" do
15
- subject.allow_blank = expected
16
- expect(subject.allow_blank).to eq(expected)
30
+ expect(subject.allow_blank).to be(true)
17
31
  end
18
32
 
19
33
  it "has :scopes" do
20
- subject.scopes = expected
21
- expect(subject.scopes).to eq(expected)
34
+ expect(subject.scopes).to be(false)
22
35
  end
23
36
 
24
37
  it "has :if" do
25
- subject.if = expected
26
- expect(subject.if).to eq(expected)
38
+ expect(subject.if).to eq(if_condition)
27
39
  end
28
- end
29
40
 
30
- describe "#statuses=" do
31
- it "converts to string" do
32
- subject.statuses = [:a, :b]
33
- expect(subject.statuses).to eq(["a", "b"])
41
+ it "has :statuses and converts to strings and flattens" do
42
+ expect(subject.statuses).to eq(["created", "destroyed"])
34
43
  end
35
44
 
36
- it "flattens" do
37
- subject.statuses = ["a", [:b]]
38
- expect(subject.statuses).to eq(["a", "b"])
45
+ it "has :methods_for_statuses which is the same key values" do
46
+ expect(subject.methods_for_statuses).to eq({ "created" => "created", "destroyed" => "destroyed" })
39
47
  end
48
+ end
49
+
50
+ context "with invalid status" do
51
+ let(:statuses) { [ "new" ] }
40
52
 
41
53
  it "makes sure no invalid statuses are allowed" do
42
- expect(->{
43
- subject.statuses = [:new]
44
- }).to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
54
+ expect { subject }.to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
55
+ end
56
+ end
57
+
58
+ context "with prefix" do
59
+ let(:prefix) { :admin }
60
+
61
+ it "has :statuses just the same" do
62
+ expect(subject.statuses).to eq(["created", "destroyed"])
63
+ end
64
+
65
+ it "has :methods_for_statuses" do
66
+ expect(subject.methods_for_statuses).to eq({ "created" => "admin_created", "destroyed" => "admin_destroyed" })
45
67
  end
46
68
  end
47
69
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
1
2
  require "affairs_of_state"
2
3
 
3
- require "pry"
4
4
  require "sqlite3"
5
5
 
6
6
  RSpec.configure do |config|
7
7
  config.run_all_when_everything_filtered = true
8
+ config.filter_run_when_matching :focus
9
+ # config.raise_errors_for_deprecations!
8
10
  end
9
11
 
10
- ## Create an AR model to test with
12
+ # Create an AR model to test with
11
13
  I18n.enforce_available_locales = false
12
14
 
13
15
  ActiveRecord::Base.establish_connection(
@@ -19,4 +21,5 @@ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'pies'")
19
21
  ActiveRecord::Base.connection.create_table(:pies) do |t|
20
22
  t.string :status
21
23
  t.string :super_status
24
+ t.string :sentiment
22
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: affairs_of_state
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin McPhillips
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-12 00:00:00.000000000 Z
11
+ date: 2022-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -44,56 +44,42 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sqlite3
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.4.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.4.0
69
- - !ruby/object:Gem::Dependency
70
- name: pry
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - ">="
74
60
  - !ruby/object:Gem::Version
75
- version: '0'
61
+ version: 1.4.0
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
66
  - - ">="
81
67
  - !ruby/object:Gem::Version
82
- version: '0'
68
+ version: 1.4.0
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rake
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: '0'
75
+ version: '12'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: '0'
82
+ version: '12'
97
83
  description: Add a simple state to a gem, without all the hassle of a complex state
98
84
  machine.
99
85
  email:
@@ -105,6 +91,7 @@ files:
105
91
  - ".github/workflows/ci.yml"
106
92
  - ".gitignore"
107
93
  - ".rspec"
94
+ - ".ruby_version"
108
95
  - Gemfile
109
96
  - LICENSE
110
97
  - README.md
@@ -112,8 +99,10 @@ files:
112
99
  - affairs_of_state.gemspec
113
100
  - gemfiles/activerecord-6.0.gemfile
114
101
  - gemfiles/activerecord-6.1.gemfile
102
+ - gemfiles/activerecord-7.0.gemfile
115
103
  - gemfiles/activerecord-latest.gemfile
116
104
  - lib/affairs_of_state.rb
105
+ - lib/affairs_of_state/active_record_extension.rb
117
106
  - lib/affairs_of_state/config.rb
118
107
  - lib/affairs_of_state/version.rb
119
108
  - spec/affairs_of_state_spec.rb