mini_kraken 0.1.01 → 0.1.02
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/CHANGELOG.md +3 -0
- data/README.md +0 -3
- data/lib/mini_kraken/core/any_value.rb +29 -0
- data/lib/mini_kraken/core/association.rb +21 -0
- data/lib/mini_kraken/core/association_walker.rb +179 -0
- data/lib/mini_kraken/core/atomic_term.rb +64 -0
- data/lib/mini_kraken/core/binary_relation.rb +61 -0
- data/lib/mini_kraken/core/composite_term.rb +54 -0
- data/lib/mini_kraken/core/cons_cell.rb +44 -0
- data/lib/mini_kraken/core/duck_fiber.rb +44 -0
- data/lib/mini_kraken/core/environment.rb +59 -0
- data/lib/mini_kraken/core/equals.rb +216 -0
- data/lib/mini_kraken/core/fail.rb +8 -5
- data/lib/mini_kraken/core/freshness.rb +42 -0
- data/lib/mini_kraken/core/goal.rb +31 -6
- data/lib/mini_kraken/core/k_integer.rb +15 -0
- data/lib/mini_kraken/core/k_symbol.rb +15 -0
- data/lib/mini_kraken/core/nullary_relation.rb +11 -3
- data/lib/mini_kraken/core/outcome.rb +35 -0
- data/lib/mini_kraken/core/relation.rb +31 -4
- data/lib/mini_kraken/core/succeed.rb +13 -1
- data/lib/mini_kraken/core/term.rb +7 -0
- data/lib/mini_kraken/core/variable.rb +45 -3
- data/lib/mini_kraken/core/variable_ref.rb +76 -0
- data/lib/mini_kraken/core/vocabulary.rb +161 -0
- data/lib/mini_kraken/glue/fresh_env.rb +31 -0
- data/lib/mini_kraken/glue/run_star_expression.rb +43 -0
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/core/association_spec.rb +38 -0
- data/spec/core/association_walker_spec.rb +191 -0
- data/spec/core/cons_cell_spec.rb +63 -0
- data/spec/core/duck_fiber_spec.rb +62 -0
- data/spec/core/environment_spec.rb +154 -0
- data/spec/core/equals_spec.rb +289 -0
- data/spec/core/fail_spec.rb +16 -0
- data/spec/core/goal_spec.rb +36 -10
- data/spec/core/k_symbol_spec.rb +72 -0
- data/spec/core/succeed_spec.rb +43 -0
- data/spec/core/variable_ref_spec.rb +31 -0
- data/spec/core/variable_spec.rb +11 -3
- data/spec/core/vocabulary_spec.rb +188 -0
- data/spec/glue/fresh_env_spec.rb +36 -0
- data/spec/glue/run_star_expression_spec.rb +247 -0
- data/spec/support/factory_methods.rb +54 -0
- metadata +46 -13
- data/lib/mini_kraken/core/facade.rb +0 -45
- data/lib/mini_kraken/core/formal_arg.rb +0 -6
- data/lib/mini_kraken/core/publisher.rb +0 -27
- data/lib/mini_kraken/core/run_star_expression.rb +0 -34
- data/lib/mini_kraken/dsl/kraken_dsl.rb +0 -12
- data/spec/core/facade_spec.rb +0 -38
- data/spec/core/run_star_expression_spec.rb +0 -43
- data/spec/dsl/kraken_dsl_spec.rb +0 -31
@@ -0,0 +1,289 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../lib/mini_kraken/core/environment'
|
5
|
+
|
6
|
+
require_relative '../support/factory_methods'
|
7
|
+
# Load the class under test
|
8
|
+
require_relative '../../lib/mini_kraken/core/equals'
|
9
|
+
|
10
|
+
module MiniKraken
|
11
|
+
module Core
|
12
|
+
describe Equals do
|
13
|
+
include FactoryMethods
|
14
|
+
|
15
|
+
subject { Equals.instance }
|
16
|
+
|
17
|
+
context 'Initialization:' do
|
18
|
+
it 'should be created without argument' do
|
19
|
+
expect { Equals.instance }.not_to raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should know its name' do
|
23
|
+
expect(subject.name).to eq('equals')
|
24
|
+
end
|
25
|
+
end # context
|
26
|
+
|
27
|
+
context 'Provided services:' do
|
28
|
+
def build_var(aName)
|
29
|
+
new_var = Variable.new(aName)
|
30
|
+
env.add_var(new_var)
|
31
|
+
new_var
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_var_ref(aName)
|
35
|
+
VariableRef.new(aName)
|
36
|
+
end
|
37
|
+
|
38
|
+
def solve_for(arg1, arg2)
|
39
|
+
solver = subject.solver_for([arg1, arg2], env)
|
40
|
+
outcome = solver.resume
|
41
|
+
env.propagate(outcome)
|
42
|
+
outcome
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:pea) { KSymbol.new(:pea) }
|
46
|
+
let(:pod) { KSymbol.new(:pod) }
|
47
|
+
let(:sample_cons) { ConsCell.new(pea, nil) }
|
48
|
+
let(:a_composite) { ConsCell.new(pod) }
|
49
|
+
let(:env) { Environment.new }
|
50
|
+
let(:var_q) { build_var('q') }
|
51
|
+
let(:ref_q) do
|
52
|
+
dummy = var_q # Force dependency
|
53
|
+
build_var_ref('q')
|
54
|
+
end
|
55
|
+
let(:ref_q_bis) do
|
56
|
+
dummy = var_q # Force dependency
|
57
|
+
build_var_ref('q')
|
58
|
+
end
|
59
|
+
let(:var_x) { build_var('x') }
|
60
|
+
let(:ref_x) do
|
61
|
+
dummy = var_x # Force dependency
|
62
|
+
build_var_ref('x')
|
63
|
+
end
|
64
|
+
let(:var_y) { build_var('y') }
|
65
|
+
let(:ref_y) do
|
66
|
+
dummy = var_y # Force dependency
|
67
|
+
build_var_ref('y')
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
it 'should succeed for equal literal arguments' do
|
72
|
+
result = solve_for(pea, pea)
|
73
|
+
|
74
|
+
expect(result).to be_kind_of(Outcome)
|
75
|
+
expect(result.resultant).to eq(:"#s")
|
76
|
+
expect(result.associations).to be_empty
|
77
|
+
expect(var_q.fresh?(env)).to be_truthy
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should fail for inequal literal arguments' do
|
81
|
+
result = solve_for(pea, pod)
|
82
|
+
|
83
|
+
expect(result.resultant).to eq(:"#u")
|
84
|
+
expect(result.associations).to be_empty
|
85
|
+
expect(var_q.fresh?(env)).to be_truthy
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should fail for one left literal and one composite arguments' do
|
89
|
+
result = solve_for(pea, sample_cons)
|
90
|
+
|
91
|
+
expect(result.resultant).to eq(:"#u")
|
92
|
+
expect(result.associations).to be_empty
|
93
|
+
expect(var_q.fresh?(env)).to be_truthy
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should fail for one right literal and one composite arguments' do
|
97
|
+
result = solve_for(sample_cons, pea)
|
98
|
+
|
99
|
+
expect(result.resultant).to eq(:"#u")
|
100
|
+
expect(result.associations).to be_empty
|
101
|
+
expect(var_q.fresh?(env)).to be_truthy
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should succeed for a right-handed fresh argument' do
|
105
|
+
result = solve_for(pea, ref_q)
|
106
|
+
|
107
|
+
expect(result).to be_successful
|
108
|
+
expect(env.associations.size).to eq(1)
|
109
|
+
expect(env.associations['q'].first.value).to eq(pea)
|
110
|
+
expect(var_q.fresh?(result)).to be_falsey
|
111
|
+
expect(ref_q.values(result).first).to eq(pea)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should succeed for a left-handed fresh argument' do
|
115
|
+
result = solve_for(ref_q, pea)
|
116
|
+
|
117
|
+
expect(result).to be_successful
|
118
|
+
expect(env.associations.size).to eq(1)
|
119
|
+
expect(env.associations['q'].first.value).to eq(pea)
|
120
|
+
expect(var_q.fresh?(result)).to be_falsey
|
121
|
+
expect(ref_q.values(result).first).to eq(pea)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should succeed for a right-handed bound argument equal constant' do
|
125
|
+
ref_q.associate(pod, env)
|
126
|
+
|
127
|
+
result = solve_for(pod, ref_q)
|
128
|
+
expect(result).to be_successful
|
129
|
+
expect(env.associations.size).to eq(1) # No new association
|
130
|
+
expect(ref_q.fresh?(result)).not_to be_truthy
|
131
|
+
expect(ref_q.values(result).first).to eq(pod)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should succeed for a left-handed bound argument equal constant' do
|
135
|
+
ref_q.associate(pod, env)
|
136
|
+
|
137
|
+
result = solve_for(ref_q, pod)
|
138
|
+
expect(result).to be_successful
|
139
|
+
expect(result.associations).to be_empty
|
140
|
+
expect(ref_q.fresh?(result)).to be_falsey
|
141
|
+
expect(ref_q.values(result).first).to eq(pod)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should fail for a right-handed bound argument to a distinct literal' do
|
145
|
+
ref_q.associate(pod, env)
|
146
|
+
|
147
|
+
result = solve_for(pea, ref_q)
|
148
|
+
expect(result).not_to be_successful
|
149
|
+
expect(result.associations).to be_empty
|
150
|
+
expect(ref_q.fresh?(result)).to be_falsey
|
151
|
+
expect(ref_q.values(result).first).to eq(pod)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should fail for a left-handed bound argument to a distinct literal' do
|
155
|
+
ref_q.associate(pod, env)
|
156
|
+
|
157
|
+
result = solve_for(ref_q, pea)
|
158
|
+
expect(result).not_to be_successful
|
159
|
+
expect(result.associations).to be_empty
|
160
|
+
expect(ref_q.fresh?(result)).to be_falsey
|
161
|
+
expect(ref_q.values(result).first).to eq(pod)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should succeed for a composite and right-handed fresh argument' do
|
165
|
+
result = solve_for(sample_cons, ref_q)
|
166
|
+
|
167
|
+
expect(result).to be_successful
|
168
|
+
expect(env.associations.size).to eq(1)
|
169
|
+
expect(ref_q.fresh?(result)).to be_falsey
|
170
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should succeed for composite and left-handed fresh argument' do
|
174
|
+
result = solve_for(ref_q, sample_cons)
|
175
|
+
|
176
|
+
expect(result).to be_successful
|
177
|
+
expect(env.associations.size).to eq(1)
|
178
|
+
expect(ref_q.fresh?(result)).to be_falsey
|
179
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should succeed for a right-handed bound equal argument' do
|
183
|
+
ref_q.associate(sample_cons, env)
|
184
|
+
composite = ConsCell.new(pea)
|
185
|
+
result = solve_for(composite, ref_q)
|
186
|
+
|
187
|
+
expect(result).to be_successful
|
188
|
+
expect(result.associations).to be_empty
|
189
|
+
expect(ref_q.fresh?(result)).not_to be_truthy
|
190
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should succeed for a left-handed bound equal argument' do
|
194
|
+
ref_q.associate(sample_cons, env)
|
195
|
+
composite = ConsCell.new(pea)
|
196
|
+
result = solve_for(ref_q, composite)
|
197
|
+
|
198
|
+
expect(result).to be_successful
|
199
|
+
expect(result.associations).to be_empty
|
200
|
+
expect(ref_q.fresh?(result)).not_to be_truthy
|
201
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should succeed for a right-handed bound unequal argument' do
|
205
|
+
ref_q.associate(sample_cons, env)
|
206
|
+
composite = ConsCell.new(pod)
|
207
|
+
result = solve_for(composite, ref_q)
|
208
|
+
|
209
|
+
expect(result).not_to be_successful
|
210
|
+
expect(result.associations).to be_empty
|
211
|
+
expect(ref_q.fresh?(result)).not_to be_truthy
|
212
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should succeed for a left-handed bound unequal argument' do
|
216
|
+
ref_q.associate(sample_cons, env)
|
217
|
+
composite = ConsCell.new(pod)
|
218
|
+
result = solve_for(ref_q, composite)
|
219
|
+
|
220
|
+
expect(result).not_to be_successful
|
221
|
+
expect(result.associations).to be_empty
|
222
|
+
expect(ref_q.fresh?(result)).not_to be_truthy
|
223
|
+
expect(ref_q.values(result).first).to eq(sample_cons)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should succeed for both identical fresh arguments' do
|
227
|
+
result = solve_for(ref_q, ref_q)
|
228
|
+
|
229
|
+
expect(result).to be_successful
|
230
|
+
expect(result.associations).to be_empty
|
231
|
+
expect(ref_q.fresh?(result)).to be_truthy
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should succeed for both same fresh arguments' do
|
235
|
+
result = solve_for(ref_q, ref_q_bis)
|
236
|
+
|
237
|
+
expect(result).to be_successful
|
238
|
+
expect(result.associations).to be_empty
|
239
|
+
expect(ref_q.fresh?(result)).to be_truthy
|
240
|
+
expect(ref_q_bis.fresh?(result)).to be_truthy
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should succeed for both distinct fresh arguments' do
|
244
|
+
result = solve_for(ref_x, ref_y)
|
245
|
+
|
246
|
+
expect(result).to be_successful
|
247
|
+
expect(env.associations.size).to eq(2) # Symmetric association
|
248
|
+
expect(ref_x.fresh?(result)).to be_truthy
|
249
|
+
expect(ref_y.fresh?(result)).to be_truthy
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should succeed for arguments bound to equal values' do
|
253
|
+
ref_x.associate(pea, env)
|
254
|
+
ref_y.associate(pea, env)
|
255
|
+
expect(ref_x.fresh?(env)).to be_falsey
|
256
|
+
expect(ref_y.fresh?(env)).to be_falsey
|
257
|
+
|
258
|
+
result = solve_for(ref_x, ref_y)
|
259
|
+
expect(result).to be_successful
|
260
|
+
expect(result.associations).to be_empty
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should fail for arguments bound unequal values' do
|
264
|
+
ref_x.associate(pea, env)
|
265
|
+
ref_y.associate(pod, env)
|
266
|
+
expect(ref_x.fresh?(env)).to be_falsey
|
267
|
+
expect(ref_y.fresh?(env)).to be_falsey
|
268
|
+
|
269
|
+
result = solve_for(ref_x, ref_y)
|
270
|
+
expect(result).not_to be_successful
|
271
|
+
expect(result.associations).to be_empty
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'should unify composite terms with variables' do
|
275
|
+
# Reasoned S2, frame 1:36
|
276
|
+
# (run* q (fresh (x) (== '(((,q)) (,x)) `(((,x)) pod)))) ;; => ('pod)
|
277
|
+
expr1 = cons(cons(ref_q), ref_x)
|
278
|
+
expr2 = cons(cons(ref_x), pod)
|
279
|
+
|
280
|
+
result = solve_for(expr1, expr2)
|
281
|
+
# require 'debug'
|
282
|
+
expect(result).to be_successful
|
283
|
+
expect(ref_x.fresh?(env)).to be_falsey
|
284
|
+
expect(ref_q.fresh?(env)).to be_falsey
|
285
|
+
end
|
286
|
+
end # context
|
287
|
+
end # describe
|
288
|
+
end # module
|
289
|
+
end # module
|
data/spec/core/fail_spec.rb
CHANGED
@@ -21,6 +21,22 @@ module MiniKraken
|
|
21
21
|
end # context
|
22
22
|
|
23
23
|
context 'Provided services:' do
|
24
|
+
it 'should unconditionally return a failure result' do
|
25
|
+
args = double('fake-args')
|
26
|
+
env = double('fake-env')
|
27
|
+
|
28
|
+
solver = nil
|
29
|
+
expect { solver = subject.solver_for(args, env) }.not_to raise_error
|
30
|
+
|
31
|
+
# Solver should quack like a Fiber
|
32
|
+
dummy_arg = double('dummy-stuff')
|
33
|
+
result = solver.resume(dummy_arg)
|
34
|
+
expect(result).to eq(Failure)
|
35
|
+
|
36
|
+
# Only one "solution", next 'resume' call should return nil
|
37
|
+
result = solver.resume(dummy_arg)
|
38
|
+
expect(result).to be_nil
|
39
|
+
end
|
24
40
|
end # context
|
25
41
|
end # describe
|
26
42
|
end # module
|
data/spec/core/goal_spec.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../lib/mini_kraken/core/environment'
|
5
|
+
require_relative '../../lib/mini_kraken/core/equals'
|
4
6
|
require_relative '../../lib/mini_kraken/core/fail'
|
7
|
+
require_relative '../../lib/mini_kraken/core/k_symbol'
|
5
8
|
|
6
9
|
# Load the class under test
|
7
10
|
require_relative '../../lib/mini_kraken/core/goal'
|
@@ -9,26 +12,49 @@ require_relative '../../lib/mini_kraken/core/goal'
|
|
9
12
|
module MiniKraken
|
10
13
|
module Core
|
11
14
|
describe Goal do
|
12
|
-
let(:
|
13
|
-
subject { Goal.new(
|
15
|
+
let(:nullary_relation) { Fail.instance }
|
16
|
+
subject { Goal.new(nullary_relation, []) }
|
17
|
+
let(:binary_relation) { Equals.instance }
|
18
|
+
let(:env) { Environment.new }
|
19
|
+
subject { Goal.new(binary_relation, [KSymbol.new(:pea), KSymbol.new(:pod)]) }
|
14
20
|
|
15
21
|
context 'Initialization:' do
|
16
|
-
it 'should accept one
|
17
|
-
expect { Goal.new(
|
22
|
+
it 'should accept one nullary relation and empty argument array' do
|
23
|
+
expect { Goal.new(nullary_relation, []) }.not_to raise_error
|
18
24
|
end
|
25
|
+
|
26
|
+
it 'should accept one binary relation and 2-elements array' do
|
27
|
+
expect { Goal.new(binary_relation, [KSymbol.new(:pea), KSymbol.new(:pod)]) }.not_to raise_error
|
28
|
+
end
|
19
29
|
|
20
30
|
it 'should know its relation' do
|
21
|
-
expect(subject.relation).to eq(
|
31
|
+
expect(subject.relation).to eq(binary_relation)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should know its actual arguments' do
|
35
|
+
expectations = [KSymbol.new(:pea), KSymbol.new(:pod)]
|
36
|
+
expect(subject.actuals).to eq(expectations)
|
22
37
|
end
|
23
38
|
end # context
|
24
39
|
|
25
40
|
context 'Provided services:' do
|
26
|
-
it 'should
|
27
|
-
|
28
|
-
expect(
|
29
|
-
|
30
|
-
|
41
|
+
it 'should fail if relation does not succeed' do
|
42
|
+
solver = subject.attain(env)
|
43
|
+
expect(solver.resume).not_to be_successful
|
44
|
+
|
45
|
+
# No more solution...
|
46
|
+
expect(solver.resume).to be_nil
|
31
47
|
end
|
48
|
+
|
49
|
+
it 'should succeed if relation succeeds' do
|
50
|
+
instance = Goal.new(binary_relation, [KSymbol.new(:pea), KSymbol.new(:pea)])
|
51
|
+
|
52
|
+
solver = instance.attain(env)
|
53
|
+
expect(solver.resume).to be_successful
|
54
|
+
|
55
|
+
# No more solution...
|
56
|
+
expect(solver.resume).to be_nil
|
57
|
+
end
|
32
58
|
end # context
|
33
59
|
end # describe
|
34
60
|
end # module
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
# Load the class under test
|
7
|
+
require_relative '../../lib/mini_kraken/core/k_symbol'
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Core
|
11
|
+
describe KSymbol do
|
12
|
+
let(:a_value) { :pea }
|
13
|
+
subject { KSymbol.new(a_value) }
|
14
|
+
|
15
|
+
context 'Initialization:' do
|
16
|
+
it 'should be created with a Ruby symbol' do
|
17
|
+
expect { KSymbol.new(a_value) }.not_to raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should know its value' do
|
21
|
+
expect(subject.value).to eq(a_value)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should know that it is a ground term' do
|
25
|
+
env = double('mock-env')
|
26
|
+
visitees = double('fake-visitees')
|
27
|
+
expect(subject.ground?(env)).to be_truthy
|
28
|
+
end
|
29
|
+
end # context
|
30
|
+
|
31
|
+
context 'Provided services:' do
|
32
|
+
it 'should know whether it is equal to another instance' do
|
33
|
+
# Same type, same value
|
34
|
+
other = KSymbol.new(a_value)
|
35
|
+
expect(subject).to be_eql(other)
|
36
|
+
|
37
|
+
# Same type, other value
|
38
|
+
another = KSymbol.new(:pod)
|
39
|
+
expect(subject).not_to be_eql(another)
|
40
|
+
|
41
|
+
# Different type, same value
|
42
|
+
yet_another = OpenStruct.new(:value => :pea)
|
43
|
+
expect(subject).not_to be_eql(yet_another)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should know whether it has same value than other object' do
|
47
|
+
# Same type, same value
|
48
|
+
other = KSymbol.new(a_value)
|
49
|
+
expect(subject == other).to be_truthy
|
50
|
+
|
51
|
+
# Same type, other value
|
52
|
+
another = KSymbol.new(:pod)
|
53
|
+
expect(subject == another).to be_falsy
|
54
|
+
|
55
|
+
# Same duck type, same value
|
56
|
+
yet_another = OpenStruct.new(:value => :pea)
|
57
|
+
expect(subject == yet_another).to be_truthy
|
58
|
+
|
59
|
+
# Different duck type, different value
|
60
|
+
still_another = OpenStruct.new(:value => :pod)
|
61
|
+
expect(subject == still_another).to be_falsy
|
62
|
+
|
63
|
+
# Default Ruby representation, same value
|
64
|
+
expect(subject == :pea).to be_truthy
|
65
|
+
|
66
|
+
# Default Ruby representation, different value
|
67
|
+
expect(subject == :pod).to be_falsy
|
68
|
+
end
|
69
|
+
end # context
|
70
|
+
end # describe
|
71
|
+
end # module
|
72
|
+
end # module
|