///|
test "assertions" {
// Basic equality assertion
@test.assert_eq(1 + 1, 2)
@test.assert_eq("hello", "hello")
// Boolean assertions
assert_true(5 > 3)
assert_false(2 > 5)
// Inequality assertion
@test.assert_not_eq(1, 2)
@test.assert_not_eq("foo", "bar")
}///|
test "inspect usage" {
let value = 42
inspect(value, content="42")
let list = [1, 2, 3]
debug_inspect(list, content="[1, 2, 3]")
let result : Result[Int, String] = Ok(100)
debug_inspect(result, content="Ok(100)")
}///|
test "result type" {
fn divide(a : Int, b : Int) -> Result[Int, String] {
if b == 0 {
Err("Division by zero")
} else {
Ok(a / b)
}
}
// Success case
let result1 = divide(10, 2)
debug_inspect(result1, content="Ok(5)")
// Error case
let result2 = divide(10, 0)
debug_inspect(result2, content="Err(\"Division by zero\")")
// Pattern matching on Result
match result1 {
Ok(value) => inspect(value, content="5")
Err(_) => inspect(false, content="true")
}
}///|
test "option type" {
fn find_first_even(numbers : Array[Int]) -> Int? {
for num in numbers {
if num % 2 == 0 {
return Some(num)
}
}
None
}
// Found case
let result1 = find_first_even([1, 3, 4, 5])
debug_inspect(result1, content="Some(4)")
// Not found case
let result2 = find_first_even([1, 3, 5])
debug_inspect(result2, content="None")
// Pattern matching on Option
match result1 {
Some(value) => inspect(value, content="4")
None => inspect(false, content="true")
}
}///|
test "iterators" {
// Create iterator from array
let numbers = [1, 2, 3, 4, 5]
let iter = numbers.iter()
// Collect back to array
let collected = iter.collect()
debug_inspect(collected, content="[1, 2, 3, 4, 5]")
// Map transformation
let doubled = numbers.iter().map(fn(x) { x * 2 }).collect()
debug_inspect(doubled, content="[2, 4, 6, 8, 10]")
// Filter elements
let evens = numbers.iter().filter(fn(x) { x % 2 == 0 }).collect()
debug_inspect(evens, content="[2, 4]")
// Fold (reduce) operation
let sum = numbers.iter().fold(init=0, fn(acc, x) { acc + x })
inspect(sum, content="15")
}///|
test "arrays" {
// Dynamic arrays
let arr1 = Array()
arr1.push(1)
arr1.push(2)
arr1.push(3)
debug_inspect(arr1, content="[1, 2, 3]")
// Array from literal
let arr2 = [10, 20, 30]
debug_inspect(arr2, content="[10, 20, 30]")
// Array operations
let length = arr2.length()
inspect(length, content="3")
let first = arr2[0]
inspect(first, content="10")
}///|
test "fixed arrays" {
// FixedArray from literal
let fixed_arr : FixedArray[Int] = [10, 20, 30]
debug_inspect(
fixed_arr,
content=(
#|<FixedArray: [10, 20, 30]>
),
)
// FixedArray operations
let length = fixed_arr.length()
inspect(length, content="3")
let first = fixed_arr[0]
inspect(first, content="10")
}direction: right
owners: "Owning containers" {
arr: "Array[T] / FixedArray[T] / ReadOnlyArray[T]"
bytes: "Bytes"
str: "String"
}
views: "Zero-copy views (shared storage + window bounds)" {
arrview: "ArrayView[T]"
bytesview: "BytesView"
strview: "StringView"
}
owners.arr -> views.arrview: "a[start:end]"
owners.bytes -> views.bytesview: "b[start:end]"
owners.str -> views.strview: "s[start:end]"///|
test "views are zero copy" {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4]
@test.assert_eq(view.length(), 3)
@test.assert_eq(view[0], 2)
view is [first, .. rest]
@test.assert_eq(first, 2)
@test.assert_eq(rest.length(), 2)
}///|
test "strings" {
let text = "Hello, World!"
// String length
let len = text.length()
inspect(len, content="13")
// String concatenation
let greeting = "Hello" + ", " + "World!"
inspect(greeting, content="Hello, World!")
// String comparison
let equal = "test" == "test"
inspect(equal, content="true")
}///|
test "string builder" {
let builder = StringBuilder()
builder.write_string("Hello")
builder.write_string(", ")
builder.write_string("World!")
let result = builder.to_string()
inspect(result, content="Hello, World!")
}///|
test "json" {
// JSON values
let json_null = null
@debug.debug_inspect(json_null, content="Null")
let json_bool = true.to_json()
@debug.debug_inspect(json_bool, content="True")
let json_number = (42 : Int).to_json()
@debug.debug_inspect(json_number, content="Number(42)")
let json_string = "hello".to_json()
@debug.debug_inspect(
json_string,
content=(
#|String("hello")
),
)
}///|
test "comparisons" {
// Equality
inspect(5 == 5, content="true")
inspect(5 != 3, content="true")
// Ordering
inspect(3 < 5, content="true")
inspect(5 > 3, content="true")
inspect(5 >= 5, content="true")
inspect(3 <= 5, content="true")
// String comparison
inspect("apple" < "banana", content="true")
inspect("hello" == "hello", content="true")
}///|
test "utilities" {
// Identity and ignore
let value = 42
ignore(value) // Discards the value
// Boolean negation
let result = !false
inspect(result, content="true")
// Physical equality (reference equality)
let arr1 = [1, 2, 3]
let arr2 = [1, 2, 3]
let same_ref = arr1
inspect(physical_equal(arr1, arr2), content="false") // Different objects
inspect(physical_equal(arr1, same_ref), content="true") // Same reference
}///|
test "error handling" {
// This would panic in a real scenario, but we demonstrate the concept
fn safe_divide(a : Int, b : Int) -> Int {
if b == 0 {
// In real code: panic()
// For testing, we return a default value
0
} else {
a / b
}
}
let result = safe_divide(10, 2)
inspect(result, content="5")
let safe_result = safe_divide(10, 0)
inspect(safe_result, content="0")
}pub(open) trait Add {
fn add(Self, Self) -> Self
}fn add(self : Byte, that : Byte) -> Bytefn add(self : Int, other : Int) -> Inttest {
inspect(42 + 1, content="43")
inspect(2147483647 + 1, content="-2147483648") // Overflow wraps around to minimum value
}fn add(self : Int64, other : Int64) -> Int64test {
let a = 9223372036854775807L // Int64 maximum value
let b = 1L
inspect(a + b, content="-9223372036854775808") // Wraps around to minimum value
inspect(42L + -42L, content="0")
}fn add(self : UInt, other : UInt) -> UInttest {
let a = 42U
let b = 100U
inspect(a + b, content="142")
// Demonstrate overflow behavior
let max = 4294967295U // UInt::max_value
inspect(max + 1U, content="0")
}fn add(self : UInt64, other : UInt64) -> UInt64test {
let a = 42UL
let b = 100UL
inspect(a + b, content="142")
// Demonstrate overflow behavior
let max = 18446744073709551615UL
inspect(max + 1UL, content="0")
}fn add(self : Double, other : Double) -> Doubletest {
inspect(2.5 + 3.7, content="6.2")
inspect(1.0 / 0.0 + -1.0 / 0.0, content="NaN") // Infinity + -Infinity = NaN
}fn add(self : String, other : String) -> Stringtest {
let hello = "Hello"
let world = " World!"
inspect(hello + world, content="Hello World!")
inspect("" + "abc", content="abc") // concatenating with empty string
}impl Add for FixedArray[T]fn[T] add(self : FixedArray[T], other : FixedArray[T]) -> FixedArray[T]test {
let arr1 : FixedArray[Int] = [1, 2, 3]
let arr2 : FixedArray[Int] = [4, 5, 6]
debug_inspect(
arr1 + arr2,
content=(
#|<FixedArray: [1, 2, 3, 4, 5, 6]>
),
)
}fn add(self : Bytes, other : Bytes) -> Bytesimpl Add for StringViewfn add(self : StringView, other : StringView) -> StringViewpub(open) trait BitAnd {
fn land(Self, Self) -> Self
}fn land(self : Byte, that : Byte) -> Bytefn land(self : Int, other : Int) -> Inttest {
let x = 0xF0 // 11110000
let y = 0xAA // 10101010
inspect(x & y, content="160") // 10100000 = 160
}fn land(self : Int64, other : Int64) -> Int64test {
let a = 0xFF00FF00L
let b = 0x0F0F0F0FL
inspect(a & b, content="251662080") // 0x0F000F00
}fn land(self : UInt, other : UInt) -> UInttest {
let a = 0xF0F0U // 1111_0000_1111_0000
let b = 0xFF00U // 1111_1111_0000_0000
inspect(a & b, content="61440") // 1111_0000_0000_0000 = 61440
}fn land(self : UInt64, other : UInt64) -> UInt64test {
let a = 0xF0F0F0F0F0F0F0F0UL
let b = 0xFF00FF00FF00FF00UL
inspect(a & b, content="17294086455919964160") // 0xF000F000F000F000
}pub(open) trait BitOr {
fn lor(Self, Self) -> Self
}fn lor(self : Byte, that : Byte) -> Bytefn lor(self : Int, other : Int) -> Inttest {
let x = 0xF0F0 // 1111_0000_1111_0000
let y = 0x0F0F // 0000_1111_0000_1111
inspect(x | y, content="65535") // 1111_1111_1111_1111 = 65535
}fn lor(self : Int64, other : Int64) -> Int64test {
let a = 0xFF00L // 1111_1111_0000_0000
let b = 0x0FF0L // 0000_1111_1111_0000
inspect(a | b, content="65520") // 1111_1111_1111_0000 = 65520
}fn lor(self : UInt, other : UInt) -> UInttest {
let a = 0xF0F0U // Binary: 1111_0000_1111_0000
let b = 0x0F0FU // Binary: 0000_1111_0000_1111
inspect(a | b, content="65535") // Binary: 1111_1111_1111_1111
}fn lor(self : UInt64, other : UInt64) -> UInt64test {
let a = 0xF0F0F0F0UL
let b = 0x0F0F0F0FUL
inspect(a | b, content="4294967295") // All bits set to 1
}pub(open) trait BitXOr {
fn lxor(Self, Self) -> Self
}fn lxor(self : Byte, that : Byte) -> Bytefn lxor(self : Int, other : Int) -> Inttest {
let x = 0xF0F0 // 1111_0000_1111_0000
let y = 0x0F0F // 0000_1111_0000_1111
inspect(x ^ y, content="65535") // 1111_1111_1111_1111
inspect(x ^ x, content="0") // XOR with self gives 0
}fn lxor(self : Int64, other : Int64) -> Int64test {
let a = 0xF0F0F0F0F0F0F0F0L
let b = 0x0F0F0F0F0F0F0F0FL
inspect(a ^ b, content="-1") // All bits set to 1
inspect(a ^ a, content="0") // XOR with self gives 0
}fn lxor(self : UInt, other : UInt) -> UInttest {
let a = 0xFF00U // Binary: 1111_1111_0000_0000
let b = 0x0F0FU // Binary: 0000_1111_0000_1111
inspect(a ^ b, content="61455") // Binary: 1111_0000_0000_1111
}fn lxor(self : UInt64, other : UInt64) -> UInt64test {
let a = 0xF0F0F0F0UL
let b = 0x0F0F0F0FUL
inspect(a ^ b, content="4294967295") // 0xFFFFFFFF
}pub(open) trait Compare : Eq {
fn compare(Self, Self) -> Int
fn op_lt(Self, Self) -> Bool = _
fn op_gt(Self, Self) -> Bool = _
fn op_le(Self, Self) -> Bool = _
fn op_ge(Self, Self) -> Bool = _
}fn compare(self : Bool, other : Bool) -> Inttest {
inspect(true.compare(false), content="1") // true > false
inspect(false.compare(true), content="-1") // false < true
inspect(true.compare(true), content="0") // true = true
}fn compare(self : Byte, that : Byte) -> Intfn op_ge(x : Byte, y : Byte) -> Boolfn op_gt(x : Byte, y : Byte) -> Boolfn op_le(x : Byte, y : Byte) -> Boolfn op_lt(x : Byte, y : Byte) -> Boolfn compare(self : Char, other : Char) -> Inttest {
inspect('a'.compare('b'), content="-1")
inspect('b'.compare('a'), content="1")
inspect('a'.compare('a'), content="0")
}fn op_ge(x : Char, y : Char) -> Boolfn op_gt(x : Char, y : Char) -> Boolfn op_le(x : Char, y : Char) -> Boolfn op_lt(x : Char, y : Char) -> Boolfn compare(self : Int, other : Int) -> Inttest {
let a = 42
let b = 24
inspect(a.compare(b), content="1") // 42 > 24
inspect(b.compare(a), content="-1") // 24 < 42
inspect(a.compare(a), content="0") // 42 = 42
}fn op_ge(x : Int, y : Int) -> Boolfn op_gt(x : Int, y : Int) -> Boolfn op_le(x : Int, y : Int) -> Boolfn op_lt(x : Int, y : Int) -> Boolfn compare(self : Int64, other : Int64) -> Inttest {
let a = 42L
let b = 24L
let c = -42L
inspect(a.compare(b), content="1") // 42 > 24
inspect(b.compare(a), content="-1") // 24 < 42
inspect(c.compare(a), content="-1") // -42 < 42
inspect(a.compare(a), content="0") // 42 = 42
}fn op_ge(x : Int64, y : Int64) -> Boolfn op_gt(x : Int64, y : Int64) -> Boolfn op_le(x : Int64, y : Int64) -> Boolfn op_lt(x : Int64, y : Int64) -> Boolfn compare(self : UInt, other : UInt) -> Inttest {
let a = 42U
let b = 24U
inspect(a.compare(b), content="1") // 42 > 24
inspect(b.compare(a), content="-1") // 24 < 42
inspect(a.compare(a), content="0") // 42 = 42
}fn op_ge(x : UInt, y : UInt) -> Boolfn op_gt(x : UInt, y : UInt) -> Boolfn op_le(x : UInt, y : UInt) -> Boolfn op_lt(x : UInt, y : UInt) -> Boolfn compare(self : UInt64, other : UInt64) -> Inttest {
let a = 42UL
let b = 24UL
inspect(a.compare(b), content="1") // 42 > 24
inspect(b.compare(a), content="-1") // 24 < 42
inspect(a.compare(a), content="0") // 42 = 42
}fn op_ge(x : UInt64, y : UInt64) -> Boolfn op_gt(x : UInt64, y : UInt64) -> Boolfn op_le(x : UInt64, y : UInt64) -> Boolfn op_lt(x : UInt64, y : UInt64) -> Boolfn compare(self : Double, other : Double) -> Inttest {
let a = 3.14
let b = 2.718
inspect(a.compare(b), content="1") // 3.14 > 2.718
inspect(b.compare(a), content="-1") // 2.718 < 3.14
inspect(a.compare(a), content="0") // 3.14 = 3.14
}fn op_ge(x : Double, y : Double) -> Boolfn op_gt(x : Double, y : Double) -> Boolfn op_le(x : Double, y : Double) -> Boolfn op_lt(x : Double, y : Double) -> Boolfn compare(self : String, other : String) -> Intimpl Compare for FixedArray[T]test {
let arr1 = [1, 2, 3]
let arr2 = [1, 2, 4]
let arr3 = [1, 2]
inspect(arr1.compare(arr2), content="-1") // arr1 < arr2
inspect(arr2.compare(arr1), content="1") // arr2 > arr1
inspect(arr1.compare(arr3), content="1") // arr1 > arr3 (longer)
inspect(arr1.compare(arr1), content="0") // arr1 = arr1
}impl Compare for ReadOnlyArray[T]fn compare(self : Bytes, other : Bytes) -> Inttest {
let a = b"\x01\x02\x03"
let b = b"\x01\x02\x04"
inspect(a.compare(b), content="-1") // a < b
inspect(b.compare(a), content="1") // b > a
inspect(a.compare(a), content="0") // a = a
let a = b"\x01\x02"
let b = b"\x01\x02\x03"
inspect(a.compare(b), content="-1") // shorter sequence is less
inspect(b.compare(a), content="1") // longer sequence is greater
}fn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq, T11 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq, T11 : Compare + Eq, T12 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq, T11 : Compare + Eq, T12 : Compare + Eq, T13 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq, T11 : Compare + Eq, T12 : Compare + Eq, T13 : Compare + Eq, T14 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)) -> Intfn[T0 : Compare + Eq, T1 : Compare + Eq, T2 : Compare + Eq, T3 : Compare + Eq, T4 : Compare + Eq, T5 : Compare + Eq, T6 : Compare + Eq, T7 : Compare + Eq, T8 : Compare + Eq, T9 : Compare + Eq, T10 : Compare + Eq, T11 : Compare + Eq, T12 : Compare + Eq, T13 : Compare + Eq, T14 : Compare + Eq, T15 : Compare + Eq] compare(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)) -> Intfn compare(self : BytesView, other : BytesView) -> Inttest {
let bytes = b"abcabc"
inspect(bytes[0:3].compare(bytes[3:6]), content="0") // abc = abc
inspect(bytes[0:3].compare(bytes[2:5]), content="-1") // abc < cab
inspect(bytes[1:4].compare(bytes[3:6]), content="1") // bca > abc
inspect(bytes[0:3].compare(bytes[0:4]), content="-1") // abc < abca
inspect(bytes[1:5].compare(bytes[2:5]), content="1") // bcab > cab
}impl Compare for StringViewfn compare(self : StringView, other : StringView) -> Intpub(open) trait Default {
fn default() -> Self
}fn default() -> Booltest {
let b : Bool = false
inspect(b, content="false")
}fn default() -> Bytefn default() -> Chartest {
assert_true((Default::default() : Char).to_string() == "\u0000")
}fn default() -> Inttest {
let x : Int = 0
inspect(x, content="0")
}fn default() -> Int64test {
inspect(0L, content="0")
}fn default() -> Doubletest {
inspect(0.0, content="0")
}impl Default for FixedArray[X]fn[X] default() -> FixedArray[X]test {
let arr : FixedArray[Int] = ([] : FixedArray[_])
inspect(arr.length(), content="0")
inspect(arr.is_empty(), content="true")
}impl Default for ReadOnlyArray[T]fn[T] default() -> ReadOnlyArray[T]fn default() -> Bytestest {
let bytes = (Default::default() : Bytes)
inspect(bytes, content="b\"\"")
inspect(bytes.length(), content="0")
}impl Default for StringViewfn default() -> StringViewpub(open) trait Div {
fn div(Self, Self) -> Self
}fn div(self : Byte, that : Byte) -> Bytetest {
let a = b'\xFF' // 255
let b = b'\x03' // 3
inspect(a / b, content="b'\\x55'") // 255 / 3 = 85 (0x55)
}fn div(self : Int, other : Int) -> Inttest {
inspect(10 / 3, content="3") // truncates towards zero
inspect(-10 / 3, content="-3")
inspect(10 / -3, content="-3")
}fn div(self : Int64, other : Int64) -> Int64test {
let a = 42L
let b = 5L
inspect(a / b, content="8")
let c = -42L
let d = 5L
inspect(c / d, content="-8")
}fn div(self : UInt, other : UInt) -> UInttest {
let a = 42U
let b = 5U
inspect(a / b, content="8") // Using infix operator
}fn div(self : UInt64, other : UInt64) -> UInt64test {
let a = 100UL
let b = 20UL
inspect(a / b, content="5") // Using infix operator
}fn div(self : Double, other : Double) -> Doubletest {
inspect(6.0 / 2.0, content="3")
inspect(-6.0 / 2.0, content="-3")
inspect(1.0 / 0.0, content="Infinity")
}pub(open) trait Eq {
fn equal(Self, Self) -> Bool
fn not_equal(Self, Self) -> Bool = _
}fn equal(self : Bool, other : Bool) -> Booltest {
inspect(true == true, content="true")
inspect(false == true, content="false")
inspect(true == false, content="false")
inspect(false == false, content="true")
}fn equal(self : Byte, that : Byte) -> Boolfn not_equal(self : Byte, that : Byte) -> Boolfn equal(self : Char, other : Char) -> Booltest {
let a = 'A'
let b = 'A'
let c = 'B'
inspect(a == b, content="true")
inspect(a == c, content="false")
}fn not_equal(self : Char, other : Char) -> Booltest {
let a = 'A'
let b = 'A'
let c = 'B'
inspect(a != b, content="false")
inspect(a != c, content="true")
}fn equal(self : Int, other : Int) -> Booltest {
inspect(42 == 42, content="true")
inspect(42 == -42, content="false")
}fn not_equal(self : Int, other : Int) -> Booltest {
inspect(42 != 42, content="false")
inspect(42 != -42, content="true")
}fn equal(self : Int64, other : Int64) -> Booltest {
let a = 42L
let b = 42L
let c = -42L
inspect(a == b, content="true")
inspect(a == c, content="false")
}fn not_equal(self : Int64, other : Int64) -> Booltest {
let a = 42L
let b = 42L
let c = -42L
inspect(a != b, content="false")
inspect(a != c, content="true")
}fn equal(self : UInt, other : UInt) -> Booltest {
let a = 42U
let b = 42U
let c = 24U
inspect(a == b, content="true")
inspect(a == c, content="false")
}fn not_equal(self : UInt, other : UInt) -> Booltest {
let a = 42U
let b = 42U
let c = 24U
inspect(a != b, content="false")
inspect(a != c, content="true")
}fn equal(self : UInt64, other : UInt64) -> Booltest {
let a = 42UL
let b = 42UL
let c = 24UL
inspect(a == b, content="true")
inspect(a == c, content="false")
}fn not_equal(self : UInt64, other : UInt64) -> Booltest {
let a = 42UL
let b = 42UL
let c = 24UL
inspect(a != b, content="false")
inspect(a != c, content="true")
}fn equal(self : Double, other : Double) -> Booltest {
let a = 3.14
let b = 3.14
let c = 2.718
inspect(a == b, content="true")
inspect(a == c, content="false")
let nan = 0.0 / 0.0 // NaN
inspect(nan == nan, content="false") // NaN != NaN
}fn not_equal(self : Double, other : Double) -> Booltest {
let a = 3.14
let b = 3.14
let c = 2.718
inspect(a != b, content="false")
inspect(a != c, content="true")
let nan = 0.0 / 0.0 // NaN
inspect(nan != nan, content="true") // NaN != NaN is true
}fn equal(self : String, other : String) -> Booltest {
let str1 = "hello"
let str2 = "hello"
let str3 = "world"
inspect(str1 == str2, content="true")
inspect(str1 == str3, content="false")
}impl Eq for FixedArray[T]test {
let arr1 : FixedArray[Int] = [1, 2, 3]
let arr2 : FixedArray[Int] = [1, 2, 3]
let arr3 : FixedArray[Int] = [1, 2, 4]
inspect(arr1 == arr2, content="true")
inspect(arr1 == arr3, content="false")
}impl Eq for ReadOnlyArray[T]fn equal(self : Bytes, other : Bytes) -> Booltest {
let bytes1 = b"\x01\x02\x03"
let bytes2 = b"\x01\x02\x03"
let bytes3 = b"\x01\x02\x04"
inspect(bytes1 == bytes2, content="true")
inspect(bytes1 == bytes3, content="false")
}fn[T0 : Eq, T1 : Eq, T2 : Eq, T3 : Eq, T4 : Eq, T5 : Eq, T6 : Eq, T7 : Eq, T8 : Eq, T9 : Eq, T10 : Eq, T11 : Eq, T12 : Eq, T13 : Eq, T14 : Eq] equal(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)) -> Boolfn[T0 : Eq, T1 : Eq, T2 : Eq, T3 : Eq, T4 : Eq, T5 : Eq, T6 : Eq, T7 : Eq, T8 : Eq, T9 : Eq, T10 : Eq, T11 : Eq, T12 : Eq, T13 : Eq, T14 : Eq, T15 : Eq] equal(self : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15), other : (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)) -> Boolfn equal(self : BytesView, other : BytesView) -> Booltest {
let bytes = b"abcabc"
inspect(bytes[0:3] == bytes[3:6], content="true")
inspect(bytes[0:3] == bytes[2:5], content="false")
inspect(bytes[0:4] == bytes[3:6], content="false")
}impl Eq for StringViewfn equal(self : StringView, other : StringView) -> Booltest {
let hasher = Hasher(seed=0)
hasher.combine_byte(b'\xFF')
inspect(hasher.finalize(), content="1955036104")
}fn hash(self : Int) -> Inttest {
let hasher = Hasher(seed=0)
hasher.combine_int(42)
inspect(hasher.finalize(), content="1161967057")
}fn hash(self : UInt) -> Inttest {
let hasher = Hasher(seed=0)
hasher.combine_uint(42U)
inspect(hasher.finalize(), content="1161967057")
}fn hash(self : UInt64) -> Inttest {
let hasher = Hasher(seed=0)
hasher.combine_uint64(42UL)
inspect(hasher.finalize(), content="-1962516083")
}fn hash(self : String) -> Inttest {
let s1 = "hello"
let s2 = "hello"
let s3 = "world"
inspect(Hash::hash(s1) == Hash::hash(s2), content="true")
inspect(Hash::hash(s1) == Hash::hash(s3), content="false")
}test {
let hasher = Hasher(seed=0)
let some_value : Int? = Some(42)
let none_value : Int? = None
hasher.combine(some_value)
inspect(hasher.finalize(), content="2103260413")
let hasher2 = Hasher(seed=0)
hasher2.combine(none_value)
inspect(hasher2.finalize(), content="148298089")
}test {
let hasher = Hasher(seed=0)
let ok_result : Result[Int, String] = Ok(42)
let err_result : Result[Int, String] = Err("error")
hasher.combine(ok_result)
inspect(hasher.finalize(), content="-1948635851")
let hasher = Hasher(seed=0)
hasher.combine(err_result)
inspect(hasher.finalize(), content="1953766574")
}impl Hash for FixedArray[T]impl Hash for ReadOnlyArray[T]impl Hash for StringViewpub(open) trait Logger {
fn write_string(Self, String) -> Unit = _
#deprecated("use `write_view` instead")
fn write_substring(Self, String, Int, Int) -> Unit = _
fn write_view(Self, StringView) -> Unit = _
fn write_char(Self, Char) -> Unit = _
fn write_string_interpolation(Self, &Show) -> Unit = _
fn write(Self, &Show) -> Unit = _
}pub(open) trait Mod {
fn mod(Self, Self) -> Self
}fn mod(self : Int, other : Int) -> Inttest {
inspect(7 % 3, content="1")
inspect(-7 % 3, content="-1")
inspect(7 % -3, content="1")
}fn mod(self : Int64, other : Int64) -> Int64test {
inspect(7L % 3L, content="1")
inspect(-7L % 3L, content="-1")
inspect(7L % -3L, content="1")
}fn mod(self : UInt, other : UInt) -> UInttest {
let a = 17U
let b = 5U
inspect(a % b, content="2") // 17 divided by 5 gives quotient 3 and remainder 2
inspect(7U % 4U, content="3")
}fn mod(self : UInt64, other : UInt64) -> UInt64test {
let a = 17UL
let b = 5UL
inspect(a % b, content="2") // 17 divided by 5 gives quotient 3 and remainder 2
inspect(7UL % 4UL, content="3")
}fn mod(self : Double, other : Double) -> Doubletest {
inspect(5.0.mod(3.0), content="2")
inspect((-5.0).mod(3.0), content="-2")
inspect(5.0.mod(@double.not_a_number), content="NaN")
inspect(@double.infinity.mod(3.0), content="NaN")
}pub(open) trait Mul {
fn mul(Self, Self) -> Self
}fn mul(self : Byte, that : Byte) -> Bytetest {
let a = b'\x02'
let b = b'\x03'
inspect(a * b, content="b'\\x06'") // 2 * 3 = 6
let c = b'\xFF'
inspect(c * c, content="b'\\x01'") // 255 * 255 = 65025, truncated to 1
}fn mul(self : Int, other : Int) -> Inttest {
inspect(42 * 2, content="84")
inspect(-10 * 3, content="-30")
let max = 2147483647 // Int.max_value
inspect(max * 2, content="-2") // Overflow wraps around
}fn mul(self : Int64, other : Int64) -> Int64test {
let a = 42L
let b = 100L
inspect(a * b, content="4200")
let c = -42L
inspect(c * b, content="-4200")
}fn mul(self : UInt, other : UInt) -> UInttest {
let a = 3U
let b = 4U
inspect(a * b, content="12")
let max = 4294967295U
inspect(max * 2U, content="4294967294") // Wraps around to max * 2 % 2^32
}fn mul(self : UInt64, other : UInt64) -> UInt64test {
let a = 2UL
let b = 3UL
inspect(a * b, content="6")
// Demonstrate wrapping behavior
let max = 18446744073709551615UL
inspect(max * 2UL, content="18446744073709551614") // Wraps around to max - 1
}fn mul(self : Double, other : Double) -> Doubletest {
inspect(2.5 * 2.0, content="5")
inspect(-2.0 * 3.0, content="-6")
let nan = 0.0 / 0.0 // NaN
inspect(nan * 1.0, content="NaN")
}pub(open) trait Neg {
fn neg(Self) -> Self
}fn neg(self : Int) -> Inttest {
inspect(-42, content="-42")
inspect(42, content="42")
inspect(2147483647, content="2147483647") // Int maximum value
}fn neg(self : Int64) -> Int64test {
inspect(-42L, content="-42")
inspect(42L, content="42")
inspect(-9223372036854775808L, content="-9223372036854775808") // negating min value
}fn neg(self : Double) -> Doubletest {
inspect(-42.0, content="-42")
inspect(42.0, content="42")
inspect(-(0.0 / 0.0), content="NaN") // Negating NaN returns NaN
}pub(open) trait Shl {
fn shl(Self, Int) -> Self
}fn shl(self : Byte, count : Int) -> Bytefn shl(self : Int, other : Int) -> Inttest {
let x = 1
inspect(x << 3, content="8") // Binary: 1 -> 1000
let y = -4
inspect(y << 2, content="-16") // Binary: 100 -> 10000
}fn shl(self : Int64, other : Int) -> Int64test {
let n = 1L
inspect(n << 3, content="8") // 1 shifted left by 3 positions becomes 8
let m = -4L
inspect(m << 2, content="-16") // -4 shifted left by 2 positions becomes -16
}fn shl(self : UInt, shift : Int) -> UInttest {
let x = 1U
inspect(x << 3, content="8") // Binary: 1 -> 1000
let y = 0xFFFFFFFFU
inspect(y << 16, content="4294901760") // All bits after position 16 are discarded
}fn shl(self : UInt64, shift : Int) -> UInt64test {
let x = 1UL
inspect(x << 3, content="8") // 1 shifted left by 3 positions becomes 8
inspect(x << 63, content="9223372036854775808") // 1 shifted left by 63 positions
}#must_implement_one(output, to_string)
pub(open) trait Show {
fn output(Self, &Logger) -> Unit = _
fn to_string(Self) -> String = _
}fn to_string(self : Char) -> Stringfn to_string(self : String) -> Stringtest {
let str = "Hello \n"
inspect(str.to_string(), content="Hello \n")
inspect(str.escape(quote=true), content="\"Hello \\n\"")
}impl Show for FixedArray[X]impl Show for ReadOnlyArray[T]impl Show for StringViewpub(open) trait Shr {
fn shr(Self, Int) -> Self
}fn shr(self : Byte, count : Int) -> Bytefn shr(self : Int, other : Int) -> Inttest {
let n = -16
inspect(n >> 2, content="-4") // Sign bit is preserved during shift
let p = 16
inspect(p >> 2, content="4") // Regular right shift for positive numbers
}fn shr(self : Int64, other : Int) -> Int64test {
let n = -1024L
inspect(n >> 3, content="-128") // Preserves sign bit
let p = 1024L
inspect(p >> 3, content="128") // Regular right shift for positive numbers
}fn shr(self : UInt, shift : Int) -> UInttest {
let x = 0xFF000000U
inspect(x >> 8, content="16711680") // 0x00FF0000
inspect(x >> 24, content="255") // 0x000000FF
let x = 0xFF000000U
inspect(x >> 32, content="4278190080") // Same as x >> 0 due to masking
}fn shr(self : UInt64, shift : Int) -> UInt64test {
let x = 0xFF00FF00FF00FF00UL
inspect(x >> 8, content="71777214294589695") // Shifted right by 8 bits
inspect(x >> 64, content="18374966859414961920") // Equivalent to x >> 0 due to masking
}pub(open) trait Sub {
fn sub(Self, Self) -> Self
}fn sub(self : Byte, that : Byte) -> Bytefn sub(self : Int, other : Int) -> Inttest {
let a = 42
let b = 10
inspect(a - b, content="32")
let max = 2147483647 // Int maximum value
inspect(max - -1, content="-2147483648") // Overflow case
}fn sub(self : Int64, other : Int64) -> Int64test {
let a = 9223372036854775807L // Int64 maximum value
let b = 1L
inspect(a - b, content="9223372036854775806")
let c = -9223372036854775808L // Int64 minimum value
let d = 1L
inspect(c - d, content="9223372036854775807")
}fn sub(self : UInt, other : UInt) -> UInttest {
let a = 5U
let b = 3U
inspect(a - b, content="2")
let c = 3U
let d = 5U
inspect(c - d, content="4294967294") // wraps around to 2^32 - 2
}fn sub(self : UInt64, other : UInt64) -> UInt64test {
let a = 5UL
let b = 3UL
inspect(a - b, content="2")
let c = 3UL
let d = 5UL
inspect(c - d, content="18446744073709551614") // wraps around to 2^64 - 2
}fn sub(self : Double, other : Double) -> Doubletest {
let a = 5.0
let b = 3.0
inspect(a - b, content="2")
inspect(0.0 / 0.0 - 1.0, content="NaN") // NaN - anything = NaN
}impl ToJson for FixedArray[X]impl ToJson for ReadOnlyArray[T]impl ToJson for StringViewpub trait ToStringView {
fn to_string_view(Self) -> StringView
}impl ToStringView for Stringfn to_string_view(self : String) -> StringViewimpl ToStringView for StringViewfn to_string_view(self : StringView) -> StringView#deprecated("This type is deprecated.")
pub(all) suberror BenchError {
BenchError(String)
}test {
let err : Failure = Failure("Test assertion failed")
match err {
Failure(msg) => inspect(msg, content="Test assertion failed")
}
@json.json_inspect(err, content=["Failure", "Test assertion failed"])
}pub(all) suberror InspectError {
InspectError(String)
}test {
let x : Int = 42
inspect(x, content="42") // A mismatch would raise InspectError with a detailed message
}pub(all) suberror SnapshotError {
SnapshotError(String)
}test {
let err : SnapshotError = SnapshotError("failed to load snapshot")
match err {
SnapshotError(msg) => @test.assert_eq(msg, "failed to load snapshot")
}
}type Array[T]test {
let a = [1, 2, 3]
let b = [4, 5]
debug_inspect(a + b, content="[1, 2, 3, 4, 5]")
}test {
let arr1 = [1, 2, 3]
let arr2 = [1, 2, 4]
let arr3 = [1, 2]
inspect(arr1.compare(arr2), content="-1") // arr1 < arr2
inspect(arr2.compare(arr1), content="1") // arr2 > arr1
inspect(arr1.compare(arr3), content="1") // arr1 > arr3 (longer)
inspect(arr1.compare(arr1), content="0") // arr1 = arr1
}test {
let arr1 = [1, 2, 3]
let arr2 = [1, 2, 3]
let arr3 = [1, 2, 4]
inspect(arr1 == arr2, content="true")
inspect(arr1 == arr3, content="false")
}test {
let arr : Array[Int] = Array(capacity=10)
inspect(arr.length(), content="0")
inspect(arr.capacity(), content="10")
let arr : Array[Int] = Array()
inspect(arr.length(), content="0")
}test {
let arr = [1, 2, 3, 4, 5]
assert_true(arr.all(x => x < 6))
assert_false(arr.all(x => x < 5))
}test {
let arr = [1, 2, 3, 4, 5]
assert_true(arr.any(x => x < 6))
assert_false(arr.any(x => x < 1))
}test {
let v1 = [1, 2, 3]
let v2 : ReadOnlyArray[Int] = [4, 5, 6]
v1.append(v2)
debug_inspect(v1, content="[1, 2, 3, 4, 5, 6]")
let v1 = [1, 2, 3]
let v2 : ReadOnlyArray[Int] = []
v1.append(v2)
debug_inspect(v1, content="[1, 2, 3]")
}test {
let arr : Array[Int] = [1, 2, 3]
inspect(arr[1], content="2")
}test {
let v = [3, 4, 5]
let result = v.binary_search(3)
@test.assert_eq(result, Ok(0)) // The element 3 is found at index 0
}test {
let arr = [1, 3, 5, 7, 9]
let find_3 = arr.binary_search_by(x => x.compare(3))
debug_inspect(find_3, content="Ok(1)")
let find_4 = arr.binary_search_by(x => x.compare(4))
debug_inspect(find_4, content="Err(2)")
}test {
let src = [1, 2, 3, 4, 5]
let dst = [0, 0]
src[:3].blit_to(dst, dst_offset=1)
@debug.debug_inspect(dst, content="[0, 1, 2, 3]")
}test {
let v = [1, 1, 2, 3, 2, 3, 2, 3, 4]
let chunks = v.chunk_by((x, y) => x <= y)
debug_inspect(
chunks,
content=(
#|[
#| <ArrayView: [1, 1, 2, 3]>,
#| <ArrayView: [2, 3]>,
#| <ArrayView: [2, 3, 4]>,
#|]
),
)
let v : Array[Int] = []
debug_inspect(v.chunk_by((x, y) => x <= y), content="[]")
}test {
let arr = [1, 2, 3, 4, 5]
let chunks = arr.chunks(2)
debug_inspect(
chunks,
content=(
#|[<ArrayView: [1, 2]>, <ArrayView: [3, 4]>, <ArrayView: [5]>]
),
)
let arr : Array[Int] = []
debug_inspect(arr.chunks(3), content="[]")
}test {
let v = [3, 4, 5]
v.clear()
@test.assert_eq(v.length(), 0)
}test {
let arr = [1, 2, 3, 4, 5]
inspect(arr.contains(3), content="true")
inspect(arr.contains(6), content="false")
let arr : Array[Int] = []
inspect(arr.contains(1), content="false")
}test {
let original = [1, 2, 3]
let copied = original.copy()
@debug.debug_inspect(copied, content="[1, 2, 3]")
inspect(physical_equal(original, copied), content="false")
}test {
let arr = [1, 2, 1, 3, 1]
inspect(arr.count(1), content="3")
inspect(arr.count(4), content="0")
}test {
let arr = [1, 2, 3, 4, 5]
inspect(arr.count_if(x => x % 2 == 0), content="2")
}test {
let arr = [1, 2, 2, 3, 3, 3, 2]
arr.dedup()
debug_inspect(arr, content="[1, 2, 3, 2]")
let arr = [1, 2, 2, 2, 3, 3]
arr.dedup()
debug_inspect(arr, content="[1, 2, 3]")
let arr : Array[Int] = []
arr.dedup()
debug_inspect(arr, content="[]")
}test {
let v = [3, 4, 5]
let vv = v.drain(1, 2) // vv = [4], v = [3, 5]
@test.assert_eq(vv, [4])
@test.assert_eq(v, [3, 5])
}test {
let arr = [1, 2, 3]
let mut sum = 0
arr.each(x => sum x)
inspect(sum, content="6")
}test {
let v = [3, 4, 5]
let mut sum = 0
v.eachi((i, x) => sum x + i)
inspect(sum, content="15")
}test {
let arr = [1, 2, 3, 4, 5]
inspect(arr.ends_with([4, 5]), content="true")
inspect(arr.ends_with([3, 4]), content="false")
inspect(arr.ends_with([]), content="true")
let arr : Array[Int] = []
inspect(arr.ends_with([]), content="true")
inspect(arr.ends_with([1]), content="false")
}test {
let arr = [1, 2, 3, 4, 5]
let extracted = arr.extract_if(x => x % 2 == 0)
debug_inspect(extracted, content="[2, 4]")
debug_inspect(arr, content="[1, 3, 5]")
}test {
// Fill entire array
let arr = [1, 2, 3, 4, 5]
arr.fill(0)
@debug.debug_inspect(arr, content="[0, 0, 0, 0, 0]")
// Fill from index 1 to 3 (exclusive)
let arr2 = [1, 2, 3, 4, 5]
arr2.fill(99, start=1, end=3)
@debug.debug_inspect(arr2, content="[1, 99, 99, 4, 5]")
// Fill from index 2 to end
let arr3 = ["a", "b", "c", "d"]
arr3.fill("x", start=2)
@debug.debug_inspect(
arr3,
content=(
#|["a", "b", "x", "x"]
),
)
}test {
let arr = [1, 2, 3, 4, 5]
let evens = arr.filter(x => x % 2 == 0)
debug_inspect(evens, content="[2, 4]")
}test {
let v = [[3, 4], [5, 6]].flatten()
@test.assert_eq(v, [3, 4, 5, 6])
}test {
let sum = [1, 2, 3, 4, 5].fold(init=0, (sum, elem) => sum + elem)
@test.assert_eq(sum, 15)
}test {
let sum = [1, 2, 3, 4, 5].foldi(init=0, (index, sum, _elem) => sum + index)
@test.assert_eq(sum, 10)
}test {
let fixed = FixedArray::make(3, 42)
let dynamic = Array::from_fixed_array(fixed)
debug_inspect(dynamic, content="[42, 42, 42]")
}test {
let iter = 42
let arr = Array::from_iter(iter)
debug_inspect(arr, content="[42]")
}test {
let arr = [1, 2, 3]
debug_inspect(arr.get(-1), content="None")
debug_inspect(arr.get(0), content="Some(1)")
debug_inspect(arr.get(3), content="None")
}test {
let arr = [1, 2, 3, 4, 5]
let start = 1
let end = 4
debug_inspect(
arr.get_view(start~, end~),
content=(
#|Some(<ArrayView: [2, 3, 4]>)
),
)
let start = 3
let end = 10
debug_inspect(arr.get_view(start~, end~), content="None")
}test {
let a = [1, 2, 3]
a.insert(1, 4)
@debug.debug_inspect(a, content="[1, 4, 2, 3]")
let b = [1, 2, 3]
b.insert(0, 5)
@debug.debug_inspect(b, content="[5, 1, 2, 3]")
let c = [1, 2, 3]
c.insert(3, 6)
@debug.debug_inspect(c, content="[1, 2, 3, 6]")
}test {
let empty : Array[Int] = []
inspect(empty.is_empty(), content="true")
let non_empty = [1, 2, 3]
inspect(non_empty.is_empty(), content="false")
}test {
let ascending = [1, 2, 3, 4, 5]
let descending = [5, 4, 3, 2, 1]
let unsorted = [1, 3, 2, 4, 5]
inspect(ascending.is_sorted(), content="true")
inspect(descending.is_sorted(), content="false")
inspect(unsorted.is_sorted(), content="false")
}test {
let arr = [1, 2, 3]
let mut sum = 0
arr.iter().each(x => sum x)
inspect(sum, content="6")
}test {
let arr = [10, 20, 30]
let mut sum = 0
arr.iter2().each((i, x) => sum i + x)
inspect(sum, content="63") // (0 + 10) + (1 + 20) + (2 + 30) = 63
}test {
let s = "hello world"
inspect(s.split(" ").to_array().join(":"), content="hello:world")
}test {
let arr = [1, 2, 3]
debug_inspect(arr.last(), content="Some(3)")
let empty : Array[Int] = []
debug_inspect(empty.last(), content="None")
}test {
let arr : Array[Int] = [1, 2, 3]
inspect(arr.length(), content="3")
let empty : Array[Int] = []
inspect(empty.length(), content="0")
}test {
inspect([1, 2].lexical_compare([1, 2, 3]), content="-1")
inspect([1, 2, 3].lexical_compare([1, 2]), content="1")
inspect([1, 2, 3].lexical_compare([1, 2, 3]), content="0")
inspect([1, 2, 3].lexical_compare([1, 2, 4]), content="-1")
}test {
let arr = Array::make(3, 42)
debug_inspect(arr, content="[42, 42, 42]")
}test {
let two_dimension_array = Array::make(10, Array::make(10, 0))
two_dimension_array[0][5] = 10
@test.assert_eq(two_dimension_array[5][5], 10)
}test {
let arr = Array::makei(3, i => i * 2)
debug_inspect(arr, content="[0, 2, 4]")
}test {
let v = [3, 4, 5]
let v2 = v.map(x => x + 1)
@test.assert_eq(v2, [4, 5, 6])
}test {
let v = [3, 4, 5]
v.map_in_place(x => x + 1)
@test.assert_eq(v, [4, 5, 6])
}test {
let v = [3, 4, 5]
let v2 = v.mapi((i, x) => x + i)
@test.assert_eq(v2, [3, 5, 7])
}test {
let v = [3, 4, 5]
v.mapi_in_place((i, x) => x + i)
@test.assert_eq(v, [3, 5, 7])
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr.mut_view(start=1, end=4) // Create a view of elements at indices 1, 2, and 3
inspect(view[0], content="2") // First element of view is arr[1]
inspect(view.length(), content="3") // View contains 3 elements
}test {
let v = [1, 2, 3]
@test.assert_eq(v.pop(), Some(3))
@test.assert_eq(v, [1, 2])
}test {
let v = []
v.push(3)
}test {
let u = [1, 2, 3]
let v = [4, 5, 6]
u.push_iter(v.iter())
@test.assert_eq(u, [1, 2, 3, 4, 5, 6])
}test {
let arr = ["a", "b", "c"]
let _ = arr.pop()
arr.release_unused(placeholder="")
debug_inspect(arr, content="[\"a\", \"b\"]")
}test {
let v = [3, 4, 5]
@test.assert_eq(v.remove(1), 4)
@test.assert_eq(v, [3, 5])
}test {
let v = [3, 4].repeat(2)
@test.assert_eq(v, [3, 4, 3, 4])
}test {
let v = [1]
v.reserve_capacity(10)
@test.assert_eq(v.capacity(), 10)
}test {
let arr = [1, 2, 3, 4, 5]
arr.resize(3, 0)
debug_inspect(arr, content="[1, 2, 3]")
let arr = [1, 2, 3]
arr.resize(5, 0)
debug_inspect(arr, content="[1, 2, 3, 0, 0]")
}test {
let arr = [1, 2, 3, 4, 5]
arr.retain(x => x % 2 == 0)
debug_inspect(arr, content="[2, 4]")
let arr = [1, 2, 3]
arr.retain(x => x > 10)
debug_inspect(arr, content="[]")
let arr = [1, 2, 3]
arr.retain(_ => true)
debug_inspect(arr, content="[1, 2, 3]")
}test {
let arr = [1, 2, 3, 4, 5]
arr.retain_map(fn(x) { if x % 2 == 0 { Some(x * 2) } else { None } })
debug_inspect(arr, content="[4, 8]")
}test {
let arr = [1, 2, 3, 4, 5]
debug_inspect(arr.rev(), content="[5, 4, 3, 2, 1]")
debug_inspect(arr, content="[1, 2, 3, 4, 5]") // original array unchanged
}test {
let v = [3, 4, 5]
let mut sum = 0
v.rev_each(x => sum = sum - x)
@json.json_inspect(sum, content=-12)
}test {
let v = [3, 4, 5]
let mut sum = 0
v.rev_eachi((i, x) => sum x + i)
@test.assert_eq(sum, 15)
}test {
let sum = [1, 2, 3, 4, 5].rev_fold(init=0, (sum, elem) => sum + elem)
@test.assert_eq(sum, 15)
}test {
let sum = [1, 2, 3, 4, 5].rev_foldi(init=0, (index, sum, _elem) => sum + index)
@test.assert_eq(sum, 10)
}test {
let arr = [1, 2, 3, 4, 5]
arr.rev_in_place()
debug_inspect(arr, content="[5, 4, 3, 2, 1]")
let arr : Array[Int] = []
arr.rev_in_place()
debug_inspect(arr, content="[]")
}test {
let arr = [1, 2, 3]
let result = []
arr.rev_iter().each(x => result.push(x))
debug_inspect(result, content="[3, 2, 1]")
}test {
let arr = [1, 2, 3, 2, 4]
debug_inspect(arr.search(2), content="Some(1)") // first occurrence
debug_inspect(arr.search(5), content="None") // not found
}test {
let v = [1, 2, 3, 4, 5]
match v.search_by(x => x == 3) {
Some(index) => @test.assert_eq(index, 2) // 2
None => println("Not found")
}
}test {
let arr = [1, 2, 3]
arr[1] = 42
debug_inspect(arr, content="[1, 42, 3]")
}test {
let v = Array(capacity=10)
v.push(1)
v.push(2)
v.push(3)
v.shrink_to_fit()
@test.assert_eq(v.capacity(), 3)
}let arr = [1, 2, 3, 4, 5]
fn rand(upper : Int) -> Int {
let rng = @random.Rand::new()
rng.int(limit=upper)
}
let _shuffled = Array::shuffle(arr, rand~)test {
let arr = [1, 2, 3, 4, 5]
fn rand(upper : Int) -> Int {
let rng = @random.Rand::new()
rng.int(limit=upper)
}
Array::shuffle_in_place(arr, rand~)
}test {
let arr = [5, 4, 3, 2, 1]
arr.sort()
@test.assert_eq(arr, [1, 2, 3, 4, 5])
}test {
let arr = [5, 3, 2, 4, 1]
arr.sort_by((a, b) => a - b)
@test.assert_eq(arr, [1, 2, 3, 4, 5])
}test {
let arr = [5, 3, 2, 4, 1]
arr.sort_by_key(x => -x)
@test.assert_eq(arr, [5, 4, 3, 2, 1])
}test {
let arr = [1, 0, 2, 0, 3, 0, 4]
debug_inspect(arr.split(x => x == 0), content="[[1], [2], [3], [4]]")
let arr = [0, 1, 0, 0, 2, 0]
debug_inspect(arr.split(x => x == 0), content="[[], [1], [], [2]]")
}test {
let arr = [1, 2, 3, 4, 5]
inspect(arr.starts_with([1, 2]), content="true")
inspect(arr.starts_with([2, 3]), content="false")
inspect(arr.starts_with([]), content="true")
inspect(arr.starts_with([1, 2, 3, 4, 5, 6]), content="false")
}test {
let v = [1, 2, 3, 4, 5]
let v2 = v.strip_prefix([1, 2])
debug_inspect(
v2,
content=(
#|Some(<ArrayView: [3, 4, 5]>)
),
)
}test {
let v = [3, 4, 5]
let v2 = v.strip_suffix([5])
debug_inspect(
v2,
content=(
#|Some(<ArrayView: [3, 4]>)
),
)
}test {
let xs = [1, 2]
debug_inspect(
xs.suffixes().collect(),
content=(
#|[<ArrayView: [1, 2]>, <ArrayView: [2]>]
),
)
debug_inspect(
xs.suffixes(include_empty=true).collect(),
content=(
#|[<ArrayView: [1, 2]>, <ArrayView: [2]>, <ArrayView: []>]
),
)
}test {
let arr = [1, 2, 3]
arr.swap(0, 2)
debug_inspect(arr, content="[3, 2, 1]")
}test {
let arr = [1, 2, 3, 4, 5]
arr.truncate(3)
debug_inspect(arr, content="[1, 2, 3]")
}test {
let src = FixedArray::make(5, 0)
let dst = Array::make(5, 0)
for i in 0..<5 {
src[i] = i + 1
}
Array::unsafe_blit_fixed(dst, 1, src, 0, 2)
@debug.debug_inspect(dst, content="[0, 1, 2, 0, 0]")
}test {
let arr : Array[Int] = [1, 2, 3]
inspect(arr.unsafe_get(1), content="2")
}test {
let arr = [1, 2, 3]
arr.unsafe_set(1, 99)
debug_inspect(arr, content="[1, 99, 3]")
}test {
let arr = [(1, "a"), (2, "b"), (3, "c")]
let (nums, strs) = arr.unzip()
debug_inspect(nums, content="[1, 2, 3]")
debug_inspect(strs, content="[\"a\", \"b\", \"c\"]")
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4] // Create a view of elements at indices 1, 2, and 3
inspect(view[0], content="2") // First element of view is arr[1]
inspect(view.length(), content="3") // View contains 3 elements
}test {
let arr = [1, 2, 3, 4, 5]
let windows = arr.windows(2)
debug_inspect(
windows,
content=(
#|[
#| <ArrayView: [1, 2]>,
#| <ArrayView: [2, 3]>,
#| <ArrayView: [3, 4]>,
#| <ArrayView: [4, 5]>,
#|]
),
)
let arr = [1, 2]
debug_inspect(arr.windows(3), content="[]")
}test {
let arr1 = [1, 2, 3]
let arr2 = ['a', 'b', 'c']
debug_inspect(arr1.zip(arr2), content="[(1, 'a'), (2, 'b'), (3, 'c')]")
}test {
let arr1 = [1, 2, 3]
let arr2 = ['a', 'b', 'c']
debug_inspect(
arr1.zip_to_iter2(arr2).to_array(),
content="[(1, 'a'), (2, 'b'), (3, 'c')]",
)
}type ArrayView[T]test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4] // Creates a view of elements at indices 1,2,3
@test.assert_eq(view[0], 2)
@test.assert_eq(view.length(), 3)
}test {
let a = [1, 2, 3, 4, 5][1:4]
let b = [10, 20, 30][:2]
debug_inspect(
a + b,
content=(
#|<ArrayView: [2, 3, 4, 10, 20]>
),
)
}test {
let v = [1, 4, 6, 8, 9]
assert_false(v[:].all(elem => elem % 2 == 0))
assert_true(v[1:4].all(elem => elem % 2 == 0))
}test {
let v = [1, 2, 3, 4, 5][:]
assert_true(v.any(ele => ele < 6))
assert_false(v.any(ele => ele < 1))
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[2:4]
inspect(view[0], content="3")
inspect(view[1], content="4")
}test {
let view = [1, 3, 5, 7, 9][:]
debug_inspect(view.binary_search(5), content="Ok(2)")
debug_inspect(view.binary_search(6), content="Err(3)")
}test {
let view = [1, 3, 5, 7, 9][:]
let result = view.binary_search_by(x => x.compare(5))
debug_inspect(result, content="Ok(2)")
}test {
let src = [1, 2, 3, 4, 5]
let view = src[1:4] // view = [2, 3, 4]
let dst = [0, 0]
view.blit_to(dst, dst_offset=1)
@debug.debug_inspect(dst, content="[0, 2, 3, 4]")
}test {
let v = [1, 1, 2, 2, 2, 3, 1][:]
debug_inspect(
v.chunk_by((a, b) => a == b),
content=(
#|[
#| <ArrayView: [1, 1]>,
#| <ArrayView: [2, 2, 2]>,
#| <ArrayView: [3]>,
#| <ArrayView: [1]>,
#|]
),
)
}test {
let v = [1, 2, 3, 4, 5, 6, 7][:]
debug_inspect(
v.chunks(3),
content=(
#|[<ArrayView: [1, 2, 3]>, <ArrayView: [4, 5, 6]>, <ArrayView: [7]>]
),
)
}test {
let arr = [1, 2, 3, 4, 5][:]
inspect(arr.contains(3), content="true")
inspect(arr.contains(6), content="false")
}test {
let view = [1, 2, 1, 3, 1][:]
inspect(view.count(1), content="3")
inspect(view.count(4), content="0")
}test {
let view = [1, 2, 3, 4, 5][:]
inspect(view.count_if(x => x % 2 == 0), content="2")
}test {
let arr = [1, 2, 3][:]
let mut sum = 0
arr.each(x => sum x)
inspect(sum, content="6")
}test {
let v = [3, 4, 5][:]
let mut sum = 0
v.eachi((i, x) => sum x + i)
inspect(sum, content="15")
}test {
let view = [1, 2, 3, 4, 5][:]
inspect(view.ends_with([4, 5]), content="true")
inspect(view.ends_with([3, 4]), content="false")
}test {
let arr = [1, 2, 3, 4, 5, 6]
let v = arr[2:].filter(x => x % 2 == 0)
@test.assert_eq(v, [4, 6])
}test {
let v = [1, 2, 3, 4, 5][1:4]
debug_inspect(
v.filter_map(x => if x % 2 == 0 { Some(x * 10) } else { None }),
content="[20, 40]",
)
}test {
let sum = [1, 2, 3, 4, 5][:].fold(init=0, (sum, elem) => sum + elem)
inspect(sum, content="15")
}test {
let sum = [1, 2, 3, 4, 5][:].foldi(init=0, (index, sum, _elem) => sum + index)
inspect(sum, content="10")
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4]
debug_inspect(view.get(0), content="Some(2)")
debug_inspect(view.get(1), content="Some(3)")
debug_inspect(view.get(2), content="Some(4)")
debug_inspect(view.get(5), content="None")
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4] // view = [2, 3, 4]
let start = 1
let end = 2
debug_inspect(
view.get_view(start~, end~),
content=(
#|Some(<ArrayView: [3]>)
),
)
let start = 4
let end = 5
debug_inspect(view.get_view(start~, end~), content="None")
}test {
let view = [1, 2, 3][:]
inspect(view.is_empty(), content="false")
let empty = [1, 2][0:0]
inspect(empty.is_empty(), content="true")
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4]
inspect(view.is_sorted(), content="true")
let descending : ReadOnlyArray[Int] = [5, 4, 3, 2, 1]
inspect(descending[:].is_sorted(), content="false")
}test {
let arr = [1, 2, 3]
let view = arr[1:]
let mut sum = 0
view.iter().each(x => sum x)
inspect(sum, content="5")
}test {
let arr = [1, 2, 3]
let view = arr[1:]
let mut sum = 0
let mut sum_keys = 0
view
.iter2()
.each((i, x) => {
sum x
sum_keys i
})
inspect(sum, content="5")
inspect(sum_keys, content="1")
}test {
let a : Array[String] = ["1", "2", "3"]
let array_view = a[:]
inspect(array_view.join(","), content="1,2,3")
}test {
let view = [1, 2, 3][:]
debug_inspect(view.last(), content="Some(3)")
let empty = [1, 2][0:0]
debug_inspect(empty.last(), content="None")
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[2:4]
inspect(view.length(), content="2")
}test {
inspect([1, 2][:].lexical_compare([1, 2, 3]), content="-1")
inspect([1, 2, 3][:].lexical_compare([1, 2]), content="1")
inspect([1, 2, 3][:].lexical_compare([1, 2, 3]), content="0")
inspect([1, 2, 3][:].lexical_compare([1, 2, 4]), content="-1")
}test {
let v = [3, 4, 5]
let v2 = v[1:].map(x => x + 1)
@test.assert_eq(v2, [5, 6])
}test {
let v = [3, 4, 5]
let v2 = v[1:].mapi((i, x) => x + i)
@test.assert_eq(v2, [4, 6])
}test {
let v = [1, 2, 3, 4, 5][1:4]
debug_inspect(v.rev(), content="[4, 3, 2]")
// The view itself is unchanged.
debug_inspect(
v,
content=(
#|<ArrayView: [2, 3, 4]>
),
)
}test {
let v = [1, 2, 3, 4, 5][1:4]
let out = []
v.rev_each(x => out.push(x))
debug_inspect(out, content="[4, 3, 2]")
}test {
let v = [10, 20, 30][:]
let out = []
v.rev_eachi((i, x) => out.push((i, x)))
debug_inspect(out, content="[(0, 30), (1, 20), (2, 10)]")
}test {
let sum = [1, 2, 3, 4, 5][:].rev_fold(init=0, (sum, elem) => sum + elem)
inspect(sum, content="15")
}test {
let sum = [1, 2, 3, 4, 5][:].rev_foldi(init=0, (index, sum, _elem) => {
sum + index
})
inspect(sum, content="10")
}test {
let values = [1, 2, 3][:].rev_iter().collect()
debug_inspect(values, content="[3, 2, 1]")
}test {
let view = [1, 2, 3, 2, 4][:]
debug_inspect(view.search(2), content="Some(1)")
debug_inspect(view.search(5), content="None")
}test {
let view = [1, 2, 3, 4, 5][1:]
debug_inspect(view.search_by(x => x > 3), content="Some(2)")
debug_inspect(view.search_by(x => x > 99), content="None")
}test {
let arr = [10, 20, 30]
let v = arr[1:]
inspect(v.start_offset(), content="1")
}test {
let view = [1, 2, 3, 4, 5][:]
inspect(view.starts_with([1, 2]), content="true")
inspect(view.starts_with([2, 3]), content="false")
}test {
let v = [1, 2, 3, 4, 5][:]
debug_inspect(
v.strip_prefix([1, 2]),
content=(
#|Some(<ArrayView: [3, 4, 5]>)
),
)
debug_inspect(v.strip_prefix([2, 3]), content="None")
}test {
let v = [1, 2, 3, 4, 5][:]
debug_inspect(
v.strip_suffix([4, 5]),
content=(
#|Some(<ArrayView: [1, 2, 3]>)
),
)
debug_inspect(v.strip_suffix([3, 4]), content="None")
}test {
let v = [1, 2][:]
debug_inspect(
v.suffixes().collect(),
content=(
#|[<ArrayView: [1, 2]>, <ArrayView: [2]>]
),
)
debug_inspect(
v.suffixes(include_empty=true).collect(),
content=(
#|[<ArrayView: [1, 2]>, <ArrayView: [2]>, <ArrayView: []>]
),
)
}test {
let view = [1, 2, 3, 4, 5, 6][2:4]
let arr = view.to_owned()
@test.assert_eq(arr, [3, 4])
}test {
let arr = [1, 2, 3, 4, 5]
let view = arr[1:4] // view = [2, 3, 4]
let subview = view[1:2] // subview = [3]
inspect(subview[0], content="3")
}test {
let v = [1, 2, 3, 4, 5][:]
debug_inspect(
v.windows(3),
content=(
#|[
#| <ArrayView: [1, 2, 3]>,
#| <ArrayView: [2, 3, 4]>,
#| <ArrayView: [3, 4, 5]>,
#|]
),
)
}type Hashertest {
let hasher = Hasher(seed=0)
hasher.combine_int(42)
hasher.combine_string("hello")
inspect(hasher.finalize(), content="860601284")
}test {
let h1 = Hasher(seed=0) // Create a hasher with default seed
let h2 = Hasher(seed=42) // Create a hasher with custom seed
let x = 123
h1.combine(x)
h2.combine(x)
inspect(h1.finalize() != h2.finalize(), content="true") // Different seeds produce different hashes
}test {
let hasher = Hasher(seed=0)
hasher.combine(42)
hasher.combine("hello")
inspect(hasher.finalize(), content="860601284")
}test {
let hasher = Hasher(seed=0)
hasher.combine_bool(true)
inspect(hasher.finalize(), content="-205818221")
}test {
let hasher = Hasher(seed=0)
hasher.combine_byte(b'\xFF')
inspect(hasher.finalize(), content="1955036104")
}test {
let hasher = Hasher(seed=0)
hasher.combine_bytes(b"\xFF\x00\xFF\x00")
inspect(hasher.finalize(), content="-686861102")
}test {
let hasher = Hasher(seed=0)
hasher.combine_char('A')
inspect(hasher.finalize(), content="-1625495534")
}test {
let hasher = Hasher(seed=0)
hasher.combine_double(3.14)
inspect(hasher.finalize(), content="-428265677")
}test {
let hasher = Hasher(seed=0)
hasher.combine(3.14F)
inspect(hasher.finalize(), content="635116317") // Hash of the bits of 3.14
}test {
let hasher = Hasher(seed=0)
hasher.combine_int(42)
inspect(hasher.finalize(), content="1161967057")
}test {
let hasher = Hasher(seed=0)
hasher.combine_int64(42L)
inspect(hasher.finalize(), content="-1962516083")
}test {
let hasher = Hasher(seed=0)
hasher.combine_string("hello")
inspect(hasher.finalize(), content="-655549713")
}test {
let hasher = Hasher(seed=0)
hasher.combine_uint(42U)
inspect(hasher.finalize(), content="1161967057")
}test {
let hasher = Hasher(seed=0)
hasher.combine_uint64(42UL)
inspect(hasher.finalize(), content="-1962516083")
}test {
let hasher = Hasher(seed=0)
hasher.combine_unit()
inspect(hasher.finalize(), content="148298089")
}test {
let hasher = Hasher(seed=0)
hasher.combine_byte(b'\xFF')
inspect(hasher.finalize(), content="1955036104")
}#alias(Iterator, deprecated="The name `Iterator` is deprecated, use `Iter` instead. Note that if you have defined `iterator()` method to support `for .. in` loop, you should also rename `iterator()` to `iter()`. See https://github.com/moonbitlang/core/pull/3127 for more details.")
type Iter[X]test {
let iter = 1, 2, 3, 4, 5
inspect(iter.contains(3), content="true")
inspect(iter.contains(6), content="false")
let iter =
inspect(iter.contains(1), content="false")
}test {
let arr = []
1, 2, 3.intersperse(0).each(i => arr.push(i))
@test.assert_eq(arr, [1, 0, 2, 0, 3])
}test {
let numbers = (1).until(5)
let letters = "a", "b", "c"
debug_inspect(
numbers.zip(letters).collect(),
content="[(1, \"a\"), (2, \"b\"), (3, \"c\")]",
)
}#alias(Iterator2, deprecated="The name `Iterator2` is deprecated, use `Iter2` instead. Note that if you have defined `iterator2()` method to support `for .. in` loop, you should also rename `iterator2()` to `iter2()`. See https://github.com/moonbitlang/core/pull/3127 for more details.")
pub(all) struct Iter2[X, Y](Iter[(X, Y)])test {
let value : Json = Json::array([Json::number(1.0), Json::null()])
inspect(value.stringify(), content="[1,null]")
}test {
@debug.debug_inspect(Json(42), content="Number(42)")
@debug.debug_inspect(Json("hello"), content="String(\"hello\")")
@debug.debug_inspect(Json([1, 2]), content="Array([Number(1), Number(2)])")
}test {
let values : Array[Json] = [1.0, "hello"]
@debug.debug_inspect(
Json::array(values),
content="Array([Number(1), String(\"hello\")])",
)
}test {
@debug.debug_inspect(Json::boolean(true), content="True")
@debug.debug_inspect(Json::boolean(false), content="False")
}test {
@debug.debug_inspect(Json::number(3.14), content="Number(3.14)")
inspect(
Json::number(@double.infinity, repr="1e9999999999999999999999999999999").stringify(),
content="1e9999999999999999999999999999999",
)
}test {
let map : Map[String, Json] = { "name": "John", "age": 42.0 }
@debug.debug_inspect(
Json::object(map),
content="Object({ \"name\": String(\"John\"), \"age\": Number(42) })",
)
}test {
@debug.debug_inspect(Json::string("hello"), content="String(\"hello\")")
}type Map[K, V]test {
let map = { 3: "three", 8: "eight", 1: "one" }
@test.assert_eq(map.get(2), None)
@test.assert_eq(map.get(3), Some("three"))
map.set(3, "updated")
@test.assert_eq(map.get(3), Some("updated"))
}test {
let map = { "a": 1, "b": 2 }
inspect(map.contains_kv("a", 1), content="true")
inspect(map.contains_kv("a", 2), content="false")
inspect(map.contains_kv("c", 3), content="false")
}test {
let map = { "key": 42 }
debug_inspect(map.get("key"), content="Some(42)")
debug_inspect(map.get("nonexistent"), content="None")
}test {
let map = { b"hello": 1, b"world": 2 }
let bytes = b"prefix_hello_suffix"
let view = bytes[7:12] // view of "hello"
debug_inspect(map.get_from_bytes(view), content="Some(1)")
}test {
let map = { "hello": 1, "world": 2 }
let str = "say hello to everyone"
let view = str.view(start_offset=4, end_offset=9) // view of "hello"
debug_inspect(map.get_from_string(view), content="Some(1)")
}test {
let map = { "a": 1, "b": 2 }
inspect(map.get_or_default("a", 0), content="1")
inspect(map.get_or_default("c", 42), content="42")
}