diff --git a/changelog/current.md b/changelog/current.md index f8025b33..d3436512 100644 --- a/changelog/current.md +++ b/changelog/current.md @@ -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 + ``` diff --git a/samples/quickstart.cpp b/samples/quickstart.cpp index 06a25ae0..4fd599a4 100644 --- a/samples/quickstart.cpp +++ b/samples/quickstart.cpp @@ -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(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(tree, noindent) == - R"({ -map: { -seq: [ -0, -1, -2, -3, -[ -40, -41 -] -] -} -} -)"); + CHECK(ryml::emitrs_yaml(tree, noindent) == yaml_not_indented); } } diff --git a/src/c4/yml/detail/dbgprint.hpp b/src/c4/yml/detail/dbgprint.hpp index 04ef42ff..7c895639 100644 --- a/src/c4/yml/detail/dbgprint.hpp +++ b/src/c4/yml/detail/dbgprint.hpp @@ -57,8 +57,6 @@ #endif -#define RYML_LOGBUF_SIZE_MAX RYML_ERRMSG_SIZE - #include C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wattributes") diff --git a/src/c4/yml/emit.def.hpp b/src/c4/yml/emit.def.hpp index 16b4f105..52c0b1a9 100644 --- a/src/c4/yml/emit.def.hpp +++ b/src/c4/yml/emit.def.hpp @@ -41,6 +41,7 @@ substr Emitter::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::_write_scalar_json_dquo(csubstr s) _write('"'); } +/** @endcond */ + } // namespace yml } // namespace c4 diff --git a/src/c4/yml/emit.hpp b/src/c4/yml/emit.hpp index 4f738c23..ad08ac18 100644 --- a/src/c4/yml/emit.hpp +++ b/src/c4/yml/emit.hpp @@ -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 */ }; diff --git a/src/c4/yml/event_handler_tree.hpp b/src/c4/yml/event_handler_tree.hpp index 7b3c6957..e02ec788 100644 --- a/src/c4/yml/event_handler_tree.hpp +++ b/src/c4/yml/event_handler_tree.hpp @@ -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; } diff --git a/src/c4/yml/node_type.hpp b/src/c4/yml/node_type.hpp index f160cef7..9c8f4811 100644 --- a/src/c4/yml/node_type.hpp +++ b/src/c4/yml/node_type.hpp @@ -270,7 +270,6 @@ RYML_EXPORT inline C4_NO_INLINE bool scalar_is_null(csubstr s) noexcept /** @} */ - /** @} */ } // namespace yml diff --git a/src/c4/yml/parse_engine.def.hpp b/src/c4/yml/parse_engine.def.hpp index 44959722..cab45ec6 100644 --- a/src/c4/yml/parse_engine.def.hpp +++ b/src/c4/yml/parse_engine.def.hpp @@ -803,6 +803,7 @@ bool ParseEngine::_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::_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::_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); diff --git a/src/c4/yml/parser_state.hpp b/src/c4/yml/parser_state.hpp index aaeee4c8..13942369 100644 --- a/src/c4/yml/parser_state.hpp +++ b/src/c4/yml/parser_state.hpp @@ -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. diff --git a/src/c4/yml/tree.hpp b/src/c4/yml/tree.hpp index 900b6e18..197d9500 100644 --- a/src/c4/yml/tree.hpp +++ b/src/c4/yml/tree.hpp @@ -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 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 43e55060..94c2e8fa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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() #------------------------------------------------------------------------- diff --git a/test/test_engine_1_doc.cpp b/test/test_engine_1_doc.cpp index a802b5ff..f6b93e34 100644 --- a/test/test_engine_1_doc.cpp +++ b/test/test_engine_1_doc.cpp @@ -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()); } diff --git a/test/test_engine_2_seq.cpp b/test/test_engine_2_seq.cpp index dd67e4e9..f987577a 100644 --- a/test/test_engine_2_seq.cpp +++ b/test/test_engine_2_seq.cpp @@ -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(); diff --git a/test/test_engine_3_map.cpp b/test/test_engine_3_map.cpp index 213ea4b5..d382469c 100644 --- a/test/test_engine_3_map.cpp +++ b/test/test_engine_3_map.cpp @@ -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"); diff --git a/test/test_engine_5_tag.cpp b/test/test_engine_5_tag.cpp index f1f5ce4b..933c0c05 100644 --- a/test/test_engine_5_tag.cpp +++ b/test/test_engine_5_tag.cpp @@ -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()); } diff --git a/test/test_engine_7_seqimap.cpp b/test/test_engine_7_seqimap.cpp index bb007558..7a7e3697 100644 --- a/test/test_engine_7_seqimap.cpp +++ b/test/test_engine_7_seqimap.cpp @@ -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()); diff --git a/test/test_lib/test_case.cpp b/test/test_lib/test_case.cpp index 42985d08..2c3d9100 100644 --- a/test/test_lib/test_case.cpp +++ b/test/test_lib/test_case.cpp @@ -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) diff --git a/test/test_lib/test_case.hpp b/test/test_lib/test_case.hpp index c5f4b98d..e6bb4176 100644 --- a/test/test_lib/test_case.hpp +++ b/test/test_lib/test_case.hpp @@ -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); diff --git a/test/test_lib/test_engine.cpp b/test/test_lib/test_engine.cpp index 22cbad76..cabf7065 100644 --- a/test/test_lib/test_engine.cpp +++ b/test/test_lib/test_engine.cpp @@ -10,7 +10,7 @@ namespace yml { namespace { // inject comments on every line -std::vector inject_comments(std::string const& src_) +std::vector inject_comments_in_src(std::string const& src_) { std::vector 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 parser(&handler, opts); + ParseEngine 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 actual_evts(empty.size()); std::vector 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 arena(copy.size()); handler.reset(to_csubstr(copy), to_substr(arena), actual_evts.data(), (IntType)actual_evts.size()); - ParseEngine parser(&handler, opts); + ParseEngine 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(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 parser(&handler, opts); + ParseEngine 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(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(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(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); } } diff --git a/test/test_lib/test_engine.hpp b/test/test_lib/test_engine.hpp index 8c52cb9f..b6c6f5cf 100644 --- a/test/test_lib/test_engine.hpp +++ b/test/test_lib/test_engine.hpp @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 class EventProducerFn> @@ -198,13 +202,13 @@ C4_NO_INLINE void test_engine_error_testsuite_from_events(const EngineEvtTestCas //----------------------------------------------------------------------------- template 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>; Helper helper; extra::EventHandlerInts &handler = helper.handler; - std::string src = tc.parsed; + std::string src = test_case.yaml; std::string arena; std::vector 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(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 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(tc); + test_engine_ints_from_events(test_case); }); } //----------------------------------------------------------------------------- + template 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(tree); _c4dbgpf("~~~\n{}~~~\n", actual); - EXPECT_EQ(tc.expected_emitted, actual); + EXPECT_EQ(test_case.expected_emitted, actual); } } template 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(tc); + test_engine_tree_from_events(test_case); }); } +//----------------------------------------------------------------------------- +template 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 event_producer; + event_producer(handler); + { + SCOPED_TRACE("test_invariants_orig"); + test_invariants(event_tree); + } + std::string emitted0 = emitrs_yaml(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(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(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(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); \ } \ \