act_with_flags 0.2.4 → 3.0.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +9 -3
  3. data/.ruby-gemset +1 -1
  4. data/.ruby-version +1 -1
  5. data/.watchr +29 -16
  6. data/Appraisals +10 -6
  7. data/Gemfile +7 -6
  8. data/Gemfile.lock +124 -104
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +30 -3
  11. data/Rakefile +5 -5
  12. data/TODO +21 -0
  13. data/act_with_flags.gemspec +20 -20
  14. data/gemfiles/rails_6.0.gemfile +2 -1
  15. data/gemfiles/rails_7.0.gemfile +15 -0
  16. data/lib/act_with_flags/admin.rb +5 -48
  17. data/lib/act_with_flags/clear.rb +30 -0
  18. data/lib/act_with_flags/define.rb +6 -35
  19. data/lib/act_with_flags/flags.rb +67 -0
  20. data/lib/act_with_flags/print.rb +21 -27
  21. data/lib/act_with_flags/utils.rb +25 -13
  22. data/lib/act_with_flags/version.rb +8 -7
  23. data/lib/act_with_flags.rb +14 -25
  24. data/test/any_all_none_test.rb +6 -9
  25. data/test/benchmark_test.rb +73 -0
  26. data/test/clear_test.rb +5 -7
  27. data/test/coding_check_add_test.rb +29 -0
  28. data/test/coding_coverage_test.rb +19 -0
  29. data/test/coding_mask2d_test.rb +25 -0
  30. data/test/coding_null_test.rb +29 -0
  31. data/test/coding_one_test.rb +26 -0
  32. data/test/coding_reset_test.rb +18 -0
  33. data/test/inheritance_any_test.rb +9 -33
  34. data/test/inheritance_test.rb +7 -10
  35. data/test/internal/app/controllers/orders_controller.rb +1 -3
  36. data/test/internal/app/models/order.rb +1 -5
  37. data/test/internal/config/routes.rb +1 -1
  38. data/test/internal/db/schema.rb +6 -7
  39. data/test/legacy_test.rb +8 -9
  40. data/test/mask_test.rb +6 -7
  41. data/test/null_test.rb +3 -5
  42. data/test/one_test.rb +7 -9
  43. data/test/origin_test.rb +7 -26
  44. data/test/origins_test.rb +57 -0
  45. data/test/remove_from_test.rb +3 -4
  46. data/test/test_helper.rb +8 -8
  47. metadata +21 -41
  48. data/.rubocop.yml +0 -9
  49. data/test/internal_benchmark_test.rb +0 -52
  50. data/test/internal_check_add_test.rb +0 -36
  51. data/test/internal_null_test.rb +0 -29
  52. data/test/internal_one_test.rb +0 -27
  53. data/test/reset_test.rb +0 -17
@@ -1,68 +1,25 @@
1
- # rubocop:disable all
2
1
  # frozen_string_literal: true
3
2
 
4
3
  class ActWithFlags::Admin
5
-
6
4
  attr_reader :model
7
- attr_reader :origin
8
- attr_reader :delete_mask
9
5
 
10
6
  def initialize(model)
7
+ @locations = {}
8
+ @clears = {}
11
9
  @model = model
12
- @origin = :flags
13
- @map = {}
14
- @delete_mask = 0
15
- @max_position = 512 - 1
16
10
  @boolean_hash = {}
17
- [true, 'true', 1, '1'].each { |x| @boolean_hash[x] = true }
18
- [false, 'false', 0, '0'].each { |x| @boolean_hash[x] = false }
11
+ [true, "true", 1, "1"].each { |x| @boolean_hash[x] = true }
12
+ [false, "false", 0, "0"].each { |x| @boolean_hash[x] = false }
19
13
  end
20
14
 
21
15
  def reset_model(model)
22
16
  initialize model
23
17
  end
24
18
 
25
- def names
26
- @map.keys.sort
27
- end
28
-
29
19
  def to_boolean(value)
30
20
  res = @boolean_hash[value]
31
- return res unless res.nil?
21
+ return res unless res.nil?
32
22
 
33
23
  raise "invalid boolean <#{value}>"
34
24
  end
35
-
36
- def origin=(name)
37
- raise 'invalid update of origin' unless @map.empty? || (origin == name)
38
- @origin = name
39
- end
40
-
41
- def position(name)
42
- pos = @map[name]
43
- return pos if pos
44
-
45
- parent = self.model.superclass.act_with_flags
46
- return parent.position(name) if parent
47
-
48
- raise "unknown flag '#{model}##{name}'"
49
- end
50
-
51
- def mask(*names)
52
- names.inject(0) { |msk, name| msk | ( 1 << position(name) ) }
53
- end
54
-
55
- def add(name, pos)
56
- values = @map.values
57
- pos ||= (0..@max_position).detect { |i| !values.include?(i) }
58
- raise "invalid position '#{name} @ #{pos}'" unless pos
59
- raise "name in use '#{name} @ #{pos}'" if @map.key?(name)
60
- raise "position in use '#{name} @ #{pos}'" if @map.value?(pos)
61
- @map[name] = pos
62
- end
63
-
64
- def add_to_delete_mask(name)
65
- @delete_mask |= mask(name)
66
- end
67
-
68
25
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActWithFlags::Admin
4
+ attr_reader :clears
5
+
6
+ def clear_at_save(*flags)
7
+ flags.each { |name| add_to_clear_mask(name) }
8
+ clears.each { |orig, mask|
9
+ before_save(orig, mask)
10
+ }
11
+ @clears = {}
12
+ end
13
+
14
+ private
15
+
16
+ def add_to_clear_mask(name)
17
+ _model, orig, _pos = location(name).values
18
+ mask = @clears[orig] || 0
19
+ mask |= 1 << position(name)
20
+ @clears[orig] = mask
21
+ end
22
+
23
+ def before_save(orig, mask)
24
+ model.class_eval %(
25
+ before_save do |row|
26
+ row.#{orig} &= ~#{mask}
27
+ end
28
+ ), __FILE__, __LINE__ - 4
29
+ end
30
+ end
@@ -1,16 +1,13 @@
1
- # rubocop:disable all
2
1
  # frozen_string_literal: true
3
2
 
4
3
  class ActWithFlags::Admin
5
-
6
- def add_accessors(origin, accessor, mask)
7
- #p ["act_with_flags#add_accessors:", model, origin, accessor, mask]
4
+ def add_accessors(accessor, origin, mask)
8
5
  unless model.method_defined?(:act_with_flags)
9
6
  model.class_eval %(
10
7
  def act_with_flags
11
8
  #{model}.act_with_flags
12
9
  end
13
- )
10
+ ), __FILE__, __LINE__ - 4
14
11
  end
15
12
 
16
13
  model.class_eval %(
@@ -19,7 +16,7 @@ class ActWithFlags::Admin
19
16
  end
20
17
 
21
18
  def #{accessor}?
22
- raise "Uninitialized '#{model}.#{origin}'" if #{origin}.nil?
19
+ raise "Uninitialized '#{model}.#{origin}'" if #{origin}.nil?
23
20
  if #{origin}.is_a?(String)
24
21
  flags = self.#{origin}.to_i
25
22
  !( flags & #{mask} ).zero?
@@ -29,9 +26,9 @@ class ActWithFlags::Admin
29
26
  end
30
27
 
31
28
  def #{accessor}=(value)
32
- raise "Uninitialized '#{model}.#{origin}'" if #{origin}.nil?
29
+ raise "Uninitialized '#{model}.#{origin}'" if #{origin}.nil?
33
30
  is_a_string = #{origin}.is_a?(String)
34
- flags = is_a_string ? self.#{origin}.to_i : self.#{origin}
31
+ flags = self.#{origin}.to_i
35
32
  flags ||= 0
36
33
 
37
34
  result = self.act_with_flags.to_boolean(value)
@@ -44,36 +41,10 @@ class ActWithFlags::Admin
44
41
 
45
42
  result
46
43
  end
47
- )
44
+ ), __FILE__, __LINE__ - 31
48
45
  end
49
46
 
50
47
  def remove_accessor(accessor)
51
48
  my_undef model, accessor, "#{accessor}?", "#{accessor}="
52
49
  end
53
-
54
- def validate_accessor(*names)
55
- names.each { |acc|
56
- raise "redefining #{acc} rejected" if model.method_defined?(acc)
57
- }
58
- end
59
-
60
- def my_undef(*names)
61
- names.each { |name|
62
- model.class_eval %(
63
- begin
64
- undef #{name}
65
- rescue
66
- end
67
- )
68
- }
69
- end
70
-
71
- def before_save
72
- model.class_eval %(
73
- before_save do |row|
74
- row.#{origin} &= ~row.class.act_with_flags.delete_mask
75
- end
76
- )
77
- end
78
-
79
50
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActWithFlags::Admin
4
+ Location = Struct.new(:model, :origin, :position)
5
+
6
+ attr_reader :locations
7
+
8
+ def mask(*flags)
9
+ return 0 if flags.empty?
10
+
11
+ res = mask2d(*flags)
12
+ raise "Mixing origins fails: #{flags}" unless res.length == 1
13
+
14
+ res.values.first
15
+ end
16
+
17
+ def mask2d(*flags)
18
+ res = {}
19
+ flags.each { |flag|
20
+ model, orig, pos = location(flag).values
21
+ idx = "#{model}##{orig}"
22
+ mask = res[idx] || 0
23
+ res[idx] = mask | (1 << pos)
24
+ }
25
+ res
26
+ end
27
+
28
+ def location(name)
29
+ location = @locations[name]
30
+ return location if location
31
+
32
+ parent = model.superclass.act_with_flags
33
+ return parent.location(name) if parent
34
+
35
+ raise "unknown flag '#{model}##{name}'"
36
+ end
37
+
38
+ private
39
+
40
+ def position(name)
41
+ location(name).position
42
+ end
43
+
44
+ def add_to_locations(flag, location)
45
+ location = check_position(location)
46
+ who = "<#{flag}: #{location.origin}@#{location.position}>"
47
+ raise "name already used #{who}" if @locations.key?(flag)
48
+ bool = @locations.has_value?(location)
49
+ raise "position already used #{who}" if bool
50
+ @locations[flag] = location
51
+ end
52
+
53
+ def check_position(location)
54
+ model, orig, pos = location.values
55
+ return location if pos
56
+
57
+ max_position = -1
58
+ @locations.each { |name, location|
59
+ model2, orig2, pos2 = location.values
60
+ next unless model == model2 && orig == orig2
61
+
62
+ max_position = pos2 if pos2 > max_position
63
+ }
64
+
65
+ Location.new(model, orig, max_position + 1)
66
+ end
67
+ end
@@ -1,44 +1,39 @@
1
- # rubocop:disable all
2
1
  # frozen_string_literal: true
3
2
 
4
3
  class ActWithFlags::Admin
5
-
6
4
  def to_s
7
5
  res = []
8
- res << title('Variables')
9
- res << variables(:origin, :boolean_hash)
6
+ res << title("Variables")
7
+ res << variables(:boolean_hash)
10
8
  res << variables(:delete_mask)
11
9
 
12
- res << title('Flags sorted alfabetically')
13
- @map.sort.each { |key, pos| res << "#{key} #{position(key)}" }
14
-
15
- res << title('Flags sorted by position')
16
- @map.sort.sort_by(&:last).each { |key, pos|
17
- res << "#{key} #{position(key)}"
10
+ res << blk("Flags sorted alfabetically") { |key, loc|
11
+ "#{key} #{loc}"
18
12
  }
19
-
20
- res << title('Flags and mask; sorted alfabetically')
21
- @map.sort.each { |key, pos|
22
- res << "#{key} #{sprintf('0x%08X', mask(key))}"
23
- }
24
-
25
- res << title('FLAG assignment; sorted alfabetically')
26
- @map.sort.each { |key, pos|
27
- res << "FLAG_#{key.upcase} = #{sprintf('0x%08X', mask(key))}"
13
+ res << blk("Flags and mask; sorted alfabetically") { |key, loc|
14
+ "#{key} #{sprintf("0x%08X", mask(key))}"
28
15
  }
29
-
30
- res << title('FLAG assignment; sorted by position')
31
- @map.sort.sort_by(&:last).each { |key, pos|
32
- res << "FLAG_#{key.upcase} = #{sprintf('0x%08X', mask(key))}"
16
+ res << blk("FLAG assignment; sorted alfabetically") { |key, loc|
17
+ "FLAG_#{key.upcase} = #{sprintf("0x%08X", mask(key))}"
33
18
  }
34
19
 
20
+ res << title("@locations")
21
+ res << @locations
35
22
  res.flatten.join("\n")
36
23
  end
37
24
 
38
- private
25
+ private
26
+
39
27
  def title(msg)
40
- sep = '#' * 10
41
- ['', "#{sep} #{msg} #{sep}"]
28
+ sep = "#" * 10
29
+ ["", "#{sep} #{msg} #{sep}"]
30
+ end
31
+
32
+ def blk(legend, &block)
33
+ res = [title(legend)]
34
+ sorted = @locations.sort
35
+ sorted.each { |key, loc| res << block.call(key, loc) }
36
+ res
42
37
  end
43
38
 
44
39
  def variables(*names)
@@ -47,5 +42,4 @@ class ActWithFlags::Admin
47
42
  "#{name} #{value}"
48
43
  }
49
44
  end
50
-
51
45
  end
@@ -1,16 +1,14 @@
1
- # rubocop: disable all
1
+ # frozen_string_literal: true
2
2
 
3
3
  class ActWithFlags::Admin
4
-
5
- def add_accessor(name, pos)
6
- #p "** act_with_flags: add_accessor '#{name} @ #{pos}'"
4
+ def add_flag(name, origin, pos)
7
5
  accessor = name.to_sym
8
6
  validate_accessor accessor, "#{accessor}?", "#{accessor}="
9
7
 
10
- add accessor, pos
8
+ loc = Location.new(model, origin, pos)
9
+ add_to_locations accessor, loc
11
10
  mask = mask(accessor)
12
- origin = self.origin
13
- add_accessors(origin, accessor, mask)
11
+ add_accessors(accessor, origin, mask)
14
12
  end
15
13
 
16
14
  def add_mask_et_all(origin)
@@ -33,19 +31,33 @@ class ActWithFlags::Admin
33
31
  mask = self.class.act_with_flags.mask(*names)
34
32
  ( self.#{origin} & mask ).zero?
35
33
  end
36
- )
37
- end
38
-
39
- def delete_mask_et_all
40
- my_undef :flags_mask, :flags_any?, :flags_all?, :flags_none?
34
+ ), __FILE__, __LINE__ - 19
41
35
  end
42
36
 
43
37
  def reset
44
- delete_mask_et_all
38
+ names = @locations.keys.sort
45
39
  names.each { |name|
46
40
  remove_accessor name
47
41
  }
48
42
  reset_model model
49
43
  end
50
44
 
45
+ private
46
+
47
+ def validate_accessor(*names)
48
+ names.each { |acc|
49
+ raise "redefining #{acc} rejected" if model.method_defined?(acc)
50
+ }
51
+ end
52
+
53
+ def my_undef(*names)
54
+ names.each { |name|
55
+ model.class_eval %(
56
+ begin
57
+ undef #{name}
58
+ rescue
59
+ end
60
+ ), __FILE__, __LINE__ - 5
61
+ }
62
+ end
51
63
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
- # rubocop: disable all
3
2
 
4
3
  module ActWithFlags
5
- VERSION = '0.2.4' # 2021-06-21
6
- # VERSION = '0.2.3' # 2020-07-14
7
- # VERSION = '0.2.2' # 2020-04-27
8
- # VERSION = '0.2.1' # 2020-03-01
9
- # VERSION = '0.2.0' # 2019-10-04
10
- # VERSION = '0.1.0' # 2019-04-07
4
+ VERSION = "3.0.1" # 2022-08-07
5
+ # VERSION = "3.0.0" # 2022-07-27
6
+ # VERSION = "0.2.4" # 2021-06-21
7
+ # VERSION = "0.2.3" # 2020-07-14
8
+ # VERSION = "0.2.2" # 2020-04-27
9
+ # VERSION = "0.2.1" # 2020-03-01
10
+ # VERSION = "0.2.0" # 2019-10-04
11
+ # VERSION = "0.1.0" # 2019-04-07
11
12
  end
@@ -1,4 +1,3 @@
1
- # rubocop:disable all
2
1
  # frozen_string_literal: true
3
2
 
4
3
  # Principles:
@@ -8,47 +7,37 @@
8
7
  # POLS
9
8
  # DEI
10
9
  # TDD considered harmful
10
+ # TGCB
11
11
 
12
12
  class << ActiveRecord::Base
13
-
14
- attr_accessor :act_with_flags
13
+ attr_reader :act_with_flags
15
14
 
16
15
  def add_to_flags(*flags, origin: :flags, **hash)
17
- #p "act_with_flags: add_to_flags #{flags.inspect}"
18
- #p "act_with_flags: origin #{origin.inspect}"
19
- #p "act_with_flags: hash #{hash.inspect}"
20
-
21
- @act_with_flags ||= ActWithFlags::Admin.new self
22
- if origin.is_a?(Integer)
23
- hash[:origin] = origin
24
- else
25
- @act_with_flags.origin = origin
26
- @act_with_flags.delete_mask_et_all
16
+ unless @act_with_flags
17
+ @act_with_flags ||= ActWithFlags::Admin.new self
27
18
  @act_with_flags.add_mask_et_all origin
28
19
  end
29
20
 
30
- flags.each { |name| @act_with_flags.add_accessor(name, nil) }
31
- hash.each { |name, pos| @act_with_flags.add_accessor(name, pos) }
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) }
32
23
 
33
24
  @act_with_flags
34
25
  end
35
26
 
36
27
  def remove_from_flags(*flags)
37
- #p "remove_from_flags #{flags.inspect}"
38
28
  flags.each { |name| @act_with_flags.remove_accessor(name) }
39
29
  end
40
30
 
41
31
  def clear_flags_at_save(*flags)
42
- #p "clear_flags_at_save #{flags.inspect}"
43
- flags.each { |name| @act_with_flags.add_to_delete_mask(name) }
44
- @act_with_flags.before_save
32
+ @act_with_flags.clear_at_save(*flags)
45
33
  end
46
-
47
34
  end
48
35
 
49
36
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
50
- require 'act_with_flags/version'
51
- require 'act_with_flags/utils'
52
- require 'act_with_flags/define'
53
- require 'act_with_flags/admin'
54
- require 'act_with_flags/print'
37
+ require "act_with_flags/version"
38
+ require "act_with_flags/utils"
39
+ require "act_with_flags/define"
40
+ require "act_with_flags/admin"
41
+ require "act_with_flags/flags"
42
+ require "act_with_flags/clear"
43
+ require "act_with_flags/print"
@@ -1,8 +1,6 @@
1
- # rubocop: disable all
1
+ require "test_helper"
2
2
 
3
- require 'test_helper'
4
-
5
- describe 'any? all? and none?' do
3
+ describe "any? all? and none?" do
6
4
  let(:order) { Order.create }
7
5
 
8
6
  def setup
@@ -10,28 +8,28 @@ describe 'any? all? and none?' do
10
8
  Order.add_to_flags a: 1, b: 7, c: 3
11
9
  end
12
10
 
13
- it 'checks any?' do
11
+ it "checks any?" do
14
12
  order.a = true
15
13
  assert order.flags_any?(:a, :b)
16
14
  order.a = false
17
15
  refute order.flags_any?(:a, :b)
18
16
  end
19
17
 
20
- it 'checks any? #2' do
18
+ it "checks any? #2" do
21
19
  order.b = true
22
20
  assert order.flags_any?(:a, :b)
23
21
  order.b = false
24
22
  refute order.flags_any?(:a, :b)
25
23
  end
26
24
 
27
- it 'checks all?' do
25
+ it "checks all?" do
28
26
  order.a = order.b = true
29
27
  assert order.flags_all?(:a, :b)
30
28
  order.a = false
31
29
  refute order.flags_all?(:a, :b)
32
30
  end
33
31
 
34
- it 'checks none? #2' do
32
+ it "checks none? #2" do
35
33
  order.a = order.b = true
36
34
  refute order.flags_none?(:a, :b)
37
35
  order.a = false
@@ -39,5 +37,4 @@ describe 'any? all? and none?' do
39
37
  order.b = false
40
38
  assert order.flags_none?(:a, :b)
41
39
  end
42
-
43
40
  end
@@ -0,0 +1,73 @@
1
+ # For development purposes; do not waste your tine reading it!
2
+ # YAGNI
3
+
4
+ require "test_helper"
5
+ require "benchmark"
6
+ require "benchmark/ips"
7
+ # ENV["MORE"] = "true"
8
+
9
+ describe "Internal timings flag" do
10
+ let(:order) { Order.create }
11
+
12
+ def setup
13
+ reset_order
14
+ Order.add_to_flags :blocked
15
+ end
16
+
17
+ it "times ips" do
18
+ return unless ENV["MORE"]
19
+
20
+ Benchmark.ips do |x|
21
+ x.report("assign true : ") { order.blocked = true }
22
+ x.report("assign false: ") { order.blocked = false }
23
+ x.report("assign \"false\": ") { order.blocked = "false" }
24
+ x.report("x = order.blocked? ") { x = order.blocked? }
25
+ x.report("x = order.blocked ") { x = order.blocked }
26
+
27
+ x.compare!
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "Internal timings mask" do
33
+ let(:order) { Order.create }
34
+ let(:admin) { Order.act_with_flags }
35
+
36
+ def setup
37
+ reset_order
38
+ Order.add_to_flags a: 1, b: 7, c: 3
39
+ # Order.add_to_flags a: 1, b: 60, c: 3
40
+ # Order.add_to_flags a: 1, b: 1000, c: 3
41
+ end
42
+
43
+ it "times ips" do
44
+ return unless ENV["MORE"]
45
+
46
+ Benchmark.ips do |x|
47
+ x.report("mask(:a, :b): ") { admin.mask(:a, :b) }
48
+ x.report("any?(:a, :b): ") { order.flags_any?(:a, :b) }
49
+ x.report("all?(:a, :b): ") { order.flags_all?(:a, :b) }
50
+ x.report("none?(:a, :b): ") { order.flags_none?(:a, :b) }
51
+
52
+ x.compare!
53
+ end
54
+ end
55
+ end
56
+
57
+ class BenchFoo < Minitest::Benchmark
58
+ def bench_order_blocked
59
+ return unless ENV["MORE"]
60
+
61
+ n = 1_000_000
62
+ n = 100_000
63
+ n = 10_000
64
+ Order.add_to_flags :blocked2
65
+ order = Order.create
66
+ assert_performance_constant do |input|
67
+ n.times do
68
+ order.blocked2 = true
69
+ order.blocked2 = !order.blocked2
70
+ end
71
+ end
72
+ end
73
+ end
data/test/clear_test.rb CHANGED
@@ -1,7 +1,6 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
- describe 'Clear Flags at Save' do
4
- let(:admin) { Order.act_with_flags }
3
+ describe "Clear flags at save" do
5
4
  let(:order) { Order.create }
6
5
 
7
6
  def setup
@@ -10,21 +9,20 @@ describe 'Clear Flags at Save' do
10
9
  order.a = order.b = order.c = true
11
10
  end
12
11
 
13
- it 'checks sanity' do
12
+ it "checks sanity" do
14
13
  assert_equal 0x8a, order.flags
15
14
  assert order.b
16
15
  end
17
16
 
18
- it 'clear flags during save' do
17
+ it "clear flags during save" do
19
18
  Order.clear_flags_at_save :b
20
19
  order.save
21
20
  order.reload
22
21
  assert_equal 0x0a, order.flags
23
22
  end
24
23
 
25
- it 'does not remove accessor' do
24
+ it "does not remove accessor" do
26
25
  Order.clear_flags_at_save :b
27
26
  Order.respond_to? :b
28
27
  end
29
-
30
28
  end
@@ -0,0 +1,29 @@
1
+ require "test_helper"
2
+
3
+ describe "Internal check add flag" do
4
+ let(:order) { Order.create }
5
+
6
+ def setup
7
+ reset_order
8
+ Order.add_to_flags a: 1, b: 7
9
+ end
10
+
11
+ it "skip reserved position" do
12
+ Order.add_to_flags :xx
13
+ order.xx = true
14
+ assert_equal 0x100, order.flags
15
+
16
+ Order.add_to_flags :yy
17
+ order.yy = true
18
+ assert_equal 0x300, order.flags
19
+ end
20
+
21
+ it "rejects redefinition" do
22
+ Order.add_to_flags :z
23
+ assert_raises { Order.add_to_flags :z }
24
+ end
25
+
26
+ it "rejects reuse of position" do
27
+ assert_raises { Order.add_to_flags qq: 1 }
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ describe "Coverage" do
4
+ let(:order) { Order.create }
5
+
6
+ def setup
7
+ reset_order
8
+ Order.add_to_flags a: 1, b: 7
9
+ end
10
+
11
+ it "coverage to_s" do
12
+ res = order.act_with_flags.to_s
13
+ puts res if ENV["MORE"]
14
+ end
15
+
16
+ it "coverage location raise" do
17
+ assert_raises { order.act_with_flags.location(:unknown) }
18
+ end
19
+ end