OILS / spec / ysh-expr-compare.test.sh View on Github | oilshell.org

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