aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2024-05-30 14:36:36 +0200
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-06-02 14:47:08 -0400
commit601df0e8f77bb9da13557e9f54abbd99b973c4f2 (patch)
tree4ad9421380a2d25c4910d0bb84de07f9e6d232c8
parent1b32e27aa47c59a71b1cf4fefd40ce6e5ffc5bfb (diff)
Port `tests\core\encoding\json`
-rw-r--r--core/encoding/json/marshal.odin4
-rw-r--r--core/encoding/json/parser.odin65
-rw-r--r--core/encoding/json/types.odin14
-rw-r--r--tests/core/Makefile2
-rw-r--r--tests/core/build.bat2
-rw-r--r--tests/core/encoding/json/test_core_json.odin88
6 files changed, 67 insertions, 108 deletions
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin
index 4f5b50ec5..2933adf9a 100644
--- a/core/encoding/json/marshal.odin
+++ b/core/encoding/json/marshal.odin
@@ -62,8 +62,8 @@ Marshal_Options :: struct {
mjson_skipped_first_braces_end: bool,
}
-marshal :: proc(v: any, opt: Marshal_Options = {}, allocator := context.allocator) -> (data: []byte, err: Marshal_Error) {
- b := strings.builder_make(allocator)
+marshal :: proc(v: any, opt: Marshal_Options = {}, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Marshal_Error) {
+ b := strings.builder_make(allocator, loc)
defer if err != nil {
strings.builder_destroy(&b)
}
diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin
index 3973725dc..38f71edf6 100644
--- a/core/encoding/json/parser.odin
+++ b/core/encoding/json/parser.odin
@@ -28,27 +28,27 @@ make_parser_from_string :: proc(data: string, spec := DEFAULT_SPECIFICATION, par
}
-parse :: proc(data: []byte, spec := DEFAULT_SPECIFICATION, parse_integers := false, allocator := context.allocator) -> (Value, Error) {
- return parse_string(string(data), spec, parse_integers, allocator)
+parse :: proc(data: []byte, spec := DEFAULT_SPECIFICATION, parse_integers := false, allocator := context.allocator, loc := #caller_location) -> (Value, Error) {
+ return parse_string(string(data), spec, parse_integers, allocator, loc)
}
-parse_string :: proc(data: string, spec := DEFAULT_SPECIFICATION, parse_integers := false, allocator := context.allocator) -> (Value, Error) {
+parse_string :: proc(data: string, spec := DEFAULT_SPECIFICATION, parse_integers := false, allocator := context.allocator, loc := #caller_location) -> (Value, Error) {
context.allocator = allocator
p := make_parser_from_string(data, spec, parse_integers, allocator)
switch p.spec {
case .JSON:
- return parse_object(&p)
+ return parse_object(&p, loc)
case .JSON5:
- return parse_value(&p)
+ return parse_value(&p, loc)
case .SJSON:
#partial switch p.curr_token.kind {
case .Ident, .String:
- return parse_object_body(&p, .EOF)
+ return parse_object_body(&p, .EOF, loc)
}
- return parse_value(&p)
+ return parse_value(&p, loc)
}
- return parse_object(&p)
+ return parse_object(&p, loc)
}
token_end_pos :: proc(tok: Token) -> Pos {
@@ -106,7 +106,7 @@ parse_comma :: proc(p: ^Parser) -> (do_break: bool) {
return false
}
-parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
+parse_value :: proc(p: ^Parser, loc := #caller_location) -> (value: Value, err: Error) {
err = .None
token := p.curr_token
#partial switch token.kind {
@@ -142,13 +142,13 @@ parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
case .String:
advance_token(p)
- return unquote_string(token, p.spec, p.allocator)
+ return unquote_string(token, p.spec, p.allocator, loc)
case .Open_Brace:
- return parse_object(p)
+ return parse_object(p, loc)
case .Open_Bracket:
- return parse_array(p)
+ return parse_array(p, loc)
case:
if p.spec != .JSON {
@@ -176,7 +176,7 @@ parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
return
}
-parse_array :: proc(p: ^Parser) -> (value: Value, err: Error) {
+parse_array :: proc(p: ^Parser, loc := #caller_location) -> (value: Value, err: Error) {
err = .None
expect_token(p, .Open_Bracket) or_return
@@ -184,14 +184,14 @@ parse_array :: proc(p: ^Parser) -> (value: Value, err: Error) {
array.allocator = p.allocator
defer if err != nil {
for elem in array {
- destroy_value(elem)
+ destroy_value(elem, loc=loc)
}
- delete(array)
+ delete(array, loc)
}
for p.curr_token.kind != .Close_Bracket {
- elem := parse_value(p) or_return
- append(&array, elem)
+ elem := parse_value(p, loc) or_return
+ append(&array, elem, loc)
if parse_comma(p) {
break
@@ -228,38 +228,39 @@ clone_string :: proc(s: string, allocator: mem.Allocator, loc := #caller_locatio
return
}
-parse_object_key :: proc(p: ^Parser, key_allocator: mem.Allocator) -> (key: string, err: Error) {
+parse_object_key :: proc(p: ^Parser, key_allocator: mem.Allocator, loc := #caller_location) -> (key: string, err: Error) {
tok := p.curr_token
if p.spec != .JSON {
if allow_token(p, .Ident) {
- return clone_string(tok.text, key_allocator)
+ return clone_string(tok.text, key_allocator, loc)
}
}
if tok_err := expect_token(p, .String); tok_err != nil {
err = .Expected_String_For_Object_Key
return
}
- return unquote_string(tok, p.spec, key_allocator)
+ return unquote_string(tok, p.spec, key_allocator, loc)
}
-parse_object_body :: proc(p: ^Parser, end_token: Token_Kind) -> (obj: Object, err: Error) {
- obj.allocator = p.allocator
+parse_object_body :: proc(p: ^Parser, end_token: Token_Kind, loc := #caller_location) -> (obj: Object, err: Error) {
+ obj = make(Object, allocator=p.allocator, loc=loc)
+
defer if err != nil {
for key, elem in obj {
- delete(key, p.allocator)
- destroy_value(elem)
+ delete(key, p.allocator, loc)
+ destroy_value(elem, loc=loc)
}
- delete(obj)
+ delete(obj, loc)
}
for p.curr_token.kind != end_token {
- key := parse_object_key(p, p.allocator) or_return
+ key := parse_object_key(p, p.allocator, loc) or_return
parse_colon(p) or_return
- elem := parse_value(p) or_return
+ elem := parse_value(p, loc) or_return
if key in obj {
err = .Duplicate_Object_Key
- delete(key, p.allocator)
+ delete(key, p.allocator, loc)
return
}
@@ -267,7 +268,7 @@ parse_object_body :: proc(p: ^Parser, end_token: Token_Kind) -> (obj: Object, er
// inserting empty key/values into the object and for those we do not
// want to allocate anything
if key != "" {
- reserve_error := reserve(&obj, len(obj) + 1)
+ reserve_error := reserve(&obj, len(obj) + 1, loc)
if reserve_error == mem.Allocator_Error.Out_Of_Memory {
return nil, .Out_Of_Memory
}
@@ -281,9 +282,9 @@ parse_object_body :: proc(p: ^Parser, end_token: Token_Kind) -> (obj: Object, er
return obj, .None
}
-parse_object :: proc(p: ^Parser) -> (value: Value, err: Error) {
+parse_object :: proc(p: ^Parser, loc := #caller_location) -> (value: Value, err: Error) {
expect_token(p, .Open_Brace) or_return
- obj := parse_object_body(p, .Close_Brace) or_return
+ obj := parse_object_body(p, .Close_Brace, loc) or_return
expect_token(p, .Close_Brace) or_return
return obj, .None
}
@@ -480,4 +481,4 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a
}
return string(b[:w]), nil
-}
+} \ No newline at end of file
diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin
index 73e183615..41eb21377 100644
--- a/core/encoding/json/types.odin
+++ b/core/encoding/json/types.odin
@@ -89,22 +89,22 @@ Error :: enum {
-destroy_value :: proc(value: Value, allocator := context.allocator) {
+destroy_value :: proc(value: Value, allocator := context.allocator, loc := #caller_location) {
context.allocator = allocator
#partial switch v in value {
case Object:
for key, elem in v {
- delete(key)
- destroy_value(elem)
+ delete(key, loc=loc)
+ destroy_value(elem, loc=loc)
}
- delete(v)
+ delete(v, loc=loc)
case Array:
for elem in v {
- destroy_value(elem)
+ destroy_value(elem, loc=loc)
}
- delete(v)
+ delete(v, loc=loc)
case String:
- delete(v)
+ delete(v, loc=loc)
}
}
diff --git a/tests/core/Makefile b/tests/core/Makefile
index 46b9e352e..98027ab39 100644
--- a/tests/core/Makefile
+++ b/tests/core/Makefile
@@ -49,7 +49,7 @@ encoding_test:
$(ODIN) test encoding/cbor $(COMMON) -out:test_cbor
$(ODIN) test encoding/hex $(COMMON) -out:test_hex
$(ODIN) test encoding/hxa $(COMMON) -out:test_hxa
- $(ODIN) run encoding/json $(COMMON) -out:test_json
+ $(ODIN) test encoding/json $(COMMON) -out:test_json
$(ODIN) run encoding/varint $(COMMON) -out:test_varint
$(ODIN) run encoding/xml $(COMMON) -out:test_xml
diff --git a/tests/core/build.bat b/tests/core/build.bat
index 094a12f14..4bc5bb938 100644
--- a/tests/core/build.bat
+++ b/tests/core/build.bat
@@ -30,7 +30,7 @@ echo ---
%PATH_TO_ODIN% test encoding/cbor %COMMON% -out:test_cbor.exe || exit /b
%PATH_TO_ODIN% test encoding/hex %COMMON% -out:test_hex.exe || exit /b
%PATH_TO_ODIN% test encoding/hxa %COMMON% -out:test_hxa.exe || exit /b
-%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe || exit /b
+%PATH_TO_ODIN% test encoding/json %COMMON% -out:test_json.exe || exit /b
%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe || exit /b
%PATH_TO_ODIN% run encoding/xml %COMMON% -out:test_xml.exe || exit /b
diff --git a/tests/core/encoding/json/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin
index 813d11b2c..92c050952 100644
--- a/tests/core/encoding/json/test_core_json.odin
+++ b/tests/core/encoding/json/test_core_json.odin
@@ -2,46 +2,8 @@ package test_core_json
import "core:encoding/json"
import "core:testing"
-import "core:fmt"
-import "core:os"
import "core:mem/virtual"
-TEST_count := 0
-TEST_fail := 0
-
-when ODIN_TEST {
- expect :: testing.expect
- log :: testing.log
-} else {
- expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
- TEST_count += 1
- if !condition {
- TEST_fail += 1
- fmt.printf("[%v] %v\n", loc, message)
- return
- }
- }
- log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
- fmt.printf("[%v] ", loc)
- fmt.printf("log: %v\n", v)
- }
-}
-
-main :: proc() {
- t := testing.T{}
-
- parse_json(&t)
- marshal_json(&t)
- unmarshal_json(&t)
- surrogate(&t)
- utf8_string_of_multibyte_characters(&t)
-
- fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
- if TEST_fail > 0 {
- os.exit(1)
- }
-}
-
@test
parse_json :: proc(t: ^testing.T) {
@@ -72,10 +34,9 @@ parse_json :: proc(t: ^testing.T) {
}
`
- _, err := json.parse(transmute([]u8)json_data)
-
- msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err)
- expect(t, err == nil, msg)
+ val, err := json.parse(transmute([]u8)json_data)
+ json.destroy_value(val)
+ testing.expectf(t, err == nil, "Expected `json.parse` to return nil, got %v", err)
}
@test
@@ -83,7 +44,7 @@ out_of_memory_in_parse_json :: proc(t: ^testing.T) {
arena: virtual.Arena
arena_buffer: [256]byte
arena_init_error := virtual.arena_init_buffer(&arena, arena_buffer[:])
- testing.expect(t, arena_init_error == nil, fmt.tprintf("Expected arena initialization to not return error, got: %v\n", arena_init_error))
+ testing.expectf(t, arena_init_error == nil, "Expected arena initialization to not return error, got: %v\n", arena_init_error)
context.allocator = virtual.arena_allocator(&arena)
@@ -114,11 +75,11 @@ out_of_memory_in_parse_json :: proc(t: ^testing.T) {
}
`
- _, err := json.parse(transmute([]u8)json_data)
+ val, err := json.parse(transmute([]u8)json_data)
+ json.destroy_value(val)
expected_error := json.Error.Out_Of_Memory
- msg := fmt.tprintf("Expected `json.parse` to fail with %v, got %v", expected_error, err)
- expect(t, err == json.Error.Out_Of_Memory, msg)
+ testing.expectf(t, err == json.Error.Out_Of_Memory, "Expected `json.parse` to fail with %v, got %v", expected_error, err)
}
@test
@@ -134,9 +95,9 @@ marshal_json :: proc(t: ^testing.T) {
b = 5,
}
- _, err := json.marshal(my_struct)
- msg := fmt.tprintf("Expected `json.marshal` to return nil, got %v", err)
- expect(t, err == nil, msg)
+ data, err := json.marshal(my_struct)
+ defer delete(data)
+ testing.expectf(t, err == nil, "Expected `json.marshal` to return nil, got %v", err)
}
PRODUCTS := `
@@ -378,17 +339,12 @@ unmarshal_json :: proc(t: ^testing.T) {
err := json.unmarshal(transmute([]u8)PRODUCTS, &g, json.DEFAULT_SPECIFICATION)
defer cleanup(g)
- msg := fmt.tprintf("Expected `json.unmarshal` to return nil, got %v", err)
- expect(t, err == nil, msg)
-
- msg = fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products))
- expect(t, len(g.products) == len(original_data.products), msg)
-
- msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash)
- expect(t, original_data.cash == g.cash, msg)
+ testing.expectf(t, err == nil, "Expected `json.unmarshal` to return nil, got %v", err)
+ testing.expectf(t, len(g.products) == len(original_data.products), "Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products))
+ testing.expectf(t, original_data.cash == g.cash, "Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash)
for p, i in g.products {
- expect(t, p == original_data.products[i], "Producted unmarshaled improperly")
+ testing.expect(t, p == original_data.products[i], "Producted unmarshaled improperly")
}
}
@@ -397,17 +353,19 @@ surrogate :: proc(t: ^testing.T) {
input := `+ + * 😃 - /`
out, err := json.marshal(input)
- expect(t, err == nil, fmt.tprintf("Expected `json.marshal(%q)` to return a nil error, got %v", input, err))
+ defer delete(out)
+ testing.expectf(t, err == nil, "Expected `json.marshal(%q)` to return a nil error, got %v", input, err)
back: string
uerr := json.unmarshal(out, &back)
- expect(t, uerr == nil, fmt.tprintf("Expected `json.unmarshal(%q)` to return a nil error, got %v", string(out), uerr))
- expect(t, back == input, fmt.tprintf("Expected `json.unmarshal(%q)` to return %q, got %v", string(out), input, uerr))
+ defer delete(back)
+ testing.expectf(t, uerr == nil, "Expected `json.unmarshal(%q)` to return a nil error, got %v", string(out), uerr)
+ testing.expectf(t, back == input, "Expected `json.unmarshal(%q)` to return %q, got %v", string(out), input, uerr)
}
@test
utf8_string_of_multibyte_characters :: proc(t: ^testing.T) {
- _, err := json.parse_string(`"🐛✅"`)
- msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err)
- expect(t, err == nil, msg)
-}
+ val, err := json.parse_string(`"🐛✅"`)
+ defer json.destroy_value(val)
+ testing.expectf(t, err == nil, "Expected `json.parse` to return nil, got %v", err)
+} \ No newline at end of file