mini_kraken 0.2.03 → 0.3.03
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 +378 -333
- data/CHANGELOG.md +48 -0
- data/README.md +29 -21
- data/lib/mini_kraken/atomic/all_atomic.rb +5 -0
- data/lib/mini_kraken/atomic/atomic_term.rb +96 -0
- data/lib/mini_kraken/atomic/k_boolean.rb +42 -0
- data/lib/mini_kraken/{core → atomic}/k_integer.rb +2 -5
- data/lib/mini_kraken/atomic/k_string.rb +17 -0
- data/lib/mini_kraken/{core → atomic}/k_symbol.rb +4 -8
- data/lib/mini_kraken/composite/all_composite.rb +4 -0
- data/lib/mini_kraken/composite/composite_term.rb +27 -0
- data/lib/mini_kraken/composite/cons_cell.rb +301 -0
- data/lib/mini_kraken/composite/cons_cell_visitor.rb +50 -0
- data/lib/mini_kraken/composite/list.rb +32 -0
- data/lib/mini_kraken/core/all_core.rb +8 -0
- data/lib/mini_kraken/core/any_value.rb +31 -7
- data/lib/mini_kraken/core/arity.rb +69 -0
- data/lib/mini_kraken/core/association.rb +29 -4
- data/lib/mini_kraken/core/association_copy.rb +50 -0
- data/lib/mini_kraken/core/base_term.rb +13 -0
- data/lib/mini_kraken/core/blackboard.rb +315 -0
- data/lib/mini_kraken/core/bookmark.rb +46 -0
- data/lib/mini_kraken/core/context.rb +492 -0
- data/lib/mini_kraken/core/duck_fiber.rb +21 -19
- data/lib/mini_kraken/core/entry.rb +40 -0
- data/lib/mini_kraken/core/fail.rb +20 -18
- data/lib/mini_kraken/core/fusion.rb +29 -0
- data/lib/mini_kraken/core/goal.rb +20 -29
- data/lib/mini_kraken/core/log_var.rb +22 -0
- data/lib/mini_kraken/core/log_var_ref.rb +108 -0
- data/lib/mini_kraken/core/nullary_relation.rb +2 -9
- data/lib/mini_kraken/core/parametrized_term.rb +68 -0
- data/lib/mini_kraken/core/relation.rb +14 -28
- data/lib/mini_kraken/core/scope.rb +67 -0
- data/lib/mini_kraken/core/solver_adapter.rb +58 -0
- data/lib/mini_kraken/core/specification.rb +48 -0
- data/lib/mini_kraken/core/succeed.rb +21 -17
- data/lib/mini_kraken/core/symbol_table.rb +137 -0
- data/lib/mini_kraken/core/term.rb +15 -4
- data/lib/mini_kraken/glue/dsl.rb +44 -88
- data/lib/mini_kraken/glue/run_star_expression.rb +28 -30
- data/lib/mini_kraken/rela/all_rela.rb +8 -0
- data/lib/mini_kraken/rela/binary_relation.rb +30 -0
- data/lib/mini_kraken/rela/conde.rb +143 -0
- data/lib/mini_kraken/rela/conj2.rb +65 -0
- data/lib/mini_kraken/rela/def_relation.rb +93 -0
- data/lib/mini_kraken/rela/disj2.rb +70 -0
- data/lib/mini_kraken/rela/fresh.rb +98 -0
- data/lib/mini_kraken/{core → rela}/goal_relation.rb +7 -9
- data/lib/mini_kraken/rela/unify.rb +265 -0
- data/lib/mini_kraken/version.rb +1 -1
- data/mini_kraken.gemspec +2 -2
- data/spec/.rubocop.yml +1 -1
- data/spec/atomic/atomic_term_spec.rb +98 -0
- data/spec/{core → atomic}/k_boolean_spec.rb +19 -34
- data/spec/{core → atomic}/k_symbol_spec.rb +3 -16
- data/spec/composite/cons_cell_spec.rb +225 -0
- data/spec/{core → composite}/cons_cell_visitor_spec.rb +36 -20
- data/spec/composite/list_spec.rb +50 -0
- data/spec/core/any_value_spec.rb +52 -0
- data/spec/core/arity_spec.rb +92 -0
- data/spec/core/association_copy_spec.rb +69 -0
- data/spec/core/association_spec.rb +31 -4
- data/spec/core/blackboard_spec.rb +287 -0
- data/spec/core/bookmark_spec.rb +40 -0
- data/spec/core/context_spec.rb +245 -0
- data/spec/core/core_spec.rb +40 -0
- data/spec/core/duck_fiber_spec.rb +16 -46
- data/spec/core/fail_spec.rb +5 -6
- data/spec/core/goal_spec.rb +22 -12
- data/spec/core/log_var_ref_spec.rb +105 -0
- data/spec/core/log_var_spec.rb +64 -0
- data/spec/core/nullary_relation_spec.rb +33 -0
- data/spec/core/parametrized_tem_spec.rb +39 -0
- data/spec/core/relation_spec.rb +33 -0
- data/spec/core/scope_spec.rb +73 -0
- data/spec/core/solver_adapter_spec.rb +70 -0
- data/spec/core/specification_spec.rb +43 -0
- data/spec/core/succeed_spec.rb +5 -5
- data/spec/core/symbol_table_spec.rb +142 -0
- data/spec/glue/dsl_chap1_spec.rb +88 -144
- data/spec/glue/dsl_chap2_spec.rb +454 -19
- data/spec/glue/run_star_expression_spec.rb +81 -906
- data/spec/rela/conde_spec.rb +153 -0
- data/spec/rela/conj2_spec.rb +123 -0
- data/spec/rela/def_relation_spec.rb +119 -0
- data/spec/rela/disj2_spec.rb +117 -0
- data/spec/rela/fresh_spec.rb +147 -0
- data/spec/rela/unify_spec.rb +369 -0
- data/spec/support/factory_atomic.rb +29 -0
- data/spec/support/factory_composite.rb +21 -0
- data/spec/support/factory_methods.rb +11 -26
- metadata +98 -70
- data/lib/mini_kraken/core/association_walker.rb +0 -183
- data/lib/mini_kraken/core/atomic_term.rb +0 -67
- data/lib/mini_kraken/core/base_arg.rb +0 -10
- data/lib/mini_kraken/core/binary_relation.rb +0 -63
- data/lib/mini_kraken/core/composite_goal.rb +0 -46
- data/lib/mini_kraken/core/composite_term.rb +0 -41
- data/lib/mini_kraken/core/conde.rb +0 -143
- data/lib/mini_kraken/core/conj2.rb +0 -79
- data/lib/mini_kraken/core/cons_cell.rb +0 -82
- data/lib/mini_kraken/core/cons_cell_visitor.rb +0 -102
- data/lib/mini_kraken/core/def_relation.rb +0 -53
- data/lib/mini_kraken/core/designation.rb +0 -55
- data/lib/mini_kraken/core/disj2.rb +0 -72
- data/lib/mini_kraken/core/environment.rb +0 -73
- data/lib/mini_kraken/core/equals.rb +0 -193
- data/lib/mini_kraken/core/formal_arg.rb +0 -22
- data/lib/mini_kraken/core/formal_ref.rb +0 -25
- data/lib/mini_kraken/core/freshness.rb +0 -45
- data/lib/mini_kraken/core/goal_arg.rb +0 -12
- data/lib/mini_kraken/core/goal_template.rb +0 -102
- data/lib/mini_kraken/core/k_boolean.rb +0 -35
- data/lib/mini_kraken/core/outcome.rb +0 -63
- data/lib/mini_kraken/core/variable.rb +0 -41
- data/lib/mini_kraken/core/variable_ref.rb +0 -84
- data/lib/mini_kraken/core/vocabulary.rb +0 -446
- data/lib/mini_kraken/glue/fresh_env.rb +0 -103
- data/lib/mini_kraken/glue/fresh_env_factory.rb +0 -83
- data/spec/core/association_walker_spec.rb +0 -192
- data/spec/core/conde_spec.rb +0 -147
- data/spec/core/conj2_spec.rb +0 -114
- data/spec/core/cons_cell_spec.rb +0 -107
- data/spec/core/def_relation_spec.rb +0 -97
- data/spec/core/disj2_spec.rb +0 -99
- data/spec/core/environment_spec.rb +0 -142
- data/spec/core/equals_spec.rb +0 -317
- data/spec/core/goal_template_spec.rb +0 -74
- data/spec/core/outcome_spec.rb +0 -56
- data/spec/core/variable_ref_spec.rb +0 -30
- data/spec/core/variable_spec.rb +0 -35
- data/spec/core/vocabulary_spec.rb +0 -219
- data/spec/glue/fresh_env_factory_spec.rb +0 -97
- data/spec/glue/fresh_env_spec.rb +0 -62
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../lib/mini_kraken/core/context'
|
5
|
+
require_relative '../../lib/mini_kraken/core/log_var'
|
6
|
+
require_relative '../../lib/mini_kraken/atomic/k_symbol'
|
7
|
+
require_relative '../../lib/mini_kraken/composite/cons_cell'
|
8
|
+
|
9
|
+
# Load the class under test
|
10
|
+
require_relative '../../lib/mini_kraken/core/log_var_ref'
|
11
|
+
|
12
|
+
|
13
|
+
module MiniKraken
|
14
|
+
module Core
|
15
|
+
describe LogVarRef do
|
16
|
+
let(:ctx) { Context.new }
|
17
|
+
let(:foo) { Atomic::KSymbol.new(:foo) }
|
18
|
+
subject { LogVarRef.new('q') }
|
19
|
+
|
20
|
+
context 'Initialization:' do
|
21
|
+
it 'should be initialized with a name' do
|
22
|
+
expect { LogVarRef.new('q') }.not_to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should know its name' do
|
26
|
+
expect(subject.name).to eq('q')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should not know the internal name of the variable' do
|
30
|
+
expect(subject.i_name).to be_nil
|
31
|
+
end
|
32
|
+
end # context
|
33
|
+
|
34
|
+
context 'Provided services:' do
|
35
|
+
def var(aName)
|
36
|
+
LogVar.new(aName)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should know whether its variable is unbound or not' do
|
40
|
+
v = var('q')
|
41
|
+
ctx.insert(v)
|
42
|
+
expect(subject).to be_unbound(ctx)
|
43
|
+
ctx.associate('q', double('something'))
|
44
|
+
expect(subject).not_to be_unbound(ctx)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should know whether its variable is floating or not' do
|
48
|
+
ctx.add_vars(%w[q x])
|
49
|
+
expect(subject).not_to be_floating(ctx)
|
50
|
+
|
51
|
+
x_ref = LogVarRef.new('x')
|
52
|
+
ctx.associate('q', x_ref)
|
53
|
+
expect(subject).to be_floating(ctx)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should know whether its variable is pinned or not' do
|
57
|
+
ctx.add_vars(%w[q x])
|
58
|
+
expect(subject).not_to be_pinned(ctx)
|
59
|
+
|
60
|
+
x_ref = LogVarRef.new('x')
|
61
|
+
ctx.associate('q', x_ref)
|
62
|
+
expect(subject).not_to be_pinned(ctx)
|
63
|
+
|
64
|
+
ctx.associate('x', foo)
|
65
|
+
expect(subject).to be_pinned(ctx)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should return its variable as its sole dependency' do
|
69
|
+
ctx.add_vars('q')
|
70
|
+
|
71
|
+
expect(subject.i_name).to be_nil
|
72
|
+
expect(subject.dependencies(ctx).size).to eq(1)
|
73
|
+
v = ctx.lookup(subject.name)
|
74
|
+
expect(subject.i_name).to eq(v.i_name)
|
75
|
+
expect(subject.dependencies(ctx).to_a).to eq([v.i_name])
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should duplicate itself when its variable has no value' do
|
79
|
+
substitutions = { 'z' => foo }
|
80
|
+
|
81
|
+
result = subject.dup_cond(substitutions)
|
82
|
+
expect(result).to be_kind_of(LogVarRef)
|
83
|
+
expect(result.name).to eq(subject.name)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should replace itself when its variable has an atomic value' do
|
87
|
+
substitutions = { 'q' => foo }
|
88
|
+
|
89
|
+
result = subject.dup_cond(substitutions)
|
90
|
+
expect(result).to eq(:foo)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should replace itself when its variable has an atomic value' do
|
94
|
+
x_ref = LogVarRef.new('x')
|
95
|
+
substitutions = { 'q' => x_ref, 'x' => foo }
|
96
|
+
|
97
|
+
# The substitutions are chained
|
98
|
+
result = subject.dup_cond(substitutions)
|
99
|
+
expect(result).to be_kind_of(Atomic::KSymbol)
|
100
|
+
expect(result).to eq(:foo)
|
101
|
+
end
|
102
|
+
end # context
|
103
|
+
end # describe
|
104
|
+
end # module
|
105
|
+
end # module
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/mini_kraken/core/log_var'
|
7
|
+
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe LogVar do
|
12
|
+
subject { LogVar.new('q') }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'should be initialized with a name' do
|
16
|
+
expect { LogVar.new('q') }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should know its name' do
|
20
|
+
expect(subject.name).to eq('q')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have a frozen label' do
|
24
|
+
expect(subject.label).to be_frozen
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should know its default internal name' do
|
28
|
+
# By default: internal name == label
|
29
|
+
expect(subject.i_name).to eq(subject.label)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have a nil suffix' do
|
33
|
+
expect(subject.suffix).to be_nil
|
34
|
+
end
|
35
|
+
end # context
|
36
|
+
|
37
|
+
context 'Provided service:' do
|
38
|
+
let(:sample_suffix) { 'sample-suffix' }
|
39
|
+
it 'should have a label equal to its user-defined name' do
|
40
|
+
expect(subject.label).to eq(subject.name)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should accept a suffix' do
|
44
|
+
expect { subject.suffix = sample_suffix }.not_to raise_error
|
45
|
+
expect(subject.suffix).to eq(sample_suffix)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should calculate its internal name' do
|
49
|
+
# Rule: empty suffix => internal name == label
|
50
|
+
subject.suffix = ''
|
51
|
+
expect(subject.i_name).to eq(subject.label)
|
52
|
+
|
53
|
+
# Rule: suffix starting underscore: internal name = label + suffix
|
54
|
+
subject.suffix = '_10'
|
55
|
+
expect(subject.i_name).to eq(subject.label + subject.suffix)
|
56
|
+
|
57
|
+
# Rule: ... otherwise: internal name == suffix
|
58
|
+
subject.suffix = sample_suffix
|
59
|
+
expect(subject.i_name).to eq(subject.suffix)
|
60
|
+
end
|
61
|
+
end # context
|
62
|
+
end # describe
|
63
|
+
end # module
|
64
|
+
end # module
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/mini_kraken/core/nullary_relation'
|
7
|
+
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe NullaryRelation do
|
12
|
+
subject { NullaryRelation.new('fail') }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'should be initialized with a name' do
|
16
|
+
expect { NullaryRelation.new('fail') }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should know its name' do
|
20
|
+
expect(subject.name).to eq('fail')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should know its zero arity' do
|
24
|
+
expect(subject.arity).to be_nullary
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should be frozen' do
|
28
|
+
expect(subject).to be_frozen
|
29
|
+
end
|
30
|
+
end # context
|
31
|
+
end # describe
|
32
|
+
end # module
|
33
|
+
end # module
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../lib/mini_kraken/core/relation'
|
5
|
+
|
6
|
+
# Load the class under test
|
7
|
+
require_relative '../../lib/mini_kraken/core/parametrized_term'
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe ParametrizedTerm do
|
12
|
+
let(:specif) { Relation.new('disj2', 2) }
|
13
|
+
let(:arg1) { Term.new }
|
14
|
+
let(:arg2) { Term.new }
|
15
|
+
let(:arg3) { Term.new }
|
16
|
+
subject { ParametrizedTerm.new(specif, [arg1, arg2]) }
|
17
|
+
|
18
|
+
context 'Initialization:' do
|
19
|
+
it 'should be initialized with a specification and actuals' do
|
20
|
+
expect { ParametrizedTerm.new(specif, [arg1, arg2]) }.not_to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should fail when number of arguments out of arity range' do
|
24
|
+
err = StandardError
|
25
|
+
err_msg = 'Count of arguments (3) is out of allowed range (2, 2).'
|
26
|
+
expect { ParametrizedTerm.new(specif, [arg1, arg2, arg3]) }.to raise_error(err, err_msg)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should know its specification' do
|
30
|
+
expect(subject.specification).to eq(specif)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should know its actuals' do
|
34
|
+
expect(subject.actuals).to eq([arg1, arg2])
|
35
|
+
end
|
36
|
+
end # context
|
37
|
+
end # describe
|
38
|
+
end # module
|
39
|
+
end # module
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/mini_kraken/core/relation'
|
7
|
+
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe Relation do
|
12
|
+
subject { Relation.new('caro', 2) }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'should be initialized with a name and an arity' do
|
16
|
+
expect { Relation.new('caro', Arity.new(2, 2)) }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be initialized with a name and an integer' do
|
20
|
+
expect { Relation.new('caro', 2) }.not_to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should know its name' do
|
24
|
+
expect(subject.name).to eq('caro')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should know its arity' do
|
28
|
+
expect(subject.arity).to eq(Arity.new(2, 2))
|
29
|
+
end
|
30
|
+
end # context
|
31
|
+
end # describe
|
32
|
+
end # module
|
33
|
+
end # module
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../support/factory_atomic'
|
5
|
+
|
6
|
+
# Load the class under test
|
7
|
+
require_relative '../../lib/mini_kraken/core/scope'
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe Scope do
|
12
|
+
include MiniKraken::FactoryAtomic # Use mix-in module
|
13
|
+
let(:mother) { Scope.new }
|
14
|
+
subject { Scope.new(mother) }
|
15
|
+
|
16
|
+
def var(aName)
|
17
|
+
LogVar.new(aName)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'Initialization:' do
|
21
|
+
it 'could be initialized without argument' do
|
22
|
+
expect { Scope.new }.not_to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'could be initialized with a parent scope' do
|
26
|
+
expect { Scope.new(mother) }.not_to raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it "shouldn't have definitions by default" do
|
30
|
+
expect(subject.defns).to be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should know its parent (if any)' do
|
34
|
+
expect(subject.parent).to eq(mother)
|
35
|
+
end
|
36
|
+
end # context
|
37
|
+
|
38
|
+
context 'Provided services:' do
|
39
|
+
it 'should accept the addition of a variable' do
|
40
|
+
subject.insert(var('a'))
|
41
|
+
expect(subject.defns).not_to be_empty
|
42
|
+
var_a = subject.defns['a']
|
43
|
+
expect(var_a).to be_kind_of(Core::LogVar)
|
44
|
+
expect(var_a.label).to eq('a')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should accept the addition of multiple variables' do
|
48
|
+
subject.insert(var('a'))
|
49
|
+
expect(subject.defns).not_to be_empty
|
50
|
+
|
51
|
+
subject.insert(var('b'))
|
52
|
+
var_b = subject.defns['b']
|
53
|
+
expect(var_b).to be_kind_of(Core::LogVar)
|
54
|
+
expect(var_b.label).to eq('b')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should set the suffix of just created variable' do
|
58
|
+
subject.insert(var('a'))
|
59
|
+
var_a = subject.defns['a']
|
60
|
+
expect(var_a.suffix).to eq("_#{subject.object_id.to_s(16)}")
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should complain when variable names collide' do
|
64
|
+
subject.insert(var('c'))
|
65
|
+
expect(subject.defns['c']).to be_kind_of(Core::LogVar)
|
66
|
+
err = StandardError
|
67
|
+
err_msg = "Variable with name 'c' already exists."
|
68
|
+
expect { subject.insert(var('c')) }.to raise_error(err, err_msg)
|
69
|
+
end
|
70
|
+
end # context
|
71
|
+
end # describe
|
72
|
+
end # module
|
73
|
+
end # module
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
require_relative '../../lib/mini_kraken/core/context'
|
7
|
+
|
8
|
+
# Load the class under test
|
9
|
+
require_relative '../../lib/mini_kraken/core/solver_adapter'
|
10
|
+
|
11
|
+
|
12
|
+
module MiniKraken
|
13
|
+
module Core
|
14
|
+
describe SolverAdapter do
|
15
|
+
let(:ctx) { Context.new }
|
16
|
+
let(:fib) { make_fiber(ctx, true, true, false, nil) }
|
17
|
+
let(:blk) do
|
18
|
+
lambda do |adapter, _context|
|
19
|
+
adapter.adaptee.resume
|
20
|
+
end
|
21
|
+
end
|
22
|
+
subject { SolverAdapter.new(fib, &blk) }
|
23
|
+
|
24
|
+
# Factory method.
|
25
|
+
def make_fiber(ctx, *args)
|
26
|
+
Fiber.new do
|
27
|
+
signature = *args
|
28
|
+
signature.each do |outcome|
|
29
|
+
if outcome
|
30
|
+
Fiber.yield ctx.succeeded!
|
31
|
+
next
|
32
|
+
elsif outcome.nil?
|
33
|
+
Fiber.yield nil
|
34
|
+
break
|
35
|
+
else
|
36
|
+
Fiber.yield ctx.failed!
|
37
|
+
next
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'Initialization:' do
|
44
|
+
it 'should be initialized with a Fiber-like object' do
|
45
|
+
expect { SolverAdapter.new(fib, &blk) }.not_to raise_error
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should know its adaptee' do
|
49
|
+
expect(subject.adaptee).to eq(fib)
|
50
|
+
end
|
51
|
+
end # context
|
52
|
+
|
53
|
+
context 'Provided services:' do
|
54
|
+
it 'should respond to the resume message' do
|
55
|
+
result = subject.resume(ctx)
|
56
|
+
expect(result).to be_success
|
57
|
+
|
58
|
+
result = subject.resume(ctx)
|
59
|
+
expect(result).to be_success
|
60
|
+
|
61
|
+
result = subject.resume(ctx)
|
62
|
+
expect(result).to be_failure
|
63
|
+
|
64
|
+
result = subject.resume(ctx)
|
65
|
+
expect(result).to be_nil
|
66
|
+
end
|
67
|
+
end # context
|
68
|
+
end # describe
|
69
|
+
end # module
|
70
|
+
end # module
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/mini_kraken/core/specification'
|
7
|
+
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe Specification do
|
12
|
+
subject { Specification.new('cons', 2) }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'should be initialized with a name and an arity' do
|
16
|
+
expect { Specification.new('cons', Arity.new(2, 2)) }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be initialized with a name and an integer' do
|
20
|
+
expect { Specification.new('cons', 2) }.not_to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should know its name' do
|
24
|
+
expect(subject.name).to eq('cons')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should know its arity' do
|
28
|
+
expect(subject.arity).to be_binary
|
29
|
+
end
|
30
|
+
end # context
|
31
|
+
|
32
|
+
context 'Provided services:' do
|
33
|
+
it "should complain when number of arguments does't fit arity" do
|
34
|
+
dummy_arg = double('dummy-stuff')
|
35
|
+
|
36
|
+
err = StandardError
|
37
|
+
err_msg = 'Count of arguments (1) is out of allowed range (2, 2).'
|
38
|
+
expect { subject.check_arity([dummy_arg]) }.to raise_error(err, err_msg)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end # describe
|
42
|
+
end # module
|
43
|
+
end # module
|