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 }