mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-06 10:44:06 +00:00
Add test suite for core:io
This commit is contained in:
549
tests/core/io/test_core_io.odin
Normal file
549
tests/core/io/test_core_io.odin
Normal file
@@ -0,0 +1,549 @@
|
||||
package test_core_io
|
||||
|
||||
import "core:bytes"
|
||||
import "core:io"
|
||||
import "core:log"
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
|
||||
Passed_Tests :: distinct io.Stream_Mode_Set
|
||||
|
||||
_test_stream :: proc(
|
||||
t: ^testing.T,
|
||||
stream: io.Stream,
|
||||
buffer: []u8,
|
||||
|
||||
reading_consumes: bool = false,
|
||||
resets_on_empty: bool = false,
|
||||
do_destroy: bool = true,
|
||||
|
||||
loc := #caller_location
|
||||
) -> (passed: Passed_Tests, ok: bool) {
|
||||
// We only test what the stream reports to support.
|
||||
|
||||
mode_set := io.query(stream)
|
||||
|
||||
// Can't feature-test anything if Query isn't supported.
|
||||
testing.expectf(t, .Query in mode_set, "stream does not support .Query: %v", mode_set, loc = loc) or_return
|
||||
|
||||
passed += { .Query }
|
||||
|
||||
size := i64(len(buffer))
|
||||
|
||||
// Do some basic Seek sanity testing.
|
||||
if .Seek in mode_set {
|
||||
pos, err := io.seek(stream, 0, io.Seek_From(-1))
|
||||
testing.expectf(t, pos == 0 && err == .Invalid_Whence,
|
||||
"Seek(-1) didn't fail with Invalid_Whence: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, 0, .Start)
|
||||
testing.expectf(t, pos == 0 && err == nil,
|
||||
"Seek Start isn't 0: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, 0, .Current)
|
||||
testing.expectf(t, pos == 0 && err == nil,
|
||||
"Seek Current isn't 0 at the start: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, -1, .Start)
|
||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
||||
"Seek Start-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, -1, .Current)
|
||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
||||
"Seek Current-1 wasn't Invalid_Offset: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, 0, .End)
|
||||
testing.expectf(t, pos == size && err == nil,
|
||||
"Seek End+0 failed: %v != size<%i>, %v", pos, size, err, loc = loc) or_return
|
||||
|
||||
pos, err = io.seek(stream, 0, .Current)
|
||||
testing.expectf(t, pos == size && err == nil,
|
||||
"Seek Current isn't size<%v> at the End: %v, %v", size, pos, err, loc = loc) or_return
|
||||
|
||||
// Seeking past the End is accepted throughout the API.
|
||||
//
|
||||
// It's _reading_ past the End which is erroneous.
|
||||
pos, err = io.seek(stream, 1, .End)
|
||||
testing.expectf(t, pos == size+1 && err == nil,
|
||||
"Seek End+1 failed: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
// Reset our position for future tests.
|
||||
pos, err = io.seek(stream, 0, .Start)
|
||||
testing.expectf(t, pos == 0 && err == nil,
|
||||
"Seek Start reset failed: %v, %v", pos, err, loc = loc) or_return
|
||||
|
||||
passed += { .Seek }
|
||||
}
|
||||
|
||||
// Test Size.
|
||||
if .Size in mode_set {
|
||||
api_size, size_err := io.size(stream)
|
||||
testing.expectf(t, api_size == size,
|
||||
"Size reports %v for its size; expected %v", api_size, size, loc = loc) or_return
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Size expected no error: %v", size_err, loc = loc) or_return
|
||||
|
||||
passed += { .Size }
|
||||
}
|
||||
|
||||
// Test Read_At.
|
||||
if .Read_At in mode_set {
|
||||
read_buf, alloc_err := make([]u8, size)
|
||||
testing.expect_value(t, alloc_err, nil, loc = loc) or_return
|
||||
defer delete(read_buf)
|
||||
|
||||
for start in 0..<size {
|
||||
for end in 1+start..<size {
|
||||
subsize := end - start
|
||||
bytes_read, err := io.read_at(stream, read_buf[:subsize], start)
|
||||
testing.expectf(t, i64(bytes_read) == subsize && err == nil,
|
||||
"Read_At(%i) of %v bytes failed: %v, %v", start, subsize, bytes_read, err, loc = loc) or_return
|
||||
testing.expectf(t, bytes.compare(read_buf[:subsize], buffer[start:end]) == 0,
|
||||
"Read_At buffer compare failed: read_buf<%v> != buffer<%v>", read_buf, buffer, loc = loc) or_return
|
||||
}
|
||||
}
|
||||
|
||||
// Test empty streams and EOF.
|
||||
one_buf: [1]u8
|
||||
bytes_read, err := io.read_at(stream, one_buf[:], size)
|
||||
testing.expectf(t, bytes_read == 0 && err == .EOF,
|
||||
"Read_At at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||
|
||||
// Make sure size is still sane.
|
||||
if .Size in mode_set {
|
||||
api_size, size_err := io.size(stream)
|
||||
testing.expectf(t, api_size == size,
|
||||
"Read_At+Size reports %v for its size after Read_At tests; expected %v", api_size, size, loc = loc) or_return
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Read_At+Size expected no error: %v", size_err, loc = loc) or_return
|
||||
}
|
||||
|
||||
passed += { .Read_At }
|
||||
}
|
||||
|
||||
// Test Read.
|
||||
if .Read in mode_set {
|
||||
if size > 0 {
|
||||
read_buf, alloc_err := make([]u8, size)
|
||||
testing.expectf(t, alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(read_buf)
|
||||
|
||||
bytes_read, err := io.read(stream, read_buf[:1])
|
||||
testing.expectf(t, bytes_read == 1 && err == nil,
|
||||
"Read 1 byte at start failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||
testing.expectf(t, read_buf[0] == buffer[0],
|
||||
"Read of first byte failed: read_buf[0]<%v> != buffer[0]<%v>", read_buf[0], buffer[0], loc = loc) or_return
|
||||
|
||||
// Test rolling back the stream one byte then reading it again.
|
||||
if .Seek in mode_set {
|
||||
pos, seek_err := io.seek(stream, -1, .Current)
|
||||
testing.expectf(t, pos == 0 && err == nil,
|
||||
"Read+Seek Current-1 reset to 0 failed: %v, %v", pos, seek_err, loc = loc) or_return
|
||||
|
||||
bytes_read, err = io.read(stream, read_buf[:1])
|
||||
testing.expectf(t, bytes_read == 1 && err == nil,
|
||||
"Read 1 byte at start after Seek reset failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||
testing.expectf(t, read_buf[0] == buffer[0] ,
|
||||
"re-Read of first byte failed: read_buf[0]<%v> != buffer[0]<%v>", read_buf[0], buffer[0], loc = loc) or_return
|
||||
}
|
||||
|
||||
// Make sure size is still sane.
|
||||
if .Size in mode_set {
|
||||
api_size, size_err := io.size(stream)
|
||||
expected_api_size := size - 1 if reading_consumes else size
|
||||
|
||||
testing.expectf(t, api_size == expected_api_size,
|
||||
"Read+Size reports %v for its size after Read tests; expected %v", api_size, expected_api_size, loc = loc) or_return
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Read+Size expected no error: %v", size_err, loc = loc) or_return
|
||||
}
|
||||
|
||||
// Read the rest.
|
||||
if size > 1 {
|
||||
bytes_read, err = io.read(stream, read_buf[1:])
|
||||
testing.expectf(t, i64(bytes_read) == size - 1 && err == nil,
|
||||
"Read rest of stream failed: %v != %v, %v", bytes_read, size-1, err, loc = loc) or_return
|
||||
testing.expectf(t, bytes.compare(read_buf, buffer) == 0,
|
||||
"Read buffer compare failed: read_buf<%v> != buffer<%v>", read_buf, buffer, loc = loc) or_return
|
||||
}
|
||||
}
|
||||
|
||||
// Test empty streams and EOF.
|
||||
one_buf: [1]u8
|
||||
bytes_read, err := io.read(stream, one_buf[:])
|
||||
testing.expectf(t, bytes_read == 0 && err == .EOF,
|
||||
"Read at end of stream failed: %v, %v", bytes_read, err, loc = loc) or_return
|
||||
|
||||
if !resets_on_empty && .Size in mode_set {
|
||||
// Make sure size is still sane.
|
||||
api_size, size_err := io.size(stream)
|
||||
testing.expectf(t, api_size == size,
|
||||
"Read+Size reports %v for its size after Read tests; expected %v", api_size, size, loc = loc) or_return
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Read+Size expected no error: %v", size_err, loc = loc) or_return
|
||||
}
|
||||
|
||||
passed += { .Read }
|
||||
}
|
||||
|
||||
// Test Write_At.
|
||||
if .Write_At in mode_set {
|
||||
if size > 0 {
|
||||
write_buf, write_buf_alloc_err := make([]u8, size)
|
||||
testing.expectf(t, write_buf_alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(write_buf)
|
||||
|
||||
for i in 0..<size {
|
||||
write_buf[i] = buffer[i] ~ 0xAA
|
||||
}
|
||||
|
||||
bytes_written, write_err := io.write_at(stream, write_buf[:], 0)
|
||||
testing.expectf(t, i64(bytes_written) == size && write_err == nil,
|
||||
"Write_At failed: bytes_written<%v> != size<%v>: %v", bytes_written, size, write_err, loc = loc) or_return
|
||||
|
||||
// Test reading what we've written.
|
||||
if .Read_At in mode_set {
|
||||
read_buf, read_buf_alloc_err := make([]u8, size)
|
||||
testing.expectf(t, read_buf_alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(read_buf)
|
||||
bytes_read, read_err := io.read_at(stream, read_buf[:], 0)
|
||||
testing.expectf(t, i64(bytes_read) == size && read_err == nil,
|
||||
"Write_At+Read_At failed: bytes_read<%i> != size<%i>, %v", bytes_read, size, read_err, loc = loc) or_return
|
||||
testing.expectf(t, bytes.compare(read_buf, write_buf) == 0,
|
||||
"Write_At+Read_At buffer compare failed: write_buf<%v> != read_buf<%v>", write_buf, read_buf, loc = loc) or_return
|
||||
}
|
||||
} else {
|
||||
// Expect that it should be okay to write a single byte to an empty stream.
|
||||
x_buf: [1]u8 = { 'Z' }
|
||||
|
||||
bytes_written, write_err := io.write_at(stream, x_buf[:], 0)
|
||||
testing.expectf(t, i64(bytes_written) == 1 && write_err == nil,
|
||||
"Write_At(0) with 'Z' on empty stream failed: bytes_written<%v>, %v", bytes_written, write_err, loc = loc) or_return
|
||||
|
||||
// Test reading what we've written.
|
||||
if .Read_At in mode_set {
|
||||
x_buf[0] = 0
|
||||
bytes_read, read_err := io.read_at(stream, x_buf[:], 0)
|
||||
testing.expectf(t, i64(bytes_read) == 1 && read_err == nil,
|
||||
"Write_At(0)+Read_At(0) failed expectation: bytes_read<%v> != 1, %q != 'Z', %v", bytes_read, x_buf[0], read_err, loc = loc) or_return
|
||||
}
|
||||
}
|
||||
|
||||
passed += { .Write_At }
|
||||
}
|
||||
|
||||
// Test Write.
|
||||
if .Write in mode_set {
|
||||
write_buf, write_buf_alloc_err := make([]u8, size)
|
||||
testing.expectf(t, write_buf_alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(write_buf)
|
||||
|
||||
for i in 0..<size {
|
||||
write_buf[i] = buffer[i] ~ 0xAA
|
||||
}
|
||||
|
||||
pos: i64 = -1
|
||||
before_write_size: i64 = -1
|
||||
|
||||
// Do a Seek sanity check after past tests.
|
||||
if .Seek in mode_set {
|
||||
seek_err: io.Error
|
||||
pos, seek_err = io.seek(stream, 0, .Current)
|
||||
testing.expectf(t, seek_err == nil,
|
||||
"Write+Seek(Current) failed: pos<%i>, %v", pos, seek_err) or_return
|
||||
}
|
||||
|
||||
// Get the Size before writing.
|
||||
if .Size in mode_set {
|
||||
size_err: io.Error
|
||||
before_write_size, size_err = io.size(stream)
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Write+Size failed: %v", size_err, loc = loc) or_return
|
||||
}
|
||||
|
||||
bytes_written, write_err := io.write(stream, write_buf[:])
|
||||
testing.expectf(t, i64(bytes_written) == size && write_err == nil,
|
||||
"Write %i bytes failed: %i, %v", size, bytes_written, write_err, loc = loc) or_return
|
||||
|
||||
// Size sanity check, part 2.
|
||||
if before_write_size >= 0 && .Size in mode_set {
|
||||
after_write_size, size_err := io.size(stream)
|
||||
testing.expectf(t, size_err == nil,
|
||||
"Write+Size.part_2 failed: %v", size_err, loc = loc) or_return
|
||||
testing.expectf(t, after_write_size == before_write_size + size,
|
||||
"Write+Size.part_2 failed: %v != %v + %v", after_write_size, before_write_size, size, loc = loc) or_return
|
||||
}
|
||||
|
||||
// Test reading what we've written directly with Read_At.
|
||||
if pos >= 0 && .Read_At in mode_set {
|
||||
read_buf, read_buf_alloc_err := make([]u8, size)
|
||||
testing.expectf(t, read_buf_alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(read_buf)
|
||||
|
||||
bytes_read, read_err := io.read_at(stream, read_buf[:], pos)
|
||||
testing.expectf(t, i64(bytes_read) == size && read_err == nil,
|
||||
"Write+Read_At(%i) failed: bytes_read<%i> != size<%i>, %v", pos, bytes_read, size, read_err, loc = loc) or_return
|
||||
testing.expectf(t, bytes.compare(read_buf, write_buf) == 0,
|
||||
"Write+Read_At buffer compare failed: read_buf<%v> != write_buf<%v>", read_buf, write_buf, loc = loc) or_return
|
||||
}
|
||||
|
||||
// Test resetting the pointer and reading what we've written with Read.
|
||||
if .Read in mode_set && .Seek in mode_set {
|
||||
seek_err: io.Error
|
||||
pos, seek_err = io.seek(stream, 0, .Start)
|
||||
testing.expectf(t, pos == 0 && seek_err == nil,
|
||||
"Write+Read+Seek(Start) failed: pos<%i>, %v", pos, seek_err) or_return
|
||||
|
||||
read_buf, read_buf_alloc_err := make([]u8, size)
|
||||
testing.expectf(t, read_buf_alloc_err == nil, "allocation failed", loc = loc) or_return
|
||||
defer delete(read_buf)
|
||||
|
||||
bytes_read, read_err := io.read(stream, read_buf[:])
|
||||
testing.expectf(t, i64(bytes_read) == size && read_err == nil,
|
||||
"Write+Read failed: bytes_read<%i> != size<%i>, %v", bytes_read, size, read_err, loc = loc) or_return
|
||||
testing.expectf(t, bytes.compare(read_buf, write_buf) == 0,
|
||||
"Write+Readbuffer compare failed: read_buf<%v> != write_buf<%v>", read_buf, write_buf, loc = loc) or_return
|
||||
}
|
||||
|
||||
passed += { .Write }
|
||||
}
|
||||
|
||||
// Test the other modes.
|
||||
if .Flush in mode_set {
|
||||
err := io.flush(stream)
|
||||
testing.expectf(t, err == nil, "stream failed to Flush: %v", err, loc = loc) or_return
|
||||
passed += { .Flush }
|
||||
}
|
||||
|
||||
if .Close in mode_set {
|
||||
close_err := io.close(stream)
|
||||
testing.expectf(t, close_err == nil, "stream failed to Close: %v", close_err, loc = loc) or_return
|
||||
passed += { .Close }
|
||||
|
||||
// TODO(Feoramund): The OS<->IO interface will need updating for more
|
||||
// specific error messages.
|
||||
//
|
||||
// This test will catch it when they start using them, but so long as
|
||||
// they actually error, it should be okay for now.
|
||||
//
|
||||
// .EOF would be a better message for all of these.
|
||||
|
||||
if .Seek in mode_set {
|
||||
pos, err := io.seek(stream, 0, .Start)
|
||||
|
||||
testing.expectf(t, pos == 0 && err == .Invalid_Offset,
|
||||
"Seek after Close unexpected output: pos<%v>, %v", pos, err, loc = loc) or_return
|
||||
}
|
||||
|
||||
if .Read in mode_set {
|
||||
eof_buf: [1]u8
|
||||
bytes_read, err := io.read(stream, eof_buf[:])
|
||||
testing.expectf(t, bytes_read == 0 && err == .Unknown,
|
||||
"Read after Close unexpected output: bytes_read<%v>, %v", bytes_read, err, loc = loc) or_return
|
||||
}
|
||||
|
||||
if size > 0 && .Read_At in mode_set {
|
||||
eof_buf: [1]u8
|
||||
bytes_read, err := io.read_at(stream, eof_buf[:], 0)
|
||||
testing.expectf(t, bytes_read == 0 && err == .Unknown,
|
||||
"Read_At after Close unexpected output: bytes_read<%v>, %v", bytes_read, err, loc = loc) or_return
|
||||
}
|
||||
|
||||
if .Write in mode_set {
|
||||
eof_buf: [1]u8 = {'Z'}
|
||||
bytes_written, err := io.write(stream, eof_buf[:])
|
||||
testing.expectf(t, bytes_written == 0 && err == .Unknown,
|
||||
"Write after Close unexpected output: bytes_written<%v>, %v", bytes_written, err, loc = loc) or_return
|
||||
}
|
||||
|
||||
if .Write_At in mode_set {
|
||||
eof_buf: [1]u8 = {'Z'}
|
||||
bytes_written, err := io.write_at(stream, eof_buf[:], 0)
|
||||
testing.expectf(t, bytes_written == 0 && err == .Unknown,
|
||||
"Write after Close unexpected output: bytes_written<%v>, %v", bytes_written, err, loc = loc) or_return
|
||||
}
|
||||
}
|
||||
|
||||
if do_destroy && .Destroy in mode_set {
|
||||
err := io.destroy(stream)
|
||||
testing.expectf(t, err == nil, "stream failed to Destroy: %v", err, loc = loc) or_return
|
||||
passed += { .Destroy }
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
@test
|
||||
test_bytes_reader :: proc(t: ^testing.T) {
|
||||
buf: [32]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
}
|
||||
|
||||
br: bytes.Reader
|
||||
|
||||
results: Passed_Tests
|
||||
ok: bool
|
||||
|
||||
for end in 0..<i64(len(buf)) {
|
||||
results, ok =_test_stream(t, bytes.reader_init(&br, buf[:end]), buf[:end])
|
||||
if !ok {
|
||||
log.debugf("buffer[:%i] := %v", end, buf[:end])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
|
||||
@test
|
||||
test_bytes_buffer_stream :: proc(t: ^testing.T) {
|
||||
buf: [32]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
}
|
||||
|
||||
results: Passed_Tests
|
||||
ok: bool
|
||||
|
||||
for end in 0..<i64(len(buf)) {
|
||||
bb: bytes.Buffer
|
||||
// Mind that `bytes.buffer_init` copies the entire underlying slice.
|
||||
bytes.buffer_init(&bb, buf[:end])
|
||||
|
||||
// `bytes.Buffer` has a behavior of decreasing its size with each read
|
||||
// until it eventually clears the underlying buffer when it runs out of
|
||||
// data to read.
|
||||
results, ok = _test_stream(t, bytes.buffer_to_stream(&bb), buf[:end],
|
||||
reading_consumes = true, resets_on_empty = true)
|
||||
if !ok {
|
||||
log.debugf("buffer[:%i] := %v", end, buf[:end])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
|
||||
@test
|
||||
test_limited_reader :: proc(t: ^testing.T) {
|
||||
buf: [32]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
}
|
||||
|
||||
br: bytes.Reader
|
||||
bs := bytes.reader_init(&br, buf[:])
|
||||
|
||||
lr: io.Limited_Reader
|
||||
|
||||
results: Passed_Tests
|
||||
ok: bool
|
||||
|
||||
for end in 0..<i64(len(buf)) {
|
||||
io.seek(bs, 0, .Start)
|
||||
results, ok = _test_stream(t, io.limited_reader_init(&lr, bs, end), buf[:end])
|
||||
if !ok {
|
||||
log.debugf("buffer[:%i] := %v", end, buf[:end])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
|
||||
@test
|
||||
test_section_reader :: proc(t: ^testing.T) {
|
||||
buf: [32]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
}
|
||||
|
||||
br: bytes.Reader
|
||||
bs := bytes.reader_init(&br, buf[:])
|
||||
|
||||
sr: io.Section_Reader
|
||||
|
||||
results: Passed_Tests
|
||||
ok: bool
|
||||
|
||||
for start in 0..<i64(len(buf)) {
|
||||
for end in start..<i64(len(buf)) {
|
||||
results, ok = _test_stream(t, io.section_reader_init(&sr, bs, start, end-start), buf[start:end])
|
||||
if !ok {
|
||||
log.debugf("buffer[%i:%i] := %v", start, end, buf[start:end])
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
|
||||
@test
|
||||
test_string_builder_stream :: proc(t: ^testing.T) {
|
||||
sb := strings.builder_make()
|
||||
defer strings.builder_destroy(&sb)
|
||||
|
||||
// String builders do not support reading, so we'll have to set up a few
|
||||
// things outside the main test.
|
||||
|
||||
buf: [32]u8
|
||||
expected_buf: [64]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
expected_buf[i] = 'A' + i
|
||||
strings.write_byte(&sb, 'A' + i)
|
||||
}
|
||||
for i in 32..<u8(len(expected_buf)) {
|
||||
expected_buf[i] = ('A' + i-len(buf)) ~ 0xAA
|
||||
}
|
||||
|
||||
results, _ := _test_stream(t, strings.to_stream(&sb), buf[:],
|
||||
do_destroy = false)
|
||||
|
||||
testing.expectf(t, bytes.compare(sb.buf[:], expected_buf[:]) == 0, "string builder stream failed:\nbuilder<%q>\n!=\nbuffer <%q>", sb.buf[:], expected_buf[:])
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
|
||||
@test
|
||||
test_os_file_stream :: proc(t: ^testing.T) {
|
||||
defer if !testing.failed(t) {
|
||||
testing.expect_value(t, os.remove(TEMPORARY_FILENAME), nil)
|
||||
}
|
||||
|
||||
buf: [32]u8
|
||||
for i in 0..<u8(len(buf)) {
|
||||
buf[i] = 'A' + i
|
||||
}
|
||||
|
||||
TEMPORARY_FILENAME :: "test_core_io_os_file_stream"
|
||||
|
||||
fd, open_err := os.open(TEMPORARY_FILENAME, os.O_RDWR | os.O_CREATE | os.O_TRUNC, 0o644)
|
||||
if !testing.expectf(t, open_err == nil, "error on opening %q: %v", TEMPORARY_FILENAME, open_err) {
|
||||
return
|
||||
}
|
||||
|
||||
stream := os.stream_from_handle(fd)
|
||||
|
||||
bytes_written, write_err := io.write(stream, buf[:])
|
||||
if !testing.expectf(t, bytes_written == len(buf) && write_err == nil,
|
||||
"failed to Write initial buffer: bytes_written<%v> != len_buf<%v>, %v", bytes_written, len(buf), write_err) {
|
||||
return
|
||||
}
|
||||
|
||||
flush_err := io.flush(stream)
|
||||
if !testing.expectf(t, flush_err == nil,
|
||||
"failed to Flush initial buffer: %v", write_err) {
|
||||
return
|
||||
}
|
||||
|
||||
results, _ := _test_stream(t, stream, buf[:])
|
||||
|
||||
log.debugf("%#v", results)
|
||||
}
|
||||
@@ -23,6 +23,7 @@ download_assets :: proc() {
|
||||
@(require) import "encoding/xml"
|
||||
@(require) import "flags"
|
||||
@(require) import "fmt"
|
||||
@(require) import "io"
|
||||
@(require) import "math"
|
||||
@(require) import "math/big"
|
||||
@(require) import "math/linalg/glsl"
|
||||
|
||||
Reference in New Issue
Block a user