mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
743 lines
23 KiB
C++
743 lines
23 KiB
C++
#ifndef RYML_SINGLE_HEADER
|
|
#include <c4/yml/std/std.hpp>
|
|
#include <c4/yml/yml.hpp>
|
|
#endif
|
|
#include "./test_lib/test_case.hpp"
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
namespace c4 {
|
|
namespace yml {
|
|
|
|
TEST(locations, default_is_no_location)
|
|
{
|
|
{
|
|
ParserOptions opts;
|
|
EXPECT_EQ(opts.locations(), false);
|
|
}
|
|
{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler);
|
|
EXPECT_EQ(parser.options().locations(), false);
|
|
}
|
|
{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, ParserOptions{});
|
|
EXPECT_EQ(parser.options().locations(), false);
|
|
}
|
|
{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, ParserOptions().locations(false));
|
|
EXPECT_EQ(parser.options().locations(), false);
|
|
}
|
|
{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, ParserOptions().locations(true));
|
|
EXPECT_EQ(parser.options().locations(), true);
|
|
}
|
|
}
|
|
|
|
|
|
TEST(locations, error_is_triggered_querying_with_locations_disabled)
|
|
{
|
|
bool parsed_ok = false;
|
|
ExpectError::check_error_basic([&]{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, ParserOptions().locations(false));
|
|
Tree t = parse_in_arena(&parser, "test", "foo: bar");
|
|
parsed_ok = true;
|
|
t["foo"].location(parser);
|
|
});
|
|
EXPECT_TRUE(parsed_ok);
|
|
}
|
|
|
|
|
|
|
|
#define _checkloc(node, line_, col_, str) \
|
|
{ \
|
|
const Location loc = node.location(parser); \
|
|
EXPECT_EQ(loc.name, "myfile.yml"); \
|
|
EXPECT_EQ(loc.line, line_); \
|
|
EXPECT_EQ(loc.col, col_); \
|
|
EXPECT_EQ(t.arena().sub(loc.offset, csubstr(str).len), csubstr(str)); \
|
|
}
|
|
|
|
TEST(locations, no_error_is_triggered_querying_with_locations)
|
|
{
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, ParserOptions().locations(true));
|
|
EXPECT_EQ(parser.options().locations(), true);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", "foo: bar");
|
|
_checkloc(t["foo"], 0, 0, "foo");
|
|
}
|
|
|
|
|
|
TEST(locations, docval)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", "docval");
|
|
_checkloc(t.rootref(), 0u, 0u, "docval");
|
|
t = parse_in_arena(&parser, "myfile.yml", "\n docval");
|
|
_checkloc(t.rootref(), 1u, 1u, "docval");
|
|
t = parse_in_arena(&parser, "myfile.yml", "\n\n docval");
|
|
_checkloc(t.rootref(), 2u, 1u, "docval");
|
|
}
|
|
|
|
TEST(locations, docval_null)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", "~");
|
|
_checkloc(t.rootref(), 0u, 0u, "~");
|
|
t = parse_in_arena(&parser, "myfile.yml", "");
|
|
_checkloc(t.rootref(), 0u, 0u, "");
|
|
t = parse_in_arena(&parser, "myfile.yml", R"(#
|
|
#
|
|
#
|
|
#
|
|
#
|
|
)");
|
|
_checkloc(t.rootref(), 0u, 0u, "");
|
|
}
|
|
|
|
TEST(locations, seq_block)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"(
|
|
- this
|
|
- is
|
|
- a
|
|
- seq
|
|
- - and
|
|
- this
|
|
- - as
|
|
- well
|
|
- - # this one works as well
|
|
# even with a comment in between
|
|
the scalar value is here
|
|
- and here's another value
|
|
-
|
|
- another val
|
|
- yet another val
|
|
)";
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", yaml);
|
|
ConstNodeRef seq = t.rootref();
|
|
ASSERT_TRUE(seq.is_seq());
|
|
_checkloc(seq , 1u, 0u, "- ");
|
|
_checkloc(seq[0] , 1u, 2u, "this");
|
|
_checkloc(seq[1] , 2u, 2u, "is");
|
|
_checkloc(seq[2] , 3u, 2u, "a");
|
|
_checkloc(seq[3] , 4u, 2u, "seq");
|
|
_checkloc(seq[4] , 5u, 2u, "- ");
|
|
_checkloc(seq[4][0] , 5u, 4u, "and");
|
|
_checkloc(seq[4][1] , 6u, 4u, "this");
|
|
_checkloc(seq[4][2] , 7u, 4u, "- ");
|
|
_checkloc(seq[4][2][0], 7u, 6u, "as");
|
|
_checkloc(seq[4][2][1], 8u, 6u, "well");
|
|
_checkloc(seq[4][3] , 9u, 4u, "- # this one works as well");
|
|
_checkloc(seq[4][3][0], 11u, 6u, "the scalar value is here");
|
|
_checkloc(seq[4][3][1], 12u, 8u, "and here's another value");
|
|
_checkloc(seq[4][3][2], 14u, 6u, "- ");
|
|
_checkloc(seq[4][3][2][0], 14u, 8u, "another val");
|
|
_checkloc(seq[4][3][2][1], 15u, 8u, "yet another val");
|
|
}
|
|
|
|
TEST(locations, map_block)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"(
|
|
this: ~
|
|
is: ~
|
|
a: ~
|
|
map: ~
|
|
and:
|
|
this:
|
|
as: ~
|
|
well: ~
|
|
aswell: # this one works as well
|
|
# even with a comment in between
|
|
val: here
|
|
hah: here
|
|
)";
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", yaml);
|
|
ConstNodeRef map = t.rootref();
|
|
ASSERT_TRUE(map.is_map());
|
|
_checkloc(map , 1u, 0u, "this:");
|
|
_checkloc(map["this"] , 1u, 0u, "this:");
|
|
_checkloc(map["is"] , 2u, 0u, "is:");
|
|
_checkloc(map["a"] , 3u, 0u, "a:");
|
|
_checkloc(map["map"] , 4u, 0u, "map:");
|
|
_checkloc(map["and"] , 5u, 0u, "and:");
|
|
_checkloc(map["and"]["this"] , 6u, 2u, "this:");
|
|
_checkloc(map["and"]["this"]["as"] , 7u, 4u, "as:");
|
|
_checkloc(map["and"]["this"]["well"] , 8u, 4u, "well:");
|
|
_checkloc(map["and"]["aswell"] , 9u, 2u, "aswell:");
|
|
_checkloc(map["and"]["aswell"]["val"] , 11u, 4u, "val:");
|
|
_checkloc(map["and"]["aswell"]["hah"] , 12u, 4u, "hah:");
|
|
}
|
|
|
|
TEST(locations, seq_block_null)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
const Tree t = parse_in_arena(&parser, "myfile.yml", R"(---
|
|
- ~
|
|
- ~
|
|
- notnull
|
|
- ~
|
|
- ~
|
|
---
|
|
- ~
|
|
- - ~
|
|
- - - ~
|
|
- - - - ~
|
|
- - - - - ~
|
|
- - - - ~
|
|
- - - ~
|
|
- - ~
|
|
- ~
|
|
---
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
-
|
|
)");
|
|
_checkloc(t.rootref() , 0u, 0u, "---");
|
|
_checkloc(t.docref(0) , 1u, 0u, "- ");
|
|
_checkloc(t.docref(0)[0], 1u, 2u, "~");
|
|
_checkloc(t.docref(0)[1], 2u, 2u, "~");
|
|
_checkloc(t.docref(0)[2], 3u, 2u, "notnull");
|
|
_checkloc(t.docref(0)[3], 4u, 2u, "~");
|
|
_checkloc(t.docref(0)[4], 5u, 2u, "~");
|
|
_checkloc(t.docref(1) , 7u, 0u, "- ");
|
|
_checkloc(t.docref(1)[0], 7u, 2u, "~");
|
|
_checkloc(t.docref(1)[1], 8u, 2u, "- ");
|
|
_checkloc(t.docref(1)[1][0], 8u, 4u, "~");
|
|
_checkloc(t.docref(1)[2], 9u, 2u, "- ");
|
|
_checkloc(t.docref(1)[2][0], 9u, 4u, "- ");
|
|
_checkloc(t.docref(1)[2][0][0], 9u, 6u, "~");
|
|
_checkloc(t.docref(1)[3], 10u, 2u, "- ");
|
|
_checkloc(t.docref(1)[3][0], 10u, 4u, "- ");
|
|
_checkloc(t.docref(1)[3][0][0], 10u, 6u, "- ");
|
|
_checkloc(t.docref(1)[3][0][0][0], 10u, 8u, "~");
|
|
_checkloc(t.docref(1)[4], 11u, 2u, "- ");
|
|
_checkloc(t.docref(1)[4][0], 11u, 4u, "- ");
|
|
_checkloc(t.docref(1)[4][0][0], 11u, 6u, "- ");
|
|
_checkloc(t.docref(1)[4][0][0][0], 11u, 8u, "- ");
|
|
_checkloc(t.docref(1)[4][0][0][0][0], 11u, 10u, "~");
|
|
_checkloc(t.docref(1)[5], 12u, 2u, "- ");
|
|
_checkloc(t.docref(1)[5][0], 12u, 4u, "- ");
|
|
_checkloc(t.docref(1)[5][0][0], 12u, 6u, "- ");
|
|
_checkloc(t.docref(1)[5][0][0][0], 12u, 8u, "~");
|
|
_checkloc(t.docref(1)[6], 13u, 2u, "- ");
|
|
_checkloc(t.docref(1)[6][0], 13u, 4u, "- ");
|
|
_checkloc(t.docref(1)[6][0][0], 13u, 6u, "~");
|
|
_checkloc(t.docref(1)[7], 14u, 2u, "- ");
|
|
_checkloc(t.docref(1)[7][0], 14u, 4u, "~");
|
|
_checkloc(t.docref(1)[8], 15u, 2u, "~");
|
|
_checkloc(t.docref(2) , 17u, 0u, "-");
|
|
_checkloc(t.docref(2)[0], 17u, 0u, "-");
|
|
_checkloc(t.docref(2)[1], 17u, 0u, "-");
|
|
_checkloc(t.docref(2)[2], 21u, 2u, "-");
|
|
_checkloc(t.docref(2)[3], 21u, 2u, "-");
|
|
_checkloc(t.docref(2)[3][0], 21u, 2u, "-");
|
|
_checkloc(t.docref(2)[3][1], 24u, 4u, "-");
|
|
_checkloc(t.docref(2)[3][2], 24u, 4u, "-");
|
|
_checkloc(t.docref(2)[3][2][0], 25u, 6u, "-");
|
|
_checkloc(t.docref(2)[3][2][0][0], 26u, 8u, "-");
|
|
_checkloc(t.docref(2)[3][2][0][0][0], 26u, 8u, "-");
|
|
_checkloc(t.docref(2)[3][2][0][0][1], 26u, 8u, "-");
|
|
_checkloc(t.docref(2)[3][2][1], 25u, 6u, "-");
|
|
_checkloc(t.docref(2)[3][3], 24u, 4u, "-"); // fix: this should be after the previous child
|
|
_checkloc(t.docref(2)[3][4], 21u, 2u, "-"); // fix: this should be after the previous child
|
|
_checkloc(t.docref(2)[3][5], 21u, 2u, "-"); // fix: this should be after the previous child
|
|
}
|
|
|
|
TEST(locations, map_block_null)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", R"(---
|
|
~: v
|
|
---
|
|
null: v
|
|
---
|
|
: v
|
|
)");
|
|
_checkloc(t.rootref() , 0u, 0u, "---");
|
|
_checkloc(t.docref(0) , 1u, 0u, "");
|
|
_checkloc(t.docref(0)[0], 1u, 0u, "~");
|
|
_checkloc(t.docref(1) , 3u, 0u, "null");
|
|
_checkloc(t.docref(1)[0], 3u, 0u, "null");
|
|
_checkloc(t.docref(2) , 5u, 1u, "");
|
|
_checkloc(t.docref(2)[0], 5u, 3u, "");
|
|
}
|
|
|
|
TEST(locations, empty_seq)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", R"(---
|
|
- []
|
|
- []
|
|
- notnull
|
|
- []
|
|
- []
|
|
---
|
|
- []
|
|
---
|
|
[]
|
|
---
|
|
key0: []
|
|
key1: []
|
|
key2: notnull
|
|
key3: []
|
|
key4: []
|
|
---
|
|
key: []
|
|
)");
|
|
_checkloc(t.rootref() , 0u, 0u, "---");
|
|
_checkloc(t.docref(0) , 1u, 0u, "- ");
|
|
_checkloc(t.docref(0)[0], 1u, 2u, "[]");
|
|
_checkloc(t.docref(0)[1], 2u, 2u, "[]");
|
|
_checkloc(t.docref(0)[2], 3u, 2u, "notnull");
|
|
_checkloc(t.docref(0)[3], 4u, 2u, "[]");
|
|
_checkloc(t.docref(0)[4], 5u, 2u, "[]");
|
|
_checkloc(t.docref(1) , 7u, 0u, "- ");
|
|
_checkloc(t.docref(1)[0], 7u, 2u, "[]");
|
|
_checkloc(t.docref(2) , 9u, 0u, "[]");
|
|
_checkloc(t.docref(3) , 11u, 0u, "key0"); // WTF
|
|
_checkloc(t.docref(3)["key0"], 11u, 0u, "key0");
|
|
_checkloc(t.docref(3)["key1"], 12u, 0u, "key1");
|
|
_checkloc(t.docref(3)["key2"], 13u, 0u, "key2");
|
|
_checkloc(t.docref(3)["key3"], 14u, 0u, "key3");
|
|
_checkloc(t.docref(3)["key4"], 15u, 0u, "key4");
|
|
}
|
|
|
|
TEST(locations, empty_map)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", R"(---
|
|
- {}
|
|
- {}
|
|
- notnull
|
|
- {}
|
|
- {}
|
|
---
|
|
- {}
|
|
---
|
|
{}
|
|
---
|
|
key0: {}
|
|
key1: {}
|
|
key2: notnull
|
|
key3: {}
|
|
key4: {}
|
|
---
|
|
key: {}
|
|
)");
|
|
_checkloc(t.rootref() , 0u, 0u, "---");
|
|
_checkloc(t.docref(0) , 1u, 0u, "- ");
|
|
_checkloc(t.docref(0)[0], 1u, 2u, "{}");
|
|
_checkloc(t.docref(0)[1], 2u, 2u, "{}");
|
|
_checkloc(t.docref(0)[2], 3u, 2u, "notnull");
|
|
_checkloc(t.docref(0)[3], 4u, 2u, "{}");
|
|
_checkloc(t.docref(0)[4], 5u, 2u, "{}");
|
|
_checkloc(t.docref(1) , 7u, 0u, "- ");
|
|
_checkloc(t.docref(1)[0], 7u, 2u, "{}");
|
|
_checkloc(t.docref(2) , 9u, 0u, "{}");
|
|
_checkloc(t.docref(3) , 11u, 0u, "key0"); // WTF
|
|
_checkloc(t.docref(3)["key0"], 11u, 0u, "key0");
|
|
_checkloc(t.docref(3)["key1"], 12u, 0u, "key1");
|
|
_checkloc(t.docref(3)["key2"], 13u, 0u, "key2");
|
|
_checkloc(t.docref(3)["key3"], 14u, 0u, "key3");
|
|
_checkloc(t.docref(3)["key4"], 15u, 0u, "key4");
|
|
}
|
|
|
|
|
|
TEST(locations, seq_flow)
|
|
{
|
|
Tree t;
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"([one,two,three,four,items])";
|
|
parse_in_arena(&parser, "myfile.yml", yaml, &t);
|
|
ConstNodeRef seq = t.rootref();
|
|
ASSERT_TRUE(seq.is_seq());
|
|
_checkloc(seq , 0u, 0u, "[");
|
|
_checkloc(seq[0], 0u, 1u, "one");
|
|
_checkloc(seq[1], 0u, 5u, "two");
|
|
_checkloc(seq[2], 0u, 9u, "three");
|
|
_checkloc(seq[3], 0u, 15u, "four");
|
|
_checkloc(seq[4], 0u, 20u, "items");
|
|
}
|
|
|
|
TEST(locations, map_flow)
|
|
{
|
|
Tree t;
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"({one: item,two: items,three: items,four: items})";
|
|
parse_in_arena(&parser, "myfile.yml", yaml, &t);
|
|
ConstNodeRef map = t.rootref();
|
|
ASSERT_TRUE(map.is_map());
|
|
_checkloc(map , 0u, 0u, "{");
|
|
_checkloc(map[0], 0u, 1u, "one:");
|
|
_checkloc(map[1], 0u, 11u, "two:");
|
|
_checkloc(map[2], 0u, 22u, "three:");
|
|
_checkloc(map[3], 0u, 35u, "four:");
|
|
}
|
|
|
|
TEST(locations, seq_flow_nested)
|
|
{
|
|
Tree t;
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"([
|
|
one,
|
|
two,
|
|
[woops, there, [ goes, master]],
|
|
five,
|
|
{wait: is, this: { really: a map? }, nope: [ a seq!, { had: you there, eehh: no. } ]},
|
|
yep,
|
|
it,
|
|
was
|
|
])";
|
|
parse_in_arena(&parser, "myfile.yml", yaml, &t);
|
|
ConstNodeRef seq = t.rootref();
|
|
ASSERT_TRUE(seq.is_seq());
|
|
_checkloc(seq , 0u, 0u, "[");
|
|
_checkloc(seq[0] , 1u, 2u, "one");
|
|
_checkloc(seq[1] , 2u, 2u, "two");
|
|
_checkloc(seq[2] , 3u, 2u, "[");
|
|
_checkloc(seq[2][0] , 3u, 3u, "woops");
|
|
_checkloc(seq[2][1] , 3u, 14u, "there");
|
|
_checkloc(seq[2][2] , 3u, 24u, "[");
|
|
_checkloc(seq[2][2][0] , 3u, 27u, "goes");
|
|
_checkloc(seq[2][2][1] , 3u, 37u, "master");
|
|
_checkloc(seq[3] , 4u, 2u, "five");
|
|
_checkloc(seq[4] , 5u, 2u, "{");
|
|
_checkloc(seq[4]["wait"] , 5u, 3u, "wait");
|
|
_checkloc(seq[4]["this"] , 5u, 15u, "this");
|
|
_checkloc(seq[4]["this"]["really"] , 5u, 27u, "really");
|
|
_checkloc(seq[4]["nope"] , 5u, 47u, "nope");
|
|
_checkloc(seq[4]["nope"][0] , 5u, 56u, "a seq!");
|
|
_checkloc(seq[4]["nope"][1] , 5u, 64u, "{");
|
|
_checkloc(seq[4]["nope"][1]["had"] , 5u, 66u, "had");
|
|
_checkloc(seq[4]["nope"][1]["eehh"], 5u, 83u, "eehh");
|
|
_checkloc(seq[5] , 6u, 2u, "yep");
|
|
_checkloc(seq[6] , 7u, 2u, "it");
|
|
_checkloc(seq[7] , 8u, 2u, "was");
|
|
}
|
|
|
|
TEST(locations, grow_array)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree t = parse_in_arena(&parser, "myfile.yml", "docval");
|
|
_checkloc(t.rootref(), 0u, 0u, "docval");
|
|
t = parse_in_arena(&parser, "myfile.yml", "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ndocval");
|
|
_checkloc(t.rootref(), 47u, 0u, "docval");
|
|
}
|
|
|
|
// do a test with a buffer size up to 30 lines to ensure hitting
|
|
// the binary search path
|
|
TEST(locations, small_array)
|
|
{
|
|
Tree t;
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"(---
|
|
foo: yes
|
|
bar:
|
|
- 1
|
|
- 2
|
|
baz:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
)";
|
|
parse_in_arena(&parser, "myfile.yml", yaml, &t);
|
|
ConstNodeRef stream = t.rootref();
|
|
ConstNodeRef map = t.docref(0);
|
|
ASSERT_TRUE(map.is_map());
|
|
ASSERT_TRUE(map.is_doc());
|
|
_checkloc(stream , 0u, 0u, "---");
|
|
_checkloc(map , 1u, 0u, "foo");
|
|
_checkloc(map["foo"] , 1u, 0u, "foo");
|
|
_checkloc(map["bar"] , 2u, 0u, "bar");
|
|
_checkloc(map["bar"][0], 3u, 4u, "1");
|
|
_checkloc(map["bar"][1], 4u, 4u, "2");
|
|
_checkloc(map["baz"] , 5u, 0u, "baz");
|
|
_checkloc(map["baz"][0], 6u, 6u, "1_");
|
|
_checkloc(map["baz"][1], 7u, 6u, "2_");
|
|
_checkloc(map["baz"][2], 8u, 10u, "3_");
|
|
}
|
|
|
|
// do a test with a buffer of at least 30 lines to ensure hitting
|
|
// the binary search path
|
|
TEST(locations, large_array)
|
|
{
|
|
Tree t;
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
csubstr yaml = R"(---
|
|
foo1: definitely # 1
|
|
bar1:
|
|
- 1
|
|
- 2
|
|
baz1:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
|
|
|
|
|
|
foo2: definitely # 12
|
|
bar2:
|
|
- 1
|
|
- 2
|
|
baz2:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
|
|
|
|
|
|
foo3: definitely # 23
|
|
bar3:
|
|
- 1
|
|
- 2
|
|
baz3:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
|
|
|
|
|
|
foo4: definitely # 34
|
|
bar4:
|
|
- 1
|
|
- 2
|
|
baz4:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
|
|
|
|
|
|
foo5: definitely # 45
|
|
bar5:
|
|
- 1
|
|
- 2
|
|
baz5:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
|
|
|
|
|
|
foo6: definitely # 56
|
|
bar6:
|
|
- 1
|
|
- 2
|
|
baz6:
|
|
- 1_
|
|
- 2_
|
|
- 3_
|
|
)";
|
|
parse_in_arena(&parser, "myfile.yml", yaml, &t);
|
|
ConstNodeRef map = t.docref(0);
|
|
ASSERT_TRUE(map.is_map());
|
|
ASSERT_TRUE(map.is_doc());
|
|
_checkloc(t.rootref() , 0u, 0u, "---");
|
|
_checkloc(map , 1u, 0u, "foo1");
|
|
_checkloc(map["foo1"] , 0u+1u, 0u, "foo1");
|
|
_checkloc(map["bar1"] , 0u+2u, 0u, "bar1");
|
|
_checkloc(map["bar1"][0], 0u+3u, 4u, "1");
|
|
_checkloc(map["bar1"][1], 0u+4u, 4u, "2");
|
|
_checkloc(map["baz1"] , 0u+5u, 0u, "baz");
|
|
_checkloc(map["baz1"][0], 0u+6u, 6u, "1_");
|
|
_checkloc(map["baz1"][1], 0u+7u, 6u, "2_");
|
|
_checkloc(map["baz1"][2], 0u+8u, 10u, "3_");
|
|
//
|
|
_checkloc(map["foo2"] , 11u+1u, 0u, "foo2");
|
|
_checkloc(map["bar2"] , 11u+2u, 0u, "bar2");
|
|
_checkloc(map["bar2"][0], 11u+3u, 4u, "1");
|
|
_checkloc(map["bar2"][1], 11u+4u, 4u, "2");
|
|
_checkloc(map["baz2"] , 11u+5u, 0u, "baz2");
|
|
_checkloc(map["baz2"][0], 11u+6u, 6u, "1_");
|
|
_checkloc(map["baz2"][1], 11u+7u, 6u, "2_");
|
|
_checkloc(map["baz2"][2], 11u+8u, 10u, "3_");
|
|
//
|
|
_checkloc(map["foo3"] , 22u+1u, 0u, "foo3");
|
|
_checkloc(map["bar3"] , 22u+2u, 0u, "bar3");
|
|
_checkloc(map["bar3"][0], 22u+3u, 4u, "1");
|
|
_checkloc(map["bar3"][1], 22u+4u, 4u, "2");
|
|
_checkloc(map["baz3"] , 22u+5u, 0u, "baz3");
|
|
_checkloc(map["baz3"][0], 22u+6u, 6u, "1_");
|
|
_checkloc(map["baz3"][1], 22u+7u, 6u, "2_");
|
|
_checkloc(map["baz3"][2], 22u+8u, 10u, "3_");
|
|
//
|
|
_checkloc(map["foo4"] , 33u+1u, 0u, "foo4");
|
|
_checkloc(map["bar4"] , 33u+2u, 0u, "bar4");
|
|
_checkloc(map["bar4"][0], 33u+3u, 4u, "1");
|
|
_checkloc(map["bar4"][1], 33u+4u, 4u, "2");
|
|
_checkloc(map["baz4"] , 33u+5u, 0u, "baz4");
|
|
_checkloc(map["baz4"][0], 33u+6u, 6u, "1_");
|
|
_checkloc(map["baz4"][1], 33u+7u, 6u, "2_");
|
|
_checkloc(map["baz4"][2], 33u+8u, 10u, "3_");
|
|
//
|
|
_checkloc(map["foo5"] , 44u+1u, 0u, "foo5");
|
|
_checkloc(map["bar5"] , 44u+2u, 0u, "bar5");
|
|
_checkloc(map["bar5"][0], 44u+3u, 4u, "1");
|
|
_checkloc(map["bar5"][1], 44u+4u, 4u, "2");
|
|
_checkloc(map["baz5"] , 44u+5u, 0u, "baz5");
|
|
_checkloc(map["baz5"][0], 44u+6u, 6u, "1_");
|
|
_checkloc(map["baz5"][1], 44u+7u, 6u, "2_");
|
|
_checkloc(map["baz5"][2], 44u+8u, 10u, "3_");
|
|
//
|
|
_checkloc(map["foo6"] , 55u+1u, 0u, "foo6");
|
|
_checkloc(map["bar6"] , 55u+2u, 0u, "bar6");
|
|
_checkloc(map["bar6"][0], 55u+3u, 4u, "1");
|
|
_checkloc(map["bar6"][1], 55u+4u, 4u, "2");
|
|
_checkloc(map["baz6"] , 55u+5u, 0u, "baz6");
|
|
_checkloc(map["baz6"][0], 55u+6u, 6u, "1_");
|
|
_checkloc(map["baz6"][1], 55u+7u, 6u, "2_");
|
|
_checkloc(map["baz6"][2], 55u+8u, 10u, "3_");
|
|
}
|
|
|
|
|
|
TEST(locations, issue260_0)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree tree = parse_in_arena(&parser, "source.yml", R"(Body:
|
|
- Id: 1
|
|
Name: Apple
|
|
Script: |
|
|
Line One
|
|
Line Two
|
|
- Id: 2
|
|
Name: Cat
|
|
Script: |
|
|
Line One
|
|
Line Two
|
|
- Id: 3
|
|
Name: Dog
|
|
Script: |
|
|
Line One
|
|
Line Two)");
|
|
EXPECT_EQ(tree["Body"][2]["Name"].val(), "Dog");
|
|
EXPECT_EQ(tree["Body"][2]["Name"].location(parser).line, 12u);
|
|
}
|
|
|
|
TEST(locations, issue260_1)
|
|
{
|
|
ParserOptions opts = ParserOptions().locations(true);
|
|
Parser::handler_type evt_handler = {};
|
|
Parser parser(&evt_handler, opts);
|
|
Tree tree = parse_in_arena(&parser, "source.yml", R"(Body: # 0
|
|
- Id: 1 # line 1
|
|
Name: Apple
|
|
- Id: 2 # line 3
|
|
Name: Cat
|
|
Script: |
|
|
Line One
|
|
Line Two
|
|
- Id: 3 # line 8
|
|
Name: Cat2
|
|
Script: >
|
|
Line One
|
|
Line Two
|
|
- Id: 4 # line 13
|
|
Name: Cat3
|
|
Script: "
|
|
Line One
|
|
Line Two"
|
|
- Id: 5 # line 18
|
|
Name: Cat4
|
|
Script: '
|
|
Line One
|
|
Line Two'
|
|
- Id: 5 # line 23
|
|
Name: Cat5
|
|
Script:
|
|
Line One
|
|
Line Two
|
|
- Id: 6 # line 28
|
|
Name: Dog
|
|
Script: |
|
|
Line One
|
|
Line Two)");
|
|
EXPECT_EQ(tree["Body"][0].location(parser).line, 1u);
|
|
EXPECT_EQ(tree["Body"][1].location(parser).line, 3u);
|
|
EXPECT_EQ(tree["Body"][2].location(parser).line, 8u);
|
|
EXPECT_EQ(tree["Body"][3].location(parser).line, 13u);
|
|
EXPECT_EQ(tree["Body"][4].location(parser).line, 18u);
|
|
EXPECT_EQ(tree["Body"][5].location(parser).line, 23u);
|
|
EXPECT_EQ(tree["Body"][6].location(parser).line, 28u);
|
|
EXPECT_EQ(tree["Body"][0]["Id"].location(parser).line, 1u);
|
|
EXPECT_EQ(tree["Body"][1]["Id"].location(parser).line, 3u);
|
|
EXPECT_EQ(tree["Body"][2]["Id"].location(parser).line, 8u);
|
|
EXPECT_EQ(tree["Body"][3]["Id"].location(parser).line, 13u);
|
|
EXPECT_EQ(tree["Body"][4]["Id"].location(parser).line, 18u);
|
|
EXPECT_EQ(tree["Body"][5]["Id"].location(parser).line, 23u);
|
|
EXPECT_EQ(tree["Body"][6]["Id"].location(parser).line, 28u);
|
|
EXPECT_EQ(tree["Body"][0]["Name"].location(parser).line, 1u+1u);
|
|
EXPECT_EQ(tree["Body"][1]["Name"].location(parser).line, 3u+1u);
|
|
EXPECT_EQ(tree["Body"][2]["Name"].location(parser).line, 8u+1u);
|
|
EXPECT_EQ(tree["Body"][3]["Name"].location(parser).line, 13u+1u);
|
|
EXPECT_EQ(tree["Body"][4]["Name"].location(parser).line, 18u+1u);
|
|
EXPECT_EQ(tree["Body"][5]["Name"].location(parser).line, 23u+1u);
|
|
EXPECT_EQ(tree["Body"][6]["Name"].location(parser).line, 28u+1u);
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
}
|
|
|
|
} // namespace yml
|
|
} // namespace c4
|