aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/ryml/test/test_basic.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-11-07 14:49:13 +0100
committerGitHub Enterprise <[email protected]>2025-11-07 14:49:13 +0100
commit24e43a913f29ac3b314354e8ce5175f135bcc64f (patch)
treeca442937ceeb63461012b33a4576e9835099f106 /thirdparty/ryml/test/test_basic.cpp
parentget oplog attachments (#622) (diff)
downloadzen-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.cpp304
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