2024-11-30 14:48:01 +00:00
|
|
|
import gleam/list
|
|
|
|
import gleeunit
|
|
|
|
import gleeunit/should
|
2024-11-30 18:38:22 +00:00
|
|
|
import ieee_float.{finite, nan, positive_infinity}
|
|
|
|
import kmer.{
|
2024-11-30 19:50:40 +00:00
|
|
|
type DecodeResult, type DecodedValue, Array, Boolean, Bytes, Float, Integer,
|
2024-11-30 20:13:08 +00:00
|
|
|
Map, Null, String, Undefined,
|
2024-11-30 18:38:22 +00:00
|
|
|
}
|
2024-11-30 14:48:01 +00:00
|
|
|
|
|
|
|
pub fn main() {
|
|
|
|
gleeunit.main()
|
|
|
|
}
|
|
|
|
|
2024-11-30 18:38:22 +00:00
|
|
|
fn table_test_decode(test_case: BitArray, expected: DecodedValue) {
|
|
|
|
kmer.decode(test_case) |> is_value(expected)
|
2024-11-30 14:48:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn is_value(val: DecodeResult, expected: DecodedValue) {
|
|
|
|
should.be_ok(val) |> should.equal(#(expected, <<>>))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_immediate_int_test() {
|
|
|
|
[
|
|
|
|
// Small integers under 24
|
|
|
|
#(<<0>>, Integer(0)),
|
|
|
|
#(<<10>>, Integer(10)),
|
|
|
|
#(<<23>>, Integer(23)),
|
|
|
|
]
|
2024-11-30 18:38:22 +00:00
|
|
|
|> table_fn(table_test_decode)
|
2024-11-30 14:48:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_int_test() {
|
|
|
|
[
|
|
|
|
// 1-byte length (Maj.arg 24)
|
|
|
|
#(<<24, 24>>, Integer(24)),
|
|
|
|
#(<<24, 100>>, Integer(100)),
|
|
|
|
// 2-byte length (Maj.arg 25)
|
|
|
|
#(<<25, 1234:16>>, Integer(1234)),
|
|
|
|
#(<<25, 12_345:16>>, Integer(12_345)),
|
|
|
|
// 3-byte length (Maj.arg 26)
|
|
|
|
#(<<26, 1_234_567:32>>, Integer(1_234_567)),
|
|
|
|
#(<<26, 999_999_999:32>>, Integer(999_999_999)),
|
|
|
|
// 4-byte length (Maj.arg 27)
|
|
|
|
#(<<27, 2_099_210_021_019_898_881:64>>, Integer(2_099_210_021_019_898_881)),
|
|
|
|
#(<<27, 3:64>>, Integer(3)),
|
|
|
|
]
|
2024-11-30 18:38:22 +00:00
|
|
|
|> table_fn(table_test_decode)
|
2024-11-30 14:48:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_negative_int_test() {
|
|
|
|
[
|
|
|
|
// Immediate negative (under 25)
|
|
|
|
#(<<1:3, 0:5>>, Integer(-1)),
|
|
|
|
#(<<1:3, 8:5>>, Integer(-9)),
|
|
|
|
#(<<1:3, 23:5>>, Integer(-24)),
|
|
|
|
// 1-byte length (Maj.arg 24)
|
|
|
|
#(<<1:3, 24:5, 24:8>>, Integer(-25)),
|
|
|
|
#(<<1:3, 24:5, 100:8>>, Integer(-101)),
|
|
|
|
// 2-byte length (Maj.arg 25)
|
|
|
|
#(<<1:3, 25:5, 1234:16>>, Integer(-1235)),
|
|
|
|
#(<<1:3, 25:5, 12_345:16>>, Integer(-12_346)),
|
|
|
|
// 3-byte length (Maj.arg 26)
|
|
|
|
#(<<1:3, 26:5, 1_234_567:32>>, Integer(-1_234_568)),
|
|
|
|
#(<<1:3, 26:5, 999_999_999:32>>, Integer(-1_000_000_000)),
|
|
|
|
// 4-byte length (Maj.arg 27)
|
|
|
|
#(
|
|
|
|
<<1:3, 27:5, 2_099_210_021_019_898_881:64>>,
|
|
|
|
Integer(-2_099_210_021_019_898_882),
|
|
|
|
),
|
|
|
|
#(<<1:3, 27:5, 3:64>>, Integer(-4)),
|
|
|
|
]
|
2024-11-30 18:38:22 +00:00
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_simple_test() {
|
|
|
|
[
|
|
|
|
#(<<7:3, 20:5>>, Boolean(False)),
|
|
|
|
#(<<7:3, 21:5>>, Boolean(True)),
|
|
|
|
#(<<7:3, 22:5>>, Null),
|
|
|
|
#(<<7:3, 23:5>>, Undefined),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_float_test() {
|
|
|
|
[
|
|
|
|
#(<<7:3, 25:5, 0x0000:16>>, Float(finite(0.0))),
|
|
|
|
#(<<7:3, 25:5, 0x3c00:16>>, Float(finite(1.0))),
|
|
|
|
#(<<7:3, 25:5, 0x3e00:16>>, Float(finite(1.5))),
|
|
|
|
#(<<7:3, 25:5, 0xc400:16>>, Float(finite(-4.0))),
|
|
|
|
#(<<7:3, 25:5, 0x7c00:16>>, Float(positive_infinity())),
|
|
|
|
#(<<7:3, 25:5, 0x7e00:16>>, Float(nan())),
|
|
|
|
#(<<7:3, 26:5, 0x47c35000:32>>, Float(finite(100_000.0))),
|
|
|
|
#(<<7:3, 27:5, 0x3ff199999999999a:64>>, Float(finite(1.1))),
|
|
|
|
#(<<7:3, 27:5, 0x7e37e43c8800759c:64>>, Float(finite(1.0e300))),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_bytestring_test() {
|
|
|
|
[
|
|
|
|
#(
|
|
|
|
<<2:3, 9:5, 10, 11, 12, 13, 14, 15, 16, 17, 18>>,
|
|
|
|
Bytes(<<10, 11, 12, 13, 14, 15, 16, 17, 18>>),
|
|
|
|
),
|
|
|
|
#(
|
|
|
|
<<2:3, 24:5, 8:8, 11, 12, 13, 14, 15, 16, 17, 18>>,
|
|
|
|
Bytes(<<11, 12, 13, 14, 15, 16, 17, 18>>),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn decode_string_test() {
|
|
|
|
[
|
|
|
|
#(<<3:3, 11:5, "Hello world">>, String("Hello world")),
|
|
|
|
#(
|
|
|
|
<<3:3, 24:5, 25:8, "perché siamo fatti così">>,
|
|
|
|
String("perché siamo fatti così"),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
2024-11-30 14:48:01 +00:00
|
|
|
}
|
|
|
|
|
2024-11-30 19:50:40 +00:00
|
|
|
pub fn decode_list_test() {
|
|
|
|
[
|
|
|
|
#(
|
|
|
|
<<4:3, 5:5, 1, 2, 3, 4, 5>>,
|
|
|
|
Array([Integer(1), Integer(2), Integer(3), Integer(4), Integer(5)]),
|
|
|
|
),
|
|
|
|
#(
|
|
|
|
<<4:3, 24:5, 3:8, 3:3, 11:5, "Hello world", 1:3, 24:5, 123:8, 3>>,
|
|
|
|
Array([String("Hello world"), Integer(-124), Integer(3)]),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
2024-11-30 20:13:08 +00:00
|
|
|
pub fn decode_map_test() {
|
|
|
|
[
|
|
|
|
#(
|
|
|
|
<<5:3, 2:5, 3:3, 8:5, "test-key", 5, 3:3, 5:5, "other", 10>>,
|
|
|
|
Map([#(String("test-key"), Integer(5)), #(String("other"), Integer(10))]),
|
|
|
|
),
|
|
|
|
#(
|
|
|
|
<<5:3, 24:5, 4:8, 1, 2, 3, 4, 5, 6, 7, 8>>,
|
|
|
|
Map([
|
|
|
|
#(Integer(1), Integer(2)),
|
|
|
|
#(Integer(3), Integer(4)),
|
|
|
|
#(Integer(5), Integer(6)),
|
|
|
|
#(Integer(7), Integer(8)),
|
|
|
|
]),
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|> table_fn(table_test_decode)
|
|
|
|
}
|
|
|
|
|
2024-11-30 14:48:01 +00:00
|
|
|
fn table_fn(tests: List(#(a, b)), test_fn: fn(a, b) -> Nil) {
|
|
|
|
list.map(tests, fn(t) {
|
|
|
|
let #(test_case, expected) = t
|
|
|
|
test_fn(test_case, expected)
|
|
|
|
})
|
|
|
|
}
|