act_with_flags 3.0.1 → 3.1.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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +16 -8
- data/README.md +54 -13
- data/lib/act_with_flags/flags.rb +4 -6
- data/lib/act_with_flags/utils.rb +9 -1
- data/lib/act_with_flags/version.rb +2 -1
- data/lib/act_with_flags.rb +22 -16
- data/test/range_test.rb +89 -0
- metadata +3 -3
- data/TODO +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e2b18cdaf7777bddb191c830bc942a6fd7c377a4267c8e7beae3b2ace3552e9
|
4
|
+
data.tar.gz: 1aed1f1e86fdbdd1cff793c0296c1b6e23c7400dc43f7df17ad8e13c3b1998d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11154bcaf21ff519f34863fdb847ffefd1e9a2fb493cfcdd8d0e015de42b601a9b3bf20d9e914d0e8681f39e321194ba3a27048a74fb43ce3972b9844cf0f14c
|
7
|
+
data.tar.gz: 4471f2dc9a7b48654fa9ea689e4f51e660f6eacb0012fc1ea75c43fd2cb9c91149c49243e24a78e4527407d4c75dd51e7b0066095efebb14f007eb3dda36a839
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
act_with_flags (3.0
|
4
|
+
act_with_flags (3.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -100,7 +100,7 @@ GEM
|
|
100
100
|
marcel (1.0.2)
|
101
101
|
method_source (1.0.0)
|
102
102
|
mini_mime (1.1.2)
|
103
|
-
minitest (5.16.
|
103
|
+
minitest (5.16.3)
|
104
104
|
net-imap (0.2.3)
|
105
105
|
digest
|
106
106
|
net-protocol
|
@@ -120,7 +120,7 @@ GEM
|
|
120
120
|
racc (~> 1.4)
|
121
121
|
observr (1.0.5)
|
122
122
|
parallel (1.22.1)
|
123
|
-
parser (3.1.2.
|
123
|
+
parser (3.1.2.1)
|
124
124
|
ast (~> 2.4.1)
|
125
125
|
racc (1.6.0)
|
126
126
|
rack (2.2.4)
|
@@ -157,18 +157,21 @@ GEM
|
|
157
157
|
regexp_parser (2.5.0)
|
158
158
|
rexml (3.2.5)
|
159
159
|
ricecream (0.2.1)
|
160
|
-
rubocop (1.
|
160
|
+
rubocop (1.35.0)
|
161
161
|
json (~> 2.3)
|
162
162
|
parallel (~> 1.10)
|
163
|
-
parser (>= 3.1.
|
163
|
+
parser (>= 3.1.2.1)
|
164
164
|
rainbow (>= 2.2.2, < 4.0)
|
165
165
|
regexp_parser (>= 1.8, < 3.0)
|
166
166
|
rexml (>= 3.2.5, < 4.0)
|
167
|
-
rubocop-ast (>= 1.
|
167
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
168
168
|
ruby-progressbar (~> 1.7)
|
169
169
|
unicode-display_width (>= 1.4.0, < 3.0)
|
170
|
-
rubocop-ast (1.
|
170
|
+
rubocop-ast (1.21.0)
|
171
171
|
parser (>= 3.1.1.0)
|
172
|
+
rubocop-performance (1.14.3)
|
173
|
+
rubocop (>= 1.7.0, < 2.0)
|
174
|
+
rubocop-ast (>= 0.4.0)
|
172
175
|
ruby-progressbar (1.11.0)
|
173
176
|
simplecov (0.21.2)
|
174
177
|
docile (~> 1.1)
|
@@ -177,6 +180,11 @@ GEM
|
|
177
180
|
simplecov-html (0.12.3)
|
178
181
|
simplecov_json_formatter (0.1.4)
|
179
182
|
sqlite3 (1.4.4)
|
183
|
+
standard (1.16.0)
|
184
|
+
rubocop (= 1.35.0)
|
185
|
+
rubocop-performance (= 1.14.3)
|
186
|
+
standardrb (1.0.1)
|
187
|
+
standard
|
180
188
|
strscan (3.0.4)
|
181
189
|
thor (1.2.1)
|
182
190
|
timeout (0.3.0)
|
@@ -202,9 +210,9 @@ DEPENDENCIES
|
|
202
210
|
rails
|
203
211
|
rake
|
204
212
|
ricecream
|
205
|
-
rubocop
|
206
213
|
simplecov
|
207
214
|
sqlite3
|
215
|
+
standardrb
|
208
216
|
|
209
217
|
BUNDLED WITH
|
210
218
|
2.3.14
|
data/README.md
CHANGED
@@ -1,40 +1,80 @@
|
|
1
1
|
# ActWithFlags
|
2
|
+
|
2
3
|
[](http://badge.fury.io/rb/act_with_flags)
|
3
4
|
|
4
|
-
|
5
|
+
A Rails gem required by key.matiq.
|
6
|
+
|
7
|
+
Handles booleans in "flags".
|
8
|
+
Defines setters and getters to access the booleans.
|
9
|
+
|
5
10
|
|
6
11
|
## Installation
|
7
12
|
|
8
|
-
|
13
|
+
As usual:
|
14
|
+
```ruby
|
15
|
+
# Gemfile
|
16
|
+
...
|
17
|
+
gem 'act_with_flags'
|
18
|
+
```
|
19
|
+
|
20
|
+
or manually:
|
21
|
+
```shell
|
22
|
+
$ gem install act_with_flags
|
23
|
+
```
|
9
24
|
|
10
|
-
gem 'act_with_flags'
|
11
25
|
|
12
|
-
|
26
|
+
## Version 3.1.x
|
27
|
+
|
28
|
+
Added option "range" limiting the position of booleans.
|
29
|
+
|
30
|
+
An example:
|
31
|
+
```ruby
|
32
|
+
ii = 3
|
33
|
+
Order.add_to_flags range: (2..4), a: (ii += 1) # accepted
|
34
|
+
Order.add_to_flags range: (2..4), b: (ii += 1) # raises exception
|
35
|
+
```
|
36
|
+
|
37
|
+
Option "range" enables an early static check.
|
13
38
|
|
14
|
-
|
39
|
+
Option "range" does not replace the dynamic "validate" in models,
|
40
|
+
which is strongly recommended for complex applications.
|
41
|
+
Due to Ruby "act_with_flags" can handle a huge quantity
|
42
|
+
of booleans in an integer (or a string),
|
43
|
+
but your database may fail above a certain amount of bits.
|
15
44
|
|
16
|
-
|
45
|
+
The option ":max_bits" is deprecated.
|
17
46
|
|
18
|
-
$ gem install act_with_flags
|
19
47
|
|
20
|
-
## Version 3.x
|
48
|
+
## Version 3.0.x
|
21
49
|
|
22
50
|
As required by key.matiq an enhanced "origin:" has been implemented.
|
23
51
|
Act_with_flags now supports many "origin:"s
|
24
52
|
(not just renaming the default "flags").
|
25
53
|
|
26
54
|
An example:
|
27
|
-
|
28
|
-
~~~
|
55
|
+
```ruby
|
29
56
|
Order.add_to_flags :a # origin is :flags
|
30
57
|
Order.add_to_flags :b, b2: 63 # origin is :flags
|
31
58
|
Order.add_to_flags :c, origin: :origin1
|
32
59
|
Order.add_to_flags d: 3, origin: :origin2
|
33
60
|
Order.add_to_flags :d2, origin: :origin2
|
34
|
-
|
61
|
+
```
|
35
62
|
|
36
63
|
The default "origin:" continues to be "flags".
|
37
64
|
|
65
|
+
|
66
|
+
## Testing
|
67
|
+
|
68
|
+
As "Best Practice" a test coverage of 100% has been achieved
|
69
|
+
(and should be kept).
|
70
|
+
|
71
|
+
GitHub workflow enable tests for several configurations.
|
72
|
+
Please, feel free to inspect the corresponding file.
|
73
|
+
|
74
|
+
The "gem appraisal" is used for an additional set of configurations.
|
75
|
+
Feel free to inspect the corresponding file.
|
76
|
+
|
77
|
+
|
38
78
|
## Links
|
39
79
|
|
40
80
|
Further reading:
|
@@ -45,9 +85,10 @@ Further reading:
|
|
45
85
|
- [gem has-bit-field](https://github.com/pjb3/has-bit-field)
|
46
86
|
- [gem bitfield_attribute](https://github.com/gzigzigzeo/bitfield_attribute)
|
47
87
|
|
88
|
+
|
48
89
|
## License MIT
|
49
90
|
|
50
|
-
Copyright (c) 2019-2022 [Dittmar Krall](matiq
|
51
|
-
is released under the MIT license:
|
91
|
+
Copyright (c) 2019-2022 [Dittmar Krall](matiq UG (haftungsbeschränkt))
|
92
|
+
and is released under the MIT license:
|
52
93
|
|
53
94
|
* https://opensource.org/licenses/MIT
|
data/lib/act_with_flags/flags.rb
CHANGED
@@ -42,7 +42,6 @@ class ActWithFlags::Admin
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def add_to_locations(flag, location)
|
45
|
-
location = check_position(location)
|
46
45
|
who = "<#{flag}: #{location.origin}@#{location.position}>"
|
47
46
|
raise "name already used #{who}" if @locations.key?(flag)
|
48
47
|
bool = @locations.has_value?(location)
|
@@ -50,18 +49,17 @@ class ActWithFlags::Admin
|
|
50
49
|
@locations[flag] = location
|
51
50
|
end
|
52
51
|
|
53
|
-
def
|
54
|
-
|
55
|
-
return location if pos
|
52
|
+
def check_pos(model, origin, pos)
|
53
|
+
return pos if pos
|
56
54
|
|
57
55
|
max_position = -1
|
58
56
|
@locations.each { |name, location|
|
59
57
|
model2, orig2, pos2 = location.values
|
60
|
-
next unless model == model2 &&
|
58
|
+
next unless model == model2 && origin == orig2
|
61
59
|
|
62
60
|
max_position = pos2 if pos2 > max_position
|
63
61
|
}
|
64
62
|
|
65
|
-
|
63
|
+
max_position + 1
|
66
64
|
end
|
67
65
|
end
|
data/lib/act_with_flags/utils.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ActWithFlags::Admin
|
4
|
-
def add_flag(name, origin,
|
4
|
+
def add_flag(name, pos, origin, range)
|
5
5
|
accessor = name.to_sym
|
6
6
|
validate_accessor accessor, "#{accessor}?", "#{accessor}="
|
7
7
|
|
8
|
+
pos = check_pos(model, origin, pos)
|
8
9
|
loc = Location.new(model, origin, pos)
|
9
10
|
add_to_locations accessor, loc
|
11
|
+
|
12
|
+
unless range.nil?
|
13
|
+
unless range.cover?(pos)
|
14
|
+
raise RangeError, "Position <#{loc.position}> out of range <#{range}>"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
10
18
|
mask = mask(accessor)
|
11
19
|
add_accessors(accessor, origin, mask)
|
12
20
|
end
|
data/lib/act_with_flags.rb
CHANGED
@@ -9,30 +9,36 @@
|
|
9
9
|
# TDD considered harmful
|
10
10
|
# TGCB
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
module ActWithFlags
|
13
|
+
module Base
|
14
|
+
attr_reader :act_with_flags
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def add_to_flags(*flags, origin: :flags, range: nil, **hash)
|
17
|
+
unless @act_with_flags
|
18
|
+
@act_with_flags ||= ActWithFlags::Admin.new self
|
19
|
+
@act_with_flags.add_mask_et_all origin
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
flags.each { |name| @act_with_flags.add_flag(name, nil, origin, range) }
|
23
|
+
hash.each { |name, pos| @act_with_flags.add_flag(name, pos, origin, range) }
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
@act_with_flags
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def remove_from_flags(*flags)
|
29
|
+
flags.each { |name| @act_with_flags.remove_accessor(name) }
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
def clear_flags_at_save(*flags)
|
33
|
+
@act_with_flags.clear_at_save(*flags)
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
38
|
+
class ActiveRecord::Base
|
39
|
+
extend ActWithFlags::Base
|
40
|
+
end
|
41
|
+
|
36
42
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
|
37
43
|
require "act_with_flags/version"
|
38
44
|
require "act_with_flags/utils"
|
data/test/range_test.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
describe "range" do
|
4
|
+
def setup
|
5
|
+
reset_order
|
6
|
+
end
|
7
|
+
|
8
|
+
it "runs without range" do
|
9
|
+
Order.add_to_flags :a
|
10
|
+
Order.add_to_flags :b
|
11
|
+
end
|
12
|
+
|
13
|
+
it "runs with range(inside)" do
|
14
|
+
Order.add_to_flags range: 2..4, a: 2
|
15
|
+
Order.add_to_flags range: 2..4, b: 3
|
16
|
+
end
|
17
|
+
|
18
|
+
it "fails with outside range" do
|
19
|
+
assert_raises(RangeError) { Order.add_to_flags range: 2..3, a: 1 }
|
20
|
+
assert_raises(RangeError) { Order.add_to_flags range: 2..3, b: 4 }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "runs at borders" do
|
24
|
+
Order.add_to_flags range: 2..3, a: 2
|
25
|
+
Order.add_to_flags range: 2..3, b: 3
|
26
|
+
end
|
27
|
+
|
28
|
+
it "runs with ... as range" do
|
29
|
+
Order.add_to_flags range: 2...3, a: 2
|
30
|
+
assert_raises(RangeError) { Order.add_to_flags range: 2...3, b: 3 }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "detects wrong range" do
|
34
|
+
assert_raises(RangeError) { Order.add_to_flags range: "a".."z", a: 2 }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "tests range 0..0 no position" do
|
38
|
+
Order.add_to_flags :a, range: 0..0
|
39
|
+
assert_raises(RangeError) { Order.add_to_flags :b, range: 0..0 }
|
40
|
+
end
|
41
|
+
|
42
|
+
it "tests range ..0 no position" do
|
43
|
+
Order.add_to_flags :a, range: ..0
|
44
|
+
assert_raises(RangeError) { Order.add_to_flags :b, range: ..0 }
|
45
|
+
end
|
46
|
+
|
47
|
+
it "tests range ...0 no position" do
|
48
|
+
assert_raises(RangeError) { Order.add_to_flags :a, range: ...0 }
|
49
|
+
end
|
50
|
+
|
51
|
+
# YAGNI
|
52
|
+
# # includes range: ( .. 3 ) equivalent to range: ..3
|
53
|
+
# n = 100
|
54
|
+
# (0..n).each do |i|
|
55
|
+
# rng = ..i
|
56
|
+
#
|
57
|
+
# (0..i).each do |j|
|
58
|
+
# it "tests range ..#{i} with position #{j}" do
|
59
|
+
# Order.add_to_flags a: j, range: rng
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# it "fails range ..#{i} with position overflow" do
|
64
|
+
# assert_raises(RangeError) { Order.add_to_flags b: (i + 1), range: rng }
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# it "runs ii plus" do
|
69
|
+
# ii = 0
|
70
|
+
# (0..2).each { |íí|
|
71
|
+
# sym = "x#{ii}".to_sym
|
72
|
+
# j = f(ii, ii + 1) # filler
|
73
|
+
# rand j
|
74
|
+
# Order.add_to_flags :range => ii..f(íí, íí), sym => (ii += 1)
|
75
|
+
# orden = Order.new
|
76
|
+
# refute orden.send("#{sym}?") # checks that accessor is active
|
77
|
+
# orden.x0 = true # checks that first accessor is still there
|
78
|
+
# assert orden.x0?
|
79
|
+
# }
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# private
|
83
|
+
#
|
84
|
+
# def f(x, y)
|
85
|
+
# return y + 1 if x == 0
|
86
|
+
# return f(x - 1, 1) if y == 0
|
87
|
+
# f(x - 1, f(x, y - 1))
|
88
|
+
# end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: act_with_flags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dittmar Krall
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -112,7 +112,6 @@ files:
|
|
112
112
|
- MIT-LICENSE
|
113
113
|
- README.md
|
114
114
|
- Rakefile
|
115
|
-
- TODO
|
116
115
|
- act_with_flags.gemspec
|
117
116
|
- gemfiles/rails_6.0.gemfile
|
118
117
|
- gemfiles/rails_6.1.gemfile
|
@@ -152,6 +151,7 @@ files:
|
|
152
151
|
- test/one_test.rb
|
153
152
|
- test/origin_test.rb
|
154
153
|
- test/origins_test.rb
|
154
|
+
- test/range_test.rb
|
155
155
|
- test/remove_from_test.rb
|
156
156
|
- test/string_test.rb
|
157
157
|
- test/test_helper.rb
|
data/TODO
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# max_bits
|
2
|
-
|
3
|
-
add_to_flags(
|
4
|
-
...
|
5
|
-
max_bits: 63
|
6
|
-
)
|
7
|
-
|
8
|
-
Sinn und Zweck von :max_bits. Beispiel ein bigint Feld von PostgreSQL hat
|
9
|
-
64 Bits. Das Bit 2**63 ist allerdings nur bei negativen Zahlen gesetzt.
|
10
|
-
Damit stehen für add_to_flags bei solch einem Feld nur 63 Bits also
|
11
|
-
höchstens das Bit 2**62 zur Verfügung. Die Option max_bits: 62 würde sichern,
|
12
|
-
dass kein höheres Bit verwendet wird. Falls doch würde bereits bei
|
13
|
-
add_to_flags eine Exception bereits beim Start der Rails-Web-App geworfen und
|
14
|
-
nicht erst bei der Verwendung des Bits.
|
15
|
-
|
16
|
-
## Solution
|
17
|
-
|
18
|
-
Rails supports already "validate" which is, IMHO,
|
19
|
-
the right way to limit values to be stored in the database.
|
20
|
-
Furthermore, invalid values, stored by equivocation,
|
21
|
-
are detected by "validate".
|