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

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