porolog 0.0.8 → 1.0.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/README.md +11 -1
- data/Rakefile +2 -2
- data/bin/porolog +34 -13
- data/coverage/badge.svg +1 -1
- data/coverage/index.html +43822 -25140
- data/doc/Array.html +158 -51
- data/doc/Object.html +2 -2
- data/doc/Porolog.html +1584 -1113
- data/doc/Symbol.html +2 -2
- data/doc/_index.html +40 -56
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +8 -4
- data/doc/index.html +8 -4
- data/doc/method_list.html +424 -248
- data/doc/top-level-namespace.html +1 -1
- data/lib/porolog.rb +184 -61
- data/lib/porolog/arguments.rb +12 -11
- data/lib/porolog/core_ext.rb +27 -9
- data/lib/porolog/error.rb +3 -0
- data/lib/porolog/goal.rb +57 -15
- data/lib/porolog/instantiation.rb +55 -9
- data/lib/porolog/predicate.rb +52 -26
- data/lib/porolog/predicate/builtin.rb +825 -0
- data/lib/porolog/rule.rb +8 -24
- data/lib/porolog/scope.rb +1 -1
- data/lib/porolog/tail.rb +5 -0
- data/lib/porolog/value.rb +3 -3
- data/lib/porolog/variable.rb +29 -11
- data/test/porolog/arguments_test.rb +45 -66
- data/test/porolog/core_ext_test.rb +25 -0
- data/test/porolog/goal_test.rb +86 -9
- data/test/porolog/instantiation_test.rb +36 -0
- data/test/porolog/porolog_test.rb +285 -30
- data/test/porolog/predicate/builtin_test.rb +1340 -0
- data/test/porolog/predicate_test.rb +78 -16
- data/test/porolog/rule_test.rb +19 -0
- data/test/porolog/variable_test.rb +44 -55
- data/test/samples_test.rb +277 -0
- data/test/test_helper.rb +9 -0
- metadata +9 -5
@@ -608,6 +608,42 @@ describe 'Porolog' do
|
|
608
608
|
assert_equal [value1], instantiation1.values_for(variable3)
|
609
609
|
end
|
610
610
|
|
611
|
+
it 'should return the value of variable1 given the instantiation of the flathead of variable1' do
|
612
|
+
value1 = goal1.value([1,2,3,4])
|
613
|
+
|
614
|
+
instantiation1 = variable1.instantiate variable2, nil, :flathead
|
615
|
+
variable2.instantiate value1
|
616
|
+
|
617
|
+
assert_equal [[1,2,3,4,UNKNOWN_TAIL]], instantiation1.values_for(variable1)
|
618
|
+
end
|
619
|
+
|
620
|
+
it 'should return the value of variable1 given the instantiation of the flathead of variable2' do
|
621
|
+
value1 = goal1.value([1,2,3,4])
|
622
|
+
|
623
|
+
instantiation1 = variable2.instantiate variable1, :flathead
|
624
|
+
variable2.instantiate value1
|
625
|
+
|
626
|
+
assert_equal [[1,2,3,4,UNKNOWN_TAIL]], instantiation1.values_for(variable1)
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'should return the value of variable1 given the instantiation of the flattail of variable1' do
|
630
|
+
value1 = goal1.value([1,2,3,4])
|
631
|
+
|
632
|
+
instantiation1 = variable1.instantiate variable2, nil, :flattail
|
633
|
+
variable2.instantiate value1
|
634
|
+
|
635
|
+
assert_equal [[UNKNOWN_TAIL,1,2,3,4]], instantiation1.values_for(variable1)
|
636
|
+
end
|
637
|
+
|
638
|
+
it 'should return the value of variable1 given the instantiation of the flattail of variable2' do
|
639
|
+
value1 = goal1.value([1,2,3,4])
|
640
|
+
|
641
|
+
instantiation1 = variable2.instantiate variable1, :flattail
|
642
|
+
variable2.instantiate value1
|
643
|
+
|
644
|
+
assert_equal [[UNKNOWN_TAIL,1,2,3,4]], instantiation1.values_for(variable1)
|
645
|
+
end
|
646
|
+
|
611
647
|
end
|
612
648
|
|
613
649
|
describe '#value_at_index' do
|
@@ -13,10 +13,24 @@ describe 'Porolog' do
|
|
13
13
|
reset
|
14
14
|
end
|
15
15
|
|
16
|
-
describe 'UNKNOWN_TAIL
|
16
|
+
describe 'UNKNOWN_TAIL' do
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
describe '#inspect' do
|
19
|
+
|
20
|
+
it 'should return distinctive notation' do
|
21
|
+
assert_equal '...', UNKNOWN_TAIL.inspect
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#tail' do
|
27
|
+
|
28
|
+
it 'should return itself' do
|
29
|
+
assert_equal UNKNOWN_TAIL, UNKNOWN_TAIL.tail
|
30
|
+
assert_equal UNKNOWN_TAIL, UNKNOWN_TAIL.tail(1)
|
31
|
+
assert_equal UNKNOWN_TAIL, UNKNOWN_TAIL.tail(5)
|
32
|
+
end
|
33
|
+
|
20
34
|
end
|
21
35
|
|
22
36
|
end
|
@@ -73,6 +87,42 @@ describe 'Porolog' do
|
|
73
87
|
assert_Arguments upsilon([]), :upsilon, [[]]
|
74
88
|
end
|
75
89
|
|
90
|
+
it 'should define a method in a base class as an instance method and a class method' do
|
91
|
+
class Base1 ; end
|
92
|
+
|
93
|
+
refute_includes Base1.methods, :localised_predicate
|
94
|
+
refute_includes Base1.instance_methods, :localised_predicate
|
95
|
+
|
96
|
+
class Base1
|
97
|
+
|
98
|
+
builtin :between, class_base: self
|
99
|
+
predicate :localised_predicate, class_base: self
|
100
|
+
|
101
|
+
localised_predicate(:X) << [
|
102
|
+
between(:X, 1, 5)
|
103
|
+
]
|
104
|
+
|
105
|
+
def process
|
106
|
+
localised_predicate(:X).solve_for(:X)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_includes Base1.methods, :localised_predicate
|
111
|
+
assert_includes Base1.instance_methods, :localised_predicate
|
112
|
+
|
113
|
+
refute_includes methods, :localised_predicate
|
114
|
+
|
115
|
+
assert_solutions Base1.localised_predicate(:X), [
|
116
|
+
{ X: 1 },
|
117
|
+
{ X: 2 },
|
118
|
+
{ X: 3 },
|
119
|
+
{ X: 4 },
|
120
|
+
{ X: 5 },
|
121
|
+
]
|
122
|
+
|
123
|
+
assert_equal [1,2,3,4,5], Base1.new.process
|
124
|
+
end
|
125
|
+
|
76
126
|
end
|
77
127
|
|
78
128
|
describe '#unify_goals' do
|
@@ -267,7 +317,7 @@ describe 'Porolog' do
|
|
267
317
|
end
|
268
318
|
|
269
319
|
after do
|
270
|
-
assert_equal 1, @spy.calls.size
|
320
|
+
assert_equal 1, @spy.calls.size, "expected unify_arrays to be called once for #{name}"
|
271
321
|
end
|
272
322
|
|
273
323
|
it 'should unify empty arrays' do
|
@@ -367,9 +417,43 @@ describe 'Porolog' do
|
|
367
417
|
assert_nil unify(:draw, :word, goal), name
|
368
418
|
|
369
419
|
expected_log = [
|
370
|
-
'Cannot unify because
|
420
|
+
'Cannot unify because "picturing" != "something" (variable != variable)'
|
421
|
+
]
|
422
|
+
|
423
|
+
assert_equal expected_log, goal.log
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'should unify the unknown array with a variable' do
|
427
|
+
goal.instantiate :X, UNKNOWN_ARRAY
|
428
|
+
goal.instantiate :Y, [1,2,3,4]
|
429
|
+
|
430
|
+
unifications = unify(goal[:X], goal[:Y], goal)
|
431
|
+
|
432
|
+
expected_unifications = [
|
433
|
+
[goal[:X], goal[:Y], goal, goal]
|
434
|
+
]
|
435
|
+
|
436
|
+
assert_equal expected_unifications, unifications
|
437
|
+
|
438
|
+
expected_log = []
|
439
|
+
|
440
|
+
assert_equal expected_log, goal.log
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'should unify the unknown array with an array' do
|
444
|
+
goal.instantiate :X, [1,2,3,4]
|
445
|
+
goal.instantiate :Y, UNKNOWN_ARRAY
|
446
|
+
|
447
|
+
unifications = unify(goal[:X], goal[:Y], goal)
|
448
|
+
|
449
|
+
expected_unifications = [
|
450
|
+
[goal[:X], goal[:Y], goal, goal]
|
371
451
|
]
|
372
452
|
|
453
|
+
assert_equal expected_unifications, unifications
|
454
|
+
|
455
|
+
expected_log = []
|
456
|
+
|
373
457
|
assert_equal expected_log, goal.log
|
374
458
|
end
|
375
459
|
|
@@ -470,7 +554,7 @@ describe 'Porolog' do
|
|
470
554
|
assert_nil unify([7,11,13], 'word', goal), name
|
471
555
|
|
472
556
|
expected_log = [
|
473
|
-
'Cannot unify [7, 11, 13] with "word"',
|
557
|
+
'Cannot unify [7, 11, 13] with "word" (array != atomic)',
|
474
558
|
]
|
475
559
|
|
476
560
|
assert_equal expected_log, goal.log
|
@@ -480,7 +564,59 @@ describe 'Porolog' do
|
|
480
564
|
assert_nil unify('word', [7,11,13], goal), name
|
481
565
|
|
482
566
|
expected_log = [
|
483
|
-
'Cannot unify "word" with [7, 11, 13]',
|
567
|
+
'Cannot unify "word" with [7, 11, 13] (atomic != array)',
|
568
|
+
]
|
569
|
+
|
570
|
+
assert_equal expected_log, goal.log
|
571
|
+
end
|
572
|
+
|
573
|
+
end
|
574
|
+
|
575
|
+
describe 'when [:array, :tail]' do
|
576
|
+
|
577
|
+
let(:goal) { new_goal :p, :x, :y }
|
578
|
+
|
579
|
+
it 'should unify an array and a tail' do
|
580
|
+
assert unify([7,11,13], Tail.new([[7,11,goal[:P]]]), goal), name
|
581
|
+
|
582
|
+
expected_log = []
|
583
|
+
|
584
|
+
assert_equal expected_log, goal.log
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'should not unify an array and tail when they cannot be unified' do
|
588
|
+
refute unify([7,11,13], Tail.new([[7,11,14]]), goal), name
|
589
|
+
|
590
|
+
expected_log = [
|
591
|
+
'Cannot unify incompatible values: 13 with 14',
|
592
|
+
'Cannot unify: [7, 11, 13] with [7, 11, 14]',
|
593
|
+
'Cannot unify because [7, 11, 13] != *[[7, 11, 14]] (array != tail)'
|
594
|
+
]
|
595
|
+
|
596
|
+
assert_equal expected_log, goal.log
|
597
|
+
end
|
598
|
+
|
599
|
+
end
|
600
|
+
|
601
|
+
describe 'when [:tail, :array]' do
|
602
|
+
|
603
|
+
let(:goal) { new_goal :p, :x, :y }
|
604
|
+
|
605
|
+
it 'should unify a tail and an array' do
|
606
|
+
assert unify(Tail.new([[7,11,13]]), [7,11,goal[:P]], goal), name
|
607
|
+
|
608
|
+
expected_log = []
|
609
|
+
|
610
|
+
assert_equal expected_log, goal.log
|
611
|
+
end
|
612
|
+
|
613
|
+
it 'should not unify a tail and an array when they cannot be unified' do
|
614
|
+
refute unify(Tail.new([[7,11,13]]), [7,11,14], goal), name
|
615
|
+
|
616
|
+
expected_log = [
|
617
|
+
'Cannot unify incompatible values: 13 with 14',
|
618
|
+
'Cannot unify: [7, 11, 13] with [7, 11, 14]',
|
619
|
+
'Cannot unify because *[[7, 11, 13]] != [7, 11, 14] (tail != array)'
|
484
620
|
]
|
485
621
|
|
486
622
|
assert_equal expected_log, goal.log
|
@@ -488,6 +624,22 @@ describe 'Porolog' do
|
|
488
624
|
|
489
625
|
end
|
490
626
|
|
627
|
+
describe 'when [:tail, :tail]' do
|
628
|
+
|
629
|
+
it 'something' do
|
630
|
+
expected_unifications = [
|
631
|
+
[goal[:B], [goal[:H]]/:T, goal, goal],
|
632
|
+
[goal[:C], [goal[:H]]/:NT, goal, goal]
|
633
|
+
]
|
634
|
+
assert_equal expected_unifications, unify(
|
635
|
+
[:A, :B, :C],
|
636
|
+
[:A, [:H]/:T, [:H]/:NT],
|
637
|
+
goal
|
638
|
+
)
|
639
|
+
end
|
640
|
+
|
641
|
+
end
|
642
|
+
|
491
643
|
end
|
492
644
|
|
493
645
|
describe '#unify_arrays' do
|
@@ -1094,7 +1246,7 @@ describe 'Porolog' do
|
|
1094
1246
|
|
1095
1247
|
merged, unifications = unify_arrays_with_no_tails(arrays, arrays_goals, [])
|
1096
1248
|
|
1097
|
-
expected_merged = [1, 2, nil, 4,
|
1249
|
+
expected_merged = [1, 2, nil, 4, g3[:z]]
|
1098
1250
|
expected_unifications = [
|
1099
1251
|
[g2[:j], g1[1], g2, g1],
|
1100
1252
|
[g2[:n], g1[2], g2, g1],
|
@@ -1197,21 +1349,6 @@ describe 'Porolog' do
|
|
1197
1349
|
], g3.log
|
1198
1350
|
end
|
1199
1351
|
|
1200
|
-
it 'should raise an exception when an array has no associated goal' do # NOT DONE: need to expose the call to unify_arrays_with_no_tails
|
1201
|
-
|
1202
|
-
error = assert_raises Porolog::NoGoalError do
|
1203
|
-
variable1 = Variable.new :x, g1
|
1204
|
-
value = Value.new [7,11,13,23,29], g2
|
1205
|
-
|
1206
|
-
variable1.values << [7,11,13,23,29]
|
1207
|
-
variable1.values << [7,12,13,23,29]
|
1208
|
-
|
1209
|
-
variable1.instantiate value
|
1210
|
-
end
|
1211
|
-
|
1212
|
-
assert_equal 'Array [7, 11, 13, 23, 29] has no goal for unification', error.message
|
1213
|
-
end
|
1214
|
-
|
1215
1352
|
end
|
1216
1353
|
|
1217
1354
|
describe '#unify_arrays_with_some_tails' do
|
@@ -1307,7 +1444,7 @@ describe 'Porolog' do
|
|
1307
1444
|
|
1308
1445
|
merged, unifications = unify_arrays_with_some_tails(arrays, arrays_goals, [])
|
1309
1446
|
|
1310
|
-
expected_merged = [1, 2, nil, 4,
|
1447
|
+
expected_merged = [1, 2, nil, 4, g3[:z]]
|
1311
1448
|
expected_unifications = [
|
1312
1449
|
[g2.variable(:j), g1.value(1), g2, g1],
|
1313
1450
|
[g3.variable(:x), g1.value(1), g3, g1],
|
@@ -1466,7 +1603,7 @@ describe 'Porolog' do
|
|
1466
1603
|
|
1467
1604
|
end
|
1468
1605
|
|
1469
|
-
describe '#unify_arrays_with_all_tails' do
|
1606
|
+
describe '#unify_arrays_with_all_tails' do
|
1470
1607
|
|
1471
1608
|
let(:g1) { new_goal(:p, :x, :y) }
|
1472
1609
|
let(:g2) { new_goal(:q, :a, :b) }
|
@@ -1527,6 +1664,7 @@ describe 'Porolog' do
|
|
1527
1664
|
[g3[:x], g2[2], g3, g2],
|
1528
1665
|
[g2[:y], g1[5], g2, g1],
|
1529
1666
|
[g1[:z], g3[6], g1, g3],
|
1667
|
+
[g1[:z], g1[6], g1, g1],
|
1530
1668
|
]
|
1531
1669
|
|
1532
1670
|
assert_equal expected_merged, merged
|
@@ -1879,11 +2017,11 @@ describe 'Porolog' do
|
|
1879
2017
|
assert_nil unify_headtail_with_tail(arrays, arrays_goals, []), name
|
1880
2018
|
|
1881
2019
|
assert_equal [
|
1882
|
-
'Cannot unify because
|
2020
|
+
'Cannot unify because 1 != 2 (variable != variable)',
|
1883
2021
|
'Cannot unify heads: Goal1.:h with Goal2.:h',
|
1884
2022
|
], g1.log
|
1885
2023
|
assert_equal [
|
1886
|
-
'Cannot unify because
|
2024
|
+
'Cannot unify because 1 != 2 (variable != variable)',
|
1887
2025
|
'Cannot unify heads: Goal1.:h with Goal2.:h',
|
1888
2026
|
], g2.log
|
1889
2027
|
assert_equal [
|
@@ -1911,12 +2049,12 @@ describe 'Porolog' do
|
|
1911
2049
|
assert_nil unify_headtail_with_tail(arrays, arrays_goals, []), name
|
1912
2050
|
|
1913
2051
|
assert_equal [
|
1914
|
-
'Cannot unify because
|
2052
|
+
'Cannot unify because [2, 3] != [2, 4] (variable != variable)',
|
1915
2053
|
'Cannot unify headtail tails: Goal1.:t with Goal2.:t',
|
1916
2054
|
'Could not unify headtail arrays: [Goal1.:h, Goal1.2, Goal1.3] with [Goal2.:h, Goal2.2, Goal2.4] with [Goal4.:h, *Goal4.:t]',
|
1917
2055
|
], g1.log
|
1918
2056
|
assert_equal [
|
1919
|
-
'Cannot unify because
|
2057
|
+
'Cannot unify because [2, 3] != [2, 4] (variable != variable)',
|
1920
2058
|
'Cannot unify headtail tails: Goal1.:t with Goal2.:t',
|
1921
2059
|
'Could not unify headtail arrays: [Goal1.:h, Goal1.2, Goal1.3] with [Goal2.:h, Goal2.2, Goal2.4] with [Goal4.:h, *Goal4.:t]',
|
1922
2060
|
], g2.log
|
@@ -1980,7 +2118,6 @@ describe 'Porolog' do
|
|
1980
2118
|
assert_equal [
|
1981
2119
|
'Cannot unify incompatible values: 3 with 4',
|
1982
2120
|
'Cannot unify: [3] with [4]',
|
1983
|
-
#'Cannot unify: Goal2.3 with Goal3.4',
|
1984
2121
|
], g2.log
|
1985
2122
|
assert_equal [
|
1986
2123
|
'Cannot unify incompatible values: 3 with 4',
|
@@ -2172,4 +2309,122 @@ describe 'Porolog' do
|
|
2172
2309
|
|
2173
2310
|
end
|
2174
2311
|
|
2312
|
+
describe '#builtin' do
|
2313
|
+
|
2314
|
+
it 'should create a Predicate' do
|
2315
|
+
# -- Precondition Baseline --
|
2316
|
+
assert_equal 0, Scope[:default].predicates.size
|
2317
|
+
|
2318
|
+
# -- Test --
|
2319
|
+
single_predicate = builtin :member
|
2320
|
+
|
2321
|
+
# -- Compare Result Against Baseline --
|
2322
|
+
assert_equal 1, Scope[:default].predicates.size
|
2323
|
+
assert_equal :member, Scope[:default].predicates.first.name
|
2324
|
+
assert_Predicate single_predicate, :member, []
|
2325
|
+
end
|
2326
|
+
|
2327
|
+
it 'should define a method to create Arguments for solving' do
|
2328
|
+
Object.class_eval{
|
2329
|
+
remove_method(:member) if public_method_defined?(:member)
|
2330
|
+
}
|
2331
|
+
|
2332
|
+
refute respond_to?(:member)
|
2333
|
+
|
2334
|
+
builtin :member
|
2335
|
+
|
2336
|
+
assert respond_to?(:member)
|
2337
|
+
assert_Arguments member(:X, ['left','right']), :member, [:X, ['left','right']]
|
2338
|
+
|
2339
|
+
assert_includes methods, :member
|
2340
|
+
end
|
2341
|
+
|
2342
|
+
it 'should create multiple Predicates' do
|
2343
|
+
assert_equal 0, Scope[:default].predicates.size
|
2344
|
+
|
2345
|
+
multiple_predicates = builtin :member, :append, :is
|
2346
|
+
|
2347
|
+
assert_equal 3, Scope[:default].predicates.size
|
2348
|
+
assert_equal :member, Scope[:default].predicates[0].name
|
2349
|
+
assert_equal :append, Scope[:default].predicates[1].name
|
2350
|
+
assert_equal :is, Scope[:default].predicates[2].name
|
2351
|
+
assert_instance_of Array, multiple_predicates
|
2352
|
+
assert_equal 3, multiple_predicates.size
|
2353
|
+
assert_Predicate multiple_predicates[0], :member, []
|
2354
|
+
assert_Predicate multiple_predicates[1], :append, []
|
2355
|
+
assert_Predicate multiple_predicates[2], :is, []
|
2356
|
+
end
|
2357
|
+
|
2358
|
+
it 'should define multiple methods to create Arguments for solving' do
|
2359
|
+
Object.class_eval{
|
2360
|
+
remove_method(:member) if public_method_defined?(:member)
|
2361
|
+
remove_method(:append) if public_method_defined?(:append)
|
2362
|
+
}
|
2363
|
+
|
2364
|
+
refute respond_to?(:member)
|
2365
|
+
refute respond_to?(:append)
|
2366
|
+
|
2367
|
+
builtin :member, :append
|
2368
|
+
|
2369
|
+
assert respond_to?(:member)
|
2370
|
+
assert respond_to?(:append)
|
2371
|
+
assert_Arguments member(:X, :L), :member, [:X, :L]
|
2372
|
+
assert_Arguments append(:A, :B, :AB), :append, [:A, :B, :AB]
|
2373
|
+
end
|
2374
|
+
|
2375
|
+
it 'should define a method in a base class as an instance method and a class method' do
|
2376
|
+
Object.class_eval{
|
2377
|
+
remove_method(:member) if public_method_defined?(:member)
|
2378
|
+
}
|
2379
|
+
|
2380
|
+
class Base2 ; end
|
2381
|
+
|
2382
|
+
refute_includes Base2.methods, :member
|
2383
|
+
refute_includes Base2.instance_methods, :member
|
2384
|
+
|
2385
|
+
builtin :member, class_base: Base2
|
2386
|
+
|
2387
|
+
assert_includes Base2.methods, :member
|
2388
|
+
assert_includes Base2.instance_methods, :member
|
2389
|
+
|
2390
|
+
refute_includes methods, :member
|
2391
|
+
|
2392
|
+
class Base2
|
2393
|
+
def process
|
2394
|
+
member(:X, [4,5,6]).solve_for(:X)
|
2395
|
+
end
|
2396
|
+
end
|
2397
|
+
|
2398
|
+
assert_solutions Base2.member(:X, [1,2,3]), [
|
2399
|
+
{ X: 1 },
|
2400
|
+
{ X: 2 },
|
2401
|
+
{ X: 3 },
|
2402
|
+
]
|
2403
|
+
|
2404
|
+
assert_equal [4,5,6], Base2.new.process
|
2405
|
+
end
|
2406
|
+
|
2407
|
+
end
|
2408
|
+
|
2409
|
+
describe '#_' do
|
2410
|
+
|
2411
|
+
let(:goal) { new_goal :p, :x, :y }
|
2412
|
+
|
2413
|
+
it 'should return a different variable on each call' do
|
2414
|
+
# _ is overridden by MiniTest
|
2415
|
+
variable1 = Porolog._
|
2416
|
+
variable2 = Porolog._
|
2417
|
+
variable3 = Porolog._
|
2418
|
+
|
2419
|
+
assert_equal :_a, variable1
|
2420
|
+
assert_equal :_b, variable2
|
2421
|
+
assert_equal :_c, variable3
|
2422
|
+
|
2423
|
+
refute_equal variable1, variable2
|
2424
|
+
refute_equal variable2, variable3
|
2425
|
+
refute_equal variable3, variable1
|
2426
|
+
end
|
2427
|
+
|
2428
|
+
end
|
2429
|
+
|
2175
2430
|
end
|