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

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