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