mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-28 18:30:06 +00:00
Merge branch 'master' into fix-fmt-compquat-sign
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
ODIN=../../odin
|
||||
COMMON=-no-bounds-check -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
|
||||
all: crypto_bench \
|
||||
hash_bench
|
||||
|
||||
crypto_bench:
|
||||
$(ODIN) test crypto $(COMMON) -o:speed -out:bench_crypto
|
||||
|
||||
hash_bench:
|
||||
$(ODIN) test hash $(COMMON) -o:speed -out:bench_hash
|
||||
|
||||
clean:
|
||||
rm bench_*
|
||||
@@ -0,0 +1,13 @@
|
||||
@echo off
|
||||
set COMMON=-no-bounds-check -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
set PATH_TO_ODIN==..\..\odin
|
||||
|
||||
echo ---
|
||||
echo Running core:crypto benchmarks
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test crypto %COMMON% -o:speed -out:bench_crypto.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:hash benchmarks
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test hash %COMMON% -o:speed -out:bench_hash.exe || exit /b
|
||||
@@ -0,0 +1,356 @@
|
||||
package benchmark_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
|
||||
import "core:crypto/aes"
|
||||
import "core:crypto/chacha20"
|
||||
import "core:crypto/chacha20poly1305"
|
||||
import "core:crypto/ed25519"
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
// Cryptographic primitive benchmarks.
|
||||
|
||||
@(test)
|
||||
benchmark_crypto :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str, context.allocator)
|
||||
defer {
|
||||
log.info(strings.to_string(str))
|
||||
strings.builder_destroy(&str)
|
||||
}
|
||||
|
||||
{
|
||||
name := "ChaCha20 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_chacha20,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "ChaCha20 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "ChaCha20 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "Poly1305 64 zero bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_poly1305,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "Poly1305 1024 zero bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "chacha20poly1305 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_chacha20poly1305,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "chacha20poly1305 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "chacha20poly1305 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "AES256-GCM 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_aes256_gcm,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
key := [aes.KEY_SIZE_256]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
ctx: aes.Context_GCM
|
||||
aes.init_gcm(&ctx, key[:])
|
||||
|
||||
context.user_ptr = &ctx
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "AES256-GCM 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
|
||||
name = "AES256-GCM 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
iters :: 10000
|
||||
|
||||
priv_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
|
||||
priv_bytes, _ := hex.decode(transmute([]byte)(priv_str), context.temp_allocator)
|
||||
priv_key: ed25519.Private_Key
|
||||
start := time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.private_key_set_bytes(&priv_key, priv_bytes)
|
||||
assert(ok, "private key should deserialize")
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
fmt.sbprintfln(&str,
|
||||
"ed25519.private_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
pub_bytes := priv_key._pub_key._b[:] // "I know what I am doing"
|
||||
pub_key: ed25519.Public_Key
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.public_key_set_bytes(&pub_key, pub_bytes[:])
|
||||
assert(ok, "public key should deserialize")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
fmt.sbprintfln(&str,
|
||||
"ed25519.public_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
msg := "Got a job for you, 621."
|
||||
sig_bytes: [ed25519.SIGNATURE_SIZE]byte
|
||||
msg_bytes := transmute([]byte)(msg)
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ed25519.sign(&priv_key, msg_bytes, sig_bytes[:])
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
fmt.sbprintfln(&str,
|
||||
"ed25519.sign: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.verify(&pub_key, msg_bytes, sig_bytes[:])
|
||||
assert(ok, "signature should validate")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
fmt.sbprintfln(&str,
|
||||
"ed25519.verify: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
}
|
||||
{
|
||||
point_str := "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
scalar_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
|
||||
|
||||
point, _ := hex.decode(transmute([]byte)(point_str), context.temp_allocator)
|
||||
scalar, _ := hex.decode(transmute([]byte)(scalar_str), context.temp_allocator)
|
||||
out: [x25519.POINT_SIZE]byte = ---
|
||||
|
||||
iters :: 10000
|
||||
start := time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
x25519.scalarmult(out[:], scalar[:], point[:])
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
|
||||
fmt.sbprintfln(&str,
|
||||
"x25519.scalarmult: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(private)
|
||||
_setup_sized_buf :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
assert(options != nil)
|
||||
|
||||
options.input = make([]u8, options.bytes, allocator)
|
||||
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||
}
|
||||
|
||||
@(private)
|
||||
_teardown_sized_buf :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
assert(options != nil)
|
||||
|
||||
delete(options.input)
|
||||
return nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_benchmark_chacha20 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [chacha20.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
nonce := [chacha20.NONCE_SIZE]byte {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
ctx: chacha20.Context = ---
|
||||
chacha20.init(&ctx, key[:], nonce[:])
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
chacha20.xor_bytes(&ctx, buf, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_benchmark_poly1305 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [poly1305.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
|
||||
tag: [poly1305.TAG_SIZE]byte = ---
|
||||
for _ in 0 ..= options.rounds {
|
||||
poly1305.sum(tag[:], buf, key[:])
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
//options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
_benchmark_chacha20poly1305 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [chacha20.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
nonce := [chacha20.NONCE_SIZE]byte {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
tag: [chacha20poly1305.TAG_SIZE]byte = ---
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
chacha20poly1305.encrypt(buf, tag[:], key[:], nonce[:], nil, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_aes256_gcm :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
nonce: [aes.GCM_NONCE_SIZE]byte
|
||||
tag: [aes.GCM_TAG_SIZE]byte = ---
|
||||
|
||||
ctx := transmute(^aes.Context_GCM)context.user_ptr
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
aes.seal_gcm(ctx, buf, tag[:], nonce[:], nil, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
@(private)
|
||||
benchmark_print :: proc(str: ^strings.Builder, name: string, options: ^time.Benchmark_Options, loc := #caller_location) {
|
||||
fmt.sbprintfln(str, "[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
time.duration_nanoseconds(options.duration),
|
||||
options.rounds_per_second,
|
||||
options.megabytes_per_second,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package benchmark_core_hash
|
||||
|
||||
import "core:fmt"
|
||||
import "core:hash/xxhash"
|
||||
import "base:intrinsics"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
|
||||
@(test)
|
||||
benchmark_hash :: proc(t: ^testing.T) {
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str, context.allocator)
|
||||
defer {
|
||||
fmt.println(strings.to_string(str))
|
||||
strings.builder_destroy(&str)
|
||||
}
|
||||
|
||||
{
|
||||
name := "XXH32 100 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 100,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh32,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x85f6413c)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH32 1 MiB zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 1_048_576,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh32,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x9430f97f)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH64 100 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 100,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh64,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x17bb1103c92c502f)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH64 1 MiB zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 1_048_576,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh64,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x87d2a1b6e1163ef1)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH3_64 100 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 100,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh3_64,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x801fedc74ccd608c)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH3_64 1 MiB zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 1_048_576,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh3_64,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x918780b90550bf34)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH3_128 100 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 100,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh3_128,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0x6ba30a4e9dffe1ff801fedc74ccd608c)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
{
|
||||
name := "XXH3_128 1 MiB zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 1_048_576,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh3_128,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
err := time.benchmark(options, context.allocator)
|
||||
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
|
||||
hash := u128(0xb6ef17a3448492b6918780b90550bf34)
|
||||
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
|
||||
benchmark_print(&str, name, options)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
|
||||
setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
options.input = make([]u8, options.bytes, allocator)
|
||||
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||
}
|
||||
|
||||
teardown_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
delete(options.input)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u32
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH32(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u64
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH64(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh3_64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u64
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH3_64(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u128
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH3_128(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = h
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_print :: proc(str: ^strings.Builder, name: string, options: ^time.Benchmark_Options, loc := #caller_location) {
|
||||
fmt.sbprintfln(str, "[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
time.duration_nanoseconds(options.duration),
|
||||
options.rounds_per_second,
|
||||
options.megabytes_per_second,
|
||||
)
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
// Boilerplate for tests
|
||||
package common
|
||||
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
errorf :: testing.errorf
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v:%s] FAIL %v\n", loc, loc.procedure, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
errorf :: proc(t: ^testing.T, message: string, args: ..any, loc := #caller_location) {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v:%s] Error %v\n", loc, loc.procedure, fmt.tprintf(message, ..args))
|
||||
return
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
report :: proc(t: ^testing.T) {
|
||||
if TEST_fail > 0 {
|
||||
if TEST_fail > 1 {
|
||||
fmt.printf("%v/%v tests successful, %v tests failed.\n", TEST_count - TEST_fail, TEST_count, TEST_fail)
|
||||
} else {
|
||||
fmt.printf("%v/%v tests successful, 1 test failed.\n", TEST_count - TEST_fail, TEST_count)
|
||||
}
|
||||
os.exit(1)
|
||||
} else {
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count, TEST_count)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns absolute path to `sub_path` where `sub_path` is within the "tests/" sub-directory of the Odin project root
|
||||
// and we're being run from the Odin project root or from a sub-directory of "tests/"
|
||||
// e.g. get_data_path("assets/blah") will return "/Odin_root/tests/assets/blah" if run within "/Odin_root",
|
||||
// "/Odin_root/tests" or "/Odin_root/tests/subdir" etc
|
||||
get_data_path :: proc(t: ^testing.T, sub_path: string) -> (data_path: string) {
|
||||
|
||||
cwd := os.get_current_directory()
|
||||
defer delete(cwd)
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
norm, was_allocation := strings.replace_all(cwd, "\\", "/")
|
||||
if !was_allocation {
|
||||
norm = strings.clone(norm)
|
||||
}
|
||||
defer delete(norm)
|
||||
} else {
|
||||
norm := cwd
|
||||
}
|
||||
|
||||
last_index := strings.last_index(norm, "/tests/")
|
||||
if last_index == -1 {
|
||||
len := len(norm)
|
||||
if len >= 6 && norm[len-6:] == "/tests" {
|
||||
data_path = fmt.tprintf("%s/%s", norm, sub_path)
|
||||
} else {
|
||||
data_path = fmt.tprintf("%s/tests/%s", norm, sub_path)
|
||||
}
|
||||
} else {
|
||||
data_path = fmt.tprintf("%s/tests/%s", norm[:last_index], sub_path)
|
||||
}
|
||||
|
||||
return data_path
|
||||
}
|
||||
+62
-57
@@ -1,16 +1,15 @@
|
||||
ODIN=../../odin
|
||||
PYTHON=$(shell which python3)
|
||||
COMMON=-vet -strict-style
|
||||
COLLECTION=-collection:tests=..
|
||||
COMMON=-no-bounds-check -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
|
||||
all: all_bsd \
|
||||
net_test
|
||||
|
||||
all_bsd: c_libc_test \
|
||||
all_bsd: download_test_assets \
|
||||
c_libc_test \
|
||||
compress_test \
|
||||
container_test \
|
||||
crypto_test \
|
||||
download_test_assets \
|
||||
encoding_test \
|
||||
filepath_test \
|
||||
fmt_test \
|
||||
@@ -21,86 +20,92 @@ all_bsd: c_libc_test \
|
||||
match_test \
|
||||
math_test \
|
||||
noise_test \
|
||||
odin_test \
|
||||
os_exit_test \
|
||||
reflect_test \
|
||||
runtime_test \
|
||||
slice_test \
|
||||
strings_test \
|
||||
thread_test \
|
||||
runtime_test \
|
||||
time_test \
|
||||
fmt_test
|
||||
time_test
|
||||
|
||||
download_test_assets:
|
||||
$(PYTHON) download_assets.py
|
||||
|
||||
image_test:
|
||||
$(ODIN) run image $(COMMON) -out:test_core_image
|
||||
c_libc_test:
|
||||
$(ODIN) test c/libc $(COMMON) -out:test_core_libc
|
||||
|
||||
compress_test:
|
||||
$(ODIN) run compress $(COMMON) -out:test_core_compress
|
||||
$(ODIN) test compress $(COMMON) -out:test_core_compress
|
||||
|
||||
container_test:
|
||||
$(ODIN) run container $(COMMON) $(COLLECTION) -out:test_core_container
|
||||
|
||||
strings_test:
|
||||
$(ODIN) run strings $(COMMON) -out:test_core_strings
|
||||
|
||||
hash_test:
|
||||
$(ODIN) run hash $(COMMON) -o:speed -no-bounds-check -out:test_hash
|
||||
$(ODIN) test container $(COMMON) -out:test_core_container
|
||||
|
||||
crypto_test:
|
||||
$(ODIN) run crypto $(COMMON) $(COLLECTION) -o:speed -no-bounds-check -out:test_crypto
|
||||
|
||||
noise_test:
|
||||
$(ODIN) run math/noise $(COMMON) -out:test_noise
|
||||
$(ODIN) test crypto $(COMMON) -o:speed -out:test_crypto
|
||||
|
||||
encoding_test:
|
||||
$(ODIN) run encoding/hxa $(COMMON) $(COLLECTION) -out:test_hxa
|
||||
$(ODIN) run encoding/json $(COMMON) -out:test_json
|
||||
$(ODIN) run encoding/varint $(COMMON) -out:test_varint
|
||||
$(ODIN) run encoding/xml $(COMMON) -out:test_xml
|
||||
$(ODIN) run encoding/cbor $(COMMON) -out:test_cbor
|
||||
$(ODIN) run encoding/hex $(COMMON) -out:test_hex
|
||||
$(ODIN) run encoding/base64 $(COMMON) -out:test_base64
|
||||
|
||||
math_test:
|
||||
$(ODIN) run math $(COMMON) $(COLLECTION) -out:test_core_math
|
||||
|
||||
linalg_glsl_math_test:
|
||||
$(ODIN) run math/linalg/glsl $(COMMON) $(COLLECTION) -out:test_linalg_glsl_math
|
||||
$(ODIN) test encoding/base64 $(COMMON) -out:test_base64
|
||||
$(ODIN) test encoding/cbor $(COMMON) -out:test_cbor
|
||||
$(ODIN) test encoding/hex $(COMMON) -out:test_hex
|
||||
$(ODIN) test encoding/hxa $(COMMON) -out:test_hxa
|
||||
$(ODIN) test encoding/json $(COMMON) -out:test_json
|
||||
$(ODIN) test encoding/varint $(COMMON) -out:test_varint
|
||||
$(ODIN) test encoding/xml $(COMMON) -out:test_xml
|
||||
|
||||
filepath_test:
|
||||
$(ODIN) run path/filepath $(COMMON) $(COLLECTION) -out:test_core_filepath
|
||||
$(ODIN) test path/filepath $(COMMON) -out:test_core_filepath
|
||||
|
||||
reflect_test:
|
||||
$(ODIN) run reflect $(COMMON) $(COLLECTION) -out:test_core_reflect
|
||||
fmt_test:
|
||||
$(ODIN) test fmt $(COMMON) -out:test_core_fmt
|
||||
|
||||
slice_test:
|
||||
$(ODIN) run slice $(COMMON) -out:test_core_slice
|
||||
hash_test:
|
||||
$(ODIN) test hash $(COMMON) -o:speed -out:test_hash
|
||||
|
||||
image_test:
|
||||
$(ODIN) test image $(COMMON) -out:test_core_image
|
||||
|
||||
i18n_test:
|
||||
$(ODIN) test text/i18n $(COMMON) -out:test_core_i18n
|
||||
|
||||
match_test:
|
||||
$(ODIN) test text/match $(COMMON) -out:test_core_match
|
||||
|
||||
math_test:
|
||||
$(ODIN) test math $(COMMON) -out:test_core_math
|
||||
|
||||
linalg_glsl_math_test:
|
||||
$(ODIN) test math/linalg/glsl $(COMMON) -out:test_linalg_glsl_math
|
||||
|
||||
noise_test:
|
||||
$(ODIN) test math/noise $(COMMON) -out:test_noise
|
||||
|
||||
net_test:
|
||||
$(ODIN) test net $(COMMON) -out:test_core_net
|
||||
|
||||
os_exit_test:
|
||||
$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0
|
||||
|
||||
i18n_test:
|
||||
$(ODIN) run text/i18n $(COMMON) -out:test_core_i18n
|
||||
odin_test:
|
||||
$(ODIN) test odin $(COMMON) -out:test_core_odin
|
||||
|
||||
match_test:
|
||||
$(ODIN) run text/match $(COMMON) -out:test_core_match
|
||||
|
||||
c_libc_test:
|
||||
$(ODIN) run c/libc $(COMMON) -out:test_core_libc
|
||||
|
||||
net_test:
|
||||
$(ODIN) run net $(COMMON) -out:test_core_net
|
||||
|
||||
fmt_test:
|
||||
$(ODIN) run fmt $(COMMON) -out:test_core_fmt
|
||||
|
||||
thread_test:
|
||||
$(ODIN) run thread $(COMMON) -out:test_core_thread
|
||||
reflect_test:
|
||||
$(ODIN) test reflect $(COMMON) -out:test_core_reflect
|
||||
|
||||
runtime_test:
|
||||
$(ODIN) run runtime $(COMMON) -out:test_core_runtime
|
||||
$(ODIN) test runtime $(COMMON) -out:test_core_runtime
|
||||
|
||||
slice_test:
|
||||
$(ODIN) test slice $(COMMON) -out:test_core_slice
|
||||
|
||||
strings_test:
|
||||
$(ODIN) test strings $(COMMON) -out:test_core_strings
|
||||
|
||||
thread_test:
|
||||
$(ODIN) test thread $(COMMON) -out:test_core_thread
|
||||
|
||||
time_test:
|
||||
$(ODIN) run time $(COMMON) -out:test_core_time
|
||||
$(ODIN) test time $(COMMON) -out:test_core_time
|
||||
|
||||
clean:
|
||||
rm test_*
|
||||
+76
-67
@@ -1,110 +1,119 @@
|
||||
@echo off
|
||||
set COMMON=-no-bounds-check -vet -strict-style
|
||||
set COLLECTION=-collection:tests=..
|
||||
set COMMON=-no-bounds-check -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
set PATH_TO_ODIN==..\..\odin
|
||||
python3 download_assets.py
|
||||
echo ---
|
||||
echo Running core:c/libc tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test c\libc %COMMON% -out:test_libc.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:compress tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run compress %COMMON% -out:test_core_compress.exe || exit /b
|
||||
%PATH_TO_ODIN% test compress %COMMON% -out:test_core_compress.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:container tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run container %COMMON% %COLLECTION% -out:test_core_container.exe || exit /b
|
||||
%PATH_TO_ODIN% test container %COMMON% -out:test_core_container.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:crypto tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run crypto %COMMON% %COLLECTION% -out:test_crypto.exe || exit /b
|
||||
%PATH_TO_ODIN% test crypto %COMMON% -o:speed -out:test_crypto.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:encoding tests
|
||||
echo ---
|
||||
rem %PATH_TO_ODIN% run encoding/hxa %COMMON% %COLLECTION% -out:test_hxa.exe || exit /b
|
||||
%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe || exit /b
|
||||
%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe || exit /b
|
||||
%PATH_TO_ODIN% run encoding/xml %COMMON% -out:test_xml.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/cbor %COMMON% -out:test_cbor.exe || exit /b
|
||||
%PATH_TO_ODIN% run encoding/hex %COMMON% -out:test_hex.exe || exit /b
|
||||
%PATH_TO_ODIN% run encoding/base64 %COMMON% -out:test_base64.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:fmt tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run fmt %COMMON% %COLLECTION% -out:test_core_fmt.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:hash tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:image tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run image %COMMON% -out:test_core_image.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math %COMMON% %COLLECTION% -out:test_core_math.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math/linalg/glsl tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math/linalg/glsl %COMMON% %COLLECTION% -out:test_linalg_glsl.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math/noise tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:net
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run net %COMMON% -out:test_core_net.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:odin tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_core_odin.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/base64 %COMMON% -out:test_base64.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/cbor %COMMON% -out:test_cbor.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/hex %COMMON% -out:test_hex.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/hxa %COMMON% -out:test_hxa.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/json %COMMON% -out:test_json.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/varint %COMMON% -out:test_varint.exe || exit /b
|
||||
%PATH_TO_ODIN% test encoding/xml %COMMON% -out:test_xml.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:path/filepath tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run path/filepath %COMMON% %COLLECTION% -out:test_core_filepath.exe || exit /b
|
||||
%PATH_TO_ODIN% test path/filepath %COMMON% -out:test_core_filepath.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:reflect tests
|
||||
echo Running core:fmt tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe || exit /b
|
||||
%PATH_TO_ODIN% test fmt %COMMON% -out:test_core_fmt.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:runtime tests
|
||||
echo Running core:hash tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run runtime %COMMON% %COLLECTION% -out:test_core_runtime.exe || exit /b
|
||||
%PATH_TO_ODIN% test hash %COMMON% -o:speed -out:test_core_hash.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:slice tests
|
||||
echo Running core:image tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run slice %COMMON% -out:test_core_slice.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:strings tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run strings %COMMON% -out:test_core_strings.exe || exit /b
|
||||
%PATH_TO_ODIN% test image %COMMON% -out:test_core_image.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:text/i18n tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run text\i18n %COMMON% -out:test_core_i18n.exe || exit /b
|
||||
%PATH_TO_ODIN% test text\i18n %COMMON% -out:test_core_i18n.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running text:match tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test text/match %COMMON% -out:test_core_match.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test math %COMMON% -out:test_core_math.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math/linalg/glsl tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test math/linalg/glsl %COMMON% -out:test_linalg_glsl.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:math/noise tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test math/noise %COMMON% -out:test_noise.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:net
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test net %COMMON% -out:test_core_net.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:odin tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test odin %COMMON% -o:size -out:test_core_odin.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:reflect tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test reflect %COMMON% -out:test_core_reflect.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:runtime tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test runtime %COMMON% -out:test_core_runtime.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:slice tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test slice %COMMON% -out:test_core_slice.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:strings tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% test strings %COMMON% -out:test_core_strings.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:thread tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run thread %COMMON% %COLLECTION% -out:test_core_thread.exe || exit /b
|
||||
%PATH_TO_ODIN% test thread %COMMON% -out:test_core_thread.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:time tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run time %COMMON% %COLLECTION% -out:test_core_time.exe || exit /b
|
||||
%PATH_TO_ODIN% test time %COMMON% -out:test_core_time.exe || exit /b
|
||||
@@ -1,36 +0,0 @@
|
||||
package test_core_libc
|
||||
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_libc_complex(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package test_core_libc
|
||||
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:c/libc"
|
||||
import "core:log"
|
||||
|
||||
reldiff :: proc(lhs, rhs: $T) -> f64 {
|
||||
if lhs == rhs {
|
||||
@@ -14,7 +14,7 @@ reldiff :: proc(lhs, rhs: $T) -> f64 {
|
||||
return out
|
||||
}
|
||||
|
||||
isclose :: proc(lhs, rhs: $T, rtol:f64 = 1e-12, atol:f64 = 1e-12) -> bool {
|
||||
isclose :: proc(t: ^testing.T, lhs, rhs: $T, rtol:f64 = 1e-12, atol:f64 = 1e-12) -> bool {
|
||||
adiff := f64(abs(lhs - rhs))
|
||||
if adiff < atol {
|
||||
return true
|
||||
@@ -23,7 +23,7 @@ isclose :: proc(lhs, rhs: $T, rtol:f64 = 1e-12, atol:f64 = 1e-12) -> bool {
|
||||
if rdiff < rtol {
|
||||
return true
|
||||
}
|
||||
fmt.printf("not close -- lhs:%v rhs:%v -- adiff:%e rdiff:%e\n",lhs, rhs, adiff, rdiff)
|
||||
log.infof("not close -- lhs:%v rhs:%v -- adiff:%e rdiff:%e\n",lhs, rhs, adiff, rdiff)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ test_libc_complex :: proc(t: ^testing.T) {
|
||||
test_libc_pow_binding(t, libc.complex_float, f32, libc_powf, 1e-12, 1e-5)
|
||||
}
|
||||
|
||||
@test
|
||||
test_libc_pow_binding :: proc(t: ^testing.T, $LIBC_COMPLEX:typeid, $F:typeid, pow: proc(LIBC_COMPLEX, LIBC_COMPLEX) -> LIBC_COMPLEX,
|
||||
rtol: f64, atol: f64) {
|
||||
// Tests that c/libc/pow(f) functions have two arguments and that the function works as expected for simple inputs
|
||||
@@ -56,8 +55,8 @@ test_libc_pow_binding :: proc(t: ^testing.T, $LIBC_COMPLEX:typeid, $F:typeid, po
|
||||
for n in -4..=4 {
|
||||
complex_power := LIBC_COMPLEX(complex(F(n), F(0.)))
|
||||
result := pow(complex_base, complex_power)
|
||||
expect(t, isclose(expected_real, F(real(result)), rtol, atol), fmt.tprintf("ftype:%T, n:%v reldiff(%v, re(%v)) is greater than specified rtol:%e", F{}, n, expected_real, result, rtol))
|
||||
expect(t, isclose(expected_imag, F(imag(result)), rtol, atol), fmt.tprintf("ftype:%T, n:%v reldiff(%v, im(%v)) is greater than specified rtol:%e", F{}, n, expected_imag, result, rtol))
|
||||
testing.expectf(t, isclose(t, expected_real, F(real(result)), rtol, atol), "ftype:%T, n:%v reldiff(%v, re(%v)) is greater than specified rtol:%e", F{}, n, expected_real, result, rtol)
|
||||
testing.expectf(t, isclose(t, expected_imag, F(imag(result)), rtol, atol), "ftype:%T, n:%v reldiff(%v, im(%v)) is greater than specified rtol:%e", F{}, n, expected_imag, result, rtol)
|
||||
expected_real *= 2
|
||||
}
|
||||
}
|
||||
@@ -83,8 +82,8 @@ test_libc_pow_binding :: proc(t: ^testing.T, $LIBC_COMPLEX:typeid, $F:typeid, po
|
||||
expected_real = 0.
|
||||
expected_imag = -value
|
||||
}
|
||||
expect(t, isclose(expected_real, F(real(result)), rtol, atol), fmt.tprintf("ftype:%T, n:%v reldiff(%v, re(%v)) is greater than specified rtol:%e", F{}, n, expected_real, result, rtol))
|
||||
expect(t, isclose(expected_imag, F(imag(result)), rtol, atol), fmt.tprintf("ftype:%T, n:%v reldiff(%v, im(%v)) is greater than specified rtol:%e", F{}, n, expected_imag, result, rtol))
|
||||
testing.expectf(t, isclose(t, expected_real, F(real(result)), rtol, atol), "ftype:%T, n:%v reldiff(%v, re(%v)) is greater than specified rtol:%e", F{}, n, expected_real, result, rtol)
|
||||
testing.expectf(t, isclose(t, expected_imag, F(imag(result)), rtol, atol), "ftype:%T, n:%v reldiff(%v, im(%v)) is greater than specified rtol:%e", F{}, n, expected_imag, result, rtol)
|
||||
value *= 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,47 +15,7 @@ import "core:testing"
|
||||
import "core:compress/zlib"
|
||||
import "core:compress/gzip"
|
||||
import "core:compress/shoco"
|
||||
|
||||
import "core:bytes"
|
||||
import "core:fmt"
|
||||
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:io"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
w := io.to_writer(os.stream_from_handle(os.stdout))
|
||||
t := testing.T{w=w}
|
||||
zlib_test(&t)
|
||||
gzip_test(&t)
|
||||
shoco_test(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
zlib_test :: proc(t: ^testing.T) {
|
||||
@@ -80,26 +40,14 @@ zlib_test :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
buf: bytes.Buffer
|
||||
err := zlib.inflate(ODIN_DEMO, &buf)
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
err := zlib.inflate(ODIN_DEMO, &buf)
|
||||
|
||||
expect(t, err == nil, "ZLIB failed to decompress ODIN_DEMO")
|
||||
testing.expect(t, err == nil, "ZLIB failed to decompress ODIN_DEMO")
|
||||
s := bytes.buffer_to_string(&buf)
|
||||
|
||||
expect(t, s[68] == 240 && s[69] == 159 && s[70] == 152, "ZLIB result should've contained 😃 at position 68.")
|
||||
|
||||
expect(t, len(s) == 438, "ZLIB result has an unexpected length.")
|
||||
|
||||
testing.expect(t, s[68] == 240 && s[69] == 159 && s[70] == 152, "ZLIB result should've contained 😃 at position 68.")
|
||||
testing.expect(t, len(s) == 438, "ZLIB result has an unexpected length.")
|
||||
bytes.buffer_destroy(&buf)
|
||||
|
||||
for _, v in track.allocation_map {
|
||||
error := fmt.tprintf("ZLIB test leaked %v bytes", v.size)
|
||||
expect(t, false, error)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -117,24 +65,12 @@ gzip_test :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
buf: bytes.Buffer
|
||||
err := gzip.load(TEST, &buf)
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
err := gzip.load(TEST, &buf) // , 438);
|
||||
|
||||
expect(t, err == nil, "GZIP failed to decompress TEST")
|
||||
s := bytes.buffer_to_string(&buf)
|
||||
|
||||
expect(t, s == "payload", "GZIP result wasn't 'payload'")
|
||||
testing.expect(t, err == nil, "GZIP failed to decompress TEST")
|
||||
testing.expect(t, bytes.buffer_to_string(&buf) == "payload", "GZIP result wasn't 'payload'")
|
||||
|
||||
bytes.buffer_destroy(&buf)
|
||||
|
||||
for _, v in track.allocation_map {
|
||||
error := fmt.tprintf("GZIP test leaked %v bytes", v.size)
|
||||
expect(t, false, error)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -168,31 +104,26 @@ shoco_test :: proc(t: ^testing.T) {
|
||||
defer delete(buffer)
|
||||
|
||||
size, err := shoco.decompress(v.compressed, buffer[:])
|
||||
msg := fmt.tprintf("Expected `decompress` to return `nil`, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
testing.expectf(t, err == nil, "Expected `decompress` to return `nil`, got %v", err)
|
||||
|
||||
msg = fmt.tprintf("Decompressed %v bytes into %v. Expected to decompress into %v bytes.", len(v.compressed), size, expected_raw)
|
||||
expect(t, size == expected_raw, msg)
|
||||
expect(t, string(buffer[:size]) == string(v.raw), "Decompressed contents don't match.")
|
||||
testing.expectf(t, size == expected_raw, "Decompressed %v bytes into %v. Expected to decompress into %v bytes", len(v.compressed), size, expected_raw)
|
||||
testing.expect(t, string(buffer[:size]) == string(v.raw), "Decompressed contents don't match")
|
||||
|
||||
size, err = shoco.compress(string(v.raw), buffer[:])
|
||||
expect(t, err == nil, "Expected `compress` to return `nil`.")
|
||||
testing.expect(t, err == nil, "Expected `compress` to return `nil`.")
|
||||
|
||||
msg = fmt.tprintf("Compressed %v bytes into %v. Expected to compress into %v bytes.", expected_raw, size, expected_compressed)
|
||||
expect(t, size == expected_compressed, msg)
|
||||
testing.expectf(t, size == expected_compressed, "Compressed %v bytes into %v. Expected to compress into %v bytes", expected_raw, size, expected_compressed)
|
||||
|
||||
size, err = shoco.decompress(v.compressed, buffer[:expected_raw - 10])
|
||||
msg = fmt.tprintf("Decompressing into too small a buffer returned %v, expected `.Output_Too_Short`", err)
|
||||
expect(t, err == .Output_Too_Short, msg)
|
||||
testing.expectf(t, err == .Output_Too_Short, "Decompressing into too small a buffer returned %v, expected `.Output_Too_Short`", err)
|
||||
|
||||
size, err = shoco.compress(string(v.raw), buffer[:expected_compressed - 10])
|
||||
msg = fmt.tprintf("Compressing into too small a buffer returned %v, expected `.Output_Too_Short`", err)
|
||||
expect(t, err == .Output_Too_Short, msg)
|
||||
testing.expectf(t, err == .Output_Too_Short, "Compressing into too small a buffer returned %v, expected `.Output_Too_Short`", err)
|
||||
|
||||
size, err = shoco.decompress(v.compressed[:v.short_pack], buffer[:])
|
||||
expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after selecting a pack.")
|
||||
testing.expectf(t, err == .Stream_Too_Short, "Insufficient data after pack returned %v, expected `.Stream_Too_Short`", err)
|
||||
|
||||
size, err = shoco.decompress(v.compressed[:v.short_sentinel], buffer[:])
|
||||
expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after non-ASCII sentinel.")
|
||||
testing.expectf(t, err == .Stream_Too_Short, "No more data after non-ASCII sentinel returned %v, expected `.Stream_Too_Short`", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,53 +4,54 @@ import "core:container/avl"
|
||||
import "core:math/rand"
|
||||
import "core:slice"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import tc "tests:common"
|
||||
import "core:log"
|
||||
|
||||
@(test)
|
||||
test_avl :: proc(t: ^testing.T) {
|
||||
tc.log(t, fmt.tprintf("Testing avl, using random seed %v, add -define:RANDOM_SEED=%v to reuse it.", random_seed, random_seed))
|
||||
log.infof("Testing avl using random seed %v.", t.seed)
|
||||
|
||||
// Initialization.
|
||||
tree: avl.Tree(int)
|
||||
avl.init(&tree, slice.cmp_proc(int))
|
||||
tc.expect(t, avl.len(&tree) == 0, "empty: len should be 0")
|
||||
tc.expect(t, avl.first(&tree) == nil, "empty: first should be nil")
|
||||
tc.expect(t, avl.last(&tree) == nil, "empty: last should be nil")
|
||||
testing.expect(t, avl.len(&tree) == 0, "empty: len should be 0")
|
||||
testing.expect(t, avl.first(&tree) == nil, "empty: first should be nil")
|
||||
testing.expect(t, avl.last(&tree) == nil, "empty: last should be nil")
|
||||
|
||||
iter := avl.iterator(&tree, avl.Direction.Forward)
|
||||
tc.expect(t, avl.iterator_get(&iter) == nil, "empty/iterator: first node should be nil")
|
||||
testing.expect(t, avl.iterator_get(&iter) == nil, "empty/iterator: first node should be nil")
|
||||
|
||||
r: rand.Rand
|
||||
rand.init(&r, random_seed)
|
||||
rand.init(&r, t.seed)
|
||||
|
||||
// Test insertion.
|
||||
NR_INSERTS :: 32 + 1 // Ensure at least 1 collision.
|
||||
inserted_map := make(map[int]^avl.Node(int))
|
||||
defer delete(inserted_map)
|
||||
for i := 0; i < NR_INSERTS; i += 1 {
|
||||
v := int(rand.uint32(&r) & 0x1f)
|
||||
existing_node, in_map := inserted_map[v]
|
||||
|
||||
n, ok, _ := avl.find_or_insert(&tree, v)
|
||||
tc.expect(t, in_map != ok, "insert: ok should match inverse of map lookup")
|
||||
testing.expect(t, in_map != ok, "insert: ok should match inverse of map lookup")
|
||||
if ok {
|
||||
inserted_map[v] = n
|
||||
} else {
|
||||
tc.expect(t, existing_node == n, "insert: expecting existing node")
|
||||
testing.expect(t, existing_node == n, "insert: expecting existing node")
|
||||
}
|
||||
}
|
||||
nrEntries := len(inserted_map)
|
||||
tc.expect(t, avl.len(&tree) == nrEntries, "insert: len after")
|
||||
testing.expect(t, avl.len(&tree) == nrEntries, "insert: len after")
|
||||
validate_avl(t, &tree)
|
||||
|
||||
// Ensure that all entries can be found.
|
||||
for k, v in inserted_map {
|
||||
tc.expect(t, v == avl.find(&tree, k), "Find(): Node")
|
||||
tc.expect(t, k == v.value, "Find(): Node value")
|
||||
testing.expect(t, v == avl.find(&tree, k), "Find(): Node")
|
||||
testing.expect(t, k == v.value, "Find(): Node value")
|
||||
}
|
||||
|
||||
// Test the forward/backward iterators.
|
||||
inserted_values: [dynamic]int
|
||||
defer delete(inserted_values)
|
||||
for k in inserted_map {
|
||||
append(&inserted_values, k)
|
||||
}
|
||||
@@ -60,38 +61,38 @@ test_avl :: proc(t: ^testing.T) {
|
||||
visited: int
|
||||
for node in avl.iterator_next(&iter) {
|
||||
v, idx := node.value, visited
|
||||
tc.expect(t, inserted_values[idx] == v, "iterator/forward: value")
|
||||
tc.expect(t, node == avl.iterator_get(&iter), "iterator/forward: get")
|
||||
testing.expect(t, inserted_values[idx] == v, "iterator/forward: value")
|
||||
testing.expect(t, node == avl.iterator_get(&iter), "iterator/forward: get")
|
||||
visited += 1
|
||||
}
|
||||
tc.expect(t, visited == nrEntries, "iterator/forward: visited")
|
||||
testing.expect(t, visited == nrEntries, "iterator/forward: visited")
|
||||
|
||||
slice.reverse(inserted_values[:])
|
||||
iter = avl.iterator(&tree, avl.Direction.Backward)
|
||||
visited = 0
|
||||
for node in avl.iterator_next(&iter) {
|
||||
v, idx := node.value, visited
|
||||
tc.expect(t, inserted_values[idx] == v, "iterator/backward: value")
|
||||
testing.expect(t, inserted_values[idx] == v, "iterator/backward: value")
|
||||
visited += 1
|
||||
}
|
||||
tc.expect(t, visited == nrEntries, "iterator/backward: visited")
|
||||
testing.expect(t, visited == nrEntries, "iterator/backward: visited")
|
||||
|
||||
// Test removal.
|
||||
rand.shuffle(inserted_values[:], &r)
|
||||
for v, i in inserted_values {
|
||||
node := avl.find(&tree, v)
|
||||
tc.expect(t, node != nil, "remove: find (pre)")
|
||||
testing.expect(t, node != nil, "remove: find (pre)")
|
||||
|
||||
ok := avl.remove(&tree, v)
|
||||
tc.expect(t, ok, "remove: succeeds")
|
||||
tc.expect(t, nrEntries - (i + 1) == avl.len(&tree), "remove: len (post)")
|
||||
testing.expect(t, ok, "remove: succeeds")
|
||||
testing.expect(t, nrEntries - (i + 1) == avl.len(&tree), "remove: len (post)")
|
||||
validate_avl(t, &tree)
|
||||
|
||||
tc.expect(t, nil == avl.find(&tree, v), "remove: find (post")
|
||||
testing.expect(t, nil == avl.find(&tree, v), "remove: find (post")
|
||||
}
|
||||
tc.expect(t, avl.len(&tree) == 0, "remove: len should be 0")
|
||||
tc.expect(t, avl.first(&tree) == nil, "remove: first should be nil")
|
||||
tc.expect(t, avl.last(&tree) == nil, "remove: last should be nil")
|
||||
testing.expect(t, avl.len(&tree) == 0, "remove: len should be 0")
|
||||
testing.expect(t, avl.first(&tree) == nil, "remove: first should be nil")
|
||||
testing.expect(t, avl.last(&tree) == nil, "remove: last should be nil")
|
||||
|
||||
// Refill the tree.
|
||||
for v in inserted_values {
|
||||
@@ -104,25 +105,25 @@ test_avl :: proc(t: ^testing.T) {
|
||||
v := node.value
|
||||
|
||||
ok := avl.iterator_remove(&iter)
|
||||
tc.expect(t, ok, "iterator/remove: success")
|
||||
testing.expect(t, ok, "iterator/remove: success")
|
||||
|
||||
ok = avl.iterator_remove(&iter)
|
||||
tc.expect(t, !ok, "iterator/remove: redundant removes should fail")
|
||||
testing.expect(t, !ok, "iterator/remove: redundant removes should fail")
|
||||
|
||||
tc.expect(t, avl.find(&tree, v) == nil, "iterator/remove: node should be gone")
|
||||
tc.expect(t, avl.iterator_get(&iter) == nil, "iterator/remove: get should return nil")
|
||||
testing.expect(t, avl.find(&tree, v) == nil, "iterator/remove: node should be gone")
|
||||
testing.expect(t, avl.iterator_get(&iter) == nil, "iterator/remove: get should return nil")
|
||||
|
||||
// Ensure that iterator_next still works.
|
||||
node, ok = avl.iterator_next(&iter)
|
||||
tc.expect(t, ok == (avl.len(&tree) > 0), "iterator/remove: next should return false")
|
||||
tc.expect(t, node == avl.first(&tree), "iterator/remove: next should return first")
|
||||
testing.expect(t, ok == (avl.len(&tree) > 0), "iterator/remove: next should return false")
|
||||
testing.expect(t, node == avl.first(&tree), "iterator/remove: next should return first")
|
||||
|
||||
validate_avl(t, &tree)
|
||||
}
|
||||
tc.expect(t, avl.len(&tree) == nrEntries - 1, "iterator/remove: len should drop by 1")
|
||||
testing.expect(t, avl.len(&tree) == nrEntries - 1, "iterator/remove: len should drop by 1")
|
||||
|
||||
avl.destroy(&tree)
|
||||
tc.expect(t, avl.len(&tree) == 0, "destroy: len should be 0")
|
||||
testing.expect(t, avl.len(&tree) == 0, "destroy: len should be 0")
|
||||
}
|
||||
|
||||
@(private)
|
||||
@@ -141,10 +142,10 @@ tree_check_invariants :: proc(
|
||||
}
|
||||
|
||||
// Validate the parent pointer.
|
||||
tc.expect(t, parent == node._parent, "invalid parent pointer")
|
||||
testing.expect(t, parent == node._parent, "invalid parent pointer")
|
||||
|
||||
// Validate that the balance factor is -1, 0, 1.
|
||||
tc.expect(
|
||||
testing.expect(
|
||||
t,
|
||||
node._balance == -1 || node._balance == 0 || node._balance == 1,
|
||||
"invalid balance factor",
|
||||
@@ -155,7 +156,7 @@ tree_check_invariants :: proc(
|
||||
r_height := tree_check_invariants(t, tree, node._right, node)
|
||||
|
||||
// Validate the AVL invariant and the balance factor.
|
||||
tc.expect(t, int(node._balance) == r_height - l_height, "AVL balance factor invariant violated")
|
||||
testing.expect(t, int(node._balance) == r_height - l_height, "AVL balance factor invariant violated")
|
||||
if l_height > r_height {
|
||||
return l_height + 1
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package test_core_container
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
expect_equal :: proc(t: ^testing.T, the_slice, expected: []int, loc := #caller_location) {
|
||||
_eq :: proc(a, b: []int) -> bool {
|
||||
if len(a) != len(b) do return false
|
||||
for a, i in a {
|
||||
if b[i] != a do return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
tc.expect(t, _eq(the_slice, expected), fmt.tprintf("Expected %v, got %v\n", the_slice, expected), loc)
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_avl(&t)
|
||||
test_rbtree(&t)
|
||||
test_small_array(&t)
|
||||
tc.report(&t)
|
||||
}
|
||||
@@ -3,14 +3,10 @@ package test_core_container
|
||||
import rb "core:container/rbtree"
|
||||
import "core:math/rand"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "base:intrinsics"
|
||||
import "core:mem"
|
||||
import "core:slice"
|
||||
import tc "tests:common"
|
||||
|
||||
RANDOM_SEED :: #config(RANDOM_SEED, 0)
|
||||
random_seed := u64(intrinsics.read_cycle_counter()) when RANDOM_SEED == 0 else u64(RANDOM_SEED)
|
||||
import "core:log"
|
||||
|
||||
test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
track: mem.Tracking_Allocator
|
||||
@@ -19,17 +15,17 @@ test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
r: rand.Rand
|
||||
rand.init(&r, random_seed)
|
||||
rand.init(&r, t.seed)
|
||||
|
||||
tc.log(t, fmt.tprintf("Testing Red-Black Tree($Key=%v,$Value=%v), using random seed %v, add -define:RANDOM_SEED=%v to reuse it.", type_info_of(Key), type_info_of(Value), random_seed, random_seed))
|
||||
log.infof("Testing Red-Black Tree($Key=%v,$Value=%v) using random seed %v.", type_info_of(Key), type_info_of(Value), t.seed)
|
||||
tree: rb.Tree(Key, Value)
|
||||
rb.init(&tree)
|
||||
|
||||
tc.expect(t, rb.len(&tree) == 0, "empty: len should be 0")
|
||||
tc.expect(t, rb.first(&tree) == nil, "empty: first should be nil")
|
||||
tc.expect(t, rb.last(&tree) == nil, "empty: last should be nil")
|
||||
testing.expect(t, rb.len(&tree) == 0, "empty: len should be 0")
|
||||
testing.expect(t, rb.first(&tree) == nil, "empty: first should be nil")
|
||||
testing.expect(t, rb.last(&tree) == nil, "empty: last should be nil")
|
||||
iter := rb.iterator(&tree, .Forward)
|
||||
tc.expect(t, rb.iterator_get(&iter) == nil, "empty/iterator: first node should be nil")
|
||||
testing.expect(t, rb.iterator_get(&iter) == nil, "empty/iterator: first node should be nil")
|
||||
|
||||
// Test insertion.
|
||||
NR_INSERTS :: 32 + 1 // Ensure at least 1 collision.
|
||||
@@ -45,27 +41,27 @@ test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
|
||||
existing_node, in_map := inserted_map[k]
|
||||
n, inserted, _ := rb.find_or_insert(&tree, k, v)
|
||||
tc.expect(t, in_map != inserted, "insert: inserted should match inverse of map lookup")
|
||||
testing.expect(t, in_map != inserted, "insert: inserted should match inverse of map lookup")
|
||||
if inserted {
|
||||
inserted_map[k] = n
|
||||
} else {
|
||||
tc.expect(t, existing_node == n, "insert: expecting existing node")
|
||||
testing.expect(t, existing_node == n, "insert: expecting existing node")
|
||||
}
|
||||
}
|
||||
|
||||
entry_count := len(inserted_map)
|
||||
tc.expect(t, rb.len(&tree) == entry_count, "insert: len after")
|
||||
testing.expect(t, rb.len(&tree) == entry_count, "insert: len after")
|
||||
validate_rbtree(t, &tree)
|
||||
|
||||
first := rb.first(&tree)
|
||||
last := rb.last(&tree)
|
||||
tc.expect(t, first != nil && first.key == min_key, fmt.tprintf("insert: first should be present with key %v", min_key))
|
||||
tc.expect(t, last != nil && last.key == max_key, fmt.tprintf("insert: last should be present with key %v", max_key))
|
||||
testing.expectf(t, first != nil && first.key == min_key, "insert: first should be present with key %v", min_key)
|
||||
testing.expectf(t, last != nil && last.key == max_key, "insert: last should be present with key %v", max_key)
|
||||
|
||||
// Ensure that all entries can be found.
|
||||
for k, v in inserted_map {
|
||||
tc.expect(t, v == rb.find(&tree, k), "Find(): Node")
|
||||
tc.expect(t, k == v.key, "Find(): Node key")
|
||||
testing.expect(t, v == rb.find(&tree, k), "Find(): Node")
|
||||
testing.expect(t, k == v.key, "Find(): Node key")
|
||||
}
|
||||
|
||||
// Test the forward/backward iterators.
|
||||
@@ -79,21 +75,21 @@ test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
visited: int
|
||||
for node in rb.iterator_next(&iter) {
|
||||
k, idx := node.key, visited
|
||||
tc.expect(t, inserted_keys[idx] == k, "iterator/forward: key")
|
||||
tc.expect(t, node == rb.iterator_get(&iter), "iterator/forward: get")
|
||||
testing.expect(t, inserted_keys[idx] == k, "iterator/forward: key")
|
||||
testing.expect(t, node == rb.iterator_get(&iter), "iterator/forward: get")
|
||||
visited += 1
|
||||
}
|
||||
tc.expect(t, visited == entry_count, "iterator/forward: visited")
|
||||
testing.expect(t, visited == entry_count, "iterator/forward: visited")
|
||||
|
||||
slice.reverse(inserted_keys[:])
|
||||
iter = rb.iterator(&tree, rb.Direction.Backward)
|
||||
visited = 0
|
||||
for node in rb.iterator_next(&iter) {
|
||||
k, idx := node.key, visited
|
||||
tc.expect(t, inserted_keys[idx] == k, "iterator/backward: key")
|
||||
testing.expect(t, inserted_keys[idx] == k, "iterator/backward: key")
|
||||
visited += 1
|
||||
}
|
||||
tc.expect(t, visited == entry_count, "iterator/backward: visited")
|
||||
testing.expect(t, visited == entry_count, "iterator/backward: visited")
|
||||
|
||||
// Test removal (and on_remove callback)
|
||||
rand.shuffle(inserted_keys[:], &r)
|
||||
@@ -104,19 +100,19 @@ test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
}
|
||||
for k, i in inserted_keys {
|
||||
node := rb.find(&tree, k)
|
||||
tc.expect(t, node != nil, "remove: find (pre)")
|
||||
testing.expect(t, node != nil, "remove: find (pre)")
|
||||
|
||||
ok := rb.remove(&tree, k)
|
||||
tc.expect(t, ok, "remove: succeeds")
|
||||
tc.expect(t, entry_count - (i + 1) == rb.len(&tree), "remove: len (post)")
|
||||
testing.expect(t, ok, "remove: succeeds")
|
||||
testing.expect(t, entry_count - (i + 1) == rb.len(&tree), "remove: len (post)")
|
||||
validate_rbtree(t, &tree)
|
||||
|
||||
tc.expect(t, nil == rb.find(&tree, k), "remove: find (post")
|
||||
testing.expect(t, nil == rb.find(&tree, k), "remove: find (post")
|
||||
}
|
||||
tc.expect(t, rb.len(&tree) == 0, "remove: len should be 0")
|
||||
tc.expect(t, callback_count == 0, fmt.tprintf("remove: on_remove should've been called %v times, it was %v", entry_count, callback_count))
|
||||
tc.expect(t, rb.first(&tree) == nil, "remove: first should be nil")
|
||||
tc.expect(t, rb.last(&tree) == nil, "remove: last should be nil")
|
||||
testing.expect(t, rb.len(&tree) == 0, "remove: len should be 0")
|
||||
testing.expectf(t, callback_count == 0, "remove: on_remove should've been called %v times, it was %v", entry_count, callback_count)
|
||||
testing.expect(t, rb.first(&tree) == nil, "remove: first should be nil")
|
||||
testing.expect(t, rb.last(&tree) == nil, "remove: last should be nil")
|
||||
|
||||
// Refill the tree.
|
||||
for k in inserted_keys {
|
||||
@@ -130,32 +126,32 @@ test_rbtree_integer :: proc(t: ^testing.T, $Key: typeid, $Value: typeid) {
|
||||
k := node.key
|
||||
|
||||
ok := rb.iterator_remove(&iter)
|
||||
tc.expect(t, ok, "iterator/remove: success")
|
||||
testing.expect(t, ok, "iterator/remove: success")
|
||||
|
||||
ok = rb.iterator_remove(&iter)
|
||||
tc.expect(t, !ok, "iterator/remove: redundant removes should fail")
|
||||
testing.expect(t, !ok, "iterator/remove: redundant removes should fail")
|
||||
|
||||
tc.expect(t, rb.find(&tree, k) == nil, "iterator/remove: node should be gone")
|
||||
tc.expect(t, rb.iterator_get(&iter) == nil, "iterator/remove: get should return nil")
|
||||
testing.expect(t, rb.find(&tree, k) == nil, "iterator/remove: node should be gone")
|
||||
testing.expect(t, rb.iterator_get(&iter) == nil, "iterator/remove: get should return nil")
|
||||
|
||||
// Ensure that iterator_next still works.
|
||||
node, ok = rb.iterator_next(&iter)
|
||||
tc.expect(t, ok == (rb.len(&tree) > 0), "iterator/remove: next should return false")
|
||||
tc.expect(t, node == rb.first(&tree), "iterator/remove: next should return first")
|
||||
testing.expect(t, ok == (rb.len(&tree) > 0), "iterator/remove: next should return false")
|
||||
testing.expect(t, node == rb.first(&tree), "iterator/remove: next should return first")
|
||||
|
||||
validate_rbtree(t, &tree)
|
||||
}
|
||||
tc.expect(t, rb.len(&tree) == entry_count - 1, "iterator/remove: len should drop by 1")
|
||||
testing.expect(t, rb.len(&tree) == entry_count - 1, "iterator/remove: len should drop by 1")
|
||||
|
||||
rb.destroy(&tree)
|
||||
tc.expect(t, rb.len(&tree) == 0, "destroy: len should be 0")
|
||||
tc.expect(t, callback_count == 0, fmt.tprintf("remove: on_remove should've been called %v times, it was %v", entry_count, callback_count))
|
||||
testing.expect(t, rb.len(&tree) == 0, "destroy: len should be 0")
|
||||
testing.expectf(t, callback_count == 0, "remove: on_remove should've been called %v times, it was %v", entry_count, callback_count)
|
||||
|
||||
// print_tree_node(tree._root)
|
||||
delete(inserted_map)
|
||||
delete(inserted_keys)
|
||||
tc.expect(t, len(track.allocation_map) == 0, fmt.tprintf("Expected 0 leaks, have %v", len(track.allocation_map)))
|
||||
tc.expect(t, len(track.bad_free_array) == 0, fmt.tprintf("Expected 0 bad frees, have %v", len(track.bad_free_array)))
|
||||
testing.expectf(t, len(track.allocation_map) == 0, "Expected 0 leaks, have %v", len(track.allocation_map))
|
||||
testing.expectf(t, len(track.bad_free_array) == 0, "Expected 0 bad frees, have %v", len(track.bad_free_array))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -194,7 +190,7 @@ validate_rbtree :: proc(t: ^testing.T, tree: ^$T/rb.Tree($Key, $Value)) {
|
||||
}
|
||||
|
||||
verify_rbtree_propery_1 :: proc(t: ^testing.T, n: ^$N/rb.Node($Key, $Value)) {
|
||||
tc.expect(t, rb.node_color(n) == .Black || rb.node_color(n) == .Red, "Property #1: Each node is either red or black.")
|
||||
testing.expect(t, rb.node_color(n) == .Black || rb.node_color(n) == .Red, "Property #1: Each node is either red or black.")
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
@@ -203,14 +199,14 @@ verify_rbtree_propery_1 :: proc(t: ^testing.T, n: ^$N/rb.Node($Key, $Value)) {
|
||||
}
|
||||
|
||||
verify_rbtree_propery_2 :: proc(t: ^testing.T, root: ^$N/rb.Node($Key, $Value)) {
|
||||
tc.expect(t, rb.node_color(root) == .Black, "Property #2: Root node should be black.")
|
||||
testing.expect(t, rb.node_color(root) == .Black, "Property #2: Root node should be black.")
|
||||
}
|
||||
|
||||
verify_rbtree_propery_4 :: proc(t: ^testing.T, n: ^$N/rb.Node($Key, $Value)) {
|
||||
if rb.node_color(n) == .Red {
|
||||
// A red node's left, right and parent should be black
|
||||
all_black := rb.node_color(n._left) == .Black && rb.node_color(n._right) == .Black && rb.node_color(n._parent) == .Black
|
||||
tc.expect(t, all_black, "Property #3: Red node's children + parent must be black.")
|
||||
testing.expect(t, all_black, "Property #3: Red node's children + parent must be black.")
|
||||
}
|
||||
if n == nil {
|
||||
return
|
||||
@@ -233,7 +229,7 @@ verify_rbtree_propery_5_helper :: proc(t: ^testing.T, n: ^$N/rb.Node($Key, $Valu
|
||||
if path_black_count^ == -1 {
|
||||
path_black_count^ = black_count
|
||||
} else {
|
||||
tc.expect(t, black_count == path_black_count^, "Property #5: Paths from a node to its leaves contain same black count.")
|
||||
testing.expect(t, black_count == path_black_count^, "Property #5: Paths from a node to its leaves contain same black count.")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -241,4 +237,4 @@ verify_rbtree_propery_5_helper :: proc(t: ^testing.T, n: ^$N/rb.Node($Key, $Valu
|
||||
verify_rbtree_propery_5_helper(t, n._right, black_count, path_black_count)
|
||||
}
|
||||
// Properties 4 and 5 together guarantee that no path in the tree is more than about twice as long as any other path,
|
||||
// which guarantees that it has O(log n) height.
|
||||
// which guarantees that it has O(log n) height.
|
||||
|
||||
@@ -3,44 +3,47 @@ package test_core_container
|
||||
import "core:testing"
|
||||
import "core:container/small_array"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_small_array :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing small_array")
|
||||
|
||||
test_small_array_removes(t)
|
||||
test_small_array_inject_at(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_small_array_removes :: proc(t: ^testing.T) {
|
||||
array: small_array.Small_Array(10, int)
|
||||
small_array.append(&array, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
array: small_array.Small_Array(10, int)
|
||||
small_array.append(&array, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
small_array.ordered_remove(&array, 0)
|
||||
expect_equal(t, small_array.slice(&array), []int { 1, 2, 3, 4, 5, 6, 7, 8, 9 })
|
||||
small_array.ordered_remove(&array, 5)
|
||||
expect_equal(t, small_array.slice(&array), []int { 1, 2, 3, 4, 5, 7, 8, 9 })
|
||||
small_array.ordered_remove(&array, 6)
|
||||
expect_equal(t, small_array.slice(&array), []int { 1, 2, 3, 4, 5, 7, 9 })
|
||||
small_array.unordered_remove(&array, 0)
|
||||
expect_equal(t, small_array.slice(&array), []int { 9, 2, 3, 4, 5, 7 })
|
||||
small_array.unordered_remove(&array, 2)
|
||||
expect_equal(t, small_array.slice(&array), []int { 9, 2, 7, 4, 5 })
|
||||
small_array.unordered_remove(&array, 4)
|
||||
expect_equal(t, small_array.slice(&array), []int { 9, 2, 7, 4 })
|
||||
small_array.ordered_remove(&array, 0)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 1, 2, 3, 4, 5, 6, 7, 8, 9 }))
|
||||
small_array.ordered_remove(&array, 5)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 1, 2, 3, 4, 5, 7, 8, 9 }))
|
||||
small_array.ordered_remove(&array, 6)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 1, 2, 3, 4, 5, 7, 9 }))
|
||||
small_array.unordered_remove(&array, 0)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 9, 2, 3, 4, 5, 7 }))
|
||||
small_array.unordered_remove(&array, 2)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 9, 2, 7, 4, 5 }))
|
||||
small_array.unordered_remove(&array, 4)
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 9, 2, 7, 4 }))
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_small_array_inject_at :: proc(t: ^testing.T) {
|
||||
array: small_array.Small_Array(13, int)
|
||||
small_array.append(&array, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
array: small_array.Small_Array(13, int)
|
||||
small_array.append(&array, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||
|
||||
tc.expect(t, small_array.inject_at(&array, 0, 0), "Expected to be able to inject into small array")
|
||||
expect_equal(t, small_array.slice(&array), []int { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 })
|
||||
tc.expect(t, small_array.inject_at(&array, 0, 5), "Expected to be able to inject into small array")
|
||||
expect_equal(t, small_array.slice(&array), []int { 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 8, 9 })
|
||||
tc.expect(t, small_array.inject_at(&array, 0, small_array.len(array)), "Expected to be able to inject into small array")
|
||||
expect_equal(t, small_array.slice(&array), []int { 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 0 })
|
||||
testing.expect(t, small_array.inject_at(&array, 0, 0), "Expected to be able to inject into small array")
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }))
|
||||
testing.expect(t, small_array.inject_at(&array, 0, 5), "Expected to be able to inject into small array")
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 8, 9 }))
|
||||
testing.expect(t, small_array.inject_at(&array, 0, small_array.len(array)), "Expected to be able to inject into small array")
|
||||
testing.expect(t, slice_equal(small_array.slice(&array), []int { 0, 0, 1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 0 }))
|
||||
}
|
||||
|
||||
slice_equal :: proc(a, b: []int) -> bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for a, i in a {
|
||||
if b[i] != a {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -13,41 +13,20 @@ package test_core_crypto
|
||||
*/
|
||||
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:testing"
|
||||
import "base:runtime"
|
||||
import "core:log"
|
||||
|
||||
import "core:crypto"
|
||||
import "core:crypto/chacha20"
|
||||
import "core:crypto/chacha20poly1305"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_rand_bytes(&t)
|
||||
|
||||
test_hash(&t)
|
||||
test_mac(&t)
|
||||
test_kdf(&t) // After hash/mac tests because those should pass first.
|
||||
test_ecc25519(&t)
|
||||
|
||||
test_aes(&t)
|
||||
test_chacha20(&t)
|
||||
test_chacha20poly1305(&t)
|
||||
test_sha3_variants(&t)
|
||||
|
||||
bench_crypto(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
_PLAINTEXT_SUNSCREEN_STR := "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
|
||||
|
||||
@(test)
|
||||
test_chacha20 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing (X)ChaCha20")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases taken from RFC 8439, and draft-irtf-cfrg-xchacha-03
|
||||
plaintext := transmute([]byte)(_PLAINTEXT_SUNSCREEN_STR)
|
||||
@@ -90,14 +69,12 @@ test_chacha20 :: proc(t: ^testing.T) {
|
||||
chacha20.xor_bytes(&ctx, derived_ciphertext[:], plaintext[:])
|
||||
|
||||
derived_ciphertext_str := string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == ciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
|
||||
xkey := [chacha20.KEY_SIZE]byte {
|
||||
@@ -137,21 +114,17 @@ test_chacha20 :: proc(t: ^testing.T) {
|
||||
chacha20.xor_bytes(&ctx, derived_ciphertext[:], plaintext[:])
|
||||
|
||||
derived_ciphertext_str = string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == xciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
xciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
xciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing chacha20poly1205")
|
||||
|
||||
plaintext := transmute([]byte)(_PLAINTEXT_SUNSCREEN_STR)
|
||||
|
||||
aad := [12]byte {
|
||||
@@ -209,25 +182,21 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
)
|
||||
|
||||
derived_ciphertext_str := string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == ciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected ciphertext %s for encrypt(aad, plaintext), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected ciphertext %s for encrypt(aad, plaintext), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
|
||||
derived_tag_str := string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf(
|
||||
"Expected tag %s for encrypt(aad, plaintext), but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
),
|
||||
"Expected tag %s for encrypt(aad, plaintext), but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
)
|
||||
|
||||
derived_plaintext: [114]byte
|
||||
@@ -240,15 +209,13 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
ciphertext[:],
|
||||
)
|
||||
derived_plaintext_str := string(derived_plaintext[:])
|
||||
tc.expect(t, ok, "Expected true for decrypt(tag, aad, ciphertext)")
|
||||
tc.expect(
|
||||
testing.expect(t, ok, "Expected true for decrypt(tag, aad, ciphertext)")
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_plaintext_str == _PLAINTEXT_SUNSCREEN_STR,
|
||||
fmt.tprintf(
|
||||
"Expected plaintext %s for decrypt(tag, aad, ciphertext), but got %s instead",
|
||||
_PLAINTEXT_SUNSCREEN_STR,
|
||||
derived_plaintext_str,
|
||||
),
|
||||
"Expected plaintext %s for decrypt(tag, aad, ciphertext), but got %s instead",
|
||||
_PLAINTEXT_SUNSCREEN_STR,
|
||||
derived_plaintext_str,
|
||||
)
|
||||
|
||||
derived_ciphertext[0] ~= 0xa5
|
||||
@@ -260,7 +227,7 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
aad[:],
|
||||
derived_ciphertext[:],
|
||||
)
|
||||
tc.expect(t, !ok, "Expected false for decrypt(tag, aad, corrupted_ciphertext)")
|
||||
testing.expect(t, !ok, "Expected false for decrypt(tag, aad, corrupted_ciphertext)")
|
||||
|
||||
aad[0] ~= 0xa5
|
||||
ok = chacha20poly1305.decrypt(
|
||||
@@ -271,15 +238,13 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
aad[:],
|
||||
ciphertext[:],
|
||||
)
|
||||
tc.expect(t, !ok, "Expected false for decrypt(tag, corrupted_aad, ciphertext)")
|
||||
testing.expect(t, !ok, "Expected false for decrypt(tag, corrupted_aad, ciphertext)")
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_rand_bytes :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing rand_bytes")
|
||||
|
||||
if !crypto.HAS_RAND_BYTES {
|
||||
tc.log(t, "rand_bytes not supported - skipping")
|
||||
log.info("rand_bytes not supported - skipping")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -307,10 +272,5 @@ test_rand_bytes :: proc(t: ^testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tc.expect(
|
||||
t,
|
||||
seems_ok,
|
||||
"Expected to randomize the head and tail of the buffer within a handful of attempts",
|
||||
)
|
||||
testing.expect(t, seems_ok, "Expected to randomize the head and tail of the buffer within a handful of attempts")
|
||||
}
|
||||
|
||||
@@ -2,21 +2,20 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/aes"
|
||||
import "core:crypto/sha2"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_aes :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing AES")
|
||||
log.info("Testing AES")
|
||||
|
||||
impls := make([dynamic]aes.Implementation, 0, 2)
|
||||
defer delete(impls)
|
||||
append(&impls, aes.Implementation.Portable)
|
||||
if aes.is_hardware_accelerated() {
|
||||
append(&impls, aes.Implementation.Hardware)
|
||||
@@ -29,9 +28,8 @@ test_aes :: proc(t: ^testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-ECB/%v", impl))
|
||||
log.infof("Testing AES-ECB/%v", impl)
|
||||
|
||||
test_vectors := []struct {
|
||||
key: string,
|
||||
@@ -111,39 +109,34 @@ test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
|
||||
aes.encrypt_ecb(&ctx, dst[:], plaintext)
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext,
|
||||
fmt.tprintf(
|
||||
"AES-ECB/%v: Expected: %s for encrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-ECB/%v: Expected: %s for encrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
)
|
||||
|
||||
aes.decrypt_ecb(&ctx, dst[:], ciphertext)
|
||||
dst_str = string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.plaintext,
|
||||
fmt.tprintf(
|
||||
"AES-ECB/%v: Expected: %s for decrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.ciphertext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-ECB/%v: Expected: %s for decrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.ciphertext,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-CTR/%v", impl))
|
||||
log.infof("Testing AES-CTR/%v", impl)
|
||||
|
||||
test_vectors := []struct {
|
||||
key: string,
|
||||
@@ -185,18 +178,16 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
aes.xor_bytes_ctr(&ctx, dst, plaintext)
|
||||
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext,
|
||||
fmt.tprintf(
|
||||
"AES-CTR/%v: Expected: %s for encrypt(%s, %s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-CTR/%v: Expected: %s for encrypt(%s, %s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -224,21 +215,18 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
digest_str := string(hex.encode(digest[:], context.temp_allocator))
|
||||
|
||||
expected_digest_str := "d4445343afeb9d1237f95b10d00358aed4c1d7d57c9fe480cd0afb5e2ffd448c"
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
expected_digest_str == digest_str,
|
||||
fmt.tprintf(
|
||||
"AES-CTR/%v: Expected %s for keystream digest, but got %s instead",
|
||||
impl,
|
||||
expected_digest_str,
|
||||
digest_str,
|
||||
),
|
||||
"AES-CTR/%v: Expected %s for keystream digest, but got %s instead",
|
||||
impl,
|
||||
expected_digest_str,
|
||||
digest_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-GCM/%v", impl))
|
||||
log.infof("Testing AES-GCM/%v", impl)
|
||||
|
||||
// NIST did a reorg of their site, so the source of the test vectors
|
||||
// is only available from an archive. The commented out tests are
|
||||
@@ -422,41 +410,37 @@ test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tag_str := string(hex.encode(tag_[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext && tag_str == v.tag,
|
||||
fmt.tprintf(
|
||||
"AES-GCM/%v: Expected: (%s, %s) for seal(%s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
tag_str,
|
||||
),
|
||||
"AES-GCM/%v: Expected: (%s, %s) for seal(%s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
tag_str,
|
||||
)
|
||||
|
||||
ok := aes.open_gcm(&ctx, dst, iv, aad, ciphertext, tag)
|
||||
dst_str = string(hex.encode(dst[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok && dst_str == v.plaintext,
|
||||
fmt.tprintf(
|
||||
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
dst_str,
|
||||
ok,
|
||||
),
|
||||
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
dst_str,
|
||||
ok,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import field "core:crypto/_fiat/field_curve25519"
|
||||
@@ -10,25 +8,8 @@ import "core:crypto/ed25519"
|
||||
import "core:crypto/ristretto255"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_ecc25519 :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing curve25519 ECC")
|
||||
|
||||
test_sqrt_ratio_m1(t)
|
||||
test_ristretto255(t)
|
||||
|
||||
test_ed25519(t)
|
||||
test_x25519(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing sqrt_ratio_m1")
|
||||
|
||||
test_vectors := []struct {
|
||||
u: string,
|
||||
v: string,
|
||||
@@ -90,25 +71,21 @@ test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
|
||||
field.fe_relax_cast(&vee),
|
||||
)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
(was_square == 1) == v.was_square && field.fe_equal_bytes(&r, r_) == 1,
|
||||
fmt.tprintf(
|
||||
"Expected (%v, %s) for SQRT_RATIO_M1(%s, %s), got %s",
|
||||
v.was_square,
|
||||
v.r,
|
||||
v.u,
|
||||
v.v,
|
||||
fe_str(&r),
|
||||
),
|
||||
"Expected (%v, %s) for SQRT_RATIO_M1(%s, %s), got %s",
|
||||
v.was_square,
|
||||
v.r,
|
||||
v.u,
|
||||
v.v,
|
||||
fe_str(&r),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_ristretto255 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing ristretto255")
|
||||
|
||||
ge_gen: ristretto255.Group_Element
|
||||
ristretto255.ge_generator(&ge_gen)
|
||||
|
||||
@@ -158,7 +135,7 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ge: ristretto255.Group_Element
|
||||
ok := ristretto255.ge_set_bytes(&ge, b)
|
||||
tc.expect(t, !ok, fmt.tprintf("Expected false for %s", x))
|
||||
testing.expectf(t, !ok, "Expected false for %s", x)
|
||||
}
|
||||
|
||||
generator_multiples := []string {
|
||||
@@ -185,22 +162,20 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ge := &ges[i]
|
||||
ok := ristretto255.ge_set_bytes(ge, b)
|
||||
tc.expect(t, ok, fmt.tprintf("Expected true for %s", x))
|
||||
testing.expectf(t, ok, "Expected true for %s", x)
|
||||
|
||||
x_check := ge_str(ge)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x == x_check,
|
||||
fmt.tprintf(
|
||||
"Expected %s (round-trip) but got %s instead",
|
||||
x,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s (round-trip) but got %s instead",
|
||||
x,
|
||||
x_check,
|
||||
)
|
||||
|
||||
if i == 1 {
|
||||
tc.expect(
|
||||
testing.expect(
|
||||
t,
|
||||
ristretto255.ge_equal(ge, &ge_gen) == 1,
|
||||
"Expected element 1 to be the generator",
|
||||
@@ -217,41 +192,35 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ristretto255.ge_scalarmult_generator(&ge_check, &sc)
|
||||
x_check := ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (specialized), got %s",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (specialized), got %s",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
ristretto255.ge_scalarmult(&ge_check, &ges[1], &sc)
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (generic), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (generic), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
ristretto255.ge_scalarmult_vartime(&ge_check, &ges[1], &sc)
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (generic vartime), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (generic vartime), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
switch i {
|
||||
@@ -261,28 +230,24 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
ristretto255.ge_add(&ge_check, ge_prev, &ge_gen)
|
||||
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ristretto255.ge_equal(&ges[i], &ge_check) == 1,
|
||||
fmt.tprintf(
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (fast compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (fast compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -344,22 +309,18 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
ristretto255.ge_set_wide_bytes(&ge, in_bytes)
|
||||
|
||||
ge_check := ge_str(&ge)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ge_check == v.output,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s, got %s",
|
||||
v.output,
|
||||
ge_check,
|
||||
),
|
||||
"Expected %s for %s, got %s",
|
||||
v.output,
|
||||
ge_check,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_ed25519 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing ed25519")
|
||||
|
||||
test_vectors_rfc := []struct {
|
||||
priv_key: string,
|
||||
pub_key: string,
|
||||
@@ -401,87 +362,73 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
|
||||
priv_key: ed25519.Private_Key
|
||||
ok := ed25519.private_key_set_bytes(&priv_key, priv_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected %s to be a valid private key",
|
||||
v.priv_key,
|
||||
),
|
||||
"Expected %s to be a valid private key",
|
||||
v.priv_key,
|
||||
)
|
||||
|
||||
key_bytes: [32]byte
|
||||
ed25519.private_key_bytes(&priv_key, key_bytes[:])
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected private key %s round-trip, got %s",
|
||||
v.priv_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected private key %s round-trip, got %s",
|
||||
v.priv_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
pub_key: ed25519.Public_Key
|
||||
ok = ed25519.public_key_set_bytes(&pub_key, pub_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected %s to be a valid public key (priv->pub: %s)",
|
||||
v.pub_key,
|
||||
string(hex.encode(priv_key._pub_key._b[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected %s to be a valid public key (priv->pub: %s)",
|
||||
v.pub_key,
|
||||
string(hex.encode(priv_key._pub_key._b[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
ed25519.public_key_bytes(&pub_key, key_bytes[:])
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected public key %s round-trip, got %s",
|
||||
v.pub_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected public key %s round-trip, got %s",
|
||||
v.pub_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
sig: [ed25519.SIGNATURE_SIZE]byte
|
||||
ed25519.sign(&priv_key, msg_bytes, sig[:])
|
||||
x := string(hex.encode(sig[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x == v.sig,
|
||||
fmt.tprintf(
|
||||
"Expected %s for sign(%s, %s), got %s",
|
||||
v.sig,
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
x,
|
||||
),
|
||||
"Expected %s for sign(%s, %s), got %s",
|
||||
v.sig,
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
x,
|
||||
)
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected true for verify(%s, %s, %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected true for verify(%s, %s, %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
ok = ed25519.verify(&priv_key._pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected true for verify(pub(%s), %s %s)",
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected true for verify(pub(%s), %s %s)",
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
// Corrupt the message and make sure verification fails.
|
||||
@@ -493,15 +440,13 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
msg_bytes[0] = msg_bytes[0] ~ 69
|
||||
}
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == false,
|
||||
fmt.tprintf(
|
||||
"Expected false for verify(%s, %s (corrupted), %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected false for verify(%s, %s (corrupted), %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -634,15 +579,13 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
|
||||
pub_key: ed25519.Public_Key
|
||||
ok := ed25519.public_key_set_bytes(&pub_key, pub_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.pub_key_ok,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d: Expected %s to be a (in)valid public key, got %v",
|
||||
i,
|
||||
v.pub_key,
|
||||
ok,
|
||||
),
|
||||
"speccheck/%d: Expected %s to be a (in)valid public key, got %v",
|
||||
i,
|
||||
v.pub_key,
|
||||
ok,
|
||||
)
|
||||
|
||||
// If A is rejected for being non-canonical, skip signature check.
|
||||
@@ -651,17 +594,15 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.sig_ok,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s)",
|
||||
i,
|
||||
v.sig_ok,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s)",
|
||||
i,
|
||||
v.sig_ok,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
// If the signature is accepted, skip the relaxed signature check.
|
||||
@@ -670,25 +611,21 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes, true)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.sig_ok_relaxed,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s, true)",
|
||||
i,
|
||||
v.sig_ok_relaxed,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s, true)",
|
||||
i,
|
||||
v.sig_ok_relaxed,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_x25519 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing X25519")
|
||||
|
||||
// Local copy of this so that the base point doesn't need to be exported.
|
||||
_BASE_POINT: [32]byte = {
|
||||
9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -720,17 +657,15 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
x25519.scalarmult(derived_point[:], scalar[:], point[:])
|
||||
derived_point_str := string(hex.encode(derived_point[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_point_str == v.product,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s * %s, but got %s instead",
|
||||
v.product,
|
||||
v.scalar,
|
||||
v.point,
|
||||
derived_point_str,
|
||||
),
|
||||
)
|
||||
"Expected %s for %s * %s, but got %s instead",
|
||||
v.product,
|
||||
v.scalar,
|
||||
v.point,
|
||||
derived_point_str,
|
||||
)
|
||||
|
||||
// Abuse the test vectors to sanity-check the scalar-basepoint multiply.
|
||||
p1, p2: [x25519.POINT_SIZE]byte
|
||||
@@ -738,15 +673,13 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
x25519.scalarmult(p2[:], scalar[:], _BASE_POINT[:])
|
||||
p1_str := string(hex.encode(p1[:], context.temp_allocator))
|
||||
p2_str := string(hex.encode(p2[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
p1_str == p2_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s * basepoint, but got %s instead",
|
||||
p2_str,
|
||||
v.scalar,
|
||||
p1_str,
|
||||
),
|
||||
"Expected %s for %s * basepoint, but got %s instead",
|
||||
p2_str,
|
||||
v.scalar,
|
||||
p1_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -763,4 +696,4 @@ fe_str :: proc(fe: ^field.Tight_Field_Element) -> string {
|
||||
b: [32]byte
|
||||
field.fe_to_bytes(&b, fe)
|
||||
return string(hex.encode(b[:], context.temp_allocator))
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,17 @@ package test_core_crypto
|
||||
import "base:runtime"
|
||||
import "core:bytes"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_hash :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing Hashes")
|
||||
|
||||
// TODO:
|
||||
// - Stick the test vectors in a JSON file or something.
|
||||
data_1_000_000_a := strings.repeat("a", 1_000_000)
|
||||
data_1_000_000_a := strings.repeat("a", 1_000_000, context.temp_allocator)
|
||||
|
||||
digest: [hash.MAX_DIGEST_SIZE]byte
|
||||
test_vectors := []struct{
|
||||
@@ -496,16 +490,14 @@ test_hash :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.hash,
|
||||
fmt.tprintf(
|
||||
"%s/incremental: Expected: %s for input of %s, but got %s instead",
|
||||
algo_name,
|
||||
v.hash,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
"%s/incremental: Expected: %s for input of %s, but got %s instead",
|
||||
algo_name,
|
||||
v.hash,
|
||||
v.str,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -521,25 +513,21 @@ test_hash :: proc(t: ^testing.T) {
|
||||
// still correct.
|
||||
digest_sz := hash.DIGEST_SIZES[algo]
|
||||
block_sz := hash.BLOCK_SIZES[algo]
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
digest_sz <= hash.MAX_DIGEST_SIZE,
|
||||
fmt.tprintf(
|
||||
"%s: Digest size %d exceeds max %d",
|
||||
algo_name,
|
||||
digest_sz,
|
||||
hash.MAX_DIGEST_SIZE,
|
||||
),
|
||||
"%s: Digest size %d exceeds max %d",
|
||||
algo_name,
|
||||
digest_sz,
|
||||
hash.MAX_DIGEST_SIZE,
|
||||
)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
block_sz <= hash.MAX_BLOCK_SIZE,
|
||||
fmt.tprintf(
|
||||
"%s: Block size %d exceeds max %d",
|
||||
algo_name,
|
||||
block_sz,
|
||||
hash.MAX_BLOCK_SIZE,
|
||||
),
|
||||
"%s: Block size %d exceeds max %d",
|
||||
algo_name,
|
||||
block_sz,
|
||||
hash.MAX_BLOCK_SIZE,
|
||||
)
|
||||
|
||||
// Exercise most of the happy-path for the high level interface.
|
||||
@@ -553,15 +541,13 @@ test_hash :: proc(t: ^testing.T) {
|
||||
a_str := string(hex.encode(digest_a, context.temp_allocator))
|
||||
b_str := string(hex.encode(digest_b, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
a_str == b_str,
|
||||
fmt.tprintf(
|
||||
"%s/cmp: Expected: %s (hash_stream) == %s (hash_bytes)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
),
|
||||
"%s/cmp: Expected: %s (hash_stream) == %s (hash_bytes)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
)
|
||||
|
||||
// Exercise the rolling digest functionality, which also covers
|
||||
@@ -571,25 +557,21 @@ test_hash :: proc(t: ^testing.T) {
|
||||
|
||||
api_algo := hash.algorithm(&ctx)
|
||||
api_digest_size := hash.digest_size(&ctx)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
algo == api_algo,
|
||||
fmt.tprintf(
|
||||
"%s/algorithm: Expected: %v but got %v instead",
|
||||
algo_name,
|
||||
algo,
|
||||
api_algo,
|
||||
),
|
||||
"%s/algorithm: Expected: %v but got %v instead",
|
||||
algo_name,
|
||||
algo,
|
||||
api_algo,
|
||||
)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
hash.DIGEST_SIZES[algo] == api_digest_size,
|
||||
fmt.tprintf(
|
||||
"%s/digest_size: Expected: %d but got %d instead",
|
||||
algo_name,
|
||||
hash.DIGEST_SIZES[algo],
|
||||
api_digest_size,
|
||||
),
|
||||
"%s/digest_size: Expected: %d but got %d instead",
|
||||
algo_name,
|
||||
hash.DIGEST_SIZES[algo],
|
||||
api_digest_size,
|
||||
)
|
||||
|
||||
hash.update(&ctx, digest_a)
|
||||
@@ -604,16 +586,14 @@ test_hash :: proc(t: ^testing.T) {
|
||||
b_str = string(hex.encode(digest_b, context.temp_allocator))
|
||||
c_str := string(hex.encode(digest_c, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
a_str == b_str && b_str == c_str,
|
||||
fmt.tprintf(
|
||||
"%s/rolling: Expected: %s (first) == %s (second) == %s (third)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
c_str,
|
||||
),
|
||||
"%s/rolling: Expected: %s (first) == %s (second) == %s (third)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
c_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,28 +2,14 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
import "core:crypto/hkdf"
|
||||
import "core:crypto/pbkdf2"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_kdf :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing KDFs")
|
||||
|
||||
test_hkdf(t)
|
||||
test_pbkdf2(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_hkdf :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing HKDF")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tmp: [128]byte // Good enough.
|
||||
|
||||
@@ -70,25 +56,23 @@ test_hkdf :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.okm,
|
||||
fmt.tprintf(
|
||||
"HKDF-%s: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
algo_name,
|
||||
v.okm,
|
||||
v.ikm,
|
||||
v.salt,
|
||||
v.info,
|
||||
dst_str,
|
||||
),
|
||||
"HKDF-%s: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
algo_name,
|
||||
v.okm,
|
||||
v.ikm,
|
||||
v.salt,
|
||||
v.info,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_pbkdf2 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing PBKDF2")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tmp: [64]byte // 512-bits is enough for every output for now.
|
||||
|
||||
@@ -174,18 +158,16 @@ test_pbkdf2 :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.dk,
|
||||
fmt.tprintf(
|
||||
"HMAC-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
|
||||
algo_name,
|
||||
v.dk,
|
||||
v.password,
|
||||
v.salt,
|
||||
v.iterations,
|
||||
dst_str,
|
||||
),
|
||||
"HMAC-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
|
||||
algo_name,
|
||||
v.dk,
|
||||
v.password,
|
||||
v.salt,
|
||||
v.iterations,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,17 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
import "core:crypto/hmac"
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/siphash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_mac :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing MACs")
|
||||
|
||||
test_hmac(t)
|
||||
test_poly1305(t)
|
||||
test_siphash_2_4(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_hmac :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases pulled out of RFC 6234, note that HMAC is a generic
|
||||
// construct so as long as the underlying hash is correct and all
|
||||
// the code paths are covered the implementation is "fine", so
|
||||
@@ -86,40 +73,36 @@ test_hmac :: proc(t: ^testing.T) {
|
||||
msg_str := string(hex.encode(msg, context.temp_allocator))
|
||||
dst_str := string(hex.encode(dst[:tag_len], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == expected_str,
|
||||
fmt.tprintf(
|
||||
"%s/incremental: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
dst_str,
|
||||
),
|
||||
"%s/incremental: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
dst_str,
|
||||
)
|
||||
|
||||
hmac.sum(algo, dst, msg, key)
|
||||
oneshot_str := string(hex.encode(dst[:tag_len], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
oneshot_str == expected_str,
|
||||
fmt.tprintf(
|
||||
"%s/oneshot: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
oneshot_str,
|
||||
),
|
||||
"%s/oneshot: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
oneshot_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_poly1305 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing poly1305")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases taken from poly1305-donna.
|
||||
key := [poly1305.KEY_SIZE]byte {
|
||||
@@ -157,16 +140,17 @@ test_poly1305 :: proc(t: ^testing.T) {
|
||||
|
||||
// Verify - oneshot + compare
|
||||
ok := poly1305.verify(tag[:], msg[:], key[:])
|
||||
tc.expect(t, ok, "oneshot verify call failed")
|
||||
testing.expect(t, ok, "oneshot verify call failed")
|
||||
|
||||
// Sum - oneshot
|
||||
derived_tag: [poly1305.TAG_SIZE]byte
|
||||
poly1305.sum(derived_tag[:], msg[:], key[:])
|
||||
derived_tag_str := string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf("Expected %s for sum(msg, key), but got %s instead", tag_str, derived_tag_str),
|
||||
"Expected %s for sum(msg, key), but got %s instead",
|
||||
tag_str, derived_tag_str,
|
||||
)
|
||||
|
||||
// Incremental
|
||||
@@ -182,21 +166,16 @@ test_poly1305 :: proc(t: ^testing.T) {
|
||||
}
|
||||
poly1305.final(&ctx, derived_tag[:])
|
||||
derived_tag_str = string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for init/update/final - incremental, but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
),
|
||||
"Expected %s for init/update/final - incremental, but got %s instead",
|
||||
tag_str, derived_tag_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing SipHash-2-4")
|
||||
|
||||
// Test vectors from
|
||||
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||
test_vectors := [?]u64 {
|
||||
@@ -225,6 +204,7 @@ test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
|
||||
for i in 0 ..< len(test_vectors) {
|
||||
data := make([]byte, i)
|
||||
defer delete(data)
|
||||
for j in 0 ..< i {
|
||||
data[j] = byte(j)
|
||||
}
|
||||
@@ -232,15 +212,13 @@ test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
vector := test_vectors[i]
|
||||
computed := siphash.sum_2_4(data[:], key[:])
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
computed == vector,
|
||||
fmt.tprintf(
|
||||
"Expected: 0x%x for input of %v, but got 0x%x instead",
|
||||
vector,
|
||||
data,
|
||||
computed,
|
||||
),
|
||||
"Expected: 0x%x for input of %v, but got 0x%x instead",
|
||||
vector,
|
||||
data,
|
||||
computed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,14 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/kmac"
|
||||
import "core:crypto/shake"
|
||||
import "core:crypto/tuplehash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_sha3_variants :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing SHA3 derived functions")
|
||||
|
||||
test_shake(t)
|
||||
test_cshake(t)
|
||||
test_tuplehash(t)
|
||||
test_kmac(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_shake :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing SHAKE")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -67,23 +51,21 @@ test_shake :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"SHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
"SHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_cshake :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing cSHAKE")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -135,29 +117,27 @@ test_cshake :: proc(t: ^testing.T) {
|
||||
shake.init_cshake_256(&ctx, domainsep)
|
||||
}
|
||||
|
||||
data, _ := hex.decode(transmute([]byte)(v.str))
|
||||
data, _ := hex.decode(transmute([]byte)(v.str), context.temp_allocator)
|
||||
shake.write(&ctx, data)
|
||||
shake.read(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"cSHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
"cSHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_tuplehash :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing TupleHash(XOF)")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -317,7 +297,7 @@ test_tuplehash :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
for e in v.tuple {
|
||||
data, _ := hex.decode(transmute([]byte)(e))
|
||||
data, _ := hex.decode(transmute([]byte)(e), context.temp_allocator)
|
||||
tuplehash.write_element(&ctx, data)
|
||||
}
|
||||
|
||||
@@ -332,24 +312,22 @@ test_tuplehash :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"TupleHash%s%d: Expected: %s for input of %v, but got %s instead",
|
||||
suffix,
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.tuple,
|
||||
dst_str,
|
||||
),
|
||||
"TupleHash%s%d: Expected: %s for input of %v, but got %s instead",
|
||||
suffix,
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.tuple,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_kmac :: proc(t:^testing.T) {
|
||||
tc.log(t, "Testing KMAC")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -410,7 +388,7 @@ test_kmac :: proc(t:^testing.T) {
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output) / 2, context.temp_allocator)
|
||||
|
||||
key, _ := hex.decode(transmute([]byte)(v.key))
|
||||
key, _ := hex.decode(transmute([]byte)(v.key), context.temp_allocator)
|
||||
domainsep := transmute([]byte)(v.domainsep)
|
||||
|
||||
ctx: kmac.Context
|
||||
@@ -421,24 +399,22 @@ test_kmac :: proc(t:^testing.T) {
|
||||
kmac.init_256(&ctx, key, domainsep)
|
||||
}
|
||||
|
||||
data, _ := hex.decode(transmute([]byte)(v.msg))
|
||||
data, _ := hex.decode(transmute([]byte)(v.msg), context.temp_allocator)
|
||||
kmac.update(&ctx, data)
|
||||
kmac.final(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"KMAC%d: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.key,
|
||||
v.domainsep,
|
||||
v.msg,
|
||||
dst_str,
|
||||
),
|
||||
"KMAC%d: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.key,
|
||||
v.domainsep,
|
||||
v.msg,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
|
||||
import "core:crypto/aes"
|
||||
import "core:crypto/chacha20"
|
||||
import "core:crypto/chacha20poly1305"
|
||||
import "core:crypto/ed25519"
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
// Cryptographic primitive benchmarks.
|
||||
|
||||
@(test)
|
||||
bench_crypto :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
fmt.println("Starting benchmarks:")
|
||||
|
||||
bench_chacha20(t)
|
||||
bench_poly1305(t)
|
||||
bench_chacha20poly1305(t)
|
||||
bench_aes256_gcm(t)
|
||||
bench_ed25519(t)
|
||||
bench_x25519(t)
|
||||
}
|
||||
|
||||
_setup_sized_buf :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
assert(options != nil)
|
||||
|
||||
options.input = make([]u8, options.bytes, allocator)
|
||||
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||
}
|
||||
|
||||
_teardown_sized_buf :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
assert(options != nil)
|
||||
|
||||
delete(options.input)
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_chacha20 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [chacha20.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
nonce := [chacha20.NONCE_SIZE]byte {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
ctx: chacha20.Context = ---
|
||||
chacha20.init(&ctx, key[:], nonce[:])
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
chacha20.xor_bytes(&ctx, buf, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_poly1305 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [poly1305.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
|
||||
tag: [poly1305.TAG_SIZE]byte = ---
|
||||
for _ in 0 ..= options.rounds {
|
||||
poly1305.sum(tag[:], buf, key[:])
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
//options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_chacha20poly1305 :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
key := [chacha20.KEY_SIZE]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
nonce := [chacha20.NONCE_SIZE]byte {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
tag: [chacha20poly1305.TAG_SIZE]byte = ---
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
chacha20poly1305.encrypt(buf, tag[:], key[:], nonce[:], nil, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_aes256_gcm :: proc(
|
||||
options: ^time.Benchmark_Options,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
err: time.Benchmark_Error,
|
||||
) {
|
||||
buf := options.input
|
||||
nonce: [aes.GCM_NONCE_SIZE]byte
|
||||
tag: [aes.GCM_TAG_SIZE]byte = ---
|
||||
|
||||
ctx := transmute(^aes.Context_GCM)context.user_ptr
|
||||
|
||||
for _ in 0 ..= options.rounds {
|
||||
aes.seal_gcm(ctx, buf, tag[:], nonce[:], nil, buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
|
||||
fmt.printf(
|
||||
"\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
time.duration_nanoseconds(options.duration),
|
||||
options.rounds_per_second,
|
||||
options.megabytes_per_second,
|
||||
)
|
||||
}
|
||||
|
||||
bench_chacha20 :: proc(t: ^testing.T) {
|
||||
name := "ChaCha20 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_chacha20,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "ChaCha20 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "ChaCha20 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
bench_poly1305 :: proc(t: ^testing.T) {
|
||||
name := "Poly1305 64 zero bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_poly1305,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "Poly1305 1024 zero bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
bench_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
name := "chacha20poly1305 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_chacha20poly1305,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "chacha20poly1305 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "chacha20poly1305 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
bench_aes256_gcm :: proc(t: ^testing.T) {
|
||||
name := "AES256-GCM 64 bytes"
|
||||
options := &time.Benchmark_Options {
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_sized_buf,
|
||||
bench = _benchmark_aes256_gcm,
|
||||
teardown = _teardown_sized_buf,
|
||||
}
|
||||
|
||||
key := [aes.KEY_SIZE_256]byte {
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
ctx: aes.Context_GCM
|
||||
aes.init_gcm(&ctx, key[:])
|
||||
|
||||
context.user_ptr = &ctx
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "AES256-GCM 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "AES256-GCM 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
bench_ed25519 :: proc(t: ^testing.T) {
|
||||
iters :: 10000
|
||||
|
||||
priv_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
|
||||
priv_bytes, _ := hex.decode(transmute([]byte)(priv_str), context.temp_allocator)
|
||||
priv_key: ed25519.Private_Key
|
||||
start := time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.private_key_set_bytes(&priv_key, priv_bytes)
|
||||
assert(ok, "private key should deserialize")
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf(
|
||||
"ed25519.private_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
),
|
||||
)
|
||||
|
||||
pub_bytes := priv_key._pub_key._b[:] // "I know what I am doing"
|
||||
pub_key: ed25519.Public_Key
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.public_key_set_bytes(&pub_key, pub_bytes[:])
|
||||
assert(ok, "public key should deserialize")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf(
|
||||
"ed25519.public_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
),
|
||||
)
|
||||
|
||||
msg := "Got a job for you, 621."
|
||||
sig_bytes: [ed25519.SIGNATURE_SIZE]byte
|
||||
msg_bytes := transmute([]byte)(msg)
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ed25519.sign(&priv_key, msg_bytes, sig_bytes[:])
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(t, fmt.tprintf("ed25519.sign: ~%f us/op", time.duration_microseconds(elapsed) / iters))
|
||||
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
ok := ed25519.verify(&pub_key, msg_bytes, sig_bytes[:])
|
||||
assert(ok, "signature should validate")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf("ed25519.verify: ~%f us/op", time.duration_microseconds(elapsed) / iters),
|
||||
)
|
||||
}
|
||||
|
||||
bench_x25519 :: proc(t: ^testing.T) {
|
||||
point_str := "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
scalar_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
|
||||
|
||||
point, _ := hex.decode(transmute([]byte)(point_str), context.temp_allocator)
|
||||
scalar, _ := hex.decode(transmute([]byte)(scalar_str), context.temp_allocator)
|
||||
out: [x25519.POINT_SIZE]byte = ---
|
||||
|
||||
iters :: 10000
|
||||
start := time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
x25519.scalarmult(out[:], scalar[:], point[:])
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf("x25519.scalarmult: ~%f us/op", time.duration_microseconds(elapsed) / iters),
|
||||
)
|
||||
}
|
||||
@@ -1,61 +1,38 @@
|
||||
package test_encoding_base64
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:encoding/base64"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:reflect"
|
||||
import "core:testing"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect_value :: testing.expect_value
|
||||
|
||||
} else {
|
||||
expect_value :: proc(t: ^testing.T, value, expected: $T, loc := #caller_location) -> bool where intrinsics.type_is_comparable(T) {
|
||||
TEST_count += 1
|
||||
ok := value == expected || reflect.is_nil(value) && reflect.is_nil(expected)
|
||||
if !ok {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] expected %v, got %v\n", loc, expected, value)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
Test :: struct {
|
||||
vector: string,
|
||||
base64: string,
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_encoding(&t)
|
||||
test_decoding(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
tests :: []Test{
|
||||
{"", ""},
|
||||
{"f", "Zg=="},
|
||||
{"fo", "Zm8="},
|
||||
{"foo", "Zm9v"},
|
||||
{"foob", "Zm9vYg=="},
|
||||
{"fooba", "Zm9vYmE="},
|
||||
{"foobar", "Zm9vYmFy"},
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_encoding :: proc(t: ^testing.T) {
|
||||
expect_value(t, base64.encode(transmute([]byte)string("")), "")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("f")), "Zg==")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("fo")), "Zm8=")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("foo")), "Zm9v")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("foob")), "Zm9vYg==")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("fooba")), "Zm9vYmE=")
|
||||
expect_value(t, base64.encode(transmute([]byte)string("foobar")), "Zm9vYmFy")
|
||||
for test in tests {
|
||||
v := base64.encode(transmute([]byte)test.vector)
|
||||
defer delete(v)
|
||||
testing.expect_value(t, v, test.base64)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_decoding :: proc(t: ^testing.T) {
|
||||
expect_value(t, string(base64.decode("")), "")
|
||||
expect_value(t, string(base64.decode("Zg==")), "f")
|
||||
expect_value(t, string(base64.decode("Zm8=")), "fo")
|
||||
expect_value(t, string(base64.decode("Zm9v")), "foo")
|
||||
expect_value(t, string(base64.decode("Zm9vYg==")), "foob")
|
||||
expect_value(t, string(base64.decode("Zm9vYmE=")), "fooba")
|
||||
expect_value(t, string(base64.decode("Zm9vYmFy")), "foobar")
|
||||
for test in tests {
|
||||
v := string(base64.decode(test.base64))
|
||||
defer delete(v)
|
||||
testing.expect_value(t, v, test.vector)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,105 +1,15 @@
|
||||
package test_encoding_cbor
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:bytes"
|
||||
import "core:encoding/cbor"
|
||||
import "core:fmt"
|
||||
import "core:io"
|
||||
import "core:math/big"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:reflect"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
expect_value :: testing.expect_value
|
||||
errorf :: testing.errorf
|
||||
log :: testing.log
|
||||
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
expect_value :: proc(t: ^testing.T, value, expected: $T, loc := #caller_location) -> bool where intrinsics.type_is_comparable(T) {
|
||||
TEST_count += 1
|
||||
ok := value == expected || reflect.is_nil(value) && reflect.is_nil(expected)
|
||||
if !ok {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] expected %v, got %v\n", loc, expected, value)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
errorf :: proc(t: ^testing.T, fmts: string, args: ..any, loc := #caller_location) {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] ERROR: ", loc)
|
||||
fmt.printf(fmts, ..args)
|
||||
fmt.println()
|
||||
}
|
||||
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_marshalling(&t)
|
||||
|
||||
test_marshalling_maybe(&t)
|
||||
test_marshalling_nil_maybe(&t)
|
||||
|
||||
test_marshalling_union(&t)
|
||||
|
||||
test_lying_length_array(&t)
|
||||
|
||||
test_decode_unsigned(&t)
|
||||
test_encode_unsigned(&t)
|
||||
|
||||
test_decode_negative(&t)
|
||||
test_encode_negative(&t)
|
||||
|
||||
test_decode_simples(&t)
|
||||
test_encode_simples(&t)
|
||||
|
||||
test_decode_floats(&t)
|
||||
test_encode_floats(&t)
|
||||
|
||||
test_decode_bytes(&t)
|
||||
test_encode_bytes(&t)
|
||||
|
||||
test_decode_strings(&t)
|
||||
test_encode_strings(&t)
|
||||
|
||||
test_decode_lists(&t)
|
||||
test_encode_lists(&t)
|
||||
|
||||
test_decode_maps(&t)
|
||||
test_encode_maps(&t)
|
||||
|
||||
test_decode_tags(&t)
|
||||
test_encode_tags(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Foo :: struct {
|
||||
str: string,
|
||||
cstr: cstring,
|
||||
@@ -143,14 +53,6 @@ FooBars :: bit_set[FooBar; u16]
|
||||
|
||||
@(test)
|
||||
test_marshalling :: proc(t: ^testing.T) {
|
||||
tracker: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&tracker, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&tracker)
|
||||
context.temp_allocator = context.allocator
|
||||
defer mem.tracking_allocator_destroy(&tracker)
|
||||
|
||||
ev :: expect_value
|
||||
|
||||
{
|
||||
nice := "16 is a nice number"
|
||||
now := time.Time{_nsec = 1701117968 * 1e9}
|
||||
@@ -205,18 +107,18 @@ test_marshalling :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
data, err := cbor.marshal(f, cbor.ENCODE_FULLY_DETERMINISTIC)
|
||||
ev(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
defer delete(data)
|
||||
|
||||
decoded, derr := cbor.decode(string(data))
|
||||
ev(t, derr, nil)
|
||||
testing.expect_value(t, derr, nil)
|
||||
defer cbor.destroy(decoded)
|
||||
|
||||
diagnosis, eerr := cbor.to_diagnostic_format(decoded)
|
||||
ev(t, eerr, nil)
|
||||
testing.expect_value(t, eerr, nil)
|
||||
defer delete(diagnosis)
|
||||
|
||||
ev(t, diagnosis, `{
|
||||
testing.expect_value(t, diagnosis, `{
|
||||
"base64": 34("MTYgaXMgYSBuaWNlIG51bWJlcg=="),
|
||||
"biggest": 2(h'f951a9fd3c158afdff08ab8e0'),
|
||||
"biggie": 18446744073709551615,
|
||||
@@ -285,7 +187,7 @@ test_marshalling :: proc(t: ^testing.T) {
|
||||
|
||||
backf: Foo
|
||||
uerr := cbor.unmarshal(string(data), &backf)
|
||||
ev(t, uerr, nil)
|
||||
testing.expect_value(t, uerr, nil)
|
||||
defer {
|
||||
delete(backf.str)
|
||||
delete(backf.cstr)
|
||||
@@ -304,104 +206,102 @@ test_marshalling :: proc(t: ^testing.T) {
|
||||
big.destroy(&backf.smallest)
|
||||
}
|
||||
|
||||
ev(t, backf.str, f.str)
|
||||
ev(t, backf.cstr, f.cstr)
|
||||
testing.expect_value(t, backf.str, f.str)
|
||||
testing.expect_value(t, backf.cstr, f.cstr)
|
||||
|
||||
#partial switch v in backf.value {
|
||||
case ^cbor.Map:
|
||||
for entry, i in v {
|
||||
fm := f.value.(^cbor.Map)
|
||||
ev(t, entry.key, fm[i].key)
|
||||
testing.expect_value(t, entry.key, fm[i].key)
|
||||
|
||||
if str, is_str := entry.value.(^cbor.Text); is_str {
|
||||
ev(t, str^, fm[i].value.(^cbor.Text)^)
|
||||
testing.expect_value(t, str^, fm[i].value.(^cbor.Text)^)
|
||||
} else {
|
||||
ev(t, entry.value, fm[i].value)
|
||||
testing.expect_value(t, entry.value, fm[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
case: errorf(t, "wrong type %v", v)
|
||||
case: testing.expectf(t, false, "wrong type %v", v)
|
||||
}
|
||||
|
||||
ev(t, backf.neg, f.neg)
|
||||
ev(t, backf.iamint, f.iamint)
|
||||
ev(t, backf.base64, f.base64)
|
||||
ev(t, backf.renamed, f.renamed)
|
||||
ev(t, backf.now, f.now)
|
||||
ev(t, backf.nowie, f.nowie)
|
||||
for e, i in f.child.dyn { ev(t, backf.child.dyn[i], e) }
|
||||
for key, value in f.child.mappy { ev(t, backf.child.mappy[key], value) }
|
||||
ev(t, backf.child.my_integers, f.child.my_integers)
|
||||
ev(t, len(backf.my_bytes), 0)
|
||||
ev(t, len(backf.my_bytes), len(f.my_bytes))
|
||||
ev(t, backf.ennie, f.ennie)
|
||||
ev(t, backf.ennieb, f.ennieb)
|
||||
ev(t, backf.quat, f.quat)
|
||||
ev(t, backf.comp, f.comp)
|
||||
ev(t, backf.important, f.important)
|
||||
ev(t, backf.no, nil)
|
||||
ev(t, backf.nos, nil)
|
||||
ev(t, backf.yes, f.yes)
|
||||
ev(t, backf.biggie, f.biggie)
|
||||
ev(t, backf.smallie, f.smallie)
|
||||
ev(t, backf.onetwenty, f.onetwenty)
|
||||
ev(t, backf.small_onetwenty, f.small_onetwenty)
|
||||
ev(t, backf.ignore_this, nil)
|
||||
testing.expect_value(t, backf.neg, f.neg)
|
||||
testing.expect_value(t, backf.iamint, f.iamint)
|
||||
testing.expect_value(t, backf.base64, f.base64)
|
||||
testing.expect_value(t, backf.renamed, f.renamed)
|
||||
testing.expect_value(t, backf.now, f.now)
|
||||
testing.expect_value(t, backf.nowie, f.nowie)
|
||||
for e, i in f.child.dyn { testing.expect_value(t, backf.child.dyn[i], e) }
|
||||
for key, value in f.child.mappy { testing.expect_value(t, backf.child.mappy[key], value) }
|
||||
testing.expect_value(t, backf.child.my_integers, f.child.my_integers)
|
||||
testing.expect_value(t, len(backf.my_bytes), 0)
|
||||
testing.expect_value(t, len(backf.my_bytes), len(f.my_bytes))
|
||||
testing.expect_value(t, backf.ennie, f.ennie)
|
||||
testing.expect_value(t, backf.ennieb, f.ennieb)
|
||||
testing.expect_value(t, backf.quat, f.quat)
|
||||
testing.expect_value(t, backf.comp, f.comp)
|
||||
testing.expect_value(t, backf.important, f.important)
|
||||
testing.expect_value(t, backf.no, nil)
|
||||
testing.expect_value(t, backf.nos, nil)
|
||||
testing.expect_value(t, backf.yes, f.yes)
|
||||
testing.expect_value(t, backf.biggie, f.biggie)
|
||||
testing.expect_value(t, backf.smallie, f.smallie)
|
||||
testing.expect_value(t, backf.onetwenty, f.onetwenty)
|
||||
testing.expect_value(t, backf.small_onetwenty, f.small_onetwenty)
|
||||
testing.expect_value(t, backf.ignore_this, nil)
|
||||
|
||||
s_equals, s_err := big.equals(&backf.smallest, &f.smallest)
|
||||
ev(t, s_err, nil)
|
||||
testing.expect_value(t, s_err, nil)
|
||||
if !s_equals {
|
||||
errorf(t, "smallest: %v does not equal %v", big.itoa(&backf.smallest), big.itoa(&f.smallest))
|
||||
testing.expectf(t, false, "smallest: %v does not equal %v", big.itoa(&backf.smallest), big.itoa(&f.smallest))
|
||||
}
|
||||
|
||||
b_equals, b_err := big.equals(&backf.biggest, &f.biggest)
|
||||
ev(t, b_err, nil)
|
||||
testing.expect_value(t, b_err, nil)
|
||||
if !b_equals {
|
||||
errorf(t, "biggest: %v does not equal %v", big.itoa(&backf.biggest), big.itoa(&f.biggest))
|
||||
testing.expectf(t, false, "biggest: %v does not equal %v", big.itoa(&backf.biggest), big.itoa(&f.biggest))
|
||||
}
|
||||
}
|
||||
|
||||
for _, leak in tracker.allocation_map {
|
||||
errorf(t, "%v leaked %m\n", leak.location, leak.size)
|
||||
}
|
||||
|
||||
for bad_free in tracker.bad_free_array {
|
||||
errorf(t, "%v allocation %p was freed badly\n", bad_free.location, bad_free.memory)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_marshalling_maybe :: proc(t: ^testing.T) {
|
||||
maybe_test: Maybe(int) = 1
|
||||
data, err := cbor.marshal(maybe_test)
|
||||
expect_value(t, err, nil)
|
||||
defer delete(data)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
val, derr := cbor.decode(string(data))
|
||||
expect_value(t, derr, nil)
|
||||
testing.expect_value(t, derr, nil)
|
||||
|
||||
expect_value(t, cbor.to_diagnostic_format(val), "1")
|
||||
diag := cbor.to_diagnostic_format(val)
|
||||
testing.expect_value(t, diag, "1")
|
||||
delete(diag)
|
||||
|
||||
maybe_dest: Maybe(int)
|
||||
uerr := cbor.unmarshal(string(data), &maybe_dest)
|
||||
expect_value(t, uerr, nil)
|
||||
expect_value(t, maybe_dest, 1)
|
||||
testing.expect_value(t, uerr, nil)
|
||||
testing.expect_value(t, maybe_dest, 1)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_marshalling_nil_maybe :: proc(t: ^testing.T) {
|
||||
maybe_test: Maybe(int)
|
||||
data, err := cbor.marshal(maybe_test)
|
||||
expect_value(t, err, nil)
|
||||
defer delete(data)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
val, derr := cbor.decode(string(data))
|
||||
expect_value(t, derr, nil)
|
||||
testing.expect_value(t, derr, nil)
|
||||
|
||||
expect_value(t, cbor.to_diagnostic_format(val), "nil")
|
||||
diag := cbor.to_diagnostic_format(val)
|
||||
testing.expect_value(t, diag, "nil")
|
||||
delete(diag)
|
||||
|
||||
maybe_dest: Maybe(int)
|
||||
uerr := cbor.unmarshal(string(data), &maybe_dest)
|
||||
expect_value(t, uerr, nil)
|
||||
expect_value(t, maybe_dest, nil)
|
||||
testing.expect_value(t, uerr, nil)
|
||||
testing.expect_value(t, maybe_dest, nil)
|
||||
}
|
||||
|
||||
@(test)
|
||||
@@ -427,17 +327,24 @@ test_marshalling_union :: proc(t: ^testing.T) {
|
||||
{
|
||||
test: My_Union = My_Distinct("Hello, World!")
|
||||
data, err := cbor.marshal(test)
|
||||
expect_value(t, err, nil)
|
||||
defer delete(data)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
val, derr := cbor.decode(string(data))
|
||||
expect_value(t, derr, nil)
|
||||
defer cbor.destroy(val)
|
||||
testing.expect_value(t, derr, nil)
|
||||
|
||||
expect_value(t, cbor.to_diagnostic_format(val, -1), `1010(["My_Distinct", "Hello, World!"])`)
|
||||
diag := cbor.to_diagnostic_format(val, -1)
|
||||
defer delete(diag)
|
||||
testing.expect_value(t, diag, `1010(["My_Distinct", "Hello, World!"])`)
|
||||
|
||||
dest: My_Union
|
||||
uerr := cbor.unmarshal(string(data), &dest)
|
||||
expect_value(t, uerr, nil)
|
||||
expect_value(t, dest, My_Distinct("Hello, World!"))
|
||||
testing.expect_value(t, uerr, nil)
|
||||
testing.expect_value(t, dest, My_Distinct("Hello, World!"))
|
||||
if str, ok := dest.(My_Distinct); ok {
|
||||
delete(string(str))
|
||||
}
|
||||
}
|
||||
|
||||
My_Union_No_Nil :: union #no_nil {
|
||||
@@ -450,17 +357,21 @@ test_marshalling_union :: proc(t: ^testing.T) {
|
||||
{
|
||||
test: My_Union_No_Nil = My_Struct{.Two}
|
||||
data, err := cbor.marshal(test)
|
||||
expect_value(t, err, nil)
|
||||
defer delete(data)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
val, derr := cbor.decode(string(data))
|
||||
expect_value(t, derr, nil)
|
||||
defer cbor.destroy(val)
|
||||
testing.expect_value(t, derr, nil)
|
||||
|
||||
expect_value(t, cbor.to_diagnostic_format(val, -1), `1010(["My_Struct", {"my_enum": 1}])`)
|
||||
diag := cbor.to_diagnostic_format(val, -1)
|
||||
defer delete(diag)
|
||||
testing.expect_value(t, diag, `1010(["My_Struct", {"my_enum": 1}])`)
|
||||
|
||||
dest: My_Union_No_Nil
|
||||
uerr := cbor.unmarshal(string(data), &dest)
|
||||
expect_value(t, uerr, nil)
|
||||
expect_value(t, dest, My_Struct{.Two})
|
||||
testing.expect_value(t, uerr, nil)
|
||||
testing.expect_value(t, dest, My_Struct{.Two})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +380,7 @@ test_lying_length_array :: proc(t: ^testing.T) {
|
||||
// Input says this is an array of length max(u64), this should not allocate that amount.
|
||||
input := []byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}
|
||||
_, err := cbor.decode(string(input))
|
||||
expect_value(t, err, io.Error.Unexpected_EOF) // .Out_Of_Memory would be bad.
|
||||
testing.expect_value(t, err, io.Error.Unexpected_EOF) // .Out_Of_Memory would be bad.
|
||||
}
|
||||
|
||||
@(test)
|
||||
@@ -691,65 +602,73 @@ test_encode_lists :: proc(t: ^testing.T) {
|
||||
expect_streamed_encoding(t, "\x9f\xff", &cbor.Array{})
|
||||
|
||||
{
|
||||
bytes.buffer_reset(&buf)
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 0)
|
||||
defer bytes.buffer_destroy(&buf)
|
||||
stream := bytes.buffer_to_stream(&buf)
|
||||
encoder := cbor.Encoder{cbor.ENCODE_FULLY_DETERMINISTIC, stream, {}}
|
||||
|
||||
err: cbor.Encode_Error
|
||||
err = cbor.encode_stream_begin(stream, .Array)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
{
|
||||
err = cbor.encode_stream_array_item(encoder, u8(1))
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
err = cbor.encode_stream_array_item(encoder, &cbor.Array{u8(2), u8(3)})
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
err = cbor.encode_stream_begin(stream, .Array)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
{
|
||||
err = cbor.encode_stream_array_item(encoder, u8(4))
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
err = cbor.encode_stream_array_item(encoder, u8(5))
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
}
|
||||
|
||||
err = cbor.encode_stream_end(stream)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
}
|
||||
|
||||
err = cbor.encode_stream_end(stream)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)string("\x9f\x01\x82\x02\x03\x9f\x04\x05\xff\xff")))
|
||||
testing.expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)string("\x9f\x01\x82\x02\x03\x9f\x04\x05\xff\xff")))
|
||||
}
|
||||
|
||||
{
|
||||
bytes.buffer_reset(&buf)
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 0)
|
||||
defer bytes.buffer_destroy(&buf)
|
||||
stream := bytes.buffer_to_stream(&buf)
|
||||
encoder := cbor.Encoder{cbor.ENCODE_FULLY_DETERMINISTIC, stream, {}}
|
||||
|
||||
err: cbor.Encode_Error
|
||||
err = cbor._encode_u8(stream, 2, .Array)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
a := "a"
|
||||
err = cbor.encode(encoder, &a)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
{
|
||||
err = cbor.encode_stream_begin(stream, .Map)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
b := "b"
|
||||
c := "c"
|
||||
err = cbor.encode_stream_map_entry(encoder, &b, &c)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
|
||||
err = cbor.encode_stream_end(stream)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect_value(t, err, nil)
|
||||
}
|
||||
|
||||
expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)string("\x82\x61\x61\xbf\x61\x62\x61\x63\xff")))
|
||||
testing.expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)string("\x82\x61\x61\xbf\x61\x62\x61\x63\xff")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,30 +726,30 @@ expect_decoding :: proc(t: ^testing.T, encoded: string, decoded: string, type: t
|
||||
res, err := cbor.decode(encoded)
|
||||
defer cbor.destroy(res)
|
||||
|
||||
expect_value(t, reflect.union_variant_typeid(res), type, loc)
|
||||
expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, reflect.union_variant_typeid(res), type, loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
|
||||
str := cbor.to_diagnostic_format(res, padding=-1)
|
||||
defer delete(str)
|
||||
|
||||
expect_value(t, str, decoded, loc)
|
||||
testing.expect_value(t, str, decoded, loc)
|
||||
}
|
||||
|
||||
expect_tag :: proc(t: ^testing.T, encoded: string, nr: cbor.Tag_Number, value_decoded: string, loc := #caller_location) {
|
||||
res, err := cbor.decode(encoded)
|
||||
defer cbor.destroy(res)
|
||||
|
||||
expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
|
||||
if tag, is_tag := res.(^cbor.Tag); is_tag {
|
||||
expect_value(t, tag.number, nr, loc)
|
||||
testing.expect_value(t, tag.number, nr, loc)
|
||||
|
||||
str := cbor.to_diagnostic_format(tag, padding=-1)
|
||||
defer delete(str)
|
||||
|
||||
expect_value(t, str, value_decoded, loc)
|
||||
testing.expect_value(t, str, value_decoded, loc)
|
||||
} else {
|
||||
errorf(t, "Value %#v is not a tag", res, loc)
|
||||
testing.expectf(t, false, "Value %#v is not a tag", res, loc)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,35 +757,39 @@ expect_float :: proc(t: ^testing.T, encoded: string, expected: $T, loc := #calle
|
||||
res, err := cbor.decode(encoded)
|
||||
defer cbor.destroy(res)
|
||||
|
||||
expect_value(t, reflect.union_variant_typeid(res), typeid_of(T), loc)
|
||||
expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, reflect.union_variant_typeid(res), typeid_of(T), loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
|
||||
#partial switch r in res {
|
||||
case f16:
|
||||
when T == f16 { expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
when T == f16 { testing.expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
case f32:
|
||||
when T == f32 { expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
when T == f32 { testing.expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
case f64:
|
||||
when T == f64 { expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
when T == f64 { testing.expect_value(t, res, expected, loc) } else { unreachable() }
|
||||
case:
|
||||
unreachable()
|
||||
}
|
||||
}
|
||||
|
||||
buf: bytes.Buffer
|
||||
stream := bytes.buffer_to_stream(&buf)
|
||||
encoder := cbor.Encoder{cbor.ENCODE_FULLY_DETERMINISTIC, stream, {}}
|
||||
|
||||
expect_encoding :: proc(t: ^testing.T, val: cbor.Value, encoded: string, loc := #caller_location) {
|
||||
bytes.buffer_reset(&buf)
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 0)
|
||||
defer bytes.buffer_destroy(&buf)
|
||||
stream := bytes.buffer_to_stream(&buf)
|
||||
encoder := cbor.Encoder{cbor.ENCODE_FULLY_DETERMINISTIC, stream, {}}
|
||||
|
||||
err := cbor.encode(encoder, val)
|
||||
expect_value(t, err, nil, loc)
|
||||
expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)encoded), loc)
|
||||
err := cbor.encode(encoder, val, loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)encoded), loc)
|
||||
}
|
||||
|
||||
expect_streamed_encoding :: proc(t: ^testing.T, encoded: string, values: ..cbor.Value, loc := #caller_location) {
|
||||
bytes.buffer_reset(&buf)
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 0)
|
||||
defer bytes.buffer_destroy(&buf)
|
||||
stream := bytes.buffer_to_stream(&buf)
|
||||
encoder := cbor.Encoder{cbor.ENCODE_FULLY_DETERMINISTIC, stream, {}}
|
||||
|
||||
for value, i in values {
|
||||
err: cbor.Encode_Error
|
||||
@@ -891,15 +814,15 @@ expect_streamed_encoding :: proc(t: ^testing.T, encoded: string, values: ..cbor.
|
||||
if err2 != nil { break }
|
||||
}
|
||||
case:
|
||||
errorf(t, "%v does not support streamed encoding", reflect.union_variant_typeid(value))
|
||||
testing.expectf(t, false, "%v does not support streamed encoding", reflect.union_variant_typeid(value))
|
||||
}
|
||||
|
||||
expect_value(t, err, nil, loc)
|
||||
expect_value(t, err2, nil, loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, err2, nil, loc)
|
||||
}
|
||||
|
||||
err := cbor.encode_stream_end(stream)
|
||||
expect_value(t, err, nil, loc)
|
||||
testing.expect_value(t, err, nil, loc)
|
||||
|
||||
expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)encoded), loc)
|
||||
testing.expect_value(t, fmt.tprint(bytes.buffer_to_bytes(&buf)), fmt.tprint(transmute([]byte)encoded), loc)
|
||||
}
|
||||
|
||||
@@ -2,42 +2,6 @@ package test_core_hex
|
||||
|
||||
import "core:encoding/hex"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
hex_encode(&t)
|
||||
hex_decode(&t)
|
||||
hex_decode_sequence(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
CASES :: [][2]string{
|
||||
{"11", "3131"},
|
||||
@@ -49,10 +13,14 @@ CASES :: [][2]string{
|
||||
hex_encode :: proc(t: ^testing.T) {
|
||||
for test in CASES {
|
||||
encoded := string(hex.encode(transmute([]byte)test[0]))
|
||||
expect(
|
||||
defer delete(encoded)
|
||||
testing.expectf(
|
||||
t,
|
||||
encoded == test[1],
|
||||
fmt.tprintf("encode: %q -> %q (should be: %q)", test[0], encoded, test[1]),
|
||||
"encode: %q -> %q (should be: %q)",
|
||||
test[0],
|
||||
encoded,
|
||||
test[1],
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -61,11 +29,20 @@ hex_encode :: proc(t: ^testing.T) {
|
||||
hex_decode :: proc(t: ^testing.T) {
|
||||
for test in CASES {
|
||||
decoded, ok := hex.decode(transmute([]byte)test[1])
|
||||
expect(t, ok, fmt.tprintf("decode: %q not ok", test[1]))
|
||||
expect(
|
||||
defer delete(decoded)
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
"decode: %q not ok",
|
||||
test[1],
|
||||
)
|
||||
testing.expectf(
|
||||
t,
|
||||
string(decoded) == test[0],
|
||||
fmt.tprintf("decode: %q -> %q (should be: %q)", test[1], string(decoded), test[0]),
|
||||
"decode: %q -> %q (should be: %q)",
|
||||
test[1],
|
||||
string(decoded),
|
||||
test[0],
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -73,20 +50,37 @@ hex_decode :: proc(t: ^testing.T) {
|
||||
@(test)
|
||||
hex_decode_sequence :: proc(t: ^testing.T) {
|
||||
b, ok := hex.decode_sequence("0x23")
|
||||
expect(t, ok, "decode_sequence: 0x23 not ok")
|
||||
expect(t, b == '#', fmt.tprintf("decode_sequence: 0x23 -> %c (should be: %c)", b, '#'))
|
||||
testing.expect(t, ok, "decode_sequence: 0x23 not ok")
|
||||
testing.expectf(
|
||||
t,
|
||||
b == '#',
|
||||
"decode_sequence: 0x23 -> %c (should be: %c)",
|
||||
b,
|
||||
'#',
|
||||
)
|
||||
|
||||
b, ok = hex.decode_sequence("0X3F")
|
||||
expect(t, ok, "decode_sequence: 0X3F not ok")
|
||||
expect(t, b == '?', fmt.tprintf("decode_sequence: 0X3F -> %c (should be: %c)", b, '?'))
|
||||
testing.expect(t, ok, "decode_sequence: 0X3F not ok")
|
||||
testing.expectf(
|
||||
t,
|
||||
b == '?',
|
||||
"decode_sequence: 0X3F -> %c (should be: %c)",
|
||||
b,
|
||||
'?',
|
||||
)
|
||||
|
||||
b, ok = hex.decode_sequence("2a")
|
||||
expect(t, ok, "decode_sequence: 2a not ok")
|
||||
expect(t, b == '*', fmt.tprintf("decode_sequence: 2a -> %c (should be: %c)", b, '*'))
|
||||
testing.expect(t, ok, "decode_sequence: 2a not ok")
|
||||
testing.expectf(t,
|
||||
b == '*',
|
||||
"decode_sequence: 2a -> %c (should be: %c)",
|
||||
b,
|
||||
'*',
|
||||
)
|
||||
|
||||
_, ok = hex.decode_sequence("1")
|
||||
expect(t, !ok, "decode_sequence: 1 should be too short")
|
||||
testing.expect(t, !ok, "decode_sequence: 1 should be too short")
|
||||
|
||||
_, ok = hex.decode_sequence("123")
|
||||
expect(t, !ok, "decode_sequence: 123 should be too long")
|
||||
}
|
||||
testing.expect(t, !ok, "decode_sequence: 123 should be too long")
|
||||
}
|
||||
@@ -6,127 +6,99 @@ package test_core_hxa
|
||||
import "core:encoding/hxa"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
TEAPOT_PATH :: "core/assets/HXA/teapot.hxa"
|
||||
TEAPOT_PATH :: ODIN_ROOT + "tests/core/assets/HXA/teapot.hxa"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_read(&t)
|
||||
test_write(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
import "core:os"
|
||||
|
||||
@test
|
||||
test_read :: proc(t: ^testing.T) {
|
||||
filename := tc.get_data_path(t, TEAPOT_PATH)
|
||||
defer delete(filename)
|
||||
data, _ := os.read_entire_file(TEAPOT_PATH)
|
||||
// file, err := hxa.read_from_file(TEAPOT_PATH)
|
||||
file, err := hxa.read(data)
|
||||
file.backing = data
|
||||
file.allocator = context.allocator
|
||||
hxa.file_destroy(file)
|
||||
// fmt.printfln("%#v", file)
|
||||
|
||||
file, err := hxa.read_from_file(filename)
|
||||
e :: hxa.Read_Error.None
|
||||
tc.expect(t, err == e, fmt.tprintf("%v: read_from_file(%v) -> %v != %v", #procedure, filename, err, e))
|
||||
defer hxa.file_destroy(file)
|
||||
testing.expectf(t, err == e, "read_from_file(%v) -> %v != %v", TEAPOT_PATH, err, e)
|
||||
|
||||
/* Header */
|
||||
tc.expect(t, file.magic_number == 0x417848, fmt.tprintf("%v: file.magic_number %v != %v",
|
||||
#procedure, file.magic_number, 0x417848))
|
||||
tc.expect(t, file.version == 1, fmt.tprintf("%v: file.version %v != %v",
|
||||
#procedure, file.version, 1))
|
||||
tc.expect(t, file.internal_node_count == 1, fmt.tprintf("%v: file.internal_node_count %v != %v",
|
||||
#procedure, file.internal_node_count, 1))
|
||||
testing.expectf(t, file.magic_number == 0x417848, "file.magic_number %v != %v", file.magic_number, 0x417848)
|
||||
testing.expectf(t, file.version == 1, "file.version %v != %v", file.version, 1)
|
||||
testing.expectf(t, file.internal_node_count == 1, "file.internal_node_count %v != %v", file.internal_node_count, 1)
|
||||
|
||||
/* Nodes (only one) */
|
||||
tc.expect(t, len(file.nodes) == 1, fmt.tprintf("%v: len(file.nodes) %v != %v", #procedure, len(file.nodes), 1))
|
||||
testing.expectf(t, len(file.nodes) == 1, "len(file.nodes) %v != %v", len(file.nodes), 1)
|
||||
|
||||
m := &file.nodes[0].meta_data
|
||||
tc.expect(t, len(m^) == 38, fmt.tprintf("%v: len(m^) %v != %v", #procedure, len(m^), 38))
|
||||
testing.expectf(t, len(m^) == 38, "len(m^) %v != %v", len(m^), 38)
|
||||
{
|
||||
e :: "Texture resolution"
|
||||
tc.expect(t, m[0].name == e, fmt.tprintf("%v: m[0].name %v != %v", #procedure, m[0].name, e))
|
||||
testing.expectf(t, m[0].name == e, "m[0].name %v != %v", m[0].name, e)
|
||||
|
||||
m_v, m_v_ok := m[0].value.([]i64le)
|
||||
tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true))
|
||||
tc.expect(t, len(m_v) == 1, fmt.tprintf("%v: len(m_v) %v != %v", #procedure, len(m_v), 1))
|
||||
tc.expect(t, m_v[0] == 1024, fmt.tprintf("%v: m_v[0] %v != %v", #procedure, len(m_v), 1024))
|
||||
testing.expectf(t, m_v_ok, "m_v_ok %v != %v", m_v_ok, true)
|
||||
testing.expectf(t, len(m_v) == 1, "len(m_v) %v != %v", len(m_v), 1)
|
||||
testing.expectf(t, m_v[0] == 1024, "m_v[0] %v != %v", len(m_v), 1024)
|
||||
}
|
||||
{
|
||||
e :: "Validate"
|
||||
tc.expect(t, m[37].name == e, fmt.tprintf("%v: m[37].name %v != %v", #procedure, m[37].name, e))
|
||||
testing.expectf(t, m[37].name == e, "m[37].name %v != %v", m[37].name, e)
|
||||
|
||||
m_v, m_v_ok := m[37].value.([]i64le)
|
||||
tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true))
|
||||
tc.expect(t, len(m_v) == 1, fmt.tprintf("%v: len(m_v) %v != %v", #procedure, len(m_v), 1))
|
||||
tc.expect(t, m_v[0] == -2054847231, fmt.tprintf("%v: m_v[0] %v != %v", #procedure, len(m_v), -2054847231))
|
||||
testing.expectf(t, m_v_ok, "m_v_ok %v != %v", m_v_ok, true)
|
||||
testing.expectf(t, len(m_v) == 1, "len(m_v) %v != %v", len(m_v), 1)
|
||||
testing.expectf(t, m_v[0] == -2054847231, "m_v[0] %v != %v", len(m_v), -2054847231)
|
||||
}
|
||||
|
||||
/* Node content */
|
||||
v, v_ok := file.nodes[0].content.(hxa.Node_Geometry)
|
||||
tc.expect(t, v_ok, fmt.tprintf("%v: v_ok %v != %v", #procedure, v_ok, true))
|
||||
testing.expectf(t, v_ok, "v_ok %v != %v", v_ok, true)
|
||||
|
||||
tc.expect(t, v.vertex_count == 530, fmt.tprintf("%v: v.vertex_count %v != %v", #procedure, v.vertex_count, 530))
|
||||
tc.expect(t, v.edge_corner_count == 2026, fmt.tprintf("%v: v.edge_corner_count %v != %v",
|
||||
#procedure, v.edge_corner_count, 2026))
|
||||
tc.expect(t, v.face_count == 517, fmt.tprintf("%v: v.face_count %v != %v", #procedure, v.face_count, 517))
|
||||
testing.expectf(t, v.vertex_count == 530, "v.vertex_count %v != %v", v.vertex_count, 530)
|
||||
testing.expectf(t, v.edge_corner_count == 2026, "v.edge_corner_count %v != %v", v.edge_corner_count, 2026)
|
||||
testing.expectf(t, v.face_count == 517, "v.face_count %v != %v", v.face_count, 517)
|
||||
|
||||
/* Vertex stack */
|
||||
tc.expect(t, len(v.vertex_stack) == 1, fmt.tprintf("%v: len(v.vertex_stack) %v != %v",
|
||||
#procedure, len(v.vertex_stack), 1))
|
||||
testing.expectf(t, len(v.vertex_stack) == 1, "len(v.vertex_stack) %v != %v", len(v.vertex_stack), 1)
|
||||
{
|
||||
e := "vertex"
|
||||
tc.expect(t, v.vertex_stack[0].name == e, fmt.tprintf("%v: v.vertex_stack[0].name %v != %v",
|
||||
#procedure, v.vertex_stack[0].name, e))
|
||||
testing.expectf(t, v.vertex_stack[0].name == e, "v.vertex_stack[0].name %v != %v", v.vertex_stack[0].name, e)
|
||||
}
|
||||
tc.expect(t, v.vertex_stack[0].components == 3, fmt.tprintf("%v: v.vertex_stack[0].components %v != %v",
|
||||
#procedure, v.vertex_stack[0].components, 3))
|
||||
testing.expectf(t, v.vertex_stack[0].components == 3, "v.vertex_stack[0].components %v != %v", v.vertex_stack[0].components, 3)
|
||||
|
||||
/* Vertex stack data */
|
||||
vs_d, vs_d_ok := v.vertex_stack[0].data.([]f64le)
|
||||
tc.expect(t, vs_d_ok, fmt.tprintf("%v: vs_d_ok %v != %v", #procedure, vs_d_ok, true))
|
||||
tc.expect(t, len(vs_d) == 1590, fmt.tprintf("%v: len(vs_d) %v != %v", #procedure, len(vs_d), 1590))
|
||||
|
||||
tc.expect(t, vs_d[0] == 4.06266, fmt.tprintf("%v: vs_d[0] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[0], vs_d[0], 4.06266, 4.06266))
|
||||
tc.expect(t, vs_d[1] == 2.83457, fmt.tprintf("%v: vs_d[1] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[1], vs_d[1], 2.83457, 2.83457))
|
||||
tc.expect(t, vs_d[2] == 0hbfbc5da6a4441787, fmt.tprintf("%v: vs_d[2] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[2], vs_d[2],
|
||||
0hbfbc5da6a4441787, 0hbfbc5da6a4441787))
|
||||
tc.expect(t, vs_d[3] == 0h4010074fb549f948, fmt.tprintf("%v: vs_d[3] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[3], vs_d[3],
|
||||
0h4010074fb549f948, 0h4010074fb549f948))
|
||||
tc.expect(t, vs_d[1587] == 0h400befa82e87d2c7, fmt.tprintf("%v: vs_d[1587] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[1587], vs_d[1587],
|
||||
0h400befa82e87d2c7, 0h400befa82e87d2c7))
|
||||
tc.expect(t, vs_d[1588] == 2.83457, fmt.tprintf("%v: vs_d[1588] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[1588], vs_d[1588], 2.83457, 2.83457))
|
||||
tc.expect(t, vs_d[1589] == -1.56121, fmt.tprintf("%v: vs_d[1589] %v (%h) != %v (%h)",
|
||||
#procedure, vs_d[1589], vs_d[1589], -1.56121, -1.56121))
|
||||
testing.expectf(t, vs_d_ok, "vs_d_ok %v != %v", vs_d_ok, true)
|
||||
testing.expectf(t, len(vs_d) == 1590, "len(vs_d) %v != %v", len(vs_d), 1590)
|
||||
testing.expectf(t, vs_d[0] == 4.06266, "vs_d[0] %v (%h) != %v (%h)", vs_d[0], vs_d[0], 4.06266, 4.06266)
|
||||
testing.expectf(t, vs_d[1] == 2.83457, "vs_d[1] %v (%h) != %v (%h)", vs_d[1], vs_d[1], 2.83457, 2.83457)
|
||||
testing.expectf(t, vs_d[2] == 0hbfbc5da6a4441787, "vs_d[2] %v (%h) != %v (%h)", vs_d[2], vs_d[2], 0hbfbc5da6a4441787, 0hbfbc5da6a4441787)
|
||||
testing.expectf(t, vs_d[3] == 0h4010074fb549f948, "vs_d[3] %v (%h) != %v (%h)", vs_d[3], vs_d[3], 0h4010074fb549f948, 0h4010074fb549f948)
|
||||
testing.expectf(t, vs_d[1587] == 0h400befa82e87d2c7, "vs_d[1587] %v (%h) != %v (%h)", vs_d[1587], vs_d[1587], 0h400befa82e87d2c7, 0h400befa82e87d2c7)
|
||||
testing.expectf(t, vs_d[1588] == 2.83457, "vs_d[1588] %v (%h) != %v (%h)", vs_d[1588], vs_d[1588], 2.83457, 2.83457)
|
||||
testing.expectf(t, vs_d[1589] == -1.56121, "vs_d[1589] %v (%h) != %v (%h)", vs_d[1589], vs_d[1589], -1.56121, -1.56121)
|
||||
|
||||
/* Corner stack */
|
||||
tc.expect(t, len(v.corner_stack) == 1,
|
||||
fmt.tprintf("%v: len(v.corner_stack) %v != %v", #procedure, len(v.corner_stack), 1))
|
||||
testing.expectf(t, len(v.corner_stack) == 1, "len(v.corner_stack) %v != %v", len(v.corner_stack), 1)
|
||||
{
|
||||
e := "reference"
|
||||
tc.expect(t, v.corner_stack[0].name == e, fmt.tprintf("%v: v.corner_stack[0].name %v != %v",
|
||||
#procedure, v.corner_stack[0].name, e))
|
||||
testing.expectf(t, v.corner_stack[0].name == e, "v.corner_stack[0].name %v != %v", v.corner_stack[0].name, e)
|
||||
}
|
||||
tc.expect(t, v.corner_stack[0].components == 1, fmt.tprintf("%v: v.corner_stack[0].components %v != %v",
|
||||
#procedure, v.corner_stack[0].components, 1))
|
||||
testing.expectf(t, v.corner_stack[0].components == 1, "v.corner_stack[0].components %v != %v", v.corner_stack[0].components, 1)
|
||||
|
||||
/* Corner stack data */
|
||||
cs_d, cs_d_ok := v.corner_stack[0].data.([]i32le)
|
||||
tc.expect(t, cs_d_ok, fmt.tprintf("%v: cs_d_ok %v != %v", #procedure, cs_d_ok, true))
|
||||
tc.expect(t, len(cs_d) == 2026, fmt.tprintf("%v: len(cs_d) %v != %v", #procedure, len(cs_d), 2026))
|
||||
tc.expect(t, cs_d[0] == 6, fmt.tprintf("%v: cs_d[0] %v != %v", #procedure, cs_d[0], 6))
|
||||
tc.expect(t, cs_d[2025] == -32, fmt.tprintf("%v: cs_d[2025] %v != %v", #procedure, cs_d[2025], -32))
|
||||
testing.expectf(t, cs_d_ok, "cs_d_ok %v != %v", cs_d_ok, true)
|
||||
testing.expectf(t, len(cs_d) == 2026, "len(cs_d) %v != %v", len(cs_d), 2026)
|
||||
testing.expectf(t, cs_d[0] == 6, "cs_d[0] %v != %v", cs_d[0], 6)
|
||||
testing.expectf(t, cs_d[2025] == -32, "cs_d[2025] %v != %v", cs_d[2025], -32)
|
||||
|
||||
/* Edge and face stacks (empty) */
|
||||
tc.expect(t, len(v.edge_stack) == 0, fmt.tprintf("%v: len(v.edge_stack) %v != %v",
|
||||
#procedure, len(v.edge_stack), 0))
|
||||
tc.expect(t, len(v.face_stack) == 0, fmt.tprintf("%v: len(v.face_stack) %v != %v",
|
||||
#procedure, len(v.face_stack), 0))
|
||||
testing.expectf(t, len(v.edge_stack) == 0, "len(v.edge_stack) %v != %v", len(v.edge_stack), 0)
|
||||
testing.expectf(t, len(v.face_stack) == 0, "len(v.face_stack) %v != %v", len(v.face_stack), 0)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -154,72 +126,72 @@ test_write :: proc(t: ^testing.T) {
|
||||
|
||||
n, write_err := hxa.write(buf, w_file)
|
||||
write_e :: hxa.Write_Error.None
|
||||
tc.expect(t, write_err == write_e, fmt.tprintf("%v: write_err %v != %v", #procedure, write_err, write_e))
|
||||
tc.expect(t, n == required_size, fmt.tprintf("%v: n %v != %v", #procedure, n, required_size))
|
||||
testing.expectf(t, write_err == write_e, fmt.tprintf("write_err %v != %v", write_err, write_e))
|
||||
testing.expectf(t, n == required_size, fmt.tprintf("n %v != %v", n, required_size))
|
||||
|
||||
file, read_err := hxa.read(buf)
|
||||
read_e :: hxa.Read_Error.None
|
||||
tc.expect(t, read_err == read_e, fmt.tprintf("%v: read_err %v != %v", #procedure, read_err, read_e))
|
||||
testing.expectf(t, read_err == read_e, fmt.tprintf("read_err %v != %v", read_err, read_e))
|
||||
defer hxa.file_destroy(file)
|
||||
|
||||
tc.expect(t, file.magic_number == 0x417848, fmt.tprintf("%v: file.magic_number %v != %v",
|
||||
#procedure, file.magic_number, 0x417848))
|
||||
tc.expect(t, file.version == 3, fmt.tprintf("%v: file.version %v != %v", #procedure, file.version, 3))
|
||||
tc.expect(t, file.internal_node_count == 1, fmt.tprintf("%v: file.internal_node_count %v != %v",
|
||||
#procedure, file.internal_node_count, 1))
|
||||
testing.expectf(t, file.magic_number == 0x417848, fmt.tprintf("file.magic_number %v != %v",
|
||||
file.magic_number, 0x417848))
|
||||
testing.expectf(t, file.version == 3, fmt.tprintf("file.version %v != %v", file.version, 3))
|
||||
testing.expectf(t, file.internal_node_count == 1, fmt.tprintf("file.internal_node_count %v != %v",
|
||||
file.internal_node_count, 1))
|
||||
|
||||
tc.expect(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("%v: len(file.nodes) %v != %v",
|
||||
#procedure, len(file.nodes), len(w_file.nodes)))
|
||||
testing.expectf(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("len(file.nodes) %v != %v",
|
||||
len(file.nodes), len(w_file.nodes)))
|
||||
|
||||
m := &file.nodes[0].meta_data
|
||||
w_m := &w_file.nodes[0].meta_data
|
||||
tc.expect(t, len(m^) == len(w_m^), fmt.tprintf("%v: len(m^) %v != %v", #procedure, len(m^), len(w_m^)))
|
||||
tc.expect(t, m[0].name == w_m[0].name, fmt.tprintf("%v: m[0].name %v != %v", #procedure, m[0].name, w_m[0].name))
|
||||
testing.expectf(t, len(m^) == len(w_m^), fmt.tprintf("len(m^) %v != %v", len(m^), len(w_m^)))
|
||||
testing.expectf(t, m[0].name == w_m[0].name, fmt.tprintf("m[0].name %v != %v", m[0].name, w_m[0].name))
|
||||
|
||||
m_v, m_v_ok := m[0].value.([]f64le)
|
||||
tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true))
|
||||
tc.expect(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v: %v != len(m_v) %v",
|
||||
#procedure, len(m_v), len(n1_m1_value)))
|
||||
testing.expectf(t, m_v_ok, fmt.tprintf("m_v_ok %v != %v", m_v_ok, true))
|
||||
testing.expectf(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v != len(m_v) %v",
|
||||
len(m_v), len(n1_m1_value)))
|
||||
for i := 0; i < len(m_v); i += 1 {
|
||||
tc.expect(t, m_v[i] == n1_m1_value[i], fmt.tprintf("%v: m_v[%d] %v != %v",
|
||||
#procedure, i, m_v[i], n1_m1_value[i]))
|
||||
testing.expectf(t, m_v[i] == n1_m1_value[i], fmt.tprintf("m_v[%d] %v != %v",
|
||||
i, m_v[i], n1_m1_value[i]))
|
||||
}
|
||||
|
||||
v, v_ok := file.nodes[0].content.(hxa.Node_Image)
|
||||
tc.expect(t, v_ok, fmt.tprintf("%v: v_ok %v != %v", #procedure, v_ok, true))
|
||||
tc.expect(t, v.type == n1_content.type, fmt.tprintf("%v: v.type %v != %v", #procedure, v.type, n1_content.type))
|
||||
tc.expect(t, len(v.resolution) == 3, fmt.tprintf("%v: len(v.resolution) %v != %v",
|
||||
#procedure, len(v.resolution), 3))
|
||||
tc.expect(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("%v: len(v.image_stack) %v != %v",
|
||||
#procedure, len(v.image_stack), len(n1_content.image_stack)))
|
||||
testing.expectf(t, v_ok, fmt.tprintf("v_ok %v != %v", v_ok, true))
|
||||
testing.expectf(t, v.type == n1_content.type, fmt.tprintf("v.type %v != %v", v.type, n1_content.type))
|
||||
testing.expectf(t, len(v.resolution) == 3, fmt.tprintf("len(v.resolution) %v != %v",
|
||||
len(v.resolution), 3))
|
||||
testing.expectf(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("len(v.image_stack) %v != %v",
|
||||
len(v.image_stack), len(n1_content.image_stack)))
|
||||
for i := 0; i < len(v.image_stack); i += 1 {
|
||||
tc.expect(t, v.image_stack[i].name == n1_content.image_stack[i].name,
|
||||
fmt.tprintf("%v: v.image_stack[%d].name %v != %v",
|
||||
#procedure, i, v.image_stack[i].name, n1_content.image_stack[i].name))
|
||||
tc.expect(t, v.image_stack[i].components == n1_content.image_stack[i].components,
|
||||
fmt.tprintf("%v: v.image_stack[%d].components %v != %v",
|
||||
#procedure, i, v.image_stack[i].components, n1_content.image_stack[i].components))
|
||||
testing.expectf(t, v.image_stack[i].name == n1_content.image_stack[i].name,
|
||||
fmt.tprintf("v.image_stack[%d].name %v != %v",
|
||||
i, v.image_stack[i].name, n1_content.image_stack[i].name))
|
||||
testing.expectf(t, v.image_stack[i].components == n1_content.image_stack[i].components,
|
||||
fmt.tprintf("v.image_stack[%d].components %v != %v",
|
||||
i, v.image_stack[i].components, n1_content.image_stack[i].components))
|
||||
|
||||
switch n1_t in n1_content.image_stack[i].data {
|
||||
case []u8:
|
||||
tc.expect(t, false, fmt.tprintf("%v: n1_content.image_stack[i].data []u8", #procedure))
|
||||
testing.expectf(t, false, fmt.tprintf("n1_content.image_stack[i].data []u8", #procedure))
|
||||
case []i32le:
|
||||
tc.expect(t, false, fmt.tprintf("%v: n1_content.image_stack[i].data []i32le", #procedure))
|
||||
testing.expectf(t, false, fmt.tprintf("n1_content.image_stack[i].data []i32le", #procedure))
|
||||
case []f32le:
|
||||
l, l_ok := v.image_stack[i].data.([]f32le)
|
||||
tc.expect(t, l_ok, fmt.tprintf("%v: l_ok %v != %v", #procedure, l_ok, true))
|
||||
tc.expect(t, len(l) == len(n1_t), fmt.tprintf("%v: len(l) %v != %v", #procedure, len(l), len(n1_t)))
|
||||
testing.expectf(t, l_ok, fmt.tprintf("l_ok %v != %v", l_ok, true))
|
||||
testing.expectf(t, len(l) == len(n1_t), fmt.tprintf("len(l) %v != %v", len(l), len(n1_t)))
|
||||
for j := 0; j < len(l); j += 1 {
|
||||
tc.expect(t, l[j] == n1_t[j], fmt.tprintf("%v: l[%d] %v (%h) != %v (%h)",
|
||||
#procedure, j, l[j], l[j], n1_t[j], n1_t[j]))
|
||||
testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v (%h) != %v (%h)",
|
||||
j, l[j], l[j], n1_t[j], n1_t[j]))
|
||||
}
|
||||
case []f64le:
|
||||
l, l_ok := v.image_stack[i].data.([]f64le)
|
||||
tc.expect(t, l_ok, fmt.tprintf("%v: l_ok %v != %v", #procedure, l_ok, true))
|
||||
tc.expect(t, len(l) == len(n1_t), fmt.tprintf("%v: len(l) %v != %v", #procedure, len(l), len(n1_t)))
|
||||
testing.expectf(t, l_ok, fmt.tprintf("l_ok %v != %v", l_ok, true))
|
||||
testing.expectf(t, len(l) == len(n1_t), fmt.tprintf("len(l) %v != %v", len(l), len(n1_t)))
|
||||
for j := 0; j < len(l); j += 1 {
|
||||
tc.expect(t, l[j] == n1_t[j], fmt.tprintf("%v: l[%d] %v != %v", #procedure, j, l[j], n1_t[j]))
|
||||
testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v != %v", j, l[j], n1_t[j]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,46 +2,8 @@ package test_core_json
|
||||
|
||||
import "core:encoding/json"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:mem/virtual"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
parse_json(&t)
|
||||
marshal_json(&t)
|
||||
unmarshal_json(&t)
|
||||
surrogate(&t)
|
||||
utf8_string_of_multibyte_characters(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
parse_json :: proc(t: ^testing.T) {
|
||||
|
||||
@@ -72,10 +34,9 @@ parse_json :: proc(t: ^testing.T) {
|
||||
}
|
||||
`
|
||||
|
||||
_, err := json.parse(transmute([]u8)json_data)
|
||||
|
||||
msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
val, err := json.parse(transmute([]u8)json_data)
|
||||
json.destroy_value(val)
|
||||
testing.expectf(t, err == nil, "Expected `json.parse` to return nil, got %v", err)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -83,7 +44,7 @@ out_of_memory_in_parse_json :: proc(t: ^testing.T) {
|
||||
arena: virtual.Arena
|
||||
arena_buffer: [256]byte
|
||||
arena_init_error := virtual.arena_init_buffer(&arena, arena_buffer[:])
|
||||
testing.expect(t, arena_init_error == nil, fmt.tprintf("Expected arena initialization to not return error, got: %v\n", arena_init_error))
|
||||
testing.expectf(t, arena_init_error == nil, "Expected arena initialization to not return error, got: %v\n", arena_init_error)
|
||||
|
||||
context.allocator = virtual.arena_allocator(&arena)
|
||||
|
||||
@@ -114,11 +75,11 @@ out_of_memory_in_parse_json :: proc(t: ^testing.T) {
|
||||
}
|
||||
`
|
||||
|
||||
_, err := json.parse(transmute([]u8)json_data)
|
||||
val, err := json.parse(transmute([]u8)json_data)
|
||||
json.destroy_value(val)
|
||||
|
||||
expected_error := json.Error.Out_Of_Memory
|
||||
msg := fmt.tprintf("Expected `json.parse` to fail with %v, got %v", expected_error, err)
|
||||
expect(t, err == json.Error.Out_Of_Memory, msg)
|
||||
testing.expectf(t, err == json.Error.Out_Of_Memory, "Expected `json.parse` to fail with %v, got %v", expected_error, err)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -134,9 +95,9 @@ marshal_json :: proc(t: ^testing.T) {
|
||||
b = 5,
|
||||
}
|
||||
|
||||
_, err := json.marshal(my_struct)
|
||||
msg := fmt.tprintf("Expected `json.marshal` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
data, err := json.marshal(my_struct)
|
||||
defer delete(data)
|
||||
testing.expectf(t, err == nil, "Expected `json.marshal` to return nil, got %v", err)
|
||||
}
|
||||
|
||||
PRODUCTS := `
|
||||
@@ -378,17 +339,12 @@ unmarshal_json :: proc(t: ^testing.T) {
|
||||
err := json.unmarshal(transmute([]u8)PRODUCTS, &g, json.DEFAULT_SPECIFICATION)
|
||||
defer cleanup(g)
|
||||
|
||||
msg := fmt.tprintf("Expected `json.unmarshal` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
|
||||
msg = fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products))
|
||||
expect(t, len(g.products) == len(original_data.products), msg)
|
||||
|
||||
msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash)
|
||||
expect(t, original_data.cash == g.cash, msg)
|
||||
testing.expectf(t, err == nil, "Expected `json.unmarshal` to return nil, got %v", err)
|
||||
testing.expectf(t, len(g.products) == len(original_data.products), "Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products))
|
||||
testing.expectf(t, original_data.cash == g.cash, "Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash)
|
||||
|
||||
for p, i in g.products {
|
||||
expect(t, p == original_data.products[i], "Producted unmarshaled improperly")
|
||||
testing.expect(t, p == original_data.products[i], "Producted unmarshaled improperly")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,17 +353,19 @@ surrogate :: proc(t: ^testing.T) {
|
||||
input := `+ + * 😃 - /`
|
||||
|
||||
out, err := json.marshal(input)
|
||||
expect(t, err == nil, fmt.tprintf("Expected `json.marshal(%q)` to return a nil error, got %v", input, err))
|
||||
defer delete(out)
|
||||
testing.expectf(t, err == nil, "Expected `json.marshal(%q)` to return a nil error, got %v", input, err)
|
||||
|
||||
back: string
|
||||
uerr := json.unmarshal(out, &back)
|
||||
expect(t, uerr == nil, fmt.tprintf("Expected `json.unmarshal(%q)` to return a nil error, got %v", string(out), uerr))
|
||||
expect(t, back == input, fmt.tprintf("Expected `json.unmarshal(%q)` to return %q, got %v", string(out), input, uerr))
|
||||
defer delete(back)
|
||||
testing.expectf(t, uerr == nil, "Expected `json.unmarshal(%q)` to return a nil error, got %v", string(out), uerr)
|
||||
testing.expectf(t, back == input, "Expected `json.unmarshal(%q)` to return %q, got %v", string(out), input, uerr)
|
||||
}
|
||||
|
||||
@test
|
||||
utf8_string_of_multibyte_characters :: proc(t: ^testing.T) {
|
||||
_, err := json.parse_string(`"🐛✅"`)
|
||||
msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
}
|
||||
val, err := json.parse_string(`"🐛✅"`)
|
||||
defer json.destroy_value(val)
|
||||
testing.expectf(t, err == nil, "Expected `json.parse` to return nil, got %v", err)
|
||||
}
|
||||
@@ -2,110 +2,74 @@ package test_core_varint
|
||||
|
||||
import "core:encoding/varint"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:slice"
|
||||
import "core:math/rand"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
RANDOM_TESTS :: 100
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_leb128(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
NUM_RANDOM_TESTS_PER_BYTE_SIZE :: 10_000
|
||||
|
||||
@(test)
|
||||
test_leb128 :: proc(t: ^testing.T) {
|
||||
test_uleb :: proc(t: ^testing.T) {
|
||||
buf: [varint.LEB128_MAX_BYTES]u8
|
||||
|
||||
for vector in ULEB_Vectors {
|
||||
val, size, err := varint.decode_uleb128(vector.encoded)
|
||||
|
||||
msg := fmt.tprintf("Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size)
|
||||
expect(t, size == vector.size && val == vector.value, msg)
|
||||
|
||||
msg = fmt.tprintf("Expected decoder to return error %v, got %v for vector %v", vector.error, err, vector)
|
||||
expect(t, err == vector.error, msg)
|
||||
testing.expectf(t, size == vector.size && val == vector.value, "Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size)
|
||||
testing.expectf(t, err == vector.error, "Expected decoder to return error %v, got %v for vector %v", vector.error, err, vector)
|
||||
|
||||
if err == .None { // Try to roundtrip
|
||||
size, err = varint.encode_uleb128(buf[:], vector.value)
|
||||
|
||||
msg = fmt.tprintf("Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size])
|
||||
expect(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), msg)
|
||||
testing.expectf(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), "Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_ileb :: proc(t: ^testing.T) {
|
||||
buf: [varint.LEB128_MAX_BYTES]u8
|
||||
|
||||
for vector in ILEB_Vectors {
|
||||
val, size, err := varint.decode_ileb128(vector.encoded)
|
||||
|
||||
msg := fmt.tprintf("Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size)
|
||||
expect(t, size == vector.size && val == vector.value, msg)
|
||||
|
||||
msg = fmt.tprintf("Expected decoder to return error %v, got %v", vector.error, err)
|
||||
expect(t, err == vector.error, msg)
|
||||
testing.expectf(t, size == vector.size && val == vector.value, "Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size)
|
||||
testing.expectf(t, err == vector.error, "Expected decoder to return error %v, got %v", vector.error, err)
|
||||
|
||||
if err == .None { // Try to roundtrip
|
||||
size, err = varint.encode_ileb128(buf[:], vector.value)
|
||||
|
||||
msg = fmt.tprintf("Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size])
|
||||
expect(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), msg)
|
||||
testing.expectf(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), "Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_random :: proc(t: ^testing.T) {
|
||||
buf: [varint.LEB128_MAX_BYTES]u8
|
||||
|
||||
for num_bytes in 1..=uint(16) {
|
||||
for _ in 0..=RANDOM_TESTS {
|
||||
for _ in 0..=NUM_RANDOM_TESTS_PER_BYTE_SIZE {
|
||||
unsigned, signed := get_random(num_bytes)
|
||||
|
||||
{
|
||||
encode_size, encode_err := varint.encode_uleb128(buf[:], unsigned)
|
||||
msg := fmt.tprintf("%v failed to encode as an unsigned LEB128 value, got %v", unsigned, encode_err)
|
||||
expect(t, encode_err == .None, msg)
|
||||
testing.expectf(t, encode_err == .None, "%v failed to encode as an unsigned LEB128 value, got %v", unsigned, encode_err)
|
||||
|
||||
decoded, decode_size, decode_err := varint.decode_uleb128(buf[:])
|
||||
msg = fmt.tprintf("Expected %02x to decode as %v, got %v", buf[:encode_size], unsigned, decoded)
|
||||
expect(t, decode_err == .None && decode_size == encode_size && decoded == unsigned, msg)
|
||||
testing.expectf(t, decode_err == .None && decode_size == encode_size && decoded == unsigned, "Expected %02x to decode as %v, got %v", buf[:encode_size], unsigned, decoded)
|
||||
}
|
||||
|
||||
{
|
||||
encode_size, encode_err := varint.encode_ileb128(buf[:], signed)
|
||||
msg := fmt.tprintf("%v failed to encode as a signed LEB128 value, got %v", signed, encode_err)
|
||||
expect(t, encode_err == .None, msg)
|
||||
testing.expectf(t, encode_err == .None, "%v failed to encode as a signed LEB128 value, got %v", signed, encode_err)
|
||||
|
||||
decoded, decode_size, decode_err := varint.decode_ileb128(buf[:])
|
||||
msg = fmt.tprintf("Expected %02x to decode as %v, got %v, err: %v", buf[:encode_size], signed, decoded, decode_err)
|
||||
expect(t, decode_err == .None && decode_size == encode_size && decoded == signed, msg)
|
||||
testing.expectf(t, decode_err == .None && decode_size == encode_size && decoded == signed, "Expected %02x to decode as %v, got %v, err: %v", buf[:encode_size], signed, decoded, decode_err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(private)
|
||||
get_random :: proc(byte_count: uint) -> (u: u128, i: i128) {
|
||||
assert(byte_count >= 0 && byte_count <= size_of(u128))
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ package test_core_xml
|
||||
|
||||
import "core:encoding/xml"
|
||||
import "core:testing"
|
||||
import "core:mem"
|
||||
import "core:strings"
|
||||
import "core:io"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:hash"
|
||||
|
||||
Silent :: proc(pos: xml.Pos, format: string, args: ..any) {}
|
||||
@@ -14,9 +14,6 @@ OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, },
|
||||
expected_doctype = "",
|
||||
}
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
TEST :: struct {
|
||||
filename: string,
|
||||
options: xml.Options,
|
||||
@@ -24,22 +21,14 @@ TEST :: struct {
|
||||
crc32: u32,
|
||||
}
|
||||
|
||||
/*
|
||||
Relative to ODIN_ROOT
|
||||
*/
|
||||
TEST_FILE_PATH_PREFIX :: "tests/core/assets"
|
||||
TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/"
|
||||
|
||||
TESTS :: []TEST{
|
||||
/*
|
||||
First we test that certain files parse without error.
|
||||
*/
|
||||
|
||||
{
|
||||
/*
|
||||
Tests UTF-8 idents and values.
|
||||
Test namespaced ident.
|
||||
Tests that nested partial CDATA start doesn't trip up parser.
|
||||
*/
|
||||
@(test)
|
||||
xml_test_utf8_normal :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
// Tests UTF-8 idents and values.
|
||||
// Test namespaced ident.
|
||||
// Tests that nested partial CDATA start doesn't trip up parser.
|
||||
filename = "XML/utf8.xml",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -48,13 +37,14 @@ TESTS :: []TEST{
|
||||
expected_doctype = "恥ずべきフクロウ",
|
||||
},
|
||||
crc32 = 0xe9b62f03,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
Same as above.
|
||||
Unbox CDATA in data tag.
|
||||
*/
|
||||
@(test)
|
||||
xml_test_utf8_unbox_cdata :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
// Same as above.
|
||||
// Unbox CDATA in data tag.
|
||||
filename = "XML/utf8.xml",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -63,13 +53,14 @@ TESTS :: []TEST{
|
||||
expected_doctype = "恥ずべきフクロウ",
|
||||
},
|
||||
crc32 = 0x9c2643ed,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
Simple Qt TS translation file.
|
||||
`core:i18n` requires it to be parsed properly.
|
||||
*/
|
||||
@(test)
|
||||
xml_test_nl_qt_ts :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
// Simple Qt TS translation file.
|
||||
// `core:i18n` requires it to be parsed properly.
|
||||
filename = "I18N/nl_NL-qt-ts.ts",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -78,13 +69,14 @@ TESTS :: []TEST{
|
||||
expected_doctype = "TS",
|
||||
},
|
||||
crc32 = 0x859b7443,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
Simple XLiff 1.2 file.
|
||||
`core:i18n` requires it to be parsed properly.
|
||||
*/
|
||||
@(test)
|
||||
xml_test_xliff_1_2 :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
// Simple XLiff 1.2 file.
|
||||
// `core:i18n` requires it to be parsed properly.
|
||||
filename = "I18N/nl_NL-xliff-1.2.xliff",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -93,13 +85,14 @@ TESTS :: []TEST{
|
||||
expected_doctype = "xliff",
|
||||
},
|
||||
crc32 = 0x3deaf329,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
Simple XLiff 2.0 file.
|
||||
`core:i18n` requires it to be parsed properly.
|
||||
*/
|
||||
@(test)
|
||||
xml_test_xliff_2_0 :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
// Simple XLiff 2.0 file.
|
||||
// `core:i18n` requires it to be parsed properly.
|
||||
filename = "I18N/nl_NL-xliff-2.0.xliff",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -108,9 +101,12 @@ TESTS :: []TEST{
|
||||
expected_doctype = "xliff",
|
||||
},
|
||||
crc32 = 0x0c55e287,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@(test)
|
||||
xml_test_entities :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
filename = "XML/entities.html",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -119,9 +115,12 @@ TESTS :: []TEST{
|
||||
expected_doctype = "html",
|
||||
},
|
||||
crc32 = 0x05373317,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@(test)
|
||||
xml_test_entities_unbox :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
filename = "XML/entities.html",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -130,9 +129,12 @@ TESTS :: []TEST{
|
||||
expected_doctype = "html",
|
||||
},
|
||||
crc32 = 0x3b6d4a90,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@(test)
|
||||
xml_test_entities_unbox_decode :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
filename = "XML/entities.html",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -141,12 +143,12 @@ TESTS :: []TEST{
|
||||
expected_doctype = "html",
|
||||
},
|
||||
crc32 = 0x5be2ffdc,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
Then we test that certain errors are returned as expected.
|
||||
*/
|
||||
{
|
||||
@(test)
|
||||
xml_test_invalid_doctype :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
filename = "XML/utf8.xml",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -156,12 +158,12 @@ TESTS :: []TEST{
|
||||
},
|
||||
err = .Invalid_DocType,
|
||||
crc32 = 0x49b83d0a,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
Parse the 9.08 MiB unicode.xml for good measure.
|
||||
*/
|
||||
{
|
||||
@(test)
|
||||
xml_test_unicode :: proc(t: ^testing.T) {
|
||||
run_test(t, {
|
||||
filename = "XML/unicode.xml",
|
||||
options = {
|
||||
flags = {
|
||||
@@ -171,39 +173,37 @@ TESTS :: []TEST{
|
||||
},
|
||||
err = .None,
|
||||
crc32 = 0x0b6100ab,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
@(private)
|
||||
run_test :: proc(t: ^testing.T, test: TEST) {
|
||||
path := strings.concatenate({TEST_SUITE_PATH, test.filename})
|
||||
defer delete(path)
|
||||
|
||||
doc, err := xml.load_from_file(path, test.options, Silent)
|
||||
defer xml.destroy(doc)
|
||||
|
||||
tree_string := doc_to_string(doc)
|
||||
tree_bytes := transmute([]u8)tree_string
|
||||
defer delete(tree_bytes)
|
||||
|
||||
crc32 := hash.crc32(tree_bytes)
|
||||
|
||||
failed := err != test.err
|
||||
testing.expectf(t, err == test.err, "%v: Expected return value %v, got %v", test.filename, test.err, err)
|
||||
|
||||
failed |= crc32 != test.crc32
|
||||
testing.expectf(t, crc32 == test.crc32, "%v: Expected CRC 0x%08x, got 0x%08x, with options %v", test.filename, test.crc32, crc32, test.options)
|
||||
|
||||
if failed {
|
||||
// Don't fully print big trees.
|
||||
tree_string = tree_string[:min(2_048, len(tree_string))]
|
||||
log.error(tree_string)
|
||||
}
|
||||
}
|
||||
|
||||
test_file_path :: proc(filename: string) -> (path: string) {
|
||||
|
||||
path = fmt.tprintf("%v%v/%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename)
|
||||
temp := transmute([]u8)path
|
||||
|
||||
for r, i in path {
|
||||
if r == '\\' {
|
||||
temp[i] = '/'
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
@(private)
|
||||
doc_to_string :: proc(doc: ^xml.Document) -> (result: string) {
|
||||
/*
|
||||
Effectively a clone of the debug printer in the xml package.
|
||||
@@ -284,56 +284,4 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) {
|
||||
|
||||
print(strings.to_writer(&buf), doc)
|
||||
return strings.clone(strings.to_string(buf))
|
||||
}
|
||||
|
||||
@test
|
||||
run_tests :: proc(t: ^testing.T) {
|
||||
for test in TESTS {
|
||||
path := test_file_path(test.filename)
|
||||
log(t, fmt.tprintf("Trying to parse %v", path))
|
||||
|
||||
doc, err := xml.load_from_file(path, test.options, Silent)
|
||||
defer xml.destroy(doc)
|
||||
|
||||
tree_string := doc_to_string(doc)
|
||||
tree_bytes := transmute([]u8)tree_string
|
||||
defer delete(tree_bytes)
|
||||
|
||||
crc32 := hash.crc32(tree_bytes)
|
||||
|
||||
failed := err != test.err
|
||||
err_msg := fmt.tprintf("Expected return value %v, got %v", test.err, err)
|
||||
expect(t, err == test.err, err_msg)
|
||||
|
||||
failed |= crc32 != test.crc32
|
||||
err_msg = fmt.tprintf("Expected CRC 0x%08x, got 0x%08x, with options %v", test.crc32, crc32, test.options)
|
||||
expect(t, crc32 == test.crc32, err_msg)
|
||||
|
||||
if failed {
|
||||
/*
|
||||
Don't fully print big trees.
|
||||
*/
|
||||
tree_string = tree_string[:min(2_048, len(tree_string))]
|
||||
fmt.println(tree_string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
run_tests(&t)
|
||||
|
||||
if len(track.allocation_map) > 0 {
|
||||
for _, v in track.allocation_map {
|
||||
err_msg := fmt.tprintf("%v Leaked %v bytes.", v.location, v.size)
|
||||
expect(&t, false, err_msg)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
}
|
||||
@@ -2,48 +2,9 @@ package test_core_fmt
|
||||
|
||||
import "base:runtime"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
import "core:math"
|
||||
import "core:mem"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_fmt_memory(&t)
|
||||
test_fmt_doc_examples(&t)
|
||||
test_fmt_options(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) {
|
||||
got := fmt.tprintf(format, ..args)
|
||||
expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc)
|
||||
}
|
||||
import "core:testing"
|
||||
|
||||
@(test)
|
||||
test_fmt_memory :: proc(t: ^testing.T) {
|
||||
@@ -141,7 +102,7 @@ test_fmt_doc_examples :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_fmt_options :: proc(t: ^testing.T) {
|
||||
test_fmt_escaping_prefixes :: proc(t: ^testing.T) {
|
||||
// Escaping
|
||||
check(t, "% { } 0 { } } {", "%% {{ }} {} {{ }} }} {{", 0 )
|
||||
|
||||
@@ -152,7 +113,10 @@ test_fmt_options :: proc(t: ^testing.T) {
|
||||
check(t, "+3", "%+i", 3 )
|
||||
check(t, "0b11", "%#b", 3 )
|
||||
check(t, "0xA", "%#X", 10 )
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_fmt_indexing :: proc(t: ^testing.T) {
|
||||
// Specific index formatting
|
||||
check(t, "1 2 3", "%i %i %i", 1, 2, 3)
|
||||
check(t, "1 2 3", "%[0]i %[1]i %[2]i", 1, 2, 3)
|
||||
@@ -161,7 +125,10 @@ test_fmt_options :: proc(t: ^testing.T) {
|
||||
check(t, "1 2 3", "%i %[1]i %i", 1, 2, 3)
|
||||
check(t, "1 3 2", "%i %[2]i %i", 1, 2, 3)
|
||||
check(t, "1 1 1", "%[0]i %[0]i %[0]i", 1)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_fmt_width_precision :: proc(t: ^testing.T) {
|
||||
// Width
|
||||
check(t, "3.140", "%f", 3.14)
|
||||
check(t, "3.140", "%4f", 3.14)
|
||||
@@ -199,7 +166,10 @@ test_fmt_options :: proc(t: ^testing.T) {
|
||||
check(t, "3.140", "%*[1].*[2][0]f", 3.14, 5, 3)
|
||||
check(t, "3.140", "%*[2].*[1]f", 3.14, 3, 5)
|
||||
check(t, "3.140", "%5.*[1]f", 3.14, 3)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_fmt_arg_errors :: proc(t: ^testing.T) {
|
||||
// Error checking
|
||||
check(t, "%!(MISSING ARGUMENT)%!(NO VERB)", "%" )
|
||||
|
||||
@@ -222,7 +192,10 @@ test_fmt_options :: proc(t: ^testing.T) {
|
||||
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)%!(EXTRA 0)", "%[1]", 0)
|
||||
|
||||
check(t, "3.1%!(EXTRA 3.14)", "%.1f", 3.14, 3.14)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_fmt_python_syntax :: proc(t: ^testing.T) {
|
||||
// Python-like syntax
|
||||
check(t, "1 2 3", "{} {} {}", 1, 2, 3)
|
||||
check(t, "3 2 1", "{2} {1} {0}", 1, 2, 3)
|
||||
@@ -247,3 +220,9 @@ test_fmt_options :: proc(t: ^testing.T) {
|
||||
check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{", 1)
|
||||
check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{0", 1 )
|
||||
}
|
||||
|
||||
@(private)
|
||||
check :: proc(t: ^testing.T, exp: string, format: string, args: ..any) {
|
||||
got := fmt.tprintf(format, ..args)
|
||||
testing.expectf(t, got == exp, "(%q, %v): %q != %q", format, args, got, exp)
|
||||
}
|
||||
@@ -2,201 +2,12 @@ package test_core_hash
|
||||
|
||||
import "core:hash/xxhash"
|
||||
import "core:hash"
|
||||
import "core:time"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:math/rand"
|
||||
import "base:intrinsics"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_benchmark_runner(&t)
|
||||
test_crc64_vectors(&t)
|
||||
test_xxhash_vectors(&t)
|
||||
test_xxhash_large(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Benchmarks
|
||||
*/
|
||||
|
||||
setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
options.input = make([]u8, options.bytes, allocator)
|
||||
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||
}
|
||||
|
||||
teardown_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
delete(options.input)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u32
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH32(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u64
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH64(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh3_64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u64
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH3_64(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
|
||||
h: u128
|
||||
for _ in 0..=options.rounds {
|
||||
h = xxhash.XXH3_128(buf)
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
options.hash = h
|
||||
return nil
|
||||
}
|
||||
|
||||
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
|
||||
fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
time.duration_nanoseconds(options.duration),
|
||||
options.rounds_per_second,
|
||||
options.megabytes_per_second,
|
||||
)
|
||||
}
|
||||
|
||||
@test
|
||||
test_benchmark_runner :: proc(t: ^testing.T) {
|
||||
fmt.println("Starting benchmarks:")
|
||||
|
||||
name := "XXH32 100 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 100,
|
||||
setup = setup_xxhash,
|
||||
bench = benchmark_xxh32,
|
||||
teardown = teardown_xxhash,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x85f6413c, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH32 1 MiB zero bytes"
|
||||
options.bytes = 1_048_576
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x9430f97f, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH64 100 zero bytes"
|
||||
options.bytes = 100
|
||||
options.bench = benchmark_xxh64
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x17bb1103c92c502f, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH64 1 MiB zero bytes"
|
||||
options.bytes = 1_048_576
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x87d2a1b6e1163ef1, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH3_64 100 zero bytes"
|
||||
options.bytes = 100
|
||||
options.bench = benchmark_xxh3_64
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x801fedc74ccd608c, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH3_64 1 MiB zero bytes"
|
||||
options.bytes = 1_048_576
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x918780b90550bf34, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH3_128 100 zero bytes"
|
||||
options.bytes = 100
|
||||
options.bench = benchmark_xxh3_128
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "XXH3_128 1 MiB zero bytes"
|
||||
options.bytes = 1_048_576
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
@test
|
||||
test_xxhash_large :: proc(t: ^testing.T) {
|
||||
test_xxhash_zero_fixed :: proc(t: ^testing.T) {
|
||||
many_zeroes := make([]u8, 16 * 1024 * 1024)
|
||||
defer delete(many_zeroes)
|
||||
|
||||
@@ -204,62 +15,45 @@ test_xxhash_large :: proc(t: ^testing.T) {
|
||||
for i, v in ZERO_VECTORS {
|
||||
b := many_zeroes[:i]
|
||||
|
||||
fmt.printf("[test_xxhash_large] All at once. Size: %v\n", i)
|
||||
|
||||
xxh32 := xxhash.XXH32(b)
|
||||
xxh64 := xxhash.XXH64(b)
|
||||
xxh3_64 := xxhash.XXH3_64(b)
|
||||
xxh3_128 := xxhash.XXH3_128(b)
|
||||
|
||||
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
|
||||
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
|
||||
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
|
||||
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
|
||||
|
||||
expect(t, xxh32 == v.xxh_32, xxh32_error)
|
||||
expect(t, xxh64 == v.xxh_64, xxh64_error)
|
||||
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
|
||||
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
|
||||
testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
|
||||
testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
|
||||
testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
|
||||
testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
|
||||
}
|
||||
}
|
||||
|
||||
when #config(RAND_STATE, -1) >= 0 && #config(RAND_INC, -1) >= 0 {
|
||||
random_seed := rand.Rand{
|
||||
state = u64(#config(RAND_STATE, -1)),
|
||||
inc = u64(#config(RAND_INC, -1)),
|
||||
}
|
||||
fmt.printf("Using user-selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc)
|
||||
} else {
|
||||
random_seed := rand.create(u64(intrinsics.read_cycle_counter()))
|
||||
fmt.printf("Randonly selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc)
|
||||
}
|
||||
@(test)
|
||||
test_xxhash_zero_streamed_random_updates :: proc(t: ^testing.T) {
|
||||
many_zeroes := make([]u8, 16 * 1024 * 1024)
|
||||
defer delete(many_zeroes)
|
||||
|
||||
// Streamed
|
||||
for i, v in ZERO_VECTORS {
|
||||
b := many_zeroes[:i]
|
||||
|
||||
fmt.printf("[test_xxhash_large] Streamed. Size: %v\n", i)
|
||||
|
||||
// bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47}
|
||||
// update_size_idx: int
|
||||
|
||||
xxh_32_state, xxh_32_err := xxhash.XXH32_create_state()
|
||||
defer xxhash.XXH32_destroy_state(xxh_32_state)
|
||||
expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state.")
|
||||
testing.expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state")
|
||||
|
||||
xxh_64_state, xxh_64_err := xxhash.XXH64_create_state()
|
||||
defer xxhash.XXH64_destroy_state(xxh_64_state)
|
||||
expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state.")
|
||||
testing.expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state")
|
||||
|
||||
xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state()
|
||||
defer xxhash.XXH3_destroy_state(xxh3_64_state)
|
||||
expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state.")
|
||||
testing.expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state")
|
||||
|
||||
xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state()
|
||||
defer xxhash.XXH3_destroy_state(xxh3_128_state)
|
||||
expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state.")
|
||||
testing.expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state")
|
||||
|
||||
// XXH3_128_update
|
||||
|
||||
random_seed := rand.create(t.seed)
|
||||
for len(b) > 0 {
|
||||
update_size := min(len(b), rand.int_max(8192, &random_seed))
|
||||
if update_size > 4096 {
|
||||
@@ -281,28 +75,19 @@ test_xxhash_large :: proc(t: ^testing.T) {
|
||||
xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state)
|
||||
xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state)
|
||||
|
||||
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
|
||||
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
|
||||
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
|
||||
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
|
||||
|
||||
expect(t, xxh32 == v.xxh_32, xxh32_error)
|
||||
expect(t, xxh64 == v.xxh_64, xxh64_error)
|
||||
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
|
||||
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
|
||||
testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
|
||||
testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
|
||||
testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
|
||||
testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_xxhash_vectors :: proc(t: ^testing.T) {
|
||||
fmt.println("Verifying against XXHASH_TEST_VECTOR_SEEDED:")
|
||||
|
||||
test_xxhash_seeded :: proc(t: ^testing.T) {
|
||||
buf := make([]u8, 256)
|
||||
defer delete(buf)
|
||||
|
||||
for seed, table in XXHASH_TEST_VECTOR_SEEDED {
|
||||
fmt.printf("\tSeed: %v\n", seed)
|
||||
|
||||
for v, i in table {
|
||||
b := buf[:i]
|
||||
|
||||
@@ -311,60 +96,48 @@ test_xxhash_vectors :: proc(t: ^testing.T) {
|
||||
xxh3_64 := xxhash.XXH3_64(b, seed)
|
||||
xxh3_128 := xxhash.XXH3_128(b, seed)
|
||||
|
||||
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
|
||||
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
|
||||
|
||||
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
|
||||
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
|
||||
|
||||
expect(t, xxh32 == v.xxh_32, xxh32_error)
|
||||
expect(t, xxh64 == v.xxh_64, xxh64_error)
|
||||
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
|
||||
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
|
||||
testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
|
||||
testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
|
||||
testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
|
||||
testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
|
||||
|
||||
if len(b) > xxhash.XXH3_MIDSIZE_MAX {
|
||||
fmt.printf("XXH3 - size: %v\n", len(b))
|
||||
|
||||
xxh3_state, _ := xxhash.XXH3_create_state()
|
||||
xxhash.XXH3_64_reset_with_seed(xxh3_state, seed)
|
||||
xxhash.XXH3_64_update(xxh3_state, b)
|
||||
xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state)
|
||||
xxhash.XXH3_destroy_state(xxh3_state)
|
||||
xxh3_64s_error := fmt.tprintf("[XXH3_64s(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64_streamed)
|
||||
expect(t, xxh3_64_streamed == v.xxh3_64, xxh3_64s_error)
|
||||
testing.expectf(t, xxh3_64_streamed == v.xxh3_64, "[XXH3_64s(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64_streamed)
|
||||
|
||||
xxh3_state2, _ := xxhash.XXH3_create_state()
|
||||
xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed)
|
||||
xxhash.XXH3_128_update(xxh3_state2, b)
|
||||
xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2)
|
||||
xxhash.XXH3_destroy_state(xxh3_state2)
|
||||
xxh3_128s_error := fmt.tprintf("[XXH3_128s(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128_streamed)
|
||||
expect(t, xxh3_128_streamed == v.xxh3_128, xxh3_128s_error)
|
||||
testing.expectf(t, xxh3_128_streamed == v.xxh3_128, "[XXH3_128s(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128_streamed)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_xxhash_secret :: proc(t: ^testing.T) {
|
||||
buf := make([]u8, 256)
|
||||
defer delete(buf)
|
||||
|
||||
fmt.println("Verifying against XXHASH_TEST_VECTOR_SECRET:")
|
||||
for secret, table in XXHASH_TEST_VECTOR_SECRET {
|
||||
fmt.printf("\tSecret:\n\t\t\"%v\"\n", secret)
|
||||
|
||||
secret_bytes := transmute([]u8)secret
|
||||
|
||||
for v, i in table {
|
||||
b := buf[:i]
|
||||
|
||||
xxh3_128 := xxhash.XXH3_128(b, secret_bytes)
|
||||
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d)] Expected: %32x. Got: %32x.", i, v.xxh3_128_secret, xxh3_128)
|
||||
|
||||
expect(t, xxh3_128 == v.xxh3_128_secret, xxh3_128_error)
|
||||
testing.expectf(t, xxh3_128 == v.xxh3_128_secret, "[XXH3_128(%03d)] Expected: %32x, got: %32x", i, v.xxh3_128_secret, xxh3_128)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_crc64_vectors :: proc(t: ^testing.T) {
|
||||
fmt.println("Verifying CRC-64:")
|
||||
|
||||
vectors := map[string][4]u64 {
|
||||
"123456789" = {
|
||||
0x6c40df5f0b497347, // ECMA-182,
|
||||
@@ -379,23 +152,18 @@ test_crc64_vectors :: proc(t: ^testing.T) {
|
||||
0xe7fcf1006b503b61, // ISO 3306, input and output inverted
|
||||
},
|
||||
}
|
||||
defer delete(vectors)
|
||||
|
||||
for vector, expected in vectors {
|
||||
fmt.println("\tVector:", vector)
|
||||
b := transmute([]u8)vector
|
||||
ecma := hash.crc64_ecma_182(b)
|
||||
xz := hash.crc64_xz(b)
|
||||
iso := hash.crc64_iso_3306(b)
|
||||
iso2 := hash.crc64_iso_3306_inverse(b)
|
||||
|
||||
ecma_error := fmt.tprintf("[ CRC-64 ECMA ] Expected: %016x. Got: %016x.", expected[0], ecma)
|
||||
xz_error := fmt.tprintf("[ CRC-64 XZ ] Expected: %016x. Got: %016x.", expected[1], xz)
|
||||
iso_error := fmt.tprintf("[ CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[2], iso)
|
||||
iso2_error := fmt.tprintf("[~CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[3], iso2)
|
||||
|
||||
expect(t, ecma == expected[0], ecma_error)
|
||||
expect(t, xz == expected[1], xz_error)
|
||||
expect(t, iso == expected[2], iso_error)
|
||||
expect(t, iso2 == expected[3], iso2_error)
|
||||
testing.expectf(t, ecma == expected[0], "[ CRC-64 ECMA ] Expected: %016x, got: %016x", expected[0], ecma)
|
||||
testing.expectf(t, xz == expected[1], "[ CRC-64 XZ ] Expected: %016x, got: %016x", expected[1], xz)
|
||||
testing.expectf(t, iso == expected[2], "[ CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[2], iso)
|
||||
testing.expectf(t, iso2 == expected[3], "[~CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[3], iso2)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
Hash Test Vectors
|
||||
*/
|
||||
// Hash Test Vectors
|
||||
package test_core_hash
|
||||
|
||||
XXHASH_Test_Vectors :: struct #packed {
|
||||
@@ -6789,4 +6787,4 @@ XXHASH_TEST_VECTOR_SECRET := map[string][257]XXHASH_Test_Vectors_With_Secret{
|
||||
/* XXH3_128_with_secret */ 0x0f9b41191242ade48bbde48dff0d38ec,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,2 @@
|
||||
@echo off
|
||||
pushd ..
|
||||
odin run image
|
||||
popd
|
||||
@echo off
|
||||
odin test . -define:ODIN_TEST_TRACK_MEMORY=true -define:ODIN_TEST_PROGRESS_WIDTH=12 -vet -strict-style
|
||||
|
||||
@@ -20,49 +20,14 @@ import "core:image/tga"
|
||||
|
||||
import "core:bytes"
|
||||
import "core:hash"
|
||||
import "core:fmt"
|
||||
import "core:strings"
|
||||
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:time"
|
||||
|
||||
import "base:runtime"
|
||||
TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/PNG/"
|
||||
|
||||
TEST_SUITE_PATH :: "assets/PNG"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
I_Error :: image.Error
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
png_test(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
PNG_Test :: struct {
|
||||
file: string,
|
||||
tests: []struct {
|
||||
@@ -72,7 +37,6 @@ PNG_Test :: struct {
|
||||
hash: u32,
|
||||
},
|
||||
}
|
||||
|
||||
Default :: image.Options{}
|
||||
Alpha_Add :: image.Options{.alpha_add_if_missing}
|
||||
Premul_Drop :: image.Options{.alpha_premultiply, .alpha_drop_if_present}
|
||||
@@ -82,7 +46,7 @@ Blend_BG_Keep :: image.Options{.blend_background, .alpha_add_if_missing}
|
||||
Return_Metadata :: image.Options{.return_metadata}
|
||||
No_Channel_Expansion :: image.Options{.do_not_expand_channels, .return_metadata}
|
||||
|
||||
PNG_Dims :: struct {
|
||||
PNG_Dims :: struct {
|
||||
width: int,
|
||||
height: int,
|
||||
channels: int,
|
||||
@@ -1430,81 +1394,94 @@ Expected_Text := map[string]map[string]png.Text {
|
||||
}
|
||||
|
||||
@test
|
||||
png_test :: proc(t: ^testing.T) {
|
||||
|
||||
total_tests := 0
|
||||
total_expected := 235
|
||||
|
||||
PNG_Suites := [][]PNG_Test{
|
||||
Basic_PNG_Tests,
|
||||
Interlaced_PNG_Tests,
|
||||
Odd_Sized_PNG_Tests,
|
||||
PNG_bKGD_Tests,
|
||||
PNG_tRNS_Tests,
|
||||
PNG_Filter_Tests,
|
||||
PNG_Varied_IDAT_Tests,
|
||||
PNG_ZLIB_Levels_Tests,
|
||||
PNG_sPAL_Tests,
|
||||
PNG_Ancillary_Tests,
|
||||
Corrupt_PNG_Tests,
|
||||
|
||||
No_Postprocesing_Tests,
|
||||
|
||||
}
|
||||
|
||||
for suite in PNG_Suites {
|
||||
total_tests += run_png_suite(t, suite)
|
||||
}
|
||||
|
||||
error := fmt.tprintf("Expected %v PNG tests, %v ran.", total_expected, total_tests)
|
||||
expect(t, total_tests == total_expected, error)
|
||||
png_test_basic :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, Basic_PNG_Tests)
|
||||
}
|
||||
|
||||
run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
@test
|
||||
png_test_interlaced :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, Interlaced_PNG_Tests)
|
||||
}
|
||||
|
||||
context = runtime.default_context()
|
||||
@test
|
||||
png_test_odd_sized :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, Odd_Sized_PNG_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_bKGD :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_bKGD_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_tRNS :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_tRNS_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_sPAL :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_sPAL_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_filter :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_Filter_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_varied_idat :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_Varied_IDAT_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_zlib_levels :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_ZLIB_Levels_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_ancillary :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, PNG_Ancillary_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_corrupt :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, Corrupt_PNG_Tests)
|
||||
}
|
||||
|
||||
@test
|
||||
png_test_no_postproc :: proc(t: ^testing.T) {
|
||||
run_png_suite(t, No_Postprocesing_Tests)
|
||||
}
|
||||
|
||||
run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) {
|
||||
for file in suite {
|
||||
test_file := strings.concatenate({TEST_SUITE_PATH, "/", file.file, ".png"}, context.temp_allocator)
|
||||
test_file := strings.concatenate({TEST_SUITE_PATH, file.file, ".png"})
|
||||
defer delete(test_file)
|
||||
|
||||
img: ^png.Image
|
||||
err: png.Error
|
||||
|
||||
count := 0
|
||||
for test in file.tests {
|
||||
count += 1
|
||||
subtotal += 1
|
||||
passed := false
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
count += 1
|
||||
|
||||
img, err = png.load(test_file, test.options)
|
||||
|
||||
error := fmt.tprintf("%v failed with %v.", test_file, err)
|
||||
|
||||
passed = (test.expected_error == nil && err == nil) || (test.expected_error == err)
|
||||
|
||||
expect(t, passed, error)
|
||||
passed := (test.expected_error == nil && err == nil) || (test.expected_error == err)
|
||||
testing.expectf(t, passed, "%v failed with %v.", test_file, err)
|
||||
|
||||
if err == nil { // No point in running the other tests if it didn't load.
|
||||
pixels := bytes.buffer_to_bytes(&img.pixels)
|
||||
|
||||
// This struct compare fails at -opt:2 if PNG_Dims is not #packed.
|
||||
|
||||
dims := PNG_Dims{img.width, img.height, img.channels, img.depth}
|
||||
error = fmt.tprintf("%v has %v, expected: %v.", file.file, dims, test.dims)
|
||||
|
||||
dims := PNG_Dims{img.width, img.height, img.channels, img.depth}
|
||||
dims_pass := test.dims == dims
|
||||
|
||||
expect(t, dims_pass, error)
|
||||
|
||||
testing.expectf(t, dims_pass, "%v has %v, expected: %v.", file.file, dims, test.dims)
|
||||
passed &= dims_pass
|
||||
|
||||
png_hash := hash.crc32(pixels)
|
||||
error = fmt.tprintf("%v test %v hash is %08x, expected %08x with %v.", file.file, count, png_hash, test.hash, test.options)
|
||||
expect(t, test.hash == png_hash, error)
|
||||
png_hash := hash.crc32(pixels)
|
||||
testing.expectf(t, test.hash == png_hash, "%v test %v hash is %08x, expected %08x with %v.", file.file, count, png_hash, test.hash, test.options)
|
||||
|
||||
passed &= test.hash == png_hash
|
||||
|
||||
@@ -1515,19 +1492,16 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
defer bytes.buffer_destroy(&qoi_buffer)
|
||||
qoi_save_err := qoi.save(&qoi_buffer, img)
|
||||
|
||||
error = fmt.tprintf("%v test %v QOI save failed with %v.", file.file, count, qoi_save_err)
|
||||
expect(t, qoi_save_err == nil, error)
|
||||
testing.expectf(t, qoi_save_err == nil, "%v test %v QOI save failed with %v.", file.file, count, qoi_save_err)
|
||||
|
||||
if qoi_save_err == nil {
|
||||
qoi_img, qoi_load_err := qoi.load(qoi_buffer.buf[:])
|
||||
defer qoi.destroy(qoi_img)
|
||||
|
||||
error = fmt.tprintf("%v test %v QOI load failed with %v.", file.file, count, qoi_load_err)
|
||||
expect(t, qoi_load_err == nil, error)
|
||||
testing.expectf(t, qoi_load_err == nil, "%v test %v QOI load failed with %v.", file.file, count, qoi_load_err)
|
||||
|
||||
qoi_hash := hash.crc32(qoi_img.pixels.buf[:])
|
||||
error = fmt.tprintf("%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options)
|
||||
expect(t, qoi_hash == png_hash, error)
|
||||
testing.expectf(t, qoi_hash == png_hash, "%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1537,19 +1511,15 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
defer bytes.buffer_destroy(&tga_buffer)
|
||||
tga_save_err := tga.save(&tga_buffer, img)
|
||||
|
||||
error = fmt.tprintf("%v test %v TGA save failed with %v.", file.file, count, tga_save_err)
|
||||
expect(t, tga_save_err == nil, error)
|
||||
|
||||
testing.expectf(t, tga_save_err == nil, "%v test %v TGA save failed with %v.", file.file, count, tga_save_err)
|
||||
if tga_save_err == nil {
|
||||
tga_img, tga_load_err := tga.load(tga_buffer.buf[:])
|
||||
defer tga.destroy(tga_img)
|
||||
|
||||
error = fmt.tprintf("%v test %v TGA load failed with %v.", file.file, count, tga_load_err)
|
||||
expect(t, tga_load_err == nil, error)
|
||||
testing.expectf(t, tga_load_err == nil, "%v test %v TGA load failed with %v.", file.file, count, tga_load_err)
|
||||
|
||||
tga_hash := hash.crc32(tga_img.pixels.buf[:])
|
||||
error = fmt.tprintf("%v test %v TGA load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, tga_hash, png_hash, test.options)
|
||||
expect(t, tga_hash == png_hash, error)
|
||||
testing.expectf(t, tga_hash == png_hash, "%v test %v TGA load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, tga_hash, png_hash, test.options)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1558,22 +1528,18 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
pbm_buf, pbm_save_err := pbm.save_to_buffer(img)
|
||||
defer delete(pbm_buf)
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err)
|
||||
expect(t, pbm_save_err == nil, error)
|
||||
testing.expectf(t, pbm_save_err == nil, "%v test %v PBM save failed with %v.", file.file, count, pbm_save_err)
|
||||
|
||||
if pbm_save_err == nil {
|
||||
// Try to load it again.
|
||||
pbm_img, pbm_load_err := pbm.load(pbm_buf)
|
||||
defer pbm.destroy(pbm_img)
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err)
|
||||
expect(t, pbm_load_err == nil, error)
|
||||
testing.expectf(t, pbm_load_err == nil, "%v test %v PBM load failed with %v.", file.file, count, pbm_load_err)
|
||||
|
||||
if pbm_load_err == nil {
|
||||
pbm_hash := hash.crc32(pbm_img.pixels.buf[:])
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options)
|
||||
expect(t, pbm_hash == png_hash, error)
|
||||
testing.expectf(t, pbm_hash == png_hash, "%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1587,22 +1553,18 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
pbm_buf, pbm_save_err := pbm.save_to_buffer(img, pbm_info)
|
||||
defer delete(pbm_buf)
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err)
|
||||
expect(t, pbm_save_err == nil, error)
|
||||
testing.expectf(t, pbm_save_err == nil, "%v test %v PBM save failed with %v.", file.file, count, pbm_save_err)
|
||||
|
||||
if pbm_save_err == nil {
|
||||
// Try to load it again.
|
||||
pbm_img, pbm_load_err := pbm.load(pbm_buf)
|
||||
defer pbm.destroy(pbm_img)
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err)
|
||||
expect(t, pbm_load_err == nil, error)
|
||||
testing.expectf(t, pbm_load_err == nil, "%v test %v PBM load failed with %v.", file.file, count, pbm_load_err)
|
||||
|
||||
if pbm_load_err == nil {
|
||||
pbm_hash := hash.crc32(pbm_img.pixels.buf[:])
|
||||
|
||||
error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options)
|
||||
expect(t, pbm_hash == png_hash, error)
|
||||
testing.expectf(t, pbm_hash == png_hash, "%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1655,21 +1617,18 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
float_pbm_buf, float_pbm_save_err := pbm.save_to_buffer(float_img, pbm_info)
|
||||
defer delete(float_pbm_buf)
|
||||
|
||||
error = fmt.tprintf("%v test %v save as PFM failed with %v", file.file, count, float_pbm_save_err)
|
||||
expect(t, float_pbm_save_err == nil, error)
|
||||
testing.expectf(t, float_pbm_save_err == nil, "%v test %v save as PFM failed with %v", file.file, count, float_pbm_save_err)
|
||||
|
||||
if float_pbm_save_err == nil {
|
||||
// Load float image and compare.
|
||||
float_pbm_img, float_pbm_load_err := pbm.load(float_pbm_buf)
|
||||
defer pbm.destroy(float_pbm_img)
|
||||
|
||||
error = fmt.tprintf("%v test %v PFM load failed with %v", file.file, count, float_pbm_load_err)
|
||||
expect(t, float_pbm_load_err == nil, error)
|
||||
testing.expectf(t, float_pbm_load_err == nil, "%v test %v PFM load failed with %v", file.file, count, float_pbm_load_err)
|
||||
|
||||
load_float := mem.slice_data_cast([]f32, float_pbm_img.pixels.buf[:])
|
||||
|
||||
error = fmt.tprintf("%v test %v PFM load returned %v floats, expected %v", file.file, count, len(load_float), len(orig_float))
|
||||
expect(t, len(load_float) == len(orig_float), error)
|
||||
testing.expectf(t, len(load_float) == len(orig_float), "%v test %v PFM load returned %v floats, expected %v", file.file, count, len(load_float), len(orig_float))
|
||||
|
||||
// Compare floats
|
||||
equal := true
|
||||
@@ -1679,15 +1638,13 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
break
|
||||
}
|
||||
}
|
||||
error = fmt.tprintf("%v test %v PFM loaded floats to match", file.file, count)
|
||||
expect(t, equal, error)
|
||||
testing.expectf(t, equal, "%v test %v PFM loaded floats to match", file.file, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if .return_metadata in test.options {
|
||||
|
||||
if v, ok := img.metadata.(^image.PNG_Info); ok {
|
||||
for c in v.chunks {
|
||||
#partial switch(c.header.type) {
|
||||
@@ -1696,8 +1653,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
case "pp0n2c16", "pp0n6a08":
|
||||
gamma, gamma_ok := png.gamma(c)
|
||||
expected_gamma := f32(1.0)
|
||||
error = fmt.tprintf("%v test %v gAMA is %v, expected %v.", file.file, count, gamma, expected_gamma)
|
||||
expect(t, gamma == expected_gamma && gamma_ok, error)
|
||||
testing.expectf(t, gamma == expected_gamma && gamma_ok, "%v test %v gAMA is %v, expected %v.", file.file, count, gamma, expected_gamma)
|
||||
}
|
||||
case .PLTE:
|
||||
switch(file.file) {
|
||||
@@ -1705,8 +1661,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
plte, plte_ok := png.plte(c)
|
||||
|
||||
expected_plte_len := u16(216)
|
||||
error = fmt.tprintf("%v test %v PLTE length is %v, expected %v.", file.file, count, plte.used, expected_plte_len)
|
||||
expect(t, expected_plte_len == plte.used && plte_ok, error)
|
||||
testing.expectf(t, expected_plte_len == plte.used && plte_ok, "%v test %v PLTE length is %v, expected %v.", file.file, count, plte.used, expected_plte_len)
|
||||
}
|
||||
case .sPLT:
|
||||
switch(file.file) {
|
||||
@@ -1714,12 +1669,10 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
splt, splt_ok := png.splt(c)
|
||||
|
||||
expected_splt_len := u16(216)
|
||||
error = fmt.tprintf("%v test %v sPLT length is %v, expected %v.", file.file, count, splt.used, expected_splt_len)
|
||||
expect(t, expected_splt_len == splt.used && splt_ok, error)
|
||||
testing.expectf(t, expected_splt_len == splt.used && splt_ok, "%v test %v sPLT length is %v, expected %v.", file.file, count, splt.used, expected_splt_len)
|
||||
|
||||
expected_splt_name := "six-cube"
|
||||
error = fmt.tprintf("%v test %v sPLT name is %v, expected %v.", file.file, count, splt.name, expected_splt_name)
|
||||
expect(t, expected_splt_name == splt.name && splt_ok, error)
|
||||
testing.expectf(t, expected_splt_name == splt.name && splt_ok, "%v test %v sPLT name is %v, expected %v.", file.file, count, splt.name, expected_splt_name)
|
||||
|
||||
png.splt_destroy(splt)
|
||||
}
|
||||
@@ -1733,48 +1686,37 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
g = png.CIE_1931{x = 0.3000, y = 0.6000},
|
||||
b = png.CIE_1931{x = 0.1500, y = 0.0600},
|
||||
}
|
||||
error = fmt.tprintf("%v test %v cHRM is %v, expected %v.", file.file, count, chrm, expected_chrm)
|
||||
expect(t, expected_chrm == chrm && chrm_ok, error)
|
||||
testing.expectf(t, expected_chrm == chrm && chrm_ok, "%v test %v cHRM is %v, expected %v.", file.file, count, chrm, expected_chrm)
|
||||
}
|
||||
case .pHYs:
|
||||
phys, phys_ok := png.phys(c)
|
||||
phys_err := "%v test %v cHRM is %v, expected %v."
|
||||
switch (file.file) {
|
||||
case "cdfn2c08":
|
||||
expected_phys := png.pHYs{ppu_x = 1, ppu_y = 4, unit = .Unknown}
|
||||
error = fmt.tprintf(phys_err, file.file, count, phys, expected_phys)
|
||||
expect(t, expected_phys == phys && phys_ok, error)
|
||||
testing.expectf(t, expected_phys == phys && phys_ok, "%v test %v cHRM is %v, expected %v.", file.file, count, phys, expected_phys)
|
||||
case "cdhn2c08":
|
||||
expected_phys := png.pHYs{ppu_x = 4, ppu_y = 1, unit = .Unknown}
|
||||
error = fmt.tprintf(phys_err, file.file, count, phys, expected_phys)
|
||||
expect(t, expected_phys == phys && phys_ok, error)
|
||||
testing.expectf(t, expected_phys == phys && phys_ok, "%v test %v cHRM is %v, expected %v.", file.file, count, phys, expected_phys)
|
||||
case "cdsn2c08":
|
||||
expected_phys := png.pHYs{ppu_x = 1, ppu_y = 1, unit = .Unknown}
|
||||
error = fmt.tprintf(phys_err, file.file, count, phys, expected_phys)
|
||||
expect(t, expected_phys == phys && phys_ok, error)
|
||||
testing.expectf(t, expected_phys == phys && phys_ok, "%v test %v cHRM is %v, expected %v.", file.file, count, phys, expected_phys)
|
||||
case "cdun2c08":
|
||||
expected_phys := png.pHYs{ppu_x = 1000, ppu_y = 1000, unit = .Meter}
|
||||
error = fmt.tprintf(phys_err, file.file, count, phys, expected_phys)
|
||||
expect(t, expected_phys == phys && phys_ok, error)
|
||||
testing.expectf(t, expected_phys == phys && phys_ok, "%v test %v cHRM is %v, expected %v.", file.file, count, phys, expected_phys)
|
||||
}
|
||||
case .hIST:
|
||||
hist, hist_ok := png.hist(c)
|
||||
hist_err := "%v test %v hIST has %v entries, expected %v."
|
||||
switch (file.file) {
|
||||
case "ch1n3p04":
|
||||
error = fmt.tprintf(hist_err, file.file, count, hist.used, 15)
|
||||
expect(t, hist.used == 15 && hist_ok, error)
|
||||
testing.expectf(t, hist.used == 15 && hist_ok, "%v test %v hIST has %v entries, expected %v.", file.file, count, hist.used, 15)
|
||||
case "ch2n3p08":
|
||||
error = fmt.tprintf(hist_err, file.file, count, hist.used, 256)
|
||||
expect(t, hist.used == 256 && hist_ok, error)
|
||||
testing.expectf(t, hist.used == 256 && hist_ok, "%v test %v hIST has %v entries, expected %v.", file.file, count, hist.used, 256)
|
||||
}
|
||||
case .tIME:
|
||||
png_time, png_time_ok := png.time(c)
|
||||
time_err := "%v test %v tIME was %v, expected %v."
|
||||
expected_time: png.tIME
|
||||
|
||||
core_time, core_time_ok := png.core_time(c)
|
||||
time_core_err := "%v test %v tIME->core:time is %v, expected %v."
|
||||
expected_core: time.Time
|
||||
|
||||
switch(file.file) {
|
||||
@@ -1789,14 +1731,10 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
expected_core = time.Time{_nsec = 946684799000000000}
|
||||
|
||||
}
|
||||
error = fmt.tprintf(time_err, file.file, count, png_time, expected_time)
|
||||
expect(t, png_time == expected_time && png_time_ok, error)
|
||||
|
||||
error = fmt.tprintf(time_core_err, file.file, count, core_time, expected_core)
|
||||
expect(t, core_time == expected_core && core_time_ok, error)
|
||||
testing.expectf(t, png_time == expected_time && png_time_ok, "%v test %v tIME was %v, expected %v.", file.file, count, png_time, expected_time)
|
||||
testing.expectf(t, core_time == expected_core && core_time_ok, "%v test %v tIME->core:time is %v, expected %v.", file.file, count, core_time, expected_core)
|
||||
case .sBIT:
|
||||
sbit, sbit_ok := png.sbit(c)
|
||||
sbit_err := "%v test %v sBIT was %v, expected %v."
|
||||
expected_sbit: [4]u8
|
||||
|
||||
switch (file.file) {
|
||||
@@ -1815,8 +1753,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
case "cdfn2c08", "cdhn2c08", "cdsn2c08", "cdun2c08", "ch1n3p04", "basn3p04":
|
||||
expected_sbit = [4]u8{ 4, 4, 4, 0}
|
||||
}
|
||||
error = fmt.tprintf(sbit_err, file.file, count, sbit, expected_sbit)
|
||||
expect(t, sbit == expected_sbit && sbit_ok, error)
|
||||
testing.expectf(t, sbit == expected_sbit && sbit_ok, "%v test %v sBIT was %v, expected %v.", file.file, count, sbit, expected_sbit)
|
||||
case .tEXt, .zTXt:
|
||||
text, text_ok := png.text(c)
|
||||
defer png.text_destroy(text)
|
||||
@@ -1828,8 +1765,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test_text := Expected_Text[file.file][text.keyword].text
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text.text, test_text)
|
||||
expect(t, text.text == test_text && text_ok, error)
|
||||
testing.expectf(t, text.text == test_text && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text.text, test_text)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1842,74 +1778,59 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test := Expected_Text[file.file][text.keyword]
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
expect(t, text.language == test.language && text_ok, error)
|
||||
expect(t, text.keyword_localized == test.keyword_localized && text_ok, error)
|
||||
testing.expectf(t, text.language == test.language && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.keyword_localized == test.keyword_localized && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
}
|
||||
}
|
||||
case "ctfn0g04": // international UTF-8, finnish
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test := Expected_Text[file.file][text.keyword]
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
expect(t, text.text == test.text && text_ok, error)
|
||||
expect(t, text.language == test.language && text_ok, error)
|
||||
expect(t, text.keyword_localized == test.keyword_localized && text_ok, error)
|
||||
testing.expectf(t, text.text == test.text && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.language == test.language && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.keyword_localized == test.keyword_localized && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
}
|
||||
}
|
||||
case "ctgn0g04": // international UTF-8, greek
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test := Expected_Text[file.file][text.keyword]
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
expect(t, text.text == test.text && text_ok, error)
|
||||
expect(t, text.language == test.language && text_ok, error)
|
||||
expect(t, text.keyword_localized == test.keyword_localized && text_ok, error)
|
||||
testing.expectf(t, text.text == test.text && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.language == test.language && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.keyword_localized == test.keyword_localized && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
}
|
||||
}
|
||||
case "cthn0g04": // international UTF-8, hindi
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test := Expected_Text[file.file][text.keyword]
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
expect(t, text.text == test.text && text_ok, error)
|
||||
expect(t, text.language == test.language && text_ok, error)
|
||||
expect(t, text.keyword_localized == test.keyword_localized && text_ok, error)
|
||||
testing.expectf(t, text.text == test.text && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.language == test.language && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.keyword_localized == test.keyword_localized && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
}
|
||||
}
|
||||
case "ctjn0g04": // international UTF-8, japanese
|
||||
if file.file in Expected_Text {
|
||||
if text.keyword in Expected_Text[file.file] {
|
||||
test := Expected_Text[file.file][text.keyword]
|
||||
error = fmt.tprintf("%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
expect(t, text.text == test.text && text_ok, error)
|
||||
expect(t, text.language == test.language && text_ok, error)
|
||||
expect(t, text.keyword_localized == test.keyword_localized && text_ok, error)
|
||||
testing.expectf(t, text.text == test.text && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.language == test.language && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
testing.expectf(t, text.keyword_localized == test.keyword_localized && text_ok, "%v test %v text keyword {{%v}}:'%v', expected '%v'.", file.file, count, text.keyword, text, test)
|
||||
}
|
||||
}
|
||||
}
|
||||
case .eXIf:
|
||||
if file.file == "exif2c08" { // chunk with jpeg exif data
|
||||
exif, exif_ok := png.exif(c)
|
||||
error = fmt.tprintf("%v test %v eXIf byte order '%v', expected 'big_endian'.", file.file, count, exif.byte_order)
|
||||
error_len := fmt.tprintf("%v test %v eXIf data length '%v', expected '%v'.", file.file, len(exif.data), 978)
|
||||
expect(t, exif.byte_order == .big_endian && exif_ok, error)
|
||||
expect(t, len(exif.data) == 978 && exif_ok, error_len)
|
||||
testing.expectf(t, exif.byte_order == .big_endian && exif_ok, "%v test %v eXIf byte order '%v', expected 'big_endian'.", file.file, count, exif.byte_order)
|
||||
testing.expectf(t, len(exif.data) == 978 && exif_ok, "%v test %v eXIf data length '%v', expected '%v'.", file.file, len(exif.data), 978)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
png.destroy(img)
|
||||
|
||||
for _, v in track.allocation_map {
|
||||
error = fmt.tprintf("%v test %v leaked %v bytes @ loc %v.", file.file, count, v.size, v.location)
|
||||
expect(t, false, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ set TEST_ARGS=-fast-tests
|
||||
set TEST_ARGS=-no-random
|
||||
set TEST_ARGS=
|
||||
set OUT_NAME=math_big_test_library.dll
|
||||
set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style
|
||||
set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
echo ---
|
||||
echo Running core:math/big tests
|
||||
echo ---
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
// Tests "linalg_glsl_math.odin" in "core:math/linalg/glsl".
|
||||
// Must be run with `-collection:tests=` flag, e.g.
|
||||
// ./odin run tests/core/math/linalg/glsl/test_linalg_glsl_math.odin -collection:tests=./tests
|
||||
package test_core_math_linalg_glsl_math
|
||||
|
||||
import glsl "core:math/linalg/glsl"
|
||||
|
||||
import "core:fmt"
|
||||
import "core:math"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
|
||||
t := testing.T{}
|
||||
|
||||
test_fract_f32(&t)
|
||||
test_fract_f64(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_fract_f32 :: proc(t: ^testing.T) {
|
||||
@@ -45,7 +31,7 @@ test_fract_f32 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = glsl.fract(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%v (%h)) -> %v (%h) != %v", i, #procedure, d.v, d.v, r, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%v (%h) -> %v (%h) != %v", d.v, d.v, r, r, d.e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +60,6 @@ test_fract_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = glsl.fract(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%v (%h)) -> %v (%h) != %v", i, #procedure, d.v, d.v, r, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%v (%h) -> %v (%h) != %v", d.v, d.v, r, r, d.e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,42 +2,6 @@ package test_core_math_noise
|
||||
|
||||
import "core:testing"
|
||||
import "core:math/noise"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
V2 :: noise.Vec2
|
||||
V3 :: noise.Vec3
|
||||
V4 :: noise.Vec4
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
noise_test(&t)
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Test_Vector :: struct {
|
||||
seed: i64,
|
||||
@@ -51,6 +15,10 @@ Test_Vector :: struct {
|
||||
},
|
||||
}
|
||||
|
||||
V2 :: noise.Vec2
|
||||
V3 :: noise.Vec3
|
||||
V4 :: noise.Vec4
|
||||
|
||||
SEED_1 :: 2324223232
|
||||
SEED_2 :: 932466901
|
||||
SEED_3 :: 9321
|
||||
@@ -59,93 +27,78 @@ COORD_1 :: V4{ 242.0, 3433.0, 920.0, 222312.0}
|
||||
COORD_2 :: V4{ 590.0, 9411.0, 5201.0, 942124256.0}
|
||||
COORD_3 :: V4{12090.0, 19411.0, 81950901.0, 4224219.0}
|
||||
|
||||
Noise_Tests := []Test_Vector{
|
||||
/*
|
||||
`noise_2d` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xy, 0.25010583, noise.noise_2d},
|
||||
{SEED_2, COORD_2.xy, -0.92513955, noise.noise_2d},
|
||||
{SEED_3, COORD_3.xy, 0.67327416, noise.noise_2d},
|
||||
|
||||
/*
|
||||
`noise_2d_improve_x` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xy, 0.17074019, noise.noise_2d_improve_x},
|
||||
{SEED_2, COORD_2.xy, 0.72330487, noise.noise_2d_improve_x},
|
||||
{SEED_3, COORD_3.xy, -0.032076947, noise.noise_2d_improve_x},
|
||||
|
||||
/*
|
||||
`noise_3d_improve_xy` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xyz, 0.14819577, noise.noise_3d_improve_xy},
|
||||
{SEED_2, COORD_2.xyz, -0.065345764, noise.noise_3d_improve_xy},
|
||||
{SEED_3, COORD_3.xyz, -0.37761918, noise.noise_3d_improve_xy},
|
||||
|
||||
/*
|
||||
`noise_3d_improve_xz` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xyz, -0.50075006, noise.noise_3d_improve_xz},
|
||||
{SEED_2, COORD_2.xyz, -0.36039603, noise.noise_3d_improve_xz},
|
||||
{SEED_3, COORD_3.xyz, -0.3479203, noise.noise_3d_improve_xz},
|
||||
|
||||
/*
|
||||
`noise_3d_fallback` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xyz, 0.6557345, noise.noise_3d_fallback},
|
||||
{SEED_2, COORD_2.xyz, 0.55452216, noise.noise_3d_fallback},
|
||||
{SEED_3, COORD_3.xyz, -0.26408964, noise.noise_3d_fallback},
|
||||
|
||||
/*
|
||||
`noise_3d_fallback` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1.xyz, 0.6557345, noise.noise_3d_fallback},
|
||||
{SEED_2, COORD_2.xyz, 0.55452216, noise.noise_3d_fallback},
|
||||
{SEED_3, COORD_3.xyz, -0.26408964, noise.noise_3d_fallback},
|
||||
|
||||
/*
|
||||
`noise_4d_improve_xyz_improve_xy` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1, 0.44929826, noise.noise_4d_improve_xyz_improve_xy},
|
||||
{SEED_2, COORD_2, -0.13270882, noise.noise_4d_improve_xyz_improve_xy},
|
||||
{SEED_3, COORD_3, 0.10298563, noise.noise_4d_improve_xyz_improve_xy},
|
||||
|
||||
/*
|
||||
`noise_4d_improve_xyz_improve_xz` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1, -0.078514606, noise.noise_4d_improve_xyz_improve_xz},
|
||||
{SEED_2, COORD_2, -0.032157656, noise.noise_4d_improve_xyz_improve_xz},
|
||||
{SEED_3, COORD_3, -0.38607058, noise.noise_4d_improve_xyz_improve_xz},
|
||||
|
||||
/*
|
||||
`noise_4d_improve_xyz` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1, -0.4442258, noise.noise_4d_improve_xyz},
|
||||
{SEED_2, COORD_2, 0.36822623, noise.noise_4d_improve_xyz},
|
||||
{SEED_3, COORD_3, 0.22628775, noise.noise_4d_improve_xyz},
|
||||
|
||||
/*
|
||||
`noise_4d_fallback` tests.
|
||||
*/
|
||||
{SEED_1, COORD_1, -0.14233987, noise.noise_4d_fallback},
|
||||
{SEED_2, COORD_2, 0.1354035, noise.noise_4d_fallback},
|
||||
{SEED_3, COORD_3, 0.14565045, noise.noise_4d_fallback},
|
||||
|
||||
@(test)
|
||||
test_noise_2d :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1.xy, 0.25010583, noise.noise_2d})
|
||||
test(t, {SEED_2, COORD_2.xy, -0.92513955, noise.noise_2d})
|
||||
test(t, {SEED_3, COORD_3.xy, 0.67327416, noise.noise_2d})
|
||||
}
|
||||
|
||||
noise_test :: proc(t: ^testing.T) {
|
||||
for test in Noise_Tests {
|
||||
output: f32
|
||||
@(test)
|
||||
test_noise_2d_improve_x :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1.xy, 0.17074019, noise.noise_2d_improve_x})
|
||||
test(t, {SEED_2, COORD_2.xy, 0.72330487, noise.noise_2d_improve_x})
|
||||
test(t, {SEED_3, COORD_3.xy, -0.032076947, noise.noise_2d_improve_x})
|
||||
}
|
||||
|
||||
switch coord in test.coord {
|
||||
case V2:
|
||||
output = test.test_proc.(proc(_: i64, _: V2) -> f32)(test.seed, test.coord.(V2))
|
||||
case V3:
|
||||
output = test.test_proc.(proc(_: i64, _: V3) -> f32)(test.seed, test.coord.(V3))
|
||||
case V4:
|
||||
output = test.test_proc.(proc(_: i64, _: V4) -> f32)(test.seed, test.coord.(V4))
|
||||
}
|
||||
|
||||
error := fmt.tprintf("Seed %v, Coord: %v, Expected: %3.8f. Got %3.8f", test.seed, test.coord, test.expected, output)
|
||||
expect(t, test.expected == output, error)
|
||||
@(test)
|
||||
test_noise_3d_improve_xy :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1.xyz, 0.14819577, noise.noise_3d_improve_xy})
|
||||
test(t, {SEED_2, COORD_2.xyz, -0.065345764, noise.noise_3d_improve_xy})
|
||||
test(t, {SEED_3, COORD_3.xyz, -0.37761918, noise.noise_3d_improve_xy})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_3d_improve_xz :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1.xyz, -0.50075006, noise.noise_3d_improve_xz})
|
||||
test(t, {SEED_2, COORD_2.xyz, -0.36039603, noise.noise_3d_improve_xz})
|
||||
test(t, {SEED_3, COORD_3.xyz, -0.3479203, noise.noise_3d_improve_xz})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_3d_fallback :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1.xyz, 0.6557345, noise.noise_3d_fallback})
|
||||
test(t, {SEED_2, COORD_2.xyz, 0.55452216, noise.noise_3d_fallback})
|
||||
test(t, {SEED_3, COORD_3.xyz, -0.26408964, noise.noise_3d_fallback})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_4d_improve_xyz_improve_xy :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1, 0.44929826, noise.noise_4d_improve_xyz_improve_xy})
|
||||
test(t, {SEED_2, COORD_2, -0.13270882, noise.noise_4d_improve_xyz_improve_xy})
|
||||
test(t, {SEED_3, COORD_3, 0.10298563, noise.noise_4d_improve_xyz_improve_xy})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_4d_improve_xyz_improve_xz :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1, -0.078514606, noise.noise_4d_improve_xyz_improve_xz})
|
||||
test(t, {SEED_2, COORD_2, -0.032157656, noise.noise_4d_improve_xyz_improve_xz})
|
||||
test(t, {SEED_3, COORD_3, -0.38607058, noise.noise_4d_improve_xyz_improve_xz})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_4d_improve_xyz :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1, -0.4442258, noise.noise_4d_improve_xyz})
|
||||
test(t, {SEED_2, COORD_2, 0.36822623, noise.noise_4d_improve_xyz})
|
||||
test(t, {SEED_3, COORD_3, 0.22628775, noise.noise_4d_improve_xyz})
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_noise_4d_fallback :: proc(t: ^testing.T) {
|
||||
test(t, {SEED_1, COORD_1, -0.14233987, noise.noise_4d_fallback})
|
||||
test(t, {SEED_2, COORD_2, 0.1354035, noise.noise_4d_fallback})
|
||||
test(t, {SEED_3, COORD_3, 0.14565045, noise.noise_4d_fallback})
|
||||
}
|
||||
|
||||
test :: proc(t: ^testing.T, test: Test_Vector) {
|
||||
output: f32
|
||||
switch coord in test.coord {
|
||||
case V2:
|
||||
output = test.test_proc.(proc(_: i64, _: V2) -> f32)(test.seed, test.coord.(V2))
|
||||
case V3:
|
||||
output = test.test_proc.(proc(_: i64, _: V3) -> f32)(test.seed, test.coord.(V3))
|
||||
case V4:
|
||||
output = test.test_proc.(proc(_: i64, _: V4) -> f32)(test.seed, test.coord.(V4))
|
||||
}
|
||||
testing.expectf(t, test.expected == output, "Seed %v, Coord: %v, Expected: %3.8f. Got %3.8f", test.seed, test.coord, test.expected, output)
|
||||
}
|
||||
@@ -1,49 +1,8 @@
|
||||
// Tests "math.odin" in "core:math".
|
||||
// Must be run with `-collection:tests=` flag, e.g.
|
||||
// ./odin run tests/core/math/test_core_math.odin -collection:tests=./tests
|
||||
package test_core_math
|
||||
|
||||
import "core:fmt"
|
||||
import "core:math"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_classify_f16(&t)
|
||||
test_classify_f32(&t)
|
||||
test_classify_f64(&t)
|
||||
|
||||
test_trunc_f16(&t)
|
||||
test_trunc_f32(&t)
|
||||
test_trunc_f64(&t)
|
||||
|
||||
test_round_f16(&t)
|
||||
test_round_f32(&t)
|
||||
test_round_f64(&t)
|
||||
|
||||
test_nan(&t)
|
||||
test_acos(&t)
|
||||
test_acosh(&t)
|
||||
test_asin(&t)
|
||||
test_asinh(&t)
|
||||
test_atan(&t)
|
||||
test_atanh(&t)
|
||||
test_atan2(&t)
|
||||
test_cos(&t)
|
||||
test_cosh(&t)
|
||||
test_sin(&t)
|
||||
test_sinh(&t)
|
||||
test_sqrt(&t)
|
||||
test_tan(&t)
|
||||
test_tanh(&t)
|
||||
test_large_cos(&t)
|
||||
test_large_sin(&t)
|
||||
test_large_tan(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_classify_f16 :: proc(t: ^testing.T) {
|
||||
@@ -68,7 +27,7 @@ test_classify_f16 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.classify_f16(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
|
||||
/* Check all subnormals (exponent 0, 10-bit significand non-zero) */
|
||||
@@ -76,7 +35,7 @@ test_classify_f16 :: proc(t: ^testing.T) {
|
||||
v := transmute(f16)i
|
||||
r = math.classify_f16(v)
|
||||
e :: math.Float_Class.Subnormal
|
||||
tc.expect(t, r == e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, v, r, e))
|
||||
testing.expectf(t, r == e, "%h -> %v != %v", v, r, e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +62,7 @@ test_classify_f32 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.classify_f32(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +89,7 @@ test_classify_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.classify_f64(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,16 +134,16 @@ test_trunc_f16 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.trunc_f16(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F16
|
||||
r = math.trunc_f16(v)
|
||||
tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f16(r), "%f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F16
|
||||
r = math.trunc_f16(v)
|
||||
tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f16(r), "%f != NaN", v, r)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -237,16 +196,16 @@ test_trunc_f32 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.trunc_f32(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F32
|
||||
r = math.trunc_f32(v)
|
||||
tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f32(r), "%f -> %f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F32
|
||||
r = math.trunc_f32(v)
|
||||
tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f32(r), "%f -> %f != NaN", v, r)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -299,16 +258,16 @@ test_trunc_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.trunc_f64(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F64
|
||||
r = math.trunc_f64(v)
|
||||
tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f64(r), "%f -> %f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F64
|
||||
r = math.trunc_f64(v)
|
||||
tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f64(r), "%f -> %f != NaN", v, r)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -352,16 +311,16 @@ test_round_f16 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.round_f16(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F16
|
||||
r = math.round_f16(v)
|
||||
tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f16(r), "%f -> %f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F16
|
||||
r = math.round_f16(v)
|
||||
tc.expect(t, math.is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f16(r), "%f -> %f != NaN", v, r)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -414,16 +373,16 @@ test_round_f32 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.round_f32(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", i, d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F32
|
||||
r = math.round_f32(v)
|
||||
tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f32(r), "%f -> %f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F32
|
||||
r = math.round_f32(v)
|
||||
tc.expect(t, math.is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f32(r), "%f -> %f != NaN", v, r)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -476,16 +435,16 @@ test_round_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = math.round_f64(d.v)
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, r == d.e, "%h -> %h != %h", d.v, r, d.e)
|
||||
}
|
||||
|
||||
v = math.SNAN_F64
|
||||
r = math.round_f64(v)
|
||||
tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f64(r), "%f -> %f != NaN", v, r)
|
||||
|
||||
v = math.QNAN_F64
|
||||
r = math.round_f64(v)
|
||||
tc.expect(t, math.is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
testing.expectf(t, math.is_nan_f64(r), "%f -> %f != NaN", v, r)
|
||||
}
|
||||
|
||||
|
||||
@@ -1033,17 +992,17 @@ tolerance :: proc(a, b, e: f64) -> bool {
|
||||
}
|
||||
close :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
|
||||
ok := tolerance(a, b, 1e-9)
|
||||
// tc.expect(t, ok, fmt.tprintf("%.15g is not close to %.15g", a, b), loc)
|
||||
testing.expectf(t, ok, "%.15g is not close to %.15g", a, b, loc=loc)
|
||||
return ok
|
||||
}
|
||||
veryclose :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
|
||||
ok := tolerance(a, b, 4e-14)
|
||||
// tc.expect(t, ok, fmt.tprintf("%.15g is not veryclose to %.15g", a, b), loc)
|
||||
testing.expectf(t, ok, "%.15g is not veryclose to %.15g", a, b, loc=loc)
|
||||
return ok
|
||||
}
|
||||
soclose :: proc(t: ^testing.T, a, b, e: f64, loc := #caller_location) -> bool {
|
||||
ok := tolerance(a, b, e)
|
||||
// tc.expect(t, ok, fmt.tprintf("%.15g is not soclose to %.15g", a, b), loc)
|
||||
testing.expectf(t, ok, "%.15g is not soclose to %.15g", a, b, loc=loc)
|
||||
return ok
|
||||
}
|
||||
alike :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
|
||||
@@ -1054,34 +1013,34 @@ alike :: proc(t: ^testing.T, a, b: f64, loc := #caller_location) -> bool {
|
||||
case a == b:
|
||||
ok = math.signbit(a) == math.signbit(b)
|
||||
}
|
||||
// tc.expect(t, ok, fmt.tprintf("%.15g is not alike to %.15g", a, b), loc)
|
||||
testing.expectf(t, ok, "%.15g is not alike to %.15g", a, b, loc=loc)
|
||||
return ok
|
||||
}
|
||||
|
||||
@test
|
||||
test_nan :: proc(t: ^testing.T) {
|
||||
test_nan32 :: proc(t: ^testing.T) {
|
||||
float32 := f32(NaN)
|
||||
equal := float32 == float32
|
||||
testing.expectf(t, !equal, "float32(NaN) is %.15g, expected NaN", float32)
|
||||
}
|
||||
|
||||
@test
|
||||
test_nan64 :: proc(t: ^testing.T) {
|
||||
float64 := NaN
|
||||
if float64 == float64 {
|
||||
tc.errorf(t, "NaN returns %.15g, expected NaN", float64)
|
||||
}
|
||||
float32 := f32(float64)
|
||||
if float32 == float32 {
|
||||
tc.errorf(t, "float32(NaN) is %.15g, expected NaN", float32)
|
||||
}
|
||||
equal := float64 == float64
|
||||
testing.expectf(t, !equal, "NaN returns %.15g, expected NaN", float64)
|
||||
}
|
||||
|
||||
@test
|
||||
test_acos :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
a := vf[i] / 10
|
||||
if f := math.acos(a); !close(t, acos[i], f) {
|
||||
tc.errorf(t, "math.acos(%.15g) = %.15g, want %.15g", a, f, acos[i])
|
||||
}
|
||||
f := math.acos(a)
|
||||
testing.expectf(t, close(t, acos[i], f), "math.acos(%.15g) = %.15g, want %.15g", a, f, acos[i])
|
||||
}
|
||||
for _, i in vfacos_sc {
|
||||
if f := math.acos(vfacos_sc[i]); !alike(t, acos_sc[i], f) {
|
||||
tc.errorf(t, "math.acos(%.15g) = %.15g, want %.15g", vfacos_sc[i], f, acos_sc[i])
|
||||
}
|
||||
f := math.acos(vfacos_sc[i])
|
||||
testing.expectf(t, alike(t, acos_sc[i], f), "math.acos(%.15g) = %.15g, want %.15g", vfacos_sc[i], f, acos_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,14 +1048,12 @@ test_acos :: proc(t: ^testing.T) {
|
||||
test_acosh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
a := 1 + abs(vf[i])
|
||||
if f := math.acosh(a); !veryclose(t, acosh[i], f) {
|
||||
tc.errorf(t, "math.acosh(%.15g) = %.15g, want %.15g", a, f, acosh[i])
|
||||
}
|
||||
f := math.acosh(a)
|
||||
testing.expectf(t, veryclose(t, acosh[i], f), "math.acosh(%.15g) = %.15g, want %.15g", a, f, acosh[i])
|
||||
}
|
||||
for _, i in vfacosh_sc {
|
||||
if f := math.acosh(vfacosh_sc[i]); !alike(t, acosh_sc[i], f) {
|
||||
tc.errorf(t, "math.acosh(%.15g) = %.15g, want %.15g", vfacosh_sc[i], f, acosh_sc[i])
|
||||
}
|
||||
f := math.acosh(vfacosh_sc[i])
|
||||
testing.expectf(t, alike(t, acosh_sc[i], f), "math.acosh(%.15g) = %.15g, want %.15g", vfacosh_sc[i], f, acosh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,42 +1061,36 @@ test_acosh :: proc(t: ^testing.T) {
|
||||
test_asin :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
a := vf[i] / 10
|
||||
if f := math.asin(a); !veryclose(t, asin[i], f) {
|
||||
tc.errorf(t, "math.asin(%.15g) = %.15g, want %.15g", a, f, asin[i])
|
||||
}
|
||||
f := math.asin(a)
|
||||
testing.expectf(t, veryclose(t, asin[i], f), "math.asin(%.15g) = %.15g, want %.15g", a, f, asin[i])
|
||||
}
|
||||
for _, i in vfasin_sc {
|
||||
if f := math.asin(vfasin_sc[i]); !alike(t, asin_sc[i], f) {
|
||||
tc.errorf(t, "math.asin(%.15g) = %.15g, want %.15g", vfasin_sc[i], f, asin_sc[i])
|
||||
}
|
||||
f := math.asin(vfasin_sc[i])
|
||||
testing.expectf(t, alike(t, asin_sc[i], f), "math.asin(%.15g) = %.15g, want %.15g", vfasin_sc[i], f, asin_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_asinh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.asinh(vf[i]); !veryclose(t, asinh[i], f) {
|
||||
tc.errorf(t, "math.asinh(%.15g) = %.15g, want %.15g", vf[i], f, asinh[i])
|
||||
}
|
||||
f := math.asinh(vf[i])
|
||||
testing.expectf(t, veryclose(t, asinh[i], f), "math.asinh(%.15g) = %.15g, want %.15g", vf[i], f, asinh[i])
|
||||
}
|
||||
for _, i in vfasinh_sc {
|
||||
if f := math.asinh(vfasinh_sc[i]); !alike(t, asinh_sc[i], f) {
|
||||
tc.errorf(t, "math.asinh(%.15g) = %.15g, want %.15g", vfasinh_sc[i], f, asinh_sc[i])
|
||||
}
|
||||
f := math.asinh(vfasinh_sc[i])
|
||||
testing.expectf(t, alike(t, asinh_sc[i], f), "math.asinh(%.15g) = %.15g, want %.15g", vfasinh_sc[i], f, asinh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_atan :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.atan(vf[i]); !veryclose(t, atan[i], f) {
|
||||
tc.errorf(t, "math.atan(%.15g) = %.15g, want %.15g", vf[i], f, atan[i])
|
||||
}
|
||||
f := math.atan(vf[i])
|
||||
testing.expectf(t, veryclose(t, atan[i], f), "math.atan(%.15g) = %.15g, want %.15g", vf[i], f, atan[i])
|
||||
}
|
||||
for _, i in vfatan_sc {
|
||||
if f := math.atan(vfatan_sc[i]); !alike(t, atan_sc[i], f) {
|
||||
tc.errorf(t, "math.atan(%.15g) = %.15g, want %.15g", vfatan_sc[i], f, atan_sc[i])
|
||||
}
|
||||
f := math.atan(vfatan_sc[i])
|
||||
testing.expectf(t, alike(t, atan_sc[i], f), "math.atan(%.15g) = %.15g, want %.15g", vfatan_sc[i], f, atan_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1147,84 +1098,72 @@ test_atan :: proc(t: ^testing.T) {
|
||||
test_atanh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
a := vf[i] / 10
|
||||
if f := math.atanh(a); !veryclose(t, atanh[i], f) {
|
||||
tc.errorf(t, "math.atanh(%.15g) = %.15g, want %.15g", a, f, atanh[i])
|
||||
}
|
||||
f := math.atanh(a)
|
||||
testing.expectf(t, veryclose(t, atanh[i], f), "math.atanh(%.15g) = %.15g, want %.15g", a, f, atanh[i])
|
||||
}
|
||||
for _, i in vfatanh_sc {
|
||||
if f := math.atanh(vfatanh_sc[i]); !alike(t, atanh_sc[i], f) {
|
||||
tc.errorf(t, "math.atanh(%.15g) = %.15g, want %.15g", vfatanh_sc[i], f, atanh_sc[i])
|
||||
}
|
||||
f := math.atanh(vfatanh_sc[i])
|
||||
testing.expectf(t, alike(t, atanh_sc[i], f), "math.atanh(%.15g) = %.15g, want %.15g", vfatanh_sc[i], f, atanh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_atan2 :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.atan2(10, vf[i]); !veryclose(t, atan2[i], f) {
|
||||
tc.errorf(t, "math.atan2(10, %.15g) = %.15g, want %.15g", vf[i], f, atan2[i])
|
||||
}
|
||||
f := math.atan2(10, vf[i])
|
||||
testing.expectf(t, veryclose(t, atan2[i], f), "math.atan2(10, %.15g) = %.15g, want %.15g", vf[i], f, atan2[i])
|
||||
}
|
||||
for _, i in vfatan2_sc {
|
||||
if f := math.atan2(vfatan2_sc[i][0], vfatan2_sc[i][1]); !alike(t, atan2_sc[i], f) {
|
||||
tc.errorf(t, "math.atan2(%.15g, %.15g) = %.15g, want %.15g", vfatan2_sc[i][0], vfatan2_sc[i][1], f, atan2_sc[i])
|
||||
}
|
||||
f := math.atan2(vfatan2_sc[i][0], vfatan2_sc[i][1])
|
||||
testing.expectf(t, alike(t, atan2_sc[i], f), "math.atan2(%.15g, %.15g) = %.15g, want %.15g", vfatan2_sc[i][0], vfatan2_sc[i][1], f, atan2_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_cos :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.cos(vf[i]); !veryclose(t, cos[i], f) {
|
||||
tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vf[i], f, cos[i])
|
||||
}
|
||||
f := math.cos(vf[i])
|
||||
testing.expectf(t, veryclose(t, cos[i], f), "math.cos(%.15g) = %.15g, want %.15g", vf[i], f, cos[i])
|
||||
}
|
||||
for _, i in vfcos_sc {
|
||||
if f := math.cos(vfcos_sc[i]); !alike(t, cos_sc[i], f) {
|
||||
tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vfcos_sc[i], f, cos_sc[i])
|
||||
}
|
||||
f := math.cos(vfcos_sc[i])
|
||||
testing.expectf(t, alike(t, cos_sc[i], f), "math.cos(%.15g) = %.15g, want %.15g", vfcos_sc[i], f, cos_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_cosh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.cosh(vf[i]); !close(t, cosh[i], f) {
|
||||
tc.errorf(t, "math.cosh(%.15g) = %.15g, want %.15g", vf[i], f, cosh[i])
|
||||
}
|
||||
f := math.cosh(vf[i])
|
||||
testing.expectf(t, close(t, cosh[i], f), "math.cosh(%.15g) = %.15g, want %.15g", vf[i], f, cosh[i])
|
||||
}
|
||||
for _, i in vfcosh_sc {
|
||||
if f := math.cosh(vfcosh_sc[i]); !alike(t, cosh_sc[i], f) {
|
||||
tc.errorf(t, "math.cosh(%.15g) = %.15g, want %.15g", vfcosh_sc[i], f, cosh_sc[i])
|
||||
}
|
||||
f := math.cosh(vfcosh_sc[i])
|
||||
testing.expectf(t, alike(t, cosh_sc[i], f), "math.cosh(%.15g) = %.15g, want %.15g", vfcosh_sc[i], f, cosh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_sin :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.sin(vf[i]); !veryclose(t, sin[i], f) {
|
||||
tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vf[i], f, sin[i])
|
||||
}
|
||||
f := math.sin(vf[i])
|
||||
testing.expectf(t, veryclose(t, sin[i], f), "math.sin(%.15g) = %.15g, want %.15g", vf[i], f, sin[i])
|
||||
}
|
||||
for _, i in vfsin_sc {
|
||||
if f := math.sin(vfsin_sc[i]); !alike(t, sin_sc[i], f) {
|
||||
tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
|
||||
}
|
||||
f := math.sin(vfsin_sc[i])
|
||||
testing.expectf(t, alike(t, sin_sc[i], f), "math.sin(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_sinh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.sinh(vf[i]); !close(t, sinh[i], f) {
|
||||
tc.errorf(t, "math.sinh(%.15g) = %.15g, want %.15g", vf[i], f, sinh[i])
|
||||
}
|
||||
f := math.sinh(vf[i])
|
||||
testing.expectf(t, close(t, sinh[i], f), "math.sinh(%.15g) = %.15g, want %.15g", vf[i], f, sinh[i])
|
||||
}
|
||||
for _, i in vfsinh_sc {
|
||||
if f := math.sinh(vfsinh_sc[i]); !alike(t, sinh_sc[i], f) {
|
||||
tc.errorf(t, "math.sinh(%.15g) = %.15g, want %.15g", vfsinh_sc[i], f, sinh_sc[i])
|
||||
}
|
||||
f := math.sinh(vfsinh_sc[i])
|
||||
testing.expectf(t, alike(t, sinh_sc[i], f), "math.sinh(%.15g) = %.15g, want %.15g", vfsinh_sc[i], f, sinh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1232,38 +1171,33 @@ test_sinh :: proc(t: ^testing.T) {
|
||||
test_sqrt :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
a := abs(vf[i])
|
||||
if f := math.sqrt(a); !veryclose(t, sqrt[i], f) {
|
||||
tc.errorf(t, "math.sqrt(%.15g) = %.15g, want %.15g", a, f, sqrt[i])
|
||||
}
|
||||
f := math.sqrt(a)
|
||||
testing.expectf(t, veryclose(t, sqrt[i], f), "math.sqrt(%.15g) = %.15g, want %.15g", a, f, sqrt[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_tan :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.tan(vf[i]); !veryclose(t, tan[i], f) {
|
||||
tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vf[i], f, tan[i])
|
||||
}
|
||||
f := math.tan(vf[i])
|
||||
testing.expectf(t, veryclose(t, tan[i], f), "math.tan(%.15g) = %.15g, want %.15g", vf[i], f, tan[i])
|
||||
}
|
||||
// same special cases as Sin
|
||||
for _, i in vfsin_sc {
|
||||
if f := math.tan(vfsin_sc[i]); !alike(t, sin_sc[i], f) {
|
||||
tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
|
||||
}
|
||||
f := math.tan(vfsin_sc[i])
|
||||
testing.expectf(t, alike(t, sin_sc[i], f), "math.tan(%.15g) = %.15g, want %.15g", vfsin_sc[i], f, sin_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_tanh :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
if f := math.tanh(vf[i]); !veryclose(t, tanh[i], f) {
|
||||
tc.errorf(t, "math.tanh(%.15g) = %.15g, want %.15g", vf[i], f, tanh[i])
|
||||
}
|
||||
f := math.tanh(vf[i])
|
||||
testing.expectf(t, veryclose(t, tanh[i], f), "math.tanh(%.15g) = %.15g, want %.15g", vf[i], f, tanh[i])
|
||||
}
|
||||
for _, i in vftanh_sc {
|
||||
if f := math.tanh(vftanh_sc[i]); !alike(t, tanh_sc[i], f) {
|
||||
tc.errorf(t, "math.tanh(%.15g) = %.15g, want %.15g", vftanh_sc[i], f, tanh_sc[i])
|
||||
}
|
||||
f := math.tanh(vftanh_sc[i])
|
||||
testing.expectf(t, alike(t, tanh_sc[i], f), "math.tanh(%.15g) = %.15g, want %.15g", vftanh_sc[i], f, tanh_sc[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1273,9 +1207,7 @@ test_large_cos :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
f1 := cosLarge[i]
|
||||
f2 := math.cos(vf[i] + large)
|
||||
if !close(t, f1, f2) {
|
||||
tc.errorf(t, "math.cos(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
testing.expectf(t, close(t, f1, f2), "math.cos(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1285,9 +1217,7 @@ test_large_sin :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
f1 := sinLarge[i]
|
||||
f2 := math.sin(vf[i] + large)
|
||||
if !close(t, f1, f2) {
|
||||
tc.errorf(t, "math.sin(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
testing.expectf(t, close(t, f1, f2), "math.sin(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1297,8 +1227,6 @@ test_large_tan :: proc(t: ^testing.T) {
|
||||
for _, i in vf {
|
||||
f1 := tanLarge[i]
|
||||
f2 := math.tan(vf[i] + large)
|
||||
if !close(t, f1, f2) {
|
||||
tc.errorf(t, "math.tan(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
testing.expectf(t, close(t, f1, f2), "math.tan(%.15g) = %.15g, want %.15g", vf[i]+large, f2, f1)
|
||||
}
|
||||
}
|
||||
@@ -11,71 +11,12 @@
|
||||
package test_core_net
|
||||
|
||||
import "core:testing"
|
||||
import "core:mem"
|
||||
import "core:fmt"
|
||||
import "core:net"
|
||||
import "core:strconv"
|
||||
import "core:sync"
|
||||
import "core:time"
|
||||
import "core:thread"
|
||||
import "core:os"
|
||||
|
||||
_, _ :: time, thread
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
t := &testing.T{}
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
_tracking_allocator := mem.Tracking_Allocator{}
|
||||
|
||||
print_tracking_allocator_report :: proc() {
|
||||
for _, leak in _tracking_allocator.allocation_map {
|
||||
fmt.printf("%v leaked %v bytes\n", leak.location, leak.size)
|
||||
}
|
||||
|
||||
for bf in _tracking_allocator.bad_free_array {
|
||||
fmt.printf("%v allocation %p was freed badly\n", bf.location, bf.memory)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
mem.tracking_allocator_init(&_tracking_allocator, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&_tracking_allocator)
|
||||
|
||||
address_parsing_test(t)
|
||||
|
||||
tcp_tests(t)
|
||||
|
||||
split_url_test(t)
|
||||
join_url_test(t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
|
||||
print_tracking_allocator_report()
|
||||
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
import "core:fmt"
|
||||
|
||||
@test
|
||||
address_parsing_test :: proc(t: ^testing.T) {
|
||||
@@ -89,127 +30,66 @@ address_parsing_test :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
valid := len(vector.binstr) > 0
|
||||
|
||||
fmt.printf("%v %v\n", kind, vector.input)
|
||||
|
||||
msg := "-set a proper message-"
|
||||
switch vector.family {
|
||||
case .IP4, .IP4_Alt:
|
||||
/*
|
||||
Does `net.parse_ip4_address` think we parsed the address properly?
|
||||
*/
|
||||
// Does `net.parse_ip4_address` think we parsed the address properly?
|
||||
non_decimal := vector.family == .IP4_Alt
|
||||
any_addr := net.parse_address(vector.input, non_decimal)
|
||||
parsed_ok := any_addr != nil
|
||||
parsed: net.IP4_Address
|
||||
|
||||
any_addr := net.parse_address(vector.input, non_decimal)
|
||||
parsed_ok := any_addr != nil
|
||||
parsed: net.IP4_Address
|
||||
|
||||
/*
|
||||
Ensure that `parse_address` doesn't parse IPv4 addresses into IPv6 addreses by mistake.
|
||||
*/
|
||||
// Ensure that `parse_address` doesn't parse IPv4 addresses into IPv6 addreses by mistake.
|
||||
switch addr in any_addr {
|
||||
case net.IP4_Address:
|
||||
parsed = addr
|
||||
case net.IP6_Address:
|
||||
parsed_ok = false
|
||||
msg = fmt.tprintf("parse_address mistook %v as IPv6 address %04x", vector.input, addr)
|
||||
expect(t, false, msg)
|
||||
testing.expectf(t, false, "parse_address mistook %v as IPv6 address %04x", vector.input, addr)
|
||||
}
|
||||
|
||||
if !parsed_ok && valid {
|
||||
msg = fmt.tprintf("parse_ip4_address failed to parse %v, expected %v", vector.input, binstr_to_address(vector.binstr))
|
||||
testing.expectf(t, parsed_ok == valid, "parse_ip4_address failed to parse %v, expected %v", vector.input, binstr_to_address(t, vector.binstr))
|
||||
|
||||
} else if parsed_ok && !valid {
|
||||
msg = fmt.tprintf("parse_ip4_address parsed %v into %v, expected failure", vector.input, parsed)
|
||||
testing.expectf(t, parsed_ok == valid, "parse_ip4_address parsed %v into %v, expected failure", vector.input, parsed)
|
||||
}
|
||||
expect(t, parsed_ok == valid, msg)
|
||||
|
||||
if valid && parsed_ok {
|
||||
actual_binary := address_to_binstr(parsed)
|
||||
msg = fmt.tprintf("parse_ip4_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
|
||||
expect(t, actual_binary == vector.binstr, msg)
|
||||
testing.expectf(t, actual_binary == vector.binstr, "parse_ip4_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
|
||||
|
||||
/*
|
||||
Do we turn an address back into the same string properly?
|
||||
No point in testing the roundtrip if the first part failed.
|
||||
*/
|
||||
// Do we turn an address back into the same string properly? No point in testing the roundtrip if the first part failed.
|
||||
if len(vector.output) > 0 && actual_binary == vector.binstr {
|
||||
stringified := net.address_to_string(parsed)
|
||||
msg = fmt.tprintf("address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
|
||||
expect(t, stringified == vector.output, msg)
|
||||
testing.expectf(t, stringified == vector.output, "address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
|
||||
}
|
||||
}
|
||||
|
||||
case .IP6:
|
||||
/*
|
||||
Do we parse the address properly?
|
||||
*/
|
||||
// Do we parse the address properly?
|
||||
parsed, parsed_ok := net.parse_ip6_address(vector.input)
|
||||
|
||||
if !parsed_ok && valid {
|
||||
msg = fmt.tprintf("parse_ip6_address failed to parse %v, expected %04x", vector.input, binstr_to_address(vector.binstr))
|
||||
testing.expectf(t, parsed_ok == valid, "parse_ip6_address failed to parse %v, expected %04x", vector.input, binstr_to_address(t, vector.binstr))
|
||||
|
||||
} else if parsed_ok && !valid {
|
||||
msg = fmt.tprintf("parse_ip6_address parsed %v into %04x, expected failure", vector.input, parsed)
|
||||
testing.expectf(t, parsed_ok == valid, "parse_ip6_address parsed %v into %04x, expected failure", vector.input, parsed)
|
||||
}
|
||||
expect(t, parsed_ok == valid, msg)
|
||||
|
||||
if valid && parsed_ok {
|
||||
actual_binary := address_to_binstr(parsed)
|
||||
msg = fmt.tprintf("parse_ip6_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
|
||||
expect(t, actual_binary == vector.binstr, msg)
|
||||
testing.expectf(t, actual_binary == vector.binstr, "parse_ip6_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
|
||||
|
||||
/*
|
||||
Do we turn an address back into the same string properly?
|
||||
No point in testing the roundtrip if the first part failed.
|
||||
*/
|
||||
// Do we turn an address back into the same string properly? No point in testing the roundtrip if the first part failed.
|
||||
if len(vector.output) > 0 && actual_binary == vector.binstr {
|
||||
stringified := net.address_to_string(parsed)
|
||||
msg = fmt.tprintf("address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
|
||||
expect(t, stringified == vector.output, msg)
|
||||
testing.expectf(t, stringified == vector.output, "address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
address_to_binstr :: proc(address: net.Address) -> (binstr: string) {
|
||||
switch t in address {
|
||||
case net.IP4_Address:
|
||||
b := transmute(u32be)t
|
||||
return fmt.tprintf("%08x", b)
|
||||
case net.IP6_Address:
|
||||
b := transmute(u128be)t
|
||||
return fmt.tprintf("%32x", b)
|
||||
case:
|
||||
return ""
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
|
||||
binstr_to_address :: proc(binstr: string) -> (address: net.Address) {
|
||||
switch len(binstr) {
|
||||
case 8: // IPv4
|
||||
a, ok := strconv.parse_u64_of_base(binstr, 16)
|
||||
expect(t, ok, "failed to parse test case bin string")
|
||||
|
||||
ipv4 := u32be(a)
|
||||
return net.IP4_Address(transmute([4]u8)ipv4)
|
||||
|
||||
|
||||
case 32: // IPv6
|
||||
a, ok := strconv.parse_u128_of_base(binstr, 16)
|
||||
expect(t, ok, "failed to parse test case bin string")
|
||||
|
||||
ipv4 := u128be(a)
|
||||
return net.IP6_Address(transmute([8]u16be)ipv4)
|
||||
|
||||
case 0:
|
||||
return nil
|
||||
}
|
||||
panic("Invalid test case")
|
||||
}
|
||||
|
||||
Kind :: enum {
|
||||
IP4, // Decimal IPv4
|
||||
IP4_Alt, // Non-decimal address
|
||||
@@ -223,10 +103,7 @@ IP_Address_Parsing_Test_Vector :: struct {
|
||||
// Input address to try and parse.
|
||||
input: string,
|
||||
|
||||
/*
|
||||
Hexadecimal representation of the expected numeric value of the address.
|
||||
Zero length means input is invalid and the parser should report failure.
|
||||
*/
|
||||
// Hexadecimal representation of the expected numeric value of the address. Zero length means input is invalid and the parser should report failure.
|
||||
binstr: string,
|
||||
|
||||
// Expected `address_to_string` output, if a valid input and this string is non-empty.
|
||||
@@ -335,38 +212,30 @@ IP_Address_Parsing_Test_Vectors :: []IP_Address_Parsing_Test_Vector{
|
||||
{ .IP6, "c0a8", "", ""},
|
||||
}
|
||||
|
||||
tcp_tests :: proc(t: ^testing.T) {
|
||||
fmt.println("Testing two servers trying to bind to the same endpoint...")
|
||||
two_servers_binding_same_endpoint(t)
|
||||
fmt.println("Testing client connecting to a closed port...")
|
||||
client_connects_to_closed_port(t)
|
||||
fmt.println("Testing client sending server data...")
|
||||
client_sends_server_data(t)
|
||||
}
|
||||
|
||||
ENDPOINT := net.Endpoint{
|
||||
net.IP4_Address{127, 0, 0, 1},
|
||||
9999,
|
||||
}
|
||||
ENDPOINT_TWO_SERVERS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9991}
|
||||
ENDPOINT_CLOSED_PORT := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9992}
|
||||
ENDPOINT_SERVER_SENDS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9993}
|
||||
|
||||
@(test)
|
||||
two_servers_binding_same_endpoint :: proc(t: ^testing.T) {
|
||||
skt1, err1 := net.listen_tcp(ENDPOINT)
|
||||
skt1, err1 := net.listen_tcp(ENDPOINT_TWO_SERVERS)
|
||||
defer net.close(skt1)
|
||||
skt2, err2 := net.listen_tcp(ENDPOINT)
|
||||
skt2, err2 := net.listen_tcp(ENDPOINT_TWO_SERVERS)
|
||||
defer net.close(skt2)
|
||||
|
||||
expect(t, err1 == nil, "expected first server binding to endpoint to do so without error")
|
||||
expect(t, err2 == net.Bind_Error.Address_In_Use, "expected second server to bind to an endpoint to return .Address_In_Use")
|
||||
testing.expect(t, err1 == nil, "expected first server binding to endpoint to do so without error")
|
||||
testing.expect(t, err2 == net.Bind_Error.Address_In_Use, "expected second server to bind to an endpoint to return .Address_In_Use")
|
||||
}
|
||||
|
||||
@(test)
|
||||
client_connects_to_closed_port :: proc(t: ^testing.T) {
|
||||
skt, err := net.dial_tcp(ENDPOINT)
|
||||
|
||||
skt, err := net.dial_tcp(ENDPOINT_CLOSED_PORT)
|
||||
defer net.close(skt)
|
||||
expect(t, err == net.Dial_Error.Refused, "expected dial of a closed endpoint to return .Refused")
|
||||
testing.expect(t, err == net.Dial_Error.Refused, "expected dial of a closed endpoint to return .Refused")
|
||||
}
|
||||
|
||||
|
||||
@(test)
|
||||
client_sends_server_data :: proc(t: ^testing.T) {
|
||||
CONTENT: string: "Hellope!"
|
||||
@@ -390,8 +259,8 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
||||
|
||||
defer sync.wait_group_done(r.wg)
|
||||
|
||||
if r.skt, r.err = net.dial_tcp(ENDPOINT); r.err != nil {
|
||||
log(r.t, r.err)
|
||||
if r.skt, r.err = net.dial_tcp(ENDPOINT_SERVER_SENDS); r.err != nil {
|
||||
testing.expectf(r.t, false, "[tcp_client:dial_tcp] %v", r.err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -405,19 +274,17 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
||||
|
||||
defer sync.wait_group_done(r.wg)
|
||||
|
||||
log(r.t, "tcp_server listen")
|
||||
if r.skt, r.err = net.listen_tcp(ENDPOINT); r.err != nil {
|
||||
if r.skt, r.err = net.listen_tcp(ENDPOINT_SERVER_SENDS); r.err != nil {
|
||||
sync.wait_group_done(r.wg)
|
||||
log(r.t, r.err)
|
||||
testing.expectf(r.t, false, "[tcp_server:listen_tcp] %v", r.err)
|
||||
return
|
||||
}
|
||||
|
||||
sync.wait_group_done(r.wg)
|
||||
|
||||
log(r.t, "tcp_server accept")
|
||||
client: net.TCP_Socket
|
||||
if client, _, r.err = net.accept_tcp(r.skt.(net.TCP_Socket)); r.err != nil {
|
||||
log(r.t, r.err)
|
||||
testing.expectf(r.t, false, "[tcp_server:accept_tcp] %v", r.err)
|
||||
return
|
||||
}
|
||||
defer net.close(client)
|
||||
@@ -437,10 +304,7 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
||||
thread_data[0].wg = &wg
|
||||
thread_data[0].tid = thread.create_and_start_with_data(&thread_data[0], tcp_server, context)
|
||||
|
||||
log(t, "waiting for server to start listening")
|
||||
sync.wait_group_wait(&wg)
|
||||
log(t, "starting up client")
|
||||
|
||||
sync.wait_group_add(&wg, 2)
|
||||
|
||||
thread_data[1].t = t
|
||||
@@ -454,20 +318,15 @@ client_sends_server_data :: proc(t: ^testing.T) {
|
||||
net.close(thread_data[1].skt)
|
||||
thread.destroy(thread_data[1].tid)
|
||||
}
|
||||
|
||||
log(t, "waiting for threads to finish")
|
||||
sync.wait_group_wait(&wg)
|
||||
log(t, "threads finished")
|
||||
|
||||
okay := thread_data[0].err == nil && thread_data[1].err == nil
|
||||
msg := fmt.tprintf("Expected client and server to return `nil`, got %v and %v", thread_data[0].err, thread_data[1].err)
|
||||
expect(t, okay, msg)
|
||||
testing.expectf(t, okay, "Expected client and server to return `nil`, got %v and %v", thread_data[0].err, thread_data[1].err)
|
||||
|
||||
received := string(thread_data[0].data[:thread_data[0].length])
|
||||
|
||||
okay = received == CONTENT
|
||||
msg = fmt.tprintf("Expected client to send \"{}\", got \"{}\"", CONTENT, received)
|
||||
expect(t, okay, msg)
|
||||
testing.expectf(t, okay, "Expected client to send \"{}\", got \"{}\"", CONTENT, received)
|
||||
}
|
||||
|
||||
URL_Test :: struct {
|
||||
@@ -559,22 +418,15 @@ split_url_test :: proc(t: ^testing.T) {
|
||||
delete(test.queries)
|
||||
}
|
||||
|
||||
msg := fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.scheme, scheme)
|
||||
expect(t, scheme == test.scheme, msg)
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.host, host)
|
||||
expect(t, host == test.host, msg)
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.path, path)
|
||||
expect(t, path == test.path, msg)
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %d queries, got %d queries", len(test.queries), len(queries))
|
||||
expect(t, len(queries) == len(test.queries), msg)
|
||||
testing.expectf(t, scheme == test.scheme, "Expected `net.split_url` to return %s, got %s", test.scheme, scheme)
|
||||
testing.expectf(t, host == test.host, "Expected `net.split_url` to return %s, got %s", test.host, host)
|
||||
testing.expectf(t, path == test.path, "Expected `net.split_url` to return %s, got %s", test.path, path)
|
||||
testing.expectf(t, len(queries) == len(test.queries), "Expected `net.split_url` to return %d queries, got %d queries", len(test.queries), len(queries))
|
||||
for k, v in queries {
|
||||
expected := test.queries[k]
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", expected, v)
|
||||
expect(t, v == expected, msg)
|
||||
testing.expectf(t, v == expected, "Expected `net.split_url` to return %s, got %s", expected, v)
|
||||
}
|
||||
msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.fragment, fragment)
|
||||
expect(t, fragment == test.fragment, msg)
|
||||
|
||||
testing.expectf(t, fragment == test.fragment, "Expected `net.split_url` to return %s, got %s", test.fragment, fragment)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +511,45 @@ join_url_test :: proc(t: ^testing.T) {
|
||||
for test_url in test.url {
|
||||
pass |= url == test_url
|
||||
}
|
||||
msg := fmt.tprintf("Expected `net.join_url` to return one of %s, got %s", test.url, url)
|
||||
expect(t, pass, msg)
|
||||
testing.expectf(t, pass, "Expected `net.join_url` to return one of %s, got %s", test.url, url)
|
||||
}
|
||||
}
|
||||
|
||||
@(private)
|
||||
address_to_binstr :: proc(address: net.Address) -> (binstr: string) {
|
||||
switch t in address {
|
||||
case net.IP4_Address:
|
||||
b := transmute(u32be)t
|
||||
return fmt.tprintf("%08x", b)
|
||||
case net.IP6_Address:
|
||||
b := transmute(u128be)t
|
||||
return fmt.tprintf("%32x", b)
|
||||
case:
|
||||
return ""
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
|
||||
@(private)
|
||||
binstr_to_address :: proc(t: ^testing.T, binstr: string) -> (address: net.Address) {
|
||||
switch len(binstr) {
|
||||
case 8: // IPv4
|
||||
a, ok := strconv.parse_u64_of_base(binstr, 16)
|
||||
testing.expect(t, ok, "failed to parse test case bin string")
|
||||
|
||||
ipv4 := u32be(a)
|
||||
return net.IP4_Address(transmute([4]u8)ipv4)
|
||||
|
||||
|
||||
case 32: // IPv6
|
||||
a, ok := strconv.parse_u128_of_base(binstr, 16)
|
||||
testing.expect(t, ok, "failed to parse test case bin string")
|
||||
|
||||
ipv4 := u128be(a)
|
||||
return net.IP6_Address(transmute([8]u16be)ipv4)
|
||||
|
||||
case 0:
|
||||
return nil
|
||||
}
|
||||
panic("Invalid test case")
|
||||
}
|
||||
@@ -1,58 +1,29 @@
|
||||
package test_core_odin_parser
|
||||
|
||||
import "core:fmt"
|
||||
import "core:odin/ast"
|
||||
import "core:odin/parser"
|
||||
import "core:os"
|
||||
import "base:runtime"
|
||||
import "core:testing"
|
||||
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_parse_demo(&t)
|
||||
test_parse_bitfield(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@test
|
||||
test_parse_demo :: proc(t: ^testing.T) {
|
||||
pkg, ok := parser.parse_package_from_path("examples/demo")
|
||||
context.allocator = context.temp_allocator
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
pkg, ok := parser.parse_package_from_path(ODIN_ROOT + "examples/demo")
|
||||
|
||||
expect(t, ok == true, "parser.parse_package_from_path failed")
|
||||
testing.expect(t, ok, "parser.parse_package_from_path failed")
|
||||
|
||||
for key, value in pkg.files {
|
||||
expect(t, value.syntax_error_count == 0, fmt.tprintf("%v should contain zero errors", key))
|
||||
testing.expectf(t, value.syntax_error_count == 0, "%v should contain zero errors", key)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_parse_bitfield :: proc(t: ^testing.T) {
|
||||
context.allocator = context.temp_allocator
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
file := ast.File{
|
||||
fullpath = "test.odin",
|
||||
src = `
|
||||
@@ -78,5 +49,5 @@ Foo :: bit_field uint {
|
||||
|
||||
p := parser.default_parser()
|
||||
ok := parser.parse_file(&p, &file)
|
||||
expect(t, ok == true, "bad parse")
|
||||
}
|
||||
testing.expect(t, ok, "bad parse")
|
||||
}
|
||||
@@ -1,26 +1,19 @@
|
||||
// Tests "path.odin" in "core:path/filepath".
|
||||
// Must be run with `-collection:tests=` flag, e.g.
|
||||
// ./odin run tests/core/path/filepath/test_core_filepath.odin -collection:tests=tests
|
||||
package test_core_filepath
|
||||
|
||||
import "core:fmt"
|
||||
import "core:path/filepath"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
@(test)
|
||||
test_split_list :: proc(t: ^testing.T) {
|
||||
when ODIN_OS == .Windows {
|
||||
test_split_list_windows(&t)
|
||||
test_split_list_windows(t)
|
||||
} else {
|
||||
test_split_list_unix(&t)
|
||||
test_split_list_unix(t)
|
||||
}
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_split_list_windows :: proc(t: ^testing.T) {
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
@@ -41,12 +34,12 @@ test_split_list_windows :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i))
|
||||
r := filepath.split_list(d.v)
|
||||
defer delete(r)
|
||||
tc.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d",
|
||||
defer delete_split(r)
|
||||
testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d",
|
||||
i, #procedure, d.v, len(r), len(d.e)))
|
||||
if len(r) == len(d.e) {
|
||||
for _, j in r {
|
||||
tc.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v",
|
||||
testing.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v",
|
||||
i, #procedure, d.v, r[j], j, d.e[j]))
|
||||
}
|
||||
}
|
||||
@@ -55,47 +48,43 @@ test_split_list_windows :: proc(t: ^testing.T) {
|
||||
{
|
||||
v := ""
|
||||
r := filepath.split_list(v)
|
||||
tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r))
|
||||
defer delete_split(r)
|
||||
testing.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r))
|
||||
}
|
||||
{
|
||||
v := "a"
|
||||
r := filepath.split_list(v)
|
||||
defer delete(r)
|
||||
tc.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r)))
|
||||
defer delete_split(r)
|
||||
testing.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r)))
|
||||
if len(r) == 1 {
|
||||
tc.expect(t, r[0] == "a", fmt.tprintf("%s(%v) -> %v[0] != a", #procedure, v, r[0]))
|
||||
testing.expect(t, r[0] == "a", fmt.tprintf("%s(%v) -> %v[0] != a", #procedure, v, r[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_split_list_unix :: proc(t: ^testing.T) {
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: string,
|
||||
e: [3]string,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, "/opt/butler:/home/fancykillerpanda/Projects/Odin/Odin:/usr/local/sbin",
|
||||
{ "/opt/butler:/home/fancykillerpanda/Projects/Odin/Odin:/usr/local/sbin",
|
||||
[3]string{"/opt/butler", "/home/fancykillerpanda/Projects/Odin/Odin", "/usr/local/sbin"} }, // Issue #1537
|
||||
{ 1, "a::b", [3]string{"a", "", "b"} },
|
||||
{ 2, "a:b:", [3]string{"a", "b", ""} },
|
||||
{ 3, ":a:b", [3]string{"", "a", "b"} },
|
||||
{ 4, "::", [3]string{"", "", ""} },
|
||||
{ 5, "\"a:b\"c:d:\"f\"", [3]string{"a:bc", "d", "f"} },
|
||||
{ 6, "\"a:b:c\":d\":e\":f", [3]string{"a:b:c", "d:e", "f"} },
|
||||
{ "a::b", [3]string{"a", "", "b"} },
|
||||
{ "a:b:", [3]string{"a", "b", ""} },
|
||||
{ ":a:b", [3]string{"", "a", "b"} },
|
||||
{ "::", [3]string{"", "", ""} },
|
||||
{ "\"a:b\"c:d:\"f\"", [3]string{"a:bc", "d", "f"} },
|
||||
{ "\"a:b:c\":d\":e\":f", [3]string{"a:b:c", "d:e", "f"} },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i))
|
||||
for d in data {
|
||||
r := filepath.split_list(d.v)
|
||||
defer delete(r)
|
||||
tc.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d",
|
||||
i, #procedure, d.v, len(r), len(d.e)))
|
||||
defer delete_split(r)
|
||||
testing.expectf(t, len(r) == len(d.e), "%s len(r) %d != len(d.e) %d", d.v, len(r), len(d.e))
|
||||
if len(r) == len(d.e) {
|
||||
for _, j in r {
|
||||
tc.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v",
|
||||
i, #procedure, d.v, r[j], j, d.e[j]))
|
||||
testing.expectf(t, r[j] == d.e[j], "%v -> %v[%d] != %v", d.v, r[j], j, d.e[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,15 +92,23 @@ test_split_list_unix :: proc(t: ^testing.T) {
|
||||
{
|
||||
v := ""
|
||||
r := filepath.split_list(v)
|
||||
tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r))
|
||||
testing.expectf(t, r == nil, "'%s' -> '%v' != nil", v, r)
|
||||
}
|
||||
{
|
||||
v := "a"
|
||||
r := filepath.split_list(v)
|
||||
defer delete(r)
|
||||
tc.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r)))
|
||||
defer delete_split(r)
|
||||
testing.expectf(t, len(r) == 1, "'%s' len(r) %d != 1", v, len(r))
|
||||
if len(r) == 1 {
|
||||
tc.expect(t, r[0] == "a", fmt.tprintf("%s(%v) -> %v[0] != a", #procedure, v, r[0]))
|
||||
testing.expectf(t, r[0] == "a", "'%v' -> %v[0] != a", v, r[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(private)
|
||||
delete_split :: proc(s: []string) {
|
||||
for part in s {
|
||||
delete(part)
|
||||
}
|
||||
delete(s)
|
||||
}
|
||||
@@ -1,21 +1,8 @@
|
||||
// Tests "core:reflect/reflect".
|
||||
// Must be run with `-collection:tests=` flag, e.g.
|
||||
// ./odin run tests/core/reflect/test_core_reflect.odin -out=tests/core/test_core_reflect -collection:tests=./tests
|
||||
package test_core_reflect
|
||||
|
||||
import "core:fmt"
|
||||
import "core:reflect"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_as_u64(&t)
|
||||
test_as_f64(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_as_u64 :: proc(t: ^testing.T) {
|
||||
@@ -31,9 +18,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i8 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i8 %v) -> %v (0x%X) != %v (0x%X)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i8 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i8 %v -> %v (0x%X) != %v (0x%X)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -48,9 +34,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i16 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i16 %v) -> %v (0x%X) != %v (0x%X)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i16 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i16 %v -> %v (0x%X) != %v (0x%X)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -65,9 +50,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i32 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i32 %v) -> %v (0x%X) != %v (0x%X)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i32 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i32 %v -> %v (0x%X) != %v (0x%X)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -82,9 +66,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i64 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i64 %v) -> %v (0x%X) != %v (0x%X)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i64 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i64 %v -> %v (0x%X) != %v (0x%X)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -102,9 +85,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i128 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i128 %v) -> %v (0x%X) != %v (0x%X)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i128 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i128 %v -> %v (0x%X) != %v (0x%X)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -118,8 +100,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f16 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f16 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "f16 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f16 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -132,8 +114,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f32 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f32 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "f32 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f32 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -146,8 +128,8 @@ test_as_u64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_u64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f64 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "f64 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f64 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,8 +148,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i8 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i8 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "i8 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i8 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -182,8 +164,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i16 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i16 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "i16 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i16 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -198,8 +180,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i32 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i32 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "i32 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i32 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -214,8 +196,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i64 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "i64 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i64 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -231,9 +213,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(i128 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i128 %v) -> %v (%H) != %v (%H)\n",
|
||||
i, #procedure, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "i128 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "i128 %v -> %v (%H) != %v (%H)", d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -247,9 +228,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f16 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f16 %v (%H)) -> %v (%H) != %v (%H)\n",
|
||||
i, #procedure, d.v, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "f16 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f16 %v (%H) -> %v (%H) != %v (%H)", d.v, d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -262,9 +242,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f32 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f32 %v (%H)) -> %v (%H) != %v (%H)\n",
|
||||
i, #procedure, d.v, d.v, r, r, d.e, d.e))
|
||||
testing.expectf(t, valid, "f32 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f32 %v (%H) -> %v (%H) != %v (%H)", d.v, d.v, r, r, d.e, d.e)
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -277,8 +256,8 @@ test_as_f64 :: proc(t: ^testing.T) {
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := reflect.as_f64(d.v)
|
||||
tc.expect(t, valid, fmt.tprintf("i:%d %s(f64 %v) !valid\n", i, #procedure, d.v))
|
||||
tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e))
|
||||
testing.expectf(t, valid, "f64 %v !valid", d.v)
|
||||
testing.expectf(t, r == d.e, "f64 %v -> %v != %v", d.v, r, d.e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,10 @@
|
||||
package test_core_runtime
|
||||
|
||||
import "core:fmt"
|
||||
import "base:intrinsics"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:reflect"
|
||||
import "base:runtime"
|
||||
import "core:testing"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect_value :: testing.expect_value
|
||||
} else {
|
||||
expect_value :: proc(t: ^testing.T, value, expected: $T, loc := #caller_location) -> bool where intrinsics.type_is_comparable(T) {
|
||||
TEST_count += 1
|
||||
ok := value == expected || reflect.is_nil(value) && reflect.is_nil(expected)
|
||||
if !ok {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] expected %v, got %v\n", loc, expected, value)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_temp_allocator_big_alloc_and_alignment(&t)
|
||||
test_temp_allocator_alignment_boundary(&t)
|
||||
test_temp_allocator_returns_correct_size(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that having space for the allocation, but not for the allocation and alignment
|
||||
// is handled correctly.
|
||||
@(test)
|
||||
@@ -47,7 +14,7 @@ test_temp_allocator_alignment_boundary :: proc(t: ^testing.T) {
|
||||
|
||||
_, _ = mem.alloc(int(runtime.DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE)-120)
|
||||
_, err := mem.alloc(112, 32)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect(t, err == nil)
|
||||
}
|
||||
|
||||
// Tests that big allocations with big alignments are handled correctly.
|
||||
@@ -58,7 +25,7 @@ test_temp_allocator_big_alloc_and_alignment :: proc(t: ^testing.T) {
|
||||
|
||||
mappy: map[[8]int]int
|
||||
err := reserve(&mappy, 50000)
|
||||
expect_value(t, err, nil)
|
||||
testing.expect(t, err == nil)
|
||||
}
|
||||
|
||||
@(test)
|
||||
@@ -67,6 +34,6 @@ test_temp_allocator_returns_correct_size :: proc(t: ^testing.T) {
|
||||
context.allocator = runtime.arena_allocator(&arena)
|
||||
|
||||
bytes, err := mem.alloc_bytes(10, 16)
|
||||
expect_value(t, err, nil)
|
||||
expect_value(t, len(bytes), 10)
|
||||
}
|
||||
testing.expect(t, err == nil)
|
||||
testing.expect(t, len(bytes) == 10)
|
||||
}
|
||||
@@ -1,56 +1,16 @@
|
||||
package test_core_slice
|
||||
|
||||
import "core:slice"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:math/rand"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_sort_with_indices(&t)
|
||||
test_binary_search(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_sort_with_indices :: proc(t: ^testing.T) {
|
||||
seed := rand.uint64()
|
||||
fmt.printf("Random seed: %v\n", seed)
|
||||
|
||||
// Test sizes are all prime.
|
||||
test_sizes :: []int{7, 13, 347, 1031, 10111, 100003}
|
||||
|
||||
for test_size in test_sizes {
|
||||
fmt.printf("Sorting %v random u64 values along with index.\n", test_size)
|
||||
|
||||
r := rand.create(seed)
|
||||
r := rand.create(t.seed)
|
||||
|
||||
vals := make([]u64, test_size)
|
||||
r_idx := make([]int, test_size) // Reverse index
|
||||
@@ -61,7 +21,7 @@ test_sort_with_indices :: proc(t: ^testing.T) {
|
||||
|
||||
// Set up test values
|
||||
for _, i in vals {
|
||||
vals[i] = rand.uint64(&r)
|
||||
vals[i] = rand.uint64(&r)
|
||||
}
|
||||
|
||||
// Sort
|
||||
@@ -69,7 +29,7 @@ test_sort_with_indices :: proc(t: ^testing.T) {
|
||||
defer delete(f_idx)
|
||||
|
||||
// Verify sorted test values
|
||||
rand.init(&r, seed)
|
||||
rand.init(&r, t.seed)
|
||||
|
||||
for v, i in f_idx {
|
||||
r_idx[v] = i
|
||||
@@ -79,14 +39,14 @@ test_sort_with_indices :: proc(t: ^testing.T) {
|
||||
for v, i in vals {
|
||||
if i > 0 {
|
||||
val_pass := v >= last
|
||||
expect(t, val_pass, "Expected values to have been sorted.")
|
||||
testing.expect(t, val_pass, "Expected randomized test values to have been sorted")
|
||||
if !val_pass {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
idx_pass := vals[r_idx[i]] == rand.uint64(&r)
|
||||
expect(t, idx_pass, "Expected index to have been sorted.")
|
||||
testing.expect(t, idx_pass, "Expected index to have been sorted")
|
||||
if !idx_pass {
|
||||
break
|
||||
}
|
||||
@@ -97,16 +57,11 @@ test_sort_with_indices :: proc(t: ^testing.T) {
|
||||
|
||||
@test
|
||||
test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
seed := rand.uint64()
|
||||
fmt.printf("Random seed: %v\n", seed)
|
||||
|
||||
// Test sizes are all prime.
|
||||
test_sizes :: []int{7, 13, 347, 1031, 10111, 100003}
|
||||
|
||||
for test_size in test_sizes {
|
||||
fmt.printf("Sorting %v random u64 values along with index.\n", test_size)
|
||||
|
||||
r := rand.create(seed)
|
||||
r := rand.create(t.seed)
|
||||
|
||||
vals := make([]u64, test_size)
|
||||
r_idx := make([]int, test_size) // Reverse index
|
||||
@@ -117,7 +72,7 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
|
||||
// Set up test values
|
||||
for _, i in vals {
|
||||
vals[i] = rand.uint64(&r)
|
||||
vals[i] = rand.uint64(&r)
|
||||
}
|
||||
|
||||
// Sort
|
||||
@@ -125,7 +80,7 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
defer delete(f_idx)
|
||||
|
||||
// Verify sorted test values
|
||||
rand.init(&r, seed)
|
||||
rand.init(&r, t.seed)
|
||||
|
||||
{
|
||||
indices := make([]int, test_size)
|
||||
@@ -138,7 +93,7 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
defer delete(sorted_indices)
|
||||
for v, i in sorted_indices {
|
||||
idx_pass := v == f_idx[i]
|
||||
expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
testing.expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
if !idx_pass {
|
||||
break
|
||||
}
|
||||
@@ -154,7 +109,7 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
slice.sort_by_indices_overwrite(indices, f_idx)
|
||||
for v, i in indices {
|
||||
idx_pass := v == f_idx[i]
|
||||
expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
testing.expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
if !idx_pass {
|
||||
break
|
||||
}
|
||||
@@ -174,7 +129,7 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
slice.sort_by_indices(indices, swap, f_idx)
|
||||
for v, i in swap {
|
||||
idx_pass := v == f_idx[i]
|
||||
expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
testing.expect(t, idx_pass, "Expected the sorted index to be the same as the result from sort_with_indices")
|
||||
if !idx_pass {
|
||||
break
|
||||
}
|
||||
@@ -185,61 +140,48 @@ test_sort_by_indices :: proc(t: ^testing.T) {
|
||||
|
||||
@test
|
||||
test_binary_search :: proc(t: ^testing.T) {
|
||||
builder := strings.Builder{}
|
||||
defer strings.builder_destroy(&builder)
|
||||
|
||||
test_search :: proc(t: ^testing.T, b: ^strings.Builder, s: []i32, v: i32) -> (int, bool) {
|
||||
log(t, fmt.sbprintf(b, "Searching for %v in %v", v, s))
|
||||
strings.builder_reset(b)
|
||||
index, found := slice.binary_search(s, v)
|
||||
log(t, fmt.sbprintf(b, "index: %v, found: %v", index, found))
|
||||
strings.builder_reset(b )
|
||||
|
||||
return index, found
|
||||
}
|
||||
|
||||
index: int
|
||||
found: bool
|
||||
|
||||
s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
|
||||
|
||||
index, found = test_search(t, &builder, s, 13)
|
||||
expect(t, index == 9, "Expected index to be 9.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
index, found = slice.binary_search(s, 13)
|
||||
testing.expect(t, index == 9, "Expected index to be 9")
|
||||
testing.expect(t, found == true, "Expected found to be true")
|
||||
|
||||
index, found = test_search(t, &builder, s, 4)
|
||||
expect(t, index == 7, "Expected index to be 7.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
index, found = slice.binary_search(s, 4)
|
||||
testing.expect(t, index == 7, "Expected index to be 7.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, s, 100)
|
||||
expect(t, index == 13, "Expected index to be 13.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
index, found = slice.binary_search(s, 100)
|
||||
testing.expect(t, index == 13, "Expected index to be 13.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, s, 1)
|
||||
expect(t, index >= 1 && index <= 4, "Expected index to be 1, 2, 3, or 4.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
index, found = slice.binary_search(s, 1)
|
||||
testing.expect(t, index >= 1 && index <= 4, "Expected index to be 1, 2, 3, or 4.")
|
||||
testing.expect(t, found == true, "Expected found to be true.")
|
||||
|
||||
index, found = test_search(t, &builder, s, -1)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
index, found = slice.binary_search(s, -1)
|
||||
testing.expect(t, index == 0, "Expected index to be 0.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
a := []i32{}
|
||||
|
||||
index, found = test_search(t, &builder, a, 13)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
index, found = slice.binary_search(a, 13)
|
||||
testing.expect(t, index == 0, "Expected index to be 0.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
b := []i32{1}
|
||||
|
||||
index, found = test_search(t, &builder, b, 13)
|
||||
expect(t, index == 1, "Expected index to be 1.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
index, found = slice.binary_search(b, 13)
|
||||
testing.expect(t, index == 1, "Expected index to be 1.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
|
||||
index, found = test_search(t, &builder, b, 1)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == true, "Expected found to be true.")
|
||||
index, found = slice.binary_search(b, 1)
|
||||
testing.expect(t, index == 0, "Expected index to be 0.")
|
||||
testing.expect(t, found == true, "Expected found to be true.")
|
||||
|
||||
index, found = test_search(t, &builder, b, 0)
|
||||
expect(t, index == 0, "Expected index to be 0.")
|
||||
expect(t, found == false, "Expected found to be false.")
|
||||
}
|
||||
index, found = slice.binary_search(b, 0)
|
||||
testing.expect(t, index == 0, "Expected index to be 0.")
|
||||
testing.expect(t, found == false, "Expected found to be false.")
|
||||
}
|
||||
@@ -2,81 +2,42 @@ package test_core_strings
|
||||
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "base:runtime"
|
||||
import "core:mem"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_index_any_small_string_not_found(&t)
|
||||
test_index_any_larger_string_not_found(&t)
|
||||
test_index_any_small_string_found(&t)
|
||||
test_index_any_larger_string_found(&t)
|
||||
test_cut(&t)
|
||||
test_case_conversion(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_index_any_small_string_not_found :: proc(t: ^testing.T) {
|
||||
index := strings.index_any(".", "/:\"")
|
||||
expect(t, index == -1, "index_any should be negative")
|
||||
testing.expect(t, index == -1, "index_any should be negative")
|
||||
}
|
||||
|
||||
@test
|
||||
test_index_any_larger_string_not_found :: proc(t: ^testing.T) {
|
||||
index := strings.index_any("aaaaaaaa.aaaaaaaa", "/:\"")
|
||||
expect(t, index == -1, "index_any should be negative")
|
||||
testing.expect(t, index == -1, "index_any should be negative")
|
||||
}
|
||||
|
||||
@test
|
||||
test_index_any_small_string_found :: proc(t: ^testing.T) {
|
||||
index := strings.index_any(".", "/:.\"")
|
||||
expect(t, index == 0, "index_any should be 0")
|
||||
testing.expect(t, index == 0, "index_any should be 0")
|
||||
}
|
||||
|
||||
@test
|
||||
test_index_any_larger_string_found :: proc(t: ^testing.T) {
|
||||
index := strings.index_any("aaaaaaaa:aaaaaaaa", "/:\"")
|
||||
expect(t, index == 8, "index_any should be 8")
|
||||
testing.expect(t, index == 8, "index_any should be 8")
|
||||
}
|
||||
|
||||
@test
|
||||
test_last_index_any_small_string_found :: proc(t: ^testing.T) {
|
||||
index := strings.last_index_any(".", "/:.\"")
|
||||
expect(t, index == 0, "last_index_any should be 0")
|
||||
testing.expect(t, index == 0, "last_index_any should be 0")
|
||||
}
|
||||
|
||||
@test
|
||||
test_last_index_any_small_string_not_found :: proc(t: ^testing.T) {
|
||||
index := strings.last_index_any(".", "/:\"")
|
||||
expect(t, index == -1, "last_index_any should be -1")
|
||||
testing.expect(t, index == -1, "last_index_any should be -1")
|
||||
}
|
||||
|
||||
Cut_Test :: struct {
|
||||
@@ -100,9 +61,12 @@ test_cut :: proc(t: ^testing.T) {
|
||||
res := strings.cut(test.input, test.offset, test.length)
|
||||
defer delete(res)
|
||||
|
||||
msg := fmt.tprintf("cut(\"%v\", %v, %v) expected to return \"%v\", got \"%v\"",
|
||||
test.input, test.offset, test.length, test.output, res)
|
||||
expect(t, res == test.output, msg)
|
||||
testing.expectf(
|
||||
t,
|
||||
res == test.output,
|
||||
"cut(\"%v\", %v, %v) expected to return \"%v\", got \"%v\"",
|
||||
test.input, test.offset, test.length, test.output, res,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +82,7 @@ Case_Kind :: enum {
|
||||
Ada_Case,
|
||||
}
|
||||
|
||||
Case_Proc :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error)
|
||||
Case_Proc :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error)
|
||||
|
||||
test_cases := [Case_Kind]struct{s: string, p: Case_Proc}{
|
||||
.Lower_Space_Case = {"hellope world", to_lower_space_case},
|
||||
@@ -132,33 +96,31 @@ test_cases := [Case_Kind]struct{s: string, p: Case_Proc}{
|
||||
.Ada_Case = {"Hellope_World", to_ada_case},
|
||||
}
|
||||
|
||||
to_lower_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) {
|
||||
to_lower_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
|
||||
return strings.to_delimiter_case(r, ' ', false, allocator)
|
||||
}
|
||||
to_upper_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) {
|
||||
to_upper_space_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) {
|
||||
return strings.to_delimiter_case(r, ' ', true, allocator)
|
||||
}
|
||||
|
||||
// NOTE: we have these wrappers as having #optional_allocator_error changes the type to not be equivalent
|
||||
to_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_snake_case(r, allocator) }
|
||||
to_upper_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_upper_snake_case(r, allocator) }
|
||||
to_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_kebab_case(r, allocator) }
|
||||
to_upper_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_upper_kebab_case(r, allocator) }
|
||||
to_camel_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_camel_case(r, allocator) }
|
||||
to_pascal_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_pascal_case(r, allocator) }
|
||||
to_ada_case :: proc(r: string, allocator: runtime.Allocator) -> (string, mem.Allocator_Error) { return strings.to_ada_case(r, allocator) }
|
||||
to_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_snake_case(r, allocator) }
|
||||
to_upper_snake_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_upper_snake_case(r, allocator) }
|
||||
to_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_kebab_case(r, allocator) }
|
||||
to_upper_kebab_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_upper_kebab_case(r, allocator) }
|
||||
to_camel_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_camel_case(r, allocator) }
|
||||
to_pascal_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_pascal_case(r, allocator) }
|
||||
to_ada_case :: proc(r: string, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { return strings.to_ada_case(r, allocator) }
|
||||
|
||||
@test
|
||||
test_case_conversion :: proc(t: ^testing.T) {
|
||||
for entry in test_cases {
|
||||
for test_case, case_kind in test_cases {
|
||||
result, err := entry.p(test_case.s, context.allocator)
|
||||
msg := fmt.tprintf("ERROR: We got the allocation error '{}'\n", err)
|
||||
expect(t, err == nil, msg)
|
||||
testing.expectf(t, err == nil, "ERROR: We got the allocation error '{}'\n", err)
|
||||
defer delete(result)
|
||||
|
||||
msg = fmt.tprintf("ERROR: Input `{}` to converter {} does not match `{}`, got `{}`.\n", test_case.s, case_kind, entry.s, result)
|
||||
expect(t, result == entry.s, msg)
|
||||
testing.expectf(t, result == entry.s, "ERROR: Input `{}` to converter {} does not match `{}`, got `{}`.\n", test_case.s, case_kind, entry.s, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,9 @@
|
||||
package test_core_text_i18n
|
||||
|
||||
import "core:mem"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "base:runtime"
|
||||
import "core:testing"
|
||||
import "core:text/i18n"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
T :: i18n.get
|
||||
|
||||
Test :: struct {
|
||||
@@ -37,25 +15,28 @@ Test :: struct {
|
||||
|
||||
Test_Suite :: struct {
|
||||
file: string,
|
||||
loader: proc(string, i18n.Parse_Options, proc(int) -> int, mem.Allocator) -> (^i18n.Translation, i18n.Error),
|
||||
loader: proc(string, i18n.Parse_Options, proc(int) -> int, runtime.Allocator) -> (^i18n.Translation, i18n.Error),
|
||||
plural: proc(int) -> int,
|
||||
err: i18n.Error,
|
||||
options: i18n.Parse_Options,
|
||||
tests: []Test,
|
||||
}
|
||||
|
||||
// Custom pluralizer for plur.mo
|
||||
plur_mo_pluralizer :: proc(n: int) -> (slot: int) {
|
||||
switch {
|
||||
case n == 1: return 0
|
||||
case n != 0 && n % 1_000_000 == 0: return 1
|
||||
case: return 2
|
||||
}
|
||||
}
|
||||
TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/I18N/"
|
||||
|
||||
TESTS := []Test_Suite{
|
||||
{
|
||||
file = "assets/I18N/plur.mo",
|
||||
@(test)
|
||||
test_custom_pluralizer :: proc(t: ^testing.T) {
|
||||
// Custom pluralizer for plur.mo
|
||||
plur_mo_pluralizer :: proc(n: int) -> (slot: int) {
|
||||
switch {
|
||||
case n == 1: return 0
|
||||
case n != 0 && n % 1_000_000 == 0: return 1
|
||||
case: return 2
|
||||
}
|
||||
}
|
||||
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "plur.mo",
|
||||
loader = i18n.parse_mo_file,
|
||||
plural = plur_mo_pluralizer,
|
||||
tests = {
|
||||
@@ -66,14 +47,16 @@ TESTS := []Test_Suite{
|
||||
{"", "Message1/plural", "This is message 1", 1},
|
||||
{"", "Message1/plural", "This is message 1 - plural A", 1_000_000},
|
||||
{"", "Message1/plural", "This is message 1 - plural B", 42},
|
||||
|
||||
// This isn't in the catalog, so should ruturn the key.
|
||||
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
file = "assets/I18N/mixed_context.mo",
|
||||
@(test)
|
||||
test_mixed_context :: proc(t: ^testing.T) {
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "mixed_context.mo",
|
||||
loader = i18n.parse_mo_file,
|
||||
plural = nil,
|
||||
tests = {
|
||||
@@ -84,19 +67,25 @@ TESTS := []Test_Suite{
|
||||
// This isn't in the catalog, so should ruturn the key.
|
||||
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
file = "assets/I18N/mixed_context.mo",
|
||||
@(test)
|
||||
test_mixed_context_dupe :: proc(t: ^testing.T) {
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "mixed_context.mo",
|
||||
loader = i18n.parse_mo_file,
|
||||
plural = nil,
|
||||
// Message1 exists twice, once within Context, which has been merged into ""
|
||||
err = .Duplicate_Key,
|
||||
options = {merge_sections = true},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
file = "assets/I18N/nl_NL.mo",
|
||||
@(test)
|
||||
test_nl_mo :: proc(t: ^testing.T) {
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "nl_NL.mo",
|
||||
loader = i18n.parse_mo_file,
|
||||
plural = nil, // Default pluralizer
|
||||
tests = {
|
||||
@@ -111,12 +100,13 @@ TESTS := []Test_Suite{
|
||||
// This isn't in the catalog, so should ruturn the key.
|
||||
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// QT Linguist with default loader options.
|
||||
{
|
||||
file = "assets/I18N/nl_NL-qt-ts.ts",
|
||||
@(test)
|
||||
test_qt_linguist :: proc(t: ^testing.T) {
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "nl_NL-qt-ts.ts",
|
||||
loader = i18n.parse_qt_linguist_file,
|
||||
plural = nil, // Default pluralizer
|
||||
tests = {
|
||||
@@ -131,11 +121,13 @@ TESTS := []Test_Suite{
|
||||
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
||||
{"Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// QT Linguist, merging sections.
|
||||
{
|
||||
file = "assets/I18N/nl_NL-qt-ts.ts",
|
||||
@(test)
|
||||
test_qt_linguist_merge_sections :: proc(t: ^testing.T) {
|
||||
test(t, {
|
||||
file = TEST_SUITE_PATH + "nl_NL-qt-ts.ts",
|
||||
loader = i18n.parse_qt_linguist_file,
|
||||
plural = nil, // Default pluralizer
|
||||
options = {merge_sections = true},
|
||||
@@ -154,65 +146,38 @@ TESTS := []Test_Suite{
|
||||
{"apple_count", "%d apple(s)", "%d apple(s)", 1},
|
||||
{"apple_count", "%d apple(s)", "%d apple(s)", 42},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// QT Linguist, merging sections. Expecting .Duplicate_Key error because same key exists in more than 1 section.
|
||||
{
|
||||
file = "assets/I18N/duplicate-key.ts",
|
||||
@(test)
|
||||
test_qt_linguist_duplicate_key_err :: proc(t: ^testing.T) {
|
||||
test(t, { // QT Linguist, merging sections. Expecting .Duplicate_Key error because same key exists in more than 1 section.
|
||||
file = TEST_SUITE_PATH + "duplicate-key.ts",
|
||||
loader = i18n.parse_qt_linguist_file,
|
||||
plural = nil, // Default pluralizer
|
||||
options = {merge_sections = true},
|
||||
err = .Duplicate_Key,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// QT Linguist, not merging sections. Shouldn't return error despite same key existing in more than 1 section.
|
||||
{
|
||||
file = "assets/I18N/duplicate-key.ts",
|
||||
@(test)
|
||||
test_qt_linguist_duplicate_key :: proc(t: ^testing.T) {
|
||||
test(t, { // QT Linguist, not merging sections. Shouldn't return error despite same key existing in more than 1 section.
|
||||
file = TEST_SUITE_PATH + "duplicate-key.ts",
|
||||
loader = i18n.parse_qt_linguist_file,
|
||||
plural = nil, // Default pluralizer
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@test
|
||||
tests :: proc(t: ^testing.T) {
|
||||
cat: ^i18n.Translation
|
||||
err: i18n.Error
|
||||
test :: proc(t: ^testing.T, suite: Test_Suite, loc := #caller_location) {
|
||||
cat, err := suite.loader(suite.file, suite.options, suite.plural, context.allocator)
|
||||
testing.expectf(t, err == suite.err, "Expected loading %v to return %v, got %v", suite.file, suite.err, err, loc=loc)
|
||||
|
||||
for suite in TESTS {
|
||||
cat, err = suite.loader(suite.file, suite.options, suite.plural, context.allocator)
|
||||
|
||||
msg := fmt.tprintf("Expected loading %v to return %v, got %v", suite.file, suite.err, err)
|
||||
expect(t, err == suite.err, msg)
|
||||
|
||||
if err == .None {
|
||||
for test in suite.tests {
|
||||
val := T(test.section, test.key, test.n, cat)
|
||||
|
||||
msg = fmt.tprintf("Expected key `%v` from section `%v`'s form for value `%v` to equal `%v`, got `%v`", test.key, test.section, test.n, test.val, val)
|
||||
expect(t, val == test.val, msg)
|
||||
}
|
||||
}
|
||||
i18n.destroy(cat)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
t := testing.T{}
|
||||
tests(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
if len(track.allocation_map) > 0 {
|
||||
fmt.println()
|
||||
for _, v in track.allocation_map {
|
||||
fmt.printf("%v Leaked %v bytes.\n", v.location, v.size)
|
||||
if err == .None {
|
||||
for test in suite.tests {
|
||||
val := T(test.section, test.key, test.n, cat)
|
||||
testing.expectf(t, val == test.val, "Expected key `%v` from section `%v`'s form for value `%v` to equal `%v`, got `%v`", test.key, test.section, test.n, test.val, val, loc=loc)
|
||||
}
|
||||
}
|
||||
i18n.destroy(cat)
|
||||
}
|
||||
@@ -2,31 +2,6 @@ package test_strlib
|
||||
|
||||
import "core:text/match"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:io"
|
||||
|
||||
TEST_count: int
|
||||
TEST_fail: int
|
||||
|
||||
// inline expect with custom props
|
||||
failed :: proc(t: ^testing.T, ok: bool, loc := #caller_location) -> bool {
|
||||
TEST_count += 1
|
||||
|
||||
if !ok {
|
||||
fmt.wprintf(t.w, "%v: ", loc)
|
||||
t.error_count += 1
|
||||
TEST_fail += 1
|
||||
}
|
||||
|
||||
return !ok
|
||||
}
|
||||
|
||||
expect :: testing.expect
|
||||
|
||||
logf :: proc(t: ^testing.T, format: string, args: ..any) {
|
||||
fmt.wprintf(t.w, format, ..args)
|
||||
}
|
||||
|
||||
// find correct byte offsets
|
||||
@test
|
||||
@@ -61,18 +36,17 @@ test_find :: proc(t: ^testing.T) {
|
||||
{ "helelo", "h.-l", 0, { 0, 3, true } },
|
||||
}
|
||||
|
||||
for entry, i in ENTRIES {
|
||||
for entry in ENTRIES {
|
||||
matcher := match.matcher_init(entry.s, entry.p, entry.offset)
|
||||
start, end, ok := match.matcher_find(&matcher)
|
||||
success := entry.match.ok == ok && start == entry.match.start && end == entry.match.end
|
||||
|
||||
if failed(t, success) {
|
||||
logf(t, "Find %d failed!\n", i)
|
||||
logf(t, "\tHAYSTACK %s\tPATTERN %s\n", entry.s, entry.p)
|
||||
logf(t, "\tSTART: %d == %d?\n", entry.match.start, start)
|
||||
logf(t, "\tEND: %d == %d?\n", entry.match.end, end)
|
||||
logf(t, "\tErr: %v\tLength %d\n", matcher.err, matcher.captures_length)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
success,
|
||||
"HAYSTACK %q PATTERN %q, START: %d == %d? END: %d == %d? Err: %v Length %d",
|
||||
entry.s, entry.p, entry.match.start, start, entry.match.end, end, matcher.err, matcher.captures_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,17 +152,17 @@ test_match :: proc(t: ^testing.T) {
|
||||
{ "testing _this_ out", "%b_", "", false },
|
||||
}
|
||||
|
||||
for entry, i in ENTRIES {
|
||||
for entry in ENTRIES {
|
||||
matcher := match.matcher_init(entry.s, entry.p)
|
||||
result, ok := match.matcher_match(&matcher)
|
||||
success := entry.ok == ok && result == entry.result
|
||||
|
||||
if failed(t, success) {
|
||||
logf(t, "Match %d failed!\n", i)
|
||||
logf(t, "\tHAYSTACK %s\tPATTERN %s\n", entry.s, entry.p)
|
||||
logf(t, "\tResults: WANTED %s\tGOT %s\n", entry.result, result)
|
||||
logf(t, "\tErr: %v\tLength %d\n", matcher.err, matcher.captures_length)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
success,
|
||||
"HAYSTACK %q PATTERN %q WANTED %q GOT %q Err: %v Length %d",
|
||||
entry.s, entry.p, entry.result, result, matcher.err, matcher.captures_length,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,19 +177,23 @@ test_captures :: proc(t: ^testing.T) {
|
||||
compare_captures :: proc(t: ^testing.T, test: ^Temp, haystack: string, comp: []string, loc := #caller_location) {
|
||||
length, err := match.find_aux(haystack, test.pattern, 0, false, &test.captures)
|
||||
result := len(comp) == length && err == .OK
|
||||
if failed(t, result == true) {
|
||||
logf(t, "Captures Compare Failed!\n")
|
||||
logf(t, "\tErr: %v\n", err)
|
||||
logf(t, "\tLengths: %v != %v\n", len(comp), length)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
result,
|
||||
"Captures Compare Failed! Lengths: %v != %v Err: %v",
|
||||
len(comp), length, err,
|
||||
)
|
||||
|
||||
for i in 0..<length {
|
||||
cap := test.captures[i]
|
||||
text := haystack[cap.byte_start:cap.byte_end]
|
||||
|
||||
if failed(t, comp[i] == text) {
|
||||
logf(t, "Capture don't equal -> %s != %s\n", comp[i], text)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
comp[i] == text,
|
||||
"Capture don't equal -> %q != %q\n",
|
||||
comp[i], text,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,11 +202,12 @@ test_captures :: proc(t: ^testing.T) {
|
||||
length, err := match.find_aux(haystack, test.pattern, 0, false, &test.captures)
|
||||
result := length > 0 && err == .OK
|
||||
|
||||
if failed(t, result == ok) {
|
||||
logf(t, "Capture match failed!\n")
|
||||
logf(t, "\tErr: %v\n", err)
|
||||
logf(t, "\tLength: %v\n", length)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
result == ok,
|
||||
"Capture match failed! Length: %v Pattern: %q Haystack: %q Err: %v",
|
||||
length, test.pattern, haystack, err,
|
||||
)
|
||||
}
|
||||
|
||||
temp := Temp { pattern = "(one).+" }
|
||||
@@ -253,15 +232,8 @@ test_captures :: proc(t: ^testing.T) {
|
||||
cap2 := captures[2]
|
||||
text1 := haystack[cap1.byte_start:cap1.byte_end]
|
||||
text2 := haystack[cap2.byte_start:cap2.byte_end]
|
||||
expect(t, text1 == "233", "Multi-Capture failed at 1")
|
||||
expect(t, text2 == "hello", "Multi-Capture failed at 2")
|
||||
}
|
||||
}
|
||||
|
||||
gmatch_check :: proc(t: ^testing.T, index: int, a: []string, b: string) {
|
||||
if failed(t, a[index] == b) {
|
||||
logf(t, "GMATCH %d failed!\n", index)
|
||||
logf(t, "\t%s != %s\n", a[index], b)
|
||||
testing.expect(t, text1 == "233", "Multi-Capture failed at 1")
|
||||
testing.expect(t, text2 == "hello", "Multi-Capture failed at 2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,9 +270,9 @@ test_gmatch :: proc(t: ^testing.T) {
|
||||
@test
|
||||
test_gsub :: proc(t: ^testing.T) {
|
||||
result := match.gsub("testing123testing", "%d+", " sup ", context.temp_allocator)
|
||||
expect(t, result == "testing sup testing", "GSUB 0: failed")
|
||||
testing.expect(t, result == "testing sup testing", "GSUB 0: failed")
|
||||
result = match.gsub("testing123testing", "%a+", "345", context.temp_allocator)
|
||||
expect(t, result == "345123345", "GSUB 1: failed")
|
||||
testing.expect(t, result == "345123345", "GSUB 1: failed")
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -313,10 +285,12 @@ test_gfind :: proc(t: ^testing.T) {
|
||||
index: int
|
||||
|
||||
for word in match.gfind(s, pattern, &captures) {
|
||||
if failed(t, output[index] == word) {
|
||||
logf(t, "GFIND %d failed!\n", index)
|
||||
logf(t, "\t%s != %s\n", output[index], word)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
output[index] == word,
|
||||
"GFIND %d failed! %q != %q",
|
||||
index, output[index], word,
|
||||
)
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
@@ -332,11 +306,12 @@ test_frontier :: proc(t: ^testing.T) {
|
||||
call :: proc(data: rawptr, word: string, haystack: string, captures: []match.Match) {
|
||||
temp := cast(^Temp) data
|
||||
|
||||
if failed(temp.t, word == temp.output[temp.index]) {
|
||||
logf(temp.t, "GSUB_WITH %d failed!\n", temp.index)
|
||||
logf(temp.t, "\t%s != %s\n", temp.output[temp.index], word)
|
||||
}
|
||||
|
||||
testing.expectf(
|
||||
temp.t,
|
||||
word == temp.output[temp.index],
|
||||
"GSUB_WITH %d failed! %q != %q",
|
||||
temp.index, temp.output[temp.index], word,
|
||||
)
|
||||
temp.index += 1
|
||||
}
|
||||
|
||||
@@ -369,31 +344,21 @@ test_case_insensitive :: proc(t: ^testing.T) {
|
||||
pattern := match.pattern_case_insensitive("test", 256, context.temp_allocator)
|
||||
goal := "[tT][eE][sS][tT]"
|
||||
|
||||
if failed(t, pattern == goal) {
|
||||
logf(t, "Case Insensitive Pattern doesn't match result\n")
|
||||
logf(t, "\t%s != %s\n", pattern, goal)
|
||||
}
|
||||
testing.expectf(
|
||||
t,
|
||||
pattern == goal,
|
||||
"Case Insensitive Pattern doesn't match result. %q != %q",
|
||||
pattern, goal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t: testing.T
|
||||
stream := os.stream_from_handle(os.stdout)
|
||||
w := io.to_writer(stream)
|
||||
t.w = w
|
||||
|
||||
test_find(&t)
|
||||
test_match(&t)
|
||||
test_captures(&t)
|
||||
test_gmatch(&t)
|
||||
test_gsub(&t)
|
||||
test_gfind(&t)
|
||||
test_frontier(&t)
|
||||
test_utf8(&t)
|
||||
test_case_insensitive(&t)
|
||||
|
||||
fmt.wprintf(w, "%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
@(private)
|
||||
gmatch_check :: proc(t: ^testing.T, index: int, a: []string, b: string) {
|
||||
testing.expectf(
|
||||
t,
|
||||
a[index] == b,
|
||||
"GMATCH %d failed! %q != %q",
|
||||
index, a[index], b,
|
||||
)
|
||||
}
|
||||
@@ -2,39 +2,7 @@ package test_core_thread
|
||||
|
||||
import "core:testing"
|
||||
import "core:thread"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
t := &testing.T{}
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
poly_data_test(t)
|
||||
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
import "base:intrinsics"
|
||||
|
||||
@(test)
|
||||
poly_data_test :: proc(_t: ^testing.T) {
|
||||
@@ -46,7 +14,7 @@ poly_data_test :: proc(_t: ^testing.T) {
|
||||
b: [MAX]byte = 8
|
||||
t1 := thread.create_and_start_with_poly_data(b, proc(b: [MAX]byte) {
|
||||
b_expect: [MAX]byte = 8
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
})
|
||||
defer free(t1)
|
||||
|
||||
@@ -55,8 +23,8 @@ poly_data_test :: proc(_t: ^testing.T) {
|
||||
t2 := thread.create_and_start_with_poly_data2(b1, b2, proc(b: [3]uintptr, b2: [MAX / 2]byte) {
|
||||
b_expect: [3]uintptr = 1
|
||||
b2_expect: [MAX / 2]byte = 3
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
})
|
||||
defer free(t2)
|
||||
|
||||
@@ -64,21 +32,21 @@ poly_data_test :: proc(_t: ^testing.T) {
|
||||
b_expect: [3]uintptr = 1
|
||||
b2_expect: [MAX / 2]byte = 3
|
||||
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b3 == 333, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b3 == 333, "thread poly data not correct")
|
||||
})
|
||||
defer free(t3)
|
||||
|
||||
t4 := thread.create_and_start_with_poly_data4(uintptr(111), b1, uintptr(333), u8(5), proc(n: uintptr, b: [3]uintptr, n2: uintptr, n4: u8) {
|
||||
b_expect: [3]uintptr = 1
|
||||
|
||||
expect(poly_data_test_t, n == 111, "thread poly data not correct")
|
||||
expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
expect(poly_data_test_t, n2 == 333, "thread poly data not correct")
|
||||
expect(poly_data_test_t, n4 == 5, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, n == 111, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, n2 == 333, "thread poly data not correct")
|
||||
testing.expect(poly_data_test_t, n4 == 5, "thread poly data not correct")
|
||||
})
|
||||
defer free(t4)
|
||||
|
||||
thread.join_multiple(t1, t2, t3, t4)
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,17 @@
|
||||
package test_core_time
|
||||
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
import dt "core:time/datetime"
|
||||
|
||||
is_leap_year :: time.is_leap_year
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
expect_value :: testing.expect_value
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
defer mem.tracking_allocator_destroy(&track)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
test_ordinal_date_roundtrip(&t)
|
||||
test_component_to_time_roundtrip(&t)
|
||||
test_parse_rfc3339_string(&t)
|
||||
test_parse_iso8601_string(&t)
|
||||
|
||||
for _, leak in track.allocation_map {
|
||||
expect(&t, false, fmt.tprintf("%v leaked %m\n", leak.location, leak.size))
|
||||
}
|
||||
for bad_free in track.bad_free_array {
|
||||
expect(&t, false, fmt.tprintf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory))
|
||||
}
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_ordinal_date_roundtrip :: proc(t: ^testing.T) {
|
||||
expect(t, dt.unsafe_ordinal_to_date(dt.unsafe_date_to_ordinal(dt.MIN_DATE)) == dt.MIN_DATE, "Roundtripping MIN_DATE failed.")
|
||||
expect(t, dt.unsafe_date_to_ordinal(dt.unsafe_ordinal_to_date(dt.MIN_ORD)) == dt.MIN_ORD, "Roundtripping MIN_ORD failed.")
|
||||
expect(t, dt.unsafe_ordinal_to_date(dt.unsafe_date_to_ordinal(dt.MAX_DATE)) == dt.MAX_DATE, "Roundtripping MAX_DATE failed.")
|
||||
expect(t, dt.unsafe_date_to_ordinal(dt.unsafe_ordinal_to_date(dt.MAX_ORD)) == dt.MAX_ORD, "Roundtripping MAX_ORD failed.")
|
||||
testing.expect(t, dt.unsafe_ordinal_to_date(dt.unsafe_date_to_ordinal(dt.MIN_DATE)) == dt.MIN_DATE, "Roundtripping MIN_DATE failed.")
|
||||
testing.expect(t, dt.unsafe_date_to_ordinal(dt.unsafe_ordinal_to_date(dt.MIN_ORD)) == dt.MIN_ORD, "Roundtripping MIN_ORD failed.")
|
||||
testing.expect(t, dt.unsafe_ordinal_to_date(dt.unsafe_date_to_ordinal(dt.MAX_DATE)) == dt.MAX_DATE, "Roundtripping MAX_DATE failed.")
|
||||
testing.expect(t, dt.unsafe_date_to_ordinal(dt.unsafe_ordinal_to_date(dt.MAX_ORD)) == dt.MAX_ORD, "Roundtripping MAX_ORD failed.")
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -160,22 +109,51 @@ test_parse_rfc3339_string :: proc(t: ^testing.T) {
|
||||
is_leap := false
|
||||
if test.apply_offset {
|
||||
res, consumed := time.rfc3339_to_time_utc(test.rfc_3339, &is_leap)
|
||||
msg := fmt.tprintf("[apply offet] Parsing failed: %v -> %v (nsec: %v). Expected %v consumed, got %v", test.rfc_3339, res, res._nsec, test.consumed, consumed)
|
||||
expect(t, test.consumed == consumed, msg)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.consumed == consumed,
|
||||
"[apply offet] Parsing failed: %v -> %v (nsec: %v). Expected %v consumed, got %v",
|
||||
test.rfc_3339, res, res._nsec, test.consumed, consumed,
|
||||
)
|
||||
|
||||
if test.consumed == consumed {
|
||||
expect(t, test.datetime == res, fmt.tprintf("Time didn't match. Expected %v (%v), got %v (%v)", test.datetime, test.datetime._nsec, res, res._nsec))
|
||||
expect(t, test.is_leap == is_leap, "Expected a leap second, got none.")
|
||||
testing.expectf(
|
||||
t,
|
||||
test.datetime == res,
|
||||
"Time didn't match. Expected %v (%v), got %v (%v)",
|
||||
test.datetime, test.datetime._nsec, res, res._nsec,
|
||||
)
|
||||
testing.expect(
|
||||
t,
|
||||
test.is_leap == is_leap,
|
||||
"Expected a leap second, got none",
|
||||
)
|
||||
}
|
||||
} else {
|
||||
res, offset, consumed := time.rfc3339_to_time_and_offset(test.rfc_3339)
|
||||
msg := fmt.tprintf("Parsing failed: %v -> %v (nsec: %v), offset: %v. Expected %v consumed, got %v", test.rfc_3339, res, res._nsec, offset, test.consumed, consumed)
|
||||
expect(t, test.consumed == consumed, msg)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.consumed == consumed,
|
||||
"Parsing failed: %v -> %v (nsec: %v), offset: %v. Expected %v consumed, got %v",
|
||||
test.rfc_3339, res, res._nsec, offset, test.consumed, consumed,
|
||||
)
|
||||
|
||||
if test.consumed == consumed {
|
||||
expect(t, test.datetime == res, fmt.tprintf("Time didn't match. Expected %v (%v), got %v (%v)", test.datetime, test.datetime._nsec, res, res._nsec))
|
||||
expect(t, test.utc_offset == offset, fmt.tprintf("UTC offset didn't match. Expected %v, got %v", test.utc_offset, offset))
|
||||
expect(t, test.is_leap == is_leap, "Expected a leap second, got none.")
|
||||
testing.expectf(
|
||||
t, test.datetime == res,
|
||||
"Time didn't match. Expected %v (%v), got %v (%v)",
|
||||
test.datetime, test.datetime._nsec, res, res._nsec,
|
||||
)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.utc_offset == offset,
|
||||
"UTC offset didn't match. Expected %v, got %v",
|
||||
test.utc_offset, offset,
|
||||
)
|
||||
testing.expect(
|
||||
t, test.is_leap == is_leap,
|
||||
"Expected a leap second, got none",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,22 +165,52 @@ test_parse_iso8601_string :: proc(t: ^testing.T) {
|
||||
is_leap := false
|
||||
if test.apply_offset {
|
||||
res, consumed := time.iso8601_to_time_utc(test.iso_8601, &is_leap)
|
||||
msg := fmt.tprintf("[apply offet] Parsing failed: %v -> %v (nsec: %v). Expected %v consumed, got %v", test.iso_8601, res, res._nsec, test.consumed, consumed)
|
||||
expect(t, test.consumed == consumed, msg)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.consumed == consumed,
|
||||
"[apply offet] Parsing failed: %v -> %v (nsec: %v). Expected %v consumed, got %v",
|
||||
test.iso_8601, res, res._nsec, test.consumed, consumed,
|
||||
)
|
||||
|
||||
if test.consumed == consumed {
|
||||
expect(t, test.datetime == res, fmt.tprintf("Time didn't match. Expected %v (%v), got %v (%v)", test.datetime, test.datetime._nsec, res, res._nsec))
|
||||
expect(t, test.is_leap == is_leap, "Expected a leap second, got none.")
|
||||
testing.expectf(
|
||||
t,
|
||||
test.datetime == res,
|
||||
"Time didn't match. Expected %v (%v), got %v (%v)",
|
||||
test.datetime, test.datetime._nsec, res, res._nsec,
|
||||
)
|
||||
testing.expect(
|
||||
t,
|
||||
test.is_leap == is_leap,
|
||||
"Expected a leap second, got none",
|
||||
)
|
||||
}
|
||||
} else {
|
||||
res, offset, consumed := time.iso8601_to_time_and_offset(test.iso_8601)
|
||||
msg := fmt.tprintf("Parsing failed: %v -> %v (nsec: %v), offset: %v. Expected %v consumed, got %v", test.iso_8601, res, res._nsec, offset, test.consumed, consumed)
|
||||
expect(t, test.consumed == consumed, msg)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.consumed == consumed,
|
||||
"Parsing failed: %v -> %v (nsec: %v), offset: %v. Expected %v consumed, got %v",
|
||||
test.iso_8601, res, res._nsec, offset, test.consumed, consumed,
|
||||
)
|
||||
|
||||
if test.consumed == consumed {
|
||||
expect(t, test.datetime == res, fmt.tprintf("Time didn't match. Expected %v (%v), got %v (%v)", test.datetime, test.datetime._nsec, res, res._nsec))
|
||||
expect(t, test.utc_offset == offset, fmt.tprintf("UTC offset didn't match. Expected %v, got %v", test.utc_offset, offset))
|
||||
expect(t, test.is_leap == is_leap, "Expected a leap second, got none.")
|
||||
testing.expectf(
|
||||
t, test.datetime == res,
|
||||
"Time didn't match. Expected %v (%v), got %v (%v)",
|
||||
test.datetime, test.datetime._nsec, res, res._nsec,
|
||||
)
|
||||
testing.expectf(
|
||||
t,
|
||||
test.utc_offset == offset,
|
||||
"UTC offset didn't match. Expected %v, got %v",
|
||||
test.utc_offset, offset,
|
||||
)
|
||||
testing.expect(
|
||||
t,
|
||||
test.is_leap == is_leap,
|
||||
"Expected a leap second, got none",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,15 +239,21 @@ test_component_to_time_roundtrip :: proc(t: ^testing.T) {
|
||||
|
||||
date_component_roundtrip_test :: proc(t: ^testing.T, moment: dt.DateTime) {
|
||||
res, ok := time.datetime_to_time(moment.year, moment.month, moment.day, moment.hour, moment.minute, moment.second)
|
||||
expect(t, ok, "Couldn't convert date components into date")
|
||||
testing.expect(
|
||||
t,
|
||||
ok,
|
||||
"Couldn't convert date components into date",
|
||||
)
|
||||
|
||||
YYYY, MM, DD := time.date(res)
|
||||
hh, mm, ss := time.clock(res)
|
||||
|
||||
expected := fmt.tprintf("Expected %4d-%2d-%2d %2d:%2d:%2d, got %4d-%2d-%2d %2d:%2d:%2d",
|
||||
moment.year, moment.month, moment.day, moment.hour, moment.minute, moment.second, YYYY, MM, DD, hh, mm, ss)
|
||||
|
||||
ok = moment.year == i64(YYYY) && moment.month == i8(MM) && moment.day == i8(DD)
|
||||
ok &= moment.hour == i8(hh) && moment.minute == i8(mm) && moment.second == i8(ss)
|
||||
expect(t, ok, expected)
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
"Expected %4d-%2d-%2d %2d:%2d:%2d, got %4d-%2d-%2d %2d:%2d:%2d",
|
||||
moment.year, moment.month, moment.day, moment.hour, moment.minute, moment.second, YYYY, MM, DD, hh, mm, ss,
|
||||
)
|
||||
}
|
||||
@@ -1,23 +1,22 @@
|
||||
ODIN=../../odin
|
||||
COMMON=-file -vet -strict-style -o:minimal
|
||||
|
||||
all: all_bsd asan_test
|
||||
|
||||
all_bsd: rtti_test map_test pow_test 128_test string_compare_test
|
||||
all: asan_test rtti_test map_test pow_test 128_test string_compare_test
|
||||
|
||||
rtti_test:
|
||||
$(ODIN) run test_rtti.odin -file -vet -strict-style -o:minimal
|
||||
$(ODIN) test test_rtti.odin $(COMMON)
|
||||
|
||||
map_test:
|
||||
$(ODIN) run test_map.odin -file -vet -strict-style -o:minimal
|
||||
$(ODIN) test test_map.odin $(COMMON)
|
||||
|
||||
pow_test:
|
||||
$(ODIN) run test_pow.odin -file -vet -strict-style -o:minimal
|
||||
$(ODIN) test test_pow.odin $(COMMON)
|
||||
|
||||
128_test:
|
||||
$(ODIN) run test_128.odin -file -vet -strict-style -o:minimal
|
||||
$(ODIN) test test_128.odin $(COMMON)
|
||||
|
||||
asan_test:
|
||||
$(ODIN) run test_asan.odin -file -sanitize:address -debug
|
||||
$(ODIN) test test_asan.odin $(COMMON) -sanitize:address -debug
|
||||
|
||||
string_compare_test:
|
||||
$(ODIN) run test_string_compare.odin -file -vet -strict-style -o:minimal
|
||||
$(ODIN) test test_string_compare.odin $(COMMON)
|
||||
@@ -1,10 +1,9 @@
|
||||
@echo off
|
||||
set PATH_TO_ODIN==..\..\odin
|
||||
rem %PATH_TO_ODIN% run test_rtti.odin -file -vet -strict-style -o:minimal || exit /b
|
||||
%PATH_TO_ODIN% run test_map.odin -file -vet -strict-style -o:minimal || exit /b
|
||||
rem -define:SEED=42
|
||||
%PATH_TO_ODIN% run test_pow.odin -file -vet -strict-style -o:minimal || exit /b
|
||||
|
||||
%PATH_TO_ODIN% run test_128.odin -file -vet -strict-style -o:minimal || exit /b
|
||||
|
||||
%PATH_TO_ODIN% run test_string_compare.odin -file -vet -strict-style -o:minimal || exit /b
|
||||
set COMMON=-file -vet -strict-style -o:minimal
|
||||
%PATH_TO_ODIN% test test_rtti.odin %COMMON% || exit /b
|
||||
%PATH_TO_ODIN% test test_map.odin %COMMON% || exit /b
|
||||
%PATH_TO_ODIN% test test_pow.odin %COMMON% || exit /b
|
||||
%PATH_TO_ODIN% test test_asan.odin %COMMON% || exit /b
|
||||
%PATH_TO_ODIN% test test_128.odin %COMMON% || exit /b
|
||||
%PATH_TO_ODIN% test test_string_compare.odin %COMMON% || exit /b
|
||||
@@ -1,41 +1,7 @@
|
||||
package test_128
|
||||
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_128_align(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_128_align :: proc(t: ^testing.T) {
|
||||
Danger_Struct :: struct {
|
||||
@@ -45,15 +11,15 @@ test_128_align :: proc(t: ^testing.T) {
|
||||
|
||||
list := [?]Danger_Struct{{0, 0}, {1, 0}, {2, 0}, {3, 0}}
|
||||
|
||||
expect(t, list[0].x == 0, fmt.tprintf("[0].x (%v) != 0", list[0].x))
|
||||
expect(t, list[0].y == 0, fmt.tprintf("[0].y (%v) != 0", list[0].y))
|
||||
testing.expectf(t, list[0].x == 0, "[0].x (%v) != 0", list[0].x)
|
||||
testing.expectf(t, list[0].y == 0, "[0].y (%v) != 0", list[0].y)
|
||||
|
||||
expect(t, list[1].x == 1, fmt.tprintf("[1].x (%v) != 1", list[1].x))
|
||||
expect(t, list[1].y == 0, fmt.tprintf("[1].y (%v) != 0", list[1].y))
|
||||
testing.expectf(t, list[1].x == 1, "[1].x (%v) != 1", list[1].x)
|
||||
testing.expectf(t, list[1].y == 0, "[1].y (%v) != 0", list[1].y)
|
||||
|
||||
expect(t, list[2].x == 2, fmt.tprintf("[2].x (%v) != 2", list[2].x))
|
||||
expect(t, list[2].y == 0, fmt.tprintf("[2].y (%v) != 0", list[2].y))
|
||||
testing.expectf(t, list[2].x == 2, "[2].x (%v) != 2", list[2].x)
|
||||
testing.expectf(t, list[2].y == 0, "[2].y (%v) != 0", list[2].y)
|
||||
|
||||
expect(t, list[3].x == 3, fmt.tprintf("[3].x (%v) != 3", list[3].x))
|
||||
expect(t, list[3].y == 0, fmt.tprintf("[3].y (%v) != 0", list[3].y))
|
||||
testing.expectf(t, list[3].x == 3, "[3].x (%v) != 3", list[3].x)
|
||||
testing.expectf(t, list[3].y == 0, "[3].y (%v) != 0", list[3].y)
|
||||
}
|
||||
|
||||
@@ -1,42 +1,7 @@
|
||||
// Intended to contain code that would trigger asan easily if the abi was set up badly.
|
||||
package test_asan
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_12_bytes(&t)
|
||||
test_12_bytes_two(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_12_bytes :: proc(t: ^testing.T) {
|
||||
@@ -45,9 +10,9 @@ test_12_bytes :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
a, b, ok := internal()
|
||||
expect(t, a == max(f32), fmt.tprintf("a (%v) != max(f32)", a))
|
||||
expect(t, b == 0, fmt.tprintf("b (%v) != 0", b))
|
||||
expect(t, ok, fmt.tprintf("ok (%v) != true", ok))
|
||||
testing.expectf(t, a == max(f32), "a (%v) != max(f32)", a)
|
||||
testing.expectf(t, b == 0, "b (%v) != 0", b)
|
||||
testing.expectf(t, ok, "ok (%v) != true", ok)
|
||||
}
|
||||
|
||||
@(test)
|
||||
@@ -57,6 +22,6 @@ test_12_bytes_two :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
a, b := internal()
|
||||
expect(t, a == 100., fmt.tprintf("a (%v) != 100.", a))
|
||||
expect(t, b == max(int), fmt.tprintf("b (%v) != max(int)", b))
|
||||
testing.expectf(t, a == 100., "a (%v) != 100.", a)
|
||||
testing.expectf(t, b == max(int), "b (%v) != max(int)", b)
|
||||
}
|
||||
|
||||
+46
-116
@@ -1,26 +1,22 @@
|
||||
package test_internal_map
|
||||
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "base:intrinsics"
|
||||
import "core:math/rand"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
seed: u64
|
||||
|
||||
ENTRY_COUNTS := []int{11, 101, 1_001, 10_001, 100_001, 1_000_001}
|
||||
|
||||
@test
|
||||
map_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
seed_incr := u64(0)
|
||||
for entries in ENTRY_COUNTS {
|
||||
fmt.printf("[map_insert_random_key_value] Testing %v entries.\n", entries)
|
||||
log.infof("Testing %v entries", entries)
|
||||
m: map[i64]i64
|
||||
defer delete(m)
|
||||
|
||||
unique_keys := 0
|
||||
r := rand.create(seed + seed_incr)
|
||||
r := rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<entries {
|
||||
k := rand.int63(&r)
|
||||
v := rand.int63(&r)
|
||||
@@ -36,11 +32,11 @@ map_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
key_count += 1
|
||||
}
|
||||
|
||||
expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
|
||||
expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
|
||||
testing.expectf(t, key_count == unique_keys, "Expected key_count to equal %v, got %v", unique_keys, key_count)
|
||||
testing.expectf(t, len(m) == unique_keys, "Expected len(map) to equal %v, got %v", unique_keys, len(m))
|
||||
|
||||
// Reset randomizer and verify
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
|
||||
num_fails := 0
|
||||
for _ in 0..<entries {
|
||||
@@ -51,10 +47,10 @@ map_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
if !cond {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
|
||||
testing.expectf(t, false, "Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k])
|
||||
}
|
||||
}
|
||||
seed_incr += 1
|
||||
@@ -65,12 +61,12 @@ map_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
map_update_random_key_value :: proc(t: ^testing.T) {
|
||||
seed_incr := u64(0)
|
||||
for entries in ENTRY_COUNTS {
|
||||
fmt.printf("[map_update_random_key_value] Testing %v entries.\n", entries)
|
||||
log.infof("Testing %v entries", entries)
|
||||
m: map[i64]i64
|
||||
defer delete(m)
|
||||
|
||||
unique_keys := 0
|
||||
r := rand.create(seed + seed_incr)
|
||||
r := rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<entries {
|
||||
k := rand.int63(&r)
|
||||
v := rand.int63(&r)
|
||||
@@ -86,13 +82,13 @@ map_update_random_key_value :: proc(t: ^testing.T) {
|
||||
key_count += 1
|
||||
}
|
||||
|
||||
expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
|
||||
expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
|
||||
testing.expectf(t, key_count == unique_keys, "Expected key_count to equal %v, got %v", unique_keys, key_count)
|
||||
testing.expectf(t, len(m) == unique_keys, "Expected len(map) to equal %v, got %v", unique_keys, len(m))
|
||||
|
||||
half_entries := entries / 2
|
||||
|
||||
// Reset randomizer and update half the entries
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<half_entries {
|
||||
k := rand.int63(&r)
|
||||
v := rand.int63(&r)
|
||||
@@ -101,7 +97,7 @@ map_update_random_key_value :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
// Reset randomizer and verify
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
|
||||
num_fails := 0
|
||||
for i in 0..<entries {
|
||||
@@ -113,10 +109,10 @@ map_update_random_key_value :: proc(t: ^testing.T) {
|
||||
if !cond {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
|
||||
testing.expectf(t, false, "Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k])
|
||||
}
|
||||
}
|
||||
seed_incr += 1
|
||||
@@ -127,12 +123,12 @@ map_update_random_key_value :: proc(t: ^testing.T) {
|
||||
map_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
seed_incr := u64(0)
|
||||
for entries in ENTRY_COUNTS {
|
||||
fmt.printf("[map_delete_random_key_value] Testing %v entries.\n", entries)
|
||||
log.infof("Testing %v entries", entries)
|
||||
m: map[i64]i64
|
||||
defer delete(m)
|
||||
|
||||
unique_keys := 0
|
||||
r := rand.create(seed + seed_incr)
|
||||
r := rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<entries {
|
||||
k := rand.int63(&r)
|
||||
v := rand.int63(&r)
|
||||
@@ -148,13 +144,13 @@ map_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
key_count += 1
|
||||
}
|
||||
|
||||
expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
|
||||
expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
|
||||
testing.expectf(t, key_count == unique_keys, "Expected key_count to equal %v, got %v", unique_keys, key_count)
|
||||
testing.expectf(t, len(m) == unique_keys, "Expected len(map) to equal %v, got %v", unique_keys, len(m))
|
||||
|
||||
half_entries := entries / 2
|
||||
|
||||
// Reset randomizer and delete half the entries
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<half_entries {
|
||||
k := rand.int63(&r)
|
||||
_ = rand.int63(&r)
|
||||
@@ -163,7 +159,7 @@ map_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
// Reset randomizer and verify
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
|
||||
num_fails := 0
|
||||
for i in 0..<entries {
|
||||
@@ -174,26 +170,26 @@ map_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
if k in m {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected key present. Expected m[%v] to have been deleted, got %v", k, m[k]))
|
||||
testing.expectf(t, false, "Unexpected key present. Expected m[%v] to have been deleted, got %v", k, m[k])
|
||||
}
|
||||
} else {
|
||||
if k not_in m {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Expected key not present. Expected m[%v] = %v", k, v))
|
||||
testing.expectf(t, false, "Expected key not present. Expected m[%v] = %v", k, v)
|
||||
} else if m[k] != v {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
|
||||
testing.expectf(t, false, "Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,12 +201,12 @@ map_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
set_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
seed_incr := u64(0)
|
||||
for entries in ENTRY_COUNTS {
|
||||
fmt.printf("[set_insert_random_key_value] Testing %v entries.\n", entries)
|
||||
log.infof("Testing %v entries", entries)
|
||||
m: map[i64]struct{}
|
||||
defer delete(m)
|
||||
|
||||
unique_keys := 0
|
||||
r := rand.create(seed + seed_incr)
|
||||
r := rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<entries {
|
||||
k := rand.int63(&r)
|
||||
if k not_in m {
|
||||
@@ -224,11 +220,11 @@ set_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
key_count += 1
|
||||
}
|
||||
|
||||
expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
|
||||
expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
|
||||
testing.expectf(t, key_count == unique_keys, "Expected key_count to equal %v, got %v", unique_keys, key_count)
|
||||
testing.expectf(t, len(m) == unique_keys, "Expected len(map) to equal %v, got %v", unique_keys, len(m))
|
||||
|
||||
// Reset randomizer and verify
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
|
||||
num_fails := 0
|
||||
for _ in 0..<entries {
|
||||
@@ -238,10 +234,10 @@ set_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
if !cond {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] to exist", k))
|
||||
testing.expectf(t, false, "Unexpected value. Expected m[%v] to exist", k)
|
||||
}
|
||||
}
|
||||
seed_incr += 1
|
||||
@@ -252,12 +248,12 @@ set_insert_random_key_value :: proc(t: ^testing.T) {
|
||||
set_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
seed_incr := u64(0)
|
||||
for entries in ENTRY_COUNTS {
|
||||
fmt.printf("[set_delete_random_key_value] Testing %v entries.\n", entries)
|
||||
log.infof("Testing %v entries", entries)
|
||||
m: map[i64]struct{}
|
||||
defer delete(m)
|
||||
|
||||
unique_keys := 0
|
||||
r := rand.create(seed + seed_incr)
|
||||
r := rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<entries {
|
||||
k := rand.int63(&r)
|
||||
|
||||
@@ -272,20 +268,20 @@ set_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
key_count += 1
|
||||
}
|
||||
|
||||
expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
|
||||
expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
|
||||
testing.expectf(t, key_count == unique_keys, "Expected key_count to equal %v, got %v", unique_keys, key_count)
|
||||
testing.expectf(t, len(m) == unique_keys, "Expected len(map) to equal %v, got %v", unique_keys, len(m))
|
||||
|
||||
half_entries := entries / 2
|
||||
|
||||
// Reset randomizer and delete half the entries
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
for _ in 0..<half_entries {
|
||||
k := rand.int63(&r)
|
||||
delete_key(&m, k)
|
||||
}
|
||||
|
||||
// Reset randomizer and verify
|
||||
r = rand.create(seed + seed_incr)
|
||||
r = rand.create(t.seed + seed_incr)
|
||||
|
||||
num_fails := 0
|
||||
for i in 0..<entries {
|
||||
@@ -295,88 +291,22 @@ set_delete_random_key_value :: proc(t: ^testing.T) {
|
||||
if k in m {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Unexpected key present. Expected m[%v] to have been deleted", k))
|
||||
testing.expectf(t, false, "Unexpected key present. Expected m[%v] to have been deleted", k)
|
||||
}
|
||||
} else {
|
||||
if k not_in m {
|
||||
num_fails += 1
|
||||
if num_fails > 5 {
|
||||
fmt.println("... and more")
|
||||
log.info("... and more")
|
||||
break
|
||||
}
|
||||
expect(t, false, fmt.tprintf("Expected key not present. Expected m[%v] to exist", k))
|
||||
testing.expectf(t, false, "Expected key not present. Expected m[%v] to exist", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
seed_incr += 1
|
||||
}
|
||||
}
|
||||
|
||||
// -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
// Allow tests to be repeatable
|
||||
SEED :: #config(SEED, -1)
|
||||
when SEED > 0 {
|
||||
seed = u64(SEED)
|
||||
} else {
|
||||
seed = u64(intrinsics.read_cycle_counter())
|
||||
}
|
||||
fmt.println("Initialized seed to", seed)
|
||||
|
||||
mem_track_test(&t, map_insert_random_key_value)
|
||||
mem_track_test(&t, map_update_random_key_value)
|
||||
mem_track_test(&t, map_delete_random_key_value)
|
||||
|
||||
mem_track_test(&t, set_insert_random_key_value)
|
||||
mem_track_test(&t, set_delete_random_key_value)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
mem_track_test :: proc(t: ^testing.T, test: proc(t: ^testing.T)) {
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
test(t)
|
||||
|
||||
expect(t, len(track.allocation_map) == 0, "Expected no leaks.")
|
||||
expect(t, len(track.bad_free_array) == 0, "Expected no leaks.")
|
||||
|
||||
for _, leak in track.allocation_map {
|
||||
fmt.printf("%v leaked %v bytes\n", leak.location, leak.size)
|
||||
}
|
||||
for bad_free in track.bad_free_array {
|
||||
fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
package test_internal_math_pow
|
||||
|
||||
import "core:fmt"
|
||||
@(require) import "core:log"
|
||||
import "core:math"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
@test
|
||||
@@ -19,14 +18,14 @@ pow_test :: proc(t: ^testing.T) {
|
||||
// pow2_f64 returns the same float on all platforms because it isn't this stupid
|
||||
_v1 = 0h00000000_00000000
|
||||
}
|
||||
expect(t, _v1 == _v2, fmt.tprintf("Expected math.pow2_f64(%d) == math.pow(2, %d) (= %16x), got %16x", exp, exp, _v1, _v2))
|
||||
testing.expectf(t, _v1 == _v2, "Expected math.pow2_f64(%d) == math.pow(2, %d) (= %16x), got %16x", exp, exp, _v1, _v2)
|
||||
}
|
||||
{
|
||||
v1 := math.pow(2, f32(exp))
|
||||
v2 := math.pow2_f32(exp)
|
||||
_v1 := transmute(u32)v1
|
||||
_v2 := transmute(u32)v2
|
||||
expect(t, _v1 == _v2, fmt.tprintf("Expected math.pow2_f32(%d) == math.pow(2, %d) (= %08x), got %08x", exp, exp, _v1, _v2))
|
||||
testing.expectf(t, _v1 == _v2, "Expected math.pow2_f32(%d) == math.pow(2, %d) (= %08x), got %08x", exp, exp, _v1, _v2)
|
||||
}
|
||||
{
|
||||
v1 := math.pow(2, f16(exp))
|
||||
@@ -36,46 +35,11 @@ pow_test :: proc(t: ^testing.T) {
|
||||
|
||||
when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 {
|
||||
if exp == -25 {
|
||||
testing.logf(t, "skipping known test failure on darwin+arm64, Expected math.pow2_f16(-25) == math.pow(2, -25) (= 0000), got 0001")
|
||||
log.info("skipping known test failure on darwin+arm64, Expected math.pow2_f16(-25) == math.pow(2, -25) (= 0000), got 0001")
|
||||
_v2 = 0
|
||||
}
|
||||
}
|
||||
|
||||
expect(t, _v1 == _v2, fmt.tprintf("Expected math.pow2_f16(%d) == math.pow(2, %d) (= %04x), got %04x", exp, exp, _v1, _v2))
|
||||
testing.expectf(t, _v1 == _v2, "Expected math.pow2_f16(%d) == math.pow(2, %d) (= %04x), got %04x", exp, exp, _v1, _v2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
pow_test(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package test_internal_rtti
|
||||
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
|
||||
Buggy_Struct :: struct {
|
||||
a: int,
|
||||
b: bool,
|
||||
@@ -28,74 +25,22 @@ rtti_test :: proc(t: ^testing.T) {
|
||||
for v, i in g_b {
|
||||
checksum += (i+1) * int(v)
|
||||
}
|
||||
expect(t, checksum == 0, fmt.tprintf("Expected g_b to be zero-initialized, got %v", g_b))
|
||||
testing.expectf(t, checksum == 0, "Expected g_b to be zero-initialized, got %v", g_b)
|
||||
}
|
||||
{
|
||||
checksum := 0
|
||||
for v, i in l_b {
|
||||
checksum += (i+1) * int(v)
|
||||
}
|
||||
expect(t, checksum == 0, fmt.tprintf("Expected l_b to be zero-initialized, got %v", l_b))
|
||||
testing.expectf(t, checksum == 0, "Expected l_b to be zero-initialized, got %v", l_b)
|
||||
}
|
||||
|
||||
expect(t, size_of(Buggy_Struct) == 40, fmt.tprintf("Expected size_of(Buggy_Struct) == 40, got %v", size_of(Buggy_Struct)))
|
||||
expect(t, size_of(g_buggy) == 40, fmt.tprintf("Expected size_of(g_buggy) == 40, got %v", size_of(g_buggy)))
|
||||
expect(t, size_of(l_buggy) == 40, fmt.tprintf("Expected size_of(l_buggy) == 40, got %v", size_of(l_buggy)))
|
||||
testing.expectf(t, size_of(Buggy_Struct) == 40, "Expected size_of(Buggy_Struct) == 40, got %v", size_of(Buggy_Struct))
|
||||
testing.expectf(t, size_of(g_buggy) == 40, "Expected size_of(g_buggy) == 40, got %v", size_of(g_buggy))
|
||||
testing.expectf(t, size_of(l_buggy) == 40, "Expected size_of(l_buggy) == 40, got %v", size_of(l_buggy))
|
||||
|
||||
g_s := fmt.tprintf("%s", g_buggy)
|
||||
l_s := fmt.tprintf("%s", l_buggy)
|
||||
expect(t, g_s == EXPECTED_REPR, fmt.tprintf("Expected fmt.tprintf(\"%%s\", g_s)) to return \"%v\", got \"%v\"", EXPECTED_REPR, g_s))
|
||||
expect(t, l_s == EXPECTED_REPR, fmt.tprintf("Expected fmt.tprintf(\"%%s\", l_s)) to return \"%v\", got \"%v\"", EXPECTED_REPR, l_s))
|
||||
}
|
||||
|
||||
// -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
mem_track_test(&t, rtti_test)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
mem_track_test :: proc(t: ^testing.T, test: proc(t: ^testing.T)) {
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
test(t)
|
||||
|
||||
expect(t, len(track.allocation_map) == 0, "Expected no leaks.")
|
||||
expect(t, len(track.bad_free_array) == 0, "Expected no leaks.")
|
||||
|
||||
for _, leak in track.allocation_map {
|
||||
fmt.printf("%v leaked %v bytes\n", leak.location, leak.size)
|
||||
}
|
||||
for bad_free in track.bad_free_array {
|
||||
fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
testing.expectf(t, g_s == EXPECTED_REPR, "Expected fmt.tprintf(\"%%s\", g_s)) to return \"%v\", got \"%v\"", EXPECTED_REPR, g_s)
|
||||
testing.expectf(t, l_s == EXPECTED_REPR, "Expected fmt.tprintf(\"%%s\", l_s)) to return \"%v\", got \"%v\"", EXPECTED_REPR, l_s)
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package test_internal_string_compare
|
||||
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:testing"
|
||||
|
||||
Op :: enum { Eq, Lt, Gt }
|
||||
@@ -29,65 +27,31 @@ string_compare :: proc(t: ^testing.T) {
|
||||
for res, op in v.res {
|
||||
switch op {
|
||||
case .Eq:
|
||||
expect(t, (v.a == v.b) == res, fmt.tprintf("Expected cstring(\"%v\") == cstring(\"%v\") to be %v", v.a, v.b, res))
|
||||
expect(t, (s_a == s_b) == res, fmt.tprintf("Expected string(\"%v\") == string(\"%v\") to be %v", v.a, v.b, res))
|
||||
testing.expectf(t, (v.a == v.b) == res, "Expected cstring(\"%v\") == cstring(\"%v\") to be %v", v.a, v.b, res)
|
||||
testing.expectf(t, (s_a == s_b) == res, "Expected string(\"%v\") == string(\"%v\") to be %v", v.a, v.b, res)
|
||||
|
||||
// If a == b then a != b
|
||||
expect(t, (v.a != v.b) == !res, fmt.tprintf("Expected cstring(\"%v\") != cstring(\"%v\") to be %v", v.a, v.b, !res))
|
||||
expect(t, (s_a != s_b) == !res, fmt.tprintf("Expected string(\"%v\") != string(\"%v\") to be %v", v.a, v.b, !res))
|
||||
testing.expectf(t, (v.a != v.b) == !res, "Expected cstring(\"%v\") != cstring(\"%v\") to be %v", v.a, v.b, !res)
|
||||
testing.expectf(t, (s_a != s_b) == !res, "Expected string(\"%v\") != string(\"%v\") to be %v", v.a, v.b, !res)
|
||||
|
||||
case .Lt:
|
||||
expect(t, (v.a < v.b) == res, fmt.tprintf("Expected cstring(\"%v\") < cstring(\"%v\") to be %v", v.a, v.b, res))
|
||||
expect(t, (s_a < s_b) == res, fmt.tprintf("Expected string(\"%v\") < string(\"%v\") to be %v", v.a, v.b, res))
|
||||
testing.expectf(t, (v.a < v.b) == res, "Expected cstring(\"%v\") < cstring(\"%v\") to be %v", v.a, v.b, res)
|
||||
testing.expectf(t, (s_a < s_b) == res, "Expected string(\"%v\") < string(\"%v\") to be %v", v.a, v.b, res)
|
||||
|
||||
// .Lt | .Eq == .LtEq
|
||||
lteq := v.res[.Eq] | res
|
||||
expect(t, (v.a <= v.b) == lteq, fmt.tprintf("Expected cstring(\"%v\") <= cstring(\"%v\") to be %v", v.a, v.b, lteq))
|
||||
expect(t, (s_a <= s_b) == lteq, fmt.tprintf("Expected string(\"%v\") <= string(\"%v\") to be %v", v.a, v.b, lteq))
|
||||
testing.expectf(t, (v.a <= v.b) == lteq, "Expected cstring(\"%v\") <= cstring(\"%v\") to be %v", v.a, v.b, lteq)
|
||||
testing.expectf(t, (s_a <= s_b) == lteq, "Expected string(\"%v\") <= string(\"%v\") to be %v", v.a, v.b, lteq)
|
||||
|
||||
case .Gt:
|
||||
expect(t, (v.a > v.b) == res, fmt.tprintf("Expected cstring(\"%v\") > cstring(\"%v\") to be %v", v.a, v.b, res))
|
||||
expect(t, (s_a > s_b) == res, fmt.tprintf("Expected string(\"%v\") > string(\"%v\") to be %v", v.a, v.b, res))
|
||||
testing.expectf(t, (v.a > v.b) == res, "Expected cstring(\"%v\") > cstring(\"%v\") to be %v", v.a, v.b, res)
|
||||
testing.expectf(t, (s_a > s_b) == res, "Expected string(\"%v\") > string(\"%v\") to be %v", v.a, v.b, res)
|
||||
|
||||
// .Gt | .Eq == .GtEq
|
||||
gteq := v.res[.Eq] | res
|
||||
expect(t, (v.a >= v.b) == gteq, fmt.tprintf("Expected cstring(\"%v\") >= cstring(\"%v\") to be %v", v.a, v.b, gteq))
|
||||
expect(t, (s_a >= s_b) == gteq, fmt.tprintf("Expected string(\"%v\") >= string(\"%v\") to be %v", v.a, v.b, gteq))
|
||||
testing.expectf(t, (v.a >= v.b) == gteq, "Expected cstring(\"%v\") >= cstring(\"%v\") to be %v", v.a, v.b, gteq)
|
||||
testing.expectf(t, (s_a >= s_b) == gteq, "Expected string(\"%v\") >= string(\"%v\") to be %v", v.a, v.b, gteq)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
string_compare(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v\n", loc, message)
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -3,19 +3,19 @@
|
||||
if not exist "build\" mkdir build
|
||||
pushd build
|
||||
|
||||
set COMMON=-collection:tests=..\..
|
||||
set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style
|
||||
|
||||
@echo on
|
||||
|
||||
..\..\..\odin test ..\test_issue_829.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_1592.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_2056.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_2087.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin build ..\test_issue_2113.odin %COMMON% -file -debug || exit /b
|
||||
..\..\..\odin test ..\test_issue_2466.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_2615.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_2637.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_2666.odin %COMMON% -file || exit /b
|
||||
..\..\..\odin test ..\test_issue_829.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_1592.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_2056.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_2087.odin %COMMON% || exit /b
|
||||
..\..\..\odin build ..\test_issue_2113.odin %COMMON% -debug || exit /b
|
||||
..\..\..\odin test ..\test_issue_2466.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_2615.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_2637.odin %COMMON% || exit /b
|
||||
..\..\..\odin test ..\test_issue_2666.odin %COMMON% || exit /b
|
||||
|
||||
@echo off
|
||||
|
||||
|
||||
+11
-11
@@ -4,22 +4,22 @@ set -eu
|
||||
mkdir -p build
|
||||
pushd build
|
||||
ODIN=../../../odin
|
||||
COMMON="-collection:tests=../.."
|
||||
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style"
|
||||
|
||||
NO_NIL_ERR="Error: "
|
||||
|
||||
set -x
|
||||
|
||||
$ODIN test ../test_issue_829.odin $COMMON -file
|
||||
$ODIN test ../test_issue_1592.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2056.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2087.odin $COMMON -file
|
||||
$ODIN build ../test_issue_2113.odin $COMMON -file -debug
|
||||
$ODIN test ../test_issue_2466.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2615.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2637.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2666.odin $COMMON -file
|
||||
if [[ $($ODIN build ../test_issue_2395.odin $COMMON -file 2>&1 >/dev/null | grep -c "$NO_NIL_ERR") -eq 2 ]] ; then
|
||||
$ODIN test ../test_issue_829.odin $COMMON
|
||||
$ODIN test ../test_issue_1592.odin $COMMON
|
||||
$ODIN test ../test_issue_2056.odin $COMMON
|
||||
$ODIN test ../test_issue_2087.odin $COMMON
|
||||
$ODIN build ../test_issue_2113.odin $COMMON -debug
|
||||
$ODIN test ../test_issue_2466.odin $COMMON
|
||||
$ODIN test ../test_issue_2615.odin $COMMON
|
||||
$ODIN test ../test_issue_2637.odin $COMMON
|
||||
$ODIN test ../test_issue_2666.odin $COMMON
|
||||
if [[ $($ODIN build ../test_issue_2395.odin $COMMON 2>&1 >/dev/null | grep -c "$NO_NIL_ERR") -eq 2 ]] ; then
|
||||
echo "SUCCESSFUL 1/1"
|
||||
else
|
||||
echo "SUCCESSFUL 0/1"
|
||||
|
||||
+146
-147
@@ -1,7 +1,6 @@
|
||||
// Tests issue #1592 https://github.com/odin-lang/Odin/issues/1592
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
/* Original issue #1592 example */
|
||||
@@ -31,428 +30,428 @@ true_result :: proc() -> bool {
|
||||
@test
|
||||
test_simple_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if (CONSTANT_FALSE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if (!CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !(CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !!CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if CONSTANT_FALSE == true {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if CONSTANT_FALSE == false {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !(CONSTANT_FALSE == true) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !(CONSTANT_FALSE == false) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if (CONSTANT_TRUE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if (!CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if (!CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !!CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE == true {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE == false {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_TRUE == true) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_TRUE == false) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_proc_false :: proc(t: ^testing.T) {
|
||||
if false_result() {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !false_result() {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_proc_true :: proc(t: ^testing.T) {
|
||||
if true_result() {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !true_result() {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_false_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE || CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if CONSTANT_FALSE && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !CONSTANT_FALSE || CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !CONSTANT_FALSE && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if CONSTANT_FALSE || !CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_FALSE && !CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(CONSTANT_FALSE || CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !(CONSTANT_FALSE && CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_false_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_FALSE && CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !CONSTANT_FALSE || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !CONSTANT_FALSE && CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
|
||||
if CONSTANT_FALSE || !CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if CONSTANT_FALSE && !CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(CONSTANT_FALSE || CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_FALSE && CONSTANT_TRUE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_true_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE || CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !CONSTANT_TRUE || CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !CONSTANT_TRUE && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if CONSTANT_TRUE || !CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE && !CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
|
||||
if !(CONSTANT_TRUE || CONSTANT_FALSE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_TRUE && CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_true_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE && CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
|
||||
if !CONSTANT_TRUE || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !CONSTANT_TRUE && CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if CONSTANT_TRUE || !CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if CONSTANT_TRUE && !CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(CONSTANT_TRUE || CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(CONSTANT_TRUE && CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_false_const_false :: proc(t: ^testing.T) {
|
||||
if false_result() || CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if false_result() && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(false_result() || CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if !(false_result() && CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_false_const_true :: proc(t: ^testing.T) {
|
||||
if false_result() || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if false_result() && CONSTANT_TRUE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(false_result() || CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(false_result() && CONSTANT_TRUE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_true_const_false :: proc(t: ^testing.T) {
|
||||
if true_result() || CONSTANT_FALSE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if true_result() && CONSTANT_FALSE {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
|
||||
if !(true_result() || CONSTANT_FALSE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(true_result() && CONSTANT_FALSE) {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_true_const_true :: proc(t: ^testing.T) {
|
||||
if true_result() || CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
if true_result() && CONSTANT_TRUE {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
} else {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
}
|
||||
|
||||
if !(true_result() || CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
if !(true_result() && CONSTANT_TRUE) {
|
||||
testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
testing.expect(t, false, "!false")
|
||||
} else {
|
||||
testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
testing.expect(t, true, "!true")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Tests issue #2056 https://github.com/odin-lang/Odin/issues/2056
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
@test
|
||||
@@ -12,9 +11,9 @@ test_scalar_matrix_conversion :: proc(t: ^testing.T) {
|
||||
for i in 0..<4 {
|
||||
for j in 0..<4 {
|
||||
if i == j {
|
||||
testing.expect(t, m[i,j] == 1, fmt.tprintf("expected 1 at m[%d,%d], found %f\n", i, j, m[i,j]))
|
||||
testing.expectf(t, m[i,j] == 1, "expected 1 at m[%d,%d], found %f\n", i, j, m[i,j])
|
||||
} else {
|
||||
testing.expect(t, m[i,j] == 0, fmt.tprintf("expected 0 at m[%d,%d], found %f\n", i, j, m[i,j]))
|
||||
testing.expectf(t, m[i,j] == 0, "expected 0 at m[%d,%d], found %f\n", i, j, m[i,j])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Tests issue #2466 https://github.com/odin-lang/Odin/issues/2466
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
Bug :: struct {
|
||||
@@ -16,7 +15,7 @@ test_compound_literal_local_reuse :: proc(t: ^testing.T) {
|
||||
val = v,
|
||||
arr = {42},
|
||||
}
|
||||
testing.expect(t, bug.val == 123, fmt.tprintf("expected 123, found %d", bug.val))
|
||||
testing.expect(t, bug.arr[0] == 42, fmt.tprintf("expected 42, found %d", bug.arr[0]))
|
||||
testing.expectf(t, bug.val == 123, "expected 123, found %d", bug.val)
|
||||
testing.expectf(t, bug.arr[0] == 42, "expected 42, found %d", bug.arr[0])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Tests issue #829 https://github.com/odin-lang/Odin/issues/829
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
/* Original issue #829 example */
|
||||
@@ -13,6 +12,6 @@ env : map[string]proc(a, b : int) -> int = {
|
||||
|
||||
@(test)
|
||||
test_orig_ret :: proc(t: ^testing.T) {
|
||||
r := fmt.tprint(env["+"](1, 2))
|
||||
testing.expect(t, r == "3", fmt.tprintf("%s: \"%s\" != \"3\"\n", #procedure, r))
|
||||
}
|
||||
r := env["+"](1, 2)
|
||||
testing.expectf(t, r == 3, "%q != 3", r)
|
||||
}
|
||||
Vendored
+2
-2
@@ -1,8 +1,8 @@
|
||||
@echo off
|
||||
set COMMON=-show-timings -no-bounds-check -vet -strict-style
|
||||
set COMMON=-show-timings -no-bounds-check -vet -strict-style -define:ODIN_TEST_FANCY=false
|
||||
set PATH_TO_ODIN==..\..\odin
|
||||
|
||||
echo ---
|
||||
echo Running vendor:glfw tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run glfw %COMMON% -out:vendor_glfw.exe || exit /b
|
||||
%PATH_TO_ODIN% test glfw %COMMON% -out:vendor_glfw.exe || exit /b
|
||||
+8
-36
@@ -1,49 +1,21 @@
|
||||
package test_vendor_glfw
|
||||
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "vendor:glfw"
|
||||
import "core:os"
|
||||
|
||||
GLFW_MAJOR :: 3
|
||||
GLFW_MINOR :: 4
|
||||
GLFW_PATCH :: 0
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
|
||||
when ODIN_TEST {
|
||||
expect :: testing.expect
|
||||
log :: testing.log
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.println(message)
|
||||
return
|
||||
}
|
||||
fmt.println(" PASS")
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
test_glfw(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_glfw :: proc(t: ^testing.T) {
|
||||
major, minor, patch := glfw.GetVersion()
|
||||
expect(t, major == GLFW_MAJOR && minor == GLFW_MINOR, fmt.tprintf("Expected GLFW.GetVersion: %v.%v.%v, got %v.%v.%v instead", GLFW_MAJOR, GLFW_MINOR, GLFW_PATCH, major, minor, patch))
|
||||
testing.expectf(
|
||||
t,
|
||||
major == GLFW_MAJOR && \
|
||||
minor == GLFW_MINOR,
|
||||
"Expected GLFW.GetVersion: %v.%v.%v, got %v.%v.%v instead",
|
||||
GLFW_MAJOR, GLFW_MINOR, GLFW_PATCH,
|
||||
major, minor, patch,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user