github.com/mithrandie/csvq@v1.18.1/lib/value/comparison_test.go (about)

     1  package value
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/mithrandie/ternary"
     9  )
    10  
    11  func TestComparisonResult_String(t *testing.T) {
    12  	if IsEqual.String() != "IsEqual" {
    13  		t.Errorf("string = %s, want %s for %s.String()", IsEqual.String(), "IsEqual", IsEqual)
    14  	}
    15  }
    16  
    17  var location, _ = time.LoadLocation("UTC")
    18  
    19  var compareCombinedlyTests = []struct {
    20  	LHS    Primary
    21  	RHS    Primary
    22  	Result ComparisonResult
    23  }{
    24  	{
    25  		LHS:    NewInteger(1),
    26  		RHS:    NewNull(),
    27  		Result: IsIncommensurable,
    28  	},
    29  	{
    30  		LHS:    NewInteger(1),
    31  		RHS:    NewInteger(2),
    32  		Result: IsLess,
    33  	},
    34  	{
    35  		LHS:    NewInteger(2),
    36  		RHS:    NewInteger(1),
    37  		Result: IsGreater,
    38  	},
    39  	{
    40  		LHS:    NewInteger(2),
    41  		RHS:    NewInteger(2),
    42  		Result: IsEqual,
    43  	},
    44  	{
    45  		LHS:    NewFloat(1.5),
    46  		RHS:    NewFloat(2.0),
    47  		Result: IsLess,
    48  	},
    49  	{
    50  		LHS:    NewFloat(1.5),
    51  		RHS:    NewFloat(1.0),
    52  		Result: IsGreater,
    53  	},
    54  	{
    55  		LHS:    NewFloat(1.5),
    56  		RHS:    NewFloat(1.5),
    57  		Result: IsEqual,
    58  	},
    59  	{
    60  		LHS:    NewString("1"),
    61  		RHS:    NewInteger(2),
    62  		Result: IsLess,
    63  	},
    64  	{
    65  		LHS:    NewString("2"),
    66  		RHS:    NewInteger(1),
    67  		Result: IsGreater,
    68  	},
    69  	{
    70  		LHS:    NewString("2"),
    71  		RHS:    NewInteger(2),
    72  		Result: IsEqual,
    73  	},
    74  	{
    75  		LHS:    NewString("1.0"),
    76  		RHS:    NewFloat(1.5),
    77  		Result: IsLess,
    78  	},
    79  	{
    80  		LHS:    NewString("2.0"),
    81  		RHS:    NewFloat(1.5),
    82  		Result: IsGreater,
    83  	},
    84  	{
    85  		LHS:    NewString("1.5"),
    86  		RHS:    NewFloat(1.5),
    87  		Result: IsEqual,
    88  	},
    89  	{
    90  		LHS:    NewInteger(1),
    91  		RHS:    NewFloat(1.5),
    92  		Result: IsLess,
    93  	},
    94  	{
    95  		LHS:    NewString("1"),
    96  		RHS:    NewString("1.5"),
    97  		Result: IsLess,
    98  	},
    99  	{
   100  		LHS:    NewDatetimeFromString("2006-01-02T15:04:05-07:00", nil, location),
   101  		RHS:    NewDatetimeFromString("2006-01-02T15:04:05-07:00", nil, location),
   102  		Result: IsEqual,
   103  	},
   104  	{
   105  		LHS:    NewDatetimeFromString("2006-01-02T15:04:05-07:00", nil, location),
   106  		RHS:    NewDatetimeFromString("2006-02-02T15:04:05-07:00", nil, location),
   107  		Result: IsLess,
   108  	},
   109  	{
   110  		LHS:    NewDatetimeFromString("2006-02-02T15:04:05-07:00", nil, location),
   111  		RHS:    NewDatetimeFromString("2006-01-02T15:04:05-07:00", nil, location),
   112  		Result: IsGreater,
   113  	},
   114  	{
   115  		LHS:    NewDatetimeFromString("2006-02-02T15:04:05-07:00", nil, location),
   116  		RHS:    NewString("abc"),
   117  		Result: IsIncommensurable,
   118  	},
   119  	{
   120  		LHS:    NewBoolean(true),
   121  		RHS:    NewBoolean(true),
   122  		Result: IsBoolEqual,
   123  	},
   124  	{
   125  		LHS:    NewBoolean(true),
   126  		RHS:    NewBoolean(false),
   127  		Result: IsNotEqual,
   128  	},
   129  	{
   130  		LHS:    NewString(" A "),
   131  		RHS:    NewString("a"),
   132  		Result: IsEqual,
   133  	},
   134  	{
   135  		LHS:    NewString("A"),
   136  		RHS:    NewString("B"),
   137  		Result: IsLess,
   138  	},
   139  	{
   140  		LHS:    NewString("B"),
   141  		RHS:    NewString("A"),
   142  		Result: IsGreater,
   143  	},
   144  	{
   145  		LHS:    NewString("B"),
   146  		RHS:    NewTernaryFromString("true"),
   147  		Result: IsIncommensurable,
   148  	},
   149  	{
   150  		LHS:    NewString("1"),
   151  		RHS:    NewString("A"),
   152  		Result: IsLess,
   153  	},
   154  	{
   155  		LHS:    NewFloat(math.Inf(1)),
   156  		RHS:    NewFloat(math.Inf(1)),
   157  		Result: IsEqual,
   158  	},
   159  	{
   160  		LHS:    NewFloat(math.Inf(1)),
   161  		RHS:    NewFloat(math.Inf(-1)),
   162  		Result: IsGreater,
   163  	},
   164  	{
   165  		LHS:    NewFloat(math.NaN()),
   166  		RHS:    NewFloat(math.NaN()),
   167  		Result: IsNotEqual,
   168  	},
   169  	{
   170  		LHS:    NewFloat(math.Inf(1)),
   171  		RHS:    NewFloat(math.NaN()),
   172  		Result: IsNotEqual,
   173  	},
   174  }
   175  
   176  func TestCompareCombinedly(t *testing.T) {
   177  	for _, v := range compareCombinedlyTests {
   178  		r := CompareCombinedly(v.LHS, v.RHS, nil, location)
   179  		if r != v.Result {
   180  			t.Errorf("result = %s, want %s for comparison with %s and %s", r, v.Result, v.LHS, v.RHS)
   181  		}
   182  	}
   183  }
   184  
   185  var identicalTests = []struct {
   186  	LHS    Primary
   187  	RHS    Primary
   188  	Result ternary.Value
   189  }{
   190  	{
   191  		LHS:    NewNull(),
   192  		RHS:    NewString("R"),
   193  		Result: ternary.UNKNOWN,
   194  	},
   195  	{
   196  		LHS:    NewTernary(ternary.UNKNOWN),
   197  		RHS:    NewString("R"),
   198  		Result: ternary.UNKNOWN,
   199  	},
   200  	{
   201  		LHS:    NewString("L"),
   202  		RHS:    NewNull(),
   203  		Result: ternary.UNKNOWN,
   204  	},
   205  	{
   206  		LHS:    NewString("L"),
   207  		RHS:    NewTernary(ternary.UNKNOWN),
   208  		Result: ternary.UNKNOWN,
   209  	},
   210  	{
   211  		LHS:    NewInteger(1),
   212  		RHS:    NewInteger(1),
   213  		Result: ternary.TRUE,
   214  	},
   215  	{
   216  		LHS:    NewFloat(1),
   217  		RHS:    NewFloat(1),
   218  		Result: ternary.TRUE,
   219  	},
   220  	{
   221  		LHS:    NewDatetimeFromString("2006-02-02T15:04:05-07:00", nil, location),
   222  		RHS:    NewDatetimeFromString("2006-02-02T22:04:05", nil, location),
   223  		Result: ternary.TRUE,
   224  	},
   225  	{
   226  		LHS:    NewBoolean(true),
   227  		RHS:    NewBoolean(true),
   228  		Result: ternary.TRUE,
   229  	},
   230  	{
   231  		LHS:    NewTernary(ternary.TRUE),
   232  		RHS:    NewTernary(ternary.TRUE),
   233  		Result: ternary.TRUE,
   234  	},
   235  	{
   236  		LHS:    NewString("L"),
   237  		RHS:    NewString("R"),
   238  		Result: ternary.FALSE,
   239  	},
   240  	{
   241  		LHS:    NewString("A"),
   242  		RHS:    NewString("A"),
   243  		Result: ternary.TRUE,
   244  	},
   245  	{
   246  		LHS:    NewInteger(1),
   247  		RHS:    NewFloat(1),
   248  		Result: ternary.FALSE,
   249  	},
   250  }
   251  
   252  func TestIdentical(t *testing.T) {
   253  	for _, v := range identicalTests {
   254  		r := Identical(v.LHS, v.RHS)
   255  		if r != v.Result {
   256  			t.Errorf("result = %s, want %s for comparison with %s and %s", r, v.Result, v.LHS, v.RHS)
   257  		}
   258  	}
   259  }
   260  
   261  var compareTests = []struct {
   262  	LHS    Primary
   263  	RHS    Primary
   264  	Op     string
   265  	Result ternary.Value
   266  }{
   267  	{
   268  		LHS:    NewInteger(1),
   269  		RHS:    NewInteger(2),
   270  		Op:     "=",
   271  		Result: ternary.FALSE,
   272  	},
   273  	{
   274  		LHS:    NewInteger(1),
   275  		RHS:    NewInteger(1),
   276  		Op:     "=",
   277  		Result: ternary.TRUE,
   278  	},
   279  	{
   280  		LHS:    NewInteger(1),
   281  		RHS:    NewNull(),
   282  		Op:     "=",
   283  		Result: ternary.UNKNOWN,
   284  	},
   285  	{
   286  		LHS:    NewString("0001"),
   287  		RHS:    NewInteger(1),
   288  		Op:     "=",
   289  		Result: ternary.TRUE,
   290  	},
   291  	{
   292  		LHS:    NewString("0001"),
   293  		RHS:    NewInteger(1),
   294  		Op:     "==",
   295  		Result: ternary.FALSE,
   296  	},
   297  	{
   298  		LHS:    NewInteger(1),
   299  		RHS:    NewInteger(2),
   300  		Op:     ">",
   301  		Result: ternary.FALSE,
   302  	},
   303  	{
   304  		LHS:    NewInteger(2),
   305  		RHS:    NewInteger(1),
   306  		Op:     ">",
   307  		Result: ternary.TRUE,
   308  	},
   309  	{
   310  		LHS:    NewInteger(1),
   311  		RHS:    NewNull(),
   312  		Op:     ">",
   313  		Result: ternary.UNKNOWN,
   314  	},
   315  	{
   316  		LHS:    NewInteger(2),
   317  		RHS:    NewInteger(1),
   318  		Op:     "<",
   319  		Result: ternary.FALSE,
   320  	},
   321  	{
   322  		LHS:    NewInteger(1),
   323  		RHS:    NewInteger(2),
   324  		Op:     "<",
   325  		Result: ternary.TRUE,
   326  	},
   327  	{
   328  		LHS:    NewInteger(1),
   329  		RHS:    NewNull(),
   330  		Op:     "<",
   331  		Result: ternary.UNKNOWN,
   332  	},
   333  	{
   334  		LHS:    NewInteger(1),
   335  		RHS:    NewInteger(2),
   336  		Op:     ">=",
   337  		Result: ternary.FALSE,
   338  	},
   339  	{
   340  		LHS:    NewInteger(2),
   341  		RHS:    NewInteger(2),
   342  		Op:     ">=",
   343  		Result: ternary.TRUE,
   344  	},
   345  	{
   346  		LHS:    NewInteger(1),
   347  		RHS:    NewNull(),
   348  		Op:     ">=",
   349  		Result: ternary.UNKNOWN,
   350  	},
   351  	{
   352  		LHS:    NewInteger(2),
   353  		RHS:    NewInteger(1),
   354  		Op:     "<=",
   355  		Result: ternary.FALSE,
   356  	},
   357  	{
   358  		LHS:    NewInteger(2),
   359  		RHS:    NewInteger(2),
   360  		Op:     "<=",
   361  		Result: ternary.TRUE,
   362  	},
   363  	{
   364  		LHS:    NewInteger(1),
   365  		RHS:    NewNull(),
   366  		Op:     "<=",
   367  		Result: ternary.UNKNOWN,
   368  	},
   369  	{
   370  		LHS:    NewInteger(2),
   371  		RHS:    NewInteger(2),
   372  		Op:     "<>",
   373  		Result: ternary.FALSE,
   374  	},
   375  	{
   376  		LHS:    NewInteger(2),
   377  		RHS:    NewInteger(1),
   378  		Op:     "<>",
   379  		Result: ternary.TRUE,
   380  	},
   381  	{
   382  		LHS:    NewInteger(1),
   383  		RHS:    NewNull(),
   384  		Op:     "<>",
   385  		Result: ternary.UNKNOWN,
   386  	},
   387  	{
   388  		LHS:    NewFloat(math.Inf(1)),
   389  		RHS:    NewFloat(math.Inf(1)),
   390  		Op:     "=",
   391  		Result: ternary.TRUE,
   392  	},
   393  	{
   394  		LHS:    NewFloat(math.Inf(1)),
   395  		RHS:    NewFloat(math.Inf(-1)),
   396  		Op:     ">",
   397  		Result: ternary.TRUE,
   398  	},
   399  	{
   400  		LHS:    NewFloat(math.Inf(1)),
   401  		RHS:    NewFloat(math.NaN()),
   402  		Op:     "<",
   403  		Result: ternary.UNKNOWN,
   404  	},
   405  	{
   406  		LHS:    NewFloat(math.NaN()),
   407  		RHS:    NewFloat(math.NaN()),
   408  		Op:     "=",
   409  		Result: ternary.FALSE,
   410  	},
   411  	{
   412  		LHS:    NewFloat(math.NaN()),
   413  		RHS:    NewFloat(math.NaN()),
   414  		Op:     "==",
   415  		Result: ternary.FALSE,
   416  	},
   417  	{
   418  		LHS:    NewFloat(math.NaN()),
   419  		RHS:    NewFloat(math.NaN()),
   420  		Op:     "<>",
   421  		Result: ternary.TRUE,
   422  	},
   423  	{
   424  		LHS:    NewFloat(math.NaN()),
   425  		RHS:    NewFloat(math.Inf(1)),
   426  		Op:     "<>",
   427  		Result: ternary.TRUE,
   428  	},
   429  }
   430  
   431  func TestCompare(t *testing.T) {
   432  	for _, v := range compareTests {
   433  		r := Compare(v.LHS, v.RHS, v.Op, nil, location)
   434  		if r != v.Result {
   435  			t.Errorf("result = %s, want %s for (%s %s %s)", r, v.Result, v.LHS, v.Op, v.RHS)
   436  		}
   437  	}
   438  }
   439  
   440  var compareRowValuesTests = []struct {
   441  	LHS    RowValue
   442  	RHS    RowValue
   443  	Op     string
   444  	Result ternary.Value
   445  	Error  string
   446  }{
   447  	{
   448  		LHS: RowValue{
   449  			NewInteger(1),
   450  			NewInteger(2),
   451  			NewInteger(3),
   452  		},
   453  		RHS: RowValue{
   454  			NewInteger(1),
   455  			NewInteger(2),
   456  			NewInteger(3),
   457  		},
   458  		Op:     "=",
   459  		Result: ternary.TRUE,
   460  	},
   461  	{
   462  		LHS: RowValue{
   463  			NewInteger(1),
   464  			NewInteger(2),
   465  			NewInteger(3),
   466  		},
   467  		RHS: RowValue{
   468  			NewInteger(1),
   469  			NewNull(),
   470  			NewInteger(3),
   471  		},
   472  		Op:     "=",
   473  		Result: ternary.UNKNOWN,
   474  	},
   475  	{
   476  		LHS: RowValue{
   477  			NewInteger(1),
   478  			NewInteger(2),
   479  			NewInteger(3),
   480  		},
   481  		RHS: RowValue{
   482  			NewInteger(1),
   483  			NewNull(),
   484  			NewInteger(2),
   485  		},
   486  		Op:     "=",
   487  		Result: ternary.FALSE,
   488  	},
   489  	{
   490  		LHS: RowValue{
   491  			NewInteger(1),
   492  			NewInteger(2),
   493  			NewInteger(3),
   494  		},
   495  		RHS: RowValue{
   496  			NewInteger(1),
   497  			NewInteger(2),
   498  			NewNull(),
   499  		},
   500  		Op:     "=",
   501  		Result: ternary.UNKNOWN,
   502  	},
   503  	{
   504  		LHS: RowValue{
   505  			NewInteger(1),
   506  			NewInteger(2),
   507  			NewInteger(3),
   508  		},
   509  		RHS: RowValue{
   510  			NewInteger(1),
   511  			NewInteger(9),
   512  			NewInteger(3),
   513  		},
   514  		Op:     "=",
   515  		Result: ternary.FALSE,
   516  	},
   517  	{
   518  		LHS: RowValue{
   519  			NewInteger(1),
   520  			NewInteger(2),
   521  			NewInteger(3),
   522  		},
   523  		RHS: RowValue{
   524  			NewInteger(1),
   525  			NewInteger(2),
   526  			NewInteger(3),
   527  		},
   528  		Op:     "==",
   529  		Result: ternary.TRUE,
   530  	},
   531  	{
   532  		LHS: RowValue{
   533  			NewInteger(1),
   534  			NewInteger(2),
   535  			NewInteger(3),
   536  		},
   537  		RHS: RowValue{
   538  			NewInteger(1),
   539  			NewNull(),
   540  			NewInteger(2),
   541  		},
   542  		Op:     "==",
   543  		Result: ternary.FALSE,
   544  	},
   545  	{
   546  		LHS: RowValue{
   547  			NewInteger(1),
   548  			NewInteger(2),
   549  			NewInteger(3),
   550  		},
   551  		RHS: RowValue{
   552  			NewInteger(1),
   553  			NewNull(),
   554  			NewInteger(3),
   555  		},
   556  		Op:     "==",
   557  		Result: ternary.UNKNOWN,
   558  	},
   559  	{
   560  		LHS: RowValue{
   561  			NewInteger(1),
   562  			NewInteger(2),
   563  			NewInteger(3),
   564  		},
   565  		RHS: RowValue{
   566  			NewInteger(1),
   567  			NewInteger(0),
   568  			NewInteger(3),
   569  		},
   570  		Op:     "<>",
   571  		Result: ternary.TRUE,
   572  	},
   573  	{
   574  		LHS: RowValue{
   575  			NewInteger(1),
   576  			NewInteger(2),
   577  			NewInteger(3),
   578  		},
   579  		RHS: RowValue{
   580  			NewInteger(1),
   581  			NewNull(),
   582  			NewInteger(2),
   583  		},
   584  		Op:     "<>",
   585  		Result: ternary.TRUE,
   586  	},
   587  	{
   588  		LHS: RowValue{
   589  			NewInteger(1),
   590  			NewInteger(2),
   591  			NewInteger(3),
   592  		},
   593  		RHS: RowValue{
   594  			NewInteger(1),
   595  			NewNull(),
   596  			NewInteger(3),
   597  		},
   598  		Op:     "<>",
   599  		Result: ternary.UNKNOWN,
   600  	},
   601  	{
   602  		LHS: RowValue{
   603  			NewInteger(1),
   604  			NewInteger(2),
   605  			NewInteger(3),
   606  		},
   607  		RHS: RowValue{
   608  			NewInteger(1),
   609  			NewInteger(2),
   610  			NewInteger(3),
   611  		},
   612  		Op:     "!=",
   613  		Result: ternary.FALSE,
   614  	},
   615  	{
   616  		LHS: RowValue{
   617  			NewInteger(1),
   618  			NewInteger(2),
   619  			NewInteger(3),
   620  		},
   621  		RHS: RowValue{
   622  			NewInteger(1),
   623  			NewInteger(2),
   624  			NewInteger(2),
   625  		},
   626  		Op:     ">",
   627  		Result: ternary.TRUE,
   628  	},
   629  	{
   630  		LHS: RowValue{
   631  			NewInteger(1),
   632  			NewInteger(2),
   633  			NewInteger(3),
   634  		},
   635  		RHS: RowValue{
   636  			NewInteger(1),
   637  			NewInteger(2),
   638  			NewInteger(4),
   639  		},
   640  		Op:     ">",
   641  		Result: ternary.FALSE,
   642  	},
   643  	{
   644  		LHS: RowValue{
   645  			NewInteger(1),
   646  			NewInteger(2),
   647  			NewInteger(3),
   648  		},
   649  		RHS: RowValue{
   650  			NewInteger(1),
   651  			NewInteger(2),
   652  			NewInteger(3),
   653  		},
   654  		Op:     ">",
   655  		Result: ternary.FALSE,
   656  	},
   657  	{
   658  		LHS: RowValue{
   659  			NewInteger(1),
   660  			NewInteger(2),
   661  			NewInteger(3),
   662  		},
   663  		RHS: RowValue{
   664  			NewInteger(1),
   665  			NewInteger(2),
   666  			NewInteger(3),
   667  		},
   668  		Op:     ">=",
   669  		Result: ternary.TRUE,
   670  	},
   671  	{
   672  		LHS: RowValue{
   673  			NewInteger(1),
   674  			NewBoolean(true),
   675  			NewInteger(3),
   676  		},
   677  		RHS: RowValue{
   678  			NewInteger(1),
   679  			NewBoolean(false),
   680  			NewInteger(2),
   681  		},
   682  		Op:     ">",
   683  		Result: ternary.UNKNOWN,
   684  	},
   685  	{
   686  		LHS: RowValue{
   687  			NewInteger(1),
   688  			NewInteger(2),
   689  			NewInteger(3),
   690  		},
   691  		RHS: RowValue{
   692  			NewInteger(1),
   693  			NewInteger(2),
   694  			NewInteger(4),
   695  		},
   696  		Op:     "<",
   697  		Result: ternary.TRUE,
   698  	},
   699  	{
   700  		LHS: RowValue{
   701  			NewInteger(1),
   702  			NewInteger(2),
   703  			NewInteger(3),
   704  		},
   705  		RHS: RowValue{
   706  			NewInteger(1),
   707  			NewInteger(2),
   708  			NewInteger(2),
   709  		},
   710  		Op:     "<",
   711  		Result: ternary.FALSE,
   712  	},
   713  	{
   714  		LHS: RowValue{
   715  			NewInteger(1),
   716  			NewInteger(2),
   717  			NewInteger(3),
   718  		},
   719  		RHS: RowValue{
   720  			NewInteger(1),
   721  			NewInteger(2),
   722  			NewInteger(3),
   723  		},
   724  		Op:     "<",
   725  		Result: ternary.FALSE,
   726  	},
   727  	{
   728  		LHS: RowValue{
   729  			NewInteger(1),
   730  			NewInteger(2),
   731  			NewInteger(3),
   732  		},
   733  		RHS: RowValue{
   734  			NewInteger(1),
   735  			NewInteger(2),
   736  			NewInteger(3),
   737  		},
   738  		Op:     "<=",
   739  		Result: ternary.TRUE,
   740  	},
   741  	{
   742  		LHS: RowValue{
   743  			NewInteger(1),
   744  			NewInteger(2),
   745  			NewInteger(3),
   746  		},
   747  		RHS:    RowValue(nil),
   748  		Op:     "=",
   749  		Result: ternary.UNKNOWN,
   750  	},
   751  	{
   752  		LHS: RowValue{
   753  			NewInteger(1),
   754  			NewInteger(2),
   755  			NewInteger(3),
   756  		},
   757  		RHS: RowValue{
   758  			NewInteger(1),
   759  			NewInteger(3),
   760  		},
   761  		Op:    "=",
   762  		Error: "row value length does not match",
   763  	},
   764  }
   765  
   766  func TestCompareRowValues(t *testing.T) {
   767  	for _, v := range compareRowValuesTests {
   768  		r, err := CompareRowValues(v.LHS, v.RHS, v.Op, nil, location)
   769  		if err != nil {
   770  			if len(v.Error) < 1 {
   771  				t.Errorf("unexpected error %q for (%s %s %s)", err, v.LHS, v.Op, v.RHS)
   772  			} else if err.Error() != v.Error {
   773  				t.Errorf("error %q, want error %q for (%s %s %s)", err.Error(), v.Error, v.LHS, v.Op, v.RHS)
   774  			}
   775  			continue
   776  		}
   777  		if 0 < len(v.Error) {
   778  			t.Errorf("no error, want error %q for (%s %s %s)", v.Error, v.LHS, v.Op, v.RHS)
   779  			continue
   780  		}
   781  		if r != v.Result {
   782  			t.Errorf("result = %s, want %s for (%s %s %s)", r, v.Result, v.LHS, v.Op, v.RHS)
   783  		}
   784  	}
   785  }
   786  
   787  var equivalentToTests = []struct {
   788  	LHS    Primary
   789  	RHS    Primary
   790  	Result ternary.Value
   791  }{
   792  	{
   793  		LHS:    NewNull(),
   794  		RHS:    NewNull(),
   795  		Result: ternary.TRUE,
   796  	},
   797  	{
   798  		LHS:    NewInteger(1),
   799  		RHS:    NewNull(),
   800  		Result: ternary.UNKNOWN,
   801  	},
   802  }
   803  
   804  func TestEquivalentTo(t *testing.T) {
   805  	for _, v := range equivalentToTests {
   806  		r := Equivalent(v.LHS, v.RHS, nil, location)
   807  		if r != v.Result {
   808  			t.Errorf("result = %s, want %s for (%s is equivalent to %s)", r, v.Result, v.LHS, v.RHS)
   809  		}
   810  	}
   811  }