bcdd-result 0.4.0 → 0.6.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 +28 -0
- data/.rubocop_todo.yml +3 -13
- data/CHANGELOG.md +95 -2
- data/README.md +572 -18
- data/lib/bcdd/result/data.rb +12 -7
- data/lib/bcdd/result/error.rb +9 -1
- data/lib/bcdd/result/expectations/contract/disabled.rb +25 -0
- data/lib/bcdd/result/expectations/contract/evaluator.rb +45 -0
- data/lib/bcdd/result/expectations/contract/for_types.rb +29 -0
- data/lib/bcdd/result/expectations/contract/for_types_and_values.rb +37 -0
- data/lib/bcdd/result/expectations/contract/interface.rb +21 -0
- data/lib/bcdd/result/expectations/contract.rb +25 -0
- data/lib/bcdd/result/expectations/error.rb +15 -0
- data/lib/bcdd/result/expectations/mixin.rb +37 -0
- data/lib/bcdd/result/expectations/type_checker.rb +33 -0
- data/lib/bcdd/result/expectations.rb +50 -0
- data/lib/bcdd/result/failure.rb +1 -1
- data/lib/bcdd/result/handler/allowed_types.rb +45 -0
- data/lib/bcdd/result/handler.rb +13 -8
- data/lib/bcdd/result/mixin.rb +31 -4
- data/lib/bcdd/result/success.rb +1 -1
- data/lib/bcdd/result/version.rb +1 -1
- data/lib/bcdd/result.rb +24 -19
- data/sig/bcdd/result.rbs +229 -40
- metadata +13 -3
- data/lib/bcdd/result/type.rb +0 -17
data/lib/bcdd/result/error.rb
CHANGED
@@ -38,7 +38,15 @@ class BCDD::Result::Error < StandardError
|
|
38
38
|
|
39
39
|
class WrongSubjectMethodArity < self
|
40
40
|
def self.build(subject:, method:)
|
41
|
-
new("#{subject.class}##{method.name} has unsupported arity (#{method.arity}). Expected 0 or
|
41
|
+
new("#{subject.class}##{method.name} has unsupported arity (#{method.arity}). Expected 0, 1 or 2.")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class UnhandledTypes < self
|
46
|
+
def self.build(types:)
|
47
|
+
subject = types.size == 1 ? 'This was' : 'These were'
|
48
|
+
|
49
|
+
new("You must handle all cases. #{subject} not handled: #{types.map(&:inspect).join(', ')}")
|
42
50
|
end
|
43
51
|
end
|
44
52
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
module Contract::Disabled
|
5
|
+
extend Contract::Interface
|
6
|
+
|
7
|
+
EMPTY_SET = Set.new.freeze
|
8
|
+
|
9
|
+
def self.allowed_types
|
10
|
+
EMPTY_SET
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.type?(_type)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.type!(type)
|
18
|
+
type
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.type_and_value!(_data); end
|
22
|
+
|
23
|
+
private_constant :EMPTY_SET
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
class Contract::Evaluator
|
5
|
+
include Contract::Interface
|
6
|
+
|
7
|
+
attr_reader :allowed_types, :success, :failure
|
8
|
+
|
9
|
+
def initialize(success, failure)
|
10
|
+
@success = success
|
11
|
+
@failure = failure
|
12
|
+
|
13
|
+
@allowed_types = (success.allowed_types | failure.allowed_types).freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def type?(type)
|
17
|
+
success_disabled = success == Contract::Disabled
|
18
|
+
failure_disabled = failure == Contract::Disabled
|
19
|
+
|
20
|
+
return Contract::Disabled.type?(type) if success_disabled && failure_disabled
|
21
|
+
|
22
|
+
(!success_disabled && success.type?(type)) || (!failure_disabled && failure.type?(type))
|
23
|
+
end
|
24
|
+
|
25
|
+
def type!(type)
|
26
|
+
return type if type?(type)
|
27
|
+
|
28
|
+
raise Error::UnexpectedType.build(type: type, allowed_types: allowed_types)
|
29
|
+
end
|
30
|
+
|
31
|
+
def type_and_value!(data)
|
32
|
+
self.for(data).type_and_value!(data)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def for(data)
|
38
|
+
case data.name
|
39
|
+
when :unknown then Contract::Disabled
|
40
|
+
when :success then success
|
41
|
+
else failure
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
class Contract::ForTypes
|
5
|
+
include Contract::Interface
|
6
|
+
|
7
|
+
attr_reader :allowed_types
|
8
|
+
|
9
|
+
def initialize(types)
|
10
|
+
@allowed_types = Array(types).map(&:to_sym).to_set.freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
def type?(type)
|
14
|
+
allowed_types.member?(type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def type!(type)
|
18
|
+
return type if type?(type)
|
19
|
+
|
20
|
+
raise Error::UnexpectedType.build(type: type, allowed_types: allowed_types)
|
21
|
+
end
|
22
|
+
|
23
|
+
def type_and_value!(data)
|
24
|
+
type!(data.type)
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
class Contract::ForTypesAndValues
|
5
|
+
include Contract::Interface
|
6
|
+
|
7
|
+
def initialize(types_and_values)
|
8
|
+
@types_and_values = types_and_values.transform_keys(&:to_sym)
|
9
|
+
|
10
|
+
@types_contract = Contract::ForTypes.new(@types_and_values.keys)
|
11
|
+
end
|
12
|
+
|
13
|
+
def allowed_types
|
14
|
+
@types_contract.allowed_types
|
15
|
+
end
|
16
|
+
|
17
|
+
def type?(type)
|
18
|
+
@types_contract.type?(type)
|
19
|
+
end
|
20
|
+
|
21
|
+
def type!(type)
|
22
|
+
@types_contract.type!(type)
|
23
|
+
end
|
24
|
+
|
25
|
+
def type_and_value!(data)
|
26
|
+
type = data.type
|
27
|
+
value = data.value
|
28
|
+
allowed_value = @types_and_values[type!(type)]
|
29
|
+
|
30
|
+
return value if allowed_value === value
|
31
|
+
|
32
|
+
raise Error::UnexpectedValue.build(type: type, value: value)
|
33
|
+
rescue NoMatchingPatternError
|
34
|
+
raise Error::UnexpectedValue.build(type: data.type, value: data.value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
module Contract::Interface
|
5
|
+
def allowed_types
|
6
|
+
raise ::BCDD::Result::Error::NotImplemented
|
7
|
+
end
|
8
|
+
|
9
|
+
def type?(_type)
|
10
|
+
raise ::BCDD::Result::Error::NotImplemented
|
11
|
+
end
|
12
|
+
|
13
|
+
def type!(_type)
|
14
|
+
raise ::BCDD::Result::Error::NotImplemented
|
15
|
+
end
|
16
|
+
|
17
|
+
def type_and_value!(_data)
|
18
|
+
raise ::BCDD::Result::Error::NotImplemented
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
module Contract
|
5
|
+
require_relative 'contract/interface'
|
6
|
+
require_relative 'contract/evaluator'
|
7
|
+
require_relative 'contract/disabled'
|
8
|
+
require_relative 'contract/for_types'
|
9
|
+
require_relative 'contract/for_types_and_values'
|
10
|
+
|
11
|
+
NONE = Contract::Evaluator.new(Contract::Disabled, Contract::Disabled).freeze
|
12
|
+
|
13
|
+
ToEnsure = ->(spec) do
|
14
|
+
return Contract::Disabled if spec.nil?
|
15
|
+
|
16
|
+
spec.is_a?(Hash) ? Contract::ForTypesAndValues.new(spec) : Contract::ForTypes.new(Array(spec))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.new(success:, failure:)
|
20
|
+
Contract::Evaluator.new(ToEnsure[success], ToEnsure[failure])
|
21
|
+
end
|
22
|
+
|
23
|
+
private_constant :ToEnsure
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations::Error < BCDD::Result::Error
|
4
|
+
class UnexpectedType < self
|
5
|
+
def self.build(type:, allowed_types:)
|
6
|
+
new("type :#{type} is not allowed. Allowed types: #{allowed_types.map(&:inspect).join(', ')}")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class UnexpectedValue < self
|
11
|
+
def self.build(type:, value:)
|
12
|
+
new("value #{value.inspect} is not allowed for :#{type} type")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
module Mixin
|
5
|
+
METHODS = <<~RUBY
|
6
|
+
def Success(...)
|
7
|
+
__expected::Success(...)
|
8
|
+
end
|
9
|
+
|
10
|
+
def Failure(...)
|
11
|
+
__expected::Failure(...)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def __expected
|
17
|
+
@__expected ||= Expected.with(subject: self)
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
|
21
|
+
module Addons
|
22
|
+
module Continuable
|
23
|
+
private def Continue(value)
|
24
|
+
::BCDD::Result::Success.new(type: :continued, value: value, subject: self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
OPTIONS = { Continue: Continuable }.freeze
|
29
|
+
|
30
|
+
def self.options(names)
|
31
|
+
Array(names).filter_map { |name| OPTIONS[name] }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private_constant :Mixin
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
class TypeChecker
|
5
|
+
attr_reader :result_type, :expectations
|
6
|
+
|
7
|
+
def initialize(result_type, expectations:)
|
8
|
+
@result_type = result_type
|
9
|
+
|
10
|
+
@expectations = expectations
|
11
|
+
end
|
12
|
+
|
13
|
+
def allow?(types)
|
14
|
+
validate(types, expected: expectations, allow_empty: false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def allow_success?(types)
|
18
|
+
validate(types, expected: expectations.success, allow_empty: true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def allow_failure?(types)
|
22
|
+
validate(types, expected: expectations.failure, allow_empty: true)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validate(types, expected:, allow_empty:)
|
28
|
+
(allow_empty && types.empty?) || types.any? { |type| expected.type!(type) == result_type }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private_constant :TypeChecker
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result::Expectations
|
4
|
+
require_relative 'expectations/mixin'
|
5
|
+
require_relative 'expectations/error'
|
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
|
18
|
+
|
19
|
+
def self.evaluate(data, expectations)
|
20
|
+
expectations ||= Contract::NONE
|
21
|
+
|
22
|
+
expectations.type_and_value!(data)
|
23
|
+
|
24
|
+
TypeChecker.new(data.type, expectations: expectations)
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(subject: nil, success: nil, failure: nil, contract: nil)
|
28
|
+
@subject = subject
|
29
|
+
|
30
|
+
@contract = contract if contract.is_a?(Contract::Evaluator)
|
31
|
+
|
32
|
+
@contract ||= Contract.new(success: success, failure: failure).freeze
|
33
|
+
end
|
34
|
+
|
35
|
+
def Success(type, value = nil)
|
36
|
+
::BCDD::Result::Success.new(type: type, value: value, subject: subject, expectations: contract)
|
37
|
+
end
|
38
|
+
|
39
|
+
def Failure(type, value = nil)
|
40
|
+
::BCDD::Result::Failure.new(type: type, value: value, subject: subject, expectations: contract)
|
41
|
+
end
|
42
|
+
|
43
|
+
def with(subject:)
|
44
|
+
self.class.new(subject: subject, contract: contract)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :subject, :contract
|
50
|
+
end
|
data/lib/bcdd/result/failure.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BCDD::Result
|
4
|
+
class Handler
|
5
|
+
class AllowedTypes
|
6
|
+
attr_reader :unchecked, :type_checker
|
7
|
+
|
8
|
+
def initialize(type_checker)
|
9
|
+
@type_checker = type_checker
|
10
|
+
|
11
|
+
@expectations = type_checker.expectations
|
12
|
+
|
13
|
+
@unchecked = @expectations.allowed_types.dup
|
14
|
+
end
|
15
|
+
|
16
|
+
def allow?(types)
|
17
|
+
check!(types, type_checker.allow?(types))
|
18
|
+
end
|
19
|
+
|
20
|
+
def allow_success?(types)
|
21
|
+
unchecked.subtract(@expectations.success.allowed_types) if types.empty?
|
22
|
+
|
23
|
+
check!(types, type_checker.allow_success?(types))
|
24
|
+
end
|
25
|
+
|
26
|
+
def allow_failure?(types)
|
27
|
+
unchecked.subtract(@expectations.failure.allowed_types) if types.empty?
|
28
|
+
|
29
|
+
check!(types, type_checker.allow_failure?(types))
|
30
|
+
end
|
31
|
+
|
32
|
+
def all_checked?
|
33
|
+
unchecked.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def check!(types, checked)
|
39
|
+
unchecked.subtract(types) unless all_checked?
|
40
|
+
|
41
|
+
checked
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bcdd/result/handler.rb
CHANGED
@@ -2,27 +2,30 @@
|
|
2
2
|
|
3
3
|
class BCDD::Result
|
4
4
|
class Handler
|
5
|
+
require_relative 'handler/allowed_types'
|
6
|
+
|
5
7
|
UNDEFINED = ::Object.new
|
6
8
|
|
7
|
-
def initialize(result)
|
9
|
+
def initialize(result, type_checker:)
|
10
|
+
@allowed_types = AllowedTypes.new(type_checker)
|
11
|
+
|
8
12
|
@outcome = UNDEFINED
|
9
13
|
|
10
|
-
@_type = result._type
|
11
14
|
@result = result
|
12
15
|
end
|
13
16
|
|
14
17
|
def [](*types, &block)
|
15
18
|
raise Error::MissingTypeArgument if types.empty?
|
16
19
|
|
17
|
-
self.outcome = block if
|
20
|
+
self.outcome = block if allowed_types.allow?(types)
|
18
21
|
end
|
19
22
|
|
20
|
-
def
|
21
|
-
self.outcome = block if
|
23
|
+
def success(*types, &block)
|
24
|
+
self.outcome = block if allowed_types.allow_success?(types) && result.success?
|
22
25
|
end
|
23
26
|
|
24
|
-
def
|
25
|
-
self.outcome = block if
|
27
|
+
def failure(*types, &block)
|
28
|
+
self.outcome = block if allowed_types.allow_failure?(types) && result.failure?
|
26
29
|
end
|
27
30
|
|
28
31
|
def unknown(&block)
|
@@ -33,7 +36,7 @@ class BCDD::Result
|
|
33
36
|
|
34
37
|
private
|
35
38
|
|
36
|
-
attr_reader :
|
39
|
+
attr_reader :result, :allowed_types
|
37
40
|
|
38
41
|
def outcome?
|
39
42
|
@outcome != UNDEFINED
|
@@ -44,6 +47,8 @@ class BCDD::Result
|
|
44
47
|
end
|
45
48
|
|
46
49
|
def outcome
|
50
|
+
allowed_types.all_checked? or raise Error::UnhandledTypes.build(types: allowed_types.unchecked)
|
51
|
+
|
47
52
|
@outcome if outcome?
|
48
53
|
end
|
49
54
|
end
|
data/lib/bcdd/result/mixin.rb
CHANGED
@@ -2,12 +2,39 @@
|
|
2
2
|
|
3
3
|
class BCDD::Result
|
4
4
|
module Mixin
|
5
|
-
|
6
|
-
Success
|
5
|
+
module Methods
|
6
|
+
def Success(type, value = nil)
|
7
|
+
Success.new(type: type, value: value, subject: self)
|
8
|
+
end
|
9
|
+
|
10
|
+
def Failure(type, value = nil)
|
11
|
+
Failure.new(type: type, value: value, subject: self)
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
|
-
|
10
|
-
|
15
|
+
module Addons
|
16
|
+
module Continuable
|
17
|
+
private def Continue(value)
|
18
|
+
Success(:continued, value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
OPTIONS = { Continue: Continuable }.freeze
|
23
|
+
|
24
|
+
def self.options(names)
|
25
|
+
Array(names).filter_map { |name| OPTIONS[name] }
|
26
|
+
end
|
11
27
|
end
|
12
28
|
end
|
29
|
+
|
30
|
+
def self.mixin(with: nil)
|
31
|
+
addons = Mixin::Addons.options(with)
|
32
|
+
|
33
|
+
mod = Module.new
|
34
|
+
mod.send(:include, Mixin::Methods)
|
35
|
+
mod.send(:include, *addons) unless addons.empty?
|
36
|
+
mod
|
37
|
+
end
|
38
|
+
|
39
|
+
private_constant :Mixin
|
13
40
|
end
|
data/lib/bcdd/result/success.rb
CHANGED
data/lib/bcdd/result/version.rb
CHANGED
data/lib/bcdd/result.rb
CHANGED
@@ -2,32 +2,38 @@
|
|
2
2
|
|
3
3
|
require_relative 'result/version'
|
4
4
|
require_relative 'result/error'
|
5
|
-
require_relative 'result/type'
|
6
5
|
require_relative 'result/data'
|
7
6
|
require_relative 'result/handler'
|
8
7
|
require_relative 'result/failure'
|
9
8
|
require_relative 'result/success'
|
10
9
|
require_relative 'result/mixin'
|
10
|
+
require_relative 'result/expectations'
|
11
11
|
|
12
12
|
class BCDD::Result
|
13
13
|
attr_accessor :unknown
|
14
14
|
|
15
|
-
attr_reader :
|
15
|
+
attr_reader :subject, :data, :type_checker
|
16
16
|
|
17
17
|
protected :subject
|
18
18
|
|
19
|
-
private :unknown, :unknown
|
19
|
+
private :unknown, :unknown=, :type_checker
|
20
20
|
|
21
|
-
def initialize(type:, value:, subject: nil)
|
22
|
-
|
23
|
-
|
21
|
+
def initialize(type:, value:, subject: nil, expectations: nil)
|
22
|
+
data = Data.new(name, type, value)
|
23
|
+
|
24
|
+
@type_checker = Expectations.evaluate(data, expectations)
|
24
25
|
@subject = subject
|
26
|
+
@data = data
|
25
27
|
|
26
28
|
self.unknown = true
|
27
29
|
end
|
28
30
|
|
29
31
|
def type
|
30
|
-
|
32
|
+
data.type
|
33
|
+
end
|
34
|
+
|
35
|
+
def value
|
36
|
+
data.value
|
31
37
|
end
|
32
38
|
|
33
39
|
def success?(_type = nil)
|
@@ -45,25 +51,27 @@ class BCDD::Result
|
|
45
51
|
def on(*types, &block)
|
46
52
|
raise Error::MissingTypeArgument if types.empty?
|
47
53
|
|
48
|
-
tap { known(block) if
|
54
|
+
tap { known(block) if type_checker.allow?(types) }
|
49
55
|
end
|
50
56
|
|
51
57
|
def on_success(*types, &block)
|
52
|
-
tap { known(block) if
|
58
|
+
tap { known(block) if type_checker.allow_success?(types) && success? }
|
53
59
|
end
|
54
60
|
|
55
61
|
def on_failure(*types, &block)
|
56
|
-
tap { known(block) if
|
62
|
+
tap { known(block) if type_checker.allow_failure?(types) && failure? }
|
57
63
|
end
|
58
64
|
|
59
65
|
def on_unknown
|
60
66
|
tap { yield(value, type) if unknown }
|
61
67
|
end
|
62
68
|
|
63
|
-
def and_then(method_name = nil)
|
69
|
+
def and_then(method_name = nil, context = nil)
|
64
70
|
return self if failure?
|
65
71
|
|
66
|
-
|
72
|
+
method_name && block_given? and raise ArgumentError, 'method_name and block are mutually exclusive'
|
73
|
+
|
74
|
+
return call_subject_method(method_name, context) if method_name
|
67
75
|
|
68
76
|
result = yield(value)
|
69
77
|
|
@@ -71,17 +79,13 @@ class BCDD::Result
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def handle
|
74
|
-
handler = Handler.new(self)
|
82
|
+
handler = Handler.new(self, type_checker: type_checker)
|
75
83
|
|
76
84
|
yield handler
|
77
85
|
|
78
86
|
handler.send(:outcome)
|
79
87
|
end
|
80
88
|
|
81
|
-
def data
|
82
|
-
Data.new(self)
|
83
|
-
end
|
84
|
-
|
85
89
|
def ==(other)
|
86
90
|
self.class == other.class && type == other.type && value == other.value
|
87
91
|
end
|
@@ -108,7 +112,7 @@ class BCDD::Result
|
|
108
112
|
private
|
109
113
|
|
110
114
|
def name
|
111
|
-
|
115
|
+
:unknown
|
112
116
|
end
|
113
117
|
|
114
118
|
def known(block)
|
@@ -117,13 +121,14 @@ class BCDD::Result
|
|
117
121
|
block.call(value, type)
|
118
122
|
end
|
119
123
|
|
120
|
-
def call_subject_method(method_name)
|
124
|
+
def call_subject_method(method_name, context)
|
121
125
|
method = subject.method(method_name)
|
122
126
|
|
123
127
|
result =
|
124
128
|
case method.arity
|
125
129
|
when 0 then subject.send(method_name)
|
126
130
|
when 1 then subject.send(method_name, value)
|
131
|
+
when 2 then subject.send(method_name, value, context)
|
127
132
|
else raise Error::WrongSubjectMethodArity.build(subject: subject, method: method)
|
128
133
|
end
|
129
134
|
|