|
@@ -2,10 +2,10 @@ package test_core_xml
|
|
|
|
|
|
import "core:encoding/xml"
|
|
import "core:encoding/xml"
|
|
import "core:testing"
|
|
import "core:testing"
|
|
-import "core:mem"
|
|
|
|
import "core:strings"
|
|
import "core:strings"
|
|
import "core:io"
|
|
import "core:io"
|
|
import "core:fmt"
|
|
import "core:fmt"
|
|
|
|
+import "core:log"
|
|
import "core:hash"
|
|
import "core:hash"
|
|
|
|
|
|
Silent :: proc(pos: xml.Pos, format: string, args: ..any) {}
|
|
Silent :: proc(pos: xml.Pos, format: string, args: ..any) {}
|
|
@@ -14,9 +14,6 @@ OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, },
|
|
expected_doctype = "",
|
|
expected_doctype = "",
|
|
}
|
|
}
|
|
|
|
|
|
-TEST_count := 0
|
|
|
|
-TEST_fail := 0
|
|
|
|
-
|
|
|
|
TEST :: struct {
|
|
TEST :: struct {
|
|
filename: string,
|
|
filename: string,
|
|
options: xml.Options,
|
|
options: xml.Options,
|
|
@@ -24,22 +21,14 @@ TEST :: struct {
|
|
crc32: u32,
|
|
crc32: u32,
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- Relative to ODIN_ROOT
|
|
|
|
-*/
|
|
|
|
-TEST_FILE_PATH_PREFIX :: "tests/core/assets"
|
|
|
|
-
|
|
|
|
-TESTS :: []TEST{
|
|
|
|
- /*
|
|
|
|
- First we test that certain files parse without error.
|
|
|
|
- */
|
|
|
|
|
|
+TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/"
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- Tests UTF-8 idents and values.
|
|
|
|
- Test namespaced ident.
|
|
|
|
- Tests that nested partial CDATA start doesn't trip up parser.
|
|
|
|
- */
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_utf8_normal :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
|
|
+ // Tests UTF-8 idents and values.
|
|
|
|
+ // Test namespaced ident.
|
|
|
|
+ // Tests that nested partial CDATA start doesn't trip up parser.
|
|
filename = "XML/utf8.xml",
|
|
filename = "XML/utf8.xml",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -48,13 +37,14 @@ TESTS :: []TEST{
|
|
expected_doctype = "恥ずべきフクロウ",
|
|
expected_doctype = "恥ずべきフクロウ",
|
|
},
|
|
},
|
|
crc32 = 0xe9b62f03,
|
|
crc32 = 0xe9b62f03,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- Same as above.
|
|
|
|
- Unbox CDATA in data tag.
|
|
|
|
- */
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_utf8_unbox_cdata :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
|
|
+ // Same as above.
|
|
|
|
+ // Unbox CDATA in data tag.
|
|
filename = "XML/utf8.xml",
|
|
filename = "XML/utf8.xml",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -63,13 +53,14 @@ TESTS :: []TEST{
|
|
expected_doctype = "恥ずべきフクロウ",
|
|
expected_doctype = "恥ずべきフクロウ",
|
|
},
|
|
},
|
|
crc32 = 0x9c2643ed,
|
|
crc32 = 0x9c2643ed,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- Simple Qt TS translation file.
|
|
|
|
- `core:i18n` requires it to be parsed properly.
|
|
|
|
- */
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_nl_qt_ts :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
|
|
+ // Simple Qt TS translation file.
|
|
|
|
+ // `core:i18n` requires it to be parsed properly.
|
|
filename = "I18N/nl_NL-qt-ts.ts",
|
|
filename = "I18N/nl_NL-qt-ts.ts",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -78,13 +69,14 @@ TESTS :: []TEST{
|
|
expected_doctype = "TS",
|
|
expected_doctype = "TS",
|
|
},
|
|
},
|
|
crc32 = 0x859b7443,
|
|
crc32 = 0x859b7443,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- Simple XLiff 1.2 file.
|
|
|
|
- `core:i18n` requires it to be parsed properly.
|
|
|
|
- */
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_xliff_1_2 :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
|
|
+ // Simple XLiff 1.2 file.
|
|
|
|
+ // `core:i18n` requires it to be parsed properly.
|
|
filename = "I18N/nl_NL-xliff-1.2.xliff",
|
|
filename = "I18N/nl_NL-xliff-1.2.xliff",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -93,13 +85,14 @@ TESTS :: []TEST{
|
|
expected_doctype = "xliff",
|
|
expected_doctype = "xliff",
|
|
},
|
|
},
|
|
crc32 = 0x3deaf329,
|
|
crc32 = 0x3deaf329,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- Simple XLiff 2.0 file.
|
|
|
|
- `core:i18n` requires it to be parsed properly.
|
|
|
|
- */
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_xliff_2_0 :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
|
|
+ // Simple XLiff 2.0 file.
|
|
|
|
+ // `core:i18n` requires it to be parsed properly.
|
|
filename = "I18N/nl_NL-xliff-2.0.xliff",
|
|
filename = "I18N/nl_NL-xliff-2.0.xliff",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -108,9 +101,12 @@ TESTS :: []TEST{
|
|
expected_doctype = "xliff",
|
|
expected_doctype = "xliff",
|
|
},
|
|
},
|
|
crc32 = 0x0c55e287,
|
|
crc32 = 0x0c55e287,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_entities :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
filename = "XML/entities.html",
|
|
filename = "XML/entities.html",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -119,9 +115,12 @@ TESTS :: []TEST{
|
|
expected_doctype = "html",
|
|
expected_doctype = "html",
|
|
},
|
|
},
|
|
crc32 = 0x05373317,
|
|
crc32 = 0x05373317,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_entities_unbox :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
filename = "XML/entities.html",
|
|
filename = "XML/entities.html",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -130,9 +129,12 @@ TESTS :: []TEST{
|
|
expected_doctype = "html",
|
|
expected_doctype = "html",
|
|
},
|
|
},
|
|
crc32 = 0x3b6d4a90,
|
|
crc32 = 0x3b6d4a90,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_entities_unbox_decode :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
filename = "XML/entities.html",
|
|
filename = "XML/entities.html",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -141,12 +143,12 @@ TESTS :: []TEST{
|
|
expected_doctype = "html",
|
|
expected_doctype = "html",
|
|
},
|
|
},
|
|
crc32 = 0x5be2ffdc,
|
|
crc32 = 0x5be2ffdc,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
|
- Then we test that certain errors are returned as expected.
|
|
|
|
- */
|
|
|
|
- {
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_invalid_doctype :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
filename = "XML/utf8.xml",
|
|
filename = "XML/utf8.xml",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -156,12 +158,12 @@ TESTS :: []TEST{
|
|
},
|
|
},
|
|
err = .Invalid_DocType,
|
|
err = .Invalid_DocType,
|
|
crc32 = 0x49b83d0a,
|
|
crc32 = 0x49b83d0a,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
|
- Parse the 9.08 MiB unicode.xml for good measure.
|
|
|
|
- */
|
|
|
|
- {
|
|
|
|
|
|
+@(test)
|
|
|
|
+xml_test_unicode :: proc(t: ^testing.T) {
|
|
|
|
+ run_test(t, {
|
|
filename = "XML/unicode.xml",
|
|
filename = "XML/unicode.xml",
|
|
options = {
|
|
options = {
|
|
flags = {
|
|
flags = {
|
|
@@ -171,39 +173,37 @@ TESTS :: []TEST{
|
|
},
|
|
},
|
|
err = .None,
|
|
err = .None,
|
|
crc32 = 0x0b6100ab,
|
|
crc32 = 0x0b6100ab,
|
|
- },
|
|
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
|
|
-when ODIN_TEST {
|
|
|
|
- expect :: testing.expect
|
|
|
|
- log :: testing.log
|
|
|
|
-} else {
|
|
|
|
- expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
|
|
|
|
- TEST_count += 1
|
|
|
|
- if !condition {
|
|
|
|
- TEST_fail += 1
|
|
|
|
- fmt.printf("[%v] %v\n", loc, message)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
|
|
|
|
- fmt.printf("[%v] LOG:\n\t%v\n", loc, v)
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+@(private)
|
|
|
|
+run_test :: proc(t: ^testing.T, test: TEST) {
|
|
|
|
+ path := strings.concatenate({TEST_SUITE_PATH, test.filename})
|
|
|
|
+ defer delete(path)
|
|
|
|
|
|
-test_file_path :: proc(filename: string) -> (path: string) {
|
|
|
|
|
|
+ doc, err := xml.load_from_file(path, test.options, Silent)
|
|
|
|
+ defer xml.destroy(doc)
|
|
|
|
|
|
- path = fmt.tprintf("%v%v/%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename)
|
|
|
|
- temp := transmute([]u8)path
|
|
|
|
|
|
+ tree_string := doc_to_string(doc)
|
|
|
|
+ tree_bytes := transmute([]u8)tree_string
|
|
|
|
+ defer delete(tree_bytes)
|
|
|
|
|
|
- for r, i in path {
|
|
|
|
- if r == '\\' {
|
|
|
|
- temp[i] = '/'
|
|
|
|
- }
|
|
|
|
|
|
+ crc32 := hash.crc32(tree_bytes)
|
|
|
|
+
|
|
|
|
+ failed := err != test.err
|
|
|
|
+ testing.expectf(t, err == test.err, "%v: Expected return value %v, got %v", test.filename, test.err, err)
|
|
|
|
+
|
|
|
|
+ failed |= crc32 != test.crc32
|
|
|
|
+ testing.expectf(t, crc32 == test.crc32, "%v: Expected CRC 0x%08x, got 0x%08x, with options %v", test.filename, test.crc32, crc32, test.options)
|
|
|
|
+
|
|
|
|
+ if failed {
|
|
|
|
+ // Don't fully print big trees.
|
|
|
|
+ tree_string = tree_string[:min(2_048, len(tree_string))]
|
|
|
|
+ log.error(tree_string)
|
|
}
|
|
}
|
|
- return path
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+@(private)
|
|
doc_to_string :: proc(doc: ^xml.Document) -> (result: string) {
|
|
doc_to_string :: proc(doc: ^xml.Document) -> (result: string) {
|
|
/*
|
|
/*
|
|
Effectively a clone of the debug printer in the xml package.
|
|
Effectively a clone of the debug printer in the xml package.
|
|
@@ -284,56 +284,4 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) {
|
|
|
|
|
|
print(strings.to_writer(&buf), doc)
|
|
print(strings.to_writer(&buf), doc)
|
|
return strings.clone(strings.to_string(buf))
|
|
return strings.clone(strings.to_string(buf))
|
|
-}
|
|
|
|
-
|
|
|
|
-@test
|
|
|
|
-run_tests :: proc(t: ^testing.T) {
|
|
|
|
- for test in TESTS {
|
|
|
|
- path := test_file_path(test.filename)
|
|
|
|
- log(t, fmt.tprintf("Trying to parse %v", path))
|
|
|
|
-
|
|
|
|
- doc, err := xml.load_from_file(path, test.options, Silent)
|
|
|
|
- defer xml.destroy(doc)
|
|
|
|
-
|
|
|
|
- tree_string := doc_to_string(doc)
|
|
|
|
- tree_bytes := transmute([]u8)tree_string
|
|
|
|
- defer delete(tree_bytes)
|
|
|
|
-
|
|
|
|
- crc32 := hash.crc32(tree_bytes)
|
|
|
|
-
|
|
|
|
- failed := err != test.err
|
|
|
|
- err_msg := fmt.tprintf("Expected return value %v, got %v", test.err, err)
|
|
|
|
- expect(t, err == test.err, err_msg)
|
|
|
|
-
|
|
|
|
- failed |= crc32 != test.crc32
|
|
|
|
- err_msg = fmt.tprintf("Expected CRC 0x%08x, got 0x%08x, with options %v", test.crc32, crc32, test.options)
|
|
|
|
- expect(t, crc32 == test.crc32, err_msg)
|
|
|
|
-
|
|
|
|
- if failed {
|
|
|
|
- /*
|
|
|
|
- Don't fully print big trees.
|
|
|
|
- */
|
|
|
|
- tree_string = tree_string[:min(2_048, len(tree_string))]
|
|
|
|
- fmt.println(tree_string)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-main :: proc() {
|
|
|
|
- t := testing.T{}
|
|
|
|
-
|
|
|
|
- track: mem.Tracking_Allocator
|
|
|
|
- mem.tracking_allocator_init(&track, context.allocator)
|
|
|
|
- context.allocator = mem.tracking_allocator(&track)
|
|
|
|
-
|
|
|
|
- run_tests(&t)
|
|
|
|
-
|
|
|
|
- if len(track.allocation_map) > 0 {
|
|
|
|
- for _, v in track.allocation_map {
|
|
|
|
- err_msg := fmt.tprintf("%v Leaked %v bytes.", v.location, v.size)
|
|
|
|
- expect(&t, false, err_msg)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
|
|
|
}
|
|
}
|