Add roundtrip engine tests, fix minor problems

This commit is contained in:
Joao Paulo Magalhaes
2025-11-06 10:35:53 +00:00
parent 71ffaf89ef
commit f8ee5fbe1f
20 changed files with 407 additions and 246 deletions

View File

@@ -1,15 +1,36 @@
### Changes
### New features
- [PR#547](https://github.com/biojppm/rapidyaml/pull/547) - Fix parsing of implicit first documents with empty sequences, caused by a problem in `Tree::set_root_as_stream()`:
```yaml
[] # this container was lost during parsing
---
more data here
```
- [PR#561](https://github.com/biojppm/rapidyaml/pull/561) (fixes [#559](https://github.com/biojppm/rapidyaml/issues/559)) - Byte Order Mark: account for BOM when determining block indentation
- [PR#563](https://github.com/biojppm/rapidyaml/pull/563) (fixes [#562](https://github.com/biojppm/rapidyaml/issues/562)) - Fix bug in `NodeRef::cend()`
- [PR#565](https://github.com/biojppm/rapidyaml/pull/565) (fixes [#564](https://github.com/biojppm/rapidyaml/issues/564)) - `Tree` arena: allow relocation of zero-length strings when placed at the end (relax assertions triggered in `Tree::_relocated()`)
- [PR#557](https://github.com/biojppm/rapidyaml/pull/557) - `Tree` is now non-empty by default, and `Tree::root_id()` will no longer modify the tree when it is empty. To create an empty tree now, it is necessary to use the capacity constructor with a capacity of zero:
- [PR#550](https://github.com/biojppm/rapidyaml/pull/550) - Implement flow multiline style (`FLOW_ML`):
- The parser now detects this style automatically for flow seqs or maps when the terminating bracket sits on a line different from the opening bracket.
- Added `ParserOptions::detect_flow_ml()` to enable/disable this behavior
- Added `EmitOptions::indent_flow_ml()` to control indentation of FLOW_ML containers
- The emit implementation logic was refactored, and is now significantly cleaner
- Emitted YAML will now have anchors emitted before tags, as is customary ([see example](https://play.yaml.io/main/parser?input=LSAhdGFnICZhbmNob3IgfAogIG5vdGUgaG93IHRoZSBhbmNob3IgY29tZXMKICBmaXJzdCBpbiB0aGUgZXZlbnRz)). Previously this
- Added `ParserOptions` defaulted argument to temp-parser overloads of `parse_{yaml,json}_in_{place,arena}()`
### API changes
- **BREAKING** [PR#503](https://github.com/biojppm/rapidyaml/pull/503) (fixes [#399](https://github.com/biojppm/rapidyaml/issues/399)): change error callbacks.
- Errors in ryml now have one of these types:
- parse error: when parsing YAML/JSON. See: `pfn_error_parse`, `ErrorDataParse`, `ExceptionParse`, `err_parse_format()`, `sample_error_parse`.
- visit error: when visiting a tree (reading or writing). See: `pfn_error_visit`, `ErrorDataVisit`, `ExceptionVisit`, `err_visit_format()`, `sample_error_visit`.
- basic error: other, non specific errors. See: `pfn_error_basic`, `ErrorDataBasic`, `ExceptionBasic`, `err_basic_format()`, `sample_error_basic`.
- parse and visit errors/exceptions can be treated/caught as basic errors/exceptions.
- Add message formatting functions to simplify user-provided implementation of error callbacks:
- `err_parse_format()`: format/print a full error message for a parse error
- `err_visit_format()`: format/print a full error message for a visit error
- `err_basic_format()`: format/print a full error message for a basic error
- `location_format()`: format/print a location
- `location_format_with_context()`: useful to create a rich error message showing the YAML region causing the error, maybe even for a visit error if the source is kept and locations are enabled.
- `format_exc()`: format an exception (when exceptions are enabled)
- See the new header `c4/yml/error.hpp` (and `c4/yml/error.def.hpp` for definitions of the functions in `c4/yml/error.hpp`)
- See the relevant sample functions in the quickstart sample: `sample_error_basic`, `sample_error_parse` and `sample_error_visit`.
- There are breaking user-facing changes in the `Callbacks` structure:
- Removed member `m_error `
- Added members `m_error_basic`, `m_error_parse`, `m_error_visit`
- Added methods `.set_error_basic()`, `.set_error_parse()` and `.set_error_visit()`.
- **BREAKING** [PR#557](https://github.com/biojppm/rapidyaml/pull/557) - `Tree` is now non-empty by default, and `Tree::root_id()` will no longer modify the tree when it is empty. To create an empty tree, it is now necessary to use the capacity constructor with a capacity of zero:
```c++
// breaking change: default-constructed tree is now non-empty
Tree tree;
@@ -24,39 +45,25 @@
```
This changeset also enables the python library to call `root_id()` on a default-constructed tree (fixes [#556](https://github.com/biojppm/rapidyaml/issues/556)).
- [PR#560](https://github.com/biojppm/rapidyaml/pull/560) (see also [#554](https://github.com/biojppm/rapidyaml/issues/554)): python improvements:
- expose `Tree::to_arena()` in python. This allows safer and easier programatic creation of trees in python by ensuring scalars have the same lifetime as the tree:
- expose `Tree::to_arena()` in python. This allows safer and easier programatic creation of trees in python by ensuring scalars are placed into the tree and so have the same lifetime as the tree:
```python
t = ryml.Tree()
s = t.to_arena(temp_string()) # Save a temporary string to the tree's arena.
s = t.to_arena(temp_string()) # Copy/serialize a temporary string to the tree's arena.
# Works also with integers and floats.
t.to_val(t.root_id(), s) # Now we can safely use the scalar in the tree:
# there is no longer any risk of it being deallocated
```
- improve behavior of `Tree` methods accepting scalars: all standard buffer types are now accepted (ie, `str`, `bytes`, `bytearray` and `memoryview`).
- [PR#550](https://github.com/biojppm/rapidyaml/pull/550) - Implement FLOW_ML style (flow multiline).
- The parser now sets this style automatically for flow seqs or maps when the terminating bracket sits on a line different from the opening bracket.
- Added `ParserOptions::detect_flow_ml()` to control this behavior
- Added `EmitOptions::indent_flow_ml()` to control indentation of FLOW_ML containers
- The emit implementation logic was refactored, and is now significantly cleaner
- Emitted YAML will now have anchors emitted before tags, as is customary ([see example](https://play.yaml.io/main/parser?input=LSAhdGFnICZhbmNob3IgfAogIG5vdGUgaG93IHRoZSBhbmNob3IgY29tZXMKICBmaXJzdCBpbiB0aGUgZXZlbnRz)).
- Added `ParserOptions` defaulted argument to temp-parser overloads of `parse_{yaml,json}_in_{place,arena}()`
[PR#503](https://github.com/biojppm/rapidyaml/pull/503) (fixes [#399](https://github.com/biojppm/rapidyaml/issues/399)): change error callbacks.
- Errors in ryml now have one of these types:
- parse error: when parsing YAML/JSON. See: `pfn_error_parse`, `ErrorDataParse`, `ExceptionParse`, `err_parse_format()`, `sample_error_parse`.
- visit error: when visiting a tree (reading or writing). See: `pfn_error_visit`, `ErrorDataVisit`, `ExceptionVisit`, `err_visit_format()`, `sample_error_visit`.
- basic error: other, non specific errors. See: `pfn_error_basic`, `ErrorDataBasic`, `ExceptionBasic`, `err_basic_format()`, `sample_error_basic`.
- parse and visit errors/exceptions can be treated/caught as basic errors/exceptions
- Add message formatting functions to simplify implementation of error callbacks:
- `err_parse_format()`: format/print a full error message for a parse error
- `err_visit_format()`: format/print a full error message for a visit error
- `err_basic_format()`: format/print a full error message for a basic error
- `location_format()`: format/print a location
- `location_format_with_context()`: useful to create a rich error message showing the YAML region causing the error, maybe even for a visit error if the source is kept and locations are enabled.
- `format_exc()`: when exceptions are enabled
- See the new header `c4/yml/error.hpp` (and `c4/yml/error.def.hpp` for definitions of the functions in `c4/yml/error.hpp`)
- See the relevant sample functions in the quickstart sample: `sample_error_basic`, `sample_error_parse` and `sample_error_visit`.
- There are breaking user-facing changes in the `Callbacks` structure:
- Removed member `m_error `
- Added members `m_error_basic`, `m_error_parse`, `m_error_visit`
- Added methods `.set_error_basic()`, `.set_error_parse()` and `.set_error_visit()`.
- [PR#565](https://github.com/biojppm/rapidyaml/pull/565) (fixes [#564](https://github.com/biojppm/rapidyaml/issues/564)) - `Tree` arena: allow relocation of zero-length strings when placed at the end (relax assertions triggered in `Tree::_relocated()`)
- [PR#563](https://github.com/biojppm/rapidyaml/pull/563) (fixes [#562](https://github.com/biojppm/rapidyaml/issues/562)) - Fix bug in `NodeRef::cend()`
### Fixes in YAML parsing
- [PR#561](https://github.com/biojppm/rapidyaml/pull/561) (fixes [#559](https://github.com/biojppm/rapidyaml/issues/559)) - Byte Order Mark: account for BOM length when determining block indentation
- [PR#547](https://github.com/biojppm/rapidyaml/pull/547) - Fix parsing of implicit first documents with empty sequences, caused by a problem in `Tree::set_root_as_stream()`:
```yaml
[] # this container was lost during parsing
---
more data here
```

View File

@@ -4307,7 +4307,7 @@ void sample_style()
{
// we will be using this helper throughout this function
auto tostr = [](ryml::ConstNodeRef n) { return ryml::emitrs_yaml<std::string>(n); };
// let's parse this:
// let's parse this yaml:
ryml::csubstr yaml = R"(block map:
block key: block val
block seq:
@@ -4345,11 +4345,15 @@ flow seq, multiline: [
CHECK(tree["flow seq, singleline"].is_flow());
CHECK(tree["flow map, multiline"].is_flow());
CHECK(tree["flow seq, multiline"].is_flow());
// since the tree nodes are marked with style during the parse,
// emission will preserve the original style (minus whitespace):
//
// since the tree nodes are marked with their original parsed
// style, emitting the parsed tree will preserve the original
// style (minus whitespace):
//
CHECK(tostr(tree) == yaml); // same as before!
//
// you can set/modify the style programatically!
//
// here are more examples.
//
{
@@ -4450,9 +4454,9 @@ flow seq, multiline: [flow val,flow val]
tree.rootref().clear_style(/*recurse*/true);
// when emitting nodes which have no style set, ryml will default
// to block format for containers, and call
// ryml::scalar_style_choose() to pick the style for each
// scalar. Note that it picks single-quoted for the scalars
// containing commas:
// ryml::scalar_style_choose() to pick the style for each scalar
// (at the cost of a scan over each scalar). Note that ryml picks
// single-quoted for scalars containing commas:
CHECK(tostr(tree) ==
R"(block map:
block key: block val
@@ -4472,7 +4476,8 @@ block seq:
- flow val
)");
// you can set the style based on type conditions:
// set a single key to single-quoted
//
// eg, set a single key to single-quoted
tree["block map"].set_style_conditionally(/*type_mask*/ryml::KEY,
/*remflags*/ryml::KEY_STYLE,
/*addflags*/ryml::KEY_SQUO,
@@ -4662,6 +4667,21 @@ void sample_style_flow_ml_filter()
]
}
}
)";
ryml::csubstr yaml_not_indented = R"({
map: {
seq: [
0,
1,
2,
3,
[
40,
41
]
]
}
}
)";
// note that the parser defaults to detect multiline flow
// (FLOW_ML) containers:
@@ -4687,22 +4707,7 @@ void sample_style_flow_ml_filter()
const ryml::EmitOptions noindent = ryml::EmitOptions{}.indent_flow_ml(false);
const ryml::Tree tree = ryml::parse_in_arena(yaml);
CHECK(tree["map"].is_flow_ml()); // etc
CHECK(ryml::emitrs_yaml<std::string>(tree, noindent) ==
R"({
map: {
seq: [
0,
1,
2,
3,
[
40,
41
]
]
}
}
)");
CHECK(ryml::emitrs_yaml<std::string>(tree, noindent) == yaml_not_indented);
}
}

View File

@@ -57,8 +57,6 @@
#endif
#define RYML_LOGBUF_SIZE_MAX RYML_ERRMSG_SIZE
#include <c4/dump.hpp>
C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wattributes")

View File

@@ -41,6 +41,7 @@ substr Emitter<Writer>::emit_as(EmitType_e type, Tree const& tree, id_type id, b
return this->Writer::_get(error_on_excess);
}
/** @cond dev */
//-----------------------------------------------------------------------------
@@ -1476,6 +1477,8 @@ void Emitter<Writer>::_write_scalar_json_dquo(csubstr s)
_write('"');
}
/** @endcond */
} // namespace yml
} // namespace c4

View File

@@ -59,6 +59,7 @@ struct EmitOptions
{
public:
/** @cond dev */
typedef enum : uint32_t {
EMIT_NONROOT_KEY = 1u << 0u,
EMIT_NONROOT_DASH = 1u << 1u,
@@ -69,6 +70,7 @@ public:
_JSON_ERR_MASK = JSON_ERR_ON_TAG|JSON_ERR_ON_ANCHOR,
DEFAULT_FLAGS = EMIT_NONROOT_KEY|INDENT_FLOW_ML,
} EmitOptionFlags_e;
/** @endcond */
public:
@@ -368,19 +370,27 @@ private:
private:
// g++-4.8 has problems with the operand types here...
#if defined(__GNUC__) && (__GNUC__ < 5) && (!defined(__clang__))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wparentheses"
#endif
enum : type_bits {
_styles_block_key = KEY_LITERAL|KEY_FOLDED,
_styles_block_val = VAL_LITERAL|VAL_FOLDED,
_styles_block = _styles_block_key|_styles_block_val,
_styles_flow_key = KEY_STYLE & ~_styles_block_key,
_styles_flow_val = VAL_STYLE & ~_styles_block_val,
_styles_flow = _styles_flow_key|_styles_flow_val,
_styles_block = ((type_bits)_styles_block_key) | ((type_bits)_styles_block_val),
_styles_flow_key = KEY_STYLE & (~((type_bits)_styles_block_key)),
_styles_flow_val = VAL_STYLE & (~((type_bits)_styles_block_val)),
_styles_flow = ((type_bits)_styles_flow_key) | ((type_bits)_styles_flow_val),
_styles_squo = KEY_SQUO|VAL_SQUO,
_styles_dquo = KEY_DQUO|VAL_DQUO,
_styles_plain = KEY_PLAIN|VAL_PLAIN,
_styles_literal = KEY_LITERAL|VAL_LITERAL,
_styles_folded = KEY_FOLDED|VAL_FOLDED,
};
#if defined(__GNUC__) && (__GNUC__ < 5) && (!defined(__clang__))
#pragma GCC diagnostic pop
#endif
/** @endcond */
};

View File

@@ -349,7 +349,7 @@ public:
_c4dbgpf("node[{}]: added sibling={} prev={}", m_parent->node_id, m_curr->node_id, m_tree->prev_sibling(m_curr->node_id));
}
/** set the previous val as the first key of a new map, with flow style.
/** reset the previous val as the first key of a new map, with flow style.
*
* See the documentation for @ref doc_event_handlers, which has
* important notes about this event.
@@ -363,7 +363,7 @@ public:
_RYML_ASSERT_VISIT_(m_stack.m_callbacks, !m_tree->is_container(m_curr->node_id), m_tree, m_curr->node_id);
_RYML_ASSERT_VISIT_(m_stack.m_callbacks, !m_tree->has_key(m_curr->node_id), m_tree, m_curr->node_id);
const NodeData tmp = _val2key_(*m_curr->tr_data);
_disable_(_VALMASK|VAL_STYLE);
_disable_(_VALMASK|VAL_STYLE|VALNIL);
m_curr->tr_data->m_val = {};
begin_map_val_flow();
m_curr->tr_data->m_type = tmp.m_type;
@@ -739,6 +739,8 @@ public:
r.m_type.type = ((d.m_type.type & (_VALMASK|VAL_STYLE)) >> 1u);
r.m_type.type = (r.m_type.type & ~(_VALMASK|VAL_STYLE));
r.m_type.type = (r.m_type.type | KEY);
if(d.m_type.type & VALNIL)
r.m_type.type = (r.m_type.type | KEYNIL);
return r;
}

View File

@@ -270,7 +270,6 @@ RYML_EXPORT inline C4_NO_INLINE bool scalar_is_null(csubstr s) noexcept
/** @} */
/** @} */
} // namespace yml

View File

@@ -803,6 +803,7 @@ bool ParseEngine<EventHandler>::_is_valid_start_scalar_plain_flow(csubstr s)
case '}':
case ']':
case '\r':
_RYML_WITH_TAB_TOKENS(case '\t':)
if(s.str[0] == ':')
{
_c4dbgpf("not a scalar: found non-scalar token '{}{}'", s.str[0], s.str[1]);
@@ -952,7 +953,7 @@ bool ParseEngine<EventHandler>::_scan_scalar_plain_seq_flow(ScannedScalar *C4_RE
_c4dbgp("found suspicious '#'");
_RYML_ASSERT_BASIC_(m_evt_handler->m_stack.m_callbacks, offs > 0);
char prev = s.str[offs - 1];
if(prev == ' ' _RYML_WITH_TAB_TOKENS((|| prev == '\t')))
if(prev == ' ' _RYML_WITH_TAB_TOKENS(|| prev == '\t'))
{
_c4dbgpf("found terminating character at {}: '{}'", offs, c);
goto ended_scalar;
@@ -2205,7 +2206,7 @@ void ParseEngine<EventHandler>::_scan_block(ScannedBlock *C4_RESTRICT sb, size_t
if(fns != npos) // non-empty line
{
_RYML_WITH_TAB_TOKENS(
if(C4_UNLIKELY(lc.stripped.begins_with('\t')))
if(C4_UNLIKELY(lc.full.begins_with('\t')))
_c4err("parse error");
)
_c4dbgpf("blck: line not empty. indref={} indprov={} indentation={}", indref, provisional_indentation, lc.indentation);

View File

@@ -56,7 +56,7 @@ csubstr _parser_flags_to_str(substr buf, ParserFlag_t flags);
struct LineContents
{
substr rem; ///< current line remainder, without newline characters
substr full; ///< full line, including newline characters \n and \r
substr full; ///< full line, including newline characters `\n` and `\r`
size_t num_cols; ///< number of columns in the line, excluding newline
///< characters (ie the initial size of rem)
size_t indentation; ///< number of spaces on the beginning of the line.

View File

@@ -865,7 +865,7 @@ public:
* you can overload c4::to_chars(substr, T const&)
*
* @note To customize how the type gets serialized to the arena,
* you can overload @ref c4::yml::serialize_scalar(substr, T const&)
* you can overload @ref serialize_scalar()
*
* @note Growing the arena may cause relocation of the entire
* existing arena, and thus change the contents of individual

View File

@@ -149,6 +149,10 @@ if(CMAKE_COMPILER_IS_GNUCXX
c4_target_compile_flags(ryml-test-scalar_plain PUBLIC GCC -Wno-array-bounds -Wno-stringop-overflow)
endif()
endif()
# MSVC bigobj
if(MSVC)
target_compile_options(ryml-test-engine_1_doc PRIVATE /bigobj)
endif()
#-------------------------------------------------------------------------

View File

@@ -19,7 +19,8 @@ ENGINE_TEST(DocEmpty,
//-----------------------------------------------------------------------------
ENGINE_TEST(DocEmptyExpl,
"---\n",
"---\n"
,
"+STR\n"
"+DOC ---\n"
"=VAL :\n"
@@ -28,7 +29,7 @@ ENGINE_TEST(DocEmptyExpl,
{
___(ps.begin_stream());
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc());
___(ps.end_stream());
}
@@ -190,13 +191,13 @@ ENGINE_TEST(DocEmptyExplMult,
{
___(ps.begin_stream());
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc());
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc());
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc());
___(ps.end_stream());
}

View File

@@ -223,7 +223,7 @@ ENGINE_TEST(SimpleSeqBlock2,
___(ps.set_val_scalar_plain("bar"));
___(ps.add_sibling());
___(ps.set_key_scalar_plain("baz"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_block());
___(ps.end_doc());
@@ -350,13 +350,13 @@ ENGINE_TEST(SimpleSeqBlockEmptyScalars,
ps.begin_stream();
ps.begin_doc();
ps.begin_seq_val_block();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.end_seq_block();
ps.end_doc();
ps.end_stream();

View File

@@ -368,16 +368,16 @@ ENGINE_TEST(SimpleMapBlockEmptyVals,
ps.begin_doc();
ps.begin_map_val_block();
ps.set_key_scalar_plain("a");
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain("b");
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain("c");
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain("d");
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.end_map_block();
ps.end_doc();
ps.end_stream();
@@ -404,16 +404,16 @@ ENGINE_TEST(SimpleMapBlockEmptyKeys,
ps.begin_stream();
ps.begin_doc();
ps.begin_map_val_block();
ps.set_key_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain("a");
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain("b");
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain("c");
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain("d");
ps.end_map_block();
ps.end_doc();
@@ -443,17 +443,17 @@ ENGINE_TEST(SimpleMapBlockEmpty,
ps.begin_stream();
ps.begin_doc();
ps.begin_map_val_block();
ps.set_key_scalar_plain({});
ps.set_val_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_val_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_val_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain_empty();
ps.add_sibling();
ps.set_key_scalar_plain({});
ps.set_val_scalar_plain({});
ps.set_key_scalar_plain_empty();
ps.set_val_scalar_plain_empty();
ps.end_map_block();
ps.end_doc();
ps.end_stream();
@@ -506,7 +506,7 @@ ENGINE_TEST(SimpleMapIndentlessSeq,
ps.begin_seq_val_block();
ps.set_val_scalar_plain("bar");
ps.add_sibling();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.end_seq_block();
ps.add_sibling();
ps.set_key_scalar_plain("baz");
@@ -516,7 +516,7 @@ ENGINE_TEST(SimpleMapIndentlessSeq,
ps.begin_seq_val_block();
ps.set_val_scalar_plain("bar2");
ps.add_sibling();
ps.set_val_scalar_plain({});
ps.set_val_scalar_plain_empty();
ps.end_seq_block();
ps.add_sibling();
ps.set_key_scalar_plain("baz2");

View File

@@ -806,7 +806,7 @@ ENGINE_TEST(TagTestSuiteU99R_3,
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_scalar_plain("xxx"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_doc());
___(ps.end_stream());
@@ -836,7 +836,7 @@ ENGINE_TEST(TagTestSuiteU99R_3_1,
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_scalar_plain("xxx"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_doc());
___(ps.end_stream());
@@ -863,10 +863,10 @@ ENGINE_TEST(TagTestSuiteWZ62_0_0_0,
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!!str"));
___(ps.set_key_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain("bar"));
___(ps.end_map_flow(singleline));
___(ps.end_doc());
@@ -894,10 +894,10 @@ ENGINE_TEST(TagTestSuiteWZ62_0_0_1,
___(ps.begin_map_val_block());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!!str"));
___(ps.set_key_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain("bar"));
___(ps.end_map_block());
___(ps.end_doc());
@@ -925,10 +925,10 @@ ENGINE_TEST(TagTestSuiteWZ62_0_1_0,
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!str"));
___(ps.set_key_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain("bar"));
___(ps.end_map_flow(singleline));
___(ps.end_doc());
@@ -956,10 +956,10 @@ ENGINE_TEST(TagTestSuiteWZ62_0_1_1,
___(ps.begin_map_val_block());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!str"));
___(ps.set_key_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain("bar"));
___(ps.end_map_block());
___(ps.end_doc());
@@ -987,11 +987,11 @@ ENGINE_TEST(TagTestSuiteWZ62_1_0_0,
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!!str:"));
___(ps.set_key_scalar_plain("bar"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_block());
___(ps.end_doc());
___(ps.end_stream());
@@ -1018,11 +1018,11 @@ ENGINE_TEST(TagTestSuiteWZ62_1_0_1,
___(ps.begin_map_val_block());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!!str:"));
___(ps.set_key_scalar_plain("bar"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_block());
___(ps.end_doc());
___(ps.end_stream());
@@ -1049,11 +1049,11 @@ ENGINE_TEST(TagTestSuiteWZ62_1_1_0,
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!str:"));
___(ps.set_key_scalar_plain("bar"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_doc());
___(ps.end_stream());
@@ -1080,11 +1080,11 @@ ENGINE_TEST(TagTestSuiteWZ62_1_1_1,
___(ps.begin_map_val_block());
___(ps.set_key_scalar_plain("foo"));
___(ps.set_val_tag("!str"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.add_sibling());
___(ps.set_key_tag("!str:"));
___(ps.set_key_scalar_plain("bar"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_block());
___(ps.end_doc());
___(ps.end_stream());
@@ -1235,7 +1235,7 @@ ENGINE_TEST(DirectiveTestSuiteMUS6,
___(ps.begin_stream());
___(ps.add_directive("%YAM 1.1"));
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc());
___(ps.end_stream());
}
@@ -1273,7 +1273,7 @@ ENGINE_TEST(DirectiveMultipleYAML_W4TN,
___(ps.end_doc_expl());
___(ps.add_directive("%YAML 1.2"));
___(ps.begin_doc_expl());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_doc_expl());
___(ps.end_stream());
}

View File

@@ -235,9 +235,9 @@ ENGINE_TEST(SeqIMap2Nested,
___(ps.end_seq_flow(singleline));
___(ps.end_map_flow(singleline));
___(ps.add_sibling());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -267,7 +267,7 @@ ENGINE_TEST(SeqIMap3EmptyKey,
___(ps.begin_seq_val_flow());
___(ps.set_val_scalar_plain("val0"));
___(ps.add_sibling());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain("wtf"));
___(ps.end_map_flow(singleline));
@@ -300,7 +300,7 @@ ENGINE_TEST(SeqIMap3EmptyVal,
___(ps.add_sibling());
___(ps.set_val_scalar_plain("wtf"));
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -329,9 +329,9 @@ ENGINE_TEST(SeqIMap3EmptyKeyVal,
___(ps.begin_seq_val_flow());
___(ps.set_val_scalar_plain("val0"));
___(ps.add_sibling());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -366,9 +366,9 @@ ENGINE_TEST(SeqIMap3EmptyKeyValNested,
___(ps.set_val_scalar_plain("val1"));
___(ps.end_map_flow(singleline));
___(ps.add_sibling());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -413,9 +413,9 @@ ENGINE_TEST(SeqIMap3EmptyKeyValNested2,
___(ps.end_seq_flow(singleline));
___(ps.end_map_flow(singleline));
___(ps.add_sibling());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.actually_val_is_first_key_of_new_map_flow());
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -678,8 +678,8 @@ ENGINE_TEST(SeqIMap5QmrkNone0,
___(ps.begin_doc());
___(ps.begin_seq_val_flow());
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain({}));
___(ps.set_val_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -706,8 +706,8 @@ ENGINE_TEST(SeqIMap5QmrkNone1,
___(ps.begin_doc());
___(ps.begin_seq_val_flow());
___(ps.begin_map_val_flow());
___(ps.set_key_scalar_plain({}));
___(ps.set_val_scalar_plain({}));
___(ps.set_key_scalar_plain_empty());
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -733,11 +733,10 @@ ENGINE_TEST(SeqIMap5QmrkSquo1,
___(ps.begin_stream());
___(ps.begin_doc());
___(ps.begin_seq_val_flow());
___(ps.set_key_tag("!tag"));
___(ps.begin_map_val_flow());
___(ps.set_key_anchor("anchor"));
___(ps.set_key_scalar_squoted("squo"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -763,11 +762,10 @@ ENGINE_TEST(SeqIMap5QmrkDquo1,
___(ps.begin_stream());
___(ps.begin_doc());
___(ps.begin_seq_val_flow());
___(ps.set_key_tag("!tag"));
___(ps.begin_map_val_flow());
___(ps.set_key_anchor("anchor"));
___(ps.set_key_scalar_dquoted("dquo"));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -860,7 +858,7 @@ ENGINE_TEST(SeqIMap5QmrkSeq,
___(ps.set_val_scalar_plain("a"));
___(ps.set_val_scalar_plain("seq"));
___(ps.end_seq_flow(singleline));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());
@@ -897,7 +895,7 @@ ENGINE_TEST(SeqIMap5QmrkMap,
___(ps.set_key_scalar_plain("a"));
___(ps.set_val_scalar_plain("map"));
___(ps.end_map_flow(singleline));
___(ps.set_val_scalar_plain({}));
___(ps.set_val_scalar_plain_empty());
___(ps.end_map_flow(singleline));
___(ps.end_seq_flow(singleline));
___(ps.end_doc());

View File

@@ -47,22 +47,23 @@ id_type _num_leaves(Tree const& t, id_type node)
}
void test_compare(Tree const& actual, Tree const& expected)
void test_compare(Tree const& actual, Tree const& expected,
const char *actual_name, const char *expected_name)
{
ASSERT_EQ(actual.empty(), expected.empty());
if(actual.empty() || expected.empty())
return;
EXPECT_EQ(actual.size(), expected.size());
EXPECT_EQ(_num_leaves(actual, actual.root_id()), _num_leaves(expected, expected.root_id()));
test_compare(actual, actual.root_id(), expected, expected.root_id(), 0);
test_compare(actual, actual.root_id(), expected, expected.root_id(), 0, actual_name, expected_name);
}
void test_compare(Tree const& actual, id_type node_actual,
Tree const& expected, id_type node_expected,
id_type level)
Tree const& expected, id_type node_expected,
id_type depth, const char *actual_name, const char *expected_name)
{
RYML_TRACE_FMT("actual={} vs expected={}", node_actual, node_expected);
RYML_TRACE_FMT("{}[{}] vs {}[{}]. depth={}", actual_name, node_actual, expected_name, node_expected, depth);
ASSERT_NE(node_actual, (id_type)NONE);
ASSERT_NE(node_expected, (id_type)NONE);
@@ -122,8 +123,9 @@ void test_compare(Tree const& actual, id_type node_actual,
ia != NONE && ib != NONE;
ia = actual.next_sibling(ia), ib = expected.next_sibling(ib))
{
test_compare(actual, ia, expected, ib, level+1);
test_compare(actual, ia, expected, ib, depth+1, actual_name, expected_name);
}
}
void test_arena_not_shared(Tree const& a, Tree const& b)

View File

@@ -116,10 +116,11 @@ struct CaseData;
Case const* get_case(csubstr name);
CaseData* get_data(csubstr name);
void test_compare(Tree const& actual, Tree const& expected);
void test_compare(Tree const& actual, Tree const& expected,
const char *actual_name="actual", const char *expected_name="expected");
void test_compare(Tree const& actual, id_type node_actual,
Tree const& expected, id_type node_expected,
id_type level=0);
Tree const& expected, id_type node_expected,
id_type level=0, const char *actual_name="actual", const char *expected_name="expected");
void test_arena_not_shared(Tree const& a, Tree const& b);

View File

@@ -10,7 +10,7 @@ namespace yml {
namespace {
// inject comments on every line
std::vector<std::string> inject_comments(std::string const& src_)
std::vector<std::string> inject_comments_in_src(std::string const& src_)
{
std::vector<std::string> result;
csubstr src = to_csubstr(src_);
@@ -80,27 +80,27 @@ void test_expected_error_tree_from_yaml(std::string const& parsed_yaml, Location
}
void test_engine_testsuite_from_yaml(EngineEvtTestCase const& tc, std::string const& parsed_yaml, ParserOptions opts)
void test_engine_testsuite_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml)
{
extra::EventHandlerTestSuite::EventSink sink;
extra::EventHandlerTestSuite handler(&sink);
handler.reset();
ParseEngine<extra::EventHandlerTestSuite> parser(&handler, opts);
ParseEngine<extra::EventHandlerTestSuite> parser(&handler, test_case.opts);
std::string copy = parsed_yaml;
parser.parse_in_place_ev("(testyaml)", to_substr(copy));
csubstr result = sink;
_c4dbgpf("~~~\n{}~~~\n", result);
EXPECT_EQ(std::string(result.str, result.len), tc.expected_events);
EXPECT_EQ(std::string(result.str, result.len), test_case.expected_events);
}
void test_engine_ints_from_yaml(EngineEvtTestCase const& tc, std::string const& parsed_yaml, ParserOptions opts)
void test_engine_ints_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml)
{
extra::EventHandlerInts handler{};
using IntType = extra::ievt::DataType;
//NOTE! crashes in MIPS64 Debug c++20 (but not c++11) when size is 0:
//std::vector<IntType> actual_evts(empty.size());
std::vector<IntType> actual_evts; // DO THIS!
size_t size_reference = num_ints(tc.expected_ints.data(), tc.expected_ints.size());
size_t size_reference = num_ints(test_case.expected_ints.data(), test_case.expected_ints.size());
int size_estimated = extra::estimate_events_ints_size(to_csubstr(parsed_yaml));
// there was an error in gcc<5 where the copy buffer was NOT
// assigned when using a std::string:
@@ -109,10 +109,10 @@ void test_engine_ints_from_yaml(EngineEvtTestCase const& tc, std::string const&
_c4dbgpf("parsing: [{}]{}", copy.size(), c4::fmt::hex(copy.data()));
std::vector<char> arena(copy.size());
handler.reset(to_csubstr(copy), to_substr(arena), actual_evts.data(), (IntType)actual_evts.size());
ParseEngine<extra::EventHandlerInts> parser(&handler, opts);
ParseEngine<extra::EventHandlerInts> parser(&handler, test_case.opts);
parser.parse_in_place_ev("(testyaml)", to_substr(copy));
EXPECT_GE(size_estimated, handler.required_size_events());
if(tc.expected_ints_enabled)
if(test_case.expected_ints_enabled)
{
EXPECT_EQ(size_reference, handler.required_size_events());
}
@@ -138,17 +138,17 @@ void test_engine_ints_from_yaml(EngineEvtTestCase const& tc, std::string const&
RYML_TRACE_FMT("invariants", 0);
extra::test_events_ints_invariants(to_csubstr(copy), to_csubstr(arena), actual_evts.data(), (IntType)actual_evts.size());
}
if (tc.expected_ints_enabled)
if (test_case.expected_ints_enabled)
{
RYML_TRACE_FMT("here", 0);
test_events_ints(tc.expected_ints.data(), tc.expected_ints.size(),
test_events_ints(test_case.expected_ints.data(), test_case.expected_ints.size(),
actual_evts.data(), actual_evts.size(),
to_csubstr(parsed_yaml), to_csubstr(copy), to_csubstr(arena));
}
{
RYML_TRACE_FMT("cmp", 0);
std::string actual_test_suite_evts = extra::events_ints_to_testsuite<std::string>(to_csubstr(copy), to_csubstr(arena), actual_evts.data(), (IntType)actual_evts.size());
test_compare_events(to_csubstr(tc.expected_events),
test_compare_events(to_csubstr(test_case.expected_events),
to_csubstr(actual_test_suite_evts),
/*ignore_doc_style*/false,
/*ignore_container_style*/false,
@@ -157,76 +157,132 @@ void test_engine_ints_from_yaml(EngineEvtTestCase const& tc, std::string const&
}
}
void test_engine_tree_from_yaml(EngineEvtTestCase const& tc, std::string const& parsed_yaml, ParserOptions opts)
void test_engine_tree_from_yaml(EngineEvtTestCase const& test_case, std::string const& yaml)
{
if(tc.test_case_flags & HAS_CONTAINER_KEYS)
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
{
test_expected_error_tree_from_yaml(parsed_yaml, tc.expected_error_location);
test_expected_error_tree_from_yaml(yaml, test_case.expected_error_location);
return;
}
Tree tree = {};
EventHandlerTree handler(&tree, tree.root_id());
ASSERT_EQ(&tree, handler.m_tree);
ParseEngine<EventHandlerTree> parser(&handler, opts);
ParseEngine<EventHandlerTree> parser(&handler, test_case.opts);
ASSERT_EQ(&handler, parser.m_evt_handler);
ASSERT_EQ(&tree, parser.m_evt_handler->m_tree);
std::string copy = parsed_yaml;
std::string copy = yaml;
parser.parse_in_place_ev("(testyaml)", to_substr(copy));
#ifdef RYML_DBG
print_tree(tree);
print_tree("parsed_tree", tree);
#endif
std::string actual = emitrs_yaml<std::string>(tree);
_c4dbgpf("~~~\n{}~~~\n", actual);
EXPECT_EQ(tc.expected_emitted, actual);
EXPECT_EQ(test_case.expected_emitted, actual);
}
void test_engine_testsuite_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts)
void test_engine_roundtrip_from_yaml(EngineEvtTestCase const& test_case, std::string const& yaml)
{
if(yaml.test_case_flags & HAS_CONTAINER_KEYS)
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
return;
if(yaml.test_case_flags & HAS_MULTILINE_SCALAR)
return;
const auto injected_comments = inject_comments(yaml.parsed);
for(size_t i = 0; i < injected_comments.size(); ++i)
csubstr filename = "(testyaml)";
std::string copy = yaml;
const Tree parsed_tree = parse_in_place(filename, to_substr(copy), test_case.opts);
#ifdef RYML_DBG
print_tree("parsed_tree", parsed_tree);
#endif
{
const std::string& transformed_str = injected_comments[i];
_c4dbgpf("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comments.size(), transformed_str.size(), to_csubstr(transformed_str));
SCOPED_TRACE(transformed_str);
SCOPED_TRACE("commented");
test_engine_testsuite_from_yaml(yaml, transformed_str, opts);
SCOPED_TRACE("invariants_after_parse");
test_invariants(parsed_tree);
}
const std::string parsed_tree_emitted = emitrs_yaml<std::string>(parsed_tree);
EXPECT_EQ(test_case.expected_emitted, parsed_tree_emitted);
std::string emitted0_copy = parsed_tree_emitted;
const Tree after_roundtrip = parse_in_place(filename, to_substr(emitted0_copy), test_case.opts);
{
SCOPED_TRACE("invariants_after_roundtrip");
test_invariants(after_roundtrip);
}
{
SCOPED_TRACE("compare_trees");
test_compare(after_roundtrip, parsed_tree,
"after_roundtrip", "parsed_tree");
}
const std::string after_roundtrip_emitted = emitrs_yaml<std::string>(after_roundtrip);
EXPECT_EQ(test_case.expected_emitted, after_roundtrip_emitted);
if(testing::Test::HasFailure())
{
printf("source: ~~~\n%.*s~~~\n", (int)yaml.size(), yaml.data());
print_tree("parsed_tree", parsed_tree);
printf("parsed_tree_emitted: ~~~\n%.*s~~~\n", (int)parsed_tree_emitted.size(), parsed_tree_emitted.data());
print_tree("after_roundtrip", after_roundtrip);
printf("after_roundtrip_emitted: ~~~\n%.*s~~~\n", (int)after_roundtrip_emitted.size(), after_roundtrip_emitted.data());
}
}
void test_engine_ints_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts)
void test_engine_testsuite_from_yaml_with_comments(EngineEvtTestCase const& test_case)
{
if(yaml.test_case_flags & HAS_MULTILINE_SCALAR)
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
return;
const auto injected_comments = inject_comments(yaml.parsed);
for(size_t i = 0; i < injected_comments.size(); ++i)
if(test_case.test_case_flags & HAS_MULTILINE_SCALAR)
return;
const auto injected_comment_cases = inject_comments_in_src(test_case.yaml);
for(size_t i = 0; i < injected_comment_cases.size(); ++i)
{
const std::string& transformed_str = injected_comments[i];
_c4dbgpf("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comments.size(), transformed_str.size(), to_csubstr(transformed_str));
const std::string& transformed_str = injected_comment_cases[i];
RYML_TRACE_FMT("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comment_cases.size(), transformed_str.size(), to_csubstr(transformed_str));
SCOPED_TRACE(transformed_str);
SCOPED_TRACE("commented");
test_engine_ints_from_yaml(yaml, transformed_str, opts);
test_engine_testsuite_from_yaml(test_case, transformed_str);
}
}
void test_engine_tree_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts)
void test_engine_ints_from_yaml_with_comments(EngineEvtTestCase const& test_case)
{
if(yaml.test_case_flags & HAS_CONTAINER_KEYS)
if(test_case.test_case_flags & HAS_MULTILINE_SCALAR)
return;
if(yaml.test_case_flags & HAS_MULTILINE_SCALAR)
return;
const auto injected_comments = inject_comments(yaml.parsed);
for(size_t i = 0; i < injected_comments.size(); ++i)
const auto injected_comment_cases = inject_comments_in_src(test_case.yaml);
for(size_t i = 0; i < injected_comment_cases.size(); ++i)
{
const auto & transformed_str = injected_comments[i];
_c4dbgpf("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comments.size(), transformed_str.size(), to_csubstr(transformed_str));
const std::string& transformed_str = injected_comment_cases[i];
RYML_TRACE_FMT("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comment_cases.size(), transformed_str.size(), to_csubstr(transformed_str));
SCOPED_TRACE(transformed_str);
SCOPED_TRACE("commented");
test_engine_ints_from_yaml(yaml, transformed_str, opts);
test_engine_ints_from_yaml(test_case, transformed_str);
}
}
void test_engine_tree_from_yaml_with_comments(EngineEvtTestCase const& test_case)
{
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
return;
if(test_case.test_case_flags & HAS_MULTILINE_SCALAR)
return;
const auto injected_comment_cases = inject_comments_in_src(test_case.yaml);
for(size_t i = 0; i < injected_comment_cases.size(); ++i)
{
const std::string& transformed_str = injected_comment_cases[i];
RYML_TRACE_FMT("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comment_cases.size(), transformed_str.size(), to_csubstr(transformed_str));
SCOPED_TRACE(transformed_str);
SCOPED_TRACE("commented");
test_engine_tree_from_yaml(test_case, transformed_str);
}
}
void test_engine_roundtrip_from_yaml_with_comments(EngineEvtTestCase const& test_case)
{
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
return;
if(test_case.test_case_flags & HAS_MULTILINE_SCALAR)
return;
const auto injected_comment_cases = inject_comments_in_src(test_case.yaml);
for(size_t i = 0; i < injected_comment_cases.size(); ++i)
{
const std::string& transformed_str = injected_comment_cases[i];
RYML_TRACE_FMT("transformed[{}/{}]=~~~[{}]\n{}\n~~~", i, injected_comment_cases.size(), transformed_str.size(), to_csubstr(transformed_str));
SCOPED_TRACE(transformed_str);
SCOPED_TRACE("commented");
test_engine_roundtrip_from_yaml(test_case, transformed_str);
}
}

View File

@@ -145,28 +145,32 @@ struct TransformToSourceBufferOrArena
struct EngineEvtTestCase
{
EngineEvtTestCase( std::string s , std::string ev) : test_case_flags( ), expected_error_location( ), parsed(s ), expected_emitted(std::move(s)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase( std::string p, std::string e, std::string ev) : test_case_flags( ), expected_error_location( ), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(TestCaseFlags_e tf, std::string p, std::string e, std::string ev) : test_case_flags(tf), expected_error_location( ), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(TestCaseFlags_e tf, std::string p , std::string ev) : test_case_flags(tf), expected_error_location( ), parsed(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase( Location linecol_, std::string p , std::string ev) : test_case_flags( ), expected_error_location(linecol_), parsed(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(TestCaseFlags_e tf, Location linecol_, std::string p, std::string e, std::string ev) : test_case_flags(tf), expected_error_location(linecol_), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(TestCaseFlags_e tf, Location linecol_, std::string p , std::string ev) : test_case_flags(tf), expected_error_location(linecol_), parsed(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase( std::string s , std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags( ), expected_error_location( ), parsed(s ), expected_emitted(std::move(s)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase( std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags( ), expected_error_location( ), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(TestCaseFlags_e tf, std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags(tf), expected_error_location( ), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(TestCaseFlags_e tf, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags(tf), expected_error_location( ), parsed(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase( Location linecol_, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags( ), expected_error_location(linecol_), parsed(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(TestCaseFlags_e tf, Location linecol_, std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags(tf), expected_error_location(linecol_), parsed(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(TestCaseFlags_e tf, Location linecol_, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : test_case_flags(tf), expected_error_location(linecol_), parsed( p), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
ParserOptions opts;
TestCaseFlags_e test_case_flags;
Location expected_error_location;
std::string parsed;
std::string yaml;
std::string expected_emitted;
std::string expected_events;
std::vector<extra::IntEventWithScalar> expected_ints;
bool expected_ints_enabled;
public:
EngineEvtTestCase(ParserOptions opts_, std::string s , std::string ev) : opts(opts_), test_case_flags( ), expected_error_location( ), yaml(s ), expected_emitted(std::move(s)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(ParserOptions opts_, std::string p, std::string e, std::string ev) : opts(opts_), test_case_flags( ), expected_error_location( ), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, std::string p, std::string e, std::string ev) : opts(opts_), test_case_flags(tf), expected_error_location( ), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, std::string p , std::string ev) : opts(opts_), test_case_flags(tf), expected_error_location( ), yaml(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) {}
EngineEvtTestCase(ParserOptions opts_, Location linecol_, std::string p , std::string ev) : opts(opts_), test_case_flags( ), expected_error_location(linecol_), yaml(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, Location linecol_, std::string p, std::string e, std::string ev) : opts(opts_), test_case_flags(tf), expected_error_location(linecol_), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, Location linecol_, std::string p , std::string ev) : opts(opts_), test_case_flags(tf), expected_error_location(linecol_), yaml(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(), expected_ints_enabled(false) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(ParserOptions opts_, std::string s , std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags( ), expected_error_location( ), yaml(s ), expected_emitted(std::move(s)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(ParserOptions opts_, std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags( ), expected_error_location( ), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags(tf), expected_error_location( ), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags(tf), expected_error_location( ), yaml(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) {}
EngineEvtTestCase(ParserOptions opts_, Location linecol_, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags( ), expected_error_location(linecol_), yaml(p ), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, Location linecol_, std::string p, std::string e, std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags(tf), expected_error_location(linecol_), yaml(std::move(p)), expected_emitted(std::move(e)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
EngineEvtTestCase(ParserOptions opts_, TestCaseFlags_e tf, Location linecol_, std::string p , std::string ev, std::vector<extra::IntEventWithScalar> ints) : opts(opts_), test_case_flags(tf), expected_error_location(linecol_), yaml( p), expected_emitted(std::move(p)), expected_events(std::move(ev)), expected_ints(std::move(ints)), expected_ints_enabled(true) { _RYML_ASSERT_BASIC(linecol_); }
};
@@ -174,7 +178,7 @@ struct EngineEvtTestCase
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_testsuite_from_events(const EngineEvtTestCase& tc)
C4_NO_INLINE void test_engine_testsuite_from_events(const EngineEvtTestCase& test_case)
{
extra::EventHandlerTestSuite::EventSink sink;
extra::EventHandlerTestSuite handler(&sink);
@@ -183,7 +187,7 @@ C4_NO_INLINE void test_engine_testsuite_from_events(const EngineEvtTestCase& tc)
event_producer(handler);
csubstr result = sink;
_c4dbgpf("~~~\n{}~~~\n", result);
EXPECT_EQ(std::string(result.str, result.len), tc.expected_events);
EXPECT_EQ(std::string(result.str, result.len), test_case.expected_events);
}
template<template<class> class EventProducerFn>
@@ -198,13 +202,13 @@ C4_NO_INLINE void test_engine_error_testsuite_from_events(const EngineEvtTestCas
//-----------------------------------------------------------------------------
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_ints_from_events(EngineEvtTestCase const& tc)
C4_NO_INLINE void test_engine_ints_from_events(EngineEvtTestCase const& test_case)
{
SCOPED_TRACE("ints_from_events");
using Helper = EventTransformer<extra::EventHandlerInts, TransformToSourceBufferOrArena<extra::EventHandlerInts>>;
Helper helper;
extra::EventHandlerInts &handler = helper.handler;
std::string src = tc.parsed;
std::string src = test_case.yaml;
std::string arena;
std::vector<int> ints((size_t)extra::estimate_events_ints_size(to_csubstr(src)));
arena.resize(src.size());
@@ -219,7 +223,7 @@ C4_NO_INLINE void test_engine_ints_from_events(EngineEvtTestCase const& tc)
ASSERT_GT(handler.required_size_arena(), (int)arena.size());
arena.resize(handler.required_size_arena());
// try again
src.assign(tc.parsed.begin(), tc.parsed.end());
src.assign(test_case.yaml.begin(), test_case.yaml.end());
helper.transformer.src = to_csubstr(src);
handler.reset(to_substr(src), to_substr(arena), ints.data(), (int)ints.size());
event_producer(helper);
@@ -233,19 +237,19 @@ C4_NO_INLINE void test_engine_ints_from_events(EngineEvtTestCase const& tc)
SCOPED_TRACE("test_invariants");
extra::test_events_ints_invariants(to_csubstr(src), to_csubstr(arena), ints.data(), (int)ints.size());
}
if(tc.expected_ints_enabled)
if(test_case.expected_ints_enabled)
{
SCOPED_TRACE("compare_ints");
extra::test_events_ints(tc.expected_ints.data(), tc.expected_ints.size(),
extra::test_events_ints(test_case.expected_ints.data(), test_case.expected_ints.size(),
ints.data(), ints.size(),
to_csubstr(tc.parsed),
to_csubstr(test_case.yaml),
to_csubstr(src),
to_csubstr(arena));
}
{
std::string actual_testsuite_events = extra::events_ints_to_testsuite<std::string>(to_csubstr(src), to_csubstr(arena), ints.data(), (int)ints.size());
_c4dbgpf("~~~\n{}~~~\n", actual_testsuite_events);
test_compare_events(to_csubstr(tc.expected_events),
test_compare_events(to_csubstr(test_case.expected_events),
to_csubstr(actual_testsuite_events),
/*ignore_doc_style*/false,
/*ignore_container_style*/false,
@@ -255,20 +259,21 @@ C4_NO_INLINE void test_engine_ints_from_events(EngineEvtTestCase const& tc)
}
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_error_ints_from_events(const EngineEvtTestCase& tc)
C4_NO_INLINE void test_engine_error_ints_from_events(const EngineEvtTestCase& test_case)
{
ExpectError::check_error_parse([&]{
test_engine_ints_from_events<EventProducerFn>(tc);
test_engine_ints_from_events<EventProducerFn>(test_case);
});
}
//-----------------------------------------------------------------------------
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_tree_from_events(EngineEvtTestCase const& tc)
C4_NO_INLINE void test_engine_tree_from_events(EngineEvtTestCase const& test_case)
{
if(tc.test_case_flags & HAS_CONTAINER_KEYS)
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
{
ExpectError::check_error_parse([&]{
Tree tree = {};
@@ -289,32 +294,74 @@ C4_NO_INLINE void test_engine_tree_from_events(EngineEvtTestCase const& tc)
#endif
std::string actual = emitrs_yaml<std::string>(tree);
_c4dbgpf("~~~\n{}~~~\n", actual);
EXPECT_EQ(tc.expected_emitted, actual);
EXPECT_EQ(test_case.expected_emitted, actual);
}
}
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_error_tree_from_events(const EngineEvtTestCase& tc)
C4_NO_INLINE void test_engine_error_tree_from_events(const EngineEvtTestCase& test_case)
{
ExpectError::check_error_parse([&]{
test_engine_tree_from_events<EventProducerFn>(tc);
test_engine_tree_from_events<EventProducerFn>(test_case);
});
}
//-----------------------------------------------------------------------------
template<template<class> class EventProducerFn>
C4_NO_INLINE void test_engine_roundtrip_from_events(EngineEvtTestCase const& test_case)
{
if(test_case.test_case_flags & HAS_CONTAINER_KEYS)
return;
SCOPED_TRACE("roundtrip_from_events");
Tree event_tree = {};
EventHandlerTree handler(&event_tree, event_tree.root_id());
EventProducerFn<EventHandlerTree> event_producer;
event_producer(handler);
{
SCOPED_TRACE("test_invariants_orig");
test_invariants(event_tree);
}
std::string emitted0 = emitrs_yaml<std::string>(event_tree);
EXPECT_EQ(test_case.expected_emitted, emitted0);
std::string copy = emitted0;
Tree after_roundtrip = parse_in_place(to_substr(copy), test_case.opts);
{
SCOPED_TRACE("test_invariants_after_roundtrip");
test_invariants(after_roundtrip);
}
{
SCOPED_TRACE("compare_trees");
test_compare(after_roundtrip, event_tree, "after_roundtrip", "event_tree");
}
std::string emitted1 = emitrs_yaml<std::string>(after_roundtrip);
EXPECT_EQ(test_case.expected_emitted, emitted1);
if(testing::Test::HasFailure())
{
printf("source: ~~~\n%.*s~~~\n", (int)test_case.yaml.size(), test_case.yaml.data());
print_tree("event_tree", event_tree);
printf("event_tree_emitted: ~~~\n%.*s~~~\n", (int)emitted0.size(), emitted0.data());
print_tree("after_roundtrip", after_roundtrip);
printf("after_roundtrip_emitted: ~~~\n%.*s~~~\n", (int)emitted1.size(), emitted1.data());
}
}
//-----------------------------------------------------------------------------
void test_engine_testsuite_from_yaml(EngineEvtTestCase const& yaml, std::string const& parsed_yaml, ParserOptions opts);
void test_engine_ints_from_yaml(EngineEvtTestCase const& yaml, std::string const& parsed_yaml, ParserOptions opts);
void test_engine_tree_from_yaml(EngineEvtTestCase const& yaml, std::string const& parsed_yaml, ParserOptions opts);
void test_engine_testsuite_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml);
void test_engine_ints_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml);
void test_engine_tree_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml);
void test_engine_roundtrip_from_yaml(EngineEvtTestCase const& test_case, std::string const& parsed_yaml);
inline void test_engine_testsuite_from_yaml(EngineEvtTestCase const& yaml, ParserOptions opts) { test_engine_testsuite_from_yaml(yaml, yaml.parsed, opts); }
inline void test_engine_ints_from_yaml(EngineEvtTestCase const& yaml, ParserOptions opts) { test_engine_ints_from_yaml(yaml, yaml.parsed, opts); }
inline void test_engine_tree_from_yaml(EngineEvtTestCase const& yaml, ParserOptions opts) { test_engine_tree_from_yaml(yaml, yaml.parsed, opts); }
inline void test_engine_testsuite_from_yaml(EngineEvtTestCase const& test_case) { test_engine_testsuite_from_yaml(test_case, test_case.yaml); }
inline void test_engine_ints_from_yaml(EngineEvtTestCase const& test_case) { test_engine_ints_from_yaml(test_case, test_case.yaml); }
inline void test_engine_tree_from_yaml(EngineEvtTestCase const& test_case) { test_engine_tree_from_yaml(test_case, test_case.yaml); }
inline void test_engine_roundtrip_from_yaml(EngineEvtTestCase const& test_case) { test_engine_roundtrip_from_yaml(test_case, test_case.yaml); }
void test_engine_testsuite_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts);
void test_engine_ints_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts);
void test_engine_tree_from_yaml_with_comments(EngineEvtTestCase const& yaml, ParserOptions opts);
void test_engine_testsuite_from_yaml_with_comments(EngineEvtTestCase const& test_case);
void test_engine_ints_from_yaml_with_comments(EngineEvtTestCase const& test_case);
void test_engine_tree_from_yaml_with_comments(EngineEvtTestCase const& test_case);
void test_engine_roundtrip_from_yaml_with_comments(EngineEvtTestCase const& test_case);
void test_expected_error_testsuite_from_yaml(std::string const& parsed_yaml, Location const& expected_error_location={});
void test_expected_error_ints_from_yaml(std::string const& parsed_yaml, Location const& expected_error_location={});
@@ -486,7 +533,7 @@ ENGINE_TEST_DEFINE_CASE(name) \
/* declare a parse engine test for the existing event handlers.
* The extra arguments are for the ctor of EngineEvtTestCase */
#define ENGINE_TEST_(name, opts, ...) \
#define ENGINE_TEST_(name, ...) \
\
\
ENGINE_TEST_DECLARE_CASE(name, __VA_ARGS__) \
@@ -517,6 +564,15 @@ TEST(name, tree_from_events) \
auto const &tc = test_case_##name; \
test_engine_tree_from_events<name>(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
TEST(name, roundtrip_from_events) \
{ \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_roundtrip_from_events"); \
auto const &tc = test_case_##name; \
test_engine_roundtrip_from_events<name>(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
\
@@ -526,7 +582,7 @@ TEST(name, testsuite_from_yaml) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_testsuite_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_testsuite_from_yaml(tc, opts); \
test_engine_testsuite_from_yaml(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
@@ -535,7 +591,7 @@ TEST(name, ints_from_yaml) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_event_ints_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_ints_from_yaml(tc, opts); \
test_engine_ints_from_yaml(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
@@ -544,7 +600,16 @@ TEST(name, tree_from_yaml) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_tree_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_tree_from_yaml(tc, opts); \
test_engine_tree_from_yaml(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
TEST(name, roundtrip_from_yaml) \
{ \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_tree_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_roundtrip_from_yaml(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
@@ -555,7 +620,7 @@ TEST(name, testsuite_from_yaml_with_comments) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_testsuite_from_yaml_with_comments"); \
auto const &tc = test_case_##name; \
test_engine_testsuite_from_yaml_with_comments(tc, opts); \
test_engine_testsuite_from_yaml_with_comments(tc); \
} \
\
TEST(name, ints_from_yaml_with_comments) \
@@ -563,7 +628,7 @@ TEST(name, ints_from_yaml_with_comments) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_ints_from_yaml_with_comments"); \
auto const &tc = test_case_##name; \
test_engine_ints_from_yaml_with_comments(tc, opts); \
test_engine_ints_from_yaml_with_comments(tc); \
} \
\
TEST(name, tree_from_yaml_with_comments) \
@@ -571,7 +636,16 @@ TEST(name, tree_from_yaml_with_comments) \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_tree_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_tree_from_yaml_with_comments(tc, opts); \
test_engine_tree_from_yaml_with_comments(tc); \
_RYML_SHOWFILELINE(name); \
} \
\
TEST(name, roundtrip_from_yaml_with_comments) \
{ \
_RYML_SHOWFILELINE(name); \
SCOPED_TRACE(#name "_roundtrip_from_yaml"); \
auto const &tc = test_case_##name; \
test_engine_roundtrip_from_yaml_with_comments(tc); \
_RYML_SHOWFILELINE(name); \
} \
\