affairs_of_state 0.2.0 → 0.7.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 +5 -5
- data/.github/workflows/ci.yml +25 -0
- data/README.md +8 -4
- data/affairs_of_state.gemspec +6 -5
- data/gemfiles/{activerecord50.gemfile → activerecord-6.0.gemfile} +1 -1
- data/gemfiles/{activerecord40.gemfile → activerecord-6.1.gemfile} +1 -1
- data/gemfiles/{activerecord41.gemfile → activerecord-latest.gemfile} +1 -1
- data/lib/affairs_of_state/active_record_extension.rb +77 -0
- data/lib/affairs_of_state/config.rb +19 -0
- data/lib/affairs_of_state/version.rb +2 -1
- data/lib/affairs_of_state.rb +9 -62
- data/spec/affairs_of_state_spec.rb +118 -28
- data/spec/config_spec.rb +51 -0
- data/spec/spec_helper.rb +7 -5
- metadata +48 -36
- data/.travis.yml +0 -21
- data/gemfiles/activerecord42.gemfile +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 73f6fed4bcc0422024de20521810e21f4d9a77411382af6d6b8f52c79f941ca7
|
4
|
+
data.tar.gz: b128a4dcea99c0c3e192792ffea7a6a6b670f58994c26bd2c8d808360fd620bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fe6d2bf961248735b23fa41afaa2ebe8712a9ea55896537c6dd66efcabe1426491635e8fa3be707bbb068756a7fc3f726893cb6cefc36a61b36f6785a1c3f45
|
7
|
+
data.tar.gz: b5df8b2a439fead18dc1e79340141137b307ecb1024d7e82884f17312f9231f3e26d680e5bd31309da2447e183ee27b8a7d5ae1470e89929172c5422dd806eeb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [ push, pull_request ]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
gemfile:
|
11
|
+
- "activerecord-6.0.gemfile"
|
12
|
+
- "activerecord-6.1.gemfile"
|
13
|
+
- "activerecord-latest.gemfile"
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
env:
|
16
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: 3.0.2
|
22
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
23
|
+
- name: Run tests
|
24
|
+
run: |
|
25
|
+
bundle exec rspec --format doc
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Affairs of State
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
|
5
5
|
You have an Active Record model. It nees to have multiple states, boolean convenience methods, simple validation, but not complex rules. This gem gives you this in a single line class method.
|
6
6
|
|
@@ -60,6 +60,8 @@ or
|
|
60
60
|
affairs_of_state :active, :inactive, if: :only_validate_if_this_method_returns_true
|
61
61
|
```
|
62
62
|
|
63
|
+
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
|
+
|
63
65
|
|
64
66
|
## Methods
|
65
67
|
|
@@ -70,10 +72,11 @@ widget = Widget.first
|
|
70
72
|
widget.cancelled! if widget.active?
|
71
73
|
```
|
72
74
|
|
73
|
-
You can also access all your statuses on the model
|
75
|
+
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:
|
74
76
|
|
75
77
|
```ruby
|
76
|
-
Widget
|
78
|
+
Widget.statuses # -> ["active", "cancelled"]
|
79
|
+
Widget.statuses(:status) # -> ["active", "cancelled"]
|
77
80
|
```
|
78
81
|
|
79
82
|
It also provides scopes automagically:
|
@@ -83,10 +86,11 @@ Widget.active
|
|
83
86
|
Widget.cancelled
|
84
87
|
```
|
85
88
|
|
86
|
-
For select inputs in forms there is a convenience method that returns all states in the format expected by `options_for_select
|
89
|
+
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:
|
87
90
|
|
88
91
|
```ruby
|
89
92
|
<%= f.select :status, options_for_select(Widget.statuses_for_select) %>
|
93
|
+
<%= f.select :status, options_for_select(Widget.statuses_for_select(:status)) %>
|
90
94
|
```
|
91
95
|
|
92
96
|
|
data/affairs_of_state.gemspec
CHANGED
@@ -16,11 +16,12 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = AffairsOfState::VERSION
|
18
18
|
|
19
|
-
gem.add_dependency "activerecord", "
|
20
|
-
gem.add_dependency "activesupport", "
|
19
|
+
gem.add_dependency "activerecord", "~> 6.0"
|
20
|
+
gem.add_dependency "activesupport", "~> 6.0"
|
21
21
|
|
22
|
-
gem.add_development_dependency "rspec"
|
23
|
-
gem.add_development_dependency "sqlite3"
|
24
|
-
gem.add_development_dependency "pry"
|
22
|
+
gem.add_development_dependency "rspec", "~> 3.0"
|
23
|
+
gem.add_development_dependency "sqlite3", "~> 1.4.0"
|
24
|
+
gem.add_development_dependency "pry", "~> 0.12.0"
|
25
|
+
gem.add_development_dependency "rake", "~> 12"
|
25
26
|
|
26
27
|
end
|
@@ -0,0 +1,77 @@
|
|
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)
|
8
|
+
# config object that defines behaviour
|
9
|
+
config = AffairsOfState::Config.new(
|
10
|
+
statuses: statuses,
|
11
|
+
column: column,
|
12
|
+
allow_blank: !!allow_blank,
|
13
|
+
scopes: scopes,
|
14
|
+
if: binding.local_variable_get(:if)
|
15
|
+
)
|
16
|
+
|
17
|
+
# check for conflicts with existing calls
|
18
|
+
raise ArgumentError, "Affairs of State: #{ self } has already been called on `#{ config.column }`" if affairs_of_state_configs[config.column]
|
19
|
+
overlapping_statuses = affairs_of_state_configs.values.map(&:statuses) & config.statuses
|
20
|
+
raise ArgumentError, "Affairs of State: #{ self } already has a status #{ overlapping_statuses }" if overlapping_statuses.any?
|
21
|
+
|
22
|
+
# status methods
|
23
|
+
config.statuses.each do |status|
|
24
|
+
define_method("#{ status }?") do
|
25
|
+
self.send(config.column) == status
|
26
|
+
end
|
27
|
+
|
28
|
+
define_method("#{ status }!") do
|
29
|
+
self.send("#{ config.column }=", status)
|
30
|
+
self.save
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# column validation
|
35
|
+
validates(config.column, inclusion: { in: config.statuses, allow_blank: config.allow_blank }, if: config.if)
|
36
|
+
|
37
|
+
# scopes
|
38
|
+
if config.scopes
|
39
|
+
config.statuses.each do |status|
|
40
|
+
self.scope(status.to_sym, -> { where(config.column => status) })
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# cache the config on the object
|
45
|
+
affairs_of_state_configs[config.column] = config
|
46
|
+
|
47
|
+
include InstanceMethods
|
48
|
+
extend SingletonMethods
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def affairs_of_state_configs
|
54
|
+
@affairs_of_state_configs ||= {}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module InstanceMethods
|
59
|
+
end
|
60
|
+
|
61
|
+
module SingletonMethods
|
62
|
+
def statuses_for_select(column=nil)
|
63
|
+
statuses(column).map{ |s| [s.humanize, s] }
|
64
|
+
end
|
65
|
+
|
66
|
+
def statuses(column=nil)
|
67
|
+
if !column && affairs_of_state_configs.length == 1
|
68
|
+
affairs_of_state_configs.values.first.statuses
|
69
|
+
elsif !column && affairs_of_state_configs.length > 1
|
70
|
+
raise ArgumentError, "column is required"
|
71
|
+
elsif column
|
72
|
+
affairs_of_state_configs[column.to_sym]&.statuses
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module AffairsOfState
|
3
|
+
class Config
|
4
|
+
attr_reader :statuses, :column, :allow_blank, :scopes, :if
|
5
|
+
|
6
|
+
DISALLOWED_STATUSES = [ "new" ].freeze
|
7
|
+
|
8
|
+
def initialize(statuses:, column:, allow_blank:, scopes:, if:)
|
9
|
+
@column = column
|
10
|
+
@allow_blank = !!allow_blank
|
11
|
+
@scopes = !!scopes
|
12
|
+
@if = binding.local_variable_get(:if)
|
13
|
+
@statuses = statuses.flatten.map(&:to_s)
|
14
|
+
@statuses.each do |status|
|
15
|
+
raise ArgumentError.new("Affairs of State: '#{ status }' is not a valid status") if DISALLOWED_STATUSES.include?(status)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/affairs_of_state.rb
CHANGED
@@ -1,65 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class_methods do
|
7
|
-
def affairs_of_state(*args)
|
8
|
-
@_status_options = { column: :status, allow_blank: false, scopes: true, if: nil }.merge(args.extract_options!)
|
9
|
-
@_statuses = args.flatten.map(&:to_s)
|
10
|
-
|
11
|
-
const_set("STATUSES", @_statuses)
|
12
|
-
|
13
|
-
validates(@_status_options[:column], inclusion: { in: @_statuses, allow_blank: @_status_options[:allow_blank] }, if: @_status_options[:if])
|
14
|
-
|
15
|
-
if @_status_options[:scopes]
|
16
|
-
@_statuses.each do |status|
|
17
|
-
raise ArgumentError.new("Affairs of State: '#{ status }' is not a valid status") unless valid_status?(status)
|
18
|
-
self.scope status.to_sym, -> { where(@_status_options[:column] => status.to_s) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
include InstanceMethods
|
23
|
-
extend SingletonMethods
|
24
|
-
|
25
|
-
true
|
26
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/concern"
|
4
|
+
require "active_record"
|
27
5
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
![:new].include?(status.to_sym)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
module InstanceMethods
|
36
|
-
def method_missing(method, *args)
|
37
|
-
if self.class::STATUSES.map{ |s| "#{ s }?".to_sym }.include?(method)
|
38
|
-
self.class.send(:define_method, method) do
|
39
|
-
self.status == method.to_s.gsub(/\?$/, "")
|
40
|
-
end
|
41
|
-
|
42
|
-
send(method)
|
43
|
-
|
44
|
-
elsif self.class::STATUSES.map{ |s| "#{ s }!".to_sym }.include?(method)
|
45
|
-
self.class.send(:define_method, method) do
|
46
|
-
self.send("#{ self.class.instance_variable_get('@_status_options')[:column] }=", method.to_s.gsub(/\!$/, ""))
|
47
|
-
self.save
|
48
|
-
end
|
49
|
-
|
50
|
-
send(method)
|
51
|
-
else
|
52
|
-
super
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
module SingletonMethods
|
58
|
-
def statuses_for_select
|
59
|
-
@_statuses.map{ |s| [s.humanize, s] }
|
60
|
-
end
|
61
|
-
end
|
6
|
+
require "affairs_of_state/version"
|
7
|
+
require "affairs_of_state/config"
|
8
|
+
require "affairs_of_state/active_record_extension"
|
62
9
|
|
10
|
+
ActiveSupport.on_load(:active_record) do
|
11
|
+
::ActiveRecord::Base.send :include, AffairsOfState::ActiveRecordExtension
|
63
12
|
end
|
64
|
-
|
65
|
-
ActiveRecord::Base.send :include, AffairsOfState
|
@@ -1,63 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe AffairsOfState do
|
4
|
-
|
5
5
|
describe "with a simple configuration" do
|
6
6
|
class Pie < ActiveRecord::Base
|
7
7
|
affairs_of_state :active, :inactive, :cancelled
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
expect(Pie::STATUSES).to eq(["active", "inactive", "cancelled"])
|
12
|
-
end
|
10
|
+
subject { Pie }
|
13
11
|
|
14
12
|
it "should validate the column is set" do
|
15
|
-
expect(
|
13
|
+
expect(subject.new(status: nil)).to_not be_valid
|
16
14
|
end
|
17
15
|
|
18
16
|
it "should validate that we're not setting it to something stupid" do
|
19
|
-
expect(
|
17
|
+
expect(subject.new(status: "delicious_pie")).to_not be_valid
|
20
18
|
end
|
21
19
|
|
22
20
|
describe "boolean methods" do
|
23
21
|
it "should find the set status" do
|
24
|
-
p =
|
22
|
+
p = subject.new status: "active"
|
25
23
|
expect(p.active?).to be_truthy
|
26
24
|
end
|
27
25
|
|
28
26
|
it "should not find if a different status is set" do
|
29
|
-
p =
|
27
|
+
p = subject.new status: "inactive"
|
30
28
|
expect(p.cancelled?).to be_falsy
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
32
|
describe "update methods" do
|
35
33
|
it "should set the value" do
|
36
|
-
p =
|
34
|
+
p = subject.create! status: "active"
|
37
35
|
expect(p.inactive!).to be_truthy
|
38
36
|
expect(p.status).to eq("inactive")
|
39
37
|
end
|
40
38
|
end
|
41
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
|
+
|
42
48
|
it "should provide a method to pass to dropdowns" do
|
43
|
-
expect(
|
49
|
+
expect(subject.statuses_for_select).to eq([["Active", "active"], ["Inactive", "inactive"], ["Cancelled", "cancelled"]])
|
44
50
|
end
|
45
51
|
|
46
52
|
describe "scopes" do
|
47
53
|
it "should have a finder to match the status name" do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
expect(
|
54
|
-
expect(
|
55
|
-
expect(
|
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)
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
59
65
|
after(:each) do
|
60
|
-
|
66
|
+
subject.destroy_all
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
@@ -68,8 +74,20 @@ describe AffairsOfState do
|
|
68
74
|
affairs_of_state :active, :inactive, column: :super_status
|
69
75
|
end
|
70
76
|
|
77
|
+
subject { Pie2 }
|
78
|
+
|
71
79
|
it "should validate the column is set" do
|
72
|
-
expect(
|
80
|
+
expect(subject.new(status: nil, super_status: "active")).to be_valid
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should know the accessors" do
|
84
|
+
expect(subject.new(status: nil, super_status: "inactive").inactive?).to be(true)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should know the setters" do
|
88
|
+
instance = subject.create!(status: nil, super_status: "inactive")
|
89
|
+
expect(instance.active!).to be(true)
|
90
|
+
expect(instance.super_status).to eq("active")
|
73
91
|
end
|
74
92
|
end
|
75
93
|
|
@@ -80,8 +98,10 @@ describe AffairsOfState do
|
|
80
98
|
affairs_of_state :active, :inactive, allow_blank: true
|
81
99
|
end
|
82
100
|
|
101
|
+
subject { Pie3 }
|
102
|
+
|
83
103
|
it "should validate the column is set" do
|
84
|
-
expect(
|
104
|
+
expect(subject.new(status: nil)).to be_valid
|
85
105
|
end
|
86
106
|
end
|
87
107
|
|
@@ -92,8 +112,10 @@ describe AffairsOfState do
|
|
92
112
|
affairs_of_state [:on, :off]
|
93
113
|
end
|
94
114
|
|
115
|
+
subject { Pie4 }
|
116
|
+
|
95
117
|
it "should work too if that's what floats your boat" do
|
96
|
-
expect(
|
118
|
+
expect(subject.statuses).to eq(["on", "off"])
|
97
119
|
end
|
98
120
|
end
|
99
121
|
|
@@ -104,8 +126,10 @@ describe AffairsOfState do
|
|
104
126
|
affairs_of_state :active, :inactive, scopes: false
|
105
127
|
end
|
106
128
|
|
107
|
-
|
108
|
-
|
129
|
+
subject { Pie5 }
|
130
|
+
|
131
|
+
it "should not respond if the scopes are not needed" do
|
132
|
+
expect(subject).to_not respond_to(:active)
|
109
133
|
end
|
110
134
|
end
|
111
135
|
|
@@ -118,15 +142,17 @@ describe AffairsOfState do
|
|
118
142
|
attr_accessor :is_going_to_validate
|
119
143
|
end
|
120
144
|
|
145
|
+
subject { Pie6 }
|
146
|
+
|
121
147
|
it "should enforce the validation if the :if param is true" do
|
122
|
-
p =
|
148
|
+
p = subject.new
|
123
149
|
p.is_going_to_validate = true
|
124
150
|
p.status = "pie"
|
125
151
|
expect(p).to_not be_valid
|
126
152
|
end
|
127
153
|
|
128
154
|
it "should not enforce the validation if the :if param evaluates to false" do
|
129
|
-
p =
|
155
|
+
p = subject.new
|
130
156
|
p.is_going_to_validate = false
|
131
157
|
p.status = "pie"
|
132
158
|
expect(p).to be_valid
|
@@ -146,15 +172,17 @@ describe AffairsOfState do
|
|
146
172
|
end
|
147
173
|
end
|
148
174
|
|
175
|
+
subject { Pie7 }
|
176
|
+
|
149
177
|
it "should enforce the validation if the :if param is true" do
|
150
|
-
p =
|
178
|
+
p = subject.new
|
151
179
|
p.is_going_to_validate = true
|
152
180
|
p.status = "pie"
|
153
181
|
expect(p).to_not be_valid
|
154
182
|
end
|
155
183
|
|
156
184
|
it "should not enforce the validation if the :if param evaluates to false" do
|
157
|
-
p =
|
185
|
+
p = subject.new
|
158
186
|
p.is_going_to_validate = false
|
159
187
|
p.status = "pie"
|
160
188
|
expect(p).to be_valid
|
@@ -167,4 +195,66 @@ describe AffairsOfState do
|
|
167
195
|
end
|
168
196
|
end
|
169
197
|
|
198
|
+
describe "multiple invocations" do
|
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 Pie < 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 Pie < ActiveRecord::Base
|
230
|
+
self.table_name = "pies"
|
231
|
+
|
232
|
+
affairs_of_state :active, :inactive
|
233
|
+
affairs_of_state :dormant, :active, column: :super_status
|
234
|
+
end
|
235
|
+
}.to raise_error(ArgumentError)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "raises if statuses is called with no argument" do
|
239
|
+
expect {
|
240
|
+
subject.statuses
|
241
|
+
}.to raise_error(ArgumentError)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "returns the statuses for the column" do
|
245
|
+
expect(subject.statuses(:status)).to eq(["active", "inactive"])
|
246
|
+
expect(subject.statuses("super_status")).to eq(["moderated", "unmoderated"])
|
247
|
+
end
|
248
|
+
|
249
|
+
it "raises if statuses_for_select is called with no argument" do
|
250
|
+
expect {
|
251
|
+
subject.statuses_for_select
|
252
|
+
}.to raise_error(ArgumentError)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "returns the statuses_for_select for the column" do
|
256
|
+
expect(subject.statuses_for_select(:status)).to eq([["Active", "active"], ["Inactive", "inactive"]])
|
257
|
+
expect(subject.statuses_for_select("super_status")).to eq([["Moderated", "moderated"], ["Unmoderated", "unmoderated"]])
|
258
|
+
end
|
259
|
+
end
|
170
260
|
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe AffairsOfState::Config do
|
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
|
+
)
|
13
|
+
end
|
14
|
+
let(:column) { "state" }
|
15
|
+
let(:statuses) { [ :created, [ :destroyed ] ] }
|
16
|
+
let(:allow_blank) { "sure" }
|
17
|
+
let(:scopes) { nil }
|
18
|
+
let(:if_condition) { "false" }
|
19
|
+
|
20
|
+
subject { config }
|
21
|
+
|
22
|
+
describe "accessors" do
|
23
|
+
it "has :column" do
|
24
|
+
expect(subject.column).to eq(column)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has :allow_blank" do
|
28
|
+
expect(subject.allow_blank).to be(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has :scopes" do
|
32
|
+
expect(subject.scopes).to be(false)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has :if" do
|
36
|
+
expect(subject.if).to eq(if_condition)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has :statuses and converts to strings and flattens" do
|
40
|
+
expect(subject.statuses).to eq(["created", "destroyed"])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with invalid status" do
|
45
|
+
let(:statuses) { [ "new" ] }
|
46
|
+
|
47
|
+
it "makes sure no invalid statuses are allowed" do
|
48
|
+
expect { subject }.to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "affairs_of_state"
|
3
|
+
|
4
|
+
require "pry"
|
5
|
+
require "sqlite3"
|
5
6
|
|
6
7
|
RSpec.configure do |config|
|
7
8
|
config.run_all_when_everything_filtered = true
|
9
|
+
config.filter_run_when_matching :focus
|
8
10
|
end
|
9
11
|
|
10
|
-
|
12
|
+
# Create an AR model to test with
|
11
13
|
I18n.enforce_available_locales = false
|
12
14
|
|
13
15
|
ActiveRecord::Base.establish_connection(
|
metadata
CHANGED
@@ -1,85 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: affairs_of_state
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '6.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '6.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '6.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
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
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.4.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.4.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.12.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.12.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '12'
|
83
97
|
description: Add a simple state to a gem, without all the hassle of a complex state
|
84
98
|
machine.
|
85
99
|
email:
|
@@ -88,28 +102,30 @@ executables: []
|
|
88
102
|
extensions: []
|
89
103
|
extra_rdoc_files: []
|
90
104
|
files:
|
105
|
+
- ".github/workflows/ci.yml"
|
91
106
|
- ".gitignore"
|
92
107
|
- ".rspec"
|
93
|
-
- ".travis.yml"
|
94
108
|
- Gemfile
|
95
109
|
- LICENSE
|
96
110
|
- README.md
|
97
111
|
- Rakefile
|
98
112
|
- affairs_of_state.gemspec
|
99
|
-
- gemfiles/
|
100
|
-
- gemfiles/
|
101
|
-
- gemfiles/
|
102
|
-
- gemfiles/activerecord50.gemfile
|
113
|
+
- gemfiles/activerecord-6.0.gemfile
|
114
|
+
- gemfiles/activerecord-6.1.gemfile
|
115
|
+
- gemfiles/activerecord-latest.gemfile
|
103
116
|
- lib/affairs_of_state.rb
|
117
|
+
- lib/affairs_of_state/active_record_extension.rb
|
118
|
+
- lib/affairs_of_state/config.rb
|
104
119
|
- lib/affairs_of_state/version.rb
|
105
120
|
- spec/affairs_of_state_spec.rb
|
121
|
+
- spec/config_spec.rb
|
106
122
|
- spec/db/.gitkeep
|
107
123
|
- spec/spec_helper.rb
|
108
124
|
homepage: http://github.com/kmcphillips/affairs_of_state
|
109
125
|
licenses:
|
110
126
|
- MIT
|
111
127
|
metadata: {}
|
112
|
-
post_install_message:
|
128
|
+
post_install_message:
|
113
129
|
rdoc_options: []
|
114
130
|
require_paths:
|
115
131
|
- lib
|
@@ -124,14 +140,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
140
|
- !ruby/object:Gem::Version
|
125
141
|
version: '0'
|
126
142
|
requirements: []
|
127
|
-
|
128
|
-
|
129
|
-
signing_key:
|
143
|
+
rubygems_version: 3.2.22
|
144
|
+
signing_key:
|
130
145
|
specification_version: 4
|
131
146
|
summary: You have an Active Record model. It nees to have multiple states, but not
|
132
147
|
complex rules. This gem gives you validation, easy check and change methods, and
|
133
148
|
a single configuration line.
|
134
|
-
test_files:
|
135
|
-
- spec/affairs_of_state_spec.rb
|
136
|
-
- spec/db/.gitkeep
|
137
|
-
- spec/spec_helper.rb
|
149
|
+
test_files: []
|
data/.travis.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
script: bundle exec rspec
|
3
|
-
sudo: false
|
4
|
-
rvm:
|
5
|
-
- "2.1.0"
|
6
|
-
- "2.2.2"
|
7
|
-
- "2.3.1"
|
8
|
-
|
9
|
-
gemfile:
|
10
|
-
- Gemfile
|
11
|
-
- gemfiles/activerecord40.gemfile
|
12
|
-
- gemfiles/activerecord41.gemfile
|
13
|
-
- gemfiles/activerecord42.gemfile
|
14
|
-
- gemfiles/activerecord50.gemfile
|
15
|
-
|
16
|
-
matrix:
|
17
|
-
exclude:
|
18
|
-
- rvm: "2.1.0"
|
19
|
-
gemfile: Gemfile
|
20
|
-
- rvm: "2.1.0"
|
21
|
-
gemfile: gemfiles/activerecord50.gemfile
|