diff options
| author | Stefan Boberg <[email protected]> | 2025-11-07 14:49:13 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-11-07 14:49:13 +0100 |
| commit | 24e43a913f29ac3b314354e8ce5175f135bcc64f (patch) | |
| tree | ca442937ceeb63461012b33a4576e9835099f106 /thirdparty/ryml/test/test_basic.cpp | |
| parent | get oplog attachments (#622) (diff) | |
| download | zen-24e43a913f29ac3b314354e8ce5175f135bcc64f.tar.xz zen-24e43a913f29ac3b314354e8ce5175f135bcc64f.zip | |
switch to xmake for package management (#611)
This change removes our dependency on vcpkg for package management, in favour of bringing some code in-tree in the `thirdparty` folder as well as using the xmake build-in package management feature. For the latter, all the package definitions are maintained in the zen repo itself, in the `repo` folder.
It should now also be easier to build the project as it will no longer depend on having the right version of vcpkg installed, which has been a common problem for new people coming in to the codebase. Now you should only need xmake to build.
* Bumps xmake requirement on github runners to 2.9.9 to resolve an issue where xmake on Windows invokes cmake with `v144` toolchain which does not exist
* BLAKE3 is now in-tree at `thirdparty/blake3`
* cpr is now in-tree at `thirdparty/cpr`
* cxxopts is now in-tree at `thirdparty/cxxopts`
* fmt is now in-tree at `thirdparty/fmt`
* robin-map is now in-tree at `thirdparty/robin-map`
* ryml is now in-tree at `thirdparty/ryml`
* sol2 is now in-tree at `thirdparty/sol2`
* spdlog is now in-tree at `thirdparty/spdlog`
* utfcpp is now in-tree at `thirdparty/utfcpp`
* xmake package repo definitions is in `repo`
* implemented support for sanitizers. ASAN is supported on windows, TSAN, UBSAN, MSAN etc are supported on Linux/MacOS though I have not yet tested it extensively on MacOS
* the zencore encryption implementation also now supports using mbedTLS which is used on MacOS, though for now we still use openssl on Linux
* crashpad
* bumps libcurl to 8.11.0 (from 8.8.0) which should address a rare build upload bug
Diffstat (limited to 'thirdparty/ryml/test/test_basic.cpp')
| -rw-r--r-- | thirdparty/ryml/test/test_basic.cpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/thirdparty/ryml/test/test_basic.cpp b/thirdparty/ryml/test/test_basic.cpp new file mode 100644 index 000000000..7a10c073b --- /dev/null +++ b/thirdparty/ryml/test/test_basic.cpp @@ -0,0 +1,304 @@ +#ifndef RYML_SINGLE_HEADER +#include "c4/yml/std/std.hpp" +#include "c4/yml/parse.hpp" +#include "c4/yml/emit.hpp" +#include <c4/format.hpp> +#include <c4/yml/detail/checks.hpp> +#include <c4/yml/detail/print.hpp> +#endif + +#include "./test_case.hpp" + +#include <gtest/gtest.h> + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4389) // signed/unsigned mismatch +#elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +#endif + +namespace c4 { +namespace yml { + +TEST(general, parsing) +{ + auto tree = parse_in_arena("{foo: 1}"); + + char cmpbuf[128] = {0}; + substr cmp(cmpbuf); + size_t ret; + + ret = cat(cmp, tree["foo"].val()); + EXPECT_EQ(cmp.first(ret), "1"); + + ret = cat(cmp, tree["foo"].key()); + EXPECT_EQ(cmp.first(ret), "foo"); +} + +TEST(general, emitting) +{ + std::string cmpbuf; + + Tree tree; + auto r = tree.rootref(); + + r |= MAP; // this is needed to make the root a map + + r["foo"] = "1"; // ryml works only with strings. + // Note that the tree will be __pointing__ at the + // strings "foo" and "1" used here. You need + // to make sure they have at least the same + // lifetime as the tree. + + auto s = r["seq"]; // does not change the tree until s is written to. + s |= SEQ; + r["seq"].append_child() = "bar0"; // value of this child is now __pointing__ at "bar0" + r["seq"].append_child() = "bar1"; + r["seq"].append_child() = "bar2"; + + //print_tree(tree); + + // emit to stdout (can also emit to FILE* or ryml::span) + emitrs_yaml(tree, &cmpbuf); + const char* exp = R"(foo: 1 +seq: + - bar0 + - bar1 + - bar2 +)"; + EXPECT_EQ(cmpbuf, exp); + + // serializing: using operator<< instead of operator= + // will make the tree serialize the value into a char + // arena inside the tree. This arena can be reserved at will. + int ch3 = 33, ch4 = 44; + s.append_child() << ch3; + s.append_child() << ch4; + + { + std::string tmp = "child5"; + s.append_child() << tmp; // requires #include <c4/yml/std/string.hpp> + // now tmp can go safely out of scope, as it was + // serialized to the tree's internal string arena + // Note the include highlighted above is required so that ryml + // knows how to turn an std::string into a c4::csubstr/c4::substr. + } + + emitrs_yaml(tree, &cmpbuf); + exp = R"(foo: 1 +seq: + - bar0 + - bar1 + - bar2 + - 33 + - 44 + - child5 +)"; + EXPECT_EQ(cmpbuf, exp); + + // to serialize keys: + int k=66; + r.append_child() << key(k) << 7; + + emitrs_yaml(tree, &cmpbuf); + exp = R"(foo: 1 +seq: + - bar0 + - bar1 + - bar2 + - 33 + - 44 + - child5 +66: 7 +)"; + EXPECT_EQ(cmpbuf, exp); +} + +TEST(general, map_to_root) +{ + std::string cmpbuf; const char *exp; + std::map<std::string, int> m({{"bar", 2}, {"foo", 1}}); + Tree t; + t.rootref() << m; + + emitrs_yaml(t, &cmpbuf); + exp = R"(bar: 2 +foo: 1 +)"; + EXPECT_EQ(cmpbuf, exp); + + t["foo"] << 10; + t["bar"] << 20; + + m.clear(); + t.rootref() >> m; + + EXPECT_EQ(m["foo"], 10); + EXPECT_EQ(m["bar"], 20); +} + +TEST(general, print_tree) +{ + const char yaml[] = R"( +a: + b: bval + c: + d: + - e + - d + - f: fval + g: gval + h: + - + x: a + y: b + - + z: c + u: +)"; + Tree t = parse_in_arena(yaml); + print_tree(t); // to make sure this is covered too +} + +TEST(general, numbers) +{ + const char yaml[] = R"(- -1 +- -1.0 +- +1.0 +- 1e-2 +- 1e+2 +)"; + Tree t = parse_in_arena(yaml); + auto s = emitrs_yaml<std::string>(t); + EXPECT_EQ(s, std::string(yaml)); +} + +// github issue 29: https://github.com/biojppm/rapidyaml/issues/29 +TEST(general, newlines_on_maps_nested_in_seqs) +{ + const char yaml[] = R"(enemy: +- actors: + - {name: Enemy_Bokoblin_Junior, value: 4.0} + - {name: Enemy_Bokoblin_Middle, value: 16.0} + - {name: Enemy_Bokoblin_Senior, value: 32.0} + - {name: Enemy_Bokoblin_Dark, value: 48.0} + species: BokoblinSeries +)"; + std::string expected = R"(enemy: + - actors: + - name: Enemy_Bokoblin_Junior + value: 4.0 + - name: Enemy_Bokoblin_Middle + value: 16.0 + - name: Enemy_Bokoblin_Senior + value: 32.0 + - name: Enemy_Bokoblin_Dark + value: 48.0 + species: BokoblinSeries +)"; + Tree t = parse_in_arena(yaml); + auto s = emitrs_yaml<std::string>(t); + EXPECT_EQ(expected, s); +} + + +TEST(general, test_suite_RZT7) +{ + csubstr yaml = R"( +--- +Time: 2001-11-23 15:01:42 -5 +User: ed +Warning: + This is an error message + for the log file +--- +Time: 2001-11-23 15:02:31 -5 +User: ed +Warning: + A slightly different error + message. +--- +Date: 2001-11-23 15:03:17 -5 +User: ed +Fatal: + Unknown variable "bar" +Stack: + - file: TopClass.py + line: 23 + code: | + x = MoreObject("345\n") + - file: MoreClass.py + line: 58 + code: |- + foo = bar +)"; + test_check_emit_check(yaml, [](Tree const &t){ + ASSERT_TRUE(t.rootref().is_stream()); + ConstNodeRef doc0 = t.rootref()[0]; + EXPECT_EQ(doc0["Time"].val(), csubstr("2001-11-23 15:01:42 -5")); + EXPECT_EQ(doc0["User"].val(), csubstr("ed")); + EXPECT_EQ(doc0["Warning"].val(), csubstr("This is an error message for the log file")); + ConstNodeRef doc1 = t.rootref()[1]; + EXPECT_EQ(doc1["Time"].val(), csubstr("2001-11-23 15:02:31 -5")); + EXPECT_EQ(doc1["User"].val(), csubstr("ed")); + EXPECT_EQ(doc1["Warning"].val(), csubstr("A slightly different error message.")); + ConstNodeRef doc2 = t.rootref()[2]; + EXPECT_EQ(doc2["Date"].val(), csubstr("2001-11-23 15:03:17 -5")); + EXPECT_EQ(doc2["User"].val(), csubstr("ed")); + EXPECT_EQ(doc2["Fatal"].val(), csubstr("Unknown variable \"bar\"")); + EXPECT_EQ(doc2["Stack"][0]["file"].val(), csubstr("TopClass.py")); + EXPECT_EQ(doc2["Stack"][0]["line"].val(), csubstr("23")); + EXPECT_EQ(doc2["Stack"][0]["code"].val(), csubstr("x = MoreObject(\"345\\n\")\n")); + EXPECT_EQ(doc2["Stack"][1]["file"].val(), csubstr("MoreClass.py")); + EXPECT_EQ(doc2["Stack"][1]["line"].val(), csubstr("58")); + EXPECT_EQ(doc2["Stack"][1]["code"].val(), csubstr("foo = bar")); + }); +} + + +TEST(general, github_issue_124) +{ + // All these inputs are basically the same. + // However, the comment was found to confuse the parser in #124. + csubstr yaml[] = { + "a:\n - b\nc: d", + "a:\n - b\n\n# ignore me:\nc: d", + "a:\n - b\n\n # ignore me:\nc: d", + "a:\n - b\n\n # ignore me:\nc: d", + "a:\n - b\n\n#:\nc: d", // also try with just a ':' in the comment + "a:\n - b\n\n# :\nc: d", + "a:\n - b\n\n#\nc: d", // also try with empty comment + }; + for(csubstr inp : yaml) + { + SCOPED_TRACE(inp); + Tree t = parse_in_arena(inp); + std::string s = emitrs_yaml<std::string>(t); + // The re-emitted output should not contain the comment. + EXPECT_EQ(c4::to_csubstr(s), "a:\n - b\nc: d\n"); + } +} + + + +//------------------------------------------- +// this is needed to use the test case library +Case const* get_case(csubstr /*name*/) +{ + return nullptr; +} + +} // namespace yml +} // namespace c4 + +#if defined(_MSC_VER) +# pragma warning(pop) +#elif defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif |