bcdd-result 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -1
  3. data/CHANGELOG.md +70 -16
  4. data/README.md +293 -83
  5. data/Steepfile +4 -4
  6. data/examples/multiple_listeners/Rakefile +55 -0
  7. data/examples/multiple_listeners/app/models/account/member.rb +10 -0
  8. data/examples/multiple_listeners/app/models/account/owner_creation.rb +62 -0
  9. data/examples/multiple_listeners/app/models/account.rb +11 -0
  10. data/examples/multiple_listeners/app/models/user/creation.rb +67 -0
  11. data/examples/multiple_listeners/app/models/user/token/creation.rb +51 -0
  12. data/examples/multiple_listeners/app/models/user/token.rb +7 -0
  13. data/examples/multiple_listeners/app/models/user.rb +15 -0
  14. data/examples/multiple_listeners/config/boot.rb +16 -0
  15. data/examples/multiple_listeners/config/initializers/bcdd.rb +11 -0
  16. data/examples/multiple_listeners/config.rb +27 -0
  17. data/examples/multiple_listeners/db/setup.rb +61 -0
  18. data/examples/multiple_listeners/lib/bcdd/result/rollback_on_failure.rb +15 -0
  19. data/examples/multiple_listeners/lib/bcdd/result/transitions_record.rb +28 -0
  20. data/examples/multiple_listeners/lib/runtime_breaker.rb +11 -0
  21. data/examples/multiple_listeners/lib/transitions_listener/stdout.rb +54 -0
  22. data/examples/single_listener/Rakefile +92 -0
  23. data/examples/single_listener/app/models/account/member.rb +10 -0
  24. data/examples/single_listener/app/models/account/owner_creation.rb +62 -0
  25. data/examples/single_listener/app/models/account.rb +11 -0
  26. data/examples/single_listener/app/models/user/creation.rb +67 -0
  27. data/examples/single_listener/app/models/user/token/creation.rb +51 -0
  28. data/examples/single_listener/app/models/user/token.rb +7 -0
  29. data/examples/single_listener/app/models/user.rb +15 -0
  30. data/examples/single_listener/config/boot.rb +16 -0
  31. data/examples/single_listener/config/initializers/bcdd.rb +11 -0
  32. data/examples/single_listener/config.rb +23 -0
  33. data/examples/single_listener/db/setup.rb +49 -0
  34. data/examples/single_listener/lib/bcdd/result/rollback_on_failure.rb +15 -0
  35. data/examples/single_listener/lib/runtime_breaker.rb +11 -0
  36. data/examples/single_listener/lib/single_transitions_listener.rb +108 -0
  37. data/lib/bcdd/result/callable_and_then/caller.rb +1 -1
  38. data/lib/bcdd/result/config.rb +6 -1
  39. data/lib/bcdd/result/context/expectations/mixin.rb +2 -2
  40. data/lib/bcdd/result/context/mixin.rb +2 -2
  41. data/lib/bcdd/result/context/success.rb +20 -2
  42. data/lib/bcdd/result/contract/for_types.rb +1 -1
  43. data/lib/bcdd/result/contract/for_types_and_values.rb +2 -0
  44. data/lib/bcdd/result/expectations/mixin.rb +2 -2
  45. data/lib/bcdd/result/ignored_types.rb +14 -0
  46. data/lib/bcdd/result/mixin.rb +2 -2
  47. data/lib/bcdd/result/transitions/config.rb +26 -0
  48. data/lib/bcdd/result/transitions/listener.rb +51 -0
  49. data/lib/bcdd/result/transitions/listeners.rb +87 -0
  50. data/lib/bcdd/result/transitions/tracking/disabled.rb +1 -13
  51. data/lib/bcdd/result/transitions/tracking/enabled.rb +76 -17
  52. data/lib/bcdd/result/transitions/tracking.rb +8 -3
  53. data/lib/bcdd/result/transitions/tree.rb +26 -0
  54. data/lib/bcdd/result/transitions.rb +3 -4
  55. data/lib/bcdd/result/version.rb +1 -1
  56. data/lib/bcdd/result.rb +7 -5
  57. data/sig/bcdd/result/config.rbs +1 -0
  58. data/sig/bcdd/result/context.rbs +9 -0
  59. data/sig/bcdd/result/ignored_types.rbs +9 -0
  60. data/sig/bcdd/result/transitions.rbs +96 -7
  61. data/sig/bcdd/result.rbs +2 -2
  62. metadata +42 -6
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDD::Result::Transitions
4
+ class Listeners
5
+ class Chain
6
+ include Listener
7
+
8
+ attr_reader :listeners
9
+
10
+ def initialize(list)
11
+ if list.empty? || list.any? { !Listener.kind?(_1) }
12
+ raise ArgumentError, "listeners must be a list of #{Listener}"
13
+ end
14
+
15
+ around_and_then = list.select(&:around_and_then?)
16
+ around_transitions = list.select(&:around_transitions?)
17
+
18
+ raise ArgumentError, 'only one listener can have around_and_then? == true' if around_and_then.size > 1
19
+ raise ArgumentError, 'only one listener can have around_transitions? == true' if around_transitions.size > 1
20
+
21
+ @listeners = { list: list, around_and_then: around_and_then[0], around_transitions: around_transitions[0] }
22
+ end
23
+
24
+ def new
25
+ list, around_and_then, around_transitions = listeners[:list], nil, nil
26
+
27
+ instances = list.map do |item|
28
+ instance = item.new
29
+ around_and_then = instance if listener?(:around_and_then, instance)
30
+ around_transitions = instance if listener?(:around_transitions, instance)
31
+
32
+ instance
33
+ end
34
+
35
+ list.one? ? list[0].new : Listeners.send(:new, instances, around_and_then, around_transitions)
36
+ end
37
+
38
+ private
39
+
40
+ def listener?(name, obj)
41
+ listener = listeners[name]
42
+
43
+ !listener.nil? && (obj.is_a?(listener) || obj == listener)
44
+ end
45
+ end
46
+
47
+ private_class_method :new
48
+
49
+ def self.[](*listeners)
50
+ Chain.new(listeners)
51
+ end
52
+
53
+ attr_reader :listeners, :around_and_then_listener, :around_transitions_listener
54
+
55
+ private :listeners, :around_and_then_listener, :around_transitions_listener
56
+
57
+ def initialize(listeners, around_and_then_listener, around_transitions_listener)
58
+ @listeners = listeners
59
+ @around_and_then_listener = around_and_then_listener || Listener::Null
60
+ @around_transitions_listener = around_transitions_listener || Listener::Null
61
+ end
62
+
63
+ def on_start(scope:)
64
+ listeners.each { _1.on_start(scope: scope) }
65
+ end
66
+
67
+ def around_transitions(scope:, &block)
68
+ around_transitions_listener.around_transitions(scope: scope, &block)
69
+ end
70
+
71
+ def around_and_then(scope:, and_then:, &block)
72
+ around_and_then_listener.around_and_then(scope: scope, and_then: and_then, &block)
73
+ end
74
+
75
+ def on_record(record:)
76
+ listeners.each { _1.on_record(record: record) }
77
+ end
78
+
79
+ def on_finish(transitions:)
80
+ listeners.each { _1.on_finish(transitions: transitions) }
81
+ end
82
+
83
+ def before_interruption(exception:, transitions:)
84
+ listeners.each { _1.before_interruption(exception: exception, transitions: transitions) }
85
+ end
86
+ end
87
+ end
@@ -6,22 +6,10 @@ module BCDD::Result::Transitions
6
6
  EnsureResult[yield]
7
7
  end
8
8
 
9
- def self.reset!; end
10
-
11
9
  def self.record(result); end
12
10
 
13
- def self.record_and_then(_type, _data, _source)
11
+ def self.record_and_then(_type, _data)
14
12
  yield
15
13
  end
16
-
17
- def self.reset_and_then!; end
18
-
19
- class << self
20
- private
21
-
22
- def start(name, desc); end
23
-
24
- def finish(result); end
25
- end
26
14
  end
27
15
  end
@@ -2,22 +2,36 @@
2
2
 
3
3
  module BCDD::Result::Transitions
4
4
  class Tracking::Enabled
5
- attr_accessor :tree, :records, :root_started_at
5
+ attr_accessor :tree, :records, :root_started_at, :listener
6
6
 
7
- private :tree, :tree=, :records, :records=, :root_started_at, :root_started_at=
7
+ private :tree, :tree=, :records, :records=, :root_started_at, :root_started_at=, :listener, :listener=
8
8
 
9
9
  def exec(name, desc)
10
- start(name, desc)
10
+ transition_node, scope = start(name, desc)
11
11
 
12
- transition_node = tree.current
12
+ result = nil
13
13
 
14
- result = EnsureResult[yield]
14
+ listener.around_transitions(scope: scope) do
15
+ result = EnsureResult[yield]
16
+ end
15
17
 
16
18
  tree.move_to_root! if transition_node.root?
17
19
 
18
20
  finish(result)
19
21
 
20
22
  result
23
+ rescue ::Exception => e
24
+ err!(e, transition_node)
25
+ end
26
+
27
+ def err!(exception, transition_node)
28
+ if transition_node.root?
29
+ listener.before_interruption(exception: exception, transitions: map_transitions)
30
+
31
+ reset!
32
+ end
33
+
34
+ raise exception
21
35
  end
22
36
 
23
37
  def reset!
@@ -30,17 +44,23 @@ module BCDD::Result::Transitions
30
44
  track(result, time: ::Time.now.getutc)
31
45
  end
32
46
 
33
- def record_and_then(type_arg, arg, source)
47
+ def record_and_then(type_arg, arg)
48
+ return yield if tree.frozen?
49
+
34
50
  type = type_arg.instance_of?(::Method) ? :method : type_arg
35
51
 
36
- unless tree.frozen?
37
- current_and_then = { type: type, arg: arg, source: source }
38
- current_and_then[:method_name] = type_arg.name if type == :method
52
+ current_and_then = { type: type, arg: arg }
53
+ current_and_then[:method_name] = type_arg.name if type == :method
39
54
 
40
- tree.current.value[1] = current_and_then
41
- end
55
+ tree.current.value[1] = current_and_then
42
56
 
43
- yield
57
+ scope, and_then = tree.current_value
58
+
59
+ result = nil
60
+
61
+ listener.around_and_then(scope: scope, and_then: and_then) { result = yield }
62
+
63
+ result
44
64
  end
45
65
 
46
66
  def reset_and_then!
@@ -55,6 +75,12 @@ module BCDD::Result::Transitions
55
75
  name_and_desc = [name, desc]
56
76
 
57
77
  tree.frozen? ? root_start(name_and_desc) : tree.insert!(name_and_desc)
78
+
79
+ scope = tree.current.value[0]
80
+
81
+ listener.on_start(scope: scope)
82
+
83
+ [tree.current, scope]
58
84
  end
59
85
 
60
86
  def finish(result)
@@ -64,11 +90,11 @@ module BCDD::Result::Transitions
64
90
 
65
91
  return unless node.root?
66
92
 
67
- duration = (now_in_milliseconds - root_started_at)
93
+ transitions = map_transitions
68
94
 
69
- metadata = { duration: duration, tree_map: tree.nested_ids }
95
+ result.send(:transitions=, transitions)
70
96
 
71
- result.send(:transitions=, version: Tracking::VERSION, records: records, metadata: metadata)
97
+ listener.on_finish(transitions: transitions)
72
98
 
73
99
  reset!
74
100
  end
@@ -78,23 +104,56 @@ module BCDD::Result::Transitions
78
104
  def root_start(name_and_desc)
79
105
  self.root_started_at = now_in_milliseconds
80
106
 
107
+ self.listener = build_listener
108
+
81
109
  self.records = []
82
110
 
83
111
  self.tree = Tree.new(name_and_desc, normalizer: TreeNodeValueNormalizer)
84
112
  end
85
113
 
86
114
  def track(result, time:)
87
- result = result.data.to_h
115
+ record = track_record(result, time)
116
+
117
+ records << record
118
+
119
+ listener.on_record(record: record)
120
+
121
+ record
122
+ end
123
+
124
+ def track_record(result, time)
125
+ result_data = result.data.to_h
126
+ result_data[:source] = result.send(:source)
88
127
 
89
128
  root, = tree.root_value
90
129
  parent, = tree.parent_value
91
130
  current, and_then = tree.current_value
92
131
 
93
- records << { root: root, parent: parent, current: current, result: result, and_then: and_then, time: time }
132
+ { root: root, parent: parent, current: current, result: result_data, and_then: and_then, time: time }
94
133
  end
95
134
 
96
135
  def now_in_milliseconds
97
136
  ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
98
137
  end
138
+
139
+ def map_transitions
140
+ duration = (now_in_milliseconds - root_started_at)
141
+
142
+ trace_id = Config.instance.trace_id.call
143
+
144
+ metadata = { duration: duration, ids_tree: tree.nested_ids, ids_matrix: tree.ids_matrix, trace_id: trace_id }
145
+
146
+ { version: Tracking::VERSION, records: records, metadata: metadata }
147
+ end
148
+
149
+ def build_listener
150
+ Config.instance.listener.new
151
+ rescue ::StandardError => e
152
+ err = "#{e.message} (#{e.class}); Backtrace: #{e.backtrace&.join(', ')}"
153
+
154
+ warn("Fallback to #{Listener::Null} because registered listener raised an exception: #{err}")
155
+
156
+ Listener::Null.new
157
+ end
99
158
  end
100
159
  end
@@ -6,14 +6,19 @@ class BCDD::Result
6
6
  require_relative 'tracking/enabled'
7
7
  require_relative 'tracking/disabled'
8
8
 
9
+ VERSION = 1
10
+
9
11
  EMPTY_ARRAY = [].freeze
10
12
  EMPTY_HASH = {}.freeze
11
13
  EMPTY_TREE = Tree.new(nil).freeze
12
- VERSION = 1
13
- EMPTY = { version: VERSION, records: EMPTY_ARRAY, metadata: { duration: 0, tree_map: EMPTY_ARRAY } }.freeze
14
+ EMPTY = {
15
+ version: VERSION,
16
+ records: EMPTY_ARRAY,
17
+ metadata: { duration: 0, ids_tree: EMPTY_ARRAY, ids_matrix: EMPTY_HASH, trace_id: nil }.freeze
18
+ }.freeze
14
19
 
15
20
  def self.instance
16
- Config.instance.feature.enabled?(:transitions) ? Tracking::Enabled.new : Tracking::Disabled
21
+ ::BCDD::Result::Config.instance.feature.enabled?(:transitions) ? Tracking::Enabled.new : Tracking::Disabled
17
22
  end
18
23
  end
19
24
  end
@@ -94,6 +94,32 @@ class BCDD::Result
94
94
  def nested_ids
95
95
  NestedIds[root]
96
96
  end
97
+
98
+ IdsMatrix = ->(tree, row, col, ids, previous) do
99
+ last_row = previous[0]
100
+
101
+ tree.each_with_index do |node, index|
102
+ row = [(index + 1), last_row].max
103
+
104
+ id, leaf = node
105
+
106
+ ids[id] = previous == [row, col] ? [row, col + 1] : [row, col]
107
+
108
+ previous = ids[id]
109
+
110
+ IdsMatrix[leaf, row, col + 1, ids, previous]
111
+ end
112
+ end
113
+
114
+ def ids_matrix
115
+ current = [0, 0]
116
+
117
+ ids = { 0 => current }
118
+
119
+ IdsMatrix[nested_ids[1], 1, 1, ids, current]
120
+
121
+ ids
122
+ end
97
123
  end
98
124
  end
99
125
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  class BCDD::Result
4
4
  module Transitions
5
+ require_relative 'transitions/listener'
6
+ require_relative 'transitions/listeners'
7
+ require_relative 'transitions/config'
5
8
  require_relative 'transitions/tree'
6
9
  require_relative 'transitions/tracking'
7
10
 
@@ -20,9 +23,5 @@ class BCDD::Result
20
23
 
21
24
  def self.transitions(name: nil, desc: nil, &block)
22
25
  Transitions.tracking.exec(name, desc, &block)
23
- rescue ::Exception => e
24
- Transitions.tracking.reset!
25
-
26
- raise e
27
26
  end
28
27
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.12.0'
5
+ VERSION = '0.13.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
3
4
  require 'singleton'
4
5
 
5
6
  require_relative 'result/version'
6
7
  require_relative 'result/error'
8
+ require_relative 'result/ignored_types'
7
9
  require_relative 'result/transitions'
8
10
  require_relative 'result/callable_and_then'
9
11
  require_relative 'result/data'
@@ -29,10 +31,10 @@ class BCDD::Result
29
31
  Config.instance
30
32
  end
31
33
 
32
- def self.configuration
34
+ def self.configuration(freeze: true)
33
35
  yield(config)
34
36
 
35
- config.freeze
37
+ freeze and config.freeze
36
38
  end
37
39
 
38
40
  def initialize(type:, value:, source: nil, expectations: nil, terminal: nil)
@@ -40,7 +42,7 @@ class BCDD::Result
40
42
 
41
43
  @type_checker = Contract.evaluate(data, expectations)
42
44
  @source = source
43
- @terminal = terminal || kind == :failure
45
+ @terminal = kind == :failure || (terminal && !IgnoredTypes.include?(type))
44
46
  @data = data
45
47
 
46
48
  self.unknown = true
@@ -153,7 +155,7 @@ class BCDD::Result
153
155
  def call_and_then_source_method(method_name, injected_value)
154
156
  method = source.method(method_name)
155
157
 
156
- Transitions.tracking.record_and_then(method, injected_value, source) do
158
+ Transitions.tracking.record_and_then(method, injected_value) do
157
159
  result = call_and_then_source_method!(method, injected_value)
158
160
 
159
161
  ensure_result_object(result, origin: :method)
@@ -170,7 +172,7 @@ class BCDD::Result
170
172
  end
171
173
 
172
174
  def call_and_then_block(block)
173
- Transitions.tracking.record_and_then(:block, nil, source) do
175
+ Transitions.tracking.record_and_then(:block, nil) do
174
176
  result = call_and_then_block!(block)
175
177
 
176
178
  ensure_result_object(result, origin: :block)
@@ -15,6 +15,7 @@ class BCDD::Result::Config
15
15
  def initialize: -> void
16
16
 
17
17
  def and_then!: () -> BCDD::Result::CallableAndThen::Config
18
+ def transitions: () -> BCDD::Result::Transitions::Config
18
19
 
19
20
  def freeze: -> BCDD::Result::Config
20
21
  def options: -> Hash[Symbol, BCDD::Result::Config::Switcher]
@@ -28,10 +28,19 @@ class BCDD::Result::Context < BCDD::Result
28
28
  def raise_unexpected_outcome_error: (BCDD::Result::Context | untyped, Symbol) -> void
29
29
  end
30
30
 
31
+ class BCDD::Result::Context
32
+ class Error < BCDD::Result::Error
33
+ class InvalidExposure < BCDD::Result::Context::Error
34
+ end
35
+ end
36
+ end
37
+
31
38
  class BCDD::Result::Context
32
39
  class Success < BCDD::Result::Context
33
40
  include BCDD::Result::Success::Methods
34
41
 
42
+ FetchValues: Proc
43
+
35
44
  def and_expose: (Symbol, Array[Symbol], terminal: bool) -> BCDD::Result::Context::Success
36
45
  end
37
46
 
@@ -0,0 +1,9 @@
1
+ class BCDD::Result
2
+ module IgnoredTypes
3
+ LIST: ::Set[::Symbol]
4
+ GIVEN: ::Symbol
5
+ CONTINUE: ::Symbol
6
+
7
+ def self.include?: (::Symbol) -> bool
8
+ end
9
+ end
@@ -1,5 +1,82 @@
1
1
  class BCDD::Result
2
2
  module Transitions
3
+ module Listener
4
+ module ClassMethods
5
+ def around_and_then?: () -> bool
6
+ def around_transitions?: () -> bool
7
+ end
8
+
9
+ extend ClassMethods
10
+
11
+ def around_transitions: (scope: Hash[Symbol, untyped]) { () -> untyped } -> untyped
12
+
13
+ def on_start: (scope: Hash[Symbol, untyped]) -> untyped
14
+
15
+ def around_and_then: (scope: Hash[Symbol, untyped], and_then: Hash[Symbol, untyped]) { () -> untyped } -> untyped
16
+
17
+ def on_record: (record: Hash[Symbol, untyped] ) -> untyped
18
+
19
+ def on_finish: (transitions: Hash[Symbol, untyped] ) -> untyped
20
+
21
+ def before_interruption: (exception: ::Exception, transitions: Hash[Symbol, untyped]) -> untyped
22
+ end
23
+
24
+ class Listeners
25
+ class Chain
26
+ include Listener
27
+
28
+ attr_reader listeners: Hash[Symbol, untyped]
29
+
30
+ def initialize: (Array[untyped]) -> void
31
+
32
+ def new: () -> Listeners
33
+
34
+ private
35
+
36
+ def listener?: (untyped, untyped) -> bool
37
+ end
38
+
39
+ def self.[]: (*untyped) -> Chain
40
+
41
+ private attr_reader listeners: Array[Listener]
42
+ private attr_reader around_and_then_listener: untyped
43
+ private attr_reader around_transitions_listener: untyped
44
+
45
+ def initialize: (Array[Listener], untyped, untyped) -> void
46
+
47
+ def around_transitions: (scope: Hash[Symbol, untyped]) { () -> untyped } -> untyped
48
+
49
+ def on_start: (scope: Hash[Symbol, untyped]) -> untyped
50
+
51
+ def around_and_then: (scope: Hash[Symbol, untyped], and_then: Hash[Symbol, untyped]) { () -> untyped } -> untyped
52
+
53
+ def on_record: (record: Hash[Symbol, untyped] ) -> untyped
54
+
55
+ def on_finish: (transitions: Hash[Symbol, untyped] ) -> untyped
56
+
57
+ def before_interruption: (exception: ::Exception, transitions: Hash[Symbol, untyped]) -> untyped
58
+ end
59
+
60
+ module Listener::Null
61
+ extend Listener
62
+
63
+ def self.new: () -> untyped
64
+ end
65
+
66
+ class Config
67
+ include ::Singleton
68
+
69
+ attr_reader listener: untyped
70
+ attr_reader trace_id: ::Proc
71
+
72
+ def self.instance: -> Config
73
+
74
+ def initialize: -> void
75
+
76
+ def listener=: (Listener) -> void
77
+ def trace_id=: (::Proc) -> void
78
+ end
79
+
3
80
  class Tree
4
81
  class Node
5
82
  attr_reader id: Integer
@@ -41,6 +118,10 @@ class BCDD::Result
41
118
  NestedIds: ^(Node) -> Array[untyped]
42
119
 
43
120
  def nested_ids: () -> Array[untyped]
121
+
122
+ IdsMatrix: ::Proc
123
+
124
+ def ids_matrix: () -> untyped
44
125
  end
45
126
 
46
127
  module Tracking
@@ -53,39 +134,47 @@ class BCDD::Result
53
134
  class Enabled
54
135
  private attr_accessor tree: Transitions::Tree
55
136
  private attr_accessor records: Array[Hash[Symbol, untyped]]
137
+ private attr_accessor listener: untyped
56
138
  private attr_accessor root_started_at: Integer
57
139
 
58
- def exec: (String, String) { () -> untyped } -> BCDD::Result
140
+ def exec: (untyped, untyped) { () -> untyped } -> untyped
141
+ def err!: (::Exception, untyped) -> void
59
142
  def reset!: () -> void
60
143
  def record: (BCDD::Result) -> void
61
- def record_and_then: ((untyped), untyped, untyped) { () -> BCDD::Result } -> BCDD::Result
144
+ def record_and_then: ((untyped), untyped) { () -> untyped } -> untyped
62
145
  def reset_and_then!: () -> void
63
146
 
64
147
  private
65
148
 
66
- def start: (String, String) -> void
67
- def finish: (BCDD::Result) -> void
149
+ def start: (String, String) -> [Transitions::Tree::Node, Hash[Symbol, untyped]]
150
+ def finish: (untyped) -> untyped
68
151
 
69
152
  TreeNodeValueNormalizer: ^(Integer, Array[untyped]) -> untyped
70
153
 
71
154
  def root_start: (Array[untyped]) -> void
72
155
 
73
156
  def track: (BCDD::Result, time: Time) -> void
157
+ def track_record: (BCDD::Result, Time) -> Hash[Symbol, untyped]
74
158
 
75
159
  def now_in_milliseconds: () -> Integer
160
+
161
+ def map_transitions: () -> Hash[Symbol, untyped]
162
+
163
+ def build_listener: () -> Listener
76
164
  end
77
165
 
78
166
  module Disabled
79
- def self.exec: (String, String) { () -> untyped } -> BCDD::Result
167
+ def self.exec: (untyped, untyped) { () -> untyped } -> untyped
168
+ def self.err!: (::Exception) -> void
80
169
  def self.reset!: () -> void
81
170
  def self.record: (BCDD::Result) -> void
82
- def self.record_and_then: ((untyped), untyped, untyped) { () -> BCDD::Result } -> BCDD::Result
171
+ def self.record_and_then: ((untyped), untyped) { () -> BCDD::Result } -> BCDD::Result
83
172
  def self.reset_and_then!: () -> void
84
173
 
85
174
  private
86
175
 
87
176
  def self.start: (String, String) -> void
88
- def self.finish: (BCDD::Result) -> void
177
+ def self.finish: (untyped) -> untyped
89
178
  end
90
179
 
91
180
  def self.instance: () -> (Enabled | singleton(Disabled))
data/sig/bcdd/result.rbs CHANGED
@@ -9,8 +9,8 @@ class BCDD::Result
9
9
  attr_reader transitions: Hash[Symbol, untyped]
10
10
 
11
11
  def self.config: -> BCDD::Result::Config
12
- def self.configuration: { (BCDD::Result::Config) -> void } -> BCDD::Result::Config
13
- def self.transitions: { () -> untyped } -> BCDD::Result
12
+ def self.configuration: (freeze: bool) { (BCDD::Result::Config) -> void } -> (bool | BCDD::Result::Config)
13
+ def self.transitions: (name: untyped, desc: untyped) { () -> untyped } -> BCDD::Result
14
14
 
15
15
  def initialize: (
16
16
  type: Symbol,