act_with_flags 3.0.1 → 3.1.0

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: 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".