bcdd-result 0.9.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +43 -16
- data/README.md +259 -40
- data/Rakefile +8 -2
- data/Steepfile +2 -2
- data/lib/bcdd/result/config/switchers/addons.rb +25 -0
- data/lib/bcdd/result/config/{constant_alias.rb → switchers/constant_aliases.rb} +4 -4
- data/lib/bcdd/result/config/switchers/features.rb +28 -0
- data/lib/bcdd/result/config/switchers/pattern_matching.rb +20 -0
- data/lib/bcdd/result/config.rb +8 -28
- data/lib/bcdd/result/context/expectations/mixin.rb +10 -2
- data/lib/bcdd/result/context/mixin.rb +13 -5
- data/lib/bcdd/result/context/success.rb +2 -2
- data/lib/bcdd/result/context.rb +10 -15
- data/lib/bcdd/result/expectations/mixin.rb +11 -5
- data/lib/bcdd/result/expectations.rb +6 -6
- data/lib/bcdd/result/mixin.rb +11 -5
- data/lib/bcdd/result/transitions/tracking/disabled.rb +17 -0
- data/lib/bcdd/result/transitions/tracking/enabled.rb +80 -0
- data/lib/bcdd/result/transitions/tracking.rb +20 -0
- data/lib/bcdd/result/transitions/tree.rb +95 -0
- data/lib/bcdd/result/transitions.rb +30 -0
- data/lib/bcdd/result/version.rb +1 -1
- data/lib/bcdd/result.rb +33 -22
- data/sig/bcdd/result/config.rbs +101 -0
- data/sig/bcdd/result/context.rbs +114 -0
- data/sig/bcdd/result/contract.rbs +119 -0
- data/sig/bcdd/result/data.rbs +16 -0
- data/sig/bcdd/result/error.rbs +31 -0
- data/sig/bcdd/result/expectations.rbs +71 -0
- data/sig/bcdd/result/handler.rbs +47 -0
- data/sig/bcdd/result/mixin.rbs +45 -0
- data/sig/bcdd/result/transitions.rbs +89 -0
- data/sig/bcdd/result/version.rbs +5 -0
- data/sig/bcdd/result.rbs +7 -519
- metadata +22 -4
data/lib/bcdd/result.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'result/version'
|
4
|
+
require_relative 'result/transitions'
|
4
5
|
require_relative 'result/error'
|
5
6
|
require_relative 'result/data'
|
6
7
|
require_relative 'result/handler'
|
@@ -13,13 +14,13 @@ require_relative 'result/context'
|
|
13
14
|
require_relative 'result/config'
|
14
15
|
|
15
16
|
class BCDD::Result
|
16
|
-
attr_accessor :unknown
|
17
|
+
attr_accessor :unknown, :transitions
|
17
18
|
|
18
|
-
attr_reader :subject, :data, :type_checker, :
|
19
|
+
attr_reader :subject, :data, :type_checker, :terminal
|
19
20
|
|
20
21
|
protected :subject
|
21
22
|
|
22
|
-
private :unknown, :unknown=, :type_checker
|
23
|
+
private :unknown, :unknown=, :type_checker, :transitions=
|
23
24
|
|
24
25
|
def self.config
|
25
26
|
Config.instance
|
@@ -31,19 +32,22 @@ class BCDD::Result
|
|
31
32
|
config.freeze
|
32
33
|
end
|
33
34
|
|
34
|
-
def initialize(type:, value:, subject: nil, expectations: nil,
|
35
|
+
def initialize(type:, value:, subject: nil, expectations: nil, terminal: nil)
|
35
36
|
data = Data.new(kind, type, value)
|
36
37
|
|
37
38
|
@type_checker = Contract.evaluate(data, expectations)
|
38
39
|
@subject = subject
|
39
|
-
@
|
40
|
+
@terminal = terminal || kind == :failure
|
40
41
|
@data = data
|
41
42
|
|
42
43
|
self.unknown = true
|
44
|
+
self.transitions = Transitions::Tracking::EMPTY
|
45
|
+
|
46
|
+
Transitions.tracking.record(self)
|
43
47
|
end
|
44
48
|
|
45
|
-
def
|
46
|
-
|
49
|
+
def terminal?
|
50
|
+
terminal
|
47
51
|
end
|
48
52
|
|
49
53
|
def type
|
@@ -85,7 +89,7 @@ class BCDD::Result
|
|
85
89
|
end
|
86
90
|
|
87
91
|
def and_then(method_name = nil, context = nil, &block)
|
88
|
-
return self if
|
92
|
+
return self if terminal?
|
89
93
|
|
90
94
|
method_name && block and raise ::ArgumentError, 'method_name and block are mutually exclusive'
|
91
95
|
|
@@ -135,28 +139,35 @@ class BCDD::Result
|
|
135
139
|
block.call(value, type)
|
136
140
|
end
|
137
141
|
|
138
|
-
def call_and_then_subject_method(method_name,
|
142
|
+
def call_and_then_subject_method(method_name, context_data)
|
139
143
|
method = subject.method(method_name)
|
140
144
|
|
141
|
-
|
142
|
-
|
143
|
-
when 0 then subject.send(method_name)
|
144
|
-
when 1 then subject.send(method_name, value)
|
145
|
-
when 2 then subject.send(method_name, value, context)
|
146
|
-
else raise Error::InvalidSubjectMethodArity.build(subject: subject, method: method, max_arity: 2)
|
147
|
-
end
|
145
|
+
Transitions.tracking.record_and_then(method, context_data, subject) do
|
146
|
+
result = call_and_then_subject_method!(method, context_data)
|
148
147
|
|
149
|
-
|
148
|
+
ensure_result_object(result, origin: :method)
|
149
|
+
end
|
150
150
|
end
|
151
151
|
|
152
|
-
def
|
153
|
-
|
152
|
+
def call_and_then_subject_method!(method, context_data)
|
153
|
+
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)
|
158
|
+
end
|
154
159
|
end
|
155
160
|
|
156
|
-
def call_and_then_block
|
157
|
-
|
161
|
+
def call_and_then_block(block)
|
162
|
+
Transitions.tracking.record_and_then(:block, nil, subject) do
|
163
|
+
result = call_and_then_block!(block)
|
164
|
+
|
165
|
+
ensure_result_object(result, origin: :block)
|
166
|
+
end
|
167
|
+
end
|
158
168
|
|
159
|
-
|
169
|
+
def call_and_then_block!(block)
|
170
|
+
block.call(value)
|
160
171
|
end
|
161
172
|
|
162
173
|
def ensure_result_object(result, origin:)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
class BCDD::Result::Config
|
2
|
+
include Singleton
|
3
|
+
|
4
|
+
ADDON: Hash[Symbol, Hash[Symbol, untyped]]
|
5
|
+
FEATURE: Hash[Symbol, Hash[Symbol, untyped]]
|
6
|
+
PATTERN_MATCHING: Hash[Symbol, Hash[Symbol, untyped]]
|
7
|
+
|
8
|
+
attr_reader addon: BCDD::Result::Config::Switcher
|
9
|
+
attr_reader feature: BCDD::Result::Config::Switcher
|
10
|
+
attr_reader constant_alias: BCDD::Result::Config::Switcher
|
11
|
+
attr_reader pattern_matching: BCDD::Result::Config::Switcher
|
12
|
+
|
13
|
+
def self.instance: -> BCDD::Result::Config
|
14
|
+
|
15
|
+
def initialize: -> void
|
16
|
+
|
17
|
+
def freeze: -> BCDD::Result::Config
|
18
|
+
def options: -> Hash[Symbol, BCDD::Result::Config::Switcher]
|
19
|
+
def to_h: -> Hash[Symbol, Hash[Symbol | String, bool]]
|
20
|
+
end
|
21
|
+
|
22
|
+
module BCDD::Result::Config::Options
|
23
|
+
def self.with_defaults: (
|
24
|
+
Hash[Symbol, Hash[Symbol, bool]],
|
25
|
+
Symbol
|
26
|
+
) -> Hash[Symbol, bool]
|
27
|
+
|
28
|
+
def self.select: (
|
29
|
+
Hash[Symbol, Hash[Symbol, bool]],
|
30
|
+
config: Symbol,
|
31
|
+
from: Hash[Symbol, untyped]
|
32
|
+
) -> Hash[Symbol, untyped]
|
33
|
+
|
34
|
+
def self.addon: (
|
35
|
+
map: Hash[Symbol, Hash[Symbol, bool]],
|
36
|
+
from: Hash[Symbol, Module]
|
37
|
+
) -> Hash[Symbol, Module]
|
38
|
+
end
|
39
|
+
|
40
|
+
class BCDD::Result::Config::Switcher
|
41
|
+
private attr_reader _affects: Hash[Symbol | String, Array[String]]
|
42
|
+
private attr_reader _options: Hash[Symbol | String, bool]
|
43
|
+
private attr_reader listener: Proc
|
44
|
+
|
45
|
+
def initialize: (
|
46
|
+
options: Hash[Symbol | String, Hash[Symbol, untyped]],
|
47
|
+
?listener: Proc
|
48
|
+
) -> void
|
49
|
+
|
50
|
+
def freeze: -> BCDD::Result::Config::Switcher
|
51
|
+
|
52
|
+
def to_h: -> Hash[Symbol | String, bool]
|
53
|
+
|
54
|
+
def options: -> Hash[Symbol | String, Hash[Symbol, untyped]]
|
55
|
+
|
56
|
+
def enabled?: (Symbol | String) -> bool
|
57
|
+
|
58
|
+
def enable!: (*(Symbol | String)) -> Hash[Symbol | String, Hash[Symbol, untyped]]
|
59
|
+
|
60
|
+
def disable!: (*(Symbol | String)) -> Hash[Symbol | String, Hash[Symbol, untyped]]
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def set_many: (Array[Symbol | String], to: bool) -> Hash[Symbol | String, Hash[Symbol, untyped]]
|
65
|
+
|
66
|
+
def set_one: (Symbol | String, bool) -> void
|
67
|
+
|
68
|
+
def require_option!: (Array[Symbol | String]) -> void
|
69
|
+
|
70
|
+
def validate_option!: (Symbol | String) -> void
|
71
|
+
|
72
|
+
def available_options_message: -> String
|
73
|
+
end
|
74
|
+
|
75
|
+
module BCDD::Result::Config::Addons
|
76
|
+
AFFECTS: Array[String]
|
77
|
+
OPTIONS: Hash[String, Hash[Symbol, untyped]]
|
78
|
+
|
79
|
+
def self.switcher: -> BCDD::Result::Config::Switcher
|
80
|
+
end
|
81
|
+
|
82
|
+
module BCDD::Result::Config::ConstantAliases
|
83
|
+
MAPPING: Hash[String, Hash[Symbol, untyped]]
|
84
|
+
OPTIONS: Hash[String, Hash[Symbol, untyped]]
|
85
|
+
Listener: Proc
|
86
|
+
|
87
|
+
def self.switcher: -> BCDD::Result::Config::Switcher
|
88
|
+
end
|
89
|
+
|
90
|
+
module BCDD::Result::Config::Features
|
91
|
+
OPTIONS: Hash[String, Hash[Symbol, untyped]]
|
92
|
+
Listener: Proc
|
93
|
+
|
94
|
+
def self.switcher: -> BCDD::Result::Config::Switcher
|
95
|
+
end
|
96
|
+
|
97
|
+
module BCDD::Result::Config::PatternMatching
|
98
|
+
OPTIONS: Hash[String, Hash[Symbol, untyped]]
|
99
|
+
|
100
|
+
def self.switcher: -> BCDD::Result::Config::Switcher
|
101
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
class BCDD::Result::Context < BCDD::Result
|
2
|
+
EXPECTED_OUTCOME: String
|
3
|
+
|
4
|
+
SubjectMethodArity: ^(Method) -> Integer
|
5
|
+
|
6
|
+
attr_reader acc: Hash[Symbol, untyped]
|
7
|
+
|
8
|
+
def initialize: (
|
9
|
+
type: Symbol,
|
10
|
+
value: untyped,
|
11
|
+
?subject: untyped,
|
12
|
+
?expectations: BCDD::Result::Contract::Evaluator,
|
13
|
+
?terminal: bool
|
14
|
+
) -> void
|
15
|
+
|
16
|
+
def and_then: (?Symbol, **untyped) ?{ (Hash[Symbol, untyped]) -> untyped } -> BCDD::Result::Context
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def call_and_then_subject_method: (Symbol, Hash[Symbol, untyped]) -> BCDD::Result::Context
|
21
|
+
def ensure_result_object: (untyped, origin: Symbol) -> BCDD::Result::Context
|
22
|
+
|
23
|
+
def raise_unexpected_outcome_error: (BCDD::Result::Context | untyped, Symbol) -> void
|
24
|
+
end
|
25
|
+
|
26
|
+
class BCDD::Result::Context
|
27
|
+
class Success < BCDD::Result::Context
|
28
|
+
include BCDD::Result::Success::Methods
|
29
|
+
|
30
|
+
def and_expose: (Symbol, Array[Symbol], terminal: bool) -> BCDD::Result::Context::Success
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
|
34
|
+
end
|
35
|
+
|
36
|
+
class BCDD::Result::Context
|
37
|
+
class Failure < BCDD::Result::Context
|
38
|
+
include BCDD::Result::Failure::Methods
|
39
|
+
|
40
|
+
def and_expose: (Symbol, Array[Symbol], **untyped) -> BCDD::Result::Context::Failure
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.Failure: (Symbol, **untyped) -> BCDD::Result::Context::Failure
|
44
|
+
end
|
45
|
+
|
46
|
+
class BCDD::Result::Context
|
47
|
+
module Mixin
|
48
|
+
Factory: singleton(BCDD::Result::Mixin::Factory)
|
49
|
+
|
50
|
+
module Methods
|
51
|
+
def Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
|
52
|
+
|
53
|
+
def Failure: (Symbol, **untyped) -> BCDD::Result::Context::Failure
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?terminal: bool) -> untyped
|
58
|
+
end
|
59
|
+
|
60
|
+
module Addons
|
61
|
+
module Continue
|
62
|
+
include BCDD::Result::Context::Mixin::Methods
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def Continue: (**untyped) -> BCDD::Result::Context::Success
|
67
|
+
end
|
68
|
+
|
69
|
+
module Given
|
70
|
+
include BCDD::Result::Context::Mixin::Methods
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def Given: (*untyped) -> BCDD::Result::Context::Success
|
75
|
+
end
|
76
|
+
|
77
|
+
OPTIONS: Hash[Symbol, Module]
|
78
|
+
|
79
|
+
def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.mixin_module: -> singleton(BCDD::Result::Context::Mixin)
|
84
|
+
|
85
|
+
def self.result_factory: -> singleton(BCDD::Result::Context)
|
86
|
+
end
|
87
|
+
|
88
|
+
class BCDD::Result::Context::Expectations < BCDD::Result::Expectations
|
89
|
+
def self.mixin_module: -> singleton(BCDD::Result::Context::Expectations::Mixin)
|
90
|
+
|
91
|
+
def self.result_factory_without_expectations: -> singleton(BCDD::Result)
|
92
|
+
|
93
|
+
def Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
|
94
|
+
def Failure: (Symbol, **untyped) -> BCDD::Result::Context::Failure
|
95
|
+
end
|
96
|
+
|
97
|
+
module BCDD::Result::Context::Expectations::Mixin
|
98
|
+
Methods: singleton(BCDD::Result::Expectations::Mixin::Methods)
|
99
|
+
Factory: singleton(BCDD::Result::Expectations::Mixin::Factory)
|
100
|
+
|
101
|
+
module Addons
|
102
|
+
module Continue
|
103
|
+
private def Continue: (**untyped) -> BCDD::Result::Context::Success
|
104
|
+
end
|
105
|
+
|
106
|
+
module Given
|
107
|
+
private def Given: (*untyped) -> BCDD::Result::Context::Success
|
108
|
+
end
|
109
|
+
|
110
|
+
OPTIONS: Hash[Symbol, Module]
|
111
|
+
|
112
|
+
def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module BCDD::Result::Contract
|
2
|
+
NONE: BCDD::Result::Contract::Evaluator
|
3
|
+
|
4
|
+
def self.evaluate: (
|
5
|
+
BCDD::Result::Data,
|
6
|
+
BCDD::Result::Contract::Evaluator
|
7
|
+
) -> BCDD::Result::Contract::TypeChecker
|
8
|
+
|
9
|
+
ToEnsure: ^(Hash[Symbol, untyped] | Array[Symbol], Hash[Symbol, Hash[Symbol, bool]])
|
10
|
+
-> BCDD::Result::Contract::Interface
|
11
|
+
|
12
|
+
def self.new: (
|
13
|
+
success: Hash[Symbol, untyped] | Array[Symbol],
|
14
|
+
failure: Hash[Symbol, untyped] | Array[Symbol],
|
15
|
+
config: Hash[Symbol, Hash[Symbol, bool]]
|
16
|
+
) -> BCDD::Result::Contract::Evaluator
|
17
|
+
end
|
18
|
+
|
19
|
+
module BCDD::Result::Contract
|
20
|
+
class TypeChecker
|
21
|
+
attr_reader result_type: Symbol
|
22
|
+
attr_reader expectations: BCDD::Result::Contract::Evaluator
|
23
|
+
|
24
|
+
def initialize: (
|
25
|
+
Symbol,
|
26
|
+
expectations: BCDD::Result::Contract::Evaluator
|
27
|
+
) -> void
|
28
|
+
|
29
|
+
def allow?: (Array[Symbol]) -> bool
|
30
|
+
def allow_success?: (Array[Symbol]) -> bool
|
31
|
+
def allow_failure?: (Array[Symbol]) -> bool
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def validate: (
|
36
|
+
Array[Symbol],
|
37
|
+
expected: BCDD::Result::Contract::Interface,
|
38
|
+
allow_empty: bool
|
39
|
+
) -> bool
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class BCDD::Result::Contract::Error < BCDD::Result::Error
|
44
|
+
class UnexpectedType < BCDD::Result::Contract::Error
|
45
|
+
def self.build: (type: Symbol, allowed_types: Set[Symbol])
|
46
|
+
-> BCDD::Result::Contract::Error::UnexpectedType
|
47
|
+
end
|
48
|
+
|
49
|
+
class UnexpectedValue < BCDD::Result::Contract::Error
|
50
|
+
def self.build: (type: Symbol, value: untyped, ?cause: Exception)
|
51
|
+
-> BCDD::Result::Contract::Error::UnexpectedValue
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module BCDD::Result::Contract
|
56
|
+
module Interface
|
57
|
+
def ==: (BCDD::Result::Contract::Interface) -> bool
|
58
|
+
|
59
|
+
def allowed_types: -> Set[Symbol]
|
60
|
+
|
61
|
+
def type?: (Symbol) -> bool
|
62
|
+
|
63
|
+
def type!: (Symbol) -> Symbol
|
64
|
+
|
65
|
+
def type_and_value!: (BCDD::Result::Data) -> void
|
66
|
+
|
67
|
+
def !=: (untyped) -> bool
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module BCDD::Result::Contract
|
72
|
+
module Disabled
|
73
|
+
extend Interface
|
74
|
+
|
75
|
+
EMPTY_SET: Set[Symbol]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module BCDD::Result::Contract
|
80
|
+
class ForTypes
|
81
|
+
include Interface
|
82
|
+
|
83
|
+
def initialize: (Array[Symbol]) -> void
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module BCDD::Result::Contract
|
88
|
+
class ForTypesAndValues
|
89
|
+
include Interface
|
90
|
+
|
91
|
+
def initialize: (
|
92
|
+
Hash[Symbol, untyped],
|
93
|
+
Hash[Symbol, Hash[Symbol, bool]]
|
94
|
+
) -> void
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def nil_as_valid_value_checking?: -> bool
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
module BCDD::Result::Contract
|
103
|
+
class Evaluator
|
104
|
+
include Interface
|
105
|
+
|
106
|
+
attr_reader allowed_types: Set[Symbol]
|
107
|
+
attr_reader success: BCDD::Result::Contract::Interface
|
108
|
+
attr_reader failure: BCDD::Result::Contract::Interface
|
109
|
+
|
110
|
+
def initialize: (
|
111
|
+
BCDD::Result::Contract::Interface,
|
112
|
+
BCDD::Result::Contract::Interface
|
113
|
+
) -> void
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def for: (BCDD::Result::Data) -> BCDD::Result::Contract::Interface
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class BCDD::Result
|
2
|
+
class Data
|
3
|
+
attr_reader kind: Symbol
|
4
|
+
attr_reader type: Symbol
|
5
|
+
attr_reader value: untyped
|
6
|
+
attr_reader to_h: Hash[Symbol, untyped]
|
7
|
+
attr_reader to_a: [Symbol, Symbol, untyped]
|
8
|
+
|
9
|
+
def initialize: (Symbol, Symbol, untyped) -> void
|
10
|
+
|
11
|
+
def inspect: -> String
|
12
|
+
|
13
|
+
alias to_ary to_a
|
14
|
+
alias to_hash to_h
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class BCDD::Result
|
2
|
+
class Error < StandardError
|
3
|
+
def self.build: (**untyped) -> BCDD::Result::Error
|
4
|
+
|
5
|
+
class NotImplemented < BCDD::Result::Error
|
6
|
+
end
|
7
|
+
|
8
|
+
class MissingTypeArgument < BCDD::Result::Error
|
9
|
+
end
|
10
|
+
|
11
|
+
class UnexpectedOutcome < BCDD::Result::Error
|
12
|
+
def self.build: (outcome: untyped, origin: Symbol, ?expected: String)
|
13
|
+
-> BCDD::Result::Error::UnexpectedOutcome
|
14
|
+
end
|
15
|
+
|
16
|
+
class InvalidResultSubject < BCDD::Result::Error
|
17
|
+
def self.build: (given_result: BCDD::Result, expected_subject: untyped)
|
18
|
+
-> BCDD::Result::Error::InvalidResultSubject
|
19
|
+
end
|
20
|
+
|
21
|
+
class InvalidSubjectMethodArity < BCDD::Result::Error
|
22
|
+
def self.build: (subject: untyped, method: Method, max_arity: Integer)
|
23
|
+
-> BCDD::Result::Error::InvalidSubjectMethodArity
|
24
|
+
end
|
25
|
+
|
26
|
+
class UnhandledTypes < BCDD::Result::Error
|
27
|
+
def self.build: (types: Set[Symbol])
|
28
|
+
-> BCDD::Result::Error::UnhandledTypes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class BCDD::Result::Expectations
|
2
|
+
def self.mixin: (
|
3
|
+
?config: Hash[Symbol, Hash[Symbol, bool]],
|
4
|
+
?success: Hash[Symbol, untyped] | Array[Symbol],
|
5
|
+
?failure: Hash[Symbol, untyped] | Array[Symbol]
|
6
|
+
) -> Module
|
7
|
+
|
8
|
+
def self.mixin!: (
|
9
|
+
?config: Hash[Symbol, Hash[Symbol, bool]],
|
10
|
+
?success: Hash[Symbol, untyped] | Array[Symbol],
|
11
|
+
?failure: Hash[Symbol, untyped] | Array[Symbol]
|
12
|
+
) -> Module
|
13
|
+
|
14
|
+
def self.mixin_module: -> singleton(BCDD::Result::Expectations::Mixin)
|
15
|
+
|
16
|
+
def self.result_factory_without_expectations: -> singleton(BCDD::Result)
|
17
|
+
|
18
|
+
def self.new: (
|
19
|
+
?subject: untyped,
|
20
|
+
?contract: BCDD::Result::Contract::Evaluator,
|
21
|
+
?terminal: bool,
|
22
|
+
**untyped
|
23
|
+
) -> (BCDD::Result::Expectations | untyped)
|
24
|
+
|
25
|
+
def initialize: (
|
26
|
+
?subject: untyped,
|
27
|
+
?contract: BCDD::Result::Contract::Evaluator,
|
28
|
+
?terminal: bool,
|
29
|
+
**untyped
|
30
|
+
) -> void
|
31
|
+
|
32
|
+
def Success: (Symbol, ?untyped) -> BCDD::Result::Success
|
33
|
+
def Failure: (Symbol, ?untyped) -> BCDD::Result::Failure
|
34
|
+
|
35
|
+
def with: (subject: untyped) -> BCDD::Result::Expectations
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def _ResultAs: (singleton(BCDD::Result), Symbol, untyped) -> untyped
|
40
|
+
|
41
|
+
attr_reader subject: untyped
|
42
|
+
attr_reader contract: BCDD::Result::Contract::Evaluator
|
43
|
+
attr_reader terminal: bool
|
44
|
+
end
|
45
|
+
|
46
|
+
module BCDD::Result::Expectations::Mixin
|
47
|
+
module Factory
|
48
|
+
def self.module!: -> Module
|
49
|
+
end
|
50
|
+
|
51
|
+
module Methods
|
52
|
+
BASE: String
|
53
|
+
FACTORY: String
|
54
|
+
|
55
|
+
def self.to_eval: (Hash[Symbol, untyped]) -> String
|
56
|
+
end
|
57
|
+
|
58
|
+
module Addons
|
59
|
+
module Continue
|
60
|
+
private def Continue: (untyped) -> BCDD::Result::Success
|
61
|
+
end
|
62
|
+
|
63
|
+
module Given
|
64
|
+
private def Given: (untyped) -> BCDD::Result::Success
|
65
|
+
end
|
66
|
+
|
67
|
+
OPTIONS: Hash[Symbol, Module]
|
68
|
+
|
69
|
+
def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class BCDD::Result
|
2
|
+
class Handler
|
3
|
+
UNDEFINED: Object
|
4
|
+
|
5
|
+
def initialize: (
|
6
|
+
BCDD::Result,
|
7
|
+
type_checker: BCDD::Result::Contract::TypeChecker
|
8
|
+
) -> void
|
9
|
+
|
10
|
+
def []: (*Symbol) { (untyped, Symbol) -> void } -> untyped
|
11
|
+
def failure: (*Symbol) { (untyped, Symbol) -> void } -> untyped
|
12
|
+
def success: (*Symbol) { (untyped, Symbol) -> void } -> untyped
|
13
|
+
def unknown: () { (untyped, Symbol) -> void } -> untyped
|
14
|
+
|
15
|
+
alias type []
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader result: BCDD::Result
|
20
|
+
attr_reader allowed_types: BCDD::Result::Handler::AllowedTypes
|
21
|
+
|
22
|
+
def outcome?: -> bool
|
23
|
+
def outcome=: (Proc) -> void
|
24
|
+
def outcome: -> untyped
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class BCDD::Result::Handler
|
29
|
+
class AllowedTypes
|
30
|
+
attr_reader unchecked: Set[Symbol]
|
31
|
+
attr_reader type_checker: BCDD::Result::Contract::TypeChecker
|
32
|
+
|
33
|
+
def initialize: (
|
34
|
+
BCDD::Result::Contract::TypeChecker
|
35
|
+
) -> void
|
36
|
+
|
37
|
+
def allow?: (Array[Symbol]) -> bool
|
38
|
+
def allow_success?: (Array[Symbol]) -> bool
|
39
|
+
def allow_failure?: (Array[Symbol]) -> bool
|
40
|
+
|
41
|
+
def all_checked?: -> bool
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def check!: (Array[Symbol], bool) -> bool
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class BCDD::Result
|
2
|
+
module Mixin
|
3
|
+
module Factory
|
4
|
+
def self.module!: -> Module
|
5
|
+
end
|
6
|
+
|
7
|
+
module Methods
|
8
|
+
def Success: (Symbol type, ?untyped value) -> BCDD::Result::Success
|
9
|
+
|
10
|
+
def Failure: (Symbol type, ?untyped value) -> BCDD::Result::Failure
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?terminal: bool) -> untyped
|
15
|
+
end
|
16
|
+
|
17
|
+
module Addons
|
18
|
+
module Continue
|
19
|
+
include BCDD::Result::Mixin::Methods
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def Continue: (untyped) -> BCDD::Result::Success
|
24
|
+
end
|
25
|
+
|
26
|
+
module Given
|
27
|
+
include BCDD::Result::Mixin::Methods
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def Given: (untyped) -> BCDD::Result::Success
|
32
|
+
end
|
33
|
+
|
34
|
+
OPTIONS: Hash[Symbol, Module]
|
35
|
+
|
36
|
+
def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.mixin: (?config: Hash[Symbol, Hash[Symbol, bool]]) -> Module
|
41
|
+
|
42
|
+
def self.mixin_module: -> singleton(BCDD::Result::Mixin)
|
43
|
+
|
44
|
+
def self.result_factory: -> singleton(BCDD::Result)
|
45
|
+
end
|