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

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