bcdd-result 0.10.0 → 0.12.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -15
  3. data/README.md +326 -67
  4. data/Rakefile +8 -2
  5. data/lib/bcdd/result/callable_and_then/caller.rb +49 -0
  6. data/lib/bcdd/result/callable_and_then/config.rb +15 -0
  7. data/lib/bcdd/result/callable_and_then/error.rb +11 -0
  8. data/lib/bcdd/result/callable_and_then.rb +9 -0
  9. data/lib/bcdd/result/config/switchers/addons.rb +9 -4
  10. data/lib/bcdd/result/config/switchers/features.rb +5 -1
  11. data/lib/bcdd/result/config.rb +9 -3
  12. data/lib/bcdd/result/context/callable_and_then.rb +39 -0
  13. data/lib/bcdd/result/context/expectations/mixin.rb +11 -3
  14. data/lib/bcdd/result/context/mixin.rb +13 -5
  15. data/lib/bcdd/result/context/success.rb +12 -8
  16. data/lib/bcdd/result/context.rb +34 -16
  17. data/lib/bcdd/result/error.rb +20 -11
  18. data/lib/bcdd/result/expectations/mixin.rb +12 -6
  19. data/lib/bcdd/result/expectations.rb +7 -7
  20. data/lib/bcdd/result/mixin.rb +11 -5
  21. data/lib/bcdd/result/transitions/tracking/disabled.rb +14 -4
  22. data/lib/bcdd/result/transitions/tracking/enabled.rb +38 -18
  23. data/lib/bcdd/result/transitions/tree.rb +10 -6
  24. data/lib/bcdd/result/transitions.rb +8 -10
  25. data/lib/bcdd/result/version.rb +1 -1
  26. data/lib/bcdd/result.rb +38 -23
  27. data/sig/bcdd/result/callable_and_then.rbs +60 -0
  28. data/sig/bcdd/result/config.rbs +3 -0
  29. data/sig/bcdd/result/context.rbs +73 -9
  30. data/sig/bcdd/result/error.rbs +9 -6
  31. data/sig/bcdd/result/expectations.rbs +12 -8
  32. data/sig/bcdd/result/mixin.rbs +10 -2
  33. data/sig/bcdd/result/transitions.rbs +16 -5
  34. data/sig/bcdd/result.rbs +12 -8
  35. metadata +8 -2
@@ -6,26 +6,18 @@ module BCDD::Result::Transitions
6
6
 
7
7
  private :tree, :tree=, :records, :records=, :root_started_at, :root_started_at=
8
8
 
9
- def start(name:, desc:)
10
- name_and_desc = [name, desc]
11
-
12
- tree.frozen? ? root_start(name_and_desc) : tree.insert!(name_and_desc)
13
- end
14
-
15
- def finish(result:)
16
- node = tree.current
9
+ def exec(name, desc)
10
+ start(name, desc)
17
11
 
18
- tree.move_up!
12
+ transition_node = tree.current
19
13
 
20
- return unless node.root?
14
+ result = EnsureResult[yield]
21
15
 
22
- duration = (now_in_milliseconds - root_started_at)
16
+ tree.move_to_root! if transition_node.root?
23
17
 
24
- metadata = { duration: duration, tree_map: tree.nested_ids }
18
+ finish(result)
25
19
 
26
- result.send(:transitions=, version: Tracking::VERSION, records: records, metadata: metadata)
27
-
28
- reset!
20
+ result
29
21
  end
30
22
 
31
23
  def reset!
@@ -38,11 +30,11 @@ module BCDD::Result::Transitions
38
30
  track(result, time: ::Time.now.getutc)
39
31
  end
40
32
 
41
- def record_and_then(type_arg, arg, subject)
33
+ def record_and_then(type_arg, arg, source)
42
34
  type = type_arg.instance_of?(::Method) ? :method : type_arg
43
35
 
44
36
  unless tree.frozen?
45
- current_and_then = { type: type, arg: arg, subject: subject }
37
+ current_and_then = { type: type, arg: arg, source: source }
46
38
  current_and_then[:method_name] = type_arg.name if type == :method
47
39
 
48
40
  tree.current.value[1] = current_and_then
@@ -51,8 +43,36 @@ module BCDD::Result::Transitions
51
43
  yield
52
44
  end
53
45
 
46
+ def reset_and_then!
47
+ return if tree.frozen?
48
+
49
+ tree.current.value[1] = Tracking::EMPTY_HASH
50
+ end
51
+
54
52
  private
55
53
 
54
+ def start(name, desc)
55
+ name_and_desc = [name, desc]
56
+
57
+ tree.frozen? ? root_start(name_and_desc) : tree.insert!(name_and_desc)
58
+ end
59
+
60
+ def finish(result)
61
+ node = tree.current
62
+
63
+ tree.move_up!
64
+
65
+ return unless node.root?
66
+
67
+ duration = (now_in_milliseconds - root_started_at)
68
+
69
+ metadata = { duration: duration, tree_map: tree.nested_ids }
70
+
71
+ result.send(:transitions=, version: Tracking::VERSION, records: records, metadata: metadata)
72
+
73
+ reset!
74
+ end
75
+
56
76
  TreeNodeValueNormalizer = ->(id, (nam, des)) { [{ id: id, name: nam, desc: des }, Tracking::EMPTY_HASH] }
57
77
 
58
78
  def root_start(name_and_desc)
@@ -74,7 +94,7 @@ module BCDD::Result::Transitions
74
94
  end
75
95
 
76
96
  def now_in_milliseconds
77
- Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
97
+ ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :millisecond)
78
98
  end
79
99
  end
80
100
  end
@@ -46,9 +46,9 @@ class BCDD::Result
46
46
  def initialize(value, normalizer: ->(_id, val) { val })
47
47
  @size = 0
48
48
 
49
- @root = Node.new(value, parent: nil, id: @size, normalizer: normalizer)
49
+ @root = Node.new(value, parent: nil, id: size, normalizer: normalizer)
50
50
 
51
- @current = @root
51
+ @current = root
52
52
  end
53
53
 
54
54
  def root_value
@@ -70,19 +70,23 @@ class BCDD::Result
70
70
  end
71
71
 
72
72
  def insert!(value)
73
- @current = insert(value)
73
+ move_to! insert(value)
74
+ end
75
+
76
+ def move_to!(node)
77
+ tap { @current = node }
74
78
  end
75
79
 
76
80
  def move_up!(level = 1)
77
- tap { level.times { @current = current.parent || root } }
81
+ tap { level.times { move_to!(current.parent || root) } }
78
82
  end
79
83
 
80
84
  def move_down!(level = 1, index: -1)
81
- tap { level.times { current.children[index].then { |child| @current = child if child } } }
85
+ tap { level.times { current.children[index].then { |child| move_to!(child) if child } } }
82
86
  end
83
87
 
84
88
  def move_to_root!
85
- tap { @current = root }
89
+ move_to!(root)
86
90
  end
87
91
 
88
92
  NestedIds = ->(node) { [node.id, node.children.map(&NestedIds)] }
@@ -7,21 +7,19 @@ class BCDD::Result
7
7
 
8
8
  THREAD_VAR_NAME = :bcdd_result_transitions_tracking
9
9
 
10
+ EnsureResult = ->(result) do
11
+ return result if result.is_a?(::BCDD::Result)
12
+
13
+ raise Error::UnexpectedOutcome.build(outcome: result, origin: :transitions)
14
+ end
15
+
10
16
  def self.tracking
11
17
  Thread.current[THREAD_VAR_NAME] ||= Tracking.instance
12
18
  end
13
19
  end
14
20
 
15
- def self.transitions(name: nil, desc: nil)
16
- Transitions.tracking.start(name: name, desc: desc)
17
-
18
- result = yield
19
-
20
- result.is_a?(::BCDD::Result) or raise Error::UnexpectedOutcome.build(outcome: result, origin: :transitions)
21
-
22
- Transitions.tracking.finish(result: result)
23
-
24
- result
21
+ def self.transitions(name: nil, desc: nil, &block)
22
+ Transitions.tracking.exec(name, desc, &block)
25
23
  rescue ::Exception => e
26
24
  Transitions.tracking.reset!
27
25
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.10.0'
5
+ VERSION = '0.12.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'singleton'
4
+
3
5
  require_relative 'result/version'
4
- require_relative 'result/transitions'
5
6
  require_relative 'result/error'
7
+ require_relative 'result/transitions'
8
+ require_relative 'result/callable_and_then'
6
9
  require_relative 'result/data'
7
10
  require_relative 'result/handler'
8
11
  require_relative 'result/failure'
@@ -16,9 +19,9 @@ require_relative 'result/config'
16
19
  class BCDD::Result
17
20
  attr_accessor :unknown, :transitions
18
21
 
19
- attr_reader :subject, :data, :type_checker, :halted
22
+ attr_reader :source, :data, :type_checker, :terminal
20
23
 
21
- protected :subject
24
+ protected :source
22
25
 
23
26
  private :unknown, :unknown=, :type_checker, :transitions=
24
27
 
@@ -32,12 +35,12 @@ class BCDD::Result
32
35
  config.freeze
33
36
  end
34
37
 
35
- def initialize(type:, value:, subject: nil, expectations: nil, halted: nil)
38
+ def initialize(type:, value:, source: nil, expectations: nil, terminal: nil)
36
39
  data = Data.new(kind, type, value)
37
40
 
38
41
  @type_checker = Contract.evaluate(data, expectations)
39
- @subject = subject
40
- @halted = halted || kind == :failure
42
+ @source = source
43
+ @terminal = terminal || kind == :failure
41
44
  @data = data
42
45
 
43
46
  self.unknown = true
@@ -46,8 +49,8 @@ class BCDD::Result
46
49
  Transitions.tracking.record(self)
47
50
  end
48
51
 
49
- def halted?
50
- halted
52
+ def terminal?
53
+ terminal
51
54
  end
52
55
 
53
56
  def type
@@ -88,12 +91,20 @@ class BCDD::Result
88
91
  tap { yield(value, type) if unknown }
89
92
  end
90
93
 
91
- def and_then(method_name = nil, context = nil, &block)
92
- return self if halted?
94
+ def and_then(method_name = nil, injected_value = nil, &block)
95
+ return self if terminal?
93
96
 
94
97
  method_name && block and raise ::ArgumentError, 'method_name and block are mutually exclusive'
95
98
 
96
- method_name ? call_and_then_subject_method(method_name, context) : call_and_then_block(block)
99
+ method_name ? call_and_then_source_method(method_name, injected_value) : call_and_then_block(block)
100
+ end
101
+
102
+ def and_then!(source, injected_value = nil, _call: nil)
103
+ raise Error::CallableAndThenDisabled unless Config.instance.feature.enabled?(:and_then!)
104
+
105
+ return self if terminal?
106
+
107
+ call_and_then_callable!(source, value: value, injected_value: injected_value, method_name: _call)
97
108
  end
98
109
 
99
110
  def handle
@@ -139,27 +150,27 @@ class BCDD::Result
139
150
  block.call(value, type)
140
151
  end
141
152
 
142
- def call_and_then_subject_method(method_name, context_data)
143
- method = subject.method(method_name)
153
+ def call_and_then_source_method(method_name, injected_value)
154
+ method = source.method(method_name)
144
155
 
145
- Transitions.tracking.record_and_then(method, context_data, subject) do
146
- result = call_and_then_subject_method!(method, context_data)
156
+ Transitions.tracking.record_and_then(method, injected_value, source) do
157
+ result = call_and_then_source_method!(method, injected_value)
147
158
 
148
159
  ensure_result_object(result, origin: :method)
149
160
  end
150
161
  end
151
162
 
152
- def call_and_then_subject_method!(method, context_data)
163
+ def call_and_then_source_method!(method, injected_value)
153
164
  case method.arity
154
- when 0 then subject.send(method.name)
155
- when 1 then subject.send(method.name, value)
156
- when 2 then subject.send(method.name, value, context_data)
157
- else raise Error::InvalidSubjectMethodArity.build(subject: subject, method: method, max_arity: 2)
165
+ when 0 then source.send(method.name)
166
+ when 1 then source.send(method.name, value)
167
+ when 2 then source.send(method.name, value, injected_value)
168
+ else raise Error::InvalidSourceMethodArity.build(source: source, method: method, max_arity: 2)
158
169
  end
159
170
  end
160
171
 
161
172
  def call_and_then_block(block)
162
- Transitions.tracking.record_and_then(:block, nil, subject) do
173
+ Transitions.tracking.record_and_then(:block, nil, source) do
163
174
  result = call_and_then_block!(block)
164
175
 
165
176
  ensure_result_object(result, origin: :block)
@@ -170,11 +181,15 @@ class BCDD::Result
170
181
  block.call(value)
171
182
  end
172
183
 
184
+ def call_and_then_callable!(source, value:, injected_value:, method_name:)
185
+ CallableAndThen::Caller.call(source, value: value, injected_value: injected_value, method_name: method_name)
186
+ end
187
+
173
188
  def ensure_result_object(result, origin:)
174
189
  raise Error::UnexpectedOutcome.build(outcome: result, origin: origin) unless result.is_a?(::BCDD::Result)
175
190
 
176
- return result if result.subject.equal?(subject)
191
+ return result if result.source.equal?(source)
177
192
 
178
- raise Error::InvalidResultSubject.build(given_result: result, expected_subject: subject)
193
+ raise Error::InvalidResultSource.build(given_result: result, expected_source: source)
179
194
  end
180
195
  end
@@ -0,0 +1,60 @@
1
+ module BCDD::Result::CallableAndThen
2
+ class Config
3
+ attr_accessor default_method_name_to_call: Symbol
4
+
5
+ def initialize: -> void
6
+
7
+ def options: () -> Hash[Symbol, untyped]
8
+ end
9
+
10
+ class Error < BCDD::Result::Error
11
+ end
12
+
13
+ class Error::InvalidArity < Error
14
+ def self.build: (
15
+ source: untyped,
16
+ method: Symbol,
17
+ arity: String
18
+ ) -> Error::InvalidArity
19
+ end
20
+
21
+ class Caller
22
+ def self.call: (
23
+ untyped source,
24
+ value: untyped,
25
+ injected_value: untyped,
26
+ method_name: (Symbol | nil)
27
+ ) -> BCDD::Result
28
+
29
+ private
30
+
31
+ def self.call_proc!: (
32
+ untyped source,
33
+ untyped value,
34
+ untyped injected_value
35
+ ) -> BCDD::Result
36
+
37
+ def self.call_method!: (
38
+ untyped source,
39
+ Method method,
40
+ untyped value,
41
+ untyped injected_value
42
+ ) -> BCDD::Result
43
+
44
+ def self.callable_method: (
45
+ untyped source,
46
+ (Symbol | nil) method_name
47
+ ) -> ::Method
48
+
49
+ def self.ensure_result_object: (
50
+ untyped source,
51
+ untyped value,
52
+ BCDD::Result result
53
+ ) -> BCDD::Result
54
+
55
+ def self.expected_result_object: () -> singleton(BCDD::Result)
56
+
57
+ def self.expected_outcome: () -> String
58
+ end
59
+ end
60
+
@@ -14,6 +14,8 @@ class BCDD::Result::Config
14
14
 
15
15
  def initialize: -> void
16
16
 
17
+ def and_then!: () -> BCDD::Result::CallableAndThen::Config
18
+
17
19
  def freeze: -> BCDD::Result::Config
18
20
  def options: -> Hash[Symbol, BCDD::Result::Config::Switcher]
19
21
  def to_h: -> Hash[Symbol, Hash[Symbol | String, bool]]
@@ -73,6 +75,7 @@ class BCDD::Result::Config::Switcher
73
75
  end
74
76
 
75
77
  module BCDD::Result::Config::Addons
78
+ AFFECTS: Array[String]
76
79
  OPTIONS: Hash[String, Hash[Symbol, untyped]]
77
80
 
78
81
  def self.switcher: -> BCDD::Result::Config::Switcher
@@ -1,23 +1,28 @@
1
1
  class BCDD::Result::Context < BCDD::Result
2
2
  EXPECTED_OUTCOME: String
3
3
 
4
- SubjectMethodArity: ^(Method) -> Integer
4
+ SourceMethodArity: ^(Method) -> Integer
5
5
 
6
6
  attr_reader acc: Hash[Symbol, untyped]
7
7
 
8
8
  def initialize: (
9
9
  type: Symbol,
10
10
  value: untyped,
11
- ?subject: untyped,
11
+ ?source: untyped,
12
12
  ?expectations: BCDD::Result::Contract::Evaluator,
13
- ?halted: bool
13
+ ?terminal: bool
14
14
  ) -> void
15
15
 
16
- def and_then: (?Symbol, **untyped) ?{ (Hash[Symbol, untyped]) -> untyped } -> BCDD::Result::Context
16
+ def and_then: (?Symbol, **untyped) ?{ (Hash[Symbol, untyped]) -> untyped } -> untyped
17
+
18
+ def and_then!: (untyped, **untyped) -> untyped
17
19
 
18
20
  private
19
21
 
20
- def call_and_then_subject_method: (Symbol, Hash[Symbol, untyped]) -> BCDD::Result::Context
22
+ def call_and_then_source_method: (Symbol, Hash[Symbol, untyped]) -> BCDD::Result::Context
23
+
24
+ def call_and_then_callable!: (untyped, value: untyped, injected_value: untyped, method_name: (Symbol | nil)) -> BCDD::Result::Context
25
+
21
26
  def ensure_result_object: (untyped, origin: Symbol) -> BCDD::Result::Context
22
27
 
23
28
  def raise_unexpected_outcome_error: (BCDD::Result::Context | untyped, Symbol) -> void
@@ -27,12 +32,59 @@ class BCDD::Result::Context
27
32
  class Success < BCDD::Result::Context
28
33
  include BCDD::Result::Success::Methods
29
34
 
30
- def and_expose: (Symbol, Array[Symbol], halted: bool) -> BCDD::Result::Context::Success
35
+ def and_expose: (Symbol, Array[Symbol], terminal: bool) -> BCDD::Result::Context::Success
31
36
  end
32
37
 
33
38
  def self.Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
34
39
  end
35
40
 
41
+ module BCDD::Result::Context::CallableAndThen
42
+ class Caller < BCDD::Result::CallableAndThen::Caller
43
+ module KeyArgs
44
+ def self.parameters?: (untyped) -> bool
45
+
46
+ def self.invalid_arity: (untyped, Symbol) -> BCDD::Result::CallableAndThen::Error::InvalidArity
47
+ end
48
+
49
+ def self.call: (
50
+ untyped source,
51
+ value: untyped,
52
+ injected_value: untyped,
53
+ method_name: (Symbol | nil),
54
+ ) -> BCDD::Result::Context
55
+
56
+ private
57
+
58
+ def self.call_proc!: (
59
+ untyped source,
60
+ Hash[Symbol, untyped] value,
61
+ nil injected_value
62
+ ) -> BCDD::Result::Context
63
+
64
+ def self.call_method!: (
65
+ untyped source,
66
+ Method method,
67
+ Hash[Symbol, untyped] value,
68
+ nil injected_value
69
+ ) -> BCDD::Result::Context
70
+
71
+ def self.callable_method: (
72
+ untyped source,
73
+ (Symbol | nil) method_name
74
+ ) -> ::Method
75
+
76
+ def self.ensure_result_object: (
77
+ untyped source,
78
+ untyped value,
79
+ BCDD::Result::Context result
80
+ ) -> BCDD::Result::Context
81
+
82
+ def self.expected_result_object: () -> singleton(BCDD::Result::Context)
83
+
84
+ def self.expected_outcome: () -> String
85
+ end
86
+ end
87
+
36
88
  class BCDD::Result::Context
37
89
  class Failure < BCDD::Result::Context
38
90
  include BCDD::Result::Failure::Methods
@@ -54,11 +106,11 @@ class BCDD::Result::Context
54
106
 
55
107
  private
56
108
 
57
- def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?halted: bool) -> untyped
109
+ def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?terminal: bool) -> untyped
58
110
  end
59
111
 
60
112
  module Addons
61
- module Continuable
113
+ module Continue
62
114
  include BCDD::Result::Context::Mixin::Methods
63
115
 
64
116
  private
@@ -66,6 +118,14 @@ class BCDD::Result::Context
66
118
  def Continue: (**untyped) -> BCDD::Result::Context::Success
67
119
  end
68
120
 
121
+ module Given
122
+ include BCDD::Result::Context::Mixin::Methods
123
+
124
+ private
125
+
126
+ def Given: (*untyped) -> BCDD::Result::Context::Success
127
+ end
128
+
69
129
  OPTIONS: Hash[Symbol, Module]
70
130
 
71
131
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -91,10 +151,14 @@ module BCDD::Result::Context::Expectations::Mixin
91
151
  Factory: singleton(BCDD::Result::Expectations::Mixin::Factory)
92
152
 
93
153
  module Addons
94
- module Continuable
154
+ module Continue
95
155
  private def Continue: (**untyped) -> BCDD::Result::Context::Success
96
156
  end
97
157
 
158
+ module Given
159
+ private def Given: (*untyped) -> BCDD::Result::Context::Success
160
+ end
161
+
98
162
  OPTIONS: Hash[Symbol, Module]
99
163
 
100
164
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -13,19 +13,22 @@ class BCDD::Result
13
13
  -> BCDD::Result::Error::UnexpectedOutcome
14
14
  end
15
15
 
16
- class InvalidResultSubject < BCDD::Result::Error
17
- def self.build: (given_result: BCDD::Result, expected_subject: untyped)
18
- -> BCDD::Result::Error::InvalidResultSubject
16
+ class InvalidResultSource < BCDD::Result::Error
17
+ def self.build: (given_result: BCDD::Result, expected_source: untyped)
18
+ -> BCDD::Result::Error::InvalidResultSource
19
19
  end
20
20
 
21
- class InvalidSubjectMethodArity < BCDD::Result::Error
22
- def self.build: (subject: untyped, method: Method, max_arity: Integer)
23
- -> BCDD::Result::Error::InvalidSubjectMethodArity
21
+ class InvalidSourceMethodArity < BCDD::Result::Error
22
+ def self.build: (source: untyped, method: Method, max_arity: Integer)
23
+ -> BCDD::Result::Error::InvalidSourceMethodArity
24
24
  end
25
25
 
26
26
  class UnhandledTypes < BCDD::Result::Error
27
27
  def self.build: (types: Set[Symbol])
28
28
  -> BCDD::Result::Error::UnhandledTypes
29
29
  end
30
+
31
+ class CallableAndThenDisabled < BCDD::Result::Error
32
+ end
30
33
  end
31
34
  end
@@ -16,31 +16,31 @@ class BCDD::Result::Expectations
16
16
  def self.result_factory_without_expectations: -> singleton(BCDD::Result)
17
17
 
18
18
  def self.new: (
19
- ?subject: untyped,
19
+ ?source: untyped,
20
20
  ?contract: BCDD::Result::Contract::Evaluator,
21
- ?halted: bool,
21
+ ?terminal: bool,
22
22
  **untyped
23
23
  ) -> (BCDD::Result::Expectations | untyped)
24
24
 
25
25
  def initialize: (
26
- ?subject: untyped,
26
+ ?source: untyped,
27
27
  ?contract: BCDD::Result::Contract::Evaluator,
28
- ?halted: bool,
28
+ ?terminal: bool,
29
29
  **untyped
30
30
  ) -> void
31
31
 
32
32
  def Success: (Symbol, ?untyped) -> BCDD::Result::Success
33
33
  def Failure: (Symbol, ?untyped) -> BCDD::Result::Failure
34
34
 
35
- def with: (subject: untyped) -> BCDD::Result::Expectations
35
+ def with: (source: untyped) -> BCDD::Result::Expectations
36
36
 
37
37
  private
38
38
 
39
39
  def _ResultAs: (singleton(BCDD::Result), Symbol, untyped) -> untyped
40
40
 
41
- attr_reader subject: untyped
41
+ attr_reader source: untyped
42
42
  attr_reader contract: BCDD::Result::Contract::Evaluator
43
- attr_reader halted: bool
43
+ attr_reader terminal: bool
44
44
  end
45
45
 
46
46
  module BCDD::Result::Expectations::Mixin
@@ -56,10 +56,14 @@ module BCDD::Result::Expectations::Mixin
56
56
  end
57
57
 
58
58
  module Addons
59
- module Continuable
59
+ module Continue
60
60
  private def Continue: (untyped) -> BCDD::Result::Success
61
61
  end
62
62
 
63
+ module Given
64
+ private def Given: (untyped) -> BCDD::Result::Success
65
+ end
66
+
63
67
  OPTIONS: Hash[Symbol, Module]
64
68
 
65
69
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -11,11 +11,11 @@ class BCDD::Result
11
11
 
12
12
  private
13
13
 
14
- def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?halted: bool) -> untyped
14
+ def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?terminal: bool) -> untyped
15
15
  end
16
16
 
17
17
  module Addons
18
- module Continuable
18
+ module Continue
19
19
  include BCDD::Result::Mixin::Methods
20
20
 
21
21
  private
@@ -23,6 +23,14 @@ class BCDD::Result
23
23
  def Continue: (untyped) -> BCDD::Result::Success
24
24
  end
25
25
 
26
+ module Given
27
+ include BCDD::Result::Mixin::Methods
28
+
29
+ private
30
+
31
+ def Given: (untyped) -> BCDD::Result::Success
32
+ end
33
+
26
34
  OPTIONS: Hash[Symbol, Module]
27
35
 
28
36
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -32,7 +32,8 @@ class BCDD::Result
32
32
  def parent_value: () -> untyped
33
33
  def current_value: () -> untyped
34
34
  def insert: (untyped) -> Node
35
- def insert!: (untyped) -> Node
35
+ def insert!: (untyped) -> Tree
36
+ def move_to!: (Node) -> Tree
36
37
  def move_up!: (?Integer level) -> Tree
37
38
  def move_down!: (?Integer level) -> Tree
38
39
  def move_to_root!: () -> Tree
@@ -54,14 +55,17 @@ class BCDD::Result
54
55
  private attr_accessor records: Array[Hash[Symbol, untyped]]
55
56
  private attr_accessor root_started_at: Integer
56
57
 
57
- def start: (name: String, desc: String) -> void
58
- def finish: (result: BCDD::Result) -> void
58
+ def exec: (String, String) { () -> untyped } -> BCDD::Result
59
59
  def reset!: () -> void
60
60
  def record: (BCDD::Result) -> void
61
61
  def record_and_then: ((untyped), untyped, untyped) { () -> BCDD::Result } -> BCDD::Result
62
+ def reset_and_then!: () -> void
62
63
 
63
64
  private
64
65
 
66
+ def start: (String, String) -> void
67
+ def finish: (BCDD::Result) -> void
68
+
65
69
  TreeNodeValueNormalizer: ^(Integer, Array[untyped]) -> untyped
66
70
 
67
71
  def root_start: (Array[untyped]) -> void
@@ -72,11 +76,16 @@ class BCDD::Result
72
76
  end
73
77
 
74
78
  module Disabled
75
- def self.start: (name: String, desc: String) -> void
76
- def self.finish: (result: BCDD::Result) -> void
79
+ def self.exec: (String, String) { () -> untyped } -> BCDD::Result
77
80
  def self.reset!: () -> void
78
81
  def self.record: (BCDD::Result) -> void
79
82
  def self.record_and_then: ((untyped), untyped, untyped) { () -> BCDD::Result } -> BCDD::Result
83
+ def self.reset_and_then!: () -> void
84
+
85
+ private
86
+
87
+ def self.start: (String, String) -> void
88
+ def self.finish: (BCDD::Result) -> void
80
89
  end
81
90
 
82
91
  def self.instance: () -> (Enabled | singleton(Disabled))
@@ -84,6 +93,8 @@ class BCDD::Result
84
93
 
85
94
  THREAD_VAR_NAME: Symbol
86
95
 
96
+ EnsureResult: ^(untyped) -> BCDD::Result
97
+
87
98
  def self.tracking: () -> (Tracking::Enabled | singleton(Tracking::Disabled))
88
99
  end
89
100
  end