You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
8.2 KiB
C++
319 lines
8.2 KiB
C++
#include "libshit/doctest.hpp"
|
|
#include "libshit/translate/node.hpp"
|
|
#include "libshit/translate/context.hpp"
|
|
|
|
#include <vector>
|
|
|
|
namespace Libshit::Translate::Test
|
|
{
|
|
TEST_SUITE_BEGIN("Libshit::Translate");
|
|
|
|
TEST_CASE("basic load test")
|
|
{
|
|
Context ctx;
|
|
std::stringstream ss(R"(
|
|
name: 日本語 # haha no
|
|
en_name: English
|
|
iso_code: en_US
|
|
decimal_sep: '.'
|
|
digit_sep: ','
|
|
---
|
|
foo:
|
|
bar: test
|
|
bar:
|
|
- asd
|
|
- def
|
|
)");
|
|
ctx.Load(ss);
|
|
SUBCASE("correct usage")
|
|
{
|
|
CHECK(ctx.GetInfo().name == "日本語");
|
|
CHECK(ctx.GetInfo().en_name == "English");
|
|
CHECK(ctx.GetInfo().iso_code == "en_US");
|
|
CHECK(ctx.GetInfo().decimal_sep == ".");
|
|
CHECK(ctx.GetInfo().digit_sep == ",");
|
|
CHECK(ctx.GetInfo().plural_exprs.size() == 0);
|
|
CHECK(ctx.GetInfo().plural_count == 1);
|
|
|
|
CHECK(ctx["foo"]["bar"]()->ToString() == "test");
|
|
CHECK(ctx["bar"]["1"]()->ToString() == "def");
|
|
}
|
|
|
|
SUBCASE("nonexisting key")
|
|
{
|
|
CHECK(ctx["not_there"]["nope"]()->ToString() == "not_there.nope()");
|
|
CHECK(ctx["not_there"]["nope"]()->ToString() == "not_there.nope()");
|
|
CHECK(ctx["nope"](12, 3.14f, "foo")->ToString() == "nope(12, 3.14, foo)");
|
|
CHECK(ctx["foo"]["nope"]()->ToString() == "foo.nope()");
|
|
CHECK(ctx["foo"](ctx["foo"]["bar"]())->ToString() == "foo(test)");
|
|
}
|
|
}
|
|
|
|
TEST_CASE("load multiple")
|
|
{
|
|
Context ctx;
|
|
std::stringstream ss(R"(
|
|
name: 日本語 # haha no
|
|
en_name: English
|
|
iso_code: en_US
|
|
decimal_sep: '.'
|
|
digit_sep: ','
|
|
genders: [ga, gb]
|
|
cases: [a, b]
|
|
macros:
|
|
foo: '<#a>'
|
|
---
|
|
foo: !gender:gb simple
|
|
bar: $INT $STRING $INT
|
|
asd: $GENERIC
|
|
genderp: ${G neutral a b}
|
|
genderadv: ${GADV x gb=gb}
|
|
sub:
|
|
foo: foo
|
|
bar: not bar
|
|
macro: ${foo "x y"}
|
|
case: !cases
|
|
default: foo
|
|
a: a
|
|
acase: ${STRING.a}
|
|
bcase: ${STRING.b}
|
|
)");
|
|
ctx.Load(ss);
|
|
|
|
SUBCASE("load extra")
|
|
{
|
|
CHECK(ctx["foo"]()->ToString() == "simple");
|
|
CHECK(ctx["extra"]()->ToString() == "extra()");
|
|
|
|
std::stringstream ss2("...\nextra: yes\n");
|
|
ctx.Load(ss2);
|
|
|
|
CHECK(ctx["foo"]()->ToString() == "simple");
|
|
CHECK(ctx["extra"]()->ToString() == "yes");
|
|
}
|
|
|
|
SUBCASE("append category")
|
|
{
|
|
CHECK(ctx["sub"]["bar"]()->ToString() == "not bar");
|
|
CHECK(ctx["sub"]["asd"]()->ToString() == "sub.asd()");
|
|
|
|
std::stringstream ss2("...\nsub:\n asd: dsa\n");
|
|
ctx.Load(ss2);
|
|
|
|
CHECK(ctx["sub"]["bar"]()->ToString() == "not bar");
|
|
CHECK(ctx["sub"]["asd"]()->ToString() == "dsa");
|
|
}
|
|
|
|
SUBCASE("replace in category")
|
|
{
|
|
REQUIRE(ctx["sub"]["foo"]()->ToString() == "foo");
|
|
|
|
std::stringstream ss2("...\nsub:\n foo: changed\n");
|
|
ctx.Load(ss2);
|
|
|
|
CHECK(ctx["sub"]["foo"]()->ToString() == "changed");
|
|
}
|
|
|
|
SUBCASE("replace same type args")
|
|
{
|
|
std::stringstream ss2("...\nbar: '<$INT> <$STRING> <$INT>'\n");
|
|
ctx.Load(ss2);
|
|
|
|
CHECK(ctx["bar"](1, "foo", 2)->ToString() == "<1> <foo> <2>");
|
|
}
|
|
|
|
SUBCASE("replace compatible args")
|
|
{
|
|
// less arguments are ok
|
|
std::stringstream ss2("...\nbar: '<$INT> <$GENERIC>'\n");
|
|
ctx.Load(ss2);
|
|
|
|
CHECK(ctx["bar"](1, "foo", 2)->ToString() == "<1> <foo>");
|
|
}
|
|
|
|
SUBCASE("replace incomatible args")
|
|
{
|
|
std::stringstream ss2("...\nbar: '<$FLOAT> <$STRING> <$INT>'\n");
|
|
CHECK_THROWS(ctx.Load(ss2));
|
|
}
|
|
|
|
SUBCASE("replace more args")
|
|
{
|
|
std::stringstream ss2("...\nbar: '<$INT> <$STRING> <$INT> $INT'\n");
|
|
CHECK_THROWS(ctx.Load(ss2));
|
|
}
|
|
|
|
SUBCASE("replace less generic")
|
|
{
|
|
std::stringstream ss2("...\nasd: '<$INT>'\n");
|
|
CHECK_THROWS(ctx.Load(ss2));
|
|
}
|
|
|
|
SUBCASE("case merge")
|
|
{
|
|
std::stringstream ss2(R"(
|
|
...
|
|
test: !cases
|
|
default: nothing
|
|
a: int$INT
|
|
b: gen$GENERIC
|
|
)");
|
|
ctx.Load(ss2);
|
|
|
|
Types t;
|
|
ctx["test"]->UpdateTypes(t);
|
|
REQUIRE(t.size() == 1);
|
|
CHECK(t[0] == Type::INTEGER);
|
|
}
|
|
|
|
SUBCASE("case invalid merge")
|
|
{
|
|
std::stringstream ss2(R"(
|
|
...
|
|
test: !cases
|
|
default: str$STRING
|
|
a: int$INT
|
|
b: gen$GENERIC
|
|
)");
|
|
CHECK_THROWS(ctx.Load(ss2));
|
|
}
|
|
|
|
SUBCASE("replace macro")
|
|
{
|
|
CHECK(ctx["sub"]["macro"]()->ToString() == "<x y>");
|
|
std::stringstream ss2{R"(
|
|
macros:
|
|
foo: bar
|
|
---
|
|
new: -$foo-
|
|
)"};
|
|
ctx.Load(ss2);
|
|
CHECK(ctx["sub"]["macro"]()->ToString() == "<x y>");
|
|
CHECK(ctx["new"]()->ToString() == "-bar-");
|
|
}
|
|
SUBCASE("add new macro")
|
|
{
|
|
std::stringstream ss2{R"(
|
|
macros:
|
|
abc: 'def ${#.:INT}'
|
|
---
|
|
old: (${foo gg})
|
|
new: '[$1:abc]'
|
|
)"};
|
|
ctx.Load(ss2);
|
|
CHECK(ctx["old"]()->ToString() == "(<gg>)");
|
|
CHECK(ctx["new"](1, 2)->ToString() == "[def 2]");
|
|
}
|
|
|
|
SUBCASE("add gender")
|
|
{
|
|
CHECK(ctx["genderp"]("foo")->ToString() == "neutral");
|
|
CHECK(ctx["genderp"](ctx["foo"]())->ToString() == "b");
|
|
CHECK(ctx["genderadv"]("foo")->ToString() == "x");
|
|
CHECK(ctx["genderadv"](ctx["foo"]())->ToString() == "gb");
|
|
|
|
std::stringstream ss2{R"(
|
|
genders: [ga, sjw, nsjw]
|
|
---
|
|
agender: !gender:ga aaa
|
|
ngender: !gender:sjw xxx
|
|
ngenderp: ${G neutral a sjw nsjw}
|
|
ngenderadv: ${GADV x ga=ga gb=gb sjw=sjw}
|
|
)"};
|
|
ctx.Load(ss2);
|
|
CHECK(ctx["genderp"]("foo")->ToString() == "neutral");
|
|
CHECK(ctx["genderp"](ctx["foo"]())->ToString() == "b");
|
|
CHECK(ctx["genderp"](ctx["agender"]())->ToString() == "a");
|
|
CHECK(ctx["genderp"](ctx["ngender"]())->ToString() == "neutral");
|
|
CHECK(ctx["genderadv"]("foo")->ToString() == "x");
|
|
CHECK(ctx["genderadv"](ctx["foo"]())->ToString() == "gb");
|
|
CHECK(ctx["genderadv"](ctx["agender"]())->ToString() == "x");
|
|
CHECK(ctx["genderadv"](ctx["ngender"]())->ToString() == "x");
|
|
|
|
CHECK(ctx["ngenderp"]("foo")->ToString() == "neutral");
|
|
CHECK(ctx["ngenderp"](ctx["foo"]())->ToString() == "neutral");
|
|
CHECK(ctx["ngenderp"](ctx["agender"]())->ToString() == "a");
|
|
CHECK(ctx["ngenderp"](ctx["ngender"]())->ToString() == "sjw");
|
|
CHECK(ctx["ngenderadv"]("foo")->ToString() == "x");
|
|
CHECK(ctx["ngenderadv"](ctx["foo"]())->ToString() == "gb");
|
|
CHECK(ctx["ngenderadv"](ctx["agender"]())->ToString() == "ga");
|
|
CHECK(ctx["ngenderadv"](ctx["ngender"]())->ToString() == "sjw");
|
|
}
|
|
|
|
SUBCASE("add cases")
|
|
{
|
|
CHECK(ctx["asd"](ctx["case"]())->ToString() == "foo");
|
|
CHECK(ctx["acase"](ctx["case"]())->ToString() == "a");
|
|
CHECK(ctx["bcase"](ctx["case"]())->ToString() == "foo");
|
|
|
|
std::stringstream ss2{R"(
|
|
cases: [a, c]
|
|
---
|
|
ncase: !cases
|
|
default: def
|
|
a: acase
|
|
b: bcase
|
|
c: ccase
|
|
ccase: ${STRING.c}
|
|
)"};
|
|
ctx.Load(ss2);
|
|
CHECK(ctx["asd"](ctx["case"]())->ToString() == "foo");
|
|
CHECK(ctx["acase"](ctx["case"]())->ToString() == "a");
|
|
CHECK(ctx["bcase"](ctx["case"]())->ToString() == "foo");
|
|
CHECK(ctx["ccase"](ctx["case"]())->ToString() == "foo");
|
|
CHECK(ctx["asd"](ctx["ncase"]())->ToString() == "def");
|
|
CHECK(ctx["acase"](ctx["ncase"]())->ToString() == "acase");
|
|
CHECK(ctx["bcase"](ctx["ncase"]())->ToString() == "bcase");
|
|
CHECK(ctx["ccase"](ctx["ncase"]())->ToString() == "ccase");
|
|
}
|
|
}
|
|
|
|
TEST_CASE("tags")
|
|
{
|
|
Context ctx;
|
|
std::stringstream ss(R"(
|
|
name: 日本語 # haha no
|
|
en_name: English
|
|
iso_code: en_US
|
|
decimal_sep: '.'
|
|
digit_sep: ','
|
|
genders: [a, b]
|
|
---
|
|
foo: !plain simple
|
|
bar: !plain $INT $STRING $INT
|
|
asd: !format $GENERIC
|
|
def: !gender
|
|
gender: a
|
|
value: aly
|
|
ghi: !gender:b bly
|
|
gend: $0:STRING ing${0:G wtf? la lb}
|
|
gadv: $0:STRING ${0:GADV x b=y}
|
|
)");
|
|
ctx.Load(ss);
|
|
|
|
CHECK(ctx["foo"]()->ToString() == "simple");
|
|
CHECK(ctx["bar"]()->ToString() == "$INT $STRING $INT");
|
|
CHECK(ctx["asd"](3)->ToString() == "3");
|
|
|
|
auto x = ctx["def"]()->Get({});
|
|
CHECK(x.gender == 1);
|
|
CHECK(x.str == "aly");
|
|
|
|
auto y = ctx["ghi"]()->Get({});
|
|
CHECK(y.gender == 2);
|
|
CHECK(y.str == "bly");
|
|
|
|
CHECK(ctx["gend"](ctx["def"]())->ToString() == "aly ingla");
|
|
CHECK(ctx["gend"](ctx["ghi"]())->ToString() == "bly inglb");
|
|
CHECK(ctx["gend"](ctx["foo"]())->ToString() == "simple ingwtf?");
|
|
CHECK(ctx["gend"]("cstr")->ToString() == "cstr ingwtf?");
|
|
|
|
CHECK(ctx["gadv"](ctx["def"]())->ToString() == "aly x");
|
|
CHECK(ctx["gadv"](ctx["ghi"]())->ToString() == "bly y");
|
|
CHECK(ctx["gadv"](ctx["foo"]())->ToString() == "simple x");
|
|
CHECK(ctx["gadv"]("cstr")->ToString() == "cstr x");
|
|
}
|
|
|
|
TEST_SUITE_END();
|
|
}
|