1 ## oils_failures_allowed: 1
2
3 #### Exact equality with === and !==
4 shopt -s ysh:all
5
6 if (3 === 3) {
7 echo 'ok'
8 }
9 if (3 === '3') {
10 echo 'FAIL'
11 }
12
13 if (3 !== 3) {
14 echo 'FAIL'
15 }
16 if (3 !== '3') {
17 echo 'ok'
18 }
19
20 # dicts
21 var d1 = {'a': 1, 'b': 2}
22 var d2 = {'a': 1, 'b': 2}
23 var d3 = {'a': 1, 'b': 3}
24 if (d1 === d2) {
25 echo 'ok'
26 }
27 if (d1 === d3) {
28 echo 'FAIL'
29 }
30 if (d1 !== d3) {
31 echo 'ok'
32 }
33
34 ## STDOUT:
35 ok
36 ok
37 ok
38 ok
39 ## END
40
41 #### Approximate equality of Str x {Str, Int, Bool} with ~==
42 shopt -s ysh:all
43
44 # Note: for now there's no !~== operator. Use: not (a ~== b)
45
46 if (' foo ' ~== 'foo') {
47 echo Str-Str
48 }
49 if (' BAD ' ~== 'foo') {
50 echo FAIL
51 }
52
53 if ('3 ' ~== 3) {
54 echo Str-Int
55 }
56
57 if ('-3 ' ~== -3) {
58 echo Str-Negative
59 }
60
61 if ('-3_456' ~== -3456) {
62 echo Str-Underscore
63 }
64
65 if ('4 ' ~== '3') {
66 echo FAIL
67 }
68
69 if (' true ' ~== true) {
70 echo Str-Bool
71 }
72 if (' true ' ~== false) {
73 echo FAIL
74 }
75
76 const matrix = [
77 ' TRue ' ~== true, # case insentiive
78 ' FALse ' ~== false,
79 ]
80
81 # = matrix
82 if (matrix === [true, true]) {
83 echo 'bool matrix'
84 }
85
86 ## STDOUT:
87 Str-Str
88 Str-Int
89 Str-Negative
90 Str-Underscore
91 Str-Bool
92 bool matrix
93 ## END
94
95 #### Wrong Types with ~==
96 shopt -s ysh:all
97
98 # The LHS side should be a string
99
100 echo one
101 if (['1'] ~== ['1']) {
102 echo bad
103 }
104 echo two
105
106 if (3 ~== 3) {
107 echo bad
108 }
109
110 ## status: 1
111 ## STDOUT:
112 one
113 ## END
114
115 #### === on float not allowed
116
117 $SH -c '
118 shopt -s ysh:upgrade
119 pp test_ (1.0 === 2.0)
120 echo ok
121 '
122 echo status=$?
123
124 $SH -c '
125 shopt -s ysh:upgrade
126 pp test_ (42 === 3.0)
127 echo ok
128 '
129 echo status=$?
130
131 ## STDOUT:
132 status=3
133 status=3
134 ## END
135
136
137 #### floatsEqual()
138
139 var x = 42.0
140 pp test_ (floatsEqual(42.0, x))
141
142 pp test_ (floatsEqual(42.0, x + 1))
143
144 ## STDOUT:
145 (Bool) true
146 (Bool) false
147 ## END
148
149 #### Comparison converts from Str -> Int or Float
150 shopt --set parse_ysh_expr_sub
151
152 echo ' i i' $[1 < 2]
153 echo 'si i' $['1' < 2]
154 echo ' i si' $[1 < '2']
155 echo ---
156
157 echo ' f f' $[2.5 > 1.5]
158 echo 'sf f' $['2.5' > 1.5]
159 echo ' f sf' $[2.5 > '1.5']
160 echo ---
161
162 echo ' i f' $[4 <= 1.5]
163 echo 'si f' $['4' <= 1.5]
164 echo ' i sf' $[4 <= '1.5']
165 echo ---
166
167 echo ' f i' $[5.0 >= 2]
168 echo 'sf i' $['5.0' >= 2]
169 echo ' f si' $[5.0 >= '2']
170
171 ## STDOUT:
172 i i true
173 si i true
174 i si true
175 ---
176 f f true
177 sf f true
178 f sf true
179 ---
180 i f false
181 si f false
182 i sf false
183 ---
184 f i true
185 sf i true
186 f si true
187 ## END
188
189 #### Comparison of Int
190 shopt -s ysh:upgrade
191
192 if (1 < 2) {
193 echo '<'
194 }
195 if (2 <= 2) {
196 echo '<='
197 }
198 if (5 > 4) {
199 echo '>'
200 }
201 if (5 >= 5) {
202 echo '>='
203 }
204
205 if (2 < 1) {
206 echo no
207 }
208
209 ## STDOUT:
210 <
211 <=
212 >
213 >=
214 ## END
215
216 #### Comparison of Str does conversion to Int
217 shopt -s ysh:upgrade
218
219 if ('2' < '11') {
220 echo '<'
221 }
222 if ('2' <= '2') {
223 echo '<='
224 }
225 if ('11' > '2') {
226 echo '>'
227 }
228 if ('5' >= '5') {
229 echo '>='
230 }
231
232 if ('2' < '1') {
233 echo no
234 }
235
236 ## STDOUT:
237 <
238 <=
239 >
240 >=
241 ## END
242
243
244 #### Mixed Type Comparison does conversion to Int
245 shopt -s ysh:upgrade
246
247 if (2 < '11') {
248 echo '<'
249 }
250 if (2 <= '2') {
251 echo '<='
252 }
253 if (11 > '2') {
254 echo '>'
255 }
256 if (5 >= '5') {
257 echo '>='
258 }
259
260 if (2 < '1') {
261 echo no
262 }
263
264 ## STDOUT:
265 <
266 <=
267 >
268 >=
269 ## END
270
271
272 #### Invalid String is an error
273 shopt -s ysh:upgrade
274
275 try {
276 = '3' < 'bar'
277 }
278 echo code=$[_error.code]
279
280 try {
281 = '3' < '123_4'
282 }
283 echo code=$[_error.code]
284
285 ## status: 3
286 ## STDOUT:
287 ## END
288
289
290 #### Bool conversion -- explicit allowed, implicit not allowed
291
292 shopt -s ysh:upgrade
293
294 if (int(false) < int(true)) {
295 echo '<'
296 }
297
298 if (int(false) <= int(false) ) {
299 echo '<='
300 }
301
302 # JavaScript and Python both have this, but YSH prefers being explicit
303
304 if (true < false) {
305 echo 'BAD'
306 }
307 echo 'should not get here'
308
309 ## status: 3
310 ## STDOUT:
311 <
312 <=
313 ## END
314
315
316 #### Chained Comparisons
317 shopt -s ysh:upgrade
318
319 if (1 < 2 < 3) {
320 echo '123'
321 }
322 if (1 < 2 <= 2 <= 3 < 4) {
323 echo '123'
324 }
325
326 if (1 < 2 < 2) {
327 echo '123'
328 } else {
329 echo 'no'
330 }
331 ## STDOUT:
332 123
333 123
334 no
335 ## END
336
337 #### List / "Tuple" comparison is not allowed
338
339 shopt -s ysh:upgrade
340
341 var t1 = 3, 0
342 var t2 = 4, 0
343 var t3 = 3, 1
344
345 if (t2 > t1) { echo yes1 }
346 if (t3 > t1) { echo yes2 }
347 if ( (0,0) > t1) { echo yes3 }
348
349 ## status: 3
350 ## STDOUT:
351 ## END
352
353 #### Ternary op behaves like if statement
354 shopt -s ysh:upgrade
355
356 if ([1]) {
357 var y = 42
358 } else {
359 var y = 0
360 }
361 echo y=$y
362
363 var x = 42 if [1] else 0
364 echo x=$x
365
366 ## STDOUT:
367 y=42
368 x=42
369 ## END
370
371 #### Undefined comparisons
372 shopt -s ysh:all
373
374 func f() { true }
375 var mydict = {}
376 var myexpr = ^[123]
377
378 var unimpl = [
379 / [a-z]+ /, # Eggex
380 myexpr, # Expr
381 ^(echo hello), # Block
382 f, # Func
383 ''.upper, # BoundFunc
384 # These cannot be constructed
385 # - Proc
386 # - Slice
387 # - Range
388 ]
389
390 for val in (unimpl) {
391 try { = val === val }
392 if (_status !== 3) {
393 exit 1
394 }
395 }
396 ## STDOUT:
397 ## END
398
399 #### Non-comparable types in case arms
400 var myexpr = ^[123]
401
402 case (myexpr) {
403 (myexpr) { echo 123; }
404 }
405 ## status: 3
406 ## STDOUT:
407 ## END
408
409 #### object identity
410
411 var d = {}
412 var s = 'str'
413
414 pp test_ (d is d)
415 pp test_ (d is not {})
416 echo
417
418 pp test_ (d is s)
419 pp test_ (d is not s)
420
421 ## STDOUT:
422 (Bool) true
423 (Bool) true
424
425 (Bool) false
426 (Bool) true
427 ## END
428
429