github.com/mithrandie/csvq@v1.18.1/lib/query/comparison_test.go (about) 1 package query 2 3 import ( 4 "testing" 5 6 "github.com/mithrandie/csvq/lib/parser" 7 "github.com/mithrandie/csvq/lib/value" 8 9 "github.com/mithrandie/ternary" 10 ) 11 12 var isTests = []struct { 13 LHS value.Primary 14 RHS value.Primary 15 Result ternary.Value 16 }{ 17 { 18 LHS: value.NewBoolean(true), 19 RHS: value.NewTernary(ternary.TRUE), 20 Result: ternary.TRUE, 21 }, 22 { 23 LHS: value.NewNull(), 24 RHS: value.NewNull(), 25 Result: ternary.TRUE, 26 }, 27 { 28 LHS: value.NewString("foo"), 29 RHS: value.NewNull(), 30 Result: ternary.FALSE, 31 }, 32 } 33 34 func TestIs(t *testing.T) { 35 for _, v := range isTests { 36 r := Is(v.LHS, v.RHS) 37 if r != v.Result { 38 t.Errorf("result = %s, want %s for (%s is %s)", r, v.Result, v.LHS, v.RHS) 39 } 40 } 41 } 42 43 var likeTests = []struct { 44 LHS value.Primary 45 Pattern value.Primary 46 Result ternary.Value 47 }{ 48 { 49 LHS: value.NewString("str"), 50 Pattern: value.NewNull(), 51 Result: ternary.UNKNOWN, 52 }, 53 { 54 LHS: value.NewString("str"), 55 Pattern: value.NewBoolean(true), 56 Result: ternary.UNKNOWN, 57 }, 58 { 59 LHS: value.NewBoolean(true), 60 Pattern: value.NewString("str"), 61 Result: ternary.UNKNOWN, 62 }, 63 { 64 LHS: value.NewString("str"), 65 Pattern: value.NewString("str"), 66 Result: ternary.TRUE, 67 }, 68 { 69 LHS: value.NewString("str"), 70 Pattern: value.NewString(""), 71 Result: ternary.FALSE, 72 }, 73 { 74 LHS: value.NewString("abcdefghijk"), 75 Pattern: value.NewString("lmn"), 76 Result: ternary.FALSE, 77 }, 78 { 79 LHS: value.NewString("abc"), 80 Pattern: value.NewString("_____"), 81 Result: ternary.FALSE, 82 }, 83 { 84 LHS: value.NewString("abcde"), 85 Pattern: value.NewString("___"), 86 Result: ternary.FALSE, 87 }, 88 { 89 LHS: value.NewString("abcde"), 90 Pattern: value.NewString("___%__"), 91 Result: ternary.TRUE, 92 }, 93 { 94 LHS: value.NewString("abcde"), 95 Pattern: value.NewString("_%__"), 96 Result: ternary.TRUE, 97 }, 98 { 99 LHS: value.NewString("abcdefghijkabcdefghijk"), 100 Pattern: value.NewString("%def%_abc%"), 101 Result: ternary.TRUE, 102 }, 103 { 104 LHS: value.NewString("abcde"), 105 Pattern: value.NewString("abc\\_e"), 106 Result: ternary.FALSE, 107 }, 108 { 109 LHS: value.NewString("abc_e"), 110 Pattern: value.NewString("abc\\_e"), 111 Result: ternary.TRUE, 112 }, 113 { 114 LHS: value.NewString("abcde"), 115 Pattern: value.NewString("abc\\%e"), 116 Result: ternary.FALSE, 117 }, 118 { 119 LHS: value.NewString("a\\bc%e"), 120 Pattern: value.NewString("a\\bc\\%e"), 121 Result: ternary.TRUE, 122 }, 123 { 124 LHS: value.NewString("abcdef"), 125 Pattern: value.NewString("abcde\\"), 126 Result: ternary.FALSE, 127 }, 128 { 129 LHS: value.NewString("abcde"), 130 Pattern: value.NewString("abc"), 131 Result: ternary.FALSE, 132 }, 133 { 134 LHS: value.NewString("abcdecba"), 135 Pattern: value.NewString("%c_a"), 136 Result: ternary.TRUE, 137 }, 138 { 139 LHS: value.NewString("aaaaa"), 140 Pattern: value.NewString("%a"), 141 Result: ternary.TRUE, 142 }, 143 { 144 LHS: value.NewString("abababc"), 145 Pattern: value.NewString("%aba_c"), 146 Result: ternary.TRUE, 147 }, 148 } 149 150 func TestLike(t *testing.T) { 151 for _, v := range likeTests { 152 r := Like(v.LHS, v.Pattern) 153 if r != v.Result { 154 t.Errorf("result = %s, want %s for (%s like %s)", r, v.Result, v.LHS, v.Pattern) 155 } 156 } 157 } 158 159 var inRowValueListTests = []struct { 160 LHS value.RowValue 161 List []value.RowValue 162 Type int 163 Operator string 164 Result ternary.Value 165 Error string 166 }{ 167 { 168 LHS: value.RowValue{ 169 value.NewInteger(1), 170 value.NewInteger(2), 171 value.NewInteger(3), 172 }, 173 List: []value.RowValue{ 174 { 175 value.NewInteger(1), 176 value.NewInteger(2), 177 value.NewInteger(3), 178 }, 179 { 180 value.NewInteger(4), 181 value.NewInteger(5), 182 value.NewInteger(6), 183 }, 184 }, 185 Type: parser.ANY, 186 Operator: "=", 187 Result: ternary.TRUE, 188 }, 189 { 190 LHS: value.RowValue{ 191 value.NewInteger(1), 192 value.NewInteger(2), 193 value.NewInteger(3), 194 }, 195 List: []value.RowValue{ 196 { 197 value.NewInteger(1), 198 value.NewInteger(2), 199 value.NewInteger(3), 200 }, 201 { 202 value.NewInteger(1), 203 value.NewInteger(2), 204 value.NewInteger(3), 205 }, 206 }, 207 Type: parser.ALL, 208 Operator: "=", 209 Result: ternary.TRUE, 210 }, 211 { 212 LHS: value.RowValue{ 213 value.NewInteger(1), 214 value.NewInteger(2), 215 value.NewInteger(3), 216 }, 217 List: []value.RowValue{ 218 { 219 value.NewInteger(1), 220 value.NewInteger(2), 221 value.NewInteger(3), 222 }, 223 { 224 value.NewInteger(1), 225 value.NewInteger(3), 226 }, 227 }, 228 Type: parser.ALL, 229 Operator: "=", 230 Error: "row value length does not match at index 1", 231 }, 232 } 233 234 func TestInRowValueList(t *testing.T) { 235 for _, v := range inRowValueListTests { 236 r, err := InRowValueList(v.LHS, v.List, v.Type, v.Operator, TestTx.Flags.DatetimeFormat, TestTx.Flags.GetTimeLocation()) 237 if err != nil { 238 if len(v.Error) < 1 { 239 t.Errorf("unexpected error %q for (%s %s %s %s)", err, v.LHS, v.Operator, parser.TokenLiteral(v.Type), v.List) 240 } else if err.Error() != v.Error { 241 t.Errorf("error %q, want error %q for (%s %s %s %s)", err.Error(), v.Error, v.LHS, v.Operator, parser.TokenLiteral(v.Type), v.List) 242 } 243 continue 244 } 245 if 0 < len(v.Error) { 246 t.Errorf("no error, want error %q for (%s %s %s %s)", v.Error, v.LHS, v.Operator, parser.TokenLiteral(v.Type), v.List) 247 continue 248 } 249 if r != v.Result { 250 t.Errorf("result = %s, want %s for (%s %s %s %s)", r, v.Result, v.LHS, v.Operator, parser.TokenLiteral(v.Type), v.List) 251 } 252 } 253 }