mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-30 02:03:55 +00:00
Merge branch 'master' into xml
This commit is contained in:
75
tests/common/common.odin
Normal file
75
tests/common/common.odin
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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
|
||||
} else {
|
||||
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] FAIL %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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,29 +1,46 @@
|
||||
ODIN=../../odin
|
||||
PYTHON=$(shell which python3)
|
||||
|
||||
all: download_test_assets image_test compress_test strings_test hash_test crypto_test encoding_test
|
||||
all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \
|
||||
math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test
|
||||
|
||||
download_test_assets:
|
||||
$(PYTHON) download_assets.py
|
||||
|
||||
image_test:
|
||||
$(ODIN) run image/test_core_image.odin -out=test_image -o:speed -no-bounds-check
|
||||
$(ODIN) run image/test_core_image.odin -file -out:test_core_image
|
||||
|
||||
compress_test:
|
||||
$(ODIN) run compress/test_core_compress.odin -out=test_compress -o:speed -no-bounds-check
|
||||
$(ODIN) run compress/test_core_compress.odin -file -out:test_core_compress
|
||||
|
||||
strings_test:
|
||||
$(ODIN) run strings/test_core_strings.odin -out=test_strings -o:speed -no-bounds-check
|
||||
|
||||
odin_test:
|
||||
$(ODIN) run odin -out=test_odin -o:speed -no-bounds-check
|
||||
$(ODIN) run strings/test_core_strings.odin -file -out:test_core_strings
|
||||
|
||||
hash_test:
|
||||
$(ODIN) run hash -out=test_hash -o:speed -no-bounds-check
|
||||
$(ODIN) run hash -o:speed -no-bounds-check -out:test_hash
|
||||
|
||||
crypto_test:
|
||||
$(ODIN) run crypto -out=crypto_hash -o:speed -no-bounds-check
|
||||
$(ODIN) run crypto -o:speed -no-bounds-check -out:test_crypto_hash
|
||||
|
||||
noise_test:
|
||||
$(ODIN) run math/noise -out:test_noise
|
||||
|
||||
encoding_test:
|
||||
$(ODIN) run encoding/json -out=test_encoding_json -o:speed -no-bounds-check
|
||||
$(ODIN) run encoding/xml -out=test_encoding_xml -o:speed -no-bounds-check
|
||||
$(ODIN) run encoding/hxa -collection:tests=.. -out:test_hxa
|
||||
$(ODIN) run encoding/json -out:test_json
|
||||
$(ODIN) run encoding/varint -out:test_varint
|
||||
|
||||
math_test:
|
||||
$(ODIN) run math/test_core_math.odin -file -collection:tests=.. -out:test_core_math
|
||||
|
||||
linalg_glsl_math_test:
|
||||
$(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -collection:tests=.. -out:test_linalg_glsl_math
|
||||
|
||||
filepath_test:
|
||||
$(ODIN) run path/filepath/test_core_filepath.odin -file -collection:tests=.. -out:test_core_filepath
|
||||
|
||||
reflect_test:
|
||||
$(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect
|
||||
|
||||
os_exit_test:
|
||||
$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0
|
||||
BIN
tests/core/assets/HXA/teapot.hxa
Normal file
BIN
tests/core/assets/HXA/teapot.hxa
Normal file
Binary file not shown.
26
tests/core/assets/Shoco/LICENSE
Normal file
26
tests/core/assets/Shoco/LICENSE
Normal file
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2016-2021 Ginger Bill. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
BIN
tests/core/assets/Shoco/LICENSE.shoco
Normal file
BIN
tests/core/assets/Shoco/LICENSE.shoco
Normal file
Binary file not shown.
95
tests/core/assets/Shoco/README.md
Normal file
95
tests/core/assets/Shoco/README.md
Normal file
@@ -0,0 +1,95 @@
|
||||
<p align="center">
|
||||
<img src="misc/logo-slim.png" alt="Odin logo" style="width:65%">
|
||||
<br/>
|
||||
The Data-Oriented Language for Sane Software Development.
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://github.com/odin-lang/odin/releases/latest">
|
||||
<img src="https://img.shields.io/github/release/odin-lang/odin.svg">
|
||||
</a>
|
||||
<a href="https://github.com/odin-lang/odin/releases/latest">
|
||||
<img src="https://img.shields.io/badge/platforms-Windows%20|%20Linux%20|%20macOS-green.svg">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://discord.gg/odinlang">
|
||||
<img src="https://img.shields.io/discord/568138951836172421?logo=discord">
|
||||
</a>
|
||||
<a href="https://github.com/odin-lang/odin/actions">
|
||||
<img src="https://github.com/odin-lang/odin/workflows/CI/badge.svg?branch=master&event=push">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# The Odin Programming Language
|
||||
|
||||
|
||||
Odin is a general-purpose programming language with distinct typing, built for high performance, modern systems, and built-in data-oriented data types. The Odin Programming Language, the C alternative for the joy of programming.
|
||||
|
||||
Website: [https://odin-lang.org/](https://odin-lang.org/)
|
||||
|
||||
```odin
|
||||
package main
|
||||
|
||||
import "core:fmt"
|
||||
|
||||
main :: proc() {
|
||||
program := "+ + * 😃 - /"
|
||||
accumulator := 0
|
||||
|
||||
for token in program {
|
||||
switch token {
|
||||
case '+': accumulator += 1
|
||||
case '-': accumulator -= 1
|
||||
case '*': accumulator *= 2
|
||||
case '/': accumulator /= 2
|
||||
case '😃': accumulator *= accumulator
|
||||
case: // Ignore everything else
|
||||
}
|
||||
}
|
||||
|
||||
fmt.printf("The program \"%s\" calculates the value %d\n",
|
||||
program, accumulator)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
#### [Getting Started](https://odin-lang.org/docs/install)
|
||||
|
||||
Instructions for downloading and installing the Odin compiler and libraries.
|
||||
|
||||
#### [Nightly Builds](https://odin-lang.org/docs/nightly/)
|
||||
|
||||
Get the latest nightly builds of Odin.
|
||||
|
||||
### Learning Odin
|
||||
|
||||
#### [Overview of Odin](https://odin-lang.org/docs/overview)
|
||||
|
||||
An overview of the Odin programming language.
|
||||
|
||||
#### [Frequently Asked Questions (FAQ)](https://odin-lang.org/docs/faq)
|
||||
|
||||
Answers to common questions about Odin.
|
||||
|
||||
#### [Packages](https://pkg.odin-lang.org/)
|
||||
|
||||
Documentation for all the official packages part of the [core](https://pkg.odin-lang.org/core/) and [vendor](https://pkg.odin-lang.org/vendor/) library collections.
|
||||
|
||||
#### [The Odin Wiki](https://github.com/odin-lang/Odin/wiki)
|
||||
|
||||
A wiki maintained by the Odin community.
|
||||
|
||||
#### [Odin Discord](https://discord.gg/sVBPHEv)
|
||||
|
||||
Get live support and talk with other odiners on the Odin Discord.
|
||||
|
||||
### Articles
|
||||
|
||||
#### [The Odin Blog](https://odin-lang.org/news/)
|
||||
|
||||
The official blog of the Odin programming language, featuring announcements, news, and in-depth articles by the Odin team and guests.
|
||||
|
||||
## Warnings
|
||||
|
||||
* The Odin compiler is still in development.
|
||||
BIN
tests/core/assets/Shoco/README.md.shoco
Normal file
BIN
tests/core/assets/Shoco/README.md.shoco
Normal file
Binary file not shown.
@@ -1,39 +1,65 @@
|
||||
@echo off
|
||||
set COMMON=-show-timings -no-bounds-check -vet -strict-style
|
||||
set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=..
|
||||
set PATH_TO_ODIN==..\..\odin
|
||||
python3 download_assets.py
|
||||
echo ---
|
||||
echo Running core:image tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run image %COMMON% -out:test_image.exe
|
||||
%PATH_TO_ODIN% run image %COMMON% -out:test_core_image.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:compress tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run compress %COMMON% -out:test_compress.exe
|
||||
%PATH_TO_ODIN% run compress %COMMON% -out:test_core_compress.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:strings tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run strings %COMMON% -out:test_strings.exe
|
||||
%PATH_TO_ODIN% run strings %COMMON% -out:test_core_strings.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:hash tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_hash.exe
|
||||
%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:odin tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_odin.exe
|
||||
%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_core_odin.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:crypto hash tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run crypto %COMMON% -o:speed -out:test_crypto.exe
|
||||
%PATH_TO_ODIN% run crypto %COMMON% -out:test_crypto_hash.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:encoding tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run encoding\json %COMMON% -out:test_json.exe
|
||||
%PATH_TO_ODIN% run encoding\xml %COMMON% -out:test_xml.exe
|
||||
%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa.exe
|
||||
%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe
|
||||
%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:math/noise tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:math tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math %COMMON% -out:test_core_math.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:math/linalg/glsl tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_linalg_glsl.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:path/filepath tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_core_filepath.exe
|
||||
|
||||
echo ---
|
||||
echo Running core:reflect tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run reflect %COMMON% -out:test_core_reflect.exe
|
||||
@@ -7,13 +7,14 @@ package test_core_compress
|
||||
List of contributors:
|
||||
Jeroen van Rijn: Initial implementation.
|
||||
|
||||
A test suite for ZLIB, GZIP.
|
||||
A test suite for ZLIB, GZIP and Shoco.
|
||||
*/
|
||||
|
||||
import "core:testing"
|
||||
|
||||
import "core:compress/zlib"
|
||||
import "core:compress/gzip"
|
||||
import "core:compress/shoco"
|
||||
|
||||
import "core:bytes"
|
||||
import "core:fmt"
|
||||
@@ -38,7 +39,8 @@ when ODIN_TEST {
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +49,12 @@ main :: proc() {
|
||||
t := testing.T{w=w}
|
||||
zlib_test(&t)
|
||||
gzip_test(&t)
|
||||
shoco_test(&t)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -130,3 +136,56 @@ gzip_test :: proc(t: ^testing.T) {
|
||||
expect(t, false, error)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
shoco_test :: proc(t: ^testing.T) {
|
||||
|
||||
Shoco_Tests :: []struct{
|
||||
compressed: []u8,
|
||||
raw: []u8,
|
||||
short_pack: int,
|
||||
short_sentinel: int,
|
||||
}{
|
||||
{ #load("../assets/Shoco/README.md.shoco"), #load("../assets/Shoco/README.md"), 10, 1006 },
|
||||
{ #load("../assets/Shoco/LICENSE.shoco"), #load("../assets/Shoco/LICENSE"), 25, 68 },
|
||||
}
|
||||
|
||||
for v in Shoco_Tests {
|
||||
expected_raw := len(v.raw)
|
||||
expected_compressed := len(v.compressed)
|
||||
|
||||
biggest_unpacked := shoco.decompress_bound(expected_compressed)
|
||||
biggest_packed := shoco.compress_bound(expected_raw)
|
||||
|
||||
buffer := make([]u8, max(biggest_packed, biggest_unpacked))
|
||||
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)
|
||||
|
||||
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.")
|
||||
|
||||
size, err = shoco.compress(string(v.raw), buffer[:])
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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.")
|
||||
|
||||
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.")
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ import "core:crypto/sm3"
|
||||
import "core:crypto/jh"
|
||||
import "core:crypto/groestl"
|
||||
import "core:crypto/haval"
|
||||
import "core:crypto/siphash"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -52,8 +54,9 @@ when ODIN_TEST {
|
||||
return
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +114,7 @@ main :: proc() {
|
||||
test_haval_192(&t)
|
||||
test_haval_224(&t)
|
||||
test_haval_256(&t)
|
||||
test_siphash_2_4(&t)
|
||||
|
||||
// "modern" crypto tests
|
||||
test_chacha20(&t)
|
||||
@@ -121,7 +125,10 @@ main :: proc() {
|
||||
|
||||
bench_modern(&t)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
TestHash :: struct {
|
||||
@@ -198,7 +205,7 @@ test_md5 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha1 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -220,7 +227,7 @@ test_sha1 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha224 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -238,7 +245,7 @@ test_sha224 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha256 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -256,7 +263,7 @@ test_sha256 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha384 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -274,7 +281,7 @@ test_sha384 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha512 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -292,7 +299,7 @@ test_sha512 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha3_224 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -314,7 +321,7 @@ test_sha3_224 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha3_256 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -336,7 +343,7 @@ test_sha3_256 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha3_384 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -358,7 +365,7 @@ test_sha3_384 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_sha3_512 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -408,7 +415,7 @@ test_shake_256 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_keccak_224 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -424,7 +431,7 @@ test_keccak_224 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_keccak_256 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -440,7 +447,7 @@ test_keccak_256 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_keccak_384 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -456,7 +463,7 @@ test_keccak_384 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_keccak_512 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf
|
||||
// https://www.di-mgt.com.au/sha_testvectors.html
|
||||
test_vectors := [?]TestHash {
|
||||
@@ -472,7 +479,7 @@ test_keccak_512 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_whirlpool :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://web.archive.org/web/20171129084214/http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", ""},
|
||||
@@ -628,7 +635,7 @@ test_blake2s :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_ripemd_128 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"cdf26213a150dc3ecb610f18f6b38b46", ""},
|
||||
@@ -648,7 +655,7 @@ test_ripemd_128 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_ripemd_160 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""},
|
||||
@@ -668,7 +675,7 @@ test_ripemd_160 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_ripemd_256 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", ""},
|
||||
@@ -677,7 +684,7 @@ test_ripemd_256 :: proc(t: ^testing.T) {
|
||||
TestHash{"87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", "message digest"},
|
||||
TestHash{"649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", "abcdefghijklmnopqrstuvwxyz"},
|
||||
TestHash{"3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
|
||||
TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
}
|
||||
for v, _ in test_vectors {
|
||||
computed := ripemd.hash_256(v.str)
|
||||
@@ -688,7 +695,7 @@ test_ripemd_256 :: proc(t: ^testing.T) {
|
||||
|
||||
@(test)
|
||||
test_ripemd_320 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// Test vectors from
|
||||
// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", ""},
|
||||
@@ -813,7 +820,7 @@ test_sm3 :: proc(t: ^testing.T) {
|
||||
test_vectors := [?]TestHash {
|
||||
TestHash{"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", ""},
|
||||
TestHash{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc"},
|
||||
TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"},
|
||||
TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"},
|
||||
TestHash{"5fdfe814b8573ca021983970fc79b2218c9570369b4859684e2e4c3fc76cb8ea", "The quick brown fox jumps over the lazy dog"},
|
||||
TestHash{"ca27d14a42fc04c1e5ecf574a95a8c2d70ecb5805e9b429026ccac8f28b20098", "The quick brown fox jumps over the lazy cog"},
|
||||
}
|
||||
@@ -945,7 +952,7 @@ test_haval_128 :: proc(t: ^testing.T) {
|
||||
TestHash{"3caf4a79e81adcd6d1716bcc1cef4573", "message digest"},
|
||||
TestHash{"dc502247fb3eb8376109eda32d361d82", "abcdefghijklmnopqrstuvwxyz"},
|
||||
TestHash{"44068770868768964d1f2c3bff4aa3d8", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
|
||||
TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
}
|
||||
for v, _ in test_vectors_3 {
|
||||
computed := haval.hash_128_3(v.str)
|
||||
@@ -981,7 +988,7 @@ test_haval_160 :: proc(t: ^testing.T) {
|
||||
TestHash{"43a47f6f1c016207f08be8115c0977bf155346da", "message digest"},
|
||||
TestHash{"eba9fa6050f24c07c29d1834a60900ea4e32e61b", "abcdefghijklmnopqrstuvwxyz"},
|
||||
TestHash{"c30bce448cf8cfe957c141e90c0a063497cdfeeb", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
|
||||
TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
|
||||
}
|
||||
for v, _ in test_vectors_3 {
|
||||
computed := haval.hash_160_3(v.str)
|
||||
@@ -1100,3 +1107,44 @@ test_haval_256 :: proc(t: ^testing.T) {
|
||||
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||
test_vectors := [?]u64 {
|
||||
0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
|
||||
0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
|
||||
0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
|
||||
0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
|
||||
0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
|
||||
0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
|
||||
0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
|
||||
0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
|
||||
0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
|
||||
0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
|
||||
0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
|
||||
0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
|
||||
0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
|
||||
0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
|
||||
0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
|
||||
0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572,
|
||||
}
|
||||
|
||||
key: [16]byte
|
||||
for i in 0..<16 {
|
||||
key[i] = byte(i)
|
||||
}
|
||||
|
||||
for i in 0..<len(test_vectors) {
|
||||
data := make([]byte, i)
|
||||
for j in 0..<i {
|
||||
data[j] = byte(j)
|
||||
}
|
||||
|
||||
vector := test_vectors[i]
|
||||
computed := siphash.sum_2_4(data[:], key[:])
|
||||
|
||||
expect(t, computed == vector, fmt.tprintf("Expected: 0x%x for input of %v, but got 0x%x instead", vector, data, computed))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
test_rand_bytes :: proc(t: ^testing.T) {
|
||||
log(t, "Testing rand_bytes")
|
||||
|
||||
if ODIN_OS != "linux" {
|
||||
if ODIN_OS != .Linux {
|
||||
log(t, "rand_bytes not supported - skipping")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -50,7 +50,10 @@ def try_download_file(url, out_file):
|
||||
print("Could not download", url)
|
||||
return 1
|
||||
|
||||
def try_download_and_unpack_zip(url, out_file, extract_path):
|
||||
def try_download_and_unpack_zip(suite):
|
||||
url = ASSETS_BASE_URL.format(suite, "{}.zip".format(suite))
|
||||
out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite)
|
||||
|
||||
print("\tDownloading {} to {}.".format(url, out_file))
|
||||
|
||||
if try_download_file(url, out_file) is not None:
|
||||
@@ -62,6 +65,7 @@ def try_download_and_unpack_zip(url, out_file, extract_path):
|
||||
with zipfile.ZipFile(out_file) as z:
|
||||
for file in z.filelist:
|
||||
filename = file.filename
|
||||
extract_path = DOWNLOAD_BASE_PATH.format(suite)
|
||||
|
||||
print("\t\tExtracting: {}".format(filename))
|
||||
z.extract(file, extract_path)
|
||||
@@ -69,56 +73,25 @@ def try_download_and_unpack_zip(url, out_file, extract_path):
|
||||
print("Could not extract ZIP file")
|
||||
return 2
|
||||
|
||||
def download_png_assets():
|
||||
suite = "PNG"
|
||||
url = ASSETS_BASE_URL.format(suite, "{}.zip".format(suite))
|
||||
out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite)
|
||||
extract_path = DOWNLOAD_BASE_PATH.format(suite)
|
||||
|
||||
def main():
|
||||
print("Downloading PNG assets")
|
||||
|
||||
# Make PNG assets path
|
||||
try:
|
||||
path = DOWNLOAD_BASE_PATH.format(suite)
|
||||
path = DOWNLOAD_BASE_PATH.format("PNG")
|
||||
os.makedirs(path)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
# Try downloading and unpacking the PNG assets
|
||||
r = try_download_and_unpack_zip(url, out_file, extract_path)
|
||||
r = try_download_and_unpack_zip("PNG")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
# We could fall back on downloading the PNG files individually, but it's slow
|
||||
|
||||
print("Done downloading PNG assets")
|
||||
|
||||
def download_unicode_assets():
|
||||
suite = "XML"
|
||||
url = "https://www.w3.org/2003/entities/2007xml/unicode.xml.zip"
|
||||
out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite)
|
||||
extract_path = DOWNLOAD_BASE_PATH.format(suite)
|
||||
|
||||
print("Downloading {}.".format(url))
|
||||
|
||||
# Make XML assets path
|
||||
try:
|
||||
path = DOWNLOAD_BASE_PATH.format(suite)
|
||||
os.makedirs(path)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
# Try downloading and unpacking the assets
|
||||
r = try_download_and_unpack_zip(url, out_file, extract_path)
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
print("Done downloading Unicode/XML assets")
|
||||
|
||||
def main():
|
||||
download_png_assets()
|
||||
download_unicode_assets()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
232
tests/core/encoding/hxa/test_core_hxa.odin
Normal file
232
tests/core/encoding/hxa/test_core_hxa.odin
Normal file
@@ -0,0 +1,232 @@
|
||||
// Tests "core:encoding:hxa".
|
||||
// Must be run with `-collection:tests=` flag, e.g.
|
||||
// ./odin run tests/core/encoding/hxa/test_core_hxa.odin -out=tests/core/test_core_hxa -collection:tests=./tests
|
||||
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"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_read(&t)
|
||||
test_write(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_read :: proc(t: ^testing.T) {
|
||||
|
||||
using hxa
|
||||
|
||||
filename := tc.get_data_path(t, TEAPOT_PATH)
|
||||
defer delete(filename)
|
||||
|
||||
file, err := 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 file_destroy(file)
|
||||
|
||||
/* 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))
|
||||
|
||||
/* Nodes (only one) */
|
||||
tc.expect(t, len(file.nodes) == 1, fmt.tprintf("%v: len(file.nodes) %v != %v", #procedure, 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))
|
||||
{
|
||||
e :: "Texture resolution"
|
||||
tc.expect(t, m[0].name == e, fmt.tprintf("%v: m[0].name %v != %v", #procedure, 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))
|
||||
}
|
||||
{
|
||||
e :: "Validate"
|
||||
tc.expect(t, m[37].name == e, fmt.tprintf("%v: m[37].name %v != %v", #procedure, 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))
|
||||
}
|
||||
|
||||
/* 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))
|
||||
|
||||
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))
|
||||
|
||||
/* 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))
|
||||
{
|
||||
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))
|
||||
}
|
||||
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))
|
||||
|
||||
/* 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))
|
||||
|
||||
/* 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))
|
||||
{
|
||||
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))
|
||||
}
|
||||
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))
|
||||
|
||||
/* 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))
|
||||
|
||||
/* 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))
|
||||
}
|
||||
|
||||
@test
|
||||
test_write :: proc(t: ^testing.T) {
|
||||
|
||||
using hxa
|
||||
|
||||
n1 :Node
|
||||
|
||||
n1_m1_value := []f64le{0.4, -1.23, 2341.6, -333.333}
|
||||
n1_m1 := Meta{"m1", n1_m1_value}
|
||||
|
||||
n1.meta_data = []Meta{n1_m1}
|
||||
|
||||
n1_l1 := Layer{"l1", 2, []f32le{32.1, -41.3}}
|
||||
n1_l2 := Layer{"l2", 3, []f64le{0.64, 1.64, -2.64}}
|
||||
|
||||
n1_content := Node_Image{Image_Type.Image_1D, [3]u32le{1, 1, 2}, Layer_Stack{n1_l1, n1_l2}}
|
||||
|
||||
n1.content = n1_content
|
||||
|
||||
w_file :File
|
||||
w_file.nodes = []Node{n1}
|
||||
|
||||
required_size := required_write_size(w_file)
|
||||
buf := make([]u8, required_size)
|
||||
|
||||
n, write_err := 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))
|
||||
|
||||
file, read_err := 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))
|
||||
defer file_destroy(file)
|
||||
|
||||
delete(buf)
|
||||
|
||||
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))
|
||||
|
||||
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)))
|
||||
|
||||
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))
|
||||
|
||||
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)))
|
||||
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]))
|
||||
}
|
||||
|
||||
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)))
|
||||
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))
|
||||
|
||||
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))
|
||||
case []i32le:
|
||||
tc.expect(t, false, fmt.tprintf("%v: 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)))
|
||||
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]))
|
||||
}
|
||||
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)))
|
||||
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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package test_core_json
|
||||
import "core:encoding/json"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -20,17 +21,22 @@ when ODIN_TEST {
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
|
||||
parse_json(&t)
|
||||
marshal_json(&t)
|
||||
unmarshal_json(&t)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -65,7 +71,8 @@ parse_json :: proc(t: ^testing.T) {
|
||||
|
||||
_, err := json.parse(transmute([]u8)json_data)
|
||||
|
||||
expect(t, err == .None, "expected json error to be none")
|
||||
msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
}
|
||||
|
||||
@test
|
||||
@@ -82,6 +89,259 @@ marshal_json :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
_, err := json.marshal(my_struct)
|
||||
|
||||
expect(t, err == .None, "expected json error to be none")
|
||||
msg := fmt.tprintf("Expected `json.marshal` to return nil, got %v", err)
|
||||
expect(t, err == nil, msg)
|
||||
}
|
||||
|
||||
PRODUCTS := `
|
||||
{
|
||||
"cash": "0",
|
||||
"products": [
|
||||
{
|
||||
"name": "Cog\nCola",
|
||||
"cost": "3",
|
||||
"owned": "1",
|
||||
|
||||
"profit": "4",
|
||||
"seconds": 3,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "gingerBeer",
|
||||
"cost": "9",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "16",
|
||||
"seconds": 5,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Coffee",
|
||||
"cost": "27",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "64",
|
||||
"seconds": 7,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Haggis",
|
||||
"cost": "81",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "256",
|
||||
"seconds": 11,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Lasagna",
|
||||
"cost": "243",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "1024",
|
||||
"seconds": 13,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Asparagus",
|
||||
"cost": "729",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "4096",
|
||||
"seconds": 17,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Yorkshire Pudding",
|
||||
"cost": "2187",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "16384",
|
||||
"seconds": 19,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Salmon Wrap",
|
||||
"cost": "6561",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "65536",
|
||||
"seconds": 23,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Poke Bowl",
|
||||
"cost": "19683",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "262144",
|
||||
"seconds": 29,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
{
|
||||
"name": "Chili Con Carne",
|
||||
"cost": "59049",
|
||||
"owned": "0",
|
||||
|
||||
"profit": "1048576",
|
||||
"seconds": 59,
|
||||
"multiplier": 1,
|
||||
"auto_click": false
|
||||
},
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
original_data := Game_Marshal{
|
||||
cash = "0",
|
||||
products = {
|
||||
{
|
||||
name = "Cog\nCola",
|
||||
cost = "3",
|
||||
owned = "1",
|
||||
profit = "4",
|
||||
seconds = 3,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "gingerBeer",
|
||||
cost = "9",
|
||||
owned = "0",
|
||||
profit = "16",
|
||||
seconds = 5,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Coffee",
|
||||
cost = "27",
|
||||
owned = "0",
|
||||
profit = "64",
|
||||
seconds = 7,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Haggis",
|
||||
cost = "81",
|
||||
owned = "0",
|
||||
profit = "256",
|
||||
seconds = 11,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Lasagna",
|
||||
cost = "243",
|
||||
owned = "0",
|
||||
profit = "1024",
|
||||
seconds = 13,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Asparagus",
|
||||
cost = "729",
|
||||
owned = "0",
|
||||
profit = "4096",
|
||||
seconds = 17,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Yorkshire Pudding",
|
||||
cost = "2187",
|
||||
owned = "0",
|
||||
profit = "16384",
|
||||
seconds = 19,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Salmon Wrap",
|
||||
cost = "6561",
|
||||
owned = "0",
|
||||
profit = "65536",
|
||||
seconds = 23,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Poke Bowl",
|
||||
cost = "19683",
|
||||
owned = "0",
|
||||
profit = "262144",
|
||||
seconds = 29,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
{
|
||||
name = "Chili Con Carne",
|
||||
cost = "59049",
|
||||
owned = "0",
|
||||
profit = "1048576",
|
||||
seconds = 59,
|
||||
multiplier = 1,
|
||||
auto_click = false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Product_Marshal :: struct {
|
||||
name: cstring,
|
||||
owned: string,
|
||||
|
||||
cost: string,
|
||||
|
||||
profit: string,
|
||||
seconds: int,
|
||||
multiplier: int,
|
||||
|
||||
auto_click: bool,
|
||||
}
|
||||
|
||||
Game_Marshal :: struct {
|
||||
cash: string,
|
||||
products: []Product_Marshal,
|
||||
}
|
||||
|
||||
cleanup :: proc(g: Game_Marshal) {
|
||||
for p in g.products {
|
||||
delete(p.name)
|
||||
delete(p.owned)
|
||||
delete(p.cost)
|
||||
delete(p.profit)
|
||||
}
|
||||
delete(g.products)
|
||||
delete(g.cash)
|
||||
}
|
||||
|
||||
@test
|
||||
unmarshal_json :: proc(t: ^testing.T) {
|
||||
g: Game_Marshal
|
||||
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)
|
||||
|
||||
for p, i in g.products {
|
||||
expect(t, p == original_data.products[i], "Producted unmarshaled improperly")
|
||||
}
|
||||
}
|
||||
156
tests/core/encoding/varint/test_core_varint.odin
Normal file
156
tests/core/encoding/varint/test_core_varint.odin
Normal file
@@ -0,0 +1,156 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_leb128 :: 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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
for num_bytes in 1..uint(16) {
|
||||
for _ in 0..RANDOM_TESTS {
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
{
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_random :: proc(byte_count: uint) -> (u: u128, i: i128) {
|
||||
assert(byte_count >= 0 && byte_count <= size_of(u128))
|
||||
|
||||
for _ in 1..byte_count {
|
||||
u <<= 8
|
||||
u |= u128(rand.uint32() & 0xff)
|
||||
}
|
||||
|
||||
bias := i128(1 << (byte_count * 7)) - 1
|
||||
i = i128(u) - bias
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
ULEB_Test_Vector :: struct {
|
||||
encoded: []u8,
|
||||
value: u128,
|
||||
size: int,
|
||||
error: varint.Error,
|
||||
}
|
||||
|
||||
ULEB_Vectors :: []ULEB_Test_Vector{
|
||||
{ []u8{0x00}, 0, 1, .None },
|
||||
{ []u8{0x7f}, 127, 1, .None },
|
||||
{ []u8{0xE5, 0x8E, 0x26}, 624485, 3, .None },
|
||||
{ []u8{0x80}, 0, 0, .Buffer_Too_Small },
|
||||
{ []u8{}, 0, 0, .Buffer_Too_Small },
|
||||
|
||||
{ []u8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}, max(u128), 19, .None },
|
||||
}
|
||||
|
||||
ILEB_Test_Vector :: struct {
|
||||
encoded: []u8,
|
||||
value: i128,
|
||||
size: int,
|
||||
error: varint.Error,
|
||||
}
|
||||
|
||||
ILEB_Vectors :: []ILEB_Test_Vector{
|
||||
{ []u8{0x00}, 0, 1, .None },
|
||||
{ []u8{0x3f}, 63, 1, .None },
|
||||
{ []u8{0x40}, -64, 1, .None },
|
||||
{ []u8{0xC0, 0xBB, 0x78}, -123456, 3, .None },
|
||||
{ []u8{}, 0, 0, .Buffer_Too_Small },
|
||||
|
||||
{ []u8{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e}, min(i128), 19, .None },
|
||||
{ []u8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, max(i128), 19, .None },
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import "core:hash"
|
||||
import "core:time"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -17,12 +18,13 @@ when ODIN_TEST {
|
||||
TEST_count += 1
|
||||
if !condition {
|
||||
TEST_fail += 1
|
||||
fmt.printf("[%v] %v", loc, message)
|
||||
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)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +33,10 @@ main :: proc() {
|
||||
test_benchmark_runner(&t)
|
||||
test_xxhash_vectors(&t)
|
||||
test_crc64_vectors(&t)
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
List of contributors:
|
||||
Jeroen van Rijn: Initial implementation.
|
||||
|
||||
A test suite for PNG.
|
||||
A test suite for PNG + QOI.
|
||||
*/
|
||||
package test_core_image
|
||||
|
||||
@@ -14,6 +14,7 @@ import "core:testing"
|
||||
import "core:compress"
|
||||
import "core:image"
|
||||
import "core:image/png"
|
||||
import "core:image/qoi"
|
||||
|
||||
import "core:bytes"
|
||||
import "core:hash"
|
||||
@@ -25,8 +26,8 @@ import "core:time"
|
||||
|
||||
import "core:runtime"
|
||||
|
||||
WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false)
|
||||
TEST_FILE_PATH_PREFIX :: "tests/core/assets/PNG"
|
||||
WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false)
|
||||
TEST_SUITE_PATH :: "assets/PNG"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -44,30 +45,20 @@ when ODIN_TEST {
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
I_Error :: image.Error
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
png_test(&t)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
}
|
||||
|
||||
test_file_path :: proc(filename: string, extension := "png") -> (path: string) {
|
||||
|
||||
path = fmt.tprintf("%v%v/%v.%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename, extension)
|
||||
temp := transmute([]u8)path
|
||||
|
||||
for r, i in path {
|
||||
if r == '\\' {
|
||||
temp[i] = '/'
|
||||
}
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
PNG_Test :: struct {
|
||||
@@ -1472,7 +1463,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
context = runtime.default_context()
|
||||
|
||||
for file in suite {
|
||||
test_file := test_file_path(file.file)
|
||||
test_file := fmt.tprintf("%v/%v.png", TEST_SUITE_PATH, file.file)
|
||||
|
||||
img: ^png.Image
|
||||
err: png.Error
|
||||
@@ -1509,11 +1500,34 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
||||
|
||||
passed &= dims_pass
|
||||
|
||||
hash := hash.crc32(pixels)
|
||||
error = fmt.tprintf("%v test %v hash is %08x, expected %08x.", file.file, count, hash, test.hash)
|
||||
expect(t, test.hash == hash, error)
|
||||
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)
|
||||
|
||||
passed &= test.hash == png_hash
|
||||
|
||||
// Roundtrip through QOI to test the QOI encoder and decoder.
|
||||
if passed && img.depth == 8 && (img.channels == 3 || img.channels == 4) {
|
||||
qoi_buffer: bytes.Buffer
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
passed &= test.hash == hash
|
||||
if .return_metadata in test.options {
|
||||
|
||||
if v, ok := img.metadata.(^image.PNG_Info); ok {
|
||||
@@ -1778,7 +1792,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b
|
||||
img := image
|
||||
|
||||
// PBM 16-bit images are big endian
|
||||
when ODIN_ENDIAN == "little" {
|
||||
when ODIN_ENDIAN == .Little {
|
||||
if img.depth == 16 {
|
||||
// The pixel components are in Big Endian. Let's byteswap back.
|
||||
input := mem.slice_data_cast([]u16, img.pixels.buf[:])
|
||||
@@ -1796,7 +1810,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b
|
||||
}
|
||||
|
||||
mode: int = 0
|
||||
when ODIN_OS == "linux" || ODIN_OS == "darwin" {
|
||||
when ODIN_OS == .Linux || ODIN_OS == .Darwin {
|
||||
// NOTE(justasd): 644 (owner read, write; group read; others read)
|
||||
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
|
||||
}
|
||||
|
||||
@@ -4,14 +4,11 @@ set PATH_TO_ODIN==..\..\..\..\odin
|
||||
set TEST_ARGS=-fast-tests
|
||||
set TEST_ARGS=-no-random
|
||||
set TEST_ARGS=
|
||||
set OUT_NAME=math_big_test_library
|
||||
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
|
||||
echo ---
|
||||
echo Running core:math/big tests
|
||||
echo ---
|
||||
|
||||
rem Fails
|
||||
:%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME%
|
||||
rem Passes
|
||||
%PATH_TO_ODIN% build . %COMMON% -o:size -out:%OUT_NAME%
|
||||
%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME%
|
||||
python3 test.py %TEST_ARGS%
|
||||
@@ -32,9 +32,9 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring {
|
||||
|
||||
@export test_initialize_constants :: proc "c" () -> (res: u64) {
|
||||
context = runtime.default_context()
|
||||
res = u64(big.initialize_constants())
|
||||
//assert(MUL_KARATSUBA_CUTOFF >= 40);
|
||||
return res
|
||||
_ = big.initialize_constants()
|
||||
|
||||
return u64(big._DIGIT_NAILS)
|
||||
}
|
||||
|
||||
@export test_error_string :: proc "c" (err: big.Error) -> (res: cstring) {
|
||||
@@ -208,7 +208,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring {
|
||||
/*
|
||||
dest = shr_digit(src, digits)
|
||||
*/
|
||||
@export test_shr_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
|
||||
@export test_shr_leg :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
|
||||
context = runtime.default_context()
|
||||
err: big.Error
|
||||
|
||||
@@ -216,7 +216,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring {
|
||||
defer big.internal_destroy(src)
|
||||
|
||||
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_digit:atoi(src):", err=err} }
|
||||
if err = #force_inline big.internal_shr_digit(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err} }
|
||||
if err = #force_inline big._private_int_shr_leg(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err} }
|
||||
|
||||
r := print_to_buffer(src)
|
||||
return PyRes{res = r, err = nil}
|
||||
@@ -225,7 +225,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring {
|
||||
/*
|
||||
dest = shl_digit(src, digits)
|
||||
*/
|
||||
@export test_shl_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
|
||||
@export test_shl_leg :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
|
||||
context = runtime.default_context()
|
||||
err: big.Error
|
||||
|
||||
@@ -233,7 +233,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring {
|
||||
defer big.internal_destroy(src)
|
||||
|
||||
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shl_digit:atoi(src):", err=err} }
|
||||
if err = #force_inline big.internal_shl_digit(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err} }
|
||||
if err = #force_inline big._private_int_shl_leg(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err} }
|
||||
|
||||
r := print_to_buffer(src)
|
||||
return PyRes{res = r, err = nil}
|
||||
|
||||
@@ -17,7 +17,6 @@ import gc
|
||||
from enum import Enum
|
||||
import argparse
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description = "Odin core:math/big test suite",
|
||||
epilog = "By default we run regression and random tests with preset parameters.",
|
||||
@@ -127,17 +126,22 @@ def we_iterate():
|
||||
# Error enum values
|
||||
#
|
||||
class Error(Enum):
|
||||
Okay = 0
|
||||
Out_Of_Memory = 1
|
||||
Invalid_Pointer = 2
|
||||
Invalid_Argument = 3
|
||||
Unknown_Error = 4
|
||||
Max_Iterations_Reached = 5
|
||||
Buffer_Overflow = 6
|
||||
Integer_Overflow = 7
|
||||
Division_by_Zero = 8
|
||||
Math_Domain_Error = 9
|
||||
Unimplemented = 127
|
||||
Okay = 0
|
||||
Out_Of_Memory = 1
|
||||
Invalid_Pointer = 2
|
||||
Invalid_Argument = 3
|
||||
Unknown_Error = 4
|
||||
Assignment_To_Immutable = 10
|
||||
Max_Iterations_Reached = 11
|
||||
Buffer_Overflow = 12
|
||||
Integer_Overflow = 13
|
||||
Integer_Underflow = 14
|
||||
Division_by_Zero = 30
|
||||
Math_Domain_Error = 31
|
||||
Cannot_Open_File = 50
|
||||
Cannot_Read_File = 51
|
||||
Cannot_Write_File = 52
|
||||
Unimplemented = 127
|
||||
|
||||
#
|
||||
# Disable garbage collection
|
||||
@@ -158,6 +162,8 @@ def load(export_name, args, res):
|
||||
export_name.restype = res
|
||||
return export_name
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Result values will be passed in a struct { res: cstring, err: Error }
|
||||
#
|
||||
@@ -165,7 +171,11 @@ class Res(Structure):
|
||||
_fields_ = [("res", c_char_p), ("err", c_uint64)]
|
||||
|
||||
initialize_constants = load(l.test_initialize_constants, [], c_uint64)
|
||||
print("initialize_constants: ", initialize_constants())
|
||||
|
||||
NAILS = initialize_constants()
|
||||
LEG_BITS = 64 - NAILS
|
||||
|
||||
print("LEG BITS: ", LEG_BITS)
|
||||
|
||||
error_string = load(l.test_error_string, [c_byte], c_char_p)
|
||||
|
||||
@@ -182,8 +192,8 @@ int_sqrt = load(l.test_sqrt, [c_char_p ], Res)
|
||||
int_root_n = load(l.test_root_n, [c_char_p, c_longlong], Res)
|
||||
|
||||
# Logical operations
|
||||
int_shl_digit = load(l.test_shl_digit, [c_char_p, c_longlong], Res)
|
||||
int_shr_digit = load(l.test_shr_digit, [c_char_p, c_longlong], Res)
|
||||
int_shl_leg = load(l.test_shl_leg, [c_char_p, c_longlong], Res)
|
||||
int_shr_leg = load(l.test_shr_leg, [c_char_p, c_longlong], Res)
|
||||
int_shl = load(l.test_shl, [c_char_p, c_longlong], Res)
|
||||
int_shr = load(l.test_shr, [c_char_p, c_longlong], Res)
|
||||
int_shr_signed = load(l.test_shr_signed, [c_char_p, c_longlong], Res)
|
||||
@@ -397,26 +407,26 @@ def test_root_n(number = 0, root = 0, expected_error = Error.Okay):
|
||||
|
||||
return test("test_root_n", res, [number, root], expected_error, expected_result)
|
||||
|
||||
def test_shl_digit(a = 0, digits = 0, expected_error = Error.Okay):
|
||||
def test_shl_leg(a = 0, digits = 0, expected_error = Error.Okay):
|
||||
args = [arg_to_odin(a), digits]
|
||||
res = int_shl_digit(*args)
|
||||
res = int_shl_leg(*args)
|
||||
expected_result = None
|
||||
if expected_error == Error.Okay:
|
||||
expected_result = a << (digits * 60)
|
||||
return test("test_shl_digit", res, [a, digits], expected_error, expected_result)
|
||||
expected_result = a << (digits * LEG_BITS)
|
||||
return test("test_shl_leg", res, [a, digits], expected_error, expected_result)
|
||||
|
||||
def test_shr_digit(a = 0, digits = 0, expected_error = Error.Okay):
|
||||
def test_shr_leg(a = 0, digits = 0, expected_error = Error.Okay):
|
||||
args = [arg_to_odin(a), digits]
|
||||
res = int_shr_digit(*args)
|
||||
res = int_shr_leg(*args)
|
||||
expected_result = None
|
||||
if expected_error == Error.Okay:
|
||||
if a < 0:
|
||||
# Don't pass negative numbers. We have a shr_signed.
|
||||
return False
|
||||
else:
|
||||
expected_result = a >> (digits * 60)
|
||||
expected_result = a >> (digits * LEG_BITS)
|
||||
|
||||
return test("test_shr_digit", res, [a, digits], expected_error, expected_result)
|
||||
return test("test_shr_leg", res, [a, digits], expected_error, expected_result)
|
||||
|
||||
def test_shl(a = 0, bits = 0, expected_error = Error.Okay):
|
||||
args = [arg_to_odin(a), bits]
|
||||
@@ -551,12 +561,12 @@ TESTS = {
|
||||
test_root_n: [
|
||||
[ 1298074214633706907132624082305024, 2, Error.Okay, ],
|
||||
],
|
||||
test_shl_digit: [
|
||||
test_shl_leg: [
|
||||
[ 3192, 1 ],
|
||||
[ 1298074214633706907132624082305024, 2 ],
|
||||
[ 1024, 3 ],
|
||||
],
|
||||
test_shr_digit: [
|
||||
test_shr_leg: [
|
||||
[ 3680125442705055547392, 1 ],
|
||||
[ 1725436586697640946858688965569256363112777243042596638790631055949824, 2 ],
|
||||
[ 219504133884436710204395031992179571, 2 ],
|
||||
@@ -614,10 +624,10 @@ total_failures = 0
|
||||
# test_shr_signed also tests shr, so we're not going to test shr randomly.
|
||||
#
|
||||
RANDOM_TESTS = [
|
||||
test_add, test_sub, test_mul, test_sqr, test_div,
|
||||
test_log, test_pow, test_sqrt, test_root_n,
|
||||
test_shl_digit, test_shr_digit, test_shl, test_shr_signed,
|
||||
test_gcd, test_lcm, test_is_square,
|
||||
test_add, test_sub, test_mul, test_sqr,
|
||||
test_log, test_pow, test_sqrt, test_root_n,
|
||||
test_shl_leg, test_shr_leg, test_shl, test_shr_signed,
|
||||
test_gcd, test_lcm, test_is_square, test_div,
|
||||
]
|
||||
SKIP_LARGE = [
|
||||
test_pow, test_root_n, # test_gcd,
|
||||
@@ -714,9 +724,9 @@ if __name__ == '__main__':
|
||||
a = randint(1, 1 << BITS)
|
||||
b = TEST_ROOT_N_PARAMS[index]
|
||||
index = (index + 1) % len(TEST_ROOT_N_PARAMS)
|
||||
elif test_proc == test_shl_digit:
|
||||
elif test_proc == test_shl_leg:
|
||||
b = randint(0, 10);
|
||||
elif test_proc == test_shr_digit:
|
||||
elif test_proc == test_shr_leg:
|
||||
a = abs(a)
|
||||
b = randint(0, 10);
|
||||
elif test_proc == test_shl:
|
||||
|
||||
85
tests/core/math/linalg/glsl/test_linalg_glsl_math.odin
Normal file
85
tests/core/math/linalg/glsl/test_linalg_glsl_math.odin
Normal file
@@ -0,0 +1,85 @@
|
||||
// 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) {
|
||||
|
||||
using math
|
||||
|
||||
r: f32
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f32,
|
||||
e: f32,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 10.5, 0.5 }, // Issue #1574 fract in linalg/glm is broken
|
||||
{ 1, -10.5, -0.5 },
|
||||
{ 2, F32_MIN, F32_MIN }, // 0x1p-126
|
||||
{ 3, -F32_MIN, -F32_MIN },
|
||||
{ 4, 0.0, 0.0 },
|
||||
{ 5, -0.0, -0.0 },
|
||||
{ 6, 1, 0.0 },
|
||||
{ 7, -1, -0.0 },
|
||||
{ 8, 0h3F80_0001, 0h3400_0000 }, // 0x1.000002p+0, 0x1p-23
|
||||
{ 9, -0h3F80_0001, -0h3400_0000 },
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_fract_f64 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
|
||||
r: f64
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f64,
|
||||
e: f64,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 10.5, 0.5 }, // Issue #1574 fract in linalg/glm is broken
|
||||
{ 1, -10.5, -0.5 },
|
||||
{ 2, F64_MIN, F64_MIN }, // 0x1p-1022
|
||||
{ 3, -F64_MIN, -F64_MIN },
|
||||
{ 4, 0.0, 0.0 },
|
||||
{ 5, -0.0, -0.0 },
|
||||
{ 6, 1, 0.0 },
|
||||
{ 7, -1, -0.0 },
|
||||
{ 8, 0h3FF0_0000_0000_0001, 0h3CB0_0000_0000_0000 }, // 0x1.0000000000001p+0, 0x1p-52
|
||||
{ 9, -0h3FF0_0000_0000_0001, -0h3CB0_0000_0000_0000 },
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
151
tests/core/math/noise/test_core_math_noise.odin
Normal file
151
tests/core/math/noise/test_core_math_noise.odin
Normal file
@@ -0,0 +1,151 @@
|
||||
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,
|
||||
coord: union {V2, V3, V4},
|
||||
expected: f32,
|
||||
|
||||
test_proc: union {
|
||||
proc(_: i64, _: V2) -> f32,
|
||||
proc(_: i64, _: V3) -> f32,
|
||||
proc(_: i64, _: V4) -> f32,
|
||||
},
|
||||
}
|
||||
|
||||
SEED_1 :: 2324223232
|
||||
SEED_2 :: 932466901
|
||||
SEED_3 :: 9321
|
||||
|
||||
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},
|
||||
|
||||
}
|
||||
|
||||
noise_test :: proc(t: ^testing.T) {
|
||||
for test in Noise_Tests {
|
||||
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))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
310
tests/core/math/test_core_math.odin
Normal file
310
tests/core/math/test_core_math.odin
Normal file
@@ -0,0 +1,310 @@
|
||||
// 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)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_classify_f16 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
using Float_Class
|
||||
|
||||
r: Float_Class
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f16,
|
||||
e: math.Float_Class,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 1.2, Normal },
|
||||
{ 1, 0h0001, Subnormal },
|
||||
{ 2, 0.0, Zero },
|
||||
{ 3, -0.0, Neg_Zero },
|
||||
{ 4, SNAN_F16, NaN },
|
||||
{ 5, QNAN_F16, NaN },
|
||||
{ 6, INF_F16, Inf },
|
||||
{ 7, NEG_INF_F16, Neg_Inf },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
|
||||
/* Check all subnormals (exponent 0, 10-bit significand non-zero) */
|
||||
for i :u16 = 1; i < 0x400; i += 1 {
|
||||
v :f16 = transmute(f16)i
|
||||
r = classify_f16(v)
|
||||
e :Float_Class: Subnormal
|
||||
tc.expect(t, r == e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, v, r, e))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_classify_f32 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
using Float_Class
|
||||
|
||||
r: Float_Class
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f32,
|
||||
e: math.Float_Class,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 1.2, Normal },
|
||||
{ 1, 0h0000_0001, Subnormal },
|
||||
{ 2, 0.0, Zero },
|
||||
{ 3, -0.0, Neg_Zero },
|
||||
{ 4, SNAN_F32, NaN },
|
||||
{ 5, QNAN_F32, NaN },
|
||||
{ 6, INF_F32, Inf },
|
||||
{ 7, NEG_INF_F32, Neg_Inf },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_classify_f64 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
using Float_Class
|
||||
|
||||
r: Float_Class
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f64,
|
||||
e: math.Float_Class,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 1.2, Normal },
|
||||
{ 1, 0h0000_0000_0000_0001, Subnormal },
|
||||
{ 2, 0.0, Zero },
|
||||
{ 3, -0.0, Neg_Zero },
|
||||
{ 4, SNAN_F64, NaN },
|
||||
{ 5, QNAN_F64, NaN },
|
||||
{ 6, INF_F64, Inf },
|
||||
{ 7, NEG_INF_F64, Neg_Inf },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_trunc_f16 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
|
||||
r, v: f16
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f16,
|
||||
e: f16,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
|
||||
{ 1, -10.5, -10 },
|
||||
|
||||
{ 2, F16_MAX, F16_MAX },
|
||||
{ 3, -F16_MAX, -F16_MAX },
|
||||
{ 4, F16_MIN, 0.0 },
|
||||
{ 5, -F16_MIN, -0.0 },
|
||||
{ 6, 0.0, 0.0 },
|
||||
{ 7, -0.0, -0.0 },
|
||||
{ 8, 1, 1 },
|
||||
{ 9, -1, -1 },
|
||||
{ 10, INF_F16, INF_F16 },
|
||||
{ 11, NEG_INF_F16, NEG_INF_F16 },
|
||||
|
||||
/* From https://en.wikipedia.org/wiki/Half-precision_floating-point_format */
|
||||
{ 12, 0h3C01, 1 }, // 0x1.004p+0 (smallest > 1)
|
||||
{ 13, -0h3C01, -1 },
|
||||
{ 14, 0h3BFF, 0.0 }, // 0x1.ffcp-1 (largest < 1)
|
||||
{ 15, -0h3BFF, -0.0 },
|
||||
{ 16, 0h0001, 0.0 }, // 0x0.004p-14 (smallest subnormal)
|
||||
{ 17, -0h0001, -0.0 },
|
||||
{ 18, 0h03FF, 0.0 }, // 0x0.ffcp-14 (largest subnormal)
|
||||
{ 19, -0h03FF, -0.0 },
|
||||
|
||||
{ 20, 0hC809, -8 }, // -0x1.024p+3
|
||||
{ 21, 0h4458, 4 }, // 0x1.16p+2
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
|
||||
v = SNAN_F16
|
||||
r = trunc_f16(v)
|
||||
tc.expect(t, is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
|
||||
v = QNAN_F16
|
||||
r = trunc_f16(v)
|
||||
tc.expect(t, is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
}
|
||||
|
||||
@test
|
||||
test_trunc_f32 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
|
||||
r, v: f32
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f32,
|
||||
e: f32,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
|
||||
{ 1, -10.5, -10 },
|
||||
|
||||
{ 2, F32_MAX, F32_MAX },
|
||||
{ 3, -F32_MAX, -F32_MAX },
|
||||
{ 4, F32_MIN, 0.0 },
|
||||
{ 5, -F32_MIN, -0.0 },
|
||||
{ 6, 0.0, 0.0 },
|
||||
{ 7, -0.0, -0.0 },
|
||||
{ 8, 1, 1 },
|
||||
{ 9, -1, -1 },
|
||||
{ 10, INF_F32, INF_F32 },
|
||||
{ 11, NEG_INF_F32, NEG_INF_F32 },
|
||||
|
||||
/* From https://en.wikipedia.org/wiki/Single-precision_floating-point_format */
|
||||
{ 12, 0h3F80_0001, 1 }, // 0x1.000002p+0 (smallest > 1)
|
||||
{ 13, -0h3F80_0001, -1 },
|
||||
{ 14, 0h3F7F_FFFF, 0.0 }, // 0x1.fffffep-1 (largest < 1)
|
||||
{ 15, -0h3F7F_FFFF, -0.0 },
|
||||
{ 16, 0h0000_0001, 0.0 }, // 0x0.000002p-126 (smallest subnormal)
|
||||
{ 17, -0h0000_0001, -0.0 },
|
||||
{ 18, 0h007F_FFFF, 0.0 }, // 0x0.fffffep-126 (largest subnormal)
|
||||
{ 19, -0h007F_FFFF, -0.0 },
|
||||
|
||||
/* From libc-test src/math/sanity/truncf.h */
|
||||
{ 20, 0hC101_11D0, -8 }, // -0x1.0223ap+3
|
||||
{ 21, 0h408B_0C34, 4 }, // 0x1.161868p+2
|
||||
{ 22, 0hC106_1A5A, -8 }, // -0x1.0c34b4p+3
|
||||
{ 23, 0hC0D1_0378, -6 }, // -0x1.a206fp+2
|
||||
{ 24, 0h4114_45DE, 9 }, // 0x1.288bbcp+3
|
||||
{ 25, 0h3F29_77E8, 0.0 }, // 0x1.52efdp-1
|
||||
{ 26, 0hBED0_2E64, -0.0 }, // -0x1.a05cc8p-2
|
||||
{ 27, 0h3F0F_CF7D, 0.0 }, // 0x1.1f9efap-1
|
||||
{ 28, 0h3F46_2ED8, 0.0 }, // 0x1.8c5dbp-1
|
||||
{ 29, 0hBF2D_C375, -0.0 }, // -0x1.5b86eap-1
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
|
||||
v = SNAN_F32
|
||||
r = trunc_f32(v)
|
||||
tc.expect(t, is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
|
||||
v = QNAN_F32
|
||||
r = trunc_f32(v)
|
||||
tc.expect(t, is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
}
|
||||
|
||||
@test
|
||||
test_trunc_f64 :: proc(t: ^testing.T) {
|
||||
|
||||
using math
|
||||
|
||||
r, v: f64
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: f64,
|
||||
e: f64,
|
||||
}
|
||||
data := []Datum{
|
||||
{ 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken
|
||||
{ 1, -10.5, -10 },
|
||||
|
||||
{ 2, F64_MAX, F64_MAX },
|
||||
{ 3, -F64_MAX, -F64_MAX },
|
||||
{ 4, F64_MIN, 0.0 },
|
||||
{ 5, -F64_MIN, -0.0 },
|
||||
{ 6, 0.0, 0.0 },
|
||||
{ 7, -0.0, -0.0 },
|
||||
{ 8, 1, 1 },
|
||||
{ 9, -1, -1 },
|
||||
{ 10, INF_F64, INF_F64 },
|
||||
{ 11, NEG_INF_F64, NEG_INF_F64 },
|
||||
|
||||
/* From https://en.wikipedia.org/wiki/Double-precision_floating-point_format */
|
||||
{ 12, 0h3FF0_0000_0000_0001, 1 }, // 0x1.0000000000001p+0 (smallest > 1)
|
||||
{ 13, -0h3FF0_0000_0000_0001, -1 },
|
||||
{ 14, 0h3FEF_FFFF_FFFF_FFFF, 0.0 }, // 0x1.fffffffffffffp-1 (largest < 1)
|
||||
{ 15, -0h3FEF_FFFF_FFFF_FFFF, -0.0 },
|
||||
{ 16, 0h0000_0000_0000_0001, 0.0 }, // 0x0.0000000000001p-1022 (smallest subnormal)
|
||||
{ 17, -0h0000_0000_0000_0001, -0.0 },
|
||||
{ 18, 0h000F_FFFF_FFFF_FFFF, 0.0 }, // 0x0.fffffffffffffp-1022 (largest subnormal)
|
||||
{ 19, -0h000F_FFFF_FFFF_FFFF, -0.0 },
|
||||
|
||||
/* From libc-test src/math/sanity/trunc.h */
|
||||
{ 20, 0hC020_2239_F3C6_A8F1, -8 }, // -0x1.02239f3c6a8f1p+3
|
||||
{ 21, 0h4011_6186_8E18_BC67, 4 }, // 0x1.161868e18bc67p+2
|
||||
{ 22, 0hC020_C34B_3E01_E6E7, -8 }, // -0x1.0c34b3e01e6e7p+3
|
||||
{ 23, 0hC01A_206F_0A19_DCC4, -6 }, // -0x1.a206f0a19dcc4p+2
|
||||
{ 24, 0h4022_88BB_B0D6_A1E6, 9 }, // 0x1.288bbb0d6a1e6p+3
|
||||
{ 25, 0h3FE5_2EFD_0CD8_0497, 0.0 }, // 0x1.52efd0cd80497p-1
|
||||
{ 26, 0hBFDA_05CC_7544_81D1, -0.0 }, // -0x1.a05cc754481d1p-2
|
||||
{ 27, 0h3FE1_F9EF_9347_45CB, 0.0 }, // 0x1.1f9ef934745cbp-1
|
||||
{ 28, 0h3FE8_C5DB_097F_7442, 0.0 }, // 0x1.8c5db097f7442p-1
|
||||
{ 29, 0hBFE5_B86E_A811_8A0E, -0.0 }, // -0x1.5b86ea8118a0ep-1
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r = 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))
|
||||
}
|
||||
|
||||
v = SNAN_F64
|
||||
r = trunc_f64(v)
|
||||
tc.expect(t, is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
|
||||
v = QNAN_F64
|
||||
r = trunc_f64(v)
|
||||
tc.expect(t, is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r))
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package test_core_odin_parser
|
||||
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
|
||||
import "core:os"
|
||||
import "core:odin/parser"
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ when ODIN_TEST {
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +31,13 @@ main :: proc() {
|
||||
t := testing.T{}
|
||||
test_parse_demo(&t)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
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")
|
||||
@@ -42,4 +47,4 @@ test_parse_demo :: proc(t: ^testing.T) {
|
||||
for key, value in pkg.files {
|
||||
expect(t, value.syntax_error_count == 0, fmt.tprintf("%v should contain zero errors", key))
|
||||
}
|
||||
}
|
||||
}
|
||||
10
tests/core/os/test_core_os_exit.odin
Normal file
10
tests/core/os/test_core_os_exit.odin
Normal file
@@ -0,0 +1,10 @@
|
||||
// Tests that Odin run returns exit code of built executable on Unix
|
||||
// Needs exit status to be inverted to return 0 on success, e.g.
|
||||
// $(./odin run tests/core/os/test_core_os_exit.odin && exit 1 || exit 0)
|
||||
package test_core_os_exit
|
||||
|
||||
import "core:os"
|
||||
|
||||
main :: proc() {
|
||||
os.exit(1)
|
||||
}
|
||||
123
tests/core/path/filepath/test_core_filepath.odin
Normal file
123
tests/core/path/filepath/test_core_filepath.odin
Normal file
@@ -0,0 +1,123 @@
|
||||
// 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{}
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
test_split_list_windows(&t)
|
||||
} else {
|
||||
test_split_list_unix(&t)
|
||||
}
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
@test
|
||||
test_split_list_windows :: proc(t: ^testing.T) {
|
||||
|
||||
using filepath
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: string,
|
||||
e: [3]string,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, "C:\\Odin;C:\\Visual Studio;\"C:\\Some Other\"",
|
||||
[3]string{"C:\\Odin", "C:\\Visual Studio", "C:\\Some Other"} }, // 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"} },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i))
|
||||
r := 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)))
|
||||
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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
v := ""
|
||||
r := split_list(v)
|
||||
tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r))
|
||||
}
|
||||
{
|
||||
v := "a"
|
||||
r := split_list(v)
|
||||
defer delete(r)
|
||||
tc.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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_split_list_unix :: proc(t: ^testing.T) {
|
||||
|
||||
using filepath
|
||||
|
||||
Datum :: struct {
|
||||
i: int,
|
||||
v: string,
|
||||
e: [3]string,
|
||||
}
|
||||
@static data := []Datum{
|
||||
{ 0, "/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"} },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i))
|
||||
r := 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)))
|
||||
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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
v := ""
|
||||
r := split_list(v)
|
||||
tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r))
|
||||
}
|
||||
{
|
||||
v := "a"
|
||||
r := split_list(v)
|
||||
defer delete(r)
|
||||
tc.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]))
|
||||
}
|
||||
}
|
||||
}
|
||||
288
tests/core/reflect/test_core_reflect.odin
Normal file
288
tests/core/reflect/test_core_reflect.odin
Normal file
@@ -0,0 +1,288 @@
|
||||
// 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) {
|
||||
using reflect
|
||||
|
||||
{
|
||||
/* i8 */
|
||||
Datum :: struct { i: int, v: i8, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7F, 0x7F },
|
||||
{ 1, -1, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 2, -0x80, 0xFFFF_FFFF_FFFF_FF80 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i16 */
|
||||
Datum :: struct { i: int, v: i16, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF, 0x7FFF },
|
||||
{ 1, -1, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 2, -0x8000, 0xFFFF_FFFF_FFFF_8000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i32 */
|
||||
Datum :: struct { i: int, v: i32, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF, 0x7FFF_FFFF },
|
||||
{ 1, -1, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 2, -0x8000_0000, 0xFFFF_FFFF_8000_0000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i64 */
|
||||
Datum :: struct { i: int, v: i64, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF },
|
||||
{ 1, -1, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 2, -0x8000_0000_0000_0000, 0x8000_0000_0000_0000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i128 */
|
||||
Datum :: struct { i: int, v: i128, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 1, -1, 0xFFFF_FFFF_FFFF_FFFF },
|
||||
{ 2, 0x8000_0000_0000_0000, 0x8000_0000_0000_0000 },
|
||||
{ 3, -0x8000_0000_0000_0000, 0x8000_0000_0000_0000 },
|
||||
{ 4, 0x0001_0000_0000_0000_0000, 0 },
|
||||
{ 5, -0x8000_0000_0000_0000_0000_0000_0000_0000, 0 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f16 */
|
||||
Datum :: struct { i: int, v: f16, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 1.2, 1 },
|
||||
{ 1, 123.12, 123 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f32 */
|
||||
Datum :: struct { i: int, v: f32, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 123.3415, 123 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f64 */
|
||||
Datum :: struct { i: int, v: f64, e: u64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 12345345345.3415234234, 12345345345 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_as_f64 :: proc(t: ^testing.T) {
|
||||
using reflect
|
||||
|
||||
{
|
||||
/* i8 */
|
||||
Datum :: struct { i: int, v: i8, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7F, 0x7F },
|
||||
{ 1, -1, -1 },
|
||||
{ 2, -0x80, -0x80 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i16 */
|
||||
Datum :: struct { i: int, v: i16, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF, 0x7FFF },
|
||||
{ 1, -1, -1 },
|
||||
{ 2, -0x8000, -0x8000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i32 */
|
||||
Datum :: struct { i: int, v: i32, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF, 0x7FFF_FFFF },
|
||||
{ 1, -1, -1 },
|
||||
{ 2, -0x8000_0000, -0x8000_0000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i64 */
|
||||
Datum :: struct { i: int, v: i64, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF },
|
||||
{ 1, -1, -1 },
|
||||
{ 2, -0x8000_0000_0000_0000, -0x8000_0000_0000_0000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* i128 */
|
||||
Datum :: struct { i: int, v: i128, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF },
|
||||
{ 1, -1, -1 },
|
||||
{ 2, 0x8000_0000_0000_0000_0000_0000_0000, 0x8000_0000_0000_0000_0000_0000_0000 },
|
||||
{ 3, -0x8000_0000_0000_0000_0000_0000_0000_0000, -0x8000_0000_0000_0000_0000_0000_0000_0000 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f16 */
|
||||
Datum :: struct { i: int, v: f16, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 1.2, 0h3FF3_3400_0000_0000 }, // Precision difference TODO: check
|
||||
{ 1, 123.12, 0h405E_C800_0000_0000 }, // Precision difference TODO: check
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f32 */
|
||||
Datum :: struct { i: int, v: f32, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 123.3415, 0h405E_D5DB_2000_0000 }, // Precision difference TODO: check
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
{
|
||||
/* f64 */
|
||||
Datum :: struct { i: int, v: f64, e: f64 }
|
||||
@static data := []Datum{
|
||||
{ 0, 12345345345.3415234234, 12345345345.3415234234 },
|
||||
}
|
||||
|
||||
for d, i in data {
|
||||
assert(i == d.i)
|
||||
r, valid := 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package test_core_image
|
||||
package test_core_strings
|
||||
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -20,7 +21,8 @@ when ODIN_TEST {
|
||||
}
|
||||
}
|
||||
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
||||
fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
||||
fmt.printf("[%v] ", loc)
|
||||
fmt.printf("log: %v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,14 +32,17 @@ main :: proc() {
|
||||
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)
|
||||
|
||||
fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
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(".", "/:\"")
|
||||
log(t, index)
|
||||
expect(t, index == -1, "index_any should be negative")
|
||||
}
|
||||
|
||||
@@ -58,3 +63,30 @@ 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")
|
||||
}
|
||||
|
||||
Cut_Test :: struct {
|
||||
input: string,
|
||||
offset: int,
|
||||
length: int,
|
||||
output: string,
|
||||
}
|
||||
|
||||
cut_tests :: []Cut_Test{
|
||||
{"some example text", 0, 4, "some" },
|
||||
{"some example text", 2, 2, "me" },
|
||||
{"some example text", 5, 7, "example" },
|
||||
{"some example text", 5, 0, "example text"},
|
||||
{"恥ずべきフクロウ", 4, 0, "フクロウ" },
|
||||
}
|
||||
|
||||
@test
|
||||
test_cut :: proc(t: ^testing.T) {
|
||||
for test in cut_tests {
|
||||
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)
|
||||
}
|
||||
}
|
||||
17
tests/issues/run.bat
Normal file
17
tests/issues/run.bat
Normal file
@@ -0,0 +1,17 @@
|
||||
@echo off
|
||||
|
||||
if not exist "build\" mkdir build
|
||||
|
||||
set COMMON=-collection:tests=.. -out:build\test_issue.exe
|
||||
|
||||
@echo on
|
||||
|
||||
..\..\odin build test_issue_829.odin %COMMON% -file
|
||||
build\test_issue
|
||||
|
||||
..\..\odin build test_issue_1592.odin %COMMON% -file
|
||||
build\test_issue
|
||||
|
||||
@echo off
|
||||
|
||||
rmdir /S /Q build
|
||||
18
tests/issues/run.sh
Executable file
18
tests/issues/run.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
mkdir -p build
|
||||
ODIN=../../odin
|
||||
COMMON="-collection:tests=.. -out:build/test_issue"
|
||||
|
||||
set -x
|
||||
|
||||
$ODIN build test_issue_829.odin $COMMON -file
|
||||
./build/test_issue
|
||||
|
||||
$ODIN build test_issue_1592.odin $COMMON -file
|
||||
./build/test_issue
|
||||
|
||||
set +x
|
||||
|
||||
rm -rf build
|
||||
489
tests/issues/test_issue_1592.odin
Normal file
489
tests/issues/test_issue_1592.odin
Normal file
@@ -0,0 +1,489 @@
|
||||
// Tests issue #1592 https://github.com/odin-lang/Odin/issues/1592
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
/* This won't short-circuit */
|
||||
test_orig()
|
||||
|
||||
/* These will short-circuit */
|
||||
test_simple_const_false(&t)
|
||||
test_simple_const_true(&t)
|
||||
|
||||
/* These won't short-circuit */
|
||||
test_simple_proc_false(&t)
|
||||
test_simple_proc_true(&t)
|
||||
|
||||
/* These won't short-circuit */
|
||||
test_const_false_const_false(&t)
|
||||
test_const_false_const_true(&t)
|
||||
test_const_true_const_false(&t)
|
||||
test_const_true_const_true(&t)
|
||||
|
||||
/* These won't short-circuit */
|
||||
test_proc_false_const_false(&t)
|
||||
test_proc_false_const_true(&t)
|
||||
test_proc_true_const_false(&t)
|
||||
test_proc_true_const_true(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
/* Original issue #1592 example */
|
||||
|
||||
// I get a LLVM code gen error when this constant is false, but it works when it is true
|
||||
CONSTANT_BOOL :: false
|
||||
|
||||
bool_result :: proc() -> bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@test
|
||||
test_orig :: proc() {
|
||||
if bool_result() || CONSTANT_BOOL {
|
||||
}
|
||||
}
|
||||
|
||||
CONSTANT_FALSE :: false
|
||||
CONSTANT_TRUE :: true
|
||||
|
||||
false_result :: proc() -> bool {
|
||||
return false
|
||||
}
|
||||
true_result :: proc() -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if (CONSTANT_FALSE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if (!CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !!CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE == true {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE == false {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_FALSE == true) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_FALSE == false) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if (CONSTANT_TRUE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if (!CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if (!CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !!CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE == true {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE == false {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_TRUE == true) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_TRUE == false) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_proc_false :: proc(t: ^testing.T) {
|
||||
if false_result() {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !false_result() {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_simple_proc_true :: proc(t: ^testing.T) {
|
||||
if true_result() {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !true_result() {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_false_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE || CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !CONSTANT_FALSE || CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_FALSE && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if CONSTANT_FALSE || !CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE && !CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(CONSTANT_FALSE || CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_FALSE && CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_false_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_FALSE || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE && CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !CONSTANT_FALSE || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_FALSE && CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
|
||||
if CONSTANT_FALSE || !CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if CONSTANT_FALSE && !CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(CONSTANT_FALSE || CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_FALSE && CONSTANT_TRUE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_true_const_false :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE || CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !CONSTANT_TRUE || CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_TRUE && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if CONSTANT_TRUE || !CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE && !CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
|
||||
if !(CONSTANT_TRUE || CONSTANT_FALSE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_TRUE && CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_const_true_const_true :: proc(t: ^testing.T) {
|
||||
if CONSTANT_TRUE || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE && CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
|
||||
if !CONSTANT_TRUE || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !CONSTANT_TRUE && CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if CONSTANT_TRUE || !CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if CONSTANT_TRUE && !CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(CONSTANT_TRUE || CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(CONSTANT_TRUE && CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_false_const_false :: proc(t: ^testing.T) {
|
||||
if false_result() || CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if false_result() && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(false_result() || CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if !(false_result() && CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_false_const_true :: proc(t: ^testing.T) {
|
||||
if false_result() || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if false_result() && CONSTANT_TRUE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(false_result() || CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(false_result() && CONSTANT_TRUE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_true_const_false :: proc(t: ^testing.T) {
|
||||
if true_result() || CONSTANT_FALSE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if true_result() && CONSTANT_FALSE {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
|
||||
if !(true_result() || CONSTANT_FALSE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(true_result() && CONSTANT_FALSE) {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
}
|
||||
|
||||
@test
|
||||
test_proc_true_const_true :: proc(t: ^testing.T) {
|
||||
if true_result() || CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
if true_result() && CONSTANT_TRUE {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
}
|
||||
|
||||
if !(true_result() || CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
if !(true_result() && CONSTANT_TRUE) {
|
||||
tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
|
||||
} else {
|
||||
tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
|
||||
}
|
||||
}
|
||||
33
tests/issues/test_issue_829.odin
Normal file
33
tests/issues/test_issue_829.odin
Normal file
@@ -0,0 +1,33 @@
|
||||
// Tests issue #829 https://github.com/odin-lang/Odin/issues/829
|
||||
package test_issues
|
||||
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
import tc "tests:common"
|
||||
|
||||
/* Original issue #829 example */
|
||||
|
||||
env : map[string]proc(a, b : int) -> int = {
|
||||
"+" = proc(a, b : int) -> int {
|
||||
return a + b
|
||||
},
|
||||
}
|
||||
|
||||
test_orig :: proc() {
|
||||
fmt.println(env["+"](1, 2))
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_orig()
|
||||
|
||||
test_orig_ret(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
test_orig_ret :: proc(t: ^testing.T) {
|
||||
r := fmt.tprint(env["+"](1, 2))
|
||||
tc.expect(t, r == "3", fmt.tprintf("%s: \"%s\" != \"3\"\n", #procedure, r))
|
||||
}
|
||||
9
tests/vendor/Makefile
vendored
9
tests/vendor/Makefile
vendored
@@ -1,6 +1,13 @@
|
||||
ODIN=../../odin
|
||||
ODINFLAGS=
|
||||
|
||||
OS=$(shell uname)
|
||||
|
||||
ifeq ($(OS), OpenBSD)
|
||||
ODINFLAGS:=$(ODINFLAGS) -extra-linker-flags:-L/usr/local/lib
|
||||
endif
|
||||
|
||||
all: botan_test
|
||||
|
||||
botan_test:
|
||||
$(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check
|
||||
$(ODIN) run botan -o:speed -no-bounds-check $(ODINFLAGS) -out=vendor_botan
|
||||
|
||||
47
tests/vendor/botan/test_vendor_botan.odin
vendored
47
tests/vendor/botan/test_vendor_botan.odin
vendored
@@ -14,6 +14,7 @@ package test_vendor_botan
|
||||
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
import "vendor:botan/md4"
|
||||
import "vendor:botan/md5"
|
||||
@@ -30,6 +31,7 @@ import "vendor:botan/gost"
|
||||
import "vendor:botan/streebog"
|
||||
import "vendor:botan/sm3"
|
||||
import "vendor:botan/skein512"
|
||||
import "vendor:botan/siphash"
|
||||
|
||||
TEST_count := 0
|
||||
TEST_fail := 0
|
||||
@@ -82,8 +84,12 @@ main :: proc() {
|
||||
test_sm3(&t)
|
||||
test_skein512_256(&t)
|
||||
test_skein512_512(&t)
|
||||
test_siphash_2_4(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
TestHash :: struct {
|
||||
@@ -575,3 +581,44 @@ test_skein512_512 :: proc(t: ^testing.T) {
|
||||
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
// Test vectors from
|
||||
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||
test_vectors := [?]u64 {
|
||||
0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
|
||||
0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
|
||||
0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
|
||||
0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
|
||||
0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
|
||||
0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
|
||||
0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
|
||||
0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
|
||||
0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
|
||||
0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
|
||||
0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
|
||||
0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
|
||||
0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
|
||||
0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
|
||||
0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
|
||||
0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572,
|
||||
}
|
||||
|
||||
key: [16]byte
|
||||
for i in 0..<16 {
|
||||
key[i] = byte(i)
|
||||
}
|
||||
|
||||
for i in 0..<len(test_vectors) {
|
||||
data := make([]byte, i)
|
||||
for j in 0..<i {
|
||||
data[j] = byte(j)
|
||||
}
|
||||
|
||||
vector := test_vectors[i]
|
||||
computed := siphash.sum_2_4(data[:], key[:])
|
||||
|
||||
expect(t, computed == vector, fmt.tprintf("Expected: 0x%x for input of %v, but got 0x%x instead", vector, data, computed))
|
||||
}
|
||||
}
|
||||
4
tests/vendor/build.bat
vendored
4
tests/vendor/build.bat
vendored
@@ -5,9 +5,9 @@ set PATH_TO_ODIN==..\..\odin
|
||||
echo ---
|
||||
echo Running vendor:botan tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run botan %COMMON%
|
||||
%PATH_TO_ODIN% run botan %COMMON% -out:vendor_botan.exe
|
||||
|
||||
echo ---
|
||||
echo Running vendor:glfw tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run glfw %COMMON%
|
||||
%PATH_TO_ODIN% run glfw %COMMON% -out:vendor_glfw.exe
|
||||
4
tests/vendor/glfw/test_vendor_glfw.odin
vendored
4
tests/vendor/glfw/test_vendor_glfw.odin
vendored
@@ -3,6 +3,7 @@ package test_vendor_glfw
|
||||
import "core:testing"
|
||||
import "core:fmt"
|
||||
import "vendor:glfw"
|
||||
import "core:os"
|
||||
|
||||
GLFW_MAJOR :: 3
|
||||
GLFW_MINOR :: 3
|
||||
@@ -36,6 +37,9 @@ main :: proc() {
|
||||
test_glfw(&t)
|
||||
|
||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||
if TEST_fail > 0 {
|
||||
os.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
|
||||
Reference in New Issue
Block a user