bcdd-result 0.6.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +31 -11
- data/CHANGELOG.md +148 -0
- data/README.md +849 -242
- data/Rakefile +9 -3
- data/Steepfile +1 -1
- data/lib/bcdd/result/config/constant_alias.rb +33 -0
- data/lib/bcdd/result/config/options.rb +26 -0
- data/lib/bcdd/result/config/switcher.rb +82 -0
- data/lib/bcdd/result/config.rb +71 -0
- data/lib/bcdd/result/context/expectations/mixin.rb +23 -0
- data/lib/bcdd/result/context/expectations.rb +25 -0
- data/lib/bcdd/result/context/failure.rb +9 -0
- data/lib/bcdd/result/context/mixin.rb +41 -0
- data/lib/bcdd/result/context/success.rb +15 -0
- data/lib/bcdd/result/context.rb +74 -0
- data/lib/bcdd/result/{expectations/contract → contract}/disabled.rb +2 -2
- data/lib/bcdd/result/{expectations → contract}/error.rb +5 -3
- data/lib/bcdd/result/{expectations/contract → contract}/evaluator.rb +2 -2
- data/lib/bcdd/result/{expectations/contract → contract}/for_types.rb +2 -2
- data/lib/bcdd/result/contract/for_types_and_values.rb +44 -0
- data/lib/bcdd/result/contract/interface.rb +21 -0
- data/lib/bcdd/result/{expectations → contract}/type_checker.rb +1 -1
- data/lib/bcdd/result/contract.rb +33 -0
- data/lib/bcdd/result/error.rb +7 -9
- data/lib/bcdd/result/expectations/mixin.rb +19 -12
- data/lib/bcdd/result/expectations.rb +51 -36
- data/lib/bcdd/result/failure/methods.rb +21 -0
- data/lib/bcdd/result/failure.rb +2 -16
- data/lib/bcdd/result/mixin.rb +26 -8
- data/lib/bcdd/result/success/methods.rb +21 -0
- data/lib/bcdd/result/success.rb +2 -16
- data/lib/bcdd/result/version.rb +1 -1
- data/lib/bcdd/result.rb +17 -4
- data/lib/bcdd-result.rb +3 -0
- data/sig/bcdd/result.rbs +340 -88
- metadata +27 -16
- data/lib/bcdd/result/expectations/contract/for_types_and_values.rb +0 -37
- data/lib/bcdd/result/expectations/contract/interface.rb +0 -21
- data/lib/bcdd/result/expectations/contract.rb +0 -25
- data/lib/result.rb +0 -5
@@ -1,37 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class BCDD::Result
|
4
|
-
module Mixin
|
3
|
+
class BCDD::Result
|
4
|
+
module Expectations::Mixin
|
5
|
+
module Factory
|
6
|
+
def self.module!
|
7
|
+
::Module.new do
|
8
|
+
def self.included(base); base.const_set(:ResultExpectationsMixin, self); end
|
9
|
+
def self.extended(base); base.const_set(:ResultExpectationsMixin, self); end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
5
14
|
METHODS = <<~RUBY
|
6
15
|
def Success(...)
|
7
|
-
|
16
|
+
_Result.Success(...)
|
8
17
|
end
|
9
18
|
|
10
19
|
def Failure(...)
|
11
|
-
|
20
|
+
_Result.Failure(...)
|
12
21
|
end
|
13
22
|
|
14
23
|
private
|
15
24
|
|
16
|
-
def
|
17
|
-
@
|
25
|
+
def _Result
|
26
|
+
@_Result ||= Result.with(subject: self)
|
18
27
|
end
|
19
28
|
RUBY
|
20
29
|
|
21
30
|
module Addons
|
22
31
|
module Continuable
|
23
32
|
private def Continue(value)
|
24
|
-
|
33
|
+
Success.new(type: :continued, value: value, subject: self)
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
28
|
-
OPTIONS = {
|
37
|
+
OPTIONS = { continue: Continuable }.freeze
|
29
38
|
|
30
|
-
def self.options(
|
31
|
-
|
39
|
+
def self.options(config_flags)
|
40
|
+
Config::Options.addon(map: config_flags, from: OPTIONS)
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
35
|
-
|
36
|
-
private_constant :Mixin
|
37
44
|
end
|
@@ -1,50 +1,65 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class BCDD::Result
|
4
|
-
|
5
|
-
|
6
|
-
require_relative 'expectations/contract'
|
7
|
-
require_relative 'expectations/type_checker'
|
8
|
-
|
9
|
-
def self.mixin(success: nil, failure: nil, with: nil)
|
10
|
-
addons = Mixin::Addons.options(with)
|
11
|
-
|
12
|
-
mod = Module.new
|
13
|
-
mod.const_set(:Expected, new(success: success, failure: failure).freeze)
|
14
|
-
mod.module_eval(Mixin::METHODS)
|
15
|
-
mod.send(:include, *addons) unless addons.empty?
|
16
|
-
mod
|
17
|
-
end
|
3
|
+
class BCDD::Result
|
4
|
+
class Expectations
|
5
|
+
require_relative 'expectations/mixin'
|
18
6
|
|
19
|
-
|
20
|
-
|
7
|
+
def self.mixin(**options)
|
8
|
+
return mixin!(**options) if Config.instance.feature.enabled?(:expectations)
|
21
9
|
|
22
|
-
|
10
|
+
result_factory_without_expectations.mixin(**options.slice(:config))
|
11
|
+
end
|
23
12
|
|
24
|
-
|
25
|
-
|
13
|
+
def self.mixin!(success: nil, failure: nil, config: nil)
|
14
|
+
addons = mixin_module::Addons.options(config)
|
26
15
|
|
27
|
-
|
28
|
-
|
16
|
+
mod = mixin_module::Factory.module!
|
17
|
+
mod.const_set(:Result, new(success: success, failure: failure, config: config).freeze)
|
18
|
+
mod.module_eval(mixin_module::METHODS)
|
19
|
+
mod.send(:include, *addons) unless addons.empty?
|
20
|
+
mod
|
21
|
+
end
|
29
22
|
|
30
|
-
|
23
|
+
def self.mixin_module
|
24
|
+
Mixin
|
25
|
+
end
|
31
26
|
|
32
|
-
|
33
|
-
|
27
|
+
def self.result_factory_without_expectations
|
28
|
+
::BCDD::Result
|
29
|
+
end
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
31
|
+
def self.new(...)
|
32
|
+
return result_factory_without_expectations unless Config.instance.feature.enabled?(:expectations)
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
34
|
+
instance = allocate
|
35
|
+
instance.send(:initialize, ...)
|
36
|
+
instance
|
37
|
+
end
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
private_class_method :mixin!, :mixin_module, :result_factory_without_expectations
|
40
|
+
|
41
|
+
def initialize(subject: nil, success: nil, failure: nil, contract: nil, config: nil)
|
42
|
+
@subject = subject
|
46
43
|
|
47
|
-
|
44
|
+
@contract = contract if contract.is_a?(Contract::Evaluator)
|
48
45
|
|
49
|
-
|
46
|
+
@contract ||= Contract.new(success: success, failure: failure, config: config).freeze
|
47
|
+
end
|
48
|
+
|
49
|
+
def Success(type, value = nil)
|
50
|
+
Success.new(type: type, value: value, subject: subject, expectations: contract)
|
51
|
+
end
|
52
|
+
|
53
|
+
def Failure(type, value = nil)
|
54
|
+
Failure.new(type: type, value: value, subject: subject, expectations: contract)
|
55
|
+
end
|
56
|
+
|
57
|
+
def with(subject:)
|
58
|
+
self.class.new(subject: subject, contract: contract)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
attr_reader :subject, :contract
|
64
|
+
end
|
50
65
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDD::Result::Failure::Methods
|
4
|
+
def success?(_type = nil)
|
5
|
+
false
|
6
|
+
end
|
7
|
+
|
8
|
+
def failure?(type = nil)
|
9
|
+
type.nil? || type_checker.allow_failure?([type])
|
10
|
+
end
|
11
|
+
|
12
|
+
def value_or
|
13
|
+
yield(value)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def name
|
19
|
+
:failure
|
20
|
+
end
|
21
|
+
end
|
data/lib/bcdd/result/failure.rb
CHANGED
@@ -2,23 +2,9 @@
|
|
2
2
|
|
3
3
|
class BCDD::Result
|
4
4
|
class Failure < self
|
5
|
-
|
6
|
-
false
|
7
|
-
end
|
5
|
+
require_relative 'failure/methods'
|
8
6
|
|
9
|
-
|
10
|
-
type.nil? || type_checker.allow_failure?([type])
|
11
|
-
end
|
12
|
-
|
13
|
-
def value_or
|
14
|
-
yield
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def name
|
20
|
-
:failure
|
21
|
-
end
|
7
|
+
include Methods
|
22
8
|
end
|
23
9
|
|
24
10
|
def self.Failure(type, value = nil)
|
data/lib/bcdd/result/mixin.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
class BCDD::Result
|
4
4
|
module Mixin
|
5
|
+
module Factory
|
6
|
+
def self.module!
|
7
|
+
::Module.new do
|
8
|
+
def self.included(base); base.const_set(:ResultMixin, self); end
|
9
|
+
def self.extended(base); base.const_set(:ResultMixin, self); end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
5
14
|
module Methods
|
6
15
|
def Success(type, value = nil)
|
7
16
|
Success.new(type: type, value: value, subject: self)
|
@@ -19,22 +28,31 @@ class BCDD::Result
|
|
19
28
|
end
|
20
29
|
end
|
21
30
|
|
22
|
-
OPTIONS = {
|
31
|
+
OPTIONS = { continue: Continuable }.freeze
|
23
32
|
|
24
|
-
def self.options(
|
25
|
-
|
33
|
+
def self.options(config_flags)
|
34
|
+
Config::Options.addon(map: config_flags, from: OPTIONS)
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
29
38
|
|
30
|
-
def self.mixin(
|
31
|
-
addons =
|
39
|
+
def self.mixin(config: nil)
|
40
|
+
addons = mixin_module::Addons.options(config)
|
32
41
|
|
33
|
-
mod =
|
34
|
-
mod.send(:include,
|
42
|
+
mod = mixin_module::Factory.module!
|
43
|
+
mod.send(:include, mixin_module::Methods)
|
44
|
+
mod.const_set(:Result, result_factory)
|
35
45
|
mod.send(:include, *addons) unless addons.empty?
|
36
46
|
mod
|
37
47
|
end
|
38
48
|
|
39
|
-
|
49
|
+
def self.mixin_module
|
50
|
+
Mixin
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.result_factory
|
54
|
+
::BCDD::Result
|
55
|
+
end
|
56
|
+
|
57
|
+
private_class_method :mixin_module, :result_factory
|
40
58
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDD::Result::Success::Methods
|
4
|
+
def success?(type = nil)
|
5
|
+
type.nil? || type_checker.allow_success?([type])
|
6
|
+
end
|
7
|
+
|
8
|
+
def failure?(_type = nil)
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def value_or
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def name
|
19
|
+
:success
|
20
|
+
end
|
21
|
+
end
|
data/lib/bcdd/result/success.rb
CHANGED
@@ -2,23 +2,9 @@
|
|
2
2
|
|
3
3
|
class BCDD::Result
|
4
4
|
class Success < self
|
5
|
-
|
6
|
-
type.nil? || type_checker.allow_success?([type])
|
7
|
-
end
|
5
|
+
require_relative 'success/methods'
|
8
6
|
|
9
|
-
|
10
|
-
false
|
11
|
-
end
|
12
|
-
|
13
|
-
def value_or
|
14
|
-
value
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def name
|
20
|
-
:success
|
21
|
-
end
|
7
|
+
include Methods
|
22
8
|
end
|
23
9
|
|
24
10
|
def self.Success(type, value = nil)
|
data/lib/bcdd/result/version.rb
CHANGED
data/lib/bcdd/result.rb
CHANGED
@@ -3,11 +3,14 @@
|
|
3
3
|
require_relative 'result/version'
|
4
4
|
require_relative 'result/error'
|
5
5
|
require_relative 'result/data'
|
6
|
+
require_relative 'result/config'
|
6
7
|
require_relative 'result/handler'
|
7
8
|
require_relative 'result/failure'
|
8
9
|
require_relative 'result/success'
|
9
10
|
require_relative 'result/mixin'
|
11
|
+
require_relative 'result/contract'
|
10
12
|
require_relative 'result/expectations'
|
13
|
+
require_relative 'result/context'
|
11
14
|
|
12
15
|
class BCDD::Result
|
13
16
|
attr_accessor :unknown
|
@@ -18,10 +21,20 @@ class BCDD::Result
|
|
18
21
|
|
19
22
|
private :unknown, :unknown=, :type_checker
|
20
23
|
|
24
|
+
def self.config
|
25
|
+
Config.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configuration
|
29
|
+
yield(config)
|
30
|
+
|
31
|
+
config.freeze
|
32
|
+
end
|
33
|
+
|
21
34
|
def initialize(type:, value:, subject: nil, expectations: nil)
|
22
35
|
data = Data.new(name, type, value)
|
23
36
|
|
24
|
-
@type_checker =
|
37
|
+
@type_checker = Contract.evaluate(data, expectations)
|
25
38
|
@subject = subject
|
26
39
|
@data = data
|
27
40
|
|
@@ -69,7 +82,7 @@ class BCDD::Result
|
|
69
82
|
def and_then(method_name = nil, context = nil)
|
70
83
|
return self if failure?
|
71
84
|
|
72
|
-
method_name && block_given? and raise ArgumentError, 'method_name and block are mutually exclusive'
|
85
|
+
method_name && block_given? and raise ::ArgumentError, 'method_name and block are mutually exclusive'
|
73
86
|
|
74
87
|
return call_subject_method(method_name, context) if method_name
|
75
88
|
|
@@ -129,7 +142,7 @@ class BCDD::Result
|
|
129
142
|
when 0 then subject.send(method_name)
|
130
143
|
when 1 then subject.send(method_name, value)
|
131
144
|
when 2 then subject.send(method_name, value, context)
|
132
|
-
else raise Error::
|
145
|
+
else raise Error::InvalidSubjectMethodArity.build(subject: subject, method: method, max_arity: 2)
|
133
146
|
end
|
134
147
|
|
135
148
|
ensure_result_object(result, origin: :method)
|
@@ -140,6 +153,6 @@ class BCDD::Result
|
|
140
153
|
|
141
154
|
return result if result.subject.equal?(subject)
|
142
155
|
|
143
|
-
raise Error::
|
156
|
+
raise Error::InvalidResultSubject.build(given_result: result, expected_subject: subject)
|
144
157
|
end
|
145
158
|
end
|
data/lib/bcdd-result.rb
ADDED