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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 743598329586132b56037a7f83e282e0a23f7f7ebcf33c0281ca29ac9285b50f
4
- data.tar.gz: 108e19ed8834782c421e247e76713bc4129113bef80a3389cb469a69d7fc8982
3
+ metadata.gz: 4e2b18cdaf7777bddb191c830bc942a6fd7c377a4267c8e7beae3b2ace3552e9
4
+ data.tar.gz: 1aed1f1e86fdbdd1cff793c0296c1b6e23c7400dc43f7df17ad8e13c3b1998d0
5
5
  SHA512:
6
- metadata.gz: c37311aab7060cf9f57063e5e60c74840042180aea327a5a3d224b62e687bee59b31876d9367ecb44978cf868df93e778f760fe6a74f8fd6610df9e44bc451cb
7
- data.tar.gz: 040b721cbc34321535dbdf281c3778fed4876c4f9cfe074c0c36ef38c9bd1b64ec5a3ae13db7b67517f396bdc826d0146e1acd88cc074845952fbd0e55c0a27c
6
+ metadata.gz: 11154bcaf21ff519f34863fdb847ffefd1e9a2fb493cfcdd8d0e015de42b601a9b3bf20d9e914d0e8681f39e321194ba3a27048a74fb43ce3972b9844cf0f14c
7
+ data.tar.gz: 4471f2dc9a7b48654fa9ea689e4f51e660f6eacb0012fc1ea75c43fd2cb9c91149c49243e24a78e4527407d4c75dd51e7b0066095efebb14f007eb3dda36a839
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gem "rails"
5
5
 
6
6
  group :test do
7
7
  gem "observr"
8
- gem "rubocop", require: false
8
+ gem "standardrb", require: false
9
9
  gem "simplecov", require: false
10
10
  gem "benchmark-ips"
11
11
  gem "ricecream"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- act_with_flags (3.0.1)
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.2)
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.0)
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.33.0)
160
+ rubocop (1.35.0)
161
161
  json (~> 2.3)
162
162
  parallel (~> 1.10)
163
- parser (>= 3.1.0.0)
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.19.1, < 2.0)
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.19.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
  [![Gem Version](https://badge.fury.io/rb/act_with_flags.png)](http://badge.fury.io/rb/act_with_flags)
3
4
 
4
- Required by key.matiq.
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
- Add this line to your application's Gemfile:
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
- And then execute:
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
- $ bundle install
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
- Or install it yourself as:
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.com UG) and
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
@@ -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 check_position(location)
54
- model, orig, pos = location.values
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 && orig == orig2
58
+ next unless model == model2 && origin == orig2
61
59
 
62
60
  max_position = pos2 if pos2 > max_position
63
61
  }
64
62
 
65
- Location.new(model, orig, max_position + 1)
63
+ max_position + 1
66
64
  end
67
65
  end
@@ -1,12 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ActWithFlags::Admin
4
- def add_flag(name, origin, pos)
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
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActWithFlags
4
- VERSION = "3.0.1" # 2022-08-07
4
+ VERSION = "3.1.0" # 2022-08-29
5
+ # VERSION = "3.0.1" # 2022-08-07
5
6
  # VERSION = "3.0.0" # 2022-07-27
6
7
  # VERSION = "0.2.4" # 2021-06-21
7
8
  # VERSION = "0.2.3" # 2020-07-14
@@ -9,30 +9,36 @@
9
9
  # TDD considered harmful
10
10
  # TGCB
11
11
 
12
- class << ActiveRecord::Base
13
- attr_reader :act_with_flags
12
+ module ActWithFlags
13
+ module Base
14
+ attr_reader :act_with_flags
14
15
 
15
- def add_to_flags(*flags, origin: :flags, **hash)
16
- unless @act_with_flags
17
- @act_with_flags ||= ActWithFlags::Admin.new self
18
- @act_with_flags.add_mask_et_all origin
19
- end
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
- flags.each { |name| @act_with_flags.add_flag(name, origin, nil) }
22
- hash.each { |name, pos| @act_with_flags.add_flag(name, origin, pos) }
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
- @act_with_flags
25
- end
25
+ @act_with_flags
26
+ end
26
27
 
27
- def remove_from_flags(*flags)
28
- flags.each { |name| @act_with_flags.remove_accessor(name) }
29
- end
28
+ def remove_from_flags(*flags)
29
+ flags.each { |name| @act_with_flags.remove_accessor(name) }
30
+ end
30
31
 
31
- def clear_flags_at_save(*flags)
32
- @act_with_flags.clear_at_save(*flags)
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"
@@ -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.1
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-07 00:00:00.000000000 Z
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".