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 echo ' i i' $[1 < 2]
151 echo 'si i' $['1' < 2]
152 echo ' i si' $[1 < '2']
153 echo ---
154
155 echo ' f f' $[2.5 > 1.5]
156 echo 'sf f' $['2.5' > 1.5]
157 echo ' f sf' $[2.5 > '1.5']
158 echo ---
159
160 echo ' i f' $[4 <= 1.5]
161 echo 'si f' $['4' <= 1.5]
162 echo ' i sf' $[4 <= '1.5']
163 echo ---
164
165 echo ' f i' $[5.0 >= 2]
166 echo 'sf i' $['5.0' >= 2]
167 echo ' f si' $[5.0 >= '2']
168
169 ## STDOUT:
170 i i true
171 si i true
172 i si true
173 ---
174 f f true
175 sf f true
176 f sf true
177 ---
178 i f false
179 si f false
180 i sf false
181 ---
182 f i true
183 sf i true
184 f si true
185 ## END
186
187 #### Comparison of Int
188 shopt -s ysh:upgrade
189
190 if (1 < 2) {
191 echo '<'
192 }
193 if (2 <= 2) {
194 echo '<='
195 }
196 if (5 > 4) {
197 echo '>'
198 }
199 if (5 >= 5) {
200 echo '>='
201 }
202
203 if (2 < 1) {
204 echo no
205 }
206
207 ## STDOUT:
208 <
209 <=
210 >
211 >=
212 ## END
213
214 #### Comparison of Str does conversion to Int
215 shopt -s ysh:upgrade
216
217 if ('2' < '11') {
218 echo '<'
219 }
220 if ('2' <= '2') {
221 echo '<='
222 }
223 if ('11' > '2') {
224 echo '>'
225 }
226 if ('5' >= '5') {
227 echo '>='
228 }
229
230 if ('2' < '1') {
231 echo no
232 }
233
234 ## STDOUT:
235 <
236 <=
237 >
238 >=
239 ## END
240
241
242 #### Mixed Type Comparison does conversion to Int
243 shopt -s ysh:upgrade
244
245 if (2 < '11') {
246 echo '<'
247 }
248 if (2 <= '2') {
249 echo '<='
250 }
251 if (11 > '2') {
252 echo '>'
253 }
254 if (5 >= '5') {
255 echo '>='
256 }
257
258 if (2 < '1') {
259 echo no
260 }
261
262 ## STDOUT:
263 <
264 <=
265 >
266 >=
267 ## END
268
269
270 #### Invalid String is an error
271 shopt -s ysh:upgrade
272
273 try {
274 = '3' < 'bar'
275 }
276 echo code=$[_error.code]
277
278 try {
279 = '3' < '123_4'
280 }
281 echo code=$[_error.code]
282
283 ## status: 3
284 ## STDOUT:
285 ## END
286
287
288 #### Bool conversion -- explicit allowed, implicit not allowed
289
290 shopt -s ysh:upgrade
291
292 if (int(false) < int(true)) {
293 echo '<'
294 }
295
296 if (int(false) <= int(false) ) {
297 echo '<='
298 }
299
300 # JavaScript and Python both have this, but Oil prefers being explicit
301
302 if (true < false) {
303 echo 'BAD'
304 }
305 echo 'should not get here'
306
307 ## status: 3
308 ## STDOUT:
309 <
310 <=
311 ## END
312
313
314 #### Chained Comparisons
315 shopt -s ysh:upgrade
316
317 if (1 < 2 < 3) {
318 echo '123'
319 }
320 if (1 < 2 <= 2 <= 3 < 4) {
321 echo '123'
322 }
323
324 if (1 < 2 < 2) {
325 echo '123'
326 } else {
327 echo 'no'
328 }
329 ## STDOUT:
330 123
331 123
332 no
333 ## END
334
335 #### List / "Tuple" comparison is not allowed
336
337 shopt -s ysh:upgrade
338
339 var t1 = 3, 0
340 var t2 = 4, 0
341 var t3 = 3, 1
342
343 if (t2 > t1) { echo yes1 }
344 if (t3 > t1) { echo yes2 }
345 if ( (0,0) > t1) { echo yes3 }
346
347 ## status: 3
348 ## STDOUT:
349 ## END
350
351 #### Ternary op behaves like if statement
352 shopt -s ysh:upgrade
353
354 if ([1]) {
355 var y = 42
356 } else {
357 var y = 0
358 }
359 echo y=$y
360
361 var x = 42 if [1] else 0
362 echo x=$x
363
364 ## STDOUT:
365 y=42
366 x=42
367 ## END
368
369 #### Undefined comparisons
370 shopt -s ysh:all
371
372 func f() { true }
373 var mydict = {}
374 var myexpr = ^[123]
375
376 var unimpl = [
377 / [a-z]+ /, # Eggex
378 myexpr, # Expr
379 ^(echo hello), # Block
380 f, # Func
381 ''.upper, # BoundFunc
382 # These cannot be constructed
383 # - Proc
384 # - Slice
385 # - Range
386 ]
387
388 for val in (unimpl) {
389 try { = val === val }
390 if (_status !== 3) {
391 exit 1
392 }
393 }
394 ## STDOUT:
395 ## END
396
397 #### Non-comparable types in case arms
398 var myexpr = ^[123]
399
400 case (myexpr) {
401 (myexpr) { echo 123; }
402 }
403 ## status: 3
404 ## STDOUT:
405 ## END
406
407 #### object identity
408
409 var d = {}
410 var s = 'str'
411
412 pp test_ (d is d)
413 pp test_ (d is not {})
414 echo
415
416 pp test_ (d is s)
417 pp test_ (d is not s)
418
419 ## STDOUT:
420 (Bool) true
421 (Bool) true
422
423 (Bool) false
424 (Bool) true
425 ## END
426
427