libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

translate.cpp (8418B)


      1 #include "libshit/doctest.hpp"
      2 #include "libshit/translate/node.hpp"
      3 #include "libshit/translate/context.hpp"
      4 
      5 #include <vector>
      6 
      7 namespace Libshit::Translate::Test
      8 {
      9   TEST_SUITE_BEGIN("Libshit::Translate");
     10 
     11   TEST_CASE("basic load test")
     12   {
     13     Context ctx;
     14     std::stringstream ss(R"(
     15 name: 日本語 # haha no
     16 en_name: English
     17 iso_code: en_US
     18 decimal_sep: '.'
     19 digit_sep: ','
     20 ---
     21 foo:
     22   bar: test
     23 bar:
     24   - asd
     25   - def
     26 )");
     27     ctx.Load(ss);
     28     SUBCASE("correct usage")
     29     {
     30       CHECK(ctx.GetInfo().name == "日本語");
     31       CHECK(ctx.GetInfo().en_name == "English");
     32       CHECK(ctx.GetInfo().iso_code == "en_US");
     33       CHECK(ctx.GetInfo().decimal_sep == ".");
     34       CHECK(ctx.GetInfo().digit_sep == ",");
     35       CHECK(ctx.GetInfo().plural_exprs.size() == 0);
     36       CHECK(ctx.GetInfo().plural_count == 1);
     37 
     38       CHECK(ctx["foo"]["bar"]()->ToString() == "test");
     39       CHECK(ctx["bar"]["1"]()->ToString() == "def");
     40     }
     41 
     42     SUBCASE("nonexisting key")
     43     {
     44       CHECK(ctx["not_there"]["nope"]()->ToString() == "not_there.nope()");
     45       CHECK(ctx["not_there"]["nope"]()->ToString() == "not_there.nope()");
     46       CHECK(ctx["nope"](12, 3.14f, "foo")->ToString() == "nope(12, 3.14, foo)");
     47       CHECK(ctx["foo"]["nope"]()->ToString() == "foo.nope()");
     48       CHECK(ctx["foo"](ctx["foo"]["bar"]())->ToString() == "foo(test)");
     49     }
     50   }
     51 
     52   TEST_CASE("load multiple")
     53   {
     54     Context ctx;
     55     std::stringstream ss(R"(
     56 name: 日本語 # haha no
     57 en_name: English
     58 iso_code: en_US
     59 decimal_sep: '.'
     60 digit_sep: ','
     61 genders: [ga, gb]
     62 cases: [a, b]
     63 macros:
     64   foo: '<#a>'
     65 ---
     66 foo: !gender:gb simple
     67 bar: $INT $STRING $INT
     68 asd: $GENERIC
     69 genderp: ${G neutral a b}
     70 genderadv: ${GADV x gb=gb}
     71 sub:
     72   foo: foo
     73   bar: not bar
     74   macro: ${foo "x y"}
     75 case: !cases
     76   default: foo
     77   a: a
     78 acase: ${STRING.a}
     79 bcase: ${STRING.b}
     80 )");
     81     ctx.Load(ss);
     82 
     83     SUBCASE("load extra")
     84     {
     85       CHECK(ctx["foo"]()->ToString() == "simple");
     86       CHECK(ctx["extra"]()->ToString() == "extra()");
     87 
     88       std::stringstream ss2("...\nextra: yes\n");
     89       ctx.Load(ss2);
     90 
     91       CHECK(ctx["foo"]()->ToString() == "simple");
     92       CHECK(ctx["extra"]()->ToString() == "yes");
     93     }
     94 
     95     SUBCASE("append category")
     96     {
     97       CHECK(ctx["sub"]["bar"]()->ToString() == "not bar");
     98       CHECK(ctx["sub"]["asd"]()->ToString() == "sub.asd()");
     99 
    100       std::stringstream ss2("...\nsub:\n  asd: dsa\n");
    101       ctx.Load(ss2);
    102 
    103       CHECK(ctx["sub"]["bar"]()->ToString() == "not bar");
    104       CHECK(ctx["sub"]["asd"]()->ToString() == "dsa");
    105     }
    106 
    107     SUBCASE("replace in category")
    108     {
    109       REQUIRE(ctx["sub"]["foo"]()->ToString() == "foo");
    110 
    111       std::stringstream ss2("...\nsub:\n  foo: changed\n");
    112       ctx.Load(ss2);
    113 
    114       CHECK(ctx["sub"]["foo"]()->ToString() == "changed");
    115     }
    116 
    117     SUBCASE("replace same type args")
    118     {
    119       std::stringstream ss2("...\nbar: '<$INT> <$STRING> <$INT>'\n");
    120       ctx.Load(ss2);
    121 
    122       CHECK(ctx["bar"](1, "foo", 2)->ToString() == "<1> <foo> <2>");
    123     }
    124 
    125     SUBCASE("replace compatible args")
    126     {
    127       // less arguments are ok
    128       std::stringstream ss2("...\nbar: '<$INT> <$GENERIC>'\n");
    129       ctx.Load(ss2);
    130 
    131       CHECK(ctx["bar"](1, "foo", 2)->ToString() == "<1> <foo>");
    132     }
    133 
    134     SUBCASE("replace incomatible args")
    135     {
    136       std::stringstream ss2("...\nbar: '<$FLOAT> <$STRING> <$INT>'\n");
    137       CHECK_THROWS(ctx.Load(ss2));
    138     }
    139 
    140     SUBCASE("replace more args")
    141     {
    142       std::stringstream ss2("...\nbar: '<$INT> <$STRING> <$INT> $INT'\n");
    143       CHECK_THROWS(ctx.Load(ss2));
    144     }
    145 
    146     SUBCASE("replace less generic")
    147     {
    148       std::stringstream ss2("...\nasd: '<$INT>'\n");
    149       CHECK_THROWS(ctx.Load(ss2));
    150     }
    151 
    152     SUBCASE("case merge")
    153     {
    154       std::stringstream ss2(R"(
    155 ...
    156 test: !cases
    157   default: nothing
    158   a: int$INT
    159   b: gen$GENERIC
    160 )");
    161       ctx.Load(ss2);
    162 
    163       Types t;
    164       ctx["test"]->UpdateTypes(t);
    165       REQUIRE(t.size() == 1);
    166       CHECK(t[0] == Type::INTEGER);
    167     }
    168 
    169     SUBCASE("case invalid merge")
    170     {
    171       std::stringstream ss2(R"(
    172 ...
    173 test: !cases
    174   default: str$STRING
    175   a: int$INT
    176   b: gen$GENERIC
    177 )");
    178       CHECK_THROWS(ctx.Load(ss2));
    179     }
    180 
    181     SUBCASE("replace macro")
    182     {
    183       CHECK(ctx["sub"]["macro"]()->ToString() == "<x y>");
    184       std::stringstream ss2{R"(
    185 macros:
    186   foo: bar
    187 ---
    188 new: -$foo-
    189 )"};
    190       ctx.Load(ss2);
    191       CHECK(ctx["sub"]["macro"]()->ToString() == "<x y>");
    192       CHECK(ctx["new"]()->ToString() == "-bar-");
    193     }
    194     SUBCASE("add new macro")
    195     {
    196       std::stringstream ss2{R"(
    197 macros:
    198   abc: 'def ${#.:INT}'
    199 ---
    200 old: (${foo gg})
    201 new: '[$1:abc]'
    202 )"};
    203       ctx.Load(ss2);
    204       CHECK(ctx["old"]()->ToString() == "(<gg>)");
    205       CHECK(ctx["new"](1, 2)->ToString() == "[def 2]");
    206     }
    207 
    208     SUBCASE("add gender")
    209     {
    210       CHECK(ctx["genderp"]("foo")->ToString() == "neutral");
    211       CHECK(ctx["genderp"](ctx["foo"]())->ToString() == "b");
    212       CHECK(ctx["genderadv"]("foo")->ToString() == "x");
    213       CHECK(ctx["genderadv"](ctx["foo"]())->ToString() == "gb");
    214 
    215       std::stringstream ss2{R"(
    216 genders: [ga, sjw, nsjw]
    217 ---
    218 agender: !gender:ga aaa
    219 ngender: !gender:sjw xxx
    220 ngenderp: ${G neutral a sjw nsjw}
    221 ngenderadv: ${GADV x ga=ga gb=gb sjw=sjw}
    222 )"};
    223       ctx.Load(ss2);
    224       CHECK(ctx["genderp"]("foo")->ToString() == "neutral");
    225       CHECK(ctx["genderp"](ctx["foo"]())->ToString() == "b");
    226       CHECK(ctx["genderp"](ctx["agender"]())->ToString() == "a");
    227       CHECK(ctx["genderp"](ctx["ngender"]())->ToString() == "neutral");
    228       CHECK(ctx["genderadv"]("foo")->ToString() == "x");
    229       CHECK(ctx["genderadv"](ctx["foo"]())->ToString() == "gb");
    230       CHECK(ctx["genderadv"](ctx["agender"]())->ToString() == "x");
    231       CHECK(ctx["genderadv"](ctx["ngender"]())->ToString() == "x");
    232 
    233       CHECK(ctx["ngenderp"]("foo")->ToString() == "neutral");
    234       CHECK(ctx["ngenderp"](ctx["foo"]())->ToString() == "neutral");
    235       CHECK(ctx["ngenderp"](ctx["agender"]())->ToString() == "a");
    236       CHECK(ctx["ngenderp"](ctx["ngender"]())->ToString() == "sjw");
    237       CHECK(ctx["ngenderadv"]("foo")->ToString() == "x");
    238       CHECK(ctx["ngenderadv"](ctx["foo"]())->ToString() == "gb");
    239       CHECK(ctx["ngenderadv"](ctx["agender"]())->ToString() == "ga");
    240       CHECK(ctx["ngenderadv"](ctx["ngender"]())->ToString() == "sjw");
    241     }
    242 
    243     SUBCASE("add cases")
    244     {
    245       CHECK(ctx["asd"](ctx["case"]())->ToString() == "foo");
    246       CHECK(ctx["acase"](ctx["case"]())->ToString() == "a");
    247       CHECK(ctx["bcase"](ctx["case"]())->ToString() == "foo");
    248 
    249       std::stringstream ss2{R"(
    250 cases: [a, c]
    251 ---
    252 ncase: !cases
    253   default: def
    254   a: acase
    255   b: bcase
    256   c: ccase
    257 ccase: ${STRING.c}
    258 )"};
    259       ctx.Load(ss2);
    260       CHECK(ctx["asd"](ctx["case"]())->ToString() == "foo");
    261       CHECK(ctx["acase"](ctx["case"]())->ToString() == "a");
    262       CHECK(ctx["bcase"](ctx["case"]())->ToString() == "foo");
    263       CHECK(ctx["ccase"](ctx["case"]())->ToString() == "foo");
    264       CHECK(ctx["asd"](ctx["ncase"]())->ToString() == "def");
    265       CHECK(ctx["acase"](ctx["ncase"]())->ToString() == "acase");
    266       CHECK(ctx["bcase"](ctx["ncase"]())->ToString() == "bcase");
    267       CHECK(ctx["ccase"](ctx["ncase"]())->ToString() == "ccase");
    268     }
    269   }
    270 
    271   TEST_CASE("tags")
    272   {
    273     Context ctx;
    274     std::stringstream ss(R"(
    275 name: 日本語 # haha no
    276 en_name: English
    277 iso_code: en_US
    278 decimal_sep: '.'
    279 digit_sep: ','
    280 genders: [a, b]
    281 ---
    282 foo: !plain simple
    283 bar: !plain $INT $STRING $INT
    284 asd: !format $GENERIC
    285 def: !gender
    286   gender: a
    287   value: aly
    288 ghi: !gender:b bly
    289 gend: $0:STRING ing${0:G wtf? la lb}
    290 gadv: $0:STRING ${0:GADV x b=y}
    291 )");
    292     ctx.Load(ss);
    293 
    294     CHECK(ctx["foo"]()->ToString() == "simple");
    295     CHECK(ctx["bar"]()->ToString() == "$INT $STRING $INT");
    296     CHECK(ctx["asd"](3)->ToString() == "3");
    297 
    298     auto x = ctx["def"]()->Get({});
    299     CHECK(x.gender == 1);
    300     CHECK(x.str == "aly");
    301 
    302     auto y = ctx["ghi"]()->Get({});
    303     CHECK(y.gender == 2);
    304     CHECK(y.str == "bly");
    305 
    306     CHECK(ctx["gend"](ctx["def"]())->ToString() == "aly ingla");
    307     CHECK(ctx["gend"](ctx["ghi"]())->ToString() == "bly inglb");
    308     CHECK(ctx["gend"](ctx["foo"]())->ToString() == "simple ingwtf?");
    309     CHECK(ctx["gend"]("cstr")->ToString() == "cstr ingwtf?");
    310 
    311     CHECK(ctx["gadv"](ctx["def"]())->ToString() == "aly x");
    312     CHECK(ctx["gadv"](ctx["ghi"]())->ToString() == "bly y");
    313     CHECK(ctx["gadv"](ctx["foo"]())->ToString() == "simple x");
    314     CHECK(ctx["gadv"]("cstr")->ToString() == "cstr x");
    315   }
    316 
    317   TEST_SUITE_END();
    318 }