skeem 0.2.21 → 0.2.22
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 +33 -337
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +1 -1
- data/lib/skeem/grammar.rb +13 -13
- data/lib/skeem/interpreter.rb +1 -1
- data/lib/skeem/primitive/primitive_builder.rb +1 -1
- data/lib/skeem/primitive/primitive_procedure.rb +1 -1
- data/lib/skeem/runtime.rb +2 -0
- data/lib/skeem/s_expr_nodes.rb +5 -3
- data/lib/skeem/tokenizer.rb +15 -20
- data/lib/skeem/version.rb +1 -1
- data/lib/skeem.rb +2 -2
- data/skeem.gemspec +8 -5
- data/spec/skeem/datum_dsl_spec.rb +50 -50
- data/spec/skeem/element_visitor_spec.rb +108 -108
- data/spec/skeem/interpreter_spec.rb +171 -169
- data/spec/skeem/lambda_spec.rb +27 -27
- data/spec/skeem/parser_spec.rb +27 -25
- data/spec/skeem/primitive/primitive_builder_spec.rb +127 -131
- data/spec/skeem/primitive/primitive_procedure_spec.rb +28 -28
- data/spec/skeem/runtime_spec.rb +52 -51
- data/spec/skeem/s_expr_nodes_spec.rb +31 -31
- data/spec/skeem/skm_compound_datum_spec.rb +36 -35
- data/spec/skeem/skm_element_spec.rb +35 -34
- data/spec/skeem/skm_empty_list_spec.rb +19 -19
- data/spec/skeem/skm_frame_spec.rb +49 -46
- data/spec/skeem/skm_pair_spec.rb +93 -93
- data/spec/skeem/skm_procedure_exec_spec.rb +11 -11
- data/spec/skeem/skm_simple_datum_spec.rb +102 -95
- data/spec/skeem/skm_unary_expression_spec.rb +60 -61
- data/spec/skeem/tokenizer_spec.rb +52 -52
- data/spec/skeem_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -2
- metadata +62 -18
@@ -29,66 +29,66 @@ module Skeem
|
|
29
29
|
->(_runtime, operands) { operands.length }
|
30
30
|
end
|
31
31
|
|
32
|
-
subject {
|
32
|
+
subject(:primitive) { described_class.new('cube', unary, cube) }
|
33
33
|
|
34
|
-
before
|
34
|
+
before { @passing = false }
|
35
35
|
|
36
36
|
context 'Initialization:' do
|
37
|
-
it '
|
38
|
-
expect {
|
37
|
+
it 'is initialized with a name, arity and a lambda' do
|
38
|
+
expect { described_class.new('newline', nullary, newline_code) }.not_to raise_error
|
39
39
|
end
|
40
40
|
|
41
|
-
it '
|
42
|
-
expect(
|
41
|
+
it 'knows its name' do
|
42
|
+
expect(primitive.identifier.value).to eq('cube')
|
43
43
|
end
|
44
44
|
|
45
|
-
it '
|
46
|
-
expect(
|
45
|
+
it 'knows its arity' do
|
46
|
+
expect(primitive.arity).to eq([1, 1])
|
47
47
|
end
|
48
48
|
|
49
|
-
it '
|
50
|
-
expect(
|
49
|
+
it 'knows its lambda' do
|
50
|
+
expect(primitive.code).to eq(cube)
|
51
51
|
end
|
52
52
|
|
53
|
-
it '
|
53
|
+
it 'complains if third argument is not a lambda' do
|
54
54
|
kode = proc { puts '' }
|
55
55
|
|
56
56
|
err = StandardError
|
57
57
|
err_msg = "Primitive procedure 'newline' must be implemented with a Ruby lambda."
|
58
|
-
expect {
|
58
|
+
expect { described_class.new('newline', nullary, kode) }.to raise_error(err, err_msg)
|
59
59
|
end
|
60
60
|
|
61
|
-
it '
|
61
|
+
it 'complains if third argument is a nullary lambda' do
|
62
62
|
kode = -> { puts '' } # Missing slot for Runtime object
|
63
63
|
|
64
64
|
err = StandardError
|
65
65
|
err_msg = "Primitive procedure 'newline' lambda takes no parameter."
|
66
|
-
expect {
|
66
|
+
expect { described_class.new('newline', nullary, kode) }.to raise_error(err, err_msg)
|
67
67
|
end
|
68
68
|
|
69
|
-
it '
|
69
|
+
it 'complains when arity and parameter count mismatch' do
|
70
70
|
err = StandardError
|
71
71
|
msg1 = "Discrepancy in primitive procedure 'cube' "
|
72
72
|
|
73
73
|
msg2 = 'between arity (0) + 1 and parameter count of lambda 2.'
|
74
|
-
expect {
|
74
|
+
expect { described_class.new('cube', nullary, cube) }.to raise_error(err, msg1 + msg2)
|
75
75
|
|
76
76
|
msg2 = 'between arity (2) + 1 and parameter count of lambda 2.'
|
77
|
-
expect {
|
77
|
+
expect { described_class.new('cube', binary, cube) }.to raise_error(err, msg1 + msg2)
|
78
78
|
|
79
79
|
# Nasty; this discrepancy isn't detected
|
80
|
-
expect {
|
80
|
+
expect { described_class.new('cube', zero_or_more, cube) }.not_to raise_error
|
81
81
|
|
82
|
-
expect {
|
82
|
+
expect { described_class.new('cube', unary, cube) }.not_to raise_error
|
83
83
|
|
84
84
|
msg2 = 'between arity (1) + 2 and parameter count of lambda 2.'
|
85
|
-
expect {
|
85
|
+
expect { described_class.new('cube', one_or_more, cube) }.to raise_error(err, msg1 + msg2)
|
86
86
|
end
|
87
87
|
end # context
|
88
88
|
|
89
89
|
context 'Procedure invokation:' do
|
90
|
-
it '
|
91
|
-
pproc =
|
90
|
+
it 'supports Skeem nullary procedure' do
|
91
|
+
pproc = described_class.new('newline', nullary, newline_code)
|
92
92
|
rtime = double('fake-runtime')
|
93
93
|
|
94
94
|
expect(pproc.call(rtime, [])).to eq("\n")
|
@@ -99,8 +99,8 @@ module Skeem
|
|
99
99
|
expect { pproc.call(rtime, ['superfluous']) }.to raise_error(err, ms1 + ms2)
|
100
100
|
end
|
101
101
|
|
102
|
-
it '
|
103
|
-
pproc =
|
102
|
+
it 'supports Skeem unary procedure' do
|
103
|
+
pproc = described_class.new('cube', unary, cube)
|
104
104
|
rtime = double('fake-runtime')
|
105
105
|
|
106
106
|
args = [SkmInteger.create(3)]
|
@@ -118,8 +118,8 @@ module Skeem
|
|
118
118
|
expect { pproc.call(rtime, too_much) }.to raise_error(err, ms1 + ms2)
|
119
119
|
end
|
120
120
|
|
121
|
-
it '
|
122
|
-
pproc =
|
121
|
+
it 'supports Skeem binary procedure' do
|
122
|
+
pproc = described_class.new('sum', binary, sum)
|
123
123
|
rtime = double('fake-runtime')
|
124
124
|
|
125
125
|
args = [SkmInteger.create(3), SkmInteger.create(5)]
|
@@ -138,8 +138,8 @@ module Skeem
|
|
138
138
|
expect { pproc.call(rtime, too_much) }.to raise_error(err, ms1 + ms2)
|
139
139
|
end
|
140
140
|
|
141
|
-
it '
|
142
|
-
pproc =
|
141
|
+
it 'supports Skeem variadic procedure' do
|
142
|
+
pproc = described_class.new('length', zero_or_more, length)
|
143
143
|
rtime = double('fake-runtime')
|
144
144
|
|
145
145
|
args = [SkmInteger.create(3), SkmInteger.create(5)]
|
data/spec/skeem/runtime_spec.rb
CHANGED
@@ -12,79 +12,80 @@ module Skeem
|
|
12
12
|
include DatumDSL
|
13
13
|
|
14
14
|
let(:some_env) { SkmFrame.new }
|
15
|
-
|
15
|
+
|
16
|
+
subject(:runtime) { described_class.new(some_env) }
|
16
17
|
|
17
18
|
context 'Initialization:' do
|
18
|
-
it '
|
19
|
-
expect {
|
19
|
+
it 'is initialized with an environment' do
|
20
|
+
expect { described_class.new(SkmFrame.new) }.not_to raise_error
|
20
21
|
end
|
21
22
|
|
22
|
-
it '
|
23
|
-
expect(
|
23
|
+
it 'knows the environment' do
|
24
|
+
expect(runtime.environment).to eq(some_env)
|
24
25
|
end
|
25
26
|
|
26
|
-
it '
|
27
|
-
expect(
|
27
|
+
it 'has an empty call stack' do
|
28
|
+
expect(runtime.call_stack).to be_empty
|
28
29
|
end
|
29
30
|
end # context
|
30
31
|
|
31
32
|
context 'Provided services:' do
|
32
|
-
it '
|
33
|
+
it 'adds entries to the environment' do
|
33
34
|
entry = double('dummy')
|
34
|
-
|
35
|
-
|
36
|
-
expect(
|
35
|
+
allow(entry).to receive(:bound!)
|
36
|
+
runtime.add_binding('dummy', entry)
|
37
|
+
expect(runtime.environment.size).to eq(1)
|
37
38
|
end
|
38
39
|
|
39
|
-
it '
|
40
|
-
expect(
|
40
|
+
it 'knows the keys in the environment' do
|
41
|
+
expect(runtime).not_to include('dummy')
|
41
42
|
entry = double('dummy')
|
42
|
-
|
43
|
-
|
44
|
-
expect(
|
43
|
+
allow(entry).to receive(:bound!)
|
44
|
+
runtime.add_binding('dummy', entry)
|
45
|
+
expect(runtime).to include('dummy')
|
45
46
|
end
|
46
47
|
end # context
|
47
48
|
|
48
49
|
context 'Evaluation:' do
|
49
50
|
include Primitive::PrimitiveBuilder
|
50
51
|
|
51
|
-
# it '
|
52
|
+
# it 'evaluates a given entry' do
|
52
53
|
# entry = integer(3)
|
53
54
|
# result = double('fake-procedure')
|
54
|
-
# expect(entry).to
|
55
|
-
# expect(result).to
|
56
|
-
#
|
57
|
-
# expect(
|
55
|
+
# expect(entry).to have_received(:expression).and_return(result)
|
56
|
+
# expect(result).to have_received(:evaluate).with(runtime).and_return(integer(3))
|
57
|
+
# runtime.define('three', entry)
|
58
|
+
# expect(runtime.evaluate('three')).to eq(3)
|
58
59
|
# end
|
59
60
|
|
60
|
-
it '
|
61
|
-
add_primitives(
|
61
|
+
it 'evaluates a given list' do
|
62
|
+
add_primitives(runtime)
|
62
63
|
sum = list([identifier('+'), 3, 4])
|
63
64
|
|
64
|
-
expect(
|
65
|
+
expect(runtime.evaluate_form(sum)).to eq(7)
|
65
66
|
end
|
66
67
|
end # context
|
67
68
|
|
68
69
|
context 'Environment nesting:' do
|
69
|
-
it '
|
70
|
-
expect(
|
71
|
-
env_before =
|
72
|
-
|
73
|
-
|
74
|
-
expect(
|
75
|
-
expect(
|
76
|
-
expect(
|
70
|
+
it 'adds nested environment' do
|
71
|
+
expect(runtime.depth).to eq(1)
|
72
|
+
env_before = runtime.environment
|
73
|
+
runtime.nest
|
74
|
+
|
75
|
+
expect(runtime.environment).not_to eq(env_before)
|
76
|
+
expect(runtime.environment.parent).to eq(env_before)
|
77
|
+
expect(runtime.depth).to eq(2)
|
77
78
|
end
|
78
79
|
|
79
|
-
it '
|
80
|
-
expect(
|
81
|
-
|
82
|
-
parent_before =
|
83
|
-
expect(
|
80
|
+
it 'removes nested environment' do
|
81
|
+
expect(runtime.depth).to eq(1)
|
82
|
+
runtime.nest
|
83
|
+
parent_before = runtime.environment.parent
|
84
|
+
expect(runtime.depth).to eq(2)
|
84
85
|
|
85
|
-
|
86
|
-
expect(
|
87
|
-
expect(
|
86
|
+
runtime.unnest
|
87
|
+
expect(runtime.environment).to eq(parent_before)
|
88
|
+
expect(runtime.depth).to eq(1)
|
88
89
|
end
|
89
90
|
end # context
|
90
91
|
|
@@ -94,23 +95,23 @@ module Skeem
|
|
94
95
|
ProcedureCall.new(pos, identifier('boolean?'), [integer(42)])
|
95
96
|
end
|
96
97
|
|
97
|
-
it '
|
98
|
-
expect {
|
99
|
-
expect(
|
100
|
-
expect(
|
98
|
+
it 'pushes a call to the stack call' do
|
99
|
+
expect { runtime.push_call(sample_call) }.not_to raise_error
|
100
|
+
expect(runtime.call_stack.size).to eq(1)
|
101
|
+
expect(runtime.caller).to eq(sample_call)
|
101
102
|
|
102
|
-
|
103
|
-
expect(
|
103
|
+
runtime.push_call(sample_call.clone)
|
104
|
+
expect(runtime.call_stack.size).to eq(2)
|
104
105
|
end
|
105
106
|
|
106
|
-
it '
|
107
|
-
|
108
|
-
expect {
|
109
|
-
expect(
|
107
|
+
it 'pops a call from the call stack' do
|
108
|
+
runtime.push_call(sample_call)
|
109
|
+
expect { runtime.pop_call }.not_to raise_error
|
110
|
+
expect(runtime.call_stack).to be_empty
|
110
111
|
|
111
112
|
err = StandardError
|
112
113
|
msg = 'Skeem call stack empty!'
|
113
|
-
expect {
|
114
|
+
expect { runtime.pop_call }.to raise_error(err, msg)
|
114
115
|
end
|
115
116
|
end # context
|
116
117
|
end # describe
|
@@ -12,27 +12,27 @@ module Skeem
|
|
12
12
|
let(:operator) { SkmIdentifier.create('+') }
|
13
13
|
let(:operands) { [1, 2, 3] }
|
14
14
|
|
15
|
-
subject {
|
15
|
+
subject(:proc_call) { described_class.new(pos, operator, operands) }
|
16
16
|
|
17
17
|
context 'Initialization:' do
|
18
|
-
it '
|
19
|
-
expect {
|
18
|
+
it 'is initialized with an operator symbol and its operands' do
|
19
|
+
expect { described_class.new(pos, operator, operands) }.not_to raise_error
|
20
20
|
end
|
21
21
|
|
22
|
-
it '
|
23
|
-
expect(
|
22
|
+
it 'knows its operator' do
|
23
|
+
expect(proc_call.operator).to eq(operator)
|
24
24
|
end
|
25
25
|
|
26
|
-
it '
|
27
|
-
expect(
|
26
|
+
it 'knows its operands' do
|
27
|
+
expect(proc_call.operands.inspect).to eq('<Skeem::SkmPair: 1, 2, 3>')
|
28
28
|
end
|
29
29
|
end # context
|
30
30
|
|
31
31
|
context 'Provided services:' do
|
32
|
-
it '
|
32
|
+
it 'returns its text representation' do
|
33
33
|
txt1 = '<Skeem::ProcedureCall: <Skeem::SkmIdentifier: +>, '
|
34
34
|
txt2 = '@operands <Skeem::SkmPair: 1, 2, 3>>'
|
35
|
-
expect(
|
35
|
+
expect(proc_call.inspect).to eq(txt1 + txt2)
|
36
36
|
end
|
37
37
|
end # context
|
38
38
|
end # describe
|
@@ -43,32 +43,32 @@ module Skeem
|
|
43
43
|
let(:s_consequent) { double('fake-consequent') }
|
44
44
|
let(:s_alt) { double('fake-alternate') }
|
45
45
|
|
46
|
-
subject {
|
46
|
+
subject(:condition) { described_class.new(pos, s_test, s_consequent, s_alt) }
|
47
47
|
|
48
48
|
context 'Initialization:' do
|
49
|
-
it '
|
50
|
-
expect {
|
49
|
+
it 'is initialized with a pos and 3 expressions' do
|
50
|
+
expect { described_class.new(pos, s_test, s_consequent, s_alt) }.not_to raise_error
|
51
51
|
end
|
52
52
|
|
53
|
-
it '
|
54
|
-
expect(
|
53
|
+
it 'knows its test' do
|
54
|
+
expect(condition.test).to eq(s_test)
|
55
55
|
end
|
56
56
|
|
57
|
-
it '
|
58
|
-
expect(
|
57
|
+
it 'knows its consequent' do
|
58
|
+
expect(condition.consequent).to eq(s_consequent)
|
59
59
|
end
|
60
60
|
|
61
|
-
it '
|
62
|
-
expect(
|
61
|
+
it 'knows its alternate' do
|
62
|
+
expect(condition.alternate).to eq(s_alt)
|
63
63
|
end
|
64
64
|
end # context
|
65
65
|
|
66
66
|
context 'Provided services:' do
|
67
|
-
it '
|
67
|
+
it 'returns its text representation' do
|
68
68
|
txt1 = '<Skeem::SkmCondition: @test #<Double "fake-test">, '
|
69
69
|
txt2 = '@consequent #<Double "fake-consequent">, '
|
70
70
|
txt3 = '@alternate #<Double "fake-alternate">>'
|
71
|
-
expect(
|
71
|
+
expect(condition.inspect).to eq(txt1 + txt2 + txt3)
|
72
72
|
end
|
73
73
|
end # context
|
74
74
|
end # describe
|
@@ -80,33 +80,33 @@ module Skeem
|
|
80
80
|
let(:s_sequence) { double('fake-sequence') }
|
81
81
|
let(:s_body) { { defs: s_defs, sequence: s_sequence } }
|
82
82
|
|
83
|
-
subject {
|
83
|
+
subject(:lambda_rep) { described_class.new(pos, s_formals, s_body) }
|
84
84
|
|
85
85
|
context 'Initialization:' do
|
86
|
-
it '
|
87
|
-
expect {
|
86
|
+
it 'is initialized with a pos and 3 expressions' do
|
87
|
+
expect { described_class.new(pos, s_formals, s_body) }.not_to raise_error
|
88
88
|
end
|
89
89
|
|
90
|
-
it '
|
91
|
-
expect(
|
90
|
+
it 'knows its formals' do
|
91
|
+
expect(lambda_rep.formals).to eq(s_formals)
|
92
92
|
end
|
93
93
|
|
94
|
-
it '
|
95
|
-
expect(
|
94
|
+
it 'knows its definitions' do
|
95
|
+
expect(lambda_rep.definitions).to eq(s_defs)
|
96
96
|
end
|
97
97
|
|
98
|
-
it '
|
99
|
-
expect(
|
98
|
+
it 'knows its sequence' do
|
99
|
+
expect(lambda_rep.sequence).to eq(s_sequence)
|
100
100
|
end
|
101
101
|
end # context
|
102
102
|
|
103
103
|
context 'Provided services:' do
|
104
|
-
it '
|
104
|
+
it 'returns its text representation' do
|
105
105
|
txt1 = '<Skeem::SkmLambdaRep: @formals #<Double "fake-formals">, '
|
106
106
|
txt2 = '@definitions #<Double "fake-definitions">, '
|
107
107
|
txt3 = '@sequence #<Double "fake-sequence">>>'
|
108
108
|
# Remove "unpredictable" part of actual text
|
109
|
-
expectation =
|
109
|
+
expectation = lambda_rep.inspect.gsub(/@object_id=[0-9a-z]+, /, '')
|
110
110
|
expect(expectation).to eq(txt1 + txt2 + txt3)
|
111
111
|
end
|
112
112
|
end # context
|
@@ -8,49 +8,49 @@ module Skeem
|
|
8
8
|
describe SkmCompoundDatum do
|
9
9
|
include DatumDSL
|
10
10
|
|
11
|
-
let(:sample_members) { [1, 2, 3] }
|
12
11
|
let(:sample_members) { [integer(1), integer(2), integer(3)] }
|
13
|
-
|
12
|
+
|
13
|
+
subject(:datum) { described_class.new(sample_members) }
|
14
14
|
|
15
15
|
context 'Initialization:' do
|
16
|
-
it '
|
17
|
-
expect {
|
16
|
+
it 'is initialized with its members' do
|
17
|
+
expect { described_class.new(sample_members) }.not_to raise_error
|
18
18
|
end
|
19
19
|
|
20
|
-
it '
|
21
|
-
expect(
|
20
|
+
it 'knows its members' do
|
21
|
+
expect(datum.members).to eq(sample_members)
|
22
22
|
|
23
|
-
other =
|
23
|
+
other = described_class.new([])
|
24
24
|
expect(other.members).to be_empty
|
25
25
|
end
|
26
26
|
end # context
|
27
27
|
|
28
28
|
context 'Provided basic services:' do
|
29
|
-
it '
|
30
|
-
expect(
|
29
|
+
it 'asserts that it is equal to itself' do
|
30
|
+
expect(datum).to eq(datum)
|
31
31
|
end
|
32
32
|
|
33
|
-
it '
|
33
|
+
it 'asserts the equality by member values' do
|
34
34
|
# Comparison with other instances
|
35
|
-
expect(
|
36
|
-
expect(
|
37
|
-
expect(
|
35
|
+
expect(datum).to eq(described_class.new(sample_members))
|
36
|
+
expect(datum).not_to eq(described_class.new([]))
|
37
|
+
expect(datum).not_to eq(described_class.new(sample_members.rotate))
|
38
38
|
|
39
39
|
# Comparison with array of values
|
40
|
-
expect(
|
41
|
-
expect(
|
40
|
+
expect(datum).to eq(sample_members)
|
41
|
+
expect(datum).not_to eq(sample_members.rotate)
|
42
42
|
end
|
43
43
|
|
44
|
-
it '
|
44
|
+
it 'responds to visitor' do
|
45
45
|
visitor = double('fake-visitor')
|
46
|
-
|
47
|
-
expect {
|
46
|
+
allow(visitor).to receive(:visit_compound_datum).with(datum)
|
47
|
+
expect { datum.accept(visitor) }.not_to raise_error
|
48
48
|
end
|
49
49
|
|
50
|
-
it '
|
50
|
+
it 'returns its text representation' do
|
51
51
|
txt1 = '<Skeem::SkmCompoundDatum: <Skeem::SkmInteger: 1>,'
|
52
52
|
txt2 = '<Skeem::SkmInteger: 2>, <Skeem::SkmInteger: 3>>'
|
53
|
-
expect(
|
53
|
+
expect(datum.inspect).to eq("#{txt1} #{txt2}")
|
54
54
|
end
|
55
55
|
end # context
|
56
56
|
|
@@ -59,39 +59,40 @@ module Skeem
|
|
59
59
|
let(:quirk_members) { [integer(1), quirk_datum, integer(3)] }
|
60
60
|
let(:runtime) { double('fake-runtime') }
|
61
61
|
|
62
|
-
it '
|
62
|
+
it 'evaluates its members' do
|
63
63
|
# subject contains simple literals
|
64
|
-
expect(
|
64
|
+
expect(datum.evaluate(runtime)).to eq(datum)
|
65
65
|
|
66
66
|
# Check that members receive the 'evaluate' message
|
67
|
-
|
68
|
-
instance =
|
69
|
-
expect(instance.evaluate(runtime)).to eq(
|
67
|
+
allow(quirk_datum).to receive(:evaluate).with(runtime).and_return(integer(2))
|
68
|
+
instance = described_class.new(quirk_members)
|
69
|
+
expect(instance.evaluate(runtime)).to eq(datum)
|
70
70
|
end
|
71
71
|
|
72
|
-
it '
|
72
|
+
it 'quasiquotes its members' do
|
73
73
|
# subject contains simple literals
|
74
|
-
expect(
|
74
|
+
expect(datum.quasiquote(runtime)).to eq(datum)
|
75
75
|
|
76
76
|
# Check that members receive the 'quasiquote' message
|
77
|
-
|
78
|
-
instance =
|
79
|
-
expect(instance.quasiquote(runtime)).to eq(
|
77
|
+
allow(quirk_datum).to receive(:quasiquote).with(runtime).and_return(integer(2))
|
78
|
+
instance = described_class.new(quirk_members)
|
79
|
+
expect(instance.quasiquote(runtime)).to eq(datum)
|
80
80
|
end
|
81
81
|
end # context
|
82
82
|
end # describe
|
83
83
|
|
84
84
|
describe SkmVector do
|
85
85
|
let(:sample_members) { [1, 2, 3] }
|
86
|
-
|
86
|
+
|
87
|
+
subject(:vector) { described_class.new(sample_members) }
|
87
88
|
|
88
89
|
context 'Initialization:' do
|
89
|
-
it '
|
90
|
-
expect {
|
90
|
+
it 'is initialized with its members' do
|
91
|
+
expect { described_class.new(sample_members) }.not_to raise_error
|
91
92
|
end
|
92
93
|
|
93
|
-
it '
|
94
|
-
expect(
|
94
|
+
it 'reacts positively to vector? predicate' do
|
95
|
+
expect(vector).to be_vector
|
95
96
|
end
|
96
97
|
end # context
|
97
98
|
end # describe
|
@@ -6,30 +6,31 @@ require_relative '../../lib/skeem/skm_element' # Load the class under test
|
|
6
6
|
module Skeem
|
7
7
|
describe SkmElement do
|
8
8
|
let(:pos) { double('fake-position') }
|
9
|
-
|
9
|
+
|
10
|
+
subject(:element) { described_class.new(pos) }
|
10
11
|
|
11
12
|
context 'Initialization:' do
|
12
|
-
it '
|
13
|
-
expect {
|
13
|
+
it 'is initialized with a position' do
|
14
|
+
expect { described_class.new(pos) }.not_to raise_error
|
14
15
|
end
|
15
16
|
|
16
|
-
it '
|
17
|
-
expect(
|
17
|
+
it 'knows its position' do
|
18
|
+
expect(element.position).to eq(pos)
|
18
19
|
end
|
19
20
|
|
20
21
|
# Default (overridable) behavior of SkmElement
|
21
|
-
it '
|
22
|
-
expect(
|
23
|
-
expect(
|
24
|
-
expect(
|
25
|
-
expect(
|
26
|
-
expect(
|
27
|
-
expect(
|
28
|
-
expect(
|
29
|
-
expect(
|
30
|
-
expect(
|
31
|
-
expect(
|
32
|
-
expect(
|
22
|
+
it 'reacts by default to predicates' do
|
23
|
+
expect(element).not_to be_boolean
|
24
|
+
expect(element).not_to be_number
|
25
|
+
expect(element).not_to be_real
|
26
|
+
expect(element).not_to be_integer
|
27
|
+
expect(element).not_to be_string
|
28
|
+
expect(element).not_to be_symbol
|
29
|
+
expect(element).not_to be_list
|
30
|
+
expect(element).not_to be_null
|
31
|
+
expect(element).not_to be_pair
|
32
|
+
expect(element).not_to be_vector
|
33
|
+
expect(element).not_to be_verbatim
|
33
34
|
end
|
34
35
|
end # context
|
35
36
|
|
@@ -38,38 +39,38 @@ module Skeem
|
|
38
39
|
let(:visitor) { double('fake-visitor') }
|
39
40
|
let(:not_implemented) { NotImplementedError }
|
40
41
|
|
41
|
-
it '
|
42
|
-
expect(
|
43
|
-
expect(
|
42
|
+
it 'is equivalent to itself' do
|
43
|
+
expect(element).to be_eqv(element)
|
44
|
+
expect(element).not_to be_eqv(element.clone)
|
44
45
|
end
|
45
46
|
|
46
|
-
it "
|
47
|
-
expect {
|
47
|
+
it "ignores the 'done!' message" do
|
48
|
+
expect { element.done! }.not_to raise_error
|
48
49
|
end
|
49
50
|
|
50
|
-
it "
|
51
|
-
expect {
|
51
|
+
it "ignores the 'quoted!' message" do
|
52
|
+
expect { element.quoted! }.not_to raise_error
|
52
53
|
end
|
53
54
|
|
54
|
-
it "
|
55
|
-
expect {
|
55
|
+
it "ignores the 'unquoted!' message" do
|
56
|
+
expect { element.unquoted! }.not_to raise_error
|
56
57
|
end
|
57
58
|
|
58
|
-
it "
|
59
|
+
it "complains when receiving 'skm_equal?' message" do
|
59
60
|
msg = 'Missing implementation of method Skeem::SkmElement#skm_equal?'
|
60
|
-
expect {
|
61
|
+
expect { element.skm_equal?('omg') }.to raise_error(NotImplementedError, msg)
|
61
62
|
end
|
62
63
|
|
63
|
-
it "
|
64
|
-
expect {
|
64
|
+
it "complains when receiving 'evaluate' message" do
|
65
|
+
expect { element.evaluate(runtime) }.to raise_error(not_implemented)
|
65
66
|
end
|
66
67
|
|
67
|
-
it "
|
68
|
-
expect {
|
68
|
+
it "complains when receiving 'quasiquote' message" do
|
69
|
+
expect { element.quasiquote(runtime) }.to raise_error(not_implemented)
|
69
70
|
end
|
70
71
|
|
71
|
-
it "
|
72
|
-
expect {
|
72
|
+
it "complains when receiving 'accept' message" do
|
73
|
+
expect { element.accept(visitor) }.to raise_error(not_implemented)
|
73
74
|
end
|
74
75
|
end # context
|
75
76
|
end # describe
|