Files
rapidyaml/test/test_merge.cpp

325 lines
6.2 KiB
C++

#ifndef RYML_SINGLE_HEADER
#include <c4/yml/std/std.hpp>
#include <c4/yml/yml.hpp>
#endif
#include <gtest/gtest.h>
#include "./test_lib/test_case.hpp"
namespace c4 {
namespace yml {
// The other test executables are written to contain the declarative-style
// YmlTestCases. This executable does not have any but the build setup
// assumes it does, and links with the test lib, which requires an existing
// get_case() function. So this is here to act as placeholder until (if?)
// proper test cases are added here. This was detected in #47 (thanks
// @cburgard).
Case const* get_case(csubstr)
{
return nullptr;
}
void test_merge(std::initializer_list<csubstr> li, csubstr expected)
{
Tree loaded, merged, ref;
parse_in_arena(expected, &ref);
// make sure the arena in the loaded tree is never resized
size_t arena_dim = 2;
for(csubstr src : li)
{
arena_dim += src.len;
}
loaded.reserve_arena(arena_dim);
for(csubstr src : li)
{
loaded.clear(); // do not clear the arena of the loaded tree
parse_in_arena(src, &loaded);
_c4dbg_tree("loaded", loaded);
merged.merge_with(&loaded);
_c4dbg_tree("merged", merged);
}
_c4dbg_tree("ref", ref);
test_compare(merged, ref);
std::string buf_result = emitrs_yaml<std::string>(merged);
std::string buf_expected = emitrs_yaml<std::string>(ref);
EXPECT_EQ(buf_result, buf_expected);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
TEST(merge, basic)
{
test_merge(
{
"{a: 0, b: 1}",
"{a: 1, c: 20}"
},
"{a: 1, b: 1, c: 20}"
);
}
TEST(merge, basic_inv)
{
test_merge(
{
"{a: 1, c: 20}",
"{a: 0, b: 1}"
},
"{a: 0, c: 20, b: 1}"
);
}
TEST(merge, dst_scalar_keeps_style)
{
Tree dst = parse_in_arena("a: b");
const Tree src = parse_in_arena("'a': 'c'");
EXPECT_EQ(dst["a"], "b");
EXPECT_EQ(src["a"], "c");
EXPECT_TRUE(dst["a"].type().is_key_plain());
EXPECT_TRUE(dst["a"].type().is_val_plain());
EXPECT_TRUE(src["a"].type().is_key_squo());
EXPECT_TRUE(src["a"].type().is_val_squo());
_c4dbg_tree("src", src);
_c4dbg_tree("dst", dst);
dst.merge_with(&src);
_c4dbg_tree("merged", dst);
EXPECT_EQ(dst["a"], "c");
EXPECT_EQ(src["a"], "c");
EXPECT_TRUE(dst["a"].type().is_key_plain());
EXPECT_TRUE(dst["a"].type().is_val_plain());
}
TEST(merge, src_scalar_assigns_style_0)
{
test_merge(
{
"{}",
"{a: 'b'}",
},
"{a: 'b'}"
);
}
TEST(merge, src_scalar_assigns_style_1)
{
test_merge(
{
"{}",
"{a: 'b'}",
"{a: \"c\"}",
},
"{a: 'c'}"
);
}
TEST(merge, src_scalar_assigns_style_2)
{
test_merge(
{
"{}",
"{a: 'b'}",
"{a: \"c\"}",
"{a: d}",
},
"{a: 'd'}"
);
}
TEST(merge, src_map_assigns_style_0)
{
test_merge(
{
"{}",
"a: 'b'",
"{aa: \"bb\"}",
},
"{a: 'b', aa: \"bb\"}"
);
}
TEST(merge, src_map_assigns_style_1)
{
test_merge(
{
"foo: bar",
"{a: 'b'}",
"{foo: \"bar\"}",
},
"foo: bar\na: 'b'\n"
);
}
TEST(merge, src_seq_assigns_style_0)
{
test_merge(
{
"[]",
"- 0\n- 1\n",
"- 2\n- 3\n",
},
"[0,1,2,3]"
);
}
TEST(merge, src_seq_assigns_style_1)
{
test_merge(
{
"- 0\n- 1\n",
"[a,b]",
"[c,d]",
},
"- 0\n- 1\n- a\n- b\n- c\n- d\n"
);
}
TEST(merge, val_to_seq)
{
test_merge(
{
"{a: 0, b: 1}",
"{a: [1, 2]}"
},
"{a: [1, 2], b: 1}"
);
}
TEST(merge, seq_to_val)
{
test_merge(
{
"{a: [1, 2]}",
"{a: 0, b: 1}",
},
"{a: 0, b: 1}"
);
}
TEST(merge, val_to_map)
{
test_merge(
{
"{a: 0, b: 1}",
"{a: {c: 10, d: 20}}"
},
"{a: {c: 10, d: 20}, b: 1}"
);
}
TEST(merge, map_to_val)
{
test_merge(
{
"{a: {c: 10, d: 20}}",
"{a: 0, b: 1}",
},
"{a: 0, b: 1}"
);
}
TEST(merge, seq_no_overlap)
{
test_merge(
{"[0, 1, 2]", "[3, 4, 5]", "[6, 7, 8]"},
"[0, 1, 2, 3, 4, 5, 6, 7, 8]"
);
}
TEST(merge, seq_overlap)
{
test_merge(
{"[0, 1, 2]", "[1, 2, 3]", "[2, 3, 4]"},
"[0, 1, 2, 1, 2, 3, 2, 3, 4]"
// or this? "[0, 1, 2, 3, 4]"
);
}
TEST(merge, map_orthogonal)
{
test_merge(
{
"{a: 0}",
"{b: 1}",
"{c: 2}"
},
"{a: 0, b: 1, c: 2}"
);
}
TEST(merge, map_overriding)
{
test_merge(
{
"{a: 0}",
"{a: 1, b: 1}",
"{c: 2}"
},
"{a: 1, b: 1, c: 2}"
);
}
TEST(merge, map_overriding_multiple)
{
test_merge(
{
"{a: 0}",
"{a: 1, b: 1}",
"{c: 2}",
"{a: 2}",
"{a: 3}",
"{c: 4}",
"{c: 5}",
"{a: 4}",
},
"{a: 4, b: 1, c: 5}"
);
}
TEST(merge, seq_nested_in_map)
{
test_merge(
{
"{a: 0, seq: [a, b, c], d: 2}",
"{a: 1, seq: [d, e, f], d: 3, c: 3}"
},
"{a: 1, seq: [a, b, c, d, e, f], d: 3, c: 3}"
);
}
TEST(merge, seq_nested_in_map_override_with_map)
{
test_merge(
{
"{a: 0, ovr: [a, b, c], d: 2}",
"{a: 1, ovr: {d: 0, b: 1, c: 2}, d: 3, c: 3}"
},
"{a: 1, ovr: {d: 0, b: 1, c: 2}, d: 3, c: 3}"
);
}
TEST(merge, seq_nested_in_map_override_with_keyval)
{
test_merge(
{
"{a: 0, ovr: [a, b, c], d: 2}",
"{a: 1, ovr: foo, d: 3, c: 3}"
},
"{a: 1, ovr: foo, d: 3, c: 3}"
);
}
} // namespace yml
} // namespace c4