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

View as plain text