1// Copyright 2021 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package types2 6 7import ( 8 "strings" 9 "testing" 10) 11 12// maketl makes a term list from a string of the term list. 13func maketl(s string) termlist { 14 s = strings.ReplaceAll(s, " ", "") 15 names := strings.Split(s, "∪") 16 r := make(termlist, len(names)) 17 for i, n := range names { 18 r[i] = testTerm(n) 19 } 20 return r 21} 22 23func TestTermlistAll(t *testing.T) { 24 if !allTermlist.isAll() { 25 t.Errorf("allTermlist is not the set of all types") 26 } 27} 28 29func TestTermlistString(t *testing.T) { 30 for _, want := range []string{ 31 "∅", 32 "", 33 "int", 34 "~int", 35 "myInt", 36 "∅ ∪ ∅", 37 " ∪ ", 38 "∅ ∪ ∪ int", 39 "∅ ∪ ∪ int ∪ myInt", 40 } { 41 if got := maketl(want).String(); got != want { 42 t.Errorf("(%v).String() == %v", want, got) 43 } 44 } 45} 46 47func TestTermlistIsEmpty(t *testing.T) { 48 for test, want := range map[string]bool{ 49 "∅": true, 50 "∅ ∪ ∅": true, 51 "∅ ∪ ∅ ∪ ": false, 52 "∅ ∪ ∅ ∪ myInt": false, 53 "": false, 54 " ∪ int": false, 55 " ∪ myInt ∪ ∅": false, 56 } { 57 xl := maketl(test) 58 got := xl.isEmpty() 59 if got != want { 60 t.Errorf("(%v).isEmpty() == %v; want %v", test, got, want) 61 } 62 } 63} 64 65func TestTermlistIsAll(t *testing.T) { 66 for test, want := range map[string]bool{ 67 "∅": false, 68 "∅ ∪ ∅": false, 69 "int ∪ ~string": false, 70 "~int ∪ myInt": false, 71 "∅ ∪ ∅ ∪ ": true, 72 "": true, 73 " ∪ int": true, 74 "myInt ∪ ": true, 75 } { 76 xl := maketl(test) 77 got := xl.isAll() 78 if got != want { 79 t.Errorf("(%v).isAll() == %v; want %v", test, got, want) 80 } 81 } 82} 83 84func TestTermlistNorm(t *testing.T) { 85 for _, test := range []struct { 86 xl, want string 87 }{ 88 {"∅", "∅"}, 89 {"∅ ∪ ∅", "∅"}, 90 {"∅ ∪ int", "int"}, 91 {"∅ ∪ myInt", "myInt"}, 92 {" ∪ int", ""}, 93 {" ∪ myInt", ""}, 94 {"int ∪ myInt", "int ∪ myInt"}, 95 {"~int ∪ int", "~int"}, 96 {"~int ∪ myInt", "~int"}, 97 {"int ∪ ~string ∪ int", "int ∪ ~string"}, 98 {"~int ∪ string ∪ ∪ ~string ∪ int", ""}, 99 {"~int ∪ string ∪ myInt ∪ ~string ∪ int", "~int ∪ ~string"}, 100 } { 101 xl := maketl(test.xl) 102 got := maketl(test.xl).norm() 103 if got.String() != test.want { 104 t.Errorf("(%v).norm() = %v; want %v", xl, got, test.want) 105 } 106 } 107} 108 109func TestTermlistSingleType(t *testing.T) { 110 // helper to deal with nil types 111 tstring := func(typ Type) string { 112 if typ == nil { 113 return "nil" 114 } 115 return typ.String() 116 } 117 118 for test, want := range map[string]string{ 119 "∅": "nil", 120 "": "nil", 121 "int": "int", 122 "myInt": "myInt", 123 "~int": "int", 124 "~int ∪ string": "nil", 125 "~int ∪ myInt": "int", 126 "∅ ∪ int": "int", 127 "∅ ∪ ~int": "int", 128 "∅ ∪ ~int ∪ string": "nil", 129 } { 130 xl := maketl(test) 131 got := tstring(xl.singleType()) 132 if got != want { 133 t.Errorf("(%v).singleType() == %v; want %v", test, got, want) 134 } 135 } 136} 137 138func TestTermlistUnion(t *testing.T) { 139 for _, test := range []struct { 140 xl, yl, want string 141 }{ 142 143 {"∅", "∅", "∅"}, 144 {"∅", "", ""}, 145 {"∅", "int", "int"}, 146 {"", "~int", ""}, 147 {"int", "~int", "~int"}, 148 {"int", "string", "int ∪ string"}, 149 {"int", "myInt", "int ∪ myInt"}, 150 {"~int", "myInt", "~int"}, 151 {"int ∪ string", "~string", "int ∪ ~string"}, 152 {"~int ∪ string", "~string ∪ int", "~int ∪ ~string"}, 153 {"~int ∪ string ∪ ∅", "~string ∪ int", "~int ∪ ~string"}, 154 {"~int ∪ myInt ∪ ∅", "~string ∪ int", "~int ∪ ~string"}, 155 {"~int ∪ string ∪ ", "~string ∪ int", ""}, 156 {"~int ∪ string ∪ myInt", "~string ∪ int", "~int ∪ ~string"}, 157 } { 158 xl := maketl(test.xl) 159 yl := maketl(test.yl) 160 got := xl.union(yl).String() 161 if got != test.want { 162 t.Errorf("(%v).union(%v) = %v; want %v", test.xl, test.yl, got, test.want) 163 } 164 } 165} 166 167func TestTermlistIntersect(t *testing.T) { 168 for _, test := range []struct { 169 xl, yl, want string 170 }{ 171 172 {"∅", "∅", "∅"}, 173 {"∅", "", "∅"}, 174 {"∅", "int", "∅"}, 175 {"∅", "myInt", "∅"}, 176 {"", "~int", "~int"}, 177 {"", "myInt", "myInt"}, 178 {"int", "~int", "int"}, 179 {"int", "string", "∅"}, 180 {"int", "myInt", "∅"}, 181 {"~int", "myInt", "myInt"}, 182 {"int ∪ string", "~string", "string"}, 183 {"~int ∪ string", "~string ∪ int", "int ∪ string"}, 184 {"~int ∪ string ∪ ∅", "~string ∪ int", "int ∪ string"}, 185 {"~int ∪ myInt ∪ ∅", "~string ∪ int", "int"}, 186 {"~int ∪ string ∪ ", "~string ∪ int", "int ∪ ~string"}, 187 {"~int ∪ string ∪ myInt", "~string ∪ int", "int ∪ string"}, 188 } { 189 xl := maketl(test.xl) 190 yl := maketl(test.yl) 191 got := xl.intersect(yl).String() 192 if got != test.want { 193 t.Errorf("(%v).intersect(%v) = %v; want %v", test.xl, test.yl, got, test.want) 194 } 195 } 196} 197 198func TestTermlistEqual(t *testing.T) { 199 for _, test := range []struct { 200 xl, yl string 201 want bool 202 }{ 203 {"∅", "∅", true}, 204 {"∅", "", false}, 205 {"", "", true}, 206 {" ∪ int", "", true}, 207 {" ∪ int", "string ∪ ", true}, 208 {" ∪ myInt", "string ∪ ", true}, 209 {"int ∪ ~string", "string ∪ int", false}, 210 {"~int ∪ string", "string ∪ myInt", false}, 211 {"int ∪ ~string ∪ ∅", "string ∪ int ∪ ~string", true}, 212 } { 213 xl := maketl(test.xl) 214 yl := maketl(test.yl) 215 got := xl.equal(yl) 216 if got != test.want { 217 t.Errorf("(%v).equal(%v) = %v; want %v", test.xl, test.yl, got, test.want) 218 } 219 } 220} 221 222func TestTermlistIncludes(t *testing.T) { 223 for _, test := range []struct { 224 xl, typ string 225 want bool 226 }{ 227 {"∅", "int", false}, 228 {"", "int", true}, 229 {"~int", "int", true}, 230 {"int", "string", false}, 231 {"~int", "string", false}, 232 {"~int", "myInt", true}, 233 {"int ∪ string", "string", true}, 234 {"~int ∪ string", "int", true}, 235 {"~int ∪ string", "myInt", true}, 236 {"~int ∪ myInt ∪ ∅", "myInt", true}, 237 {"myInt ∪ ∅ ∪ ", "int", true}, 238 } { 239 xl := maketl(test.xl) 240 yl := testTerm(test.typ).typ 241 got := xl.includes(yl) 242 if got != test.want { 243 t.Errorf("(%v).includes(%v) = %v; want %v", test.xl, yl, got, test.want) 244 } 245 } 246} 247 248func TestTermlistSupersetOf(t *testing.T) { 249 for _, test := range []struct { 250 xl, typ string 251 want bool 252 }{ 253 {"∅", "∅", true}, 254 {"∅", "", false}, 255 {"∅", "int", false}, 256 {"", "∅", true}, 257 {"", "", true}, 258 {"", "int", true}, 259 {"", "~int", true}, 260 {"", "myInt", true}, 261 {"~int", "int", true}, 262 {"~int", "~int", true}, 263 {"~int", "myInt", true}, 264 {"int", "~int", false}, 265 {"myInt", "~int", false}, 266 {"int", "string", false}, 267 {"~int", "string", false}, 268 {"int ∪ string", "string", true}, 269 {"int ∪ string", "~string", false}, 270 {"~int ∪ string", "int", true}, 271 {"~int ∪ string", "myInt", true}, 272 {"~int ∪ string ∪ ∅", "string", true}, 273 {"~string ∪ ∅ ∪ ", "myInt", true}, 274 } { 275 xl := maketl(test.xl) 276 y := testTerm(test.typ) 277 got := xl.supersetOf(y) 278 if got != test.want { 279 t.Errorf("(%v).supersetOf(%v) = %v; want %v", test.xl, y, got, test.want) 280 } 281 } 282} 283 284func TestTermlistSubsetOf(t *testing.T) { 285 for _, test := range []struct { 286 xl, yl string 287 want bool 288 }{ 289 {"∅", "∅", true}, 290 {"∅", "", true}, 291 {"", "∅", false}, 292 {"", "", true}, 293 {"int", "int ∪ string", true}, 294 {"~int", "int ∪ string", false}, 295 {"~int", "myInt ∪ string", false}, 296 {"myInt", "~int ∪ string", true}, 297 {"~int", "string ∪ string ∪ int ∪ ~int", true}, 298 {"myInt", "string ∪ string ∪ ~int", true}, 299 {"int ∪ string", "string", false}, 300 {"int ∪ string", "string ∪ int", true}, 301 {"int ∪ ~string", "string ∪ int", false}, 302 {"myInt ∪ ~string", "string ∪ int ∪ ", true}, 303 {"int ∪ ~string", "string ∪ int ∪ ∅ ∪ string", false}, 304 {"int ∪ myInt", "string ∪ ~int ∪ ∅ ∪ string", true}, 305 } { 306 xl := maketl(test.xl) 307 yl := maketl(test.yl) 308 got := xl.subsetOf(yl) 309 if got != test.want { 310 t.Errorf("(%v).subsetOf(%v) = %v; want %v", test.xl, test.yl, got, test.want) 311 } 312 } 313} 314