example/comparisons.primi

Summary

Maintainability
Test Coverage
//
// OR operator returns the first non-falsey operand, or false.
//

x = 0 or 1
assert(x == 1)

x = 1 or 2
assert(x == 1)

x = false or 2
assert(x == 2)

x = 2 or false or 4
assert(x == 2)

x = false or 0 or -4
assert(x == -4)

x = [] or {} or 123
assert(x == 123)

//
// Comparing numbers with numbers.
//

x = 0 < 2
assert(x == true)

x = 2 < 0
assert(x == false)

x = -2 > 0
assert(x == false)

x = -2 < 0
assert(x == true)

x = 0 > -2
assert(x == true)

x = 0 < -2
assert(x == false)

x = 1 < 2
assert(x == true)

x = 2 < 1
assert(x == false)

x = 2 > 1
assert(x == true)

x = 1 > 2
assert(x == false)

x = 0 == 0
assert(x == true)

x = 0 == 1
assert(x == false)

x = 0 == -1
assert(x == false)

x = 1 == -1
assert(x == false)

x = 0 != 0
assert(x == false)

x = 1 != 1
assert(x == false)

x = 1 != 0
assert(x == true)

x = 0 != 1
assert(x == true)

// Comparing numbers with decimal point.

x = 1.5 < 1.50001
assert(x == true)

x = 2.001 < 2.002
assert(x == true)

x = 2.001 > 2
assert(x == true)

x = 1.001 > 1.999
assert(x == false)

// Chained comparisons.

x = 1 < 2 < 3
assert(x == true)

x = 1 < 2 < 3 < 400
assert(x == true)

x = 1 < 2 < 3 > 400
assert(x == false)

x = 2 < 1 < 3
assert(x == false)

x = -1 < 0 < 1
assert(x == true)

x = 4 < 40 < 400
assert(x == true)

x = 400 > 40 > 4
assert(x == true)

x = 5 > 3 < 4
assert(x == true)

x = 5 > -3 < 4
assert(x == true)

x = 5 < 3 < 4
assert(x == false)

x = 5 < 3 > 4
assert(x == false)

x = 1 > 0 < 1
assert(x == true)

// Comparing numbers with numeric strings (always NOT equal).

x = 1 == "1"
assert(x == false)

x = "1" == 1
assert(x == false)

x = "1" != 1
assert(x == true)

x = 1 != "1"
assert(x == true)

x = 1 == "0"
assert(x == false)

x = "0" == 1
assert(x == false)

x = "0" != 1
assert(x == true)

x = 1 != "0"
assert(x == true)

x = 1 == "0"
assert(x == false)

x = "0" == 1
assert(x == false)

x = "0" != 1
assert(x == true)

x = 1 != "0"
assert(x == true)

x = 0 == "0"
assert(x == false)

x = "0" == 0
assert(x == false)

x = "0" != 0
assert(x == true)

x = 0 != "0"
assert(x == true)

//
// Comparing booleans with booleans.
//

assert(true == true)
assert(false == false)
assert(true != false)
assert(false != true)
assert((true == false) == false)
assert((false == true) == false)
assert((true != true) == false)
assert((false != false) == false)

// Comparing booleans with numbers.

_ = "'true == 1' is true"
assert(true == 1, _)
_ = "'1 == true' is true"
assert(1 == true, _)

_ = "'true == 0' is false"
assert((true == 0) == false, _)
_ = "'0 == true' is false"
assert((0 == true) == false, _)

_ = "'false == 1' is false"
assert((false == 1) == false, _)
_ = "'1 == false' is false"
assert((1 == false) == false, _)

_ = "'false == 0' is true"
assert(false == 0, _)
_ = "'0 == false' is true"
assert(0 == false, _)

_ = "'false == -1' is false"
assert((false == -1) == false, _)
_ = "'-1 == false' is false"
assert((false == -1) == false, _)

// Comparing booleans with nulls.

x = null and true
assert(x == false)

x = null and false
assert(x == false)

x = true and null
assert(x == false)

x = false and null
assert(x == false)

x = null and null
assert(x == false)

x = null or true
assert(x == true)

x = null or false
assert(x == false)

x = true or null
assert(x == true)

x = false or null
assert(x == false)

x = null or null
assert(x == false)

//
// Short-circuiting AND and OR operators.
//

// OR: Only the first expression in brackets will have to be executed to obtain
// the result of OR operation.
a = b = false
tmp = (a = 1) or (b = 1)
assert(tmp == 1)
assert(a == 1)
assert(b == false)

// AND: Only the first expression in brackets will have to be executed to obtain
// the result of AND operation - there's no point in continuing evaluating, if
// the first expression is already falsey.
a = b = false
tmp = (a = 0) and (b = 1)
assert(!tmp)
assert(a == 0)
assert(b == false)

// All expressions will have to be executed in order to find the result.
a = b = c = d = false
tmp = (a = 0) or (b = 0) or (c = 0) or (d = 0)
assert(a == 0)
assert(b == 0)
assert(c == 0)
assert(d == 0)

// Only the first expression will be necessary to be executed.
a = b = c = d = false
tmp = (a = 1) or (b = 0) or (c = 0) or (d = 0)
assert(a == 1)
assert(b == false)
assert(c == false)
assert(d == false)

// All expressions will have to be executed in order to find the result.
a = b = c = d = false
tmp = (a = 1) and (b = 0) or (c = 0) or (d = 0)
assert(a == 1)
assert(b == 0)
assert(c == 0)
assert(d == 0)

// All expressions will have to be executed in order to find the result.
a = b = c = d = false
tmp = (a = 1) and (b = 0) or (c = 0) or (d = 1)
assert(a == 1)
assert(b == 0)
assert(c == 0)
assert(d == 1)

// All expressions will have to be executed in order to find the result.
a = b = c = d = false
tmp = (a = 1) and (b = 1) or (c = 0) or (d = 1)
assert(a == 1)
assert(b == 1)
assert(c == 0)
assert(d == 0)

// All expressions will have to be executed in order to find the result.
a = b = c = d = false
tmp = (a = 1) and (b = 0) or (c = 1) or (d = 1)
assert(a == 1)
assert(b == 0)
assert(c == 1)
assert(d == 0)

//
// 'in' and 'not in' comparisons.
//

// Strings.

a_string = "abcdefg"
assert("abc" in a_string)
assert("cab" not in a_string)

a_string = "příliš žluťoučký KŮŇ"
assert("příliš" in a_string)
assert("šilířp" not in a_string)
assert("žluť" in a_string)
assert("ŽLUŤ" not in a_string)
assert("čký KŮŇ" in a_string)
assert("kůň" not in a_string)

// Lists.

a_list = [1, 5, 'čáu!', [], true, {}, {'key_yay': 'value_yay'}]
assert(1 in a_list)
assert(5 in a_list)
assert('čáu!' in a_list)
assert([] in a_list)
assert({} in a_list)
assert({'key_yay': 'value_yay'} in a_list)

assert(2 not in a_list)
assert('č' not in a_list)
assert([1] not in a_list)
assert(false not in a_list)
assert({'key_yay': 'different_value'} not in a_list)

// Dicts (in/not in works with keys, not values.)

a_dict = {'a': true, 'c': false, 123: null}
assert('a' in a_dict)
assert('c' in a_dict)
assert(123 in a_dict)
assert('123' not in a_dict)
// This is not true - and is currently considered a bug.
_ = "Operator 'in' should do strict comparison. Number 123 is different from string '123'."
assert('123' not in a_dict, _)

assert(2 not in a_dict)
assert('č' not in a_dict)
assert(false not in a_dict)

//
// Comparison of every type with every type.
//

all_types = {
    "number": 0,
    "string": '',
    "regex": rx'',
    "list": [],
    "dict": {},
    "bool": false,
    "null": null,
}

for (type_a, value_a in all_types.items()) {
    for (type_b, value_b in all_types.items()) {
        assert(type(value_a == value_b) == bool)
        assert(type(value_a != value_b) == bool)
    }
}