Skip to content

Commit

Permalink
minor changes in documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Jun 2, 2024
1 parent fbb3a16 commit 16a0cbf
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 65 deletions.
55 changes: 32 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -786,44 +786,53 @@ improve.
### Test suite status

As part of its CI testing, ryml uses the [YAML test
suite](https://github.com/yaml/yaml-test-suite). This is an extensive
set of reference cases covering the full YAML spec. Each of these
cases have several subparts:
suite](https://github.com/yaml/yaml-test-suite). (See also the test
suite results at
[https://matrix.yaml.info/](https://matrix.yaml.info/), but be aware
that the results there may be using an older version of ryml.) This is
an extensive and merciless set of reference cases covering the full
YAML spec. Each of these cases has several subparts:
* `in-yaml`: mildly, plainly or extremely difficult-to-parse YAML
* `in-json`: equivalent JSON (where possible/meaningful)
* `out-yaml`: equivalent standard YAML
* `emit-yaml`: equivalent standard YAML
* `events`: reference results (ie, expected tree)

When testing, ryml parses each of the 4 yaml/json parts, then emits
the parsed tree, then parses the emitted result and verifies that
emission is idempotent, ie that the emitted result is semantically the
same as its input without any loss of information. To ensure
consistency, this happens over four levels of parse/emission
pairs. And to ensure correctness, each of the stages is compared
against the `events` spec from the test, which constitutes the
reference. The tests also check for equality between the reference
* `events`: reference events according to the YAML standard

When testing, ryml parses each of the yaml/json parts, then emits the
parsed tree, then parses the emitted result and verifies that emission
is idempotent, ie that the round trip emitted result is semantically
the same as its input without any loss of information.

To ensure consistency, this happens over four successive levels of
parse->emit round trips. And to ensure correctness, each of the stages
is compared against the `events` spec from the test, which constitutes
the reference. The tests also check for equality between the reference
events in the test case and the events emitted by ryml from the data
tree parsed from the test case input. All of this is then carried out
combining several variations: both unix `\n` vs windows `\r\n` line
with several variations: both unix `\n` vs windows `\r\n` line
endings, emitting to string, file or streams, which results in ~250
tests per case part. With multiple parts per case and ~400 reference
tests per case part.

With multiple parts per case and ~400 reference
cases in the test suite, this makes over several hundred thousand
individual tests to which ryml is subjected, which are added to the
unit tests in ryml, which also employ the same extensive
combinatorial approach.
unit tests in ryml, which also employ the same extensive combinatorial
approach.

Also, note that in [their own words](http://matrix.yaml.io/), the
Also, note that in [their own words](http://matrix.yaml.info/), the
tests from the YAML test suite *contain a lot of edge cases that don't
play such an important role in real world examples*. And yet, despite
the extreme focus of the test suite, currently ryml only fails a minor
fraction of the test cases, mostly related with the deliberate
limitations noted above. Other than those limitations, by far the main
issue with ryml is that several standard-mandated parse errors fail to
materialize. For the up-to-date list of ryml failures in the
test-suite, refer to the [list of known
limitations noted above.

Other than those limitations, by far the main issue with ryml is that
several standard-mandated parse errors fail to materialize (this will
be addressed in the coming releases). For the up-to-date list of ryml
failures in the test-suite, refer to the [list of known
exceptions](test/test_suite/test_suite_parts.cpp) from ryml's test
suite runner, which is used as part of ryml's CI process.
suite runner, which is used as part of ryml's CI setup.



------
Expand Down
66 changes: 38 additions & 28 deletions doc/sphinx_yaml_standard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,42 +83,52 @@ generally a source of problems; this is good practice anyway.
YAML test suite
---------------

As part of its CI testing, ryml uses the `YAML test
suite <https://github.com/yaml/yaml-test-suite>`__. This is an extensive
set of reference cases covering the full YAML spec. Each of these cases
have several subparts:

As part of its CI testing, ryml uses the `YAML test suite <https://github.com/yaml/yaml-test-suite>`__. This is
an extensive and merciless set of reference cases covering the full
YAML spec. Each of these cases has several subparts:
- ``in-yaml``: mildly, plainly or extremely difficult-to-parse YAML
- ``in-json``: equivalent JSON (where possible/meaningful)
- ``out-yaml``: equivalent standard YAML
- ``emit-yaml``: equivalent standard YAML
- ``events``: reference results (ie, expected tree)
- ``events``: reference events according to the YAML standard

.. note::

When testing, ryml parses each of the 4 yaml/json parts, then emits the
See the test suite results at
`https://matrix.yaml.info/ <https://matrix.yaml.info/>`__,
but be aware that the results there may be using an older
version of ryml.

When testing, ryml parses each of the yaml/json parts, then emits the
parsed tree, then parses the emitted result and verifies that emission
is idempotent, ie that the emitted result is semantically the same as
its input without any loss of information. To ensure consistency, this
happens over four levels of parse/emission pairs. And to ensure
correctness, each of the stages is compared against the ``events`` spec
from the test, which constitutes the reference. The tests also check for
equality between the reference events in the test case and the events
emitted by ryml from the data tree parsed from the test case input. All
of this is then carried out combining several variations: both unix
``\n`` vs windows ``\r\n`` line endings, emitting to string, file or
streams, which results in ~250 tests per case part. With multiple parts
per case and ~400 reference cases in the test suite, this makes over
several hundred thousand individual tests to which ryml is subjected,
which are added to the unit tests in ryml, which also employ the same
extensive combinatorial approach.
is idempotent, ie that the round trip emitted result is semantically
the same as its input without any loss of information.

To ensure consistency, this happens over four successive levels of
parse->emit round trips. And to ensure correctness, each of the stages
is compared against the ``events`` spec from the test, which constitutes
the reference. The tests also check for equality between the reference
events in the test case and the events emitted by ryml from the data
tree parsed from the test case input. All of this is then carried out
with several variations: both unix ``\n`` vs windows ``\r\n`` line
endings, emitting to string, file or streams, which results in ~250
tests per case part.

With multiple parts per case and ~400 reference
cases in the test suite, this makes over several hundred thousand
individual tests to which ryml is subjected, which are added to the
unit tests in ryml, which also employ the same extensive combinatorial
approach.

Also, note that in `their own words <http://matrix.yaml.info/>`__, the
tests from the YAML test suite *contain a lot of edge cases that dont
tests from the YAML test suite *contain a lot of edge cases that don't
play such an important role in real world examples*. And yet, despite
the extreme focus of the test suite, currently ryml only fails a minor
fraction of the test cases, mostly related with the deliberate
limitations noted above. Other than those limitations, by far the main
issue with ryml is that several standard-mandated parse errors fail to
materialize. For the up-to-date list of ryml failures in the test-suite,
refer to the `list of known
exceptions <https://github.com/biojppm/rapidyaml/blob/v0.6.0/test/test_suite/test_suite_parts.cpp>`__ from ryml’s test
suite runner, which is used as part of ryml’s CI process.
limitations noted above.

Other than those limitations, by far the main issue with ryml is that
several standard-mandated parse errors fail to materialize (this will
be addressed in the coming releases). For the up-to-date list of ryml
failures in the test-suite, refer to the `list of known exceptions <test/test_suite/test_suite_parts.cpp>`__ from ryml's test
suite runner, which is used as part of ryml's CI setup.
32 changes: 18 additions & 14 deletions samples/quickstart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <iostream>
#include <sstream>
#include <vector>
#include <array>
#include <map>
#ifdef C4_EXCEPTIONS
#include <stdexcept>
Expand Down Expand Up @@ -543,12 +542,14 @@ john: doe)";
// The downside, of course, is that when you are not sure, release
// builds may be doing something crazy.
//
// So you can override this behavior and enable/disable
// assertions, by defining the macro RYML_USE_ASSERT to a proper
// value (see c4/yml/common.hpp).
// So in that case, you can either use the appropriate ryml
// predicates to check your intent (as in the examples above), or
// you can override this behavior and enable/disable assertions,
// by defining the macro RYML_USE_ASSERT to a proper value (see
// c4/yml/common.hpp).
//
// Also, to be clear, this does not apply to parse errors
// happening when the YAML is parsed. Checking for these errors is
// occurring when the YAML is parsed. Checking for these errors is
// always enabled and cannot be switched off.


Expand Down Expand Up @@ -578,19 +579,19 @@ john: doe)";
// node. It can be used to read from the node, but not write to it
// or modify the hierarchy of the node. If any modification is
// desired then a NodeRef must be used instead:
ryml::NodeRef wroot = tree.rootref();
ryml::NodeRef wroot = tree.rootref(); // writeable root

// operator= assigns an existing string to the receiving node.
// The contents are NOT copied, and this pointer will be in effect
// until the tree goes out of scope! So BEWARE to only assign from
// strings outliving the tree.
// The contents are NOT copied, and the string pointer will be in
// effect until the tree goes out of scope! So BEWARE to only
// assign from strings outliving the tree.
wroot["foo"] = "says you";
wroot["bar"][0] = "-2";
wroot["bar"][1] = "-3";
wroot["john"] = "ron";
// Now the tree is _pointing_ at the memory of the strings above.
// In this case it is OK because those are static strings and will
// outlive the tree.
// In this case it is OK because those are static strings, located
// in the executable's static section, and will outlive the tree.
CHECK(root["foo"].val() == "says you");
CHECK(root["bar"][0].val() == "-2");
CHECK(root["bar"][1].val() == "-3");
Expand All @@ -602,9 +603,12 @@ john: doe)";
// }
// CHECK(root["john"] == "dangling"); // CRASH! the string was deallocated

// operator<< first serializes the input to the tree's arena, then
// assigns the serialized string to the receiving node. This avoids
// constraints with the lifetime, since the arena lives with the tree.
// operator<<: for cases where the lifetime of the string is
// problematic WRT the tree, you can create and save a string in
// the tree using operator<<. It first serializes values to a
// string arena owned by the tree, then assigns the serialized
// string to the receiving node. This avoids constraints with the
// lifetime, since the arena lives with the tree.
CHECK(tree.arena().empty());
wroot["foo"] << "says who"; // requires to_chars(). see serialization samples below.
wroot["bar"][0] << 20;
Expand Down

0 comments on commit 16a0cbf

Please sign in to comment.