1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
package hm
import (
"fmt"
"testing"
)
var subsTests = []struct {
op string
tv TypeVariable
t Type
ok bool
size int
}{
{"get", TypeVariable('a'), nil, false, 0},
{"add", TypeVariable('a'), proton, true, 1},
{"get", TypeVariable('a'), proton, true, 1},
{"add", TypeVariable('a'), neutron, true, 1},
{"get", TypeVariable('a'), neutron, true, 1},
{"rem", TypeVariable('b'), nil, false, 1},
{"rem", TypeVariable('a'), nil, false, 0},
{"add", TypeVariable('a'), proton, true, 1},
{"add", TypeVariable('b'), proton, true, 2},
{"add", TypeVariable('c'), proton, true, 3},
}
func testSubs(t *testing.T, sub Subs) {
var T Type
var ok bool
for _, sts := range subsTests {
switch sts.op {
case "get":
if T, ok = sub.Get(sts.tv); ok != sts.ok {
t.Errorf("Expected Get to return %t. Got a value of %v instead", sts.ok, T)
}
case "add":
sub = sub.Add(sts.tv, sts.t)
case "rem":
sub = sub.Remove(sts.tv)
}
if sub.Size() != sts.size {
t.Errorf("Inconsistent size. Want %d. Got %d", sts.size, sub.Size())
}
}
// Iter
correct := []Substitution{
{TypeVariable('a'), proton},
{TypeVariable('b'), proton},
{TypeVariable('c'), proton},
}
for _, s := range sub.Iter() {
var found bool
for _, c := range correct {
if s.T == c.T && s.Tv == c.Tv {
found = true
break
}
}
if !found {
t.Errorf("Testing of %T: cannot find %v in Range", sub, s)
}
}
// Clone
cloned := sub.Clone()
cloned = cloned.Add(TypeVariable('a'), photon)
gt, ok := sub.Get(TypeVariable('a'))
if !ok {
t.Errorf("Expected the key 'a' to be found")
}
if gt == photon {
t.Errorf("Mutable cloning found")
}
}
func TestSliceSubs(t *testing.T) {
var sub Subs
sub = newSliceSubs()
if sub.Size() != 0 {
t.Error("Expected a size of 0")
}
sub = newSliceSubs(5)
if cap(sub.(*sSubs).s) != 5 {
t.Error("Expected a cap of 5")
}
if sub.Size() != 0 {
t.Error("Expected a size of 0")
}
testSubs(t, sub)
// Format for completeness sake
sub = newSliceSubs(2)
sub = sub.Add('a', proton)
sub = sub.Add('b', neutron)
if fmt.Sprintf("%v", sub) != "{a: proton, b: neutron}" {
t.Errorf("Format of sub is wrong. Got %q instead", sub)
}
}
func TestMapSubs(t *testing.T) {
var sub Subs
sub = make(mSubs)
if sub.Size() != 0 {
t.Error("Expected a size of 0")
}
testSubs(t, sub)
}
var composeTests = []struct {
a Subs
b Subs
expected Subs
}{
{mSubs{'a': proton}, &sSubs{[]Substitution{{'b', neutron}}}, &sSubs{[]Substitution{{'a', proton}, {'b', neutron}}}},
{&sSubs{[]Substitution{{'b', neutron}}}, mSubs{'a': proton}, mSubs{'a': proton, 'b': neutron}},
{mSubs{'a': proton, 'b': neutron}, &sSubs{[]Substitution{{'b', neutron}}}, &sSubs{[]Substitution{{'a', proton}, {'b', neutron}}}},
{mSubs{'a': proton, 'b': TypeVariable('a')}, &sSubs{[]Substitution{{'b', neutron}}}, &sSubs{[]Substitution{{'a', proton}, {'b', proton}}}},
{mSubs{'a': proton}, &sSubs{[]Substitution{{'b', TypeVariable('a')}}}, &sSubs{[]Substitution{{'a', proton}, {'b', proton}}}},
}
func TestCompose(t *testing.T) {
for i, cts := range composeTests {
subs := compose(cts.a, cts.b)
for _, v := range cts.expected.Iter() {
if T, ok := subs.Get(v.Tv); !ok {
t.Errorf("Test %d: Expected TypeVariable %v to be in subs", i, v.Tv)
} else if T != v.T {
t.Errorf("Test %d: Expected replacement to be %v. Got %v instead", i, v.T, T)
}
}
}
}
|