|
@@ -1,31 +1,9 @@
|
|
package test_core_text_i18n
|
|
package test_core_text_i18n
|
|
|
|
|
|
-import "core:mem"
|
|
|
|
-import "core:fmt"
|
|
|
|
-import "core:os"
|
|
|
|
|
|
+import "base:runtime"
|
|
import "core:testing"
|
|
import "core:testing"
|
|
import "core:text/i18n"
|
|
import "core:text/i18n"
|
|
|
|
|
|
-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)
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
T :: i18n.get
|
|
T :: i18n.get
|
|
|
|
|
|
Test :: struct {
|
|
Test :: struct {
|
|
@@ -37,25 +15,28 @@ Test :: struct {
|
|
|
|
|
|
Test_Suite :: struct {
|
|
Test_Suite :: struct {
|
|
file: string,
|
|
file: string,
|
|
- loader: proc(string, i18n.Parse_Options, proc(int) -> int, mem.Allocator) -> (^i18n.Translation, i18n.Error),
|
|
|
|
|
|
+ loader: proc(string, i18n.Parse_Options, proc(int) -> int, runtime.Allocator) -> (^i18n.Translation, i18n.Error),
|
|
plural: proc(int) -> int,
|
|
plural: proc(int) -> int,
|
|
err: i18n.Error,
|
|
err: i18n.Error,
|
|
options: i18n.Parse_Options,
|
|
options: i18n.Parse_Options,
|
|
tests: []Test,
|
|
tests: []Test,
|
|
}
|
|
}
|
|
|
|
|
|
-// Custom pluralizer for plur.mo
|
|
|
|
-plur_mo_pluralizer :: proc(n: int) -> (slot: int) {
|
|
|
|
- switch {
|
|
|
|
- case n == 1: return 0
|
|
|
|
- case n != 0 && n % 1_000_000 == 0: return 1
|
|
|
|
- case: return 2
|
|
|
|
|
|
+TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/I18N/"
|
|
|
|
+
|
|
|
|
+@(test)
|
|
|
|
+test_custom_pluralizer :: proc(t: ^testing.T) {
|
|
|
|
+ // Custom pluralizer for plur.mo
|
|
|
|
+ plur_mo_pluralizer :: proc(n: int) -> (slot: int) {
|
|
|
|
+ switch {
|
|
|
|
+ case n == 1: return 0
|
|
|
|
+ case n != 0 && n % 1_000_000 == 0: return 1
|
|
|
|
+ case: return 2
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-TESTS := []Test_Suite{
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/plur.mo",
|
|
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "plur.mo",
|
|
loader = i18n.parse_mo_file,
|
|
loader = i18n.parse_mo_file,
|
|
plural = plur_mo_pluralizer,
|
|
plural = plur_mo_pluralizer,
|
|
tests = {
|
|
tests = {
|
|
@@ -66,14 +47,16 @@ TESTS := []Test_Suite{
|
|
{"", "Message1/plural", "This is message 1", 1},
|
|
{"", "Message1/plural", "This is message 1", 1},
|
|
{"", "Message1/plural", "This is message 1 - plural A", 1_000_000},
|
|
{"", "Message1/plural", "This is message 1 - plural A", 1_000_000},
|
|
{"", "Message1/plural", "This is message 1 - plural B", 42},
|
|
{"", "Message1/plural", "This is message 1 - plural B", 42},
|
|
-
|
|
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
},
|
|
},
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/mixed_context.mo",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_mixed_context :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "mixed_context.mo",
|
|
loader = i18n.parse_mo_file,
|
|
loader = i18n.parse_mo_file,
|
|
plural = nil,
|
|
plural = nil,
|
|
tests = {
|
|
tests = {
|
|
@@ -84,19 +67,25 @@ TESTS := []Test_Suite{
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
},
|
|
},
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/mixed_context.mo",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_mixed_context_dupe :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "mixed_context.mo",
|
|
loader = i18n.parse_mo_file,
|
|
loader = i18n.parse_mo_file,
|
|
plural = nil,
|
|
plural = nil,
|
|
// Message1 exists twice, once within Context, which has been merged into ""
|
|
// Message1 exists twice, once within Context, which has been merged into ""
|
|
err = .Duplicate_Key,
|
|
err = .Duplicate_Key,
|
|
options = {merge_sections = true},
|
|
options = {merge_sections = true},
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/nl_NL.mo",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_nl_mo :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "nl_NL.mo",
|
|
loader = i18n.parse_mo_file,
|
|
loader = i18n.parse_mo_file,
|
|
plural = nil, // Default pluralizer
|
|
plural = nil, // Default pluralizer
|
|
tests = {
|
|
tests = {
|
|
@@ -111,12 +100,13 @@ TESTS := []Test_Suite{
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
// This isn't in the catalog, so should ruturn the key.
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
},
|
|
},
|
|
- },
|
|
|
|
-
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // QT Linguist with default loader options.
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/nl_NL-qt-ts.ts",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_qt_linguist :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "nl_NL-qt-ts.ts",
|
|
loader = i18n.parse_qt_linguist_file,
|
|
loader = i18n.parse_qt_linguist_file,
|
|
plural = nil, // Default pluralizer
|
|
plural = nil, // Default pluralizer
|
|
tests = {
|
|
tests = {
|
|
@@ -131,11 +121,13 @@ TESTS := []Test_Suite{
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
{"Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1},
|
|
},
|
|
},
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // QT Linguist, merging sections.
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/nl_NL-qt-ts.ts",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_qt_linguist_merge_sections :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, {
|
|
|
|
+ file = TEST_SUITE_PATH + "nl_NL-qt-ts.ts",
|
|
loader = i18n.parse_qt_linguist_file,
|
|
loader = i18n.parse_qt_linguist_file,
|
|
plural = nil, // Default pluralizer
|
|
plural = nil, // Default pluralizer
|
|
options = {merge_sections = true},
|
|
options = {merge_sections = true},
|
|
@@ -154,65 +146,38 @@ TESTS := []Test_Suite{
|
|
{"apple_count", "%d apple(s)", "%d apple(s)", 1},
|
|
{"apple_count", "%d apple(s)", "%d apple(s)", 1},
|
|
{"apple_count", "%d apple(s)", "%d apple(s)", 42},
|
|
{"apple_count", "%d apple(s)", "%d apple(s)", 42},
|
|
},
|
|
},
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // QT Linguist, merging sections. Expecting .Duplicate_Key error because same key exists in more than 1 section.
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/duplicate-key.ts",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_qt_linguist_duplicate_key_err :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, { // QT Linguist, merging sections. Expecting .Duplicate_Key error because same key exists in more than 1 section.
|
|
|
|
+ file = TEST_SUITE_PATH + "duplicate-key.ts",
|
|
loader = i18n.parse_qt_linguist_file,
|
|
loader = i18n.parse_qt_linguist_file,
|
|
plural = nil, // Default pluralizer
|
|
plural = nil, // Default pluralizer
|
|
options = {merge_sections = true},
|
|
options = {merge_sections = true},
|
|
err = .Duplicate_Key,
|
|
err = .Duplicate_Key,
|
|
- },
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
|
|
- // QT Linguist, not merging sections. Shouldn't return error despite same key existing in more than 1 section.
|
|
|
|
- {
|
|
|
|
- file = "assets/I18N/duplicate-key.ts",
|
|
|
|
|
|
+@(test)
|
|
|
|
+test_qt_linguist_duplicate_key :: proc(t: ^testing.T) {
|
|
|
|
+ test(t, { // QT Linguist, not merging sections. Shouldn't return error despite same key existing in more than 1 section.
|
|
|
|
+ file = TEST_SUITE_PATH + "duplicate-key.ts",
|
|
loader = i18n.parse_qt_linguist_file,
|
|
loader = i18n.parse_qt_linguist_file,
|
|
plural = nil, // Default pluralizer
|
|
plural = nil, // Default pluralizer
|
|
- },
|
|
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
|
|
-@test
|
|
|
|
-tests :: proc(t: ^testing.T) {
|
|
|
|
- cat: ^i18n.Translation
|
|
|
|
- err: i18n.Error
|
|
|
|
-
|
|
|
|
- for suite in TESTS {
|
|
|
|
- cat, err = suite.loader(suite.file, suite.options, suite.plural, context.allocator)
|
|
|
|
-
|
|
|
|
- msg := fmt.tprintf("Expected loading %v to return %v, got %v", suite.file, suite.err, err)
|
|
|
|
- expect(t, err == suite.err, msg)
|
|
|
|
-
|
|
|
|
- if err == .None {
|
|
|
|
- for test in suite.tests {
|
|
|
|
- val := T(test.section, test.key, test.n, cat)
|
|
|
|
-
|
|
|
|
- msg = fmt.tprintf("Expected key `%v` from section `%v`'s form for value `%v` to equal `%v`, got `%v`", test.key, test.section, test.n, test.val, val)
|
|
|
|
- expect(t, val == test.val, msg)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- i18n.destroy(cat)
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-main :: proc() {
|
|
|
|
- track: mem.Tracking_Allocator
|
|
|
|
- mem.tracking_allocator_init(&track, context.allocator)
|
|
|
|
- context.allocator = mem.tracking_allocator(&track)
|
|
|
|
-
|
|
|
|
- t := testing.T{}
|
|
|
|
- tests(&t)
|
|
|
|
-
|
|
|
|
- fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
|
|
|
- if TEST_fail > 0 {
|
|
|
|
- os.exit(1)
|
|
|
|
- }
|
|
|
|
|
|
+test :: proc(t: ^testing.T, suite: Test_Suite, loc := #caller_location) {
|
|
|
|
+ cat, err := suite.loader(suite.file, suite.options, suite.plural, context.allocator)
|
|
|
|
+ testing.expectf(t, err == suite.err, "Expected loading %v to return %v, got %v", suite.file, suite.err, err, loc=loc)
|
|
|
|
|
|
- if len(track.allocation_map) > 0 {
|
|
|
|
- fmt.println()
|
|
|
|
- for _, v in track.allocation_map {
|
|
|
|
- fmt.printf("%v Leaked %v bytes.\n", v.location, v.size)
|
|
|
|
|
|
+ if err == .None {
|
|
|
|
+ for test in suite.tests {
|
|
|
|
+ val := T(test.section, test.key, test.n, cat)
|
|
|
|
+ testing.expectf(t, val == test.val, "Expected key `%v` from section `%v`'s form for value `%v` to equal `%v`, got `%v`", test.key, test.section, test.n, test.val, val, loc=loc)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ i18n.destroy(cat)
|
|
}
|
|
}
|