Source file src/go/types/typeterm_test.go

     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  
     5  package types
     6  
     7  import (
     8  	"go/token"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  var myInt = func() Type {
    14  	tname := NewTypeName(token.NoPos, nil, "myInt", nil)
    15  	return NewNamed(tname, Typ[Int], nil)
    16  }()
    17  
    18  var testTerms = map[string]*term{
    19  	"∅":       nil,
    20  	"𝓤":       {},
    21  	"int":     {false, Typ[Int]},
    22  	"~int":    {true, Typ[Int]},
    23  	"string":  {false, Typ[String]},
    24  	"~string": {true, Typ[String]},
    25  	"myInt":   {false, myInt},
    26  }
    27  
    28  func TestTermString(t *testing.T) {
    29  	for want, x := range testTerms {
    30  		if got := x.String(); got != want {
    31  			t.Errorf("%v.String() == %v; want %v", x, got, want)
    32  		}
    33  	}
    34  }
    35  
    36  func split(s string, n int) []string {
    37  	r := strings.Split(s, " ")
    38  	if len(r) != n {
    39  		panic("invalid test case: " + s)
    40  	}
    41  	return r
    42  }
    43  
    44  func testTerm(name string) *term {
    45  	r, ok := testTerms[name]
    46  	if !ok {
    47  		panic("invalid test argument: " + name)
    48  	}
    49  	return r
    50  }
    51  
    52  func TestTermEqual(t *testing.T) {
    53  	for _, test := range []string{
    54  		"∅ ∅ T",
    55  		"𝓤 𝓤 T",
    56  		"int int T",
    57  		"~int ~int T",
    58  		"myInt myInt T",
    59  		"∅ 𝓤 F",
    60  		"∅ int F",
    61  		"∅ ~int F",
    62  		"𝓤 int F",
    63  		"𝓤 ~int F",
    64  		"𝓤 myInt F",
    65  		"int ~int F",
    66  		"int myInt F",
    67  		"~int myInt F",
    68  	} {
    69  		args := split(test, 3)
    70  		x := testTerm(args[0])
    71  		y := testTerm(args[1])
    72  		want := args[2] == "T"
    73  		if got := x.equal(y); got != want {
    74  			t.Errorf("%v.equal(%v) = %v; want %v", x, y, got, want)
    75  		}
    76  		// equal is symmetric
    77  		x, y = y, x
    78  		if got := x.equal(y); got != want {
    79  			t.Errorf("%v.equal(%v) = %v; want %v", x, y, got, want)
    80  		}
    81  	}
    82  }
    83  
    84  func TestTermUnion(t *testing.T) {
    85  	for _, test := range []string{
    86  		"∅ ∅ ∅ ∅",
    87  		"∅ 𝓤 𝓤 ∅",
    88  		"∅ int int ∅",
    89  		"∅ ~int ~int ∅",
    90  		"∅ myInt myInt ∅",
    91  		"𝓤 𝓤 𝓤 ∅",
    92  		"𝓤 int 𝓤 ∅",
    93  		"𝓤 ~int 𝓤 ∅",
    94  		"𝓤 myInt 𝓤 ∅",
    95  		"int int int ∅",
    96  		"int ~int ~int ∅",
    97  		"int string int string",
    98  		"int ~string int ~string",
    99  		"int myInt int myInt",
   100  		"~int ~string ~int ~string",
   101  		"~int myInt ~int ∅",
   102  
   103  		// union is symmetric, but the result order isn't - repeat symmetric cases explicitly
   104  		"𝓤 ∅ 𝓤 ∅",
   105  		"int ∅ int ∅",
   106  		"~int ∅ ~int ∅",
   107  		"myInt ∅ myInt ∅",
   108  		"int 𝓤 𝓤 ∅",
   109  		"~int 𝓤 𝓤 ∅",
   110  		"myInt 𝓤 𝓤 ∅",
   111  		"~int int ~int ∅",
   112  		"string int string int",
   113  		"~string int ~string int",
   114  		"myInt int myInt int",
   115  		"~string ~int ~string ~int",
   116  		"myInt ~int ~int ∅",
   117  	} {
   118  		args := split(test, 4)
   119  		x := testTerm(args[0])
   120  		y := testTerm(args[1])
   121  		want1 := testTerm(args[2])
   122  		want2 := testTerm(args[3])
   123  		if got1, got2 := x.union(y); !got1.equal(want1) || !got2.equal(want2) {
   124  			t.Errorf("%v.union(%v) = %v, %v; want %v, %v", x, y, got1, got2, want1, want2)
   125  		}
   126  	}
   127  }
   128  
   129  func TestTermIntersection(t *testing.T) {
   130  	for _, test := range []string{
   131  		"∅ ∅ ∅",
   132  		"∅ 𝓤 ∅",
   133  		"∅ int ∅",
   134  		"∅ ~int ∅",
   135  		"∅ myInt ∅",
   136  		"𝓤 𝓤 𝓤",
   137  		"𝓤 int int",
   138  		"𝓤 ~int ~int",
   139  		"𝓤 myInt myInt",
   140  		"int int int",
   141  		"int ~int int",
   142  		"int string ∅",
   143  		"int ~string ∅",
   144  		"int string ∅",
   145  		"~int ~string ∅",
   146  		"~int myInt myInt",
   147  	} {
   148  		args := split(test, 3)
   149  		x := testTerm(args[0])
   150  		y := testTerm(args[1])
   151  		want := testTerm(args[2])
   152  		if got := x.intersect(y); !got.equal(want) {
   153  			t.Errorf("%v.intersect(%v) = %v; want %v", x, y, got, want)
   154  		}
   155  		// intersect is symmetric
   156  		x, y = y, x
   157  		if got := x.intersect(y); !got.equal(want) {
   158  			t.Errorf("%v.intersect(%v) = %v; want %v", x, y, got, want)
   159  		}
   160  	}
   161  }
   162  
   163  func TestTermIncludes(t *testing.T) {
   164  	for _, test := range []string{
   165  		"∅ int F",
   166  		"𝓤 int T",
   167  		"int int T",
   168  		"~int int T",
   169  		"~int myInt T",
   170  		"string int F",
   171  		"~string int F",
   172  		"myInt int F",
   173  	} {
   174  		args := split(test, 3)
   175  		x := testTerm(args[0])
   176  		y := testTerm(args[1]).typ
   177  		want := args[2] == "T"
   178  		if got := x.includes(y); got != want {
   179  			t.Errorf("%v.includes(%v) = %v; want %v", x, y, got, want)
   180  		}
   181  	}
   182  }
   183  
   184  func TestTermSubsetOf(t *testing.T) {
   185  	for _, test := range []string{
   186  		"∅ ∅ T",
   187  		"𝓤 𝓤 T",
   188  		"int int T",
   189  		"~int ~int T",
   190  		"myInt myInt T",
   191  		"∅ 𝓤 T",
   192  		"∅ int T",
   193  		"∅ ~int T",
   194  		"∅ myInt T",
   195  		"𝓤 int F",
   196  		"𝓤 ~int F",
   197  		"𝓤 myInt F",
   198  		"int ~int T",
   199  		"int myInt F",
   200  		"~int myInt F",
   201  		"myInt int F",
   202  		"myInt ~int T",
   203  	} {
   204  		args := split(test, 3)
   205  		x := testTerm(args[0])
   206  		y := testTerm(args[1])
   207  		want := args[2] == "T"
   208  		if got := x.subsetOf(y); got != want {
   209  			t.Errorf("%v.subsetOf(%v) = %v; want %v", x, y, got, want)
   210  		}
   211  	}
   212  }
   213  
   214  func TestTermDisjoint(t *testing.T) {
   215  	for _, test := range []string{
   216  		"int int F",
   217  		"~int ~int F",
   218  		"int ~int F",
   219  		"int string T",
   220  		"int ~string T",
   221  		"int myInt T",
   222  		"~int ~string T",
   223  		"~int myInt F",
   224  		"string myInt T",
   225  		"~string myInt T",
   226  	} {
   227  		args := split(test, 3)
   228  		x := testTerm(args[0])
   229  		y := testTerm(args[1])
   230  		want := args[2] == "T"
   231  		if got := x.disjoint(y); got != want {
   232  			t.Errorf("%v.disjoint(%v) = %v; want %v", x, y, got, want)
   233  		}
   234  		// disjoint is symmetric
   235  		x, y = y, x
   236  		if got := x.disjoint(y); got != want {
   237  			t.Errorf("%v.disjoint(%v) = %v; want %v", x, y, got, want)
   238  		}
   239  	}
   240  }
   241  

View as plain text