Add even more tests and some impl improvements from their results

This commit is contained in:
Riyyi
2026-08-25 21:12:18 +02:00
parent 6e81c87501
commit ddaa3846f2
7 changed files with 292 additions and 58 deletions
+85 -19
View File
@@ -13,8 +13,9 @@ TEST_OUTPUT_DIR :: "./build/tests/out"
// -----------------------------------------
Test_State :: struct {
input_dir: string,
output_dir: string,
input_dir: string,
output_dir: string,
working_dir: string,
}
// -----------------------------------------
@@ -36,9 +37,13 @@ test_state_init :: proc(
temp_output_path, err2 := os.mkdir_temp(TEST_OUTPUT_DIR, name, allocator)
testing.expect(t, err2 == nil, os.error_string(err2))
working_dir, err3 := os.get_working_directory(context.allocator)
testing.expect(t, err3 == nil, os.error_string(err3))
return Test_State {
input_dir = temp_input_path,
output_dir = temp_output_path,
working_dir = working_dir,
}
}
@@ -72,9 +77,13 @@ create_file :: proc(
t: ^testing.T,
path: string,
content: string,
is_output_file := false,
allocator := context.allocator,
) {
relpath, err := os.join_path({ts.input_dir, path}, allocator)
relpath, err := os.join_path(
{!is_output_file ? ts.input_dir : ts.output_dir, path},
allocator,
)
testing.expect(t, err == nil, os.error_string(err))
defer delete(relpath, allocator)
@@ -106,27 +115,48 @@ delete_path :: proc(
}
}
pack :: proc(ts: ^Test_State, t: ^testing.T, size: u64) {
wd, err := os.get_working_directory(context.allocator)
testing.expect(t, err == nil, os.error_string(err))
entries, err2 := file.list_dir_recursive_by_path(ts.input_dir, wd)
testing.expect(t, err2 == nil, file.format_error(err2))
pack :: proc(
ts: ^Test_State,
t: ^testing.T,
size: u64,
compression: u16 = 0,
) -> (
wa_err: chunks.Error,
wm_err: chunks.Error,
) {
entries, err := file.list_dir_recursive_by_path(
ts.input_dir,
ts.working_dir,
)
testing.expect(t, err == nil, file.error_string(err))
w := chunks.writer_init(cast(u64)len(entries))
defer chunks.writer_destroy(&w)
output_file, err3 := os.open(ts.output_dir, {.Read})
testing.expect(t, err3 == nil, os.error_string(err3))
output_file, err2 := os.open(ts.output_dir, {.Read})
testing.expect(t, err2 == nil, os.error_string(err2))
defer os.close(output_file)
err4 := chunks.write_assets(&w, output_file, entries[:], size, 0)
testing.expect(t, err4 == nil, chunks.format_error(err4))
wa_err = chunks.write_assets(
&w,
output_file,
entries[:],
size,
compression,
)
if wa_err != nil do return wa_err, nil
err5 := chunks.write_metadata(&w, output_file, entries[:], size, 0)
testing.expect(t, err5 == nil, chunks.format_error(err5))
wm_err = chunks.write_metadata(
&w,
output_file,
entries[:],
size,
compression,
)
return wa_err, wm_err
}
read :: proc(
read_asset :: proc(
ts: ^Test_State,
t: ^testing.T,
path: string,
@@ -139,22 +169,58 @@ read :: proc(
testing.expect(t, err == nil, os.error_string(err))
defer delete(relpath, allocator)
file, err2 := os.open(ts.output_dir)
file, err2 := os.open(ts.output_dir, {.Read})
testing.expect(t, err2 == nil, os.error_string(err2))
defer os.close(file)
r, err3 := chunks.reader_init(file)
testing.expect(t, err3 == nil, chunks.format_error(err3))
testing.expect(t, err3 == nil, chunks.error_string(err3))
defer chunks.reader_destroy(&r)
exists, i, err4 := chunks.asset_exists(&r, relpath)
testing.expect(t, err4 == nil, chunks.format_error(err4))
testing.expect(t, err4 == nil, chunks.error_string(err4))
if exists {
bytes, err5 := chunks.read_asset(&r, relpath)
testing.expect(t, err5 == nil, chunks.format_error(err5))
testing.expect(t, err5 == nil, chunks.error_string(err5))
return true, string(bytes)
}
return false, {}
}
read_asset_raw :: proc(
ts: ^Test_State,
t: ^testing.T,
path: string,
allocator := context.allocator,
) -> (
bytes: []u8,
err: chunks.Error,
) {
relpath, err2 := os.join_path({ts.input_dir, path}, allocator)
testing.expect(t, err2 == nil, os.error_string(err2))
defer delete(relpath, allocator)
output_file, err3 := os.open(ts.output_dir, {.Read})
testing.expect(t, err3 == nil, os.error_string(err3))
defer os.close(output_file)
r, err4 := chunks.reader_init(output_file)
testing.expect(t, err4 == nil, chunks.error_string(err4))
defer chunks.reader_destroy(&r)
bytes, err = chunks.read_asset(&r, relpath)
return bytes, err
}
reader_init_raw :: proc(ts: ^Test_State, t: ^testing.T) -> chunks.Error {
output_file, err2 := os.open(ts.output_dir, {.Read})
testing.expect(t, err2 == nil, os.error_string(err2))
defer os.close(output_file)
r, err := chunks.reader_init(output_file)
defer chunks.reader_destroy(&r)
return err
}
+188 -29
View File
@@ -3,6 +3,11 @@ package tests
import "core:strings"
import "core:testing"
import "src:chunks"
// -----------------------------------------
// Single file tests
@(test)
single_asset_single_chunk_read_from_path :: proc(t: ^testing.T) {
// Arrange
@@ -11,14 +16,14 @@ single_asset_single_chunk_read_from_path :: proc(t: ^testing.T) {
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "single_tiny_file", "hello world!")
create_file(&ts, t, "single_asset", "hello world!")
pack(&ts, t, 750)
delete_path(&ts, t, "")
create_file(&ts, t, "single_tiny_file", "hello world from path!")
create_file(&ts, t, "single_asset", "hello world from path!")
// Act
_, read := read(&ts, t, "single_tiny_file")
_, read := read_asset(&ts, t, "single_asset")
// Assert
@@ -33,13 +38,13 @@ single_asset_single_chunk_read_from_chunk :: proc(t: ^testing.T) {
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "single_tiny_file", "hello world!")
create_file(&ts, t, "single_asset", "hello world!")
pack(&ts, t, 750)
delete_path(&ts, t, "")
// Act
_, read := read(&ts, t, "single_tiny_file")
_, read := read_asset(&ts, t, "single_asset")
// Assert
@@ -56,13 +61,13 @@ single_asset_multiple_chunks_read_from_chunk :: proc(t: ^testing.T) {
delete_path(&ts, t, "")
content := strings.repeat("abcde", 400)
defer delete(content)
create_file(&ts, t, "multi_chunk_file", content)
create_file(&ts, t, "single_asset", content)
pack(&ts, t, 750)
delete_path(&ts, t, "")
// Act
_, read := read(&ts, t, "multi_chunk_file")
_, read := read_asset(&ts, t, "single_asset")
// Assert
@@ -70,6 +75,7 @@ single_asset_multiple_chunks_read_from_chunk :: proc(t: ^testing.T) {
}
// -----------------------------------------
// Multi file tests
@(test)
multiple_assets_single_chunk_read_from_path :: proc(t: ^testing.T) {
@@ -90,9 +96,9 @@ multiple_assets_single_chunk_read_from_path :: proc(t: ^testing.T) {
// Act
_, a := read(&ts, t, "a")
_, b := read(&ts, t, "b")
_, c := read(&ts, t, "c")
_, a := read_asset(&ts, t, "a")
_, b := read_asset(&ts, t, "b")
_, c := read_asset(&ts, t, "c")
// Assert
@@ -117,9 +123,9 @@ multiple_assets_single_chunk_read_from_chunk :: proc(t: ^testing.T) {
// Act
_, a := read(&ts, t, "a")
_, b := read(&ts, t, "b")
_, c := read(&ts, t, "c")
_, a := read_asset(&ts, t, "a")
_, b := read_asset(&ts, t, "b")
_, c := read_asset(&ts, t, "c")
// Assert
@@ -150,9 +156,9 @@ multiple_assets_multiple_chunks_read_from_chunk :: proc(t: ^testing.T) {
// Act
_, a := read(&ts, t, "a")
_, b := read(&ts, t, "b")
_, c := read(&ts, t, "c")
_, a := read_asset(&ts, t, "a")
_, b := read_asset(&ts, t, "b")
_, c := read_asset(&ts, t, "c")
// Assert
@@ -162,6 +168,7 @@ multiple_assets_multiple_chunks_read_from_chunk :: proc(t: ^testing.T) {
}
// -----------------------------------------
// Nested path tests
@(test)
single_asset_single_chunk_nested_path_read_from_path :: proc(t: ^testing.T) {
@@ -171,14 +178,14 @@ single_asset_single_chunk_nested_path_read_from_path :: proc(t: ^testing.T) {
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "subdir/nested_file", "hello nested!")
create_file(&ts, t, "subdir/nested_asset", "hello nested!")
pack(&ts, t, 750)
delete_path(&ts, t, "")
create_file(&ts, t, "subdir/nested_file", "hello nested from path!")
create_file(&ts, t, "subdir/nested_asset", "hello nested from path!")
// Act
_, read := read(&ts, t, "subdir/nested_file")
_, read := read_asset(&ts, t, "subdir/nested_asset")
// Assert
@@ -193,13 +200,13 @@ single_asset_single_chunk_nested_path_read_from_chunk :: proc(t: ^testing.T) {
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "subdir/nested_file", "hello nested!")
create_file(&ts, t, "subdir/nested_asset", "hello nested!")
pack(&ts, t, 750)
delete_path(&ts, t, "")
// Act
_, read := read(&ts, t, "subdir/nested_file")
_, read := read_asset(&ts, t, "subdir/nested_asset")
// Assert
@@ -218,13 +225,13 @@ single_asset_multiple_chunks_nested_path_read_from_chunk :: proc(
delete_path(&ts, t, "")
content := strings.repeat("abcde", 50)
defer delete(content)
create_file(&ts, t, "subdir/nested_file", content)
create_file(&ts, t, "subdir/nested_asset", content)
pack(&ts, t, 750)
delete_path(&ts, t, "")
// Act
_, read := read(&ts, t, "subdir/nested_file")
_, read := read_asset(&ts, t, "subdir/nested_asset")
// Assert
@@ -232,6 +239,7 @@ single_asset_multiple_chunks_nested_path_read_from_chunk :: proc(
}
// -----------------------------------------
// Asset exists tests
@(test)
asset_in_path_not_in_chunk_read_matching_file :: proc(t: ^testing.T) {
@@ -248,7 +256,7 @@ asset_in_path_not_in_chunk_read_matching_file :: proc(t: ^testing.T) {
// Act
_, read := read(&ts, t, "target")
_, read := read_asset(&ts, t, "target")
// Assert
@@ -269,7 +277,7 @@ asset_in_chunk_not_in_path_read_matching_file :: proc(t: ^testing.T) {
// Act
_, read := read(&ts, t, "target")
_, read := read_asset(&ts, t, "target")
// Assert
@@ -291,7 +299,7 @@ asset_in_chunk_and_in_path_read_matching_file :: proc(t: ^testing.T) {
// Act
_, read := read(&ts, t, "target")
_, read := read_asset(&ts, t, "target")
// Assert
@@ -305,13 +313,14 @@ asset_in_path_not_in_chunk_read_non_matching_file :: proc(t: ^testing.T) {
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
// Empty asset dir
pack(&ts, t, 750)
delete_path(&ts, t, "")
create_file(&ts, t, "target", "hello from path!")
// Act
exists, _ := read(&ts, t, "non_matching")
exists, _ := read_asset(&ts, t, "non_matching")
// Assert
@@ -332,7 +341,7 @@ asset_in_chunk_not_in_path_read_non_matching_file :: proc(t: ^testing.T) {
// Act
exists, _ := read(&ts, t, "non_matching")
exists, _ := read_asset(&ts, t, "non_matching")
// Assert
@@ -354,9 +363,159 @@ asset_in_chunk_and_in_path_read_non_matching_file :: proc(t: ^testing.T) {
// Act
exists, _ := read(&ts, t, "non_matching")
exists, _ := read_asset(&ts, t, "non_matching")
// Assert
testing.expect(t, !exists)
}
// -----------------------------------------
// Error return tests
@(test)
chunk_size_too_small :: proc(t: ^testing.T) {
// Arrange
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "chunk_too_small", "hello world!")
// Act
wa_err, _ := pack(&ts, t, 100, 0)
// Assert
testing.expect(
t,
wa_err == chunks.Write_Error.Chunk_Size_Too_Small,
chunks.error_string(wa_err),
)
}
@(test)
non_chunk_file_read :: proc(t: ^testing.T) {
// Arrange
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
create_file(
&ts,
t,
"CHUNK0",
"this is definitely not a chunk file, nope",
true,
)
// Act
err := reader_init_raw(&ts, t)
// Assert
testing.expect(
t,
err == chunks.Read_Error.File_Not_A_Chunk,
chunks.error_string(err),
)
}
@(test)
compression_unimplemented :: proc(t: ^testing.T) {
// Arrange
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "tiny_file", "hello world!")
wa_err, wm_err := pack(&ts, t, 750, 1)
testing.expect(t, wa_err == nil, chunks.error_string(wa_err))
testing.expect(t, wm_err == nil, chunks.error_string(wm_err))
// Act
err := reader_init_raw(&ts, t)
// Assert
testing.expect(
t,
err == chunks.Read_Error.Unimplemented,
chunks.error_string(err),
)
}
@(test)
read_non_existent_asset :: proc(t: ^testing.T) {
// Arrange
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
create_file(&ts, t, "target", "hello from chunk!")
pack(&ts, t, 750)
delete_path(&ts, t, "")
// Act
_, err := read_asset_raw(&ts, t, "non_matching")
// Assert
testing.expect(
t,
err == chunks.Read_Error.Asset_Not_Exist,
chunks.error_string(err),
)
}
@(test)
path_too_large :: proc(t: ^testing.T) {
// Arrange
ts := test_state_init(t, #procedure)
defer test_state_destroy(&ts, t)
delete_path(&ts, t, "")
dir_segment := strings.repeat("a", 100)
defer delete(dir_segment)
// Nested to avoid OS filename limit of 255
nested_path := strings.concatenate(
{
dir_segment,
"/",
dir_segment,
"/",
dir_segment,
"/",
dir_segment,
"/",
dir_segment,
"/",
"path_too_large",
},
)
defer delete(nested_path)
create_file(&ts, t, nested_path, "hello nested!")
// Act
_, wm_err := pack(&ts, t, 750, 0)
// Assert
testing.expect(
t,
wm_err == chunks.Write_Error.Path_Too_Large,
chunks.error_string(wm_err),
)
}