From eaee939acaad23a1628c2690d79d6f1eec2ae09f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 11:25:51 -0400 Subject: [PATCH 01/10] doc: add Antora scaffolding First step of the QuickBook -> Antora + MrDocs port. Adds the component descriptor, a local playbook, the npm dependency set and the build script, all modelled on libs/openmethod/doc. MrDocs is not wired up yet: the ext.cpp-reference stanza in antora.yml stays commented out until doc/mrdocs.yml exists. doc/html/ becomes Antora's output directory, so its two tracked inputs move out: images/ to modules/ROOT/images/, and boostbook.css is dropped along with the BoostBook stylesheet it served. build_antora.sh carries one addition over openmethod's: Antora's git backend requires /.git to be a directory, and inside a Boost superproject checkout libs/test is a submodule whose .git is a file. When that is detected, an equivalent playbook rooted at the superproject is derived. A standalone clone, which is what CI checks out, is unaffected. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 2 +- doc/.gitignore | 7 + doc/antora.yml | 49 + doc/build_antora.sh | 137 + doc/html/boostbook.css | 745 ------ doc/local-playbook.yml | 58 + .../ROOT}/images/boost.test.logo.png | Bin .../images/boost_runtime_list_content.png | Bin .../images/boost_runtime_list_content.svg | 0 .../ROOT}/images/class-hier.jpg | Bin doc/{html => modules/ROOT}/images/level.png | Bin .../ROOT}/images/post_build_event.jpg | Bin .../ROOT}/images/post_build_out.jpg | Bin .../ROOT}/images/run_args.jpg | Bin doc/modules/ROOT/nav.adoc | 1 + doc/modules/ROOT/pages/index.adoc | 5 + doc/package-lock.json | 2313 +++++++++++++++++ doc/package.json | 16 + doc/refresh_mrdocs_cache.sh | 96 + 19 files changed, 2683 insertions(+), 746 deletions(-) create mode 100644 doc/.gitignore create mode 100644 doc/antora.yml create mode 100755 doc/build_antora.sh delete mode 100644 doc/html/boostbook.css create mode 100644 doc/local-playbook.yml rename doc/{html => modules/ROOT}/images/boost.test.logo.png (100%) rename doc/{html => modules/ROOT}/images/boost_runtime_list_content.png (100%) rename doc/{html => modules/ROOT}/images/boost_runtime_list_content.svg (100%) rename doc/{html => modules/ROOT}/images/class-hier.jpg (100%) rename doc/{html => modules/ROOT}/images/level.png (100%) rename doc/{html => modules/ROOT}/images/post_build_event.jpg (100%) rename doc/{html => modules/ROOT}/images/post_build_out.jpg (100%) rename doc/{html => modules/ROOT}/images/run_args.jpg (100%) create mode 100644 doc/modules/ROOT/nav.adoc create mode 100644 doc/modules/ROOT/pages/index.adoc create mode 100644 doc/package-lock.json create mode 100644 doc/package.json create mode 100755 doc/refresh_mrdocs_cache.sh diff --git a/README.md b/README.md index fd191d35b0..b4acfac6a8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![boosttest logo](doc/html/images/boost.test.logo.png) +![boosttest logo](doc/modules/ROOT/images/boost.test.logo.png) # What is Boost.Test? Boost.Test is a C++11/14/17 unit testing library, available on a wide range of platforms and compilers. diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000000..e675fe9019 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,7 @@ +html/ +node_modules/ +build/ +reference-output/ +antora.log +.superproject-playbook.yml +mrdocs.yml.bak diff --git a/doc/antora.yml b/doc/antora.yml new file mode 100644 index 0000000000..c987f2c0fc --- /dev/null +++ b/doc/antora.yml @@ -0,0 +1,49 @@ +# +# Copyright (c) 2003 Boost.Test contributors +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/test +# + +name: test +title: Boost.Test +version: ~ +start_page: index.adoc + +asciidoc: + attributes: + source-language: cpp@ + table-caption: false + # Base of the links to header sources. build_antora.sh overrides this with + # the exact commit when it can determine one; this is the fallback for + # builds that cannot, such as a local preview. + base-url: https://github.com/boostorg/test/blob/master + # Issue trackers referenced from the change log. + trac-url: https://svn.boost.org/trac/boost/ticket + pr-url: https://github.com/boostorg/test/pull + issue-url: https://github.com/boostorg/test/issues + # >>> BEGIN GENERATED ATTRIBUTES (doc/tools/qbk2adoc.py) <<< + # The QuickBook [def] macros were mostly link aliases into the reference + # chapter. They are kept as attributes so a reference page can be renamed + # in one place instead of at ~2000 call sites. + # >>> END GENERATED ATTRIBUTES <<< + +nav: + - modules/ROOT/nav.adoc + +ext: + # Re-enabled once doc/mrdocs.yml, doc/CMakeLists.txt and doc/mrdocs.cpp land. + # Commenting this out is also the fast inner loop when editing prose: it skips + # MrDocs entirely. + # cpp-reference: + # config: doc/mrdocs.yml + cpp-tagfiles: + using-namespaces: + - boost::unit_test + - boost::unit_test::data + - boost::unit_test::data::monomorphic + - boost::unit_test::framework + - boost::test_tools + - boost::debug diff --git a/doc/build_antora.sh b/doc/build_antora.sh new file mode 100755 index 0000000000..f550f0b1b4 --- /dev/null +++ b/doc/build_antora.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# +# Copyright (c) 2003 Boost.Test contributors +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/test +# + +set -ex + +if [ $# -eq 0 ] + then + echo "No playbook supplied, using default playbook" + PLAYBOOK="local-playbook.yml" + else + PLAYBOOK=$1 +fi + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd "$SCRIPT_DIR" + +if [ -z "${BOOST_SRC_DIR:-}" ]; then + CANDIDATE=$( cd "$SCRIPT_DIR/../../.." 2>/dev/null && pwd ) + if [ -n "$CANDIDATE" ]; then + BOOST_SRC_DIR_IS_VALID=ON + for F in "CMakeLists.txt" "Jamroot" "boost-build.jam" "bootstrap.sh" "libs"; do + if [ ! -e "$CANDIDATE/$F" ]; then + BOOST_SRC_DIR_IS_VALID=OFF + break + fi + done + if [ "$BOOST_SRC_DIR_IS_VALID" = "ON" ]; then + export BOOST_SRC_DIR="$CANDIDATE" + echo "Using BOOST_SRC_DIR=$BOOST_SRC_DIR" + fi + fi +fi + +BRANCH=master + +if [ -n "${BOOST_SRC_DIR:-}" ]; then + if [ -n "${CIRCLE_REPOSITORY_URL:-}" ]; then + if [[ "$CIRCLE_REPOSITORY_URL" =~ boostorg/boost(\.git)?$ ]]; then + LIB="$(basename "$(dirname "$SCRIPT_DIR")")" + REPOSITORY="boostorg/${LIB}" + BRANCH=$(git -C "$BOOST_SRC_DIR" rev-parse --abbrev-ref HEAD) + else + ACCOUNT="${CIRCLE_REPOSITORY_URL#*:}" + ACCOUNT="${ACCOUNT%%/*}" + LIB=$(basename "$(git rev-parse --show-toplevel)") + REPOSITORY="${ACCOUNT}/${LIB}" + fi + SHA=$(git -C "$BOOST_SRC_DIR/libs" ls-tree HEAD | grep -w test | awk '{print $3}') + elif [ -n "${GITHUB_REPOSITORY:-}" ]; then + REPOSITORY="${GITHUB_REPOSITORY}" + SHA="${GITHUB_SHA}" + fi +fi + +cd "$SCRIPT_DIR" + +if [ -n "${REPOSITORY}" ] && [ -n "${SHA}" ]; then + BASE_URL="https://github.com/${REPOSITORY}/blob/${SHA}" + echo "Setting base-url to $BASE_URL" + if [ -f mrdocs.yml ]; then + cp mrdocs.yml mrdocs.yml.bak + perl -i -pe 's{^\s*base-url:.*$}{base-url: '"$BASE_URL/"'}' mrdocs.yml + fi +else + echo "REPOSITORY or SHA not set; skipping base-url modification" +fi + +# Antora's git backend requires /.git to be a directory. Inside +# a Boost superproject checkout libs/test is a submodule, so its .git is a file +# and Antora refuses the source. Derive an equivalent playbook rooted at the +# superproject in that case. A standalone clone (which is what CI checks out) +# takes neither branch and uses the playbook as written. +if [ -f "$SCRIPT_DIR/../.git" ]; then + if [ -n "${BOOST_SRC_DIR:-}" ] && [ -d "$BOOST_SRC_DIR/.git" ]; then + DERIVED_PLAYBOOK=".superproject-playbook.yml" + REL_START_PATH="${SCRIPT_DIR#"$BOOST_SRC_DIR"/}" + echo "libs/test is a submodule; deriving $DERIVED_PLAYBOOK rooted at $BOOST_SRC_DIR" + perl -pe "s{^(\s*)- url: \.\.\s*\$}{\$1- url: $BOOST_SRC_DIR\n}; + s{^(\s*)start_path: doc\s*\$}{\$1start_path: $REL_START_PATH\n}" \ + "$PLAYBOOK" > "$DERIVED_PLAYBOOK" + PLAYBOOK="$DERIVED_PLAYBOOK" + else + echo "WARNING: libs/test/.git is a file (submodule) and no usable BOOST_SRC_DIR" >&2 + echo " was found; Antora will reject the content source." >&2 + fi +fi + +echo "Building documentation with Antora..." +echo "Installing npm dependencies..." +npm ci + +echo "Building docs in custom dir..." +PATH="$(pwd)/node_modules/.bin:${PATH}" +export PATH + +# The reference pages link each header to its source with `link:{base-url}/...`. +# Point that at the exact commit when we know it; otherwise antora.yml's +# fallback applies. A command-line attribute outranks the one in antora.yml. +ANTORA_ARGS=() +if [ -n "${BASE_URL:-}" ]; then + ANTORA_ARGS+=(--attribute "base-url=$BASE_URL") +fi + +# Antora exits 0 even when xrefs and includes fail to resolve. Make that fatal +# in CI, but keep local previews usable while pages are being worked on. +if [ -n "${CI:-}" ]; then + ANTORA_ARGS+=(--log-failure-level=warn) +fi + +npx antora --clean --fetch "$PLAYBOOK" "${ANTORA_ARGS[@]}" --stacktrace # --log-level all + +echo "Fixing links to non-mrdocs URIs..." +echo "BRANCH='${BRANCH:-}'" +echo "BASE_URL='${BASE_URL:-}'" + +for f in $(find html -name '*.html'); do + perl -i -pe "s{Boost.Test}{Boost.Test}g" "$f" +done + +if [ -n "${BASE_URL:-}" ]; then + if [ -f mrdocs.yml.bak ]; then + mv -f mrdocs.yml.bak mrdocs.yml + echo "Restored original mrdocs.yml" + else + echo "mrdocs.yml.bak not found; skipping restore" + fi +fi + +echo "Done" diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css deleted file mode 100644 index 86a6400eb5..0000000000 --- a/doc/html/boostbook.css +++ /dev/null @@ -1,745 +0,0 @@ -/*============================================================================= -Copyright (c) 2004 Joel de Guzman -http://spirit.sourceforge.net/ - -Copyright 2013 Niall Douglas additions for colors and alignment. -Copyright 2013 Paul A. Bristow additions for more colors and alignments. - -Distributed under the Boost Software License, Version 1.0. (See accompany- -ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ - -/*============================================================================= -Body defaults -=============================================================================*/ - - body - { - margin: 1em; - font-family: sans-serif; - } - -/*============================================================================= -Paragraphs -=============================================================================*/ - - p - { - text-align: left; - font-size: 10pt; - line-height: 1.15; - } - - .epigraph - { - text-align: right; - padding-left: 50%; - font-size: 110%; - font-family: Century Gothic; - font-style: italic; - font-weight: bold; - display: block; - } - -/*============================================================================= -Program listings -=============================================================================*/ - - /* Code on paragraphs */ - p tt.computeroutput - { - font-size: 9pt; - } - - pre.synopsis - { - font-size: 9pt; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - .programlisting, - .screen - { - font-size: 9pt; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - /* Program listings in tables don't get borders */ - td .programlisting, - td .screen - { - margin: 0pc 0pc 0pc 0pc; - padding: 0pc 0pc 0pc 0pc; - } - -/*============================================================================= -Headings -=============================================================================*/ - - h1, h2, h3, h4, h5, h6 - { - text-align: left; - margin: 1em 0em 0.5em 0em; - font-weight: bold; - } - - h1 { font-size: 140%; } - h2 { font-weight: bold; font-size: 140%; } - h3 { font-weight: bold; font-size: 130%; } - h4 { font-weight: bold; font-size: 120%; } - h5 { font-weight: normal; font-style: italic; font-size: 100%; } - h6 { font-weight: normal; font-style: italic; font-size: 90%; } - - /* Top page titles */ - title, - h1.title, - h2.title - h3.title, - h4.title, - h5.title, - h6.title, - .refentrytitle - { - font-weight: bold; - margin-bottom: 1pc; - } - - h1.title { font-size: 140% } - h2.title { font-size: 140% } - h3.title { font-size: 130% } - h4.title { font-size: 120% } - h5.title { font-size: 110% } - h6.title { font-size: 100% } - - .section h1 - { - margin: 0em 0em 0.5em 0em; - font-size: 140%; - } - - .section h2 { font-size: 140% } - .section h3 { font-size: 130% } - .section h4 { font-size: 120% } - .section h5 { font-size: 100% } - .section h6 { font-size: 80% } - - /* Code on titles */ - h1 tt.computeroutput { font-size: 140% } - h2 tt.computeroutput { font-size: 140% } - h3 tt.computeroutput { font-size: 130% } - h4 tt.computeroutput { font-size: 130% } - h5 tt.computeroutput { font-size: 130% } - h6 tt.computeroutput { font-size: 130% } - - -/*============================================================================= -Author -=============================================================================*/ - - h3.author - { - font-size: 100% - } - -/*============================================================================= -Lists -=============================================================================*/ - - li - { - font-size: 10pt; - line-height: 1.3; - } - - /* Unordered lists */ - ul - { - text-align: left; - } - - /* Ordered lists */ - ol - { - text-align: left; - } - -/*============================================================================= -Links -=============================================================================*/ - - a - { - text-decoration: none; /* no underline */ - } - - a:hover - { - text-decoration: underline; - } - -/*============================================================================= -Spirit style navigation -=============================================================================*/ - - .spirit-nav - { - text-align: right; - } - - .spirit-nav a - { - color: white; - padding-left: 0.5em; - } - - .spirit-nav img - { - border-width: 0px; - } - -/*============================================================================= -Copyright footer -=============================================================================*/ - .copyright-footer - { - text-align: right; - font-size: 70%; - } - - .copyright-footer p - { - text-align: right; - font-size: 80%; - } - -/*============================================================================= -Table of contents -=============================================================================*/ - - div.toc - { - margin: 1pc 4% 0pc 4%; - padding: 0.1pc 1pc 0.1pc 1pc; - font-size: 80%; - line-height: 1.15; - } - - .boost-toc - { - float: right; - padding: 0.5pc; - } - - /* Code on toc */ - .toc .computeroutput { font-size: 120% } - - /* No margin on nested menus */ - - .toc dl dl { margin: 0; } - -/*============================================================================= -Tables -=============================================================================*/ - - .table-title, - div.table p.title - { - margin-left: 4%; - padding-right: 0.5em; - padding-left: 0.5em; - } - - .informaltable table, - .table table - { - width: 92%; - margin-left: 4%; - margin-right: 4%; - } - - div.informaltable table, - div.table table - { - padding: 4px; - } - - /* Table Cells */ - div.informaltable table tr td, - div.table table tr td - { - padding: 0.5em; - text-align: left; - font-size: 9pt; - } - - div.informaltable table tr th, - div.table table tr th - { - padding: 0.5em 0.5em 0.5em 0.5em; - border: 1pt solid white; - font-size: 80%; - } - - table.simplelist - { - width: auto !important; - margin: 0em !important; - padding: 0em !important; - border: none !important; - } - table.simplelist td - { - margin: 0em !important; - padding: 0em !important; - text-align: left !important; - font-size: 9pt !important; - border: none !important; - } - -/*============================================================================= -Blurbs -=============================================================================*/ - - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - font-size: 9pt; /* A little bit smaller than the main text */ - line-height: 1.2; - display: block; - margin: 1pc 4% 0pc 4%; - padding: 0.5pc 0.5pc 0.5pc 0.5pc; - } - - p.blurb img - { - padding: 1pt; - } - -/*============================================================================= -Variable Lists -=============================================================================*/ - - div.variablelist - { - margin: 1em 0; - } - - /* Make the terms in definition lists bold */ - div.variablelist dl dt, - span.term - { - font-weight: bold; - font-size: 10pt; - } - - div.variablelist table tbody tr td - { - text-align: left; - vertical-align: top; - padding: 0em 2em 0em 0em; - font-size: 10pt; - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - - div.variablelist dl dt - { - margin-bottom: 0.2em; - } - - div.variablelist dl dd - { - margin: 0em 0em 0.5em 2em; - font-size: 10pt; - } - - div.variablelist table tbody tr td p, - div.variablelist dl dd p - { - margin: 0em 0em 0.5em 0em; - line-height: 1; - } - -/*============================================================================= -Misc -=============================================================================*/ - - /* Title of books and articles in bibliographies */ - span.title - { - font-style: italic; - } - - span.underline - { - text-decoration: underline; - } - - span.strikethrough - { - text-decoration: line-through; - } - - /* Copyright, Legal Notice */ - div div.legalnotice p - { - text-align: left - } - -/*============================================================================= -Colors -=============================================================================*/ - - @media screen - { - body { - background-color: #FFFFFF; - color: #000000; - } - - /* Syntax Highlighting */ - .keyword { color: #0000AA; } - .identifier { color: #000000; } - .special { color: #707070; } - .preprocessor { color: #402080; } - .char { color: teal; } - .comment { color: #800000; } - .string { color: teal; } - .number { color: teal; } - .white_bkd { background-color: #FFFFFF; } - .dk_grey_bkd { background-color: #999999; } - - /* Links */ - a, a .keyword, a .identifier, a .special, a .preprocessor - a .char, a .comment, a .string, a .number - { - color: #0082BF; - } - - a:visited, a:visited .keyword, a:visited .identifier, - a:visited .special, a:visited .preprocessor, a:visited .char, - a:visited .comment, a:visited .string, a:visited .number - { - color: #2DBBFF; - } - - h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, - h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, - h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited - { - text-decoration: none; /* no underline */ - color: #000000; - } - - /* Copyright, Legal Notice */ - .copyright - { - color: #666666; - font-size: small; - } - - div div.legalnotice p - { - color: #666666; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid #DCDCDC; - box-shadow: 4px 4px 2px #9D9D9D; - background-color: #EEEEF3; - } - - .programlisting, - .screen - { - border: 1px solid #DCDCDC; - background-color: #EEEEF3; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Blurbs */ - div.note, - div.tip, - div.important, - div.caution, - div.warning, - p.blurb - { - border: 1px solid #DCDCDC; - } - div.sidebar - { - border: 1px solid #DCDCDC; - box-shadow: 5px 5px 2px #9D9D9D; - background-color: #EEEEF3; - } - - /* Table of contents */ - div.toc, - div.toc-main - { - border: 1px solid #DCDCDC; - box-shadow: 5px 5px 2px #9D9D9D; - background-color: #EEEEF3; - margin-bottom: 10px; - } - - div.toc a:visited - { - color: #0082BF; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - background-color: #EEEEF3; - } - - div.informaltable table tr th, - div.table table tr th - { - background-color: #E3F9E4; - border: 1px solid #DCDCDC; - } - - .copyright-footer - { - color: #8F8F8F; - } - - /* Misc */ - span.highlight - { - color: #00A000; - } - } - - @media print - { - /* Links */ - a - { - color: black; - } - - a:visited - { - color: black; - } - - .spirit-nav - { - display: none; - } - - /* Program listing */ - pre.synopsis - { - border: 1px solid gray; - background-color: #EEEEF3; - } - - .programlisting, - .screen - { - border: 1px solid gray; - background-color: #EEEEF3; - } - - td .programlisting, - td .screen - { - border: 0px solid #DCDCDC; - } - - /* Table of contents */ - div.toc - { - border: 1px solid #DCDCDC; - box-shadow: 5px 5px 2px #9D9D9D; - background-color: #EEEEF3; - } - - /* Table of contents */ - div.toc-main - { - border: 1px solid #DCDCDC; - box-shadow: 5px 5px 2px #9D9D9D; - background-color: #EEEEF3; - } - - .informaltable table, - .table table - { - border: 1px solid #DCDCDC; - box-shadow: 4px 4px 2px #9D9D9D; - border-collapse: collapse; - background-color: #EEEEF3; - } - - /* Tables */ - div.informaltable table tr td, - div.table table tr td - { - border: 1px solid #DCDCDC; - background-color: #EEEEF3; - } - - div.informaltable table tr th, - div.table table tr th - { - border: 1px solid #DCDCDC; - background-color: #EEEEF3; - } - - table.simplelist tr td - { - border: none !important; - } - - /* Misc */ - span.highlight - { - font-weight: bold; - } - } - -/*============================================================================= -Images -=============================================================================*/ - - span.inlinemediaobject img - { - vertical-align: middle; - } - -/*============================================================================== -Super and Subscript: style so that line spacing isn't effected, see -http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341 -==============================================================================*/ - -sup, -sub { -height: 0; -line-height: 1; -vertical-align: baseline; -position: relative; - -} - -/* For internet explorer: */ - -* html sup, -* html sub { -vertical-align: bottom; -} - -sup { -bottom: 1ex; -} - -sub { -top: .5ex; -} - -/*============================================================================== -Indexes: pretty much the same as the TOC. -==============================================================================*/ - - .index - { - font-size: 80%; - padding-top: 0px; - padding-bottom: 0px; - margin-top: 0px; - margin-bottom: 0px; - margin-left: 0px; - } - - .index ul - { - padding-left: 3em; - } - - .index p - { - padding: 2px; - margin: 2px; - } - - .index-entry-level-0 - { - font-weight: bold; - } - - .index em - { - font-weight: bold; - } - - -/*============================================================================== -Alignment and coloring use 'role' feature, available from Quickbook 1.6 up. -Added from Niall Douglas for role color and alignment. -http://article.gmane.org/gmane.comp.lib.boost.devel/243318 -*/ - -/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */ -span.aligncenter -{ - display: inline-block; width: 100%; text-align: center; -} -span.alignright -{ - display: inline-block; width: 100%; text-align: right; -} -/* alignleft is the default. */ -span.alignleft -{ - display: inline-block; width: 100%; text-align: left; -} - -/* alignjustify stretches the word spacing so that each line has equal width -within a chosen fraction of page width (here arbitrarily 20%). -*Not* useful inside table items as the column width remains the total string width. -Nor very useful, except to temporarily restrict the width. -*/ -span.alignjustify -{ - display: inline-block; width: 20%; text-align: justify; -} - -/* Text colors. -Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords. -Quickbook Usage: [role red Some red text] - -*/ -span.red { inline-block; color: red; } -span.green { color: green; } -span.lime { color: #00FF00; } -span.blue { color: blue; } -span.navy { color: navy; } -span.yellow { color: yellow; } -span.magenta { color: magenta; } -span.indigo { color: #4B0082; } -span.cyan { color: cyan; } -span.purple { color: purple; } -span.gold { color: gold; } -span.silver { color: silver; } /* lighter gray */ -span.gray { color: #808080; } /* light gray */ diff --git a/doc/local-playbook.yml b/doc/local-playbook.yml new file mode 100644 index 0000000000..1e7d67cbb2 --- /dev/null +++ b/doc/local-playbook.yml @@ -0,0 +1,58 @@ +# +# Copyright (c) 2003 Boost.Test contributors +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/test +# + +# An antora playbook used for local development +# The playbook includes Boost.Test as its only component + +site: + title: Boost.Test + url: https://antora.cppalliance.org/develop/lib/doc + start_page: test::index.adoc + robots: allow + keys: + repo_url: 'https://github.com/boostorg/test' + +content: + sources: + - url: .. + start_path: doc + edit_url: 'https://github.com/boostorg/test/edit/develop/{path}' + +ui: + bundle: + url: https://github.com/boostorg/website-v2-docs/releases/download/ui-master/ui-bundle.zip + snapshot: true + +output: + dir: html + +antora: + extensions: + - require: '@antora/lunr-extension' # https://gitlab.com/antora/antora-lunr-extension + index_latest_only: true + - require: '@cppalliance/antora-cpp-tagfiles-extension' + cpp-tagfiles: + using-namespaces: + - 'boost::' + - require: '@cppalliance/antora-cpp-reference-extension' + dependencies: + - name: 'boost' + repo: 'https://github.com/boostorg/boost.git' + tag: 'develop' + variable: 'BOOST_SRC_DIR' + system-env: 'BOOST_SRC_DIR' + - require: '@cppalliance/antora-downloads-extension' + +asciidoc: + attributes: + # Enable pagination + page-pagination: '' + extensions: + - '@cppalliance/asciidoctor-boost-links' + - '@asciidoctor/tabs' diff --git a/doc/html/images/boost.test.logo.png b/doc/modules/ROOT/images/boost.test.logo.png similarity index 100% rename from doc/html/images/boost.test.logo.png rename to doc/modules/ROOT/images/boost.test.logo.png diff --git a/doc/html/images/boost_runtime_list_content.png b/doc/modules/ROOT/images/boost_runtime_list_content.png similarity index 100% rename from doc/html/images/boost_runtime_list_content.png rename to doc/modules/ROOT/images/boost_runtime_list_content.png diff --git a/doc/html/images/boost_runtime_list_content.svg b/doc/modules/ROOT/images/boost_runtime_list_content.svg similarity index 100% rename from doc/html/images/boost_runtime_list_content.svg rename to doc/modules/ROOT/images/boost_runtime_list_content.svg diff --git a/doc/html/images/class-hier.jpg b/doc/modules/ROOT/images/class-hier.jpg similarity index 100% rename from doc/html/images/class-hier.jpg rename to doc/modules/ROOT/images/class-hier.jpg diff --git a/doc/html/images/level.png b/doc/modules/ROOT/images/level.png similarity index 100% rename from doc/html/images/level.png rename to doc/modules/ROOT/images/level.png diff --git a/doc/html/images/post_build_event.jpg b/doc/modules/ROOT/images/post_build_event.jpg similarity index 100% rename from doc/html/images/post_build_event.jpg rename to doc/modules/ROOT/images/post_build_event.jpg diff --git a/doc/html/images/post_build_out.jpg b/doc/modules/ROOT/images/post_build_out.jpg similarity index 100% rename from doc/html/images/post_build_out.jpg rename to doc/modules/ROOT/images/post_build_out.jpg diff --git a/doc/html/images/run_args.jpg b/doc/modules/ROOT/images/run_args.jpg similarity index 100% rename from doc/html/images/run_args.jpg rename to doc/modules/ROOT/images/run_args.jpg diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc new file mode 100644 index 0000000000..3d924122c1 --- /dev/null +++ b/doc/modules/ROOT/nav.adoc @@ -0,0 +1 @@ +* xref:index.adoc[Introduction] diff --git a/doc/modules/ROOT/pages/index.adoc b/doc/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000000..5381f71673 --- /dev/null +++ b/doc/modules/ROOT/pages/index.adoc @@ -0,0 +1,5 @@ += Boost.Test + +The Boost Test Library provides a matched set of components for writing test +programs, organizing tests into test cases and test suites, and controlling +their runtime execution. diff --git a/doc/package-lock.json b/doc/package-lock.json new file mode 100644 index 0000000000..fed8a0e1c3 --- /dev/null +++ b/doc/package-lock.json @@ -0,0 +1,2313 @@ +{ + "name": "doc", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@antora/expand-path-helper": "^3.0.0", + "@antora/lunr-extension": "^1.0.0-alpha.12", + "@asciidoctor/tabs": "^1.0.0-beta.6", + "@cppalliance/antora-cpp-reference-extension": "^0.1.0", + "@cppalliance/antora-cpp-tagfiles-extension": "^0.1.0", + "@cppalliance/antora-downloads-extension": "^0.0.2", + "@cppalliance/asciidoctor-boost-links": "^0.0.2" + }, + "devDependencies": { + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14", + "antora": "3.1.14" + } + }, + "node_modules/@antora/asciidoc-loader": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.14.tgz", + "integrity": "sha512-4xxisnoBFrlLNY6f3xZtyyfgm+tBLsqesTcEStfc8jtXUMYJ4b2DWIzo1vULmxvZ7yY5+Q7YqEvS5o6kIWAG0A==", + "dev": true, + "dependencies": { + "@antora/logger": "3.1.14", + "@antora/user-require-helper": "~3.0", + "@asciidoctor/core": "~2.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/cli": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.14.tgz", + "integrity": "sha512-I6WcygMU2bFInjdURJjkYjo7K5M8B3lBB53v9OO0IcY0LhEY8Wa7IlZ7wVinf5qEjHvaYzRGTZVl6RsJtVt7Sw==", + "dev": true, + "dependencies": { + "@antora/logger": "3.1.14", + "@antora/playbook-builder": "3.1.14", + "@antora/user-require-helper": "~3.0", + "commander": "~11.1" + }, + "bin": { + "antora": "bin/antora" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/content-aggregator": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.14.tgz", + "integrity": "sha512-FVuBgnrGPiktYqK1WHbGF8O8l4m5KHlkxoJumrbacgFo8SKuiRFEo31zalxrCUsv8QM3UBEgX+LdHrve/9CGLg==", + "dev": true, + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "@antora/logger": "3.1.14", + "@antora/user-require-helper": "~3.0", + "braces": "~3.0", + "cache-directory": "~2.0", + "fast-glob": "~3.3", + "hpagent": "~1.2", + "isomorphic-git": "~1.25", + "js-yaml": "~4.1", + "multi-progress": "~4.0", + "picomatch": "~4.0", + "progress": "~2.0", + "should-proxy": "~1.0", + "simple-get": "~4.0", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/content-classifier": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.14.tgz", + "integrity": "sha512-y8Fk+KU1lqD3aawOu3ZFK92YfOZ1k3YBJhLI9QIFM6Ck4STPnf7AwYbhfOtjODlwer5/OhFmfhjUB2hn7onGnA==", + "dev": true, + "dependencies": { + "@antora/asciidoc-loader": "3.1.14", + "@antora/logger": "3.1.14", + "mime-types": "~2.1", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/document-converter": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.14.tgz", + "integrity": "sha512-f6wFnL+489DI0ZDgoxYWzbxxWqPviRiJ56OHS1NixEfvJ7OpRBDPEbX1xnsIeiyFBgqX4+nY92MsCWKTa+Gf3w==", + "dev": true, + "dependencies": { + "@antora/asciidoc-loader": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/expand-path-helper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@antora/expand-path-helper/-/expand-path-helper-3.0.0.tgz", + "integrity": "sha512-7PdEIhk97v85/CSm3HynCsX14TR6oIVz1s233nNLsiWubE8tTnpPt4sNRJR+hpmIZ6Bx9c6QDp3XIoiyu/WYYA==", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/file-publisher": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.14.tgz", + "integrity": "sha512-fTaAnkyKSOlsxQM1TBFCAmiERA6Q67XleDCD2bMPVgfcENmo0Xfx59KwCHaA92IcRSmMftydlXHPaFxNh0UVsg==", + "dev": true, + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "@antora/user-require-helper": "~3.0", + "vinyl": "~3.0", + "yazl": "~2.5" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/logger": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.14.tgz", + "integrity": "sha512-kVEeGqZbXR903hPIm+BlN97fLdQ3LoUzE/BOPZ6vRp9m9Mmbnm67Kg7fSYkfTMLB0S2UWpAPFg22RdsU5ZoAzA==", + "dev": true, + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "pino": "~9.2", + "pino-pretty": "~11.2", + "sonic-boom": "~4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/lunr-extension": { + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/@antora/lunr-extension/-/lunr-extension-1.0.0-alpha.12.tgz", + "integrity": "sha512-iiEXpJae8tCH22ao7kZ4I+eyQ/3IeFIFK1G5I9QLpkCezaVPotI8eLFY7e0xDI+zsqJEfCOsfoZGYXso6xCYlA==", + "dependencies": { + "htmlparser2": "~9.1", + "lunr": "~2.3", + "lunr-languages": "~1.10" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/navigation-builder": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.14.tgz", + "integrity": "sha512-/637YLGD7oUHGSfEfszXkk4ASfIhDAg5Xs9035J1dV07XYRlGqmtUb15rtapbcECpcQFjCyM5jFQYSNNvLrGcQ==", + "dev": true, + "dependencies": { + "@antora/asciidoc-loader": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/page-composer": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.14.tgz", + "integrity": "sha512-RfA+67TxCqUPrQbZdrfjgLpHh8MR2z2du7cyF3HGX4N6DpqEBvz81NHHl3rA3fj6BQZPQbGm2OYAMU6wzJ6Pog==", + "dev": true, + "dependencies": { + "@antora/logger": "3.1.14", + "handlebars": "~4.7", + "require-from-string": "~2.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/playbook-builder": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.14.tgz", + "integrity": "sha512-Ss2r7In00u/n9Da+JOxEqIE8NeRosf+f+agzH3Te09JV/mpgZKxEOE5V/VuP+TNNq4ww1eu5aOS8DiU2PYwj4Q==", + "dev": true, + "dependencies": { + "@iarna/toml": "~2.2", + "convict": "~6.2", + "js-yaml": "~4.1", + "json5": "~2.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/redirect-producer": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.14.tgz", + "integrity": "sha512-5koAwRk1cZrvE/qfOWKXqb3jtxrZbWA5EYHYGFEoato5By3cbC42blH4Bre9/48pjyS6znFpbZhYUBpT7PRhZA==", + "dev": true, + "dependencies": { + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-generator": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.14.tgz", + "integrity": "sha512-hQIUVtM9+xwleYWc4fIRZmiKl2p+ItOJuUm2+Hkdh07BZsySxkMOxxCyZsvTn9rc+4R94CYqDQCYElwFwdB2WA==", + "dev": true, + "dependencies": { + "@antora/asciidoc-loader": "3.1.14", + "@antora/content-aggregator": "3.1.14", + "@antora/content-classifier": "3.1.14", + "@antora/document-converter": "3.1.14", + "@antora/file-publisher": "3.1.14", + "@antora/logger": "3.1.14", + "@antora/navigation-builder": "3.1.14", + "@antora/page-composer": "3.1.14", + "@antora/playbook-builder": "3.1.14", + "@antora/redirect-producer": "3.1.14", + "@antora/site-mapper": "3.1.14", + "@antora/site-publisher": "3.1.14", + "@antora/ui-loader": "3.1.14", + "@antora/user-require-helper": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-mapper": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.14.tgz", + "integrity": "sha512-3qbETtwadl+fWREjzrBUxPUorMcMiZ+hdkB1El9z7it9KzKh0Yp7Je0+2uTxGX+Lov9uik48dZJ9e/mr5PeaRQ==", + "dev": true, + "dependencies": { + "@antora/content-classifier": "3.1.14", + "vinyl": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/site-publisher": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.14.tgz", + "integrity": "sha512-8apyEmgepUc7ms9CTEIPwN3tGtWwLqR6fbLMLs7hibqmOSR880Ut/4GRGb97sqcGQXSHdIyWK2oJKzRl1Akb6Q==", + "dev": true, + "dependencies": { + "@antora/file-publisher": "3.1.14" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/ui-loader": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.14.tgz", + "integrity": "sha512-LVvTdKQOB44CmJ1JQDu8sJf6rrLZMxPAWWackdg2JtGyGHHpd80/MBcv4BSFk7//cJQ13Oqm/7JCbhD51KAFjg==", + "dev": true, + "dependencies": { + "@antora/expand-path-helper": "~3.0", + "braces": "~3.0", + "cache-directory": "~2.0", + "fast-glob": "~3.3", + "hpagent": "~1.2", + "js-yaml": "~4.1", + "picomatch": "~4.0", + "should-proxy": "~1.0", + "simple-get": "~4.0", + "vinyl": "~3.0", + "yauzl": "~3.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@antora/user-require-helper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@antora/user-require-helper/-/user-require-helper-3.0.0.tgz", + "integrity": "sha512-KIXb8WYhnrnwH7Jj21l1w+et9k5GvcgcqvLOwxqWLEd0uVZOiMFdqFjqbVm3M+zcrs1JXWMeh2LLvxBbQs3q/Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@antora/expand-path-helper": "~3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@asciidoctor/core": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@asciidoctor/core/-/core-2.2.8.tgz", + "integrity": "sha512-oozXk7ZO1RAd/KLFLkKOhqTcG4GO3CV44WwOFg2gMcCsqCUTarvMT7xERIoWW2WurKbB0/ce+98r01p8xPOlBw==", + "dev": true, + "dependencies": { + "asciidoctor-opal-runtime": "0.3.3", + "unxhr": "1.0.1" + }, + "engines": { + "node": ">=8.11", + "npm": ">=5.0.0", + "yarn": ">=1.1.0" + } + }, + "node_modules/@asciidoctor/tabs": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@asciidoctor/tabs/-/tabs-1.0.0-beta.6.tgz", + "integrity": "sha512-gGZnW7UfRXnbiyKNd9PpGKtSuD8+DsqaaTSbQ1dHVkZ76NaolLhdQg8RW6/xqN3pX1vWZEcF4e81+Oe9rNRWxg==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@cppalliance/antora-cpp-reference-extension": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@cppalliance/antora-cpp-reference-extension/-/antora-cpp-reference-extension-0.1.0.tgz", + "integrity": "sha512-3VD/gAFebR06GiBWAy2PgEHNqyRNrvAE0FfFvotLvA0RQmHn0q+ct+j0z53N64yxuvJVj8Hl0bRRPdhh2BGjXg==", + "dependencies": { + "@antora/expand-path-helper": "^3.0.0", + "axios": "^1.13.2", + "cache-directory": "^2.0.0", + "fast-glob": "^3.3.3", + "isomorphic-git": "^1.35.0", + "js-yaml": "^4.1.0", + "semver": "^7.7.3" + } + }, + "node_modules/@cppalliance/antora-cpp-reference-extension/node_modules/isomorphic-git": { + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.35.1.tgz", + "integrity": "sha512-XNWd4cIwiGhkMs3C4mK21ch/frfzwFKtJuyv1gf0M4gK/2oZf5PTouwim8cp3Z6rkGbpSpQPaI6jGbV/C+048Q==", + "dependencies": { + "async-lock": "^1.4.1", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^4.0.0", + "sha.js": "^2.4.12", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@cppalliance/antora-cpp-reference-extension/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@cppalliance/antora-cpp-tagfiles-extension": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@cppalliance/antora-cpp-tagfiles-extension/-/antora-cpp-tagfiles-extension-0.1.0.tgz", + "integrity": "sha512-YKCRpqv8srMhqwlUcY3704H6U5DHzQ8Q73JVUv1TF+MsGdUP60DDNR6v8+Xj6PLe93K/MAo6ZUgtJ+RN40YoZQ==", + "dependencies": { + "@antora/expand-path-helper": "^3.0.0", + "cache-directory": "^2.0.0", + "fast-xml-parser": "^5.3.1", + "he": "^1.2.0", + "isomorphic-git": "^1.35.0" + } + }, + "node_modules/@cppalliance/antora-cpp-tagfiles-extension/node_modules/isomorphic-git": { + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.35.1.tgz", + "integrity": "sha512-XNWd4cIwiGhkMs3C4mK21ch/frfzwFKtJuyv1gf0M4gK/2oZf5PTouwim8cp3Z6rkGbpSpQPaI6jGbV/C+048Q==", + "dependencies": { + "async-lock": "^1.4.1", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^4.0.0", + "sha.js": "^2.4.12", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@cppalliance/antora-cpp-tagfiles-extension/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@cppalliance/antora-downloads-extension": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@cppalliance/antora-downloads-extension/-/antora-downloads-extension-0.0.2.tgz", + "integrity": "sha512-2wXahlvRz9J75ZSfzDeP4XpIZiqIm+w/YjmCWJxFPp6oWgP7e8f6ps7HqdtHNGxnK5mG38OjiCFdHjmHYfgbDA==", + "license": "BSL-1.0" + }, + "node_modules/@cppalliance/asciidoctor-boost-links": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@cppalliance/asciidoctor-boost-links/-/asciidoctor-boost-links-0.0.2.tgz", + "integrity": "sha512-9Lg1s955QeBO/xosbJbd+P4qJo1CkC0MvkiAIDZoqf10g8KQpMNy88NBAWji5YcNwXcrr8KP83GEweKMNDBMsw==", + "license": "BSL-1.0" + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/antora": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/antora/-/antora-3.1.14.tgz", + "integrity": "sha512-z8HshJsT6pUfdDOUJ15RGtpOM9LmL6JXU5JBshoR/9/xd+1qLmKPkOnUv+HrijAk93r1imxZOdkmIqhLcv8B8A==", + "dev": true, + "dependencies": { + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14" + }, + "bin": { + "antora": "bin/antora" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asciidoctor-opal-runtime": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz", + "integrity": "sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==", + "dev": true, + "dependencies": { + "glob": "7.1.3", + "unxhr": "1.0.1" + }, + "engines": { + "node": ">=8.11" + } + }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "dev": true, + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cache-directory": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cache-directory/-/cache-directory-2.0.0.tgz", + "integrity": "sha512-7YKEapH+2Uikde8hySyfobXBqPKULDyHNl/lhKm7cKf/GJFdG/tU/WpLrOg2y9aUrQrWUilYqawFIiGJPS6gDA==", + "license": "LGPL-3.0+", + "dependencies": { + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convict": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz", + "integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "yargs-parser": "^20.2.7" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "dev": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fast-xml-parser": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.2.tgz", + "integrity": "sha512-n8v8b6p4Z1sMgqRmqLJm3awW4NX7NkaKPfb3uJIBTSH7Pdvufi3PQ3/lJLQrvxcMYl7JI2jnDO90siPEpD8JBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "dev": true + }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isomorphic-git": { + "version": "1.25.10", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.25.10.tgz", + "integrity": "sha512-IxGiaKBwAdcgBXwIcxJU6rHLk+NrzYaaPKXXQffcA0GW3IUrQXdUPDXDo+hkGVcYruuz/7JlGBiuaeTCgIgivQ==", + "dev": true, + "dependencies": { + "async-lock": "^1.4.1", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "license": "MIT" + }, + "node_modules/lunr-languages": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.10.0.tgz", + "integrity": "sha512-BBjKKcwrieJlzwwc9M5H/MRXGJ2qyOSDx/NXYiwkuKjiLOOoouh0WsDzeqcLoUWcX31y7i8sb8IgsZKObdUCkw==", + "license": "MPL-1.1" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dependencies": { + "minimist": "^1.2.5" + } + }, + "node_modules/multi-progress": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multi-progress/-/multi-progress-4.0.0.tgz", + "integrity": "sha512-9zcjyOou3FFCKPXsmkbC3ethv51SFPoA4dJD6TscIp2pUmy26kBDZW6h9XofPELrzseSkuD7r0V+emGEeo39Pg==", + "dev": true, + "peerDependencies": { + "progress": "^2.0.0" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pino": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.2.0.tgz", + "integrity": "sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dev": true, + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.2.2.tgz", + "integrity": "sha512-2FnyGir8nAJAqD3srROdrF1J5BIcMT4nwj7hHSc60El6Uxlym00UbCCd8pYIterstVBFlMyF1yFV8XdGIPbj4A==", + "dev": true, + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "dev": true + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/should-proxy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/should-proxy/-/should-proxy-1.0.4.tgz", + "integrity": "sha512-RPQhIndEIVUCjkfkQ6rs6sOR6pkxJWCNdxtfG5pP0RVgUYbK5911kLTF0TNcCC0G3YCGd492rMollFT2aTd9iQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dev": true, + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unxhr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unxhr/-/unxhr-1.0.1.tgz", + "integrity": "sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg==", + "dev": true, + "engines": { + "node": ">=8.11" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vinyl": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", + "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3" + } + } + } +} diff --git a/doc/package.json b/doc/package.json new file mode 100644 index 0000000000..904a99c86a --- /dev/null +++ b/doc/package.json @@ -0,0 +1,16 @@ +{ + "devDependencies": { + "@antora/cli": "3.1.14", + "@antora/site-generator": "3.1.14", + "antora": "3.1.14" + }, + "dependencies": { + "@antora/expand-path-helper": "^3.0.0", + "@antora/lunr-extension": "^1.0.0-alpha.12", + "@asciidoctor/tabs": "^1.0.0-beta.6", + "@cppalliance/antora-cpp-reference-extension": "^0.1.0", + "@cppalliance/antora-cpp-tagfiles-extension": "^0.1.0", + "@cppalliance/antora-downloads-extension": "^0.0.2", + "@cppalliance/asciidoctor-boost-links": "^0.0.2" + } +} diff --git a/doc/refresh_mrdocs_cache.sh b/doc/refresh_mrdocs_cache.sh new file mode 100755 index 0000000000..64efcd1c79 --- /dev/null +++ b/doc/refresh_mrdocs_cache.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# +# Copyright (c) 2026 Jean-Louis Leroy +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Decide whether the cached MrDocs binary is stale and, if so, clear it so the +# next Antora build downloads the current nightly. +# +# Why this is needed: build_antora.sh runs mrdocs through the +# @cppalliance/antora-cpp-reference-extension. With no `version` pinned in +# local-playbook.yml the extension resolves "*", which is the rolling +# `develop-release` nightly. It caches the download under a directory keyed by +# the *tag name* (.../mrdocs//develop/), so once that directory exists it is +# reused indefinitely and never tracks newer nightlies. CI has no such problem +# because every runner starts with an empty cache. +# +# This script compares the upstream `develop-release` asset's publish time to +# the value we last synced to (recorded in a marker file). When upstream is +# newer -- or nothing is cached yet -- it removes the cache directory. It is a +# safe no-op when offline, rate-limited, or when a concrete version is pinned. + +set -u + +# Only the floating `develop`/`master` caches go stale; a pinned semver build is +# reproducible and must never be cleared. Skip unless we are tracking a nightly. +TAG="${MRDOCS_CACHE_TAG:-develop}" +case "$TAG" in + develop | master) ;; + *) echo "MrDocs cache tag '$TAG' is pinned; nothing to refresh."; exit 0 ;; +esac + +# Cache layout used by the reference extension: ///bin/mrdocs +case "$(uname -s)" in + Linux) OS=linux ;; + Darwin) OS=darwin ;; + *) echo "Unsupported OS for cache refresh; leaving cache untouched."; exit 0 ;; +esac + +CACHE_ROOT="${HOME}/.cache/antora/reference-collector/mrdocs/${OS}" +CACHE_DIR="${CACHE_ROOT}/${TAG}" +BIN="${CACHE_DIR}/bin/mrdocs" +MARKER="${CACHE_ROOT}/${TAG}.upstream" # records the upstream timestamp we synced + +clear_cache() { # $1 = reason + echo "Clearing MrDocs cache (${1}): ${CACHE_DIR}" + rm -rf "$CACHE_DIR" +} + +# Nothing cached yet -> let the extension download; record nothing. +if [ ! -x "$BIN" ]; then + echo "No cached MrDocs '${TAG}' build; the Antora build will download it." + exit 0 +fi + +# Ask GitHub when the develop-release Linux/macOS asset was last published. +AUTH=() +[ -n "${GITHUB_TOKEN:-}" ] && AUTH=(-H "Authorization: Bearer ${GITHUB_TOKEN}") +ASSET_SUFFIX="$([ "$OS" = darwin ] && echo Darwin || echo Linux).tar.gz" + +UPSTREAM_TS=$(curl -fsSL --max-time 15 "${AUTH[@]}" \ + "https://api.github.com/repos/cppalliance/mrdocs/releases/tags/${TAG}-release" 2>/dev/null \ + | ASSET_SUFFIX="$ASSET_SUFFIX" python3 -c ' +import json, os, sys +try: + data = json.load(sys.stdin) +except Exception: + sys.exit(0) +suffix = os.environ["ASSET_SUFFIX"] +for a in data.get("assets", []): + if a.get("name", "").endswith(suffix): + print(a.get("updated_at", "")) + break +' 2>/dev/null) + +if [ -z "$UPSTREAM_TS" ]; then + echo "Could not query upstream MrDocs (offline / rate-limited); keeping cached build." + exit 0 +fi + +LAST_TS="$(cat "$MARKER" 2>/dev/null || true)" + +if [ -z "$LAST_TS" ]; then + # First run against an existing cache: we cannot know its true upstream age, + # so adopt it as the baseline rather than forcing a surprise re-download. + # (Run `rm -rf "$CACHE_DIR"` once by hand if you suspect it is already stale.) + printf '%s\n' "$UPSTREAM_TS" > "$MARKER" + echo "Recording MrDocs '${TAG}' baseline (${UPSTREAM_TS}); keeping current cache." +elif [ "$UPSTREAM_TS" != "$LAST_TS" ]; then + clear_cache "upstream ${TAG}-release published ${UPSTREAM_TS}, cached ${LAST_TS}" + # Record what the next build will fetch so we do not clear again until it moves. + printf '%s\n' "$UPSTREAM_TS" > "$MARKER" +else + echo "Cached MrDocs '${TAG}' nightly is current (${UPSTREAM_TS})." +fi From fad9c3ed8e034cc045d5735c51490c7c068cbedf Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 11:43:24 -0400 Subject: [PATCH 02/10] doc: add the QuickBook to AsciiDoc transpiler doc/tools/qbk2adoc.py converts the 76 .qbk sources to Antora pages. It is a migration tool, not something to maintain: it runs once in the next commit and is deleted at the end of the port, recoverable from this branch's history. Pass 1 walks test.qbk following [include] and builds the section tree, the [#anchor]/[hN:id] targets and the 85 [def] macros. Pass 2 renders one .adoc per page and resolves the 556 [link]s against that map. 551 of them resolve; the five that do not are targets that do not exist in the QuickBook either, so they are already broken on the current site. They are emitted as `// FIXME` markers rather than dropped, along with the other things a human still has to look at. Two things in the sources needed care. QuickBook code fences here are backtick *runs* -- both ``...`` and ```...``` occur, and a closing run must match the opening one exactly -- and there are three stray unpaired backticks, one of which otherwise swallows the remainder of its file. An unpaired inline backtick is therefore treated as literal text and reported. Co-Authored-By: Claude Opus 5 (1M context) --- .../__pycache__/qbk2adoc.cpython-312.pyc | Bin 0 -> 53660 bytes doc/tools/qbk2adoc.py | 1064 +++++++++++++++++ 2 files changed, 1064 insertions(+) create mode 100644 doc/tools/__pycache__/qbk2adoc.cpython-312.pyc create mode 100644 doc/tools/qbk2adoc.py diff --git a/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc b/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57d6bb5b7ae6bc6170da20990e0f8f0251825483 GIT binary patch literal 53660 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 literal 0 HcmV?d00001 diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py new file mode 100644 index 0000000000..7509453974 --- /dev/null +++ b/doc/tools/qbk2adoc.py @@ -0,0 +1,1064 @@ +#!/usr/bin/env python3 +"""Convert the Boost.Test QuickBook documentation to Antora AsciiDoc. + +One-shot migration tool: it is run once to produce doc/modules/ROOT/pages and +the [def]-derived attribute block for doc/antora.yml, after which the .qbk +sources and this script are deleted. It is kept in branch history rather than +maintained. + +Usage: + python3 tools/qbk2adoc.py [--out DIR] [--attributes FILE] [--list-pages] + +Two passes: + +1. `Index` walks test.qbk following [include], recording the section tree + (QuickBook id path -> page + anchor), every [#anchor] and [hN:id] target, + and the [def] macros. +2. `Renderer` walks the same tree and emits one .adoc per page, resolving + [link]s against the pass-1 map. + +Anything the converter cannot resolve or does not understand is emitted as a +`// FIXME:` comment in the output and counted on stderr, so nothing is dropped +silently. +""" + +import argparse +import os +import re +import sys +from collections import OrderedDict, Counter + +DOC = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +LIBRARY_ID = "boost_test" + +# --------------------------------------------------------------------------- +# Configuration +# --------------------------------------------------------------------------- + +# Sections whose QuickBook id is absent or unsuitable as a page/anchor slug. +ID_OVERRIDES = { + "Practical usage recommendations": "usage_recommendations", + "Change log": "change_log", + "Acknowledgements": "acknowledgments", + "Report formats": "report_formats", + "Summary of the API for declaring and organizing tests": "summary", + "Custom command line arguments": "runtime_custom", +} + +# Chapter (depth-1 section) id -> directory under pages/. `None` means the +# chapter has no sub-pages and renders as a single top-level page. +CHAPTER_DIRS = { + "intro": "intro", + "usage_variants": None, + "tests_organization": "tests_organization", + "testing_tools": "testing_tools", + "test_output": "test_output", + "runtime_config": "runtime_config", + "adv_scenarios": "adv_scenarios", + "pem": "prod_use", + "usage_recommendations": "usage_recommendations", + "section_faq": None, + "section_glossary": None, + "change_log": None, + "acknowledgments": None, + "utf_reference": "utf_reference", +} + +# The introduction is the component's landing page. +PAGE_OVERRIDES = {"intro": "index.adoc"} + +# QuickBook tags naming a C++ entity documented by MrDocs; they all become the +# `cpp:` macro contributed by antora-cpp-tagfiles-extension. +CPP_REF_TAGS = ("classref", "funcref", "memberref", "enumref") + +ADMONITIONS = { + "note": "NOTE", + "tip": "TIP", + "warning": "WARNING", + "caution": "CAUTION", + "important": "IMPORTANT", +} + +# Macros documented only in the hand-written reference pages: MrDocs does not +# emit pages for them, so [macroref] resolves against these anchors instead. +MACROREF_TARGETS = { + "BOOST_TEST_DISABLE_ALT_STACK": "config_disable_alt_stack", + "BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE": "config_no_grid_composition", + "BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE": "config_no_zip_composition", + "BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE": "config_no_random_dataset", +} +MACROREF_PAGE = "utf_reference/link_references.adoc" + + +# --------------------------------------------------------------------------- +# Lexing helpers +# --------------------------------------------------------------------------- + +def scan_code(text, i): + """Scan the backtick-delimited span starting at text[i]. + + QuickBook delimits inline code with a single backtick and code blocks with + a run of two or more; Boost.Test's sources use runs of two *and* three, and + a closing run must match the opening run exactly. Getting this wrong makes + a stray backtick swallow the rest of the file, so it is centralised here. + + Returns (run_length, content_start, content_end, end_of_span); a run_length + of 0 means the backtick is unpaired and should be treated as literal text. + The sources contain two such strays (`parameter`s description` in + runtime_config_reference.qbk and a misplaced backtick in nullary_tests.qbk); + without this guard one of them swallows the rest of the file. + """ + n = len(text) + k = 0 + while i + k < n and text[i + k] == "`": + k += 1 + start = i + k + if k == 1: + # Inline code never crosses a blank line. + limit = text.find("\n\n", start) + limit = n if limit < 0 else limit + j = text.find("`", start, limit) + return (1, start, j, j + 1) if j >= 0 else (0, i, i, i + 1) + j = start + while j < n: + if text[j] != "`": + j += 1 + continue + m = 0 + while j + m < n and text[j + m] == "`": + m += 1 + if m == k: + return (k, start, j, j + m) + j += m + return (k, start, n, n) + + +def match_bracket(text, i): + """Return the index just past the ']' matching the '[' at text[i]. + + Skips code spans/blocks and '''passthrough''', which may legitimately + contain unbalanced brackets. + """ + depth = 0 + n = len(text) + while i < n: + c = text[i] + if c == "[": + depth += 1 + i += 1 + elif c == "]": + depth -= 1 + i += 1 + if depth == 0: + return i + elif text.startswith("'''", i): + j = text.find("'''", i + 3) + i = n if j < 0 else j + 3 + elif c == "`": + i = scan_code(text, i)[3] + else: + i += 1 + return n + + +def strip_comments(text): + """Remove [/ ... ] comments while preserving line numbering.""" + out = [] + i = 0 + n = len(text) + while i < n: + if text.startswith("[/", i): + j = match_bracket(text, i) + out.append("\n" * text.count("\n", i, j)) + i = j + elif text.startswith("'''", i): + j = text.find("'''", i + 3) + j = n if j < 0 else j + 3 + out.append(text[i:j]) + i = j + elif text[i] == "`": + j = scan_code(text, i)[3] + out.append(text[i:j]) + i = j + else: + out.append(text[i]) + i += 1 + return "".join(out) + + +def split_cells(body): + """Split a table/variablelist row body into its bracketed cells.""" + cells = [] + i = 0 + n = len(body) + while i < n: + if body[i] == "[": + j = match_bracket(body, i) + cells.append(body[i + 1:j - 1]) + i = j + else: + i += 1 + return cells + + +def split1(text): + """Split off the first whitespace-delimited token; QuickBook arguments are + routinely separated by a newline rather than a space.""" + parts = re.split(r"\s+", text.strip(), 1) + return parts[0], (parts[1] if len(parts) > 1 else "") + + +def tag_of(inner): + """Return the tag of a bracket body, e.g. 'section' for 'section:id T'.""" + m = re.match(r"([A-Za-z_][\w]*)", inner) + return m.group(1) if m else "" + + +def make_id(title): + """Approximate QuickBook's auto-generated section id.""" + title = re.sub(r"\[[@#$*'_^]?[^\]\s]*\s+([^\]]*)\]", r"\1", title) + title = title.replace("`", "").replace("'", "") + slug = re.sub(r"[^a-z0-9]+", "_", title.lower()).strip("_") + return slug or "section" + + +def attr_name(def_name): + """Map a QuickBook [def] name such as __BOOST_TEST__ to an attribute name.""" + return def_name.strip("_").lower() or "def" + + +# --------------------------------------------------------------------------- +# Pass 1 - document model +# --------------------------------------------------------------------------- + +class Section(object): + def __init__(self, sid, title, depth, src, line, parent): + self.id = sid + self.title = title + self.depth = depth + self.src = src + self.line = line + self.parent = parent + self.children = [] + self.chunks = [] # interleaved ('text', str) | ('section', Section) + self.page = None + self.qid = None + + +class Index(object): + def __init__(self, root_file): + self.defs = OrderedDict() + self.root = Section(LIBRARY_ID, "Boost.Test", 0, root_file, 0, None) + self.by_qid = {} + self.anchors = {} + self.pending_anchor = None + self._load(root_file, self.root) + self._assign_qids(self.root, [LIBRARY_ID]) + self._assign_pages() + self._collect_anchors() + + # -- loading ------------------------------------------------------------ + + def _load(self, path, current): + text = strip_comments(open(path, encoding="utf-8", errors="replace").read()) + rel = os.path.relpath(path, DOC) + i = 0 + n = len(text) + buf = [] + line = 1 + + def flush(): + if buf: + current.chunks.append(("text", "".join(buf))) + del buf[:] + + while i < n: + c = text[i] + if c == "\n": + line += 1 + buf.append(c) + i += 1 + continue + if text.startswith("'''", i) or c == "`": + if c == "`": + j = scan_code(text, i)[3] + else: + j = text.find("'''", i + 3) + j = n if j < 0 else j + 3 + buf.append(text[i:j]) + line += text.count("\n", i, j) + i = j + else: + if c != "[": + buf.append(c) + i += 1 + continue + j = match_bracket(text, i) + inner = text[i + 1:j - 1] + tag = tag_of(inner) + if tag == "include": + flush() + target = inner.split(None, 1)[1].strip() + self._load(os.path.normpath( + os.path.join(os.path.dirname(path), target)), current) + elif tag == "def": + name, value = inner.split(None, 2)[1:] + self.defs[name] = value.strip() + elif tag == "template": + pass # bt_example et al are handled structurally + elif tag == "section": + flush() + # `[#anchor][section ...]` puts the anchor just before the + # section; it names the section, so move it inside. + if current.chunks and current.chunks[-1][0] == "text": + m = re.search(r"(\[#[^\]\s]+\])\s*$", current.chunks[-1][1]) + if m: + self.pending_anchor = m.group(1) + current.chunks[-1] = ( + "text", current.chunks[-1][1][:m.start()]) + sid, title = self._parse_section_head(inner) + child = Section(sid, title, current.depth + 1, rel, line, current) + current.chunks.append(("section", child)) + current.children.append(child) + current = child + if self.pending_anchor: + current.chunks.append(("text", self.pending_anchor + "\n")) + self.pending_anchor = None + elif tag == "endsect": + flush() + if current.parent is not None: + current = current.parent + elif tag in ("library", "quickbook"): + pass + else: + buf.append(text[i:j]) + line += text.count("\n", i, j) + i = j + flush() + + def _parse_section_head(self, inner): + rest = inner[len("section"):] + sid = None + if rest.startswith(":"): + m = re.match(r":(\S+)\s*(.*)", rest, re.S) + sid, rest = m.group(1), m.group(2) + title = rest.strip() + # `[section Report formats][#ref_report_formats]` leaves the anchor in + # the title; peel it off and re-emit it inside the section body. + while True: + m = re.search(r"(\[#[^\]\s]+\])\s*$", title) + if not m: + break + self.pending_anchor = m.group(1) + title = title[:m.start()].rstrip() + if title in ID_OVERRIDES: + sid = ID_OVERRIDES[title] + elif sid is None: + sid = make_id(title) + return sid, title + + # -- ids and pages ------------------------------------------------------ + + def _assign_qids(self, sec, path): + sec.qid = ".".join(path) + self.by_qid[sec.qid] = sec + for child in sec.children: + self._assign_qids(child, path + [child.id]) + + def _assign_pages(self): + for chapter in self.root.children: + directory = CHAPTER_DIRS.get(chapter.id, chapter.id) + override = PAGE_OVERRIDES.get(chapter.id) + if override: + chapter.page = override + elif directory is None: + chapter.page = chapter.id + ".adoc" + else: + chapter.page = directory + "/index.adoc" + self._assign_pages_below(chapter, chapter.src, directory) + + def _assign_pages_below(self, sec, chapter_src, directory): + """A section starts a new page when it opens a .qbk file of its own.""" + for child in sec.children: + if directory is not None and child.src != chapter_src: + child.page = "%s/%s.adoc" % (directory, child.id) + self._assign_pages_below(child, child.src, directory) + else: + self._assign_pages_below(child, chapter_src, directory) + + def owning_page(self, sec): + while sec is not None and sec.page is None: + sec = sec.parent + return sec + + def _collect_anchors(self): + for qid, sec in self.by_qid.items(): + if sec is self.root: + continue + owner = self.owning_page(sec) + self.anchors[qid] = (owner, None if owner is sec else sec.id) + # A section renamed by ID_OVERRIDES is still linked to by the id + # QuickBook derived from its title; keep both resolvable. + for sec in list(self.by_qid.values()): + if sec.parent is None or sec.title not in ID_OVERRIDES: + continue + auto = make_id(sec.title) + if auto != sec.id: + parent_qid = sec.parent.qid + self.anchors["%s.%s" % (parent_qid, auto)] = self.anchors[sec.qid] + for sec in self.by_qid.values(): + owner = self.owning_page(sec) + for kind, chunk in sec.chunks: + if kind != "text": + continue + found = [m.group(1) for m in re.finditer(r"\[#([^\]\s]+)\]", chunk)] + found += [m.group(1) + for m in re.finditer(r"\[h[1-6]:([^\]\s]+)[\s\]]", chunk)] + for anchor in found: + self.anchors[anchor] = (owner, anchor) + # links also address these as . + self.anchors.setdefault("%s.%s" % (sec.qid, anchor), + (owner, anchor)) + + def resolve(self, target): + """Map a QuickBook link target to (page-section, anchor) or None.""" + if target in self.anchors: + return self.anchors[target] + sec = self.by_qid.get(target) + if sec is not None: + owner = self.owning_page(sec) + return (owner, None if owner is sec else sec.id) + return None + + +# --------------------------------------------------------------------------- +# Pass 2 - rendering +# --------------------------------------------------------------------------- + +LIST_RE = re.compile(r"^(\s*)([*#]+)\s+(.*)$") +FENCE_RE = re.compile(r"^\s*``\s*$") + + +class Renderer(object): + def __init__(self, index, outdir): + self.index = index + self.outdir = outdir + self.fixmes = Counter() + self.unresolved = Counter() + self.examples = set() + self.imports = set() + self.snippets = {} # callout id -> example$ resource path + self.plain = {} # def name -> plain text, for use inside code + for name, value in index.defs.items(): + self.plain[name] = self._plain_text(value) + + # -- helpers ------------------------------------------------------------ + + @staticmethod + def _plain_text(value): + """Reduce a [def] body to the text a reader sees, for code blocks.""" + m = re.match(r"\[link\s+\S+\s+(.*)\]$", value.strip(), re.S) + if m: + value = m.group(1) + value = re.sub(r"\[[*'_]\s*([^\]]*)\]", r"\1", value) + return value.replace("`", "").replace("/", "").strip() + + # QuickBook's other italic form, /like this/. Excludes C comments (/* ... */) + # and anything spanning a paragraph break; `and/or` is ruled out by the + # word-character check at the call site. + SLASH_ITALIC = re.compile(r"/(?!\*)([^/\n]{1,60}(?:\n[^/\n]{1,60})?)/(?![\w/])") + + # Characters that still take on meaning inside a monospace span. + UNSAFE_IN_CODE = re.compile(r"[{}*#^~`]|__|^_|_$") + + def code_span(self, body): + """Render `code` so AsciiDoc leaves its contents alone.""" + body = self.subst_defs(body.strip(), code=True) + if not self.UNSAFE_IN_CODE.search(body): + return "`%s`" % body + if "+" not in body and "`" not in body: + return "`+%s+`" % body # no substitutions at all + return "`%s`" % body.replace("{", "\\{").replace("`", "'") + + def fixme(self, kind, detail=""): + self.fixmes[kind] += 1 + return "// FIXME(qbk2adoc): %s %s\n" % (kind, detail) + + # `{` is escaped in prose so stray braces in the sources cannot look like + # attribute references. Substituted [def]s therefore go in as sentinels and + # become real braces on the way out of inline(). + ATTR_OPEN, ATTR_CLOSE = "\x01", "\x02" + + def subst_defs(self, text, code=False): + def repl(m): + name = m.group(0) + if name not in self.index.defs: + return name + if code: + return self.plain[name] + return "%s%s%s" % (self.ATTR_OPEN, attr_name(name), self.ATTR_CLOSE) + return re.sub(r"__[A-Za-z0-9_]+?__", repl, text) + + # -- inline ------------------------------------------------------------- + + def inline(self, text, page): + text = self.subst_defs(text) + out = [] + i = 0 + n = len(text) + while i < n: + c = text[i] + if text.startswith("'''", i): + j = text.find("'''", i + 3) + j = n if j < 0 else j + 3 + out.append(self.fixme("raw-docbook", text[i:j].replace("\n", " "))) + i = j + elif c == "`": + k, cs, ce, end = scan_code(text, i) + if k == 0: + self.fixmes["stray-backtick"] += 1 + out.append("\\`") + else: + out.append(self.code_span(text[cs:ce])) + i = end + elif c == "[": + j = match_bracket(text, i) + out.append(self.inline_tag(text[i + 1:j - 1], page)) + i = j + elif c == "{": + out.append("\\{") + i += 1 + elif c == "/" and (not out or not re.match(r"[\w/]", out[-1][-1:])): + m = self.SLASH_ITALIC.match(text, i) + if m: + out.append("_%s_" % self.inline(m.group(1), page)) + i = m.end(1) + 1 + else: + out.append(c) + i += 1 + else: + out.append(c) + i += 1 + return ("".join(out) + .replace(self.ATTR_OPEN, "{").replace(self.ATTR_CLOSE, "}")) + + def link_macro(self, target, label, page): + # `boost.debug.under_debugger` and friends address the Doxygen-generated + # reference, which MrDocs now owns; route them through the cpp: macro. + if target.startswith("boost.") and not target.startswith(LIBRARY_ID + "."): + return "cpp:%s[%s]" % (target.replace(".", "::"), + label.replace("]", "\\]")) + hit = self.index.resolve(target) + if hit is None or hit[0] is None or hit[0].page is None: + self.unresolved[target] += 1 + return "%s // FIXME(qbk2adoc): unresolved link %s" % (label, target) + owner, anchor = hit + ref = owner.page + if anchor: + ref += "#" + anchor + return "xref:%s[%s]" % (ref, label.replace("]", "\\]")) + + def inline_tag(self, inner, page): + tag = tag_of(inner) + rest = inner[len(tag):].strip() if tag else inner + if inner.startswith("#"): + return "[[%s]]" % inner[1:].strip() + if inner.startswith("*"): + return "*%s*" % self.inline(inner[1:].strip(), page) + if inner.startswith("'"): + return "_%s_" % self.inline(inner[1:].strip(), page) + if inner.startswith("_"): + return "[.underline]#%s#" % self.inline(inner[1:].strip(), page) + if inner.startswith("^"): + return "`%s`" % inner[1:].strip() + if inner.startswith("@"): + url, label = split1(inner[1:]) + label = self.inline(label, page) if label else "" + return "%s[%s]" % (url, label.replace("]", "\\]")) + if inner.startswith("$"): + return self.image_macro(inner[1:].strip(), block=False) + if tag in ("link", "links"): + target, label = split1(rest) + label = self.inline(label, page) if label else target + return self.link_macro(target, label, page) + if tag in CPP_REF_TAGS: + symbol, label = split1(rest) + label = label or symbol + return "cpp:%s[%s]" % (symbol, self.inline(label, page).replace("]", "\\]")) + if tag == "headerref": + header, label = split1(rest) + label = label or header + return "link:{base-url}/%s[%s]" % (header, self.inline(label, page)) + if tag == "macroref": + macro, label = split1(rest) + label = self.inline(label or macro, page) + anchor = MACROREF_TARGETS.get(macro) + if anchor: + return "xref:%s#%s[%s]" % (MACROREF_PAGE, anchor, label) + self.unresolved["macroref:" + macro] += 1 + return "%s // FIXME(qbk2adoc): unresolved macroref %s" % (label, macro) + if inner.strip() in self.snippets: + return "\n" + self.snippet_include(inner.strip()) + if tag == "footnote": + return "footnote:[%s]" % self.inline(rest, page).replace("]", "\\]").strip() + if tag == "ticket": + return "{trac-url}/%s[#%s]" % (rest, rest) + if tag == "pull_request": + return "{pr-url}/%s[#PR-%s]" % (rest, rest) + if tag == "github_issue": + return "{issue-url}/%s[#GH-%s]" % (rest, rest) + if tag == "br": + return " +\n" + if tag in ADMONITIONS: + return "%s: %s" % (ADMONITIONS[tag], self.inline(rest, page).strip()) + if tag == "": + return self.inline(inner, page) + self.fixmes["inline-tag:" + (tag or "?")] += 1 + return "\\[%s]" % inner + + def image_macro(self, spec, block): + m = re.match(r"(\S+)\s*(?:\[width\s+(\S+?)\s*\])?", spec) + path = os.path.basename(m.group(1)) + attrs = "width=%s" % m.group(2) if m.group(2) else "" + return "image%s:%s[%s]" % (":" if block else "", path, attrs) + + # -- blocks ------------------------------------------------------------- + + def render_body(self, text, page, level, headings): + """Render a section body (no nested [section]s) at AsciiDoc `level`.""" + out = [] + pending = [] # anchors waiting to attach to the next block + pos = 0 + n = len(text) + while pos < n: + if text[pos].isspace(): + pos += 1 + continue + line_end = text.find("\n", pos) + line_end = n if line_end < 0 else line_end + line = text[pos:line_end] + + if text[pos] == "[": + end = match_bracket(text, pos) + inner = text[pos + 1:end - 1] + tag = tag_of(inner) + if inner.startswith("#"): + pending.append("[#%s]" % inner[1:].strip()) + pos = end + continue + block = self.render_block_tag(tag, inner, page, level, headings) + if block is not None: + out.append(self.flush_anchors(pending) + block) + pos = end + continue + + if text[pos] == "`" and text.startswith("``", pos): + _, cs, ce, end = scan_code(text, pos) + out.append(self.flush_anchors(pending) + + self.code_block(text[cs:ce], page)) + pos = end + continue + + if LIST_RE.match(line): + block, pos = self.list_block(text, pos, page) + out.append(self.flush_anchors(pending) + block) + continue + + block, pos = self.paragraph(text, pos, page) + if block: + out.append(self.flush_anchors(pending) + block) + out.append(self.flush_anchors(pending)) + return "".join(out) + + @staticmethod + def flush_anchors(pending): + if not pending: + return "" + text = "".join(a + "\n" for a in pending) + del pending[:] + return text + + def render_block_tag(self, tag, inner, page, level, headings): + rest = inner[len(tag):].strip() if tag else inner + if re.match(r"^h[1-6]([\s:])", inner) or tag == "heading": + return self.heading(inner, page, level, headings) + if tag in ADMONITIONS: + return self.admonition(ADMONITIONS[tag], rest, page, level) + if tag == "table": + return self.table(inner, page) + if tag == "variablelist": + return self.variablelist(rest, page, level) + if tag == "pre": + return self.pre_block(rest, page) + if tag == "bt_example": + return self.bt_example(rest, page) + if tag == "import": + self.register_import(rest.strip()) + return "" + if inner.strip() in self.snippets: + return self.snippet_include(inner.strip()) + if tag == "role": + role, body = split1(rest) + if role == "epigraph": + return "[quote]\n____\n%s\n____\n\n" % self.inline(body, page).strip() + return self.fixme("role", role) + if tag == "xinclude": + return ("// The Doxygen-generated reference is replaced by the " + "MrDocs `reference` module.\n\n") + if inner.startswith("$"): + return self.image_macro(inner[1:].strip(), block=True) + "\n\n" + return None + + def heading(self, inner, page, level, headings): + m = re.match(r"h([1-6])(?::(\S+))?\s*(.*)", inner, re.S) + if m: + depth, anchor, title = int(m.group(1)), m.group(2), m.group(3) + else: # [heading Title] + depth, anchor = 3, None + title = inner[len("heading"):].strip() + rank = headings.index(depth) if depth in headings else 0 + out = "[#%s]\n" % anchor if anchor else "" + out += "%s %s\n\n" % ("=" * min(level + 1 + rank, 6), + self.inline(title.strip(), page).strip()) + return out + + def admonition(self, kind, body, page, level): + rendered = self.render_body(body, page, level, []).strip() + if "\n" in rendered: + return "[%s]\n====\n%s\n====\n\n" % (kind, rendered) + return "%s: %s\n\n" % (kind, rendered) + + def code_block(self, body, page): + body = self.subst_defs(body, code=True) + # QuickBook annotates code with /*< ... >*/; AsciiDoc uses markers + # in the listing plus a colist after it. + callouts = [] + + def callout(m): + callouts.append(m.group(1).strip()) + return " <%d>" % len(callouts) + + body = re.sub(r"[ \t]*/\*<(.*?)>\*/", callout, body, flags=re.S) + lines = [ln.rstrip() for ln in body.split("\n")] + while lines and not lines[0].strip(): + lines.pop(0) + while lines and not lines[-1].strip(): + lines.pop() + indent = min((len(ln) - len(ln.lstrip()) for ln in lines if ln.strip()), + default=0) + body = "\n".join(ln[indent:] for ln in lines) + out = "[source,cpp]\n----\n%s\n----\n" % body + for number, text in enumerate(callouts, 1): + out += "<%d> %s\n" % (number, self.inline(text, page).strip()) + return out + "\n" + + def pre_block(self, body, page): + """[pre] is a literal block, except QuickBook still expands markup in + it. Where markup is present, re-enable substitutions on the block.""" + markup = re.search(r"\[[a-z@#$*'_]|__[A-Za-z0-9_]+__", body) + if markup: + body = self.inline(body, page) + else: + body = self.subst_defs(body, code=True) + lines = [ln.rstrip() for ln in body.split("\n")] + while lines and not lines[0].strip(): + lines.pop(0) + while lines and not lines[-1].strip(): + lines.pop() + prefix = '[subs="+macros,+attributes,+quotes"]\n' if markup else "" + return "%s....\n%s\n....\n\n" % (prefix, "\n".join(lines)) + + def bt_example(self, rest, page): + parts = [p.strip() for p in rest.split("..")] + if len(parts) != 3: + return self.fixme("bt_example-arity", rest) + name, descr, rule = parts + self.examples.add((name, rule)) + return ("// tag reference: doc/modules/ROOT/examples/%s.%s.cpp\n" + ":bt-name: %s\n:bt-rule: %s\n:bt-descr: %s\n" + "include::partial$bt_example.adoc[]\n\n" + % (name, rule, name, rule, self.inline(descr, page).strip())) + + def register_import(self, target): + """Record an [import] and the //[callout] ids the file defines. + + doc/snippet moves to modules/ROOT/examples/snippets; doc/examples is + already the examples root, and those files are pulled in by bt_example + rather than by a bare callout. + """ + self.imports.add(target) + path = os.path.normpath(os.path.join(DOC, target.replace("../", "", 1))) + if not os.path.isfile(path): + self.fixmes["import-missing"] += 1 + return + rel = os.path.relpath(path, DOC) + if rel.startswith("snippet" + os.sep): + resource = "snippets/" + rel.split(os.sep, 1)[1].replace(os.sep, "/") + else: + resource = rel.replace(os.sep, "/") + for m in re.finditer(r"^\s*//\[([A-Za-z_]\w*)", + open(path, encoding="utf-8", errors="replace").read(), + re.M): + self.snippets[m.group(1)] = resource + + def snippet_include(self, name): + resource = self.snippets[name] + return ("[source,cpp]\n----\ninclude::example$%s[tag=%s]\n----\n\n" + % (resource, name)) + + def table(self, inner, page): + m = re.match(r"table(?::(\S+))?\s*", inner) + anchor = m.group(1) + rest = inner[m.end():] + first = rest.find("[") + title = rest[:first if first >= 0 else len(rest)].strip() + rows = [split_cells(r) for r in split_cells(rest[first:] if first >= 0 else "")] + rows = [r for r in rows if r] + if not rows: + return self.fixme("empty-table", title) + ncols = max(len(r) for r in rows) + out = [] + if anchor: + out.append("[#%s]\n" % anchor) + if title: + out.append(".%s\n" % self.inline(title, page).strip()) + out.append('[%%header%%autowidth,cols="%d*"]\n|===\n' % ncols) + for idx, row in enumerate(rows): + for cell in row: + rendered = self.render_body(cell, page, 6, []).strip() + if "\n" in rendered: + out.append("a|\n%s\n" % rendered) + else: + out.append("|%s\n" % rendered.replace("|", "\\|")) + out.append("\n") + if idx == 0 and len(rows) > 1: + pass + out.append("|===\n\n") + return "".join(out) + + def variablelist(self, rest, page, level): + first = rest.find("[") + title = rest[:first if first >= 0 else len(rest)].strip() + rows = [split_cells(r) for r in split_cells(rest[first:] if first >= 0 else "")] + out = [] + if title: + out.append(".%s\n" % self.inline(title, page).strip()) + out.append("[cols=\"1,3\"]\n|===\n") + for row in rows: + if len(row) != 2: + out.append(self.fixme("variablelist-row", str(row)[:60])) + continue + term = self.render_body(row[0], page, 6, []).strip() + desc = self.render_body(row[1], page, 6, []).strip() + out.append("|%s\na|\n%s\n\n" % (term.replace("|", "\\|"), desc)) + out.append("|===\n\n") + return "".join(out) + + def list_block(self, text, pos, page): + items = [] + n = len(text) + while pos < n: + line_end = text.find("\n", pos) + line_end = n if line_end < 0 else line_end + line = text[pos:line_end] + m = LIST_RE.match(line) + if m: + indent, marker, body = m.group(1), m.group(2), m.group(3) + items.append([len(indent) + len(marker) - 1, marker[-1], [body]]) + pos = line_end + 1 + continue + if not line.strip(): + # a blank line ends the list unless the next line continues it + nxt = text.find("\n", line_end + 1) + nxt = n if nxt < 0 else nxt + peek = text[line_end + 1:nxt] + if items and (LIST_RE.match(peek) or peek.startswith(" ")): + items[-1][2].append("") + pos = line_end + 1 + continue + pos = line_end + 1 + break + if items and line.startswith((" ", "\t")): + items[-1][2].append(line.strip()) + pos = line_end + 1 + continue + break + levels = sorted({item[0] for item in items}) + out = [] + for depth, marker, body in items: + rank = levels.index(depth) + 1 + bullet = ("*" if marker == "*" else ".") * rank + rendered = self.inline("\n".join(body).strip(), page).strip() + rendered = re.sub(r"\n\s*\n", "\n+\n", rendered) + out.append("%s %s\n" % (bullet, rendered)) + out.append("\n") + return "".join(out), pos + + def paragraph(self, text, pos, page): + n = len(text) + depth = 0 + i = pos + while i < n: + c = text[i] + if c == "[": + depth += 1 + elif c == "]": + depth = max(0, depth - 1) + elif c == "`": + i = scan_code(text, i)[3] + continue + elif c == "\n" and depth == 0: + if text.startswith("\n", i + 1): + break + nxt_end = text.find("\n", i + 1) + nxt_end = n if nxt_end < 0 else nxt_end + nxt = text[i + 1:nxt_end] + if LIST_RE.match(nxt) or nxt.startswith("``"): + break + if nxt.strip()[1:-1] in self.snippets and nxt.strip().startswith("["): + break + if nxt.lstrip().startswith("["): + inner_tag = tag_of(nxt.lstrip()[1:]) + if inner_tag in ADMONITIONS or inner_tag in ( + "table", "variablelist", "pre", "bt_example", + "import", "role", "xinclude") or re.match( + r"^h[1-6][\s:]", nxt.lstrip()[1:]): + break + i += 1 + body = text[pos:i].strip() + rendered = self.inline(body, page).strip() + if not rendered: + return "", i + 1 + if rendered[:1] in (".", "+", "=", "-") or rendered.startswith("//"): + rendered = "{empty}" + rendered + return rendered + "\n\n", i + 1 + + # -- page assembly ------------------------------------------------------ + + def heading_ranks(self, sec): + """Distinct [hN] levels used directly in a section, in document order.""" + found = [] + for kind, chunk in sec.chunks: + if kind != "text": + continue + for m in re.finditer(r"\[h([1-6])[\s:]", chunk): + depth = int(m.group(1)) + if depth not in found: + found.append(depth) + return sorted(found) + + def render_section(self, sec, page, level): + out = [] + headings = self.heading_ranks(sec) + for kind, chunk in sec.chunks: + if kind == "text": + out.append(self.render_body(chunk, page, level, headings)) + elif chunk.page is None: + out.append("[#%s]\n%s %s\n\n" % ( + chunk.id, "=" * (level + 1), + self.inline(chunk.title, page).strip())) + out.append(self.render_section(chunk, page, level + 1)) + return "".join(out) + + # QuickBook spells an epigraph's attribution as a *second* epigraph whose + # body starts with `--`; AsciiDoc puts it in the block attribute list. + EPIGRAPH_ATTRIB = re.compile( + r"\[quote\]\n____\n(.*?)\n____\n\n\[quote\]\n____\n--(.+?)\n____\n", + re.S) + + def render_page(self, sec): + body = self.render_section(sec, sec, 1) + body = self.EPIGRAPH_ATTRIB.sub( + lambda m: "[quote, %s]\n____\n%s\n____\n" + % (m.group(2).strip(), m.group(1)), body) + header = "= %s\n" % self.inline(sec.title, sec).strip() + alias = self.page_alias(sec) + if alias: + header += ":page-aliases: %s\n" % alias + return header + "\n" + body.strip() + "\n" + + def page_alias(self, sec): + """The path the BoostBook site used for this section.""" + parts = sec.qid.split(".") + return "%s.adoc" % "/".join(parts) + + def run(self): + pages = OrderedDict() + for sec in self.index.by_qid.values(): + if sec.page: + pages[sec.page] = sec + for page, sec in pages.items(): + path = os.path.join(self.outdir, page) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w", encoding="utf-8") as fh: + fh.write(self.render_page(sec)) + return pages + + +def emit_nav(index, renderer, path): + """Draft modules/ROOT/nav.adoc from the section tree, for hand-tuning.""" + lines = [] + + def walk(sec, depth): + for child in sec.children: + if child.page: + lines.append("%s xref:%s[]\n" % ("*" * depth, child.page)) + walk(child, depth + 1) + else: + # a section that is only a heading on its parent page: keep its + # sub-pages, but attach them at the parent's level + walk(child, depth) + + walk(index.root, 1) + with open(path, "w", encoding="utf-8") as fh: + fh.writelines(lines) + + +def emit_attributes(index, renderer, path): + lines = [] + for name, value in index.defs.items(): + rendered = renderer.inline(value, index.root).strip().replace("\n", " ") + rendered = re.sub(r"\s+", " ", rendered) + # QuickBook's /slash italics/ survive only in the [def] bodies. + rendered = re.sub(r"(? %d pages\n" % (len(index.by_qid), len(pages))) + sys.stderr.write("%d defs -> %s\n" % (len(index.defs), args.attributes)) + if renderer.unresolved: + sys.stderr.write("\nunresolved link targets (%d distinct, %d uses):\n" + % (len(renderer.unresolved), sum(renderer.unresolved.values()))) + for target, count in renderer.unresolved.most_common(): + sys.stderr.write(" %4d %s\n" % (count, target)) + if renderer.fixmes: + sys.stderr.write("\nFIXMEs emitted:\n") + for kind, count in renderer.fixmes.most_common(): + sys.stderr.write(" %4d %s\n" % (count, kind)) + + +if __name__ == "__main__": + main() From 75b65929aa94692a3a13b38e024087f810d961d5 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 11:47:41 -0400 Subject: [PATCH 03/10] doc: move examples and snippets under modules/ROOT/examples Antora can only include files from modules//examples, so doc/examples and doc/snippet move there. The QuickBook //[name ... //] region markers become AsciiDoc // tag::name[] ... // end::name[] markers; only comment lines change in the .cpp files. doc/examples is compiled and run by the test suite, so the paths in test/Jamfile.v2, test/CMakeLists.txt and the CI depinst arguments move with it, as do the source paths embedded in three .output files -- those are what the example prints at runtime, and they are shown in the docs. The snippets were never compiled and were not compilable: they contained QuickBook [def] macros (__BOOST_TEST__ and friends) in place of the real macro names. Those are now spelled out, which also makes them candidates for the example test harness later. modules/ROOT/partials/bt_example.adoc replaces the QuickBook `bt_example` template used at 118 call sites. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 2 +- doc/examples/example24.output | 5 -- doc/examples/exception_nothrow.output | 9 --- doc/examples/tolerance_05.output | 8 --- .../boost_runtime_list_content.output | 4 +- .../boost_runtime_list_content.run.cpp | 4 +- .../ROOT}/examples/boost_test_bitwise.output | 4 +- .../examples/boost_test_bitwise.run-fail.cpp | 4 +- .../boost_test_container_default.output | 4 +- .../boost_test_container_default.run-fail.cpp | 4 +- .../examples/boost_test_container_lex.output | 4 +- .../boost_test_container_lex.run-fail.cpp | 4 +- .../boost_test_container_lex_default.output | 4 +- ...st_test_container_lex_default.run-fail.cpp | 4 +- .../ROOT}/examples/boost_test_macro2.output | 4 +- .../examples/boost_test_macro2.run-fail.cpp | 4 +- .../ROOT}/examples/boost_test_macro3.output | 4 +- .../examples/boost_test_macro3.run-fail.cpp | 4 +- .../boost_test_macro_container_c_array.output | 4 +- ..._test_macro_container_c_array.run-fail.cpp | 4 +- .../examples/boost_test_macro_overview.output | 4 +- .../boost_test_macro_overview.run-fail.cpp | 4 +- .../boost_test_macro_workaround.output | 4 +- .../boost_test_macro_workaround.run.cpp | 4 +- .../ROOT}/examples/boost_test_message.output | 4 +- .../examples/boost_test_message.run-fail.cpp | 4 +- .../boost_test_sequence_per_element.output | 4 +- ...ost_test_sequence_per_element.run-fail.cpp | 4 +- .../ROOT}/examples/boost_test_string.output | 4 +- .../examples/boost_test_string.run-fail.cpp | 4 +- .../ROOT}/examples/custom_init.output | 4 +- .../ROOT}/examples/custom_init.run-fail.cpp | 4 +- .../ROOT}/examples/custom_main.output | 4 +- .../ROOT}/examples/custom_main.run-fail.cpp | 4 +- .../examples/custom_obsolete_init.output | 4 +- .../custom_obsolete_init.run-fail.cpp | 4 +- .../ROOT}/examples/dataset_example59.output | 4 +- .../examples/dataset_example59.run-fail.cpp | 4 +- .../ROOT}/examples/dataset_example61.output | 4 +- .../ROOT}/examples/dataset_example61.run.cpp | 4 +- .../ROOT}/examples/dataset_example62.output | 4 +- .../ROOT}/examples/dataset_example62.run.cpp | 4 +- .../ROOT}/examples/dataset_example63.output | 4 +- .../examples/dataset_example63.run-fail.cpp | 4 +- .../ROOT}/examples/dataset_example64.output | 4 +- .../examples/dataset_example64.run-fail.cpp | 4 +- .../ROOT}/examples/dataset_example65.output | 4 +- .../ROOT}/examples/dataset_example65.run.cpp | 4 +- .../ROOT}/examples/dataset_example66.output | 4 +- .../ROOT}/examples/dataset_example66.run.cpp | 4 +- .../ROOT}/examples/dataset_example67.output | 4 +- .../ROOT}/examples/dataset_example67.run.cpp | 4 +- .../ROOT}/examples/dataset_example68.output | 4 +- .../examples/dataset_example68.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_00.output | 4 +- .../ROOT}/examples/decorator_00.run.cpp | 4 +- .../ROOT}/examples/decorator_01.output | 4 +- .../ROOT}/examples/decorator_01.run.cpp | 4 +- .../ROOT}/examples/decorator_02.output | 4 +- .../ROOT}/examples/decorator_02.run.cpp | 4 +- .../ROOT}/examples/decorator_03.output | 4 +- .../ROOT}/examples/decorator_03.run.cpp | 4 +- .../ROOT}/examples/decorator_04.output | 4 +- .../ROOT}/examples/decorator_04.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_05.output | 4 +- .../ROOT}/examples/decorator_05.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_06.output | 4 +- .../ROOT}/examples/decorator_06.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_07.output | 4 +- .../ROOT}/examples/decorator_07.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_08.output | 4 +- .../ROOT}/examples/decorator_08.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_09.output | 4 +- .../ROOT}/examples/decorator_09.run.cpp | 4 +- .../ROOT}/examples/decorator_10.output | 4 +- .../ROOT}/examples/decorator_10.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_11.output | 4 +- .../ROOT}/examples/decorator_11.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_12.output | 4 +- .../ROOT}/examples/decorator_12.run.cpp | 4 +- .../ROOT}/examples/decorator_13.output | 4 +- .../ROOT}/examples/decorator_13.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_20.output | 4 +- .../ROOT}/examples/decorator_20.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_21.output | 4 +- .../ROOT}/examples/decorator_21.run-fail.cpp | 4 +- .../ROOT}/examples/decorator_22.output | 4 +- .../ROOT}/examples/decorator_22.run.cpp | 4 +- .../ROOT}/examples/decorator_23.output | 4 +- .../ROOT}/examples/decorator_23.run.cpp | 4 +- .../ROOT}/examples/example01.output | 4 +- .../ROOT}/examples/example01.run.cpp | 4 +- .../ROOT}/examples/example03.output | 4 +- .../ROOT}/examples/example03.run-fail.cpp | 4 +- .../ROOT}/examples/example06.output | 4 +- .../ROOT}/examples/example06.run.cpp | 4 +- .../ROOT}/examples/example07.output | 4 +- .../ROOT}/examples/example07.run-fail.cpp | 4 +- .../ROOT}/examples/example08.output | 4 +- .../ROOT}/examples/example08.run-fail.cpp | 4 +- .../ROOT}/examples/example09.output | 4 +- .../ROOT}/examples/example09.run-fail.cpp | 4 +- .../ROOT}/examples/example10.output | 4 +- .../ROOT}/examples/example10.run-fail.cpp | 4 +- .../ROOT}/examples/example11.output | 4 +- .../ROOT}/examples/example11.run.cpp | 4 +- .../ROOT}/examples/example12.output | 4 +- .../ROOT}/examples/example12.run-fail.cpp | 4 +- .../ROOT}/examples/example13.output | 4 +- .../ROOT}/examples/example13.run.cpp | 4 +- .../ROOT}/examples/example14.output | 4 +- .../ROOT}/examples/example14.run.cpp | 4 +- .../ROOT}/examples/example15.output | 4 +- .../ROOT}/examples/example15.run.cpp | 4 +- .../ROOT}/examples/example16.output | 4 +- .../ROOT}/examples/example16.run.cpp | 4 +- .../ROOT}/examples/example17.output | 4 +- .../ROOT}/examples/example17.run.cpp | 4 +- .../ROOT}/examples/example18.output | 4 +- .../ROOT}/examples/example18.run-fail.cpp | 4 +- .../ROOT}/examples/example20.output | 4 +- .../ROOT}/examples/example20.run.cpp | 4 +- .../ROOT}/examples/example21.output | 4 +- .../ROOT}/examples/example21.run.cpp | 4 +- .../ROOT}/examples/example22.output | 6 +- .../ROOT}/examples/example22.run-fail.cpp | 4 +- .../ROOT}/examples/example23.output | 4 +- .../ROOT}/examples/example23.run-fail.cpp | 4 +- doc/modules/ROOT/examples/example24.output | 5 ++ .../ROOT}/examples/example24.run.cpp | 4 +- .../ROOT}/examples/example25.output | 4 +- .../ROOT}/examples/example25.run-fail.cpp | 4 +- .../ROOT}/examples/example26.output | 4 +- .../ROOT}/examples/example26.run-fail.cpp | 4 +- .../ROOT}/examples/example28.output | 4 +- .../ROOT}/examples/example28.run-fail.cpp | 4 +- .../ROOT}/examples/example29.output | 4 +- .../ROOT}/examples/example29.run-fail.cpp | 4 +- .../ROOT}/examples/example30.output | 4 +- .../ROOT}/examples/example30.run-fail.cpp | 4 +- .../ROOT}/examples/example31.output | 4 +- .../ROOT}/examples/example31.run-fail.cpp | 4 +- .../ROOT}/examples/example32.output | 4 +- .../ROOT}/examples/example32.run-fail.cpp | 4 +- .../ROOT}/examples/example33.output | 4 +- .../ROOT}/examples/example33.run-fail.cpp | 4 +- .../ROOT}/examples/example34.output | 4 +- .../ROOT}/examples/example34.run-fail.cpp | 4 +- .../ROOT}/examples/example35.output | 4 +- .../ROOT}/examples/example35.run-fail.cpp | 4 +- .../ROOT}/examples/example36.output | 4 +- .../ROOT}/examples/example36.run-fail.cpp | 4 +- .../ROOT}/examples/example38.output | 4 +- .../ROOT}/examples/example38.run.cpp | 4 +- .../ROOT}/examples/example40.output | 4 +- .../ROOT}/examples/example40.run.cpp | 4 +- .../ROOT}/examples/example41.output | 4 +- .../ROOT}/examples/example41.run-fail.cpp | 4 +- .../ROOT}/examples/example42.output | 4 +- .../ROOT}/examples/example42.run-fail.cpp | 4 +- .../ROOT}/examples/example43.output | 4 +- .../ROOT}/examples/example43.run.cpp | 4 +- .../ROOT}/examples/example44.output | 4 +- .../ROOT}/examples/example44.run-fail.cpp | 4 +- .../ROOT}/examples/example46.output | 4 +- .../ROOT}/examples/example46.run-fail.cpp | 4 +- .../ROOT}/examples/example47.output | 4 +- .../ROOT}/examples/example47.run-fail.cpp | 4 +- .../ROOT}/examples/example48.output | 4 +- .../ROOT}/examples/example48.run-fail.cpp | 4 +- .../ROOT}/examples/example49.output | 4 +- .../ROOT}/examples/example49.run.cpp | 4 +- .../ROOT}/examples/example50.output | 4 +- .../ROOT}/examples/example50.run-fail.cpp | 4 +- .../ROOT}/examples/example51.output | 4 +- .../ROOT}/examples/example51.run.cpp | 4 +- .../ROOT}/examples/example52.output | 4 +- .../ROOT}/examples/example52.run-fail.cpp | 4 +- .../ROOT}/examples/example53.output | 4 +- .../ROOT}/examples/example53.run-fail.cpp | 4 +- .../ROOT}/examples/example54.output | 4 +- .../ROOT}/examples/example54.run-fail.cpp | 4 +- .../ROOT}/examples/example55.output | 4 +- .../ROOT}/examples/example55.run-fail.cpp | 4 +- .../ROOT}/examples/example56.output | 4 +- .../ROOT}/examples/example56.run-fail.cpp | 4 +- .../ROOT}/examples/example57.output | 4 +- .../ROOT}/examples/example57.run-fail.cpp | 4 +- .../ROOT}/examples/example58.output | 4 +- .../ROOT}/examples/example58.run-fail.cpp | 4 +- .../ROOT}/examples/example80_contexts.output | 4 +- .../examples/example80_contexts.run-fail.cpp | 4 +- .../ROOT}/examples/example81_contexts.output | 4 +- .../examples/example81_contexts.run-fail.cpp | 4 +- .../ROOT}/examples/example82_contexts.output | 4 +- .../examples/example82_contexts.run-fail.cpp | 4 +- .../ROOT}/examples/example83_contexts.output | 4 +- .../examples/example83_contexts.run-fail.cpp | 4 +- .../ROOT}/examples/example84_contexts.output | 4 +- .../examples/example84_contexts.run-fail.cpp | 4 +- .../ROOT}/examples/exception_api.output | 4 +- .../ROOT}/examples/exception_api.run-fail.cpp | 4 +- .../ROOT}/examples/exception_check.output | 4 +- .../examples/exception_check.run-fail.cpp | 4 +- .../examples/exception_check_predicate.output | 4 +- .../exception_check_predicate.run-fail.cpp | 4 +- .../ROOT/examples/exception_nothrow.output | 9 +++ .../examples/exception_nothrow.run-fail.cpp | 4 +- .../ROOT}/examples/exception_uncaught.output | 4 +- .../examples/exception_uncaught.run-fail.cpp | 4 +- .../ROOT}/examples/fixture_02.output | 4 +- .../ROOT}/examples/fixture_02.run.cpp | 4 +- .../ROOT}/examples/fixture_03.output | 4 +- .../ROOT}/examples/fixture_03.run.cpp | 4 +- .../ROOT}/examples/fixture_04.output | 4 +- .../ROOT}/examples/fixture_04.run-fail.cpp | 4 +- .../logger-customization-point.output | 4 +- .../logger-customization-point.run-fail.cpp | 4 +- .../examples/runtime-configuration_1.output | 4 +- .../runtime-configuration_1.run-fail.cpp | 4 +- .../examples/runtime-configuration_2.output | 4 +- .../runtime-configuration_2.run-fail.cpp | 4 +- .../examples/runtime-configuration_3.output | 4 +- .../runtime-configuration_3.run-fail.cpp | 4 +- .../runtime-configuration_4-test-fail.txt | 0 .../examples/runtime-configuration_4-test.txt | 0 .../examples/runtime-configuration_4.output | 4 +- .../runtime-configuration_4.run-fail.cpp | 4 +- .../ROOT/examples/snippets}/const_string.hpp | 0 .../examples/snippets}/const_string_test.cpp | 0 .../snippets}/dataset_1/CMakeLists.txt | 0 .../snippets}/dataset_1/test_file.cpp | 16 ++--- .../ROOT/examples/snippets/snippet12.cpp | 50 +++++++++++++++ .../ROOT/examples/snippets}/snippet13.cpp | 6 +- .../ROOT/examples/snippets}/snippet14.cpp | 4 +- .../ROOT/examples/snippets}/snippet15.cpp | 32 +++++----- .../ROOT/examples/snippets}/snippet16.cpp | 4 +- .../ROOT/examples/snippets}/snippet17.cpp | 22 +++---- .../ROOT/examples/snippets}/snippet8.cpp | 4 +- .../ROOT}/examples/tolerance_01.output | 4 +- .../ROOT}/examples/tolerance_01.run-fail.cpp | 4 +- .../ROOT}/examples/tolerance_02.output | 4 +- .../ROOT}/examples/tolerance_02.run-fail.cpp | 4 +- .../ROOT}/examples/tolerance_03.output | 4 +- .../ROOT}/examples/tolerance_03.run-fail.cpp | 4 +- .../ROOT}/examples/tolerance_04.output | 4 +- .../ROOT}/examples/tolerance_04.run-fail.cpp | 4 +- doc/modules/ROOT/examples/tolerance_05.output | 8 +++ .../ROOT}/examples/tolerance_05.run-fail.cpp | 4 +- .../ROOT}/examples/tolerance_06.output | 4 +- .../ROOT}/examples/tolerance_06.run-fail.cpp | 4 +- doc/modules/ROOT/partials/bt_example.adoc | 26 ++++++++ doc/snippet/snippet12.cpp | 64 ------------------- doc/tools/qbk2adoc.py | 38 ++++++----- test/CMakeLists.txt | 4 +- test/Jamfile.v2 | 20 +++--- 256 files changed, 640 insertions(+), 622 deletions(-) delete mode 100644 doc/examples/example24.output delete mode 100644 doc/examples/exception_nothrow.output delete mode 100644 doc/examples/tolerance_05.output rename doc/{ => modules/ROOT}/examples/boost_runtime_list_content.output (86%) rename doc/{ => modules/ROOT}/examples/boost_runtime_list_content.run.cpp (98%) rename doc/{ => modules/ROOT}/examples/boost_test_bitwise.output (94%) rename doc/{ => modules/ROOT}/examples/boost_test_bitwise.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/boost_test_container_default.output (91%) rename doc/{ => modules/ROOT}/examples/boost_test_container_default.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/boost_test_container_lex.output (96%) rename doc/{ => modules/ROOT}/examples/boost_test_container_lex.run-fail.cpp (96%) rename doc/{ => modules/ROOT}/examples/boost_test_container_lex_default.output (95%) rename doc/{ => modules/ROOT}/examples/boost_test_container_lex_default.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/boost_test_macro2.output (90%) rename doc/{ => modules/ROOT}/examples/boost_test_macro2.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/boost_test_macro3.output (93%) rename doc/{ => modules/ROOT}/examples/boost_test_macro3.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_container_c_array.output (94%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_container_c_array.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_overview.output (95%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_overview.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_workaround.output (92%) rename doc/{ => modules/ROOT}/examples/boost_test_macro_workaround.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/boost_test_message.output (90%) rename doc/{ => modules/ROOT}/examples/boost_test_message.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/boost_test_sequence_per_element.output (96%) rename doc/{ => modules/ROOT}/examples/boost_test_sequence_per_element.run-fail.cpp (96%) rename doc/{ => modules/ROOT}/examples/boost_test_string.output (93%) rename doc/{ => modules/ROOT}/examples/boost_test_string.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/custom_init.output (78%) rename doc/{ => modules/ROOT}/examples/custom_init.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/custom_main.output (78%) rename doc/{ => modules/ROOT}/examples/custom_main.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/custom_obsolete_init.output (79%) rename doc/{ => modules/ROOT}/examples/custom_obsolete_init.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/dataset_example59.output (86%) rename doc/{ => modules/ROOT}/examples/dataset_example59.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/dataset_example61.output (63%) rename doc/{ => modules/ROOT}/examples/dataset_example61.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/dataset_example62.output (61%) rename doc/{ => modules/ROOT}/examples/dataset_example62.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/dataset_example63.output (91%) rename doc/{ => modules/ROOT}/examples/dataset_example63.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/dataset_example64.output (91%) rename doc/{ => modules/ROOT}/examples/dataset_example64.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/dataset_example65.output (70%) rename doc/{ => modules/ROOT}/examples/dataset_example65.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/dataset_example66.output (66%) rename doc/{ => modules/ROOT}/examples/dataset_example66.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/dataset_example67.output (83%) rename doc/{ => modules/ROOT}/examples/dataset_example67.run.cpp (97%) rename doc/{ => modules/ROOT}/examples/dataset_example68.output (89%) rename doc/{ => modules/ROOT}/examples/dataset_example68.run-fail.cpp (97%) rename doc/{ => modules/ROOT}/examples/decorator_00.output (73%) rename doc/{ => modules/ROOT}/examples/decorator_00.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_01.output (76%) rename doc/{ => modules/ROOT}/examples/decorator_01.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_02.output (62%) rename doc/{ => modules/ROOT}/examples/decorator_02.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/decorator_03.output (77%) rename doc/{ => modules/ROOT}/examples/decorator_03.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/decorator_04.output (93%) rename doc/{ => modules/ROOT}/examples/decorator_04.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_05.output (82%) rename doc/{ => modules/ROOT}/examples/decorator_05.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_06.output (81%) rename doc/{ => modules/ROOT}/examples/decorator_06.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_07.output (96%) rename doc/{ => modules/ROOT}/examples/decorator_07.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/decorator_08.output (93%) rename doc/{ => modules/ROOT}/examples/decorator_08.run-fail.cpp (96%) rename doc/{ => modules/ROOT}/examples/decorator_09.output (67%) rename doc/{ => modules/ROOT}/examples/decorator_09.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_10.output (92%) rename doc/{ => modules/ROOT}/examples/decorator_10.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/decorator_11.output (82%) rename doc/{ => modules/ROOT}/examples/decorator_11.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/decorator_12.output (78%) rename doc/{ => modules/ROOT}/examples/decorator_12.run.cpp (95%) rename doc/{ => modules/ROOT}/examples/decorator_13.output (94%) rename doc/{ => modules/ROOT}/examples/decorator_13.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/decorator_20.output (87%) rename doc/{ => modules/ROOT}/examples/decorator_20.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/decorator_21.output (92%) rename doc/{ => modules/ROOT}/examples/decorator_21.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/decorator_22.output (93%) rename doc/{ => modules/ROOT}/examples/decorator_22.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/decorator_23.output (93%) rename doc/{ => modules/ROOT}/examples/decorator_23.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/example01.output (90%) rename doc/{ => modules/ROOT}/examples/example01.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/example03.output (80%) rename doc/{ => modules/ROOT}/examples/example03.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/example06.output (53%) rename doc/{ => modules/ROOT}/examples/example06.run.cpp (91%) rename doc/{ => modules/ROOT}/examples/example07.output (84%) rename doc/{ => modules/ROOT}/examples/example07.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example08.output (89%) rename doc/{ => modules/ROOT}/examples/example08.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/example09.output (79%) rename doc/{ => modules/ROOT}/examples/example09.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example10.output (79%) rename doc/{ => modules/ROOT}/examples/example10.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/example11.output (91%) rename doc/{ => modules/ROOT}/examples/example11.run.cpp (95%) rename doc/{ => modules/ROOT}/examples/example12.output (84%) rename doc/{ => modules/ROOT}/examples/example12.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/example13.output (50%) rename doc/{ => modules/ROOT}/examples/example13.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/example14.output (84%) rename doc/{ => modules/ROOT}/examples/example14.run.cpp (90%) rename doc/{ => modules/ROOT}/examples/example15.output (84%) rename doc/{ => modules/ROOT}/examples/example15.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/example16.output (79%) rename doc/{ => modules/ROOT}/examples/example16.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/example17.output (89%) rename doc/{ => modules/ROOT}/examples/example17.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/example18.output (85%) rename doc/{ => modules/ROOT}/examples/example18.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example20.output (63%) rename doc/{ => modules/ROOT}/examples/example20.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/example21.output (76%) rename doc/{ => modules/ROOT}/examples/example21.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/example22.output (57%) rename doc/{ => modules/ROOT}/examples/example22.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/example23.output (83%) rename doc/{ => modules/ROOT}/examples/example23.run-fail.cpp (93%) create mode 100644 doc/modules/ROOT/examples/example24.output rename doc/{ => modules/ROOT}/examples/example24.run.cpp (90%) rename doc/{ => modules/ROOT}/examples/example25.output (71%) rename doc/{ => modules/ROOT}/examples/example25.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/example26.output (65%) rename doc/{ => modules/ROOT}/examples/example26.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example28.output (78%) rename doc/{ => modules/ROOT}/examples/example28.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example29.output (80%) rename doc/{ => modules/ROOT}/examples/example29.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/example30.output (77%) rename doc/{ => modules/ROOT}/examples/example30.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example31.output (79%) rename doc/{ => modules/ROOT}/examples/example31.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/example32.output (74%) rename doc/{ => modules/ROOT}/examples/example32.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example33.output (91%) rename doc/{ => modules/ROOT}/examples/example33.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example34.output (86%) rename doc/{ => modules/ROOT}/examples/example34.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example35.output (76%) rename doc/{ => modules/ROOT}/examples/example35.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example36.output (82%) rename doc/{ => modules/ROOT}/examples/example36.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example38.output (76%) rename doc/{ => modules/ROOT}/examples/example38.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/example40.output (82%) rename doc/{ => modules/ROOT}/examples/example40.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/example41.output (76%) rename doc/{ => modules/ROOT}/examples/example41.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/example42.output (79%) rename doc/{ => modules/ROOT}/examples/example42.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/example43.output (53%) rename doc/{ => modules/ROOT}/examples/example43.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/example44.output (79%) rename doc/{ => modules/ROOT}/examples/example44.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example46.output (72%) rename doc/{ => modules/ROOT}/examples/example46.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example47.output (74%) rename doc/{ => modules/ROOT}/examples/example47.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example48.output (87%) rename doc/{ => modules/ROOT}/examples/example48.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/example49.output (82%) rename doc/{ => modules/ROOT}/examples/example49.run.cpp (92%) rename doc/{ => modules/ROOT}/examples/example50.output (75%) rename doc/{ => modules/ROOT}/examples/example50.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example51.output (73%) rename doc/{ => modules/ROOT}/examples/example51.run.cpp (93%) rename doc/{ => modules/ROOT}/examples/example52.output (68%) rename doc/{ => modules/ROOT}/examples/example52.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example53.output (93%) rename doc/{ => modules/ROOT}/examples/example53.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example54.output (74%) rename doc/{ => modules/ROOT}/examples/example54.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example55.output (74%) rename doc/{ => modules/ROOT}/examples/example55.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example56.output (74%) rename doc/{ => modules/ROOT}/examples/example56.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example57.output (74%) rename doc/{ => modules/ROOT}/examples/example57.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example58.output (74%) rename doc/{ => modules/ROOT}/examples/example58.run-fail.cpp (90%) rename doc/{ => modules/ROOT}/examples/example80_contexts.output (81%) rename doc/{ => modules/ROOT}/examples/example80_contexts.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/example81_contexts.output (91%) rename doc/{ => modules/ROOT}/examples/example81_contexts.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example82_contexts.output (94%) rename doc/{ => modules/ROOT}/examples/example82_contexts.run-fail.cpp (96%) rename doc/{ => modules/ROOT}/examples/example83_contexts.output (92%) rename doc/{ => modules/ROOT}/examples/example83_contexts.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/example84_contexts.output (94%) rename doc/{ => modules/ROOT}/examples/example84_contexts.run-fail.cpp (98%) rename doc/{ => modules/ROOT}/examples/exception_api.output (92%) rename doc/{ => modules/ROOT}/examples/exception_api.run-fail.cpp (97%) rename doc/{ => modules/ROOT}/examples/exception_check.output (75%) rename doc/{ => modules/ROOT}/examples/exception_check.run-fail.cpp (91%) rename doc/{ => modules/ROOT}/examples/exception_check_predicate.output (92%) rename doc/{ => modules/ROOT}/examples/exception_check_predicate.run-fail.cpp (94%) create mode 100644 doc/modules/ROOT/examples/exception_nothrow.output rename doc/{ => modules/ROOT}/examples/exception_nothrow.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/exception_uncaught.output (91%) rename doc/{ => modules/ROOT}/examples/exception_uncaught.run-fail.cpp (93%) rename doc/{ => modules/ROOT}/examples/fixture_02.output (78%) rename doc/{ => modules/ROOT}/examples/fixture_02.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/fixture_03.output (75%) rename doc/{ => modules/ROOT}/examples/fixture_03.run.cpp (94%) rename doc/{ => modules/ROOT}/examples/fixture_04.output (86%) rename doc/{ => modules/ROOT}/examples/fixture_04.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/logger-customization-point.output (91%) rename doc/{ => modules/ROOT}/examples/logger-customization-point.run-fail.cpp (96%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_1.output (93%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_1.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_2.output (96%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_2.run-fail.cpp (97%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_3.output (95%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_3.run-fail.cpp (97%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_4-test-fail.txt (100%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_4-test.txt (100%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_4.output (96%) rename doc/{ => modules/ROOT}/examples/runtime-configuration_4.run-fail.cpp (98%) rename doc/{snippet => modules/ROOT/examples/snippets}/const_string.hpp (100%) rename doc/{snippet => modules/ROOT/examples/snippets}/const_string_test.cpp (100%) rename doc/{snippet => modules/ROOT/examples/snippets}/dataset_1/CMakeLists.txt (100%) rename doc/{snippet => modules/ROOT/examples/snippets}/dataset_1/test_file.cpp (91%) create mode 100644 doc/modules/ROOT/examples/snippets/snippet12.cpp rename doc/{snippet => modules/ROOT/examples/snippets}/snippet13.cpp (79%) rename doc/{snippet => modules/ROOT/examples/snippets}/snippet14.cpp (94%) rename doc/{snippet => modules/ROOT/examples/snippets}/snippet15.cpp (56%) rename doc/{snippet => modules/ROOT/examples/snippets}/snippet16.cpp (90%) rename doc/{snippet => modules/ROOT/examples/snippets}/snippet17.cpp (50%) rename doc/{snippet => modules/ROOT/examples/snippets}/snippet8.cpp (96%) rename doc/{ => modules/ROOT}/examples/tolerance_01.output (83%) rename doc/{ => modules/ROOT}/examples/tolerance_01.run-fail.cpp (92%) rename doc/{ => modules/ROOT}/examples/tolerance_02.output (86%) rename doc/{ => modules/ROOT}/examples/tolerance_02.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/tolerance_03.output (92%) rename doc/{ => modules/ROOT}/examples/tolerance_03.run-fail.cpp (95%) rename doc/{ => modules/ROOT}/examples/tolerance_04.output (88%) rename doc/{ => modules/ROOT}/examples/tolerance_04.run-fail.cpp (95%) create mode 100644 doc/modules/ROOT/examples/tolerance_05.output rename doc/{ => modules/ROOT}/examples/tolerance_05.run-fail.cpp (94%) rename doc/{ => modules/ROOT}/examples/tolerance_06.output (83%) rename doc/{ => modules/ROOT}/examples/tolerance_06.run-fail.cpp (94%) create mode 100644 doc/modules/ROOT/partials/bt_example.adoc delete mode 100644 doc/snippet/snippet12.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9db99e0469..47ea6a7d9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: with: enable_pr_coverage: false # Disabled: Too many issues with lcov enable_cygwin: false - depinst_args: --include doc/examples + depinst_args: --include doc/modules enable_mingw: false enable_multiarch: false timeout: 360 diff --git a/doc/examples/example24.output b/doc/examples/example24.output deleted file mode 100644 index fe04eb855f..0000000000 --- a/doc/examples/example24.output +++ /dev/null @@ -1,5 +0,0 @@ -//[example_output -Hello, world - -no errors detected -//] \ No newline at end of file diff --git a/doc/examples/exception_nothrow.output b/doc/examples/exception_nothrow.output deleted file mode 100644 index 47eba07913..0000000000 --- a/doc/examples/exception_nothrow.output +++ /dev/null @@ -1,9 +0,0 @@ -//[example_output -> example -Running 1 test case... -../doc/examples/exception_nothrow.run-fail.cpp:18: error: in "test": exception thrown by some_func(-1) -../doc/examples/exception_nothrow.run-fail.cpp:24: error: in "test": exception thrown by do { int i(-2); some_func(i); - } while(0) - -*** 2 failures are detected in the test module "example" -//] \ No newline at end of file diff --git a/doc/examples/tolerance_05.output b/doc/examples/tolerance_05.output deleted file mode 100644 index 48e9edf8e3..0000000000 --- a/doc/examples/tolerance_05.output +++ /dev/null @@ -1,8 +0,0 @@ -//[example_output -> tolerance_05 -Running 1 test case... -../doc/examples/tolerance_05.run.cpp(20): error: in "test": check o1 == o2 has failed [ 1 != 0.99] -../doc/examples/tolerance_05.run.cpp(21): error: in "test": check o1 == d2 has failed [ 1 != 0.98999999999999999] - -*** 2 failures are detected in the test module "tolerance_05" -//] \ No newline at end of file diff --git a/doc/examples/boost_runtime_list_content.output b/doc/modules/ROOT/examples/boost_runtime_list_content.output similarity index 86% rename from doc/examples/boost_runtime_list_content.output rename to doc/modules/ROOT/examples/boost_runtime_list_content.output index 607d678ef6..1bc2afcb22 100644 --- a/doc/examples/boost_runtime_list_content.output +++ b/doc/modules/ROOT/examples/boost_runtime_list_content.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_runtime_list_content --list_content s1*: disabled suite 1 test1*: enabled @@ -13,4 +13,4 @@ s2* test1 test2 test3* -//] +// end::example_output[] diff --git a/doc/examples/boost_runtime_list_content.run.cpp b/doc/modules/ROOT/examples/boost_runtime_list_content.run.cpp similarity index 98% rename from doc/examples/boost_runtime_list_content.run.cpp rename to doc/modules/ROOT/examples/boost_runtime_list_content.run.cpp index dbc19b7c0c..1d34364c74 100644 --- a/doc/examples/boost_runtime_list_content.run.cpp +++ b/doc/modules/ROOT/examples/boost_runtime_list_content.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE list_content #include namespace utf=boost::unit_test; @@ -105,4 +105,4 @@ BOOST_AUTO_TEST_CASE( test1, // s1/s14/test1 BOOST_AUTO_TEST_SUITE_END() // s1/s14 BOOST_AUTO_TEST_SUITE_END() // s1 -//] +// end::example_code[] diff --git a/doc/examples/boost_test_bitwise.output b/doc/modules/ROOT/examples/boost_test_bitwise.output similarity index 94% rename from doc/examples/boost_test_bitwise.output rename to doc/modules/ROOT/examples/boost_test_bitwise.output index 92770d7139..e0d44dffbc 100644 --- a/doc/examples/boost_test_bitwise.output +++ b/doc/modules/ROOT/examples/boost_test_bitwise.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_bitwise --log_level=all Running 1 test case... Entering test module "boost_test_bitwise" @@ -18,4 +18,4 @@ test.cpp(13): Leaving test case "test_bitwise"; testing time: 627us Leaving test module "boost_test_bitwise"; testing time: 772us *** 3 failures are detected in the test module "boost_test_bitwise" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_bitwise.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_bitwise.run-fail.cpp similarity index 93% rename from doc/examples/boost_test_bitwise.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_bitwise.run-fail.cpp index 307905f65c..78a732601f 100644 --- a/doc/examples/boost_test_bitwise.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_bitwise.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_bitwise #include #include @@ -20,4 +20,4 @@ BOOST_AUTO_TEST_CASE(test_bitwise) int b = 0x88; BOOST_TEST( a == b, tt::bitwise() ); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_container_default.output b/doc/modules/ROOT/examples/boost_test_container_default.output similarity index 91% rename from doc/examples/boost_test_container_default.output rename to doc/modules/ROOT/examples/boost_test_container_default.output index b133a2b736..c860ffc525 100644 --- a/doc/examples/boost_test_container_default.output +++ b/doc/modules/ROOT/examples/boost_test_container_default.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_container_default --log_level=all Running 1 test case... Entering test module "boost_test_sequence" @@ -10,4 +10,4 @@ test.cpp(13): Leaving test case "test_collections_vectors"; testing time: 208us Leaving test module "boost_test_sequence"; testing time: 286us *** 1 failure is detected in the test module "boost_test_container_default" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_container_default.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_container_default.run-fail.cpp similarity index 93% rename from doc/examples/boost_test_container_default.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_container_default.run-fail.cpp index b2c5c68601..46548475c0 100644 --- a/doc/examples/boost_test_container_default.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_container_default.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_sequence #include #include @@ -24,4 +24,4 @@ BOOST_AUTO_TEST_CASE( test_collections_vectors ) BOOST_TEST(a >= c); BOOST_TEST(a != c); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_container_lex.output b/doc/modules/ROOT/examples/boost_test_container_lex.output similarity index 96% rename from doc/examples/boost_test_container_lex.output rename to doc/modules/ROOT/examples/boost_test_container_lex.output index d7053c1800..bf84d6b960 100644 --- a/doc/examples/boost_test_container_lex.output +++ b/doc/modules/ROOT/examples/boost_test_container_lex.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_container_lex --log_level=all Running 2 test cases... Entering test module "boost_test_container_lex" @@ -21,4 +21,4 @@ test.cpp:28: Leaving test case "test_compare_c_arrays_lexicographic"; testing ti Leaving test module "boost_test_container_lex"; testing time: 323us *** 5 failures are detected in the test module "boost_test_container_lex" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_container_lex.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_container_lex.run-fail.cpp similarity index 96% rename from doc/examples/boost_test_container_lex.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_container_lex.run-fail.cpp index 8d03e01a8a..88d1e5b4df 100644 --- a/doc/examples/boost_test_container_lex.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_container_lex.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_container_lex #include #include @@ -36,4 +36,4 @@ BOOST_AUTO_TEST_CASE( test_compare_c_arrays_lexicographic ) BOOST_TEST(b < c, boost::test_tools::lexicographic()); BOOST_TEST(c < a, boost::test_tools::lexicographic()); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_container_lex_default.output b/doc/modules/ROOT/examples/boost_test_container_lex_default.output similarity index 95% rename from doc/examples/boost_test_container_lex_default.output rename to doc/modules/ROOT/examples/boost_test_container_lex_default.output index a7e99ee4fe..6427eefe35 100644 --- a/doc/examples/boost_test_container_lex_default.output +++ b/doc/modules/ROOT/examples/boost_test_container_lex_default.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_container_lex_default --log_level=all Running 1 test case... Entering test module "boost_test_container_lex_default" @@ -16,4 +16,4 @@ test.cpp:17: Leaving test case "test_collections_vectors_lex"; testing time: 155 Leaving test module "boost_test_container_lex_default"; testing time: 177us *** 5 failures are detected in the test module "boost_test_container_lex_default" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_container_lex_default.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_container_lex_default.run-fail.cpp similarity index 95% rename from doc/examples/boost_test_container_lex_default.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_container_lex_default.run-fail.cpp index 727ac6e22b..326d87a208 100644 --- a/doc/examples/boost_test_container_lex_default.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_container_lex_default.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_container_lex_default #include #include @@ -26,4 +26,4 @@ BOOST_AUTO_TEST_CASE( test_collections_vectors_lex ) BOOST_TEST(c < d); // no extended diagnostic BOOST_TEST(c == d); // no extended diagnostic } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_macro2.output b/doc/modules/ROOT/examples/boost_test_macro2.output similarity index 90% rename from doc/examples/boost_test_macro2.output rename to doc/modules/ROOT/examples/boost_test_macro2.output index e94ab1ec76..c49d420394 100644 --- a/doc/examples/boost_test_macro2.output +++ b/doc/modules/ROOT/examples/boost_test_macro2.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_macro2 --log_level=all Running 2 test cases... test.cpp(16): error: in "test_op_precedence": check a % b == c has failed [13 % 2 != 12] @@ -7,4 +7,4 @@ test.cpp(25): error: in "test_op_right_associative": check !a has failed test.cpp(26): error: in "test_op_right_associative": check --a has failed [(bool)0 is false] *** 4 failures are detected in the test module "boost_test_macro2" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_macro2.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_macro2.run-fail.cpp similarity index 93% rename from doc/examples/boost_test_macro2.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_macro2.run-fail.cpp index 57f80b579b..a67bc477fc 100644 --- a/doc/examples/boost_test_macro2.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_macro2.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_macro2 #include @@ -25,4 +25,4 @@ BOOST_AUTO_TEST_CASE( test_op_right_associative ) BOOST_TEST(!a); BOOST_TEST(--a); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_macro3.output b/doc/modules/ROOT/examples/boost_test_macro3.output similarity index 93% rename from doc/examples/boost_test_macro3.output rename to doc/modules/ROOT/examples/boost_test_macro3.output index d5d4616a29..bb276b2cc9 100644 --- a/doc/examples/boost_test_macro3.output +++ b/doc/modules/ROOT/examples/boost_test_macro3.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_macro3 --log_level=all Running 1 test case... Entering test module "boost_test_macro3" @@ -11,4 +11,4 @@ test.cpp(12): Leaving test case "test_op_reportings"; testing time: 484us Leaving test module "boost_test_macro3"; testing time: 588us *** 2 failures are detected in the test module "boost_test_macro3" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_macro3.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp similarity index 91% rename from doc/examples/boost_test_macro3.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp index da1529206c..5fa258e47a 100644 --- a/doc/examples/boost_test_macro3.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_macro3 #include @@ -17,4 +17,4 @@ BOOST_AUTO_TEST_CASE( test_op_reportings ) BOOST_TEST(a - 1 < b); BOOST_TEST(b > a - 1); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_macro_container_c_array.output b/doc/modules/ROOT/examples/boost_test_macro_container_c_array.output similarity index 94% rename from doc/examples/boost_test_macro_container_c_array.output rename to doc/modules/ROOT/examples/boost_test_macro_container_c_array.output index e587b325c3..4aec669cc5 100644 --- a/doc/examples/boost_test_macro_container_c_array.output +++ b/doc/modules/ROOT/examples/boost_test_macro_container_c_array.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_containers_c_arrays --log_level=all Running 1 test case... Entering test module "boost_test_containers_c_arrays" @@ -16,4 +16,4 @@ test.cpp:15: Leaving test case "test_collections_on_c_arrays"; testing time: 204 Leaving test module "boost_test_containers_c_arrays"; testing time: 240us *** 3 failures are detected in the test module "boost_test_containers_c_arrays" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_macro_container_c_array.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_macro_container_c_array.run-fail.cpp similarity index 94% rename from doc/examples/boost_test_macro_container_c_array.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_macro_container_c_array.run-fail.cpp index 0c8c3f029f..1c7eff4fae 100644 --- a/doc/examples/boost_test_macro_container_c_array.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_macro_container_c_array.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_containers_c_arrays #include #include @@ -24,4 +24,4 @@ BOOST_AUTO_TEST_CASE( test_collections_on_c_arrays ) BOOST_TEST(b < c); // lexicographical compare BOOST_TEST(c < a); // lexicographical compare } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_macro_overview.output b/doc/modules/ROOT/examples/boost_test_macro_overview.output similarity index 95% rename from doc/examples/boost_test_macro_overview.output rename to doc/modules/ROOT/examples/boost_test_macro_overview.output index 96803a7e9c..c693b90250 100644 --- a/doc/examples/boost_test_macro_overview.output +++ b/doc/modules/ROOT/examples/boost_test_macro_overview.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_macro_overview --log_level=all Running 1 test case... Entering test module "boost_test_macro_overview" @@ -14,4 +14,4 @@ test.cpp:12: Leaving test case "test_macro_overview"; testing time: 380us Leaving test module "boost_test_macro_overview"; testing time: 459us *** 5 failures are detected in the test module "boost_test_macro_overview" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_macro_overview.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_macro_overview.run-fail.cpp similarity index 93% rename from doc/examples/boost_test_macro_overview.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_macro_overview.run-fail.cpp index bf8f9457cb..15f2b1d388 100644 --- a/doc/examples/boost_test_macro_overview.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_macro_overview.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_macro_overview #include @@ -20,4 +20,4 @@ BOOST_AUTO_TEST_CASE( test_macro_overview ) BOOST_TEST(a == b, tt::bitwise()); BOOST_TEST(a + 0.1 == b - 0.8, tt::tolerance(0.01)); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_macro_workaround.output b/doc/modules/ROOT/examples/boost_test_macro_workaround.output similarity index 92% rename from doc/examples/boost_test_macro_workaround.output rename to doc/modules/ROOT/examples/boost_test_macro_workaround.output index e494298ac3..f146968bd1 100644 --- a/doc/examples/boost_test_macro_workaround.output +++ b/doc/modules/ROOT/examples/boost_test_macro_workaround.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_macro_workaround --log_level=all Running 2 test cases... Entering test module "boost_test_macro_workaround" @@ -11,4 +11,4 @@ test.cpp:20: Leaving test case "test_ternary"; testing time: 123us Leaving test module "boost_test_macro_workaround"; testing time: 547us *** No errors detected -//] +// end::example_output[] diff --git a/doc/examples/boost_test_macro_workaround.run.cpp b/doc/modules/ROOT/examples/boost_test_macro_workaround.run.cpp similarity index 94% rename from doc/examples/boost_test_macro_workaround.run.cpp rename to doc/modules/ROOT/examples/boost_test_macro_workaround.run.cpp index 933cb0a43c..c75802dd79 100644 --- a/doc/examples/boost_test_macro_workaround.run.cpp +++ b/doc/modules/ROOT/examples/boost_test_macro_workaround.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_macro_workaround #include #include @@ -27,4 +27,4 @@ BOOST_AUTO_TEST_CASE( test_ternary ) } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_message.output b/doc/modules/ROOT/examples/boost_test_message.output similarity index 90% rename from doc/examples/boost_test_message.output rename to doc/modules/ROOT/examples/boost_test_message.output index 5e9338309e..44cdf8a870 100644 --- a/doc/examples/boost_test_message.output +++ b/doc/modules/ROOT/examples/boost_test_message.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_message --log_level=all Running 1 test case... Entering test module "boost_test_message" @@ -9,4 +9,4 @@ test.cpp(12): Leaving test case "test_message"; testing time: 219us Leaving test module "boost_test_message"; testing time: 318us *** 1 failure is detected in the test module "boost_test_message" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_message.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_message.run-fail.cpp similarity index 92% rename from doc/examples/boost_test_message.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_message.run-fail.cpp index d87f2bcd2d..c26514a4e5 100644 --- a/doc/examples/boost_test_message.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_message.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_message #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test_message ) BOOST_TEST(a == b, "a should be equal to b: " << a << "!=" << b); BOOST_TEST(a != 10, "value of a=" << a); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_sequence_per_element.output b/doc/modules/ROOT/examples/boost_test_sequence_per_element.output similarity index 96% rename from doc/examples/boost_test_sequence_per_element.output rename to doc/modules/ROOT/examples/boost_test_sequence_per_element.output index a66fd836f9..bb25a695b7 100644 --- a/doc/examples/boost_test_sequence_per_element.output +++ b/doc/modules/ROOT/examples/boost_test_sequence_per_element.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_sequence_per_element Running 2 test cases... test.cpp:21: error: in "test_sequence_per_element": check a == b has failed @@ -30,4 +30,4 @@ Mismatch at position 1: 5 >= 2. Mismatch at position 2: 3 >= 3. *** 10 failures are detected in the test module "boost_test_sequence_per_element" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_sequence_per_element.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_sequence_per_element.run-fail.cpp similarity index 96% rename from doc/examples/boost_test_sequence_per_element.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_sequence_per_element.run-fail.cpp index ed81204116..878f6511fa 100644 --- a/doc/examples/boost_test_sequence_per_element.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_sequence_per_element.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_sequence_per_element #include #include @@ -38,4 +38,4 @@ BOOST_AUTO_TEST_CASE( test_compare_c_arrays_element_wise ) BOOST_TEST(b < c, boost::test_tools::per_element()); BOOST_TEST(c < a, boost::test_tools::per_element()); } -//] +// end::example_code[] diff --git a/doc/examples/boost_test_string.output b/doc/modules/ROOT/examples/boost_test_string.output similarity index 93% rename from doc/examples/boost_test_string.output rename to doc/modules/ROOT/examples/boost_test_string.output index a7cc0a74b7..56edb2faf8 100644 --- a/doc/examples/boost_test_string.output +++ b/doc/modules/ROOT/examples/boost_test_string.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > ./boost_test_strings Running 2 test cases... test.cpp:17: error: in "test_pointers": check pa == pb has failed [0x7fff54f9dea4 != 0x7fff54f9dea0] @@ -14,4 +14,4 @@ test.cpp:29: error: in "test_strings": check b < a has failed Failure at position 4: '2' >= '1'. *** 5 failures are detected in the test module "boost_test_strings" -//] +// end::example_output[] diff --git a/doc/examples/boost_test_string.run-fail.cpp b/doc/modules/ROOT/examples/boost_test_string.run-fail.cpp similarity index 94% rename from doc/examples/boost_test_string.run-fail.cpp rename to doc/modules/ROOT/examples/boost_test_string.run-fail.cpp index d008647084..f5ff651463 100644 --- a/doc/examples/boost_test_string.run-fail.cpp +++ b/doc/modules/ROOT/examples/boost_test_string.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE boost_test_strings #include @@ -28,4 +28,4 @@ BOOST_AUTO_TEST_CASE( test_strings ) BOOST_TEST(std::string("test1") < a, boost::test_tools::per_element()); BOOST_TEST(b < a, boost::test_tools::lexicographic()); } -//] +// end::example_code[] diff --git a/doc/examples/custom_init.output b/doc/modules/ROOT/examples/custom_init.output similarity index 78% rename from doc/examples/custom_init.output rename to doc/modules/ROOT/examples/custom_init.output index 8385f62089..4acf682b5b 100644 --- a/doc/examples/custom_init.output +++ b/doc/modules/ROOT/examples/custom_init.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > custom_init using custom init Running 1 test case... test.cpp(7): error: in "test1": check false has failed *** 1 failure is detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/custom_init.run-fail.cpp b/doc/modules/ROOT/examples/custom_init.run-fail.cpp similarity index 91% rename from doc/examples/custom_init.run-fail.cpp rename to doc/modules/ROOT/examples/custom_init.run-fail.cpp index 7c2d122565..07ea98620e 100644 --- a/doc/examples/custom_init.run-fail.cpp +++ b/doc/modules/ROOT/examples/custom_init.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_ALTERNATIVE_INIT_API #include #include @@ -20,4 +20,4 @@ bool init_unit_test() std::cout << "using custom init" << std::endl; return true; } -//] +// end::example_code[] diff --git a/doc/examples/custom_main.output b/doc/modules/ROOT/examples/custom_main.output similarity index 78% rename from doc/examples/custom_main.output rename to doc/modules/ROOT/examples/custom_main.output index 9f95e87935..07e3e42026 100644 --- a/doc/examples/custom_main.output +++ b/doc/modules/ROOT/examples/custom_main.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > custom_main Using custom entry point... Running 1 test case... test.cpp(10): error: in "test1": check false has failed *** 1 failure is detected in the test module "custom_main" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/custom_main.run-fail.cpp b/doc/modules/ROOT/examples/custom_main.run-fail.cpp similarity index 94% rename from doc/examples/custom_main.run-fail.cpp rename to doc/modules/ROOT/examples/custom_main.run-fail.cpp index 68691ee25f..8a76cae129 100644 --- a/doc/examples/custom_main.run-fail.cpp +++ b/doc/modules/ROOT/examples/custom_main.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE custom_main #define BOOST_TEST_NO_MAIN #define BOOST_TEST_ALTERNATIVE_INIT_API @@ -28,4 +28,4 @@ int main(int argc, char* argv[], char* envp[]) make_use_of(envp); return utf::unit_test_main(init_unit_test, argc, argv); } -//] +// end::example_code[] diff --git a/doc/examples/custom_obsolete_init.output b/doc/modules/ROOT/examples/custom_obsolete_init.output similarity index 79% rename from doc/examples/custom_obsolete_init.output rename to doc/modules/ROOT/examples/custom_obsolete_init.output index f53e5f29d9..a1c1f5669a 100644 --- a/doc/examples/custom_obsolete_init.output +++ b/doc/modules/ROOT/examples/custom_obsolete_init.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > custom_obsolete_init using obsolete init Running 1 test case... test.cpp(6): error: in "test1": check false has failed *** 1 failure is detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/custom_obsolete_init.run-fail.cpp b/doc/modules/ROOT/examples/custom_obsolete_init.run-fail.cpp similarity index 92% rename from doc/examples/custom_obsolete_init.run-fail.cpp rename to doc/modules/ROOT/examples/custom_obsolete_init.run-fail.cpp index b98777686e..cab12e174e 100644 --- a/doc/examples/custom_obsolete_init.run-fail.cpp +++ b/doc/modules/ROOT/examples/custom_obsolete_init.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include @@ -19,4 +19,4 @@ boost::unit_test::test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[ std::cout << "using obsolete init" << std::endl; return 0; } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example59.output b/doc/modules/ROOT/examples/dataset_example59.output similarity index 86% rename from doc/examples/dataset_example59.output rename to doc/modules/ROOT/examples/dataset_example59.output index 1fff11deb9..33a799a1c7 100644 --- a/doc/examples/dataset_example59.output +++ b/doc/modules/ROOT/examples/dataset_example59.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example59 Running 8 test cases... test 1: 0 @@ -14,4 +14,4 @@ Failure occurred in a following context: sample = 7; *** 1 failure is detected in the test module "dataset_example59" -//] +// end::example_output[] diff --git a/doc/examples/dataset_example59.run-fail.cpp b/doc/modules/ROOT/examples/dataset_example59.run-fail.cpp similarity index 94% rename from doc/examples/dataset_example59.run-fail.cpp rename to doc/modules/ROOT/examples/dataset_example59.run-fail.cpp index b288a95c90..435c825cd7 100644 --- a/doc/examples/dataset_example59.run-fail.cpp +++ b/doc/modules/ROOT/examples/dataset_example59.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example59 #include #include @@ -26,4 +26,4 @@ BOOST_DATA_TEST_CASE( std::cout << "test 2: " << sample << std::endl; BOOST_TEST((sample <= 4 && sample >= 0)); } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example61.output b/doc/modules/ROOT/examples/dataset_example61.output similarity index 63% rename from doc/examples/dataset_example61.output rename to doc/modules/ROOT/examples/dataset_example61.output index 8eff76c289..04219ef4c0 100644 --- a/doc/examples/dataset_example61.output +++ b/doc/modules/ROOT/examples/dataset_example61.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > dataset_example61 Running 2 test cases... 1, qwerty 2, asdfg *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/dataset_example61.run.cpp b/doc/modules/ROOT/examples/dataset_example61.run.cpp similarity index 94% rename from doc/examples/dataset_example61.run.cpp rename to doc/modules/ROOT/examples/dataset_example61.run.cpp index 1bedf34254..e0a57c1e33 100644 --- a/doc/examples/dataset_example61.run.cpp +++ b/doc/modules/ROOT/examples/dataset_example61.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example61 #include #include @@ -24,4 +24,4 @@ BOOST_DATA_TEST_CASE( { std::cout << integer_values << ", " << string_value << std::endl; } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example62.output b/doc/modules/ROOT/examples/dataset_example62.output similarity index 61% rename from doc/examples/dataset_example62.output rename to doc/modules/ROOT/examples/dataset_example62.output index 31331044c4..1a3e5334bf 100644 --- a/doc/examples/dataset_example62.output +++ b/doc/modules/ROOT/examples/dataset_example62.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example62 Running 5 test cases... 1 @@ -8,4 +8,4 @@ Running 5 test cases... 10 *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/dataset_example62.run.cpp b/doc/modules/ROOT/examples/dataset_example62.run.cpp similarity index 93% rename from doc/examples/dataset_example62.run.cpp rename to doc/modules/ROOT/examples/dataset_example62.run.cpp index b53bb1ec85..5003d09a69 100644 --- a/doc/examples/dataset_example62.run.cpp +++ b/doc/modules/ROOT/examples/dataset_example62.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example62 #include #include @@ -23,4 +23,4 @@ BOOST_DATA_TEST_CASE( { std::cout << var << std::endl; } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example63.output b/doc/modules/ROOT/examples/dataset_example63.output similarity index 91% rename from doc/examples/dataset_example63.output rename to doc/modules/ROOT/examples/dataset_example63.output index 7f8873647a..337eb053c4 100644 --- a/doc/examples/dataset_example63.output +++ b/doc/modules/ROOT/examples/dataset_example63.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example63 Running 14 test cases... test 1: 2, 0 @@ -20,4 +20,4 @@ test 2: 1.21896, 5 test 2: 1.04704, 6 *** 1 failure is detected in the test module "dataset_example63" -//] +// end::example_output[] diff --git a/doc/examples/dataset_example63.run-fail.cpp b/doc/modules/ROOT/examples/dataset_example63.run-fail.cpp similarity index 95% rename from doc/examples/dataset_example63.run-fail.cpp rename to doc/modules/ROOT/examples/dataset_example63.run-fail.cpp index f2921c8246..371ff287f7 100644 --- a/doc/examples/dataset_example63.run-fail.cpp +++ b/doc/modules/ROOT/examples/dataset_example63.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example63 #include #include @@ -34,4 +34,4 @@ BOOST_DATA_TEST_CASE( << ", " << index << std::endl; BOOST_TEST(random_sample < 1.7); // 30% chance of failure } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example64.output b/doc/modules/ROOT/examples/dataset_example64.output similarity index 91% rename from doc/examples/dataset_example64.output rename to doc/modules/ROOT/examples/dataset_example64.output index 4e72668dbf..95cd76f7fe 100644 --- a/doc/examples/dataset_example64.output +++ b/doc/modules/ROOT/examples/dataset_example64.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example64 Running 12 test cases... test 1: 0, 0 @@ -18,4 +18,4 @@ test 2: 2 / 1.53277, 0 test 2: 2 / 1.21896, 1 *** 1 failure is detected in the test module "dataset_example64" -//] +// end::example_output[] diff --git a/doc/examples/dataset_example64.run-fail.cpp b/doc/modules/ROOT/examples/dataset_example64.run-fail.cpp similarity index 95% rename from doc/examples/dataset_example64.run-fail.cpp rename to doc/modules/ROOT/examples/dataset_example64.run-fail.cpp index 0480793846..d81ec7a5b3 100644 --- a/doc/examples/dataset_example64.run-fail.cpp +++ b/doc/modules/ROOT/examples/dataset_example64.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example64 #include #include @@ -39,4 +39,4 @@ BOOST_DATA_TEST_CASE( << std::endl; BOOST_TEST(random_sample < 1.7); // 30% chance of failure } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example65.output b/doc/modules/ROOT/examples/dataset_example65.output similarity index 70% rename from doc/examples/dataset_example65.output rename to doc/modules/ROOT/examples/dataset_example65.output index 6f3f943408..9dac1eb505 100644 --- a/doc/examples/dataset_example65.output +++ b/doc/modules/ROOT/examples/dataset_example65.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example65 Running 4 test cases... test 1: 2 @@ -7,4 +7,4 @@ test 2: 1, 2 test 2: 2, 2 *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/dataset_example65.run.cpp b/doc/modules/ROOT/examples/dataset_example65.run.cpp similarity index 94% rename from doc/examples/dataset_example65.run.cpp rename to doc/modules/ROOT/examples/dataset_example65.run.cpp index 8b63f36e5a..7a7b083a32 100644 --- a/doc/examples/dataset_example65.run.cpp +++ b/doc/modules/ROOT/examples/dataset_example65.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example65 #include #include @@ -35,4 +35,4 @@ BOOST_DATA_TEST_CASE( << xr << ", " << singleton << std::endl; BOOST_TEST(singleton == 2); } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example66.output b/doc/modules/ROOT/examples/dataset_example66.output similarity index 66% rename from doc/examples/dataset_example66.output rename to doc/modules/ROOT/examples/dataset_example66.output index 77f07d3f97..80e26f101d 100644 --- a/doc/examples/dataset_example66.output +++ b/doc/modules/ROOT/examples/dataset_example66.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > dataset_example66 Running 2 test cases... test 1: 0, cat test 1: 1, dog *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/dataset_example66.run.cpp b/doc/modules/ROOT/examples/dataset_example66.run.cpp similarity index 94% rename from doc/examples/dataset_example66.run.cpp rename to doc/modules/ROOT/examples/dataset_example66.run.cpp index bd4e84785e..ce61de2454 100644 --- a/doc/examples/dataset_example66.run.cpp +++ b/doc/modules/ROOT/examples/dataset_example66.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example66 #include #include @@ -26,4 +26,4 @@ BOOST_DATA_TEST_CASE( << std::endl; BOOST_TEST(array_element != "mammoth"); } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example67.output b/doc/modules/ROOT/examples/dataset_example67.output similarity index 83% rename from doc/examples/dataset_example67.output rename to doc/modules/ROOT/examples/dataset_example67.output index 78c6be42df..0043a7fb0d 100644 --- a/doc/examples/dataset_example67.output +++ b/doc/modules/ROOT/examples/dataset_example67.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > dataset_example67 Running 15 test cases... test 1: 0 @@ -18,4 +18,4 @@ test 2: "5", 5 test 2: "8", 8 *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/dataset_example67.run.cpp b/doc/modules/ROOT/examples/dataset_example67.run.cpp similarity index 97% rename from doc/examples/dataset_example67.run.cpp rename to doc/modules/ROOT/examples/dataset_example67.run.cpp index ce5038f3b3..79163f3021 100644 --- a/doc/examples/dataset_example67.run.cpp +++ b/doc/modules/ROOT/examples/dataset_example67.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example67 #include #include @@ -66,4 +66,4 @@ BOOST_DATA_TEST_CASE( << std::endl; BOOST_TEST(array_element.second <= 13); } -//] +// end::example_code[] diff --git a/doc/examples/dataset_example68.output b/doc/modules/ROOT/examples/dataset_example68.output similarity index 89% rename from doc/examples/dataset_example68.output rename to doc/modules/ROOT/examples/dataset_example68.output index cbca1d0d1d..d80f14eb49 100644 --- a/doc/examples/dataset_example68.output +++ b/doc/modules/ROOT/examples/dataset_example68.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example68 Running 9 test cases... test.cpp(60): error: in "test1/_7": check fib_sample == exp has failed [34 != 35] @@ -9,4 +9,4 @@ Failure occurred in a following context: fib_sample = 55; exp = 56; *** 2 failures are detected in the test module "dataset_example68" -//] +// end::example_output[] diff --git a/doc/examples/dataset_example68.run-fail.cpp b/doc/modules/ROOT/examples/dataset_example68.run-fail.cpp similarity index 97% rename from doc/examples/dataset_example68.run-fail.cpp rename to doc/modules/ROOT/examples/dataset_example68.run-fail.cpp index 371a81902e..d76044c773 100644 --- a/doc/examples/dataset_example68.run-fail.cpp +++ b/doc/modules/ROOT/examples/dataset_example68.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE dataset_example68 #include #include @@ -58,4 +58,4 @@ BOOST_DATA_TEST_CASE( { BOOST_TEST(fib_sample == exp); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_00.output b/doc/modules/ROOT/examples/decorator_00.output similarity index 73% rename from doc/examples/decorator_00.output rename to doc/modules/ROOT/examples/decorator_00.output index dc8cd39e89..386578a81d 100644 --- a/doc/examples/decorator_00.output +++ b/doc/modules/ROOT/examples/decorator_00.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > decorator_00 --list_content test_1*: with description test_1*: with description test_1*: with description test_1*: with description -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_00.run.cpp b/doc/modules/ROOT/examples/decorator_00.run.cpp similarity index 93% rename from doc/examples/decorator_00.run.cpp rename to doc/modules/ROOT/examples/decorator_00.run.cpp index 9bf2f3b096..56769e5d4a 100644 --- a/doc/examples/decorator_00.run.cpp +++ b/doc/modules/ROOT/examples/decorator_00.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_00 #include #include @@ -18,4 +18,4 @@ BOOST_DATA_TEST_CASE(test_1, data::xrange(4)) { BOOST_TEST(sample >= 0); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_01.output b/doc/modules/ROOT/examples/decorator_01.output similarity index 76% rename from doc/examples/decorator_01.output rename to doc/modules/ROOT/examples/decorator_01.output index 92bed6cad3..c9ce232771 100644 --- a/doc/examples/decorator_01.output +++ b/doc/modules/ROOT/examples/decorator_01.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_01 --run_test=@trivial Running 2 test cases... @@ -9,4 +9,4 @@ Running 2 test cases... Running 1 test case... *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_01.run.cpp b/doc/modules/ROOT/examples/decorator_01.run.cpp similarity index 93% rename from doc/examples/decorator_01.run.cpp rename to doc/modules/ROOT/examples/decorator_01.run.cpp index b3b22466f9..8330631929 100644 --- a/doc/examples/decorator_01.run.cpp +++ b/doc/modules/ROOT/examples/decorator_01.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_01 #include namespace utf = boost::unit_test; @@ -22,4 +22,4 @@ BOOST_AUTO_TEST_CASE(test_case2, { BOOST_TEST(1 == 1); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_02.output b/doc/modules/ROOT/examples/decorator_02.output similarity index 62% rename from doc/examples/decorator_02.output rename to doc/modules/ROOT/examples/decorator_02.output index 2d7c7bc63e..de97aa7025 100644 --- a/doc/examples/decorator_02.output +++ b/doc/modules/ROOT/examples/decorator_02.output @@ -1,6 +1,6 @@ -//[example_output +// tag::example_output[] > decorator_02 --run_test=@trivial Running 2 test cases... *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_02.run.cpp b/doc/modules/ROOT/examples/decorator_02.run.cpp similarity index 92% rename from doc/examples/decorator_02.run.cpp rename to doc/modules/ROOT/examples/decorator_02.run.cpp index a7cc8e6ab2..40ec1a812f 100644 --- a/doc/examples/decorator_02.run.cpp +++ b/doc/modules/ROOT/examples/decorator_02.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_02 #include namespace utf = boost::unit_test; @@ -23,4 +23,4 @@ BOOST_AUTO_TEST_SUITE(suite1, * utf::label("trivial")) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_03.output b/doc/modules/ROOT/examples/decorator_03.output similarity index 77% rename from doc/examples/decorator_03.output rename to doc/modules/ROOT/examples/decorator_03.output index 175b3446d7..8976baebd7 100644 --- a/doc/examples/decorator_03.output +++ b/doc/modules/ROOT/examples/decorator_03.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_03 --run_test=@trivial Running 3 test cases... @@ -9,4 +9,4 @@ Running 3 test cases... Running 3 test cases... *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_03.run.cpp b/doc/modules/ROOT/examples/decorator_03.run.cpp similarity index 94% rename from doc/examples/decorator_03.run.cpp rename to doc/modules/ROOT/examples/decorator_03.run.cpp index 04c2b6ce8b..790323c92b 100644 --- a/doc/examples/decorator_03.run.cpp +++ b/doc/modules/ROOT/examples/decorator_03.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_03 #include namespace utf = boost::unit_test; @@ -36,4 +36,4 @@ BOOST_AUTO_TEST_SUITE(suite1) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_04.output b/doc/modules/ROOT/examples/decorator_04.output similarity index 93% rename from doc/examples/decorator_04.output rename to doc/modules/ROOT/examples/decorator_04.output index 7d64724c55..8efe6d931e 100644 --- a/doc/examples/decorator_04.output +++ b/doc/modules/ROOT/examples/decorator_04.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_04 Running 3 test cases... test.cpp(8): error: in "test1": check false has failed @@ -22,4 +22,4 @@ test.cpp(15): error: in "test2": check false has failed *** 1 failure is detected in the test module "decorator_04" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_04.run-fail.cpp b/doc/modules/ROOT/examples/decorator_04.run-fail.cpp similarity index 93% rename from doc/examples/decorator_04.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_04.run-fail.cpp index a5dce6b3fc..69ea2cc76b 100644 --- a/doc/examples/decorator_04.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_04.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_04 #include namespace utf = boost::unit_test; @@ -27,4 +27,4 @@ BOOST_AUTO_TEST_CASE(test3) { BOOST_TEST(false); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_05.output b/doc/modules/ROOT/examples/decorator_05.output similarity index 82% rename from doc/examples/decorator_05.output rename to doc/modules/ROOT/examples/decorator_05.output index 745d27096f..aedce00251 100644 --- a/doc/examples/decorator_05.output +++ b/doc/modules/ROOT/examples/decorator_05.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_05 Running 1 test case... test.cpp(14): error: in "suite1/test2": check 2 != 2 has failed [2 == 2] @@ -10,4 +10,4 @@ test.cpp(14): error: in "suite1/test2": check 2 != 2 has failed [2 == 2] suite1* test1 test2* -//] +// end::example_output[] diff --git a/doc/examples/decorator_05.run-fail.cpp b/doc/modules/ROOT/examples/decorator_05.run-fail.cpp similarity index 93% rename from doc/examples/decorator_05.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_05.run-fail.cpp index 2950514214..65464f6cc0 100644 --- a/doc/examples/decorator_05.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_05.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_05 #include namespace utf = boost::unit_test; @@ -23,4 +23,4 @@ BOOST_AUTO_TEST_SUITE(suite1, * utf::disabled()) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_06.output b/doc/modules/ROOT/examples/decorator_06.output similarity index 81% rename from doc/examples/decorator_06.output rename to doc/modules/ROOT/examples/decorator_06.output index 88b4a023bb..baf47ada7b 100644 --- a/doc/examples/decorator_06.output +++ b/doc/modules/ROOT/examples/decorator_06.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_06 Running 1 test case... test.cpp(11): error: in "test_io": check 1 != 1 has failed [1 == 1] @@ -9,4 +9,4 @@ test.cpp(11): error: in "test_io": check 1 != 1 has failed [1 == 1] > decorator_06 --list_content test_io* test_db -//] +// end::example_output[] diff --git a/doc/examples/decorator_06.run-fail.cpp b/doc/modules/ROOT/examples/decorator_06.run-fail.cpp similarity index 93% rename from doc/examples/decorator_06.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_06.run-fail.cpp index ceee893e53..c7acad9ac5 100644 --- a/doc/examples/decorator_06.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_06.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_06 #include namespace utf = boost::unit_test; @@ -24,4 +24,4 @@ BOOST_AUTO_TEST_CASE(test_db, { BOOST_TEST(2 != 2); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_07.output b/doc/modules/ROOT/examples/decorator_07.output similarity index 96% rename from doc/examples/decorator_07.output rename to doc/modules/ROOT/examples/decorator_07.output index 969127e386..46e91dc85e 100644 --- a/doc/examples/decorator_07.output +++ b/doc/modules/ROOT/examples/decorator_07.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_07 --report_level=detailed --log_level=all Running 4 test cases... Entering test module "decorator_07" @@ -32,4 +32,4 @@ Test module "decorator_07" has failed with: Test case "s1/test1" has passed with: 1 assertion out of 1 passed -//] +// end::example_output[] diff --git a/doc/examples/decorator_07.run-fail.cpp b/doc/modules/ROOT/examples/decorator_07.run-fail.cpp similarity index 95% rename from doc/examples/decorator_07.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_07.run-fail.cpp index 783a4448a2..335cd83620 100644 --- a/doc/examples/decorator_07.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_07.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_07 #include @@ -41,4 +41,4 @@ BOOST_AUTO_TEST_SUITE(s1) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_08.output b/doc/modules/ROOT/examples/decorator_08.output similarity index 93% rename from doc/examples/decorator_08.output rename to doc/modules/ROOT/examples/decorator_08.output index df58eeab47..f50085a9c0 100644 --- a/doc/examples/decorator_08.output +++ b/doc/modules/ROOT/examples/decorator_08.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_08 --log_level=test_suite Running 4 test cases... Entering test module "decorator_08" @@ -14,4 +14,4 @@ test.cpp(45): Test case "test4" is skipped because test2 and test3 failed Leaving test module "decorator_08"; testing time: 16ms *** 2 failures are detected in the test module "decorator_08" -//] +// end::example_output[] diff --git a/doc/examples/decorator_08.run-fail.cpp b/doc/modules/ROOT/examples/decorator_08.run-fail.cpp similarity index 96% rename from doc/examples/decorator_08.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_08.run-fail.cpp index 3aac6864a8..369688cfa2 100644 --- a/doc/examples/decorator_08.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_08.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_08 #include namespace utf = boost::unit_test; @@ -54,4 +54,4 @@ BOOST_AUTO_TEST_CASE(test4, { BOOST_TEST(false); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_09.output b/doc/modules/ROOT/examples/decorator_09.output similarity index 67% rename from doc/examples/decorator_09.output rename to doc/modules/ROOT/examples/decorator_09.output index eda9e71386..899706c531 100644 --- a/doc/examples/decorator_09.output +++ b/doc/modules/ROOT/examples/decorator_09.output @@ -1,5 +1,5 @@ -//[example_output +// tag::example_output[] > decorator_09 --list_content test_1 : enable only when ODBC is available test_2*: descriptions add up -//] +// end::example_output[] diff --git a/doc/examples/decorator_09.run.cpp b/doc/modules/ROOT/examples/decorator_09.run.cpp similarity index 93% rename from doc/examples/decorator_09.run.cpp rename to doc/modules/ROOT/examples/decorator_09.run.cpp index 3b206eb2ed..3df29514e1 100644 --- a/doc/examples/decorator_09.run.cpp +++ b/doc/modules/ROOT/examples/decorator_09.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_09 #include namespace utf = boost::unit_test; @@ -23,4 +23,4 @@ BOOST_AUTO_TEST_CASE(test_2, { BOOST_TEST(2 == 2); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_10.output b/doc/modules/ROOT/examples/decorator_10.output similarity index 92% rename from doc/examples/decorator_10.output rename to doc/modules/ROOT/examples/decorator_10.output index 01ca8e24e6..b618cfb917 100644 --- a/doc/examples/decorator_10.output +++ b/doc/modules/ROOT/examples/decorator_10.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_10 Running 2 test cases... test.cpp(11): error: in "suite1/test1": check false has failed @@ -15,4 +15,4 @@ test.cpp(11): error: in "suite1/test1": check false has failed test.cpp(12): error: in "suite1/test1": check false has failed *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_10.run-fail.cpp b/doc/modules/ROOT/examples/decorator_10.run-fail.cpp similarity index 93% rename from doc/examples/decorator_10.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_10.run-fail.cpp index 4963c17ca2..f7d76cc8c1 100644 --- a/doc/examples/decorator_10.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_10.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_10 #include namespace utf = boost::unit_test; @@ -27,4 +27,4 @@ BOOST_AUTO_TEST_SUITE(suite1, } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_11.output b/doc/modules/ROOT/examples/decorator_11.output similarity index 82% rename from doc/examples/decorator_11.output rename to doc/modules/ROOT/examples/decorator_11.output index 66b66d13aa..5c8540efe0 100644 --- a/doc/examples/decorator_11.output +++ b/doc/modules/ROOT/examples/decorator_11.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > decorator_11 Running 1 test case... unknown location(0): fatal error: in "test1": signal: SIGALRM (timeout while executing function) test.cpp(5): last checkpoint: "test1" entry. *** 1 failures is detected in test module "decorator_11" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_11.run-fail.cpp b/doc/modules/ROOT/examples/decorator_11.run-fail.cpp similarity index 92% rename from doc/examples/decorator_11.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_11.run-fail.cpp index a2c9ae3444..70abde5acc 100644 --- a/doc/examples/decorator_11.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_11.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_11 #include namespace utf = boost::unit_test; @@ -19,4 +19,4 @@ BOOST_AUTO_TEST_CASE(test1, * utf::timeout(2)) BOOST_TEST(false); #endif } -//] +// end::example_code[] diff --git a/doc/examples/decorator_12.output b/doc/modules/ROOT/examples/decorator_12.output similarity index 78% rename from doc/examples/decorator_12.output rename to doc/modules/ROOT/examples/decorator_12.output index 1daae52960..1d3fb221eb 100644 --- a/doc/examples/decorator_12.output +++ b/doc/modules/ROOT/examples/decorator_12.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_12 --log_level=message Running 2 test cases... set up FX @@ -11,4 +11,4 @@ tear down FX2 tear down FX *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/decorator_12.run.cpp b/doc/modules/ROOT/examples/decorator_12.run.cpp similarity index 95% rename from doc/examples/decorator_12.run.cpp rename to doc/modules/ROOT/examples/decorator_12.run.cpp index b81b5c90d5..f2d6166516 100644 --- a/doc/examples/decorator_12.run.cpp +++ b/doc/modules/ROOT/examples/decorator_12.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_12 #include namespace utf = boost::unit_test; @@ -38,4 +38,4 @@ BOOST_AUTO_TEST_SUITE(suite1, } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_13.output b/doc/modules/ROOT/examples/decorator_13.output similarity index 94% rename from doc/examples/decorator_13.output rename to doc/modules/ROOT/examples/decorator_13.output index de5a103d63..bb1cc135e3 100644 --- a/doc/examples/decorator_13.output +++ b/doc/modules/ROOT/examples/decorator_13.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_13 Running 5 test cases... test.cpp(9): error: in "test1": check 0.001 == 0.000 has failed [0.001 != 0]. Absolute value exceeds tolerance [|0.001| > 0.0005] @@ -9,4 +9,4 @@ test.cpp(28): error: in "test4": check 0.001 == 0.000 has failed [0.001 != 0]. A test.cpp(29): error: in "test4": check 1.100 == 1.101 has failed [1.1000000000000001 != 1.101]. Relative difference exceeds tolerance [0.000908265 > 0.0005] *** 6 failures are detected in the test module "decorator_13" -//] +// end::example_output[] diff --git a/doc/examples/decorator_13.run-fail.cpp b/doc/modules/ROOT/examples/decorator_13.run-fail.cpp similarity index 95% rename from doc/examples/decorator_13.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_13.run-fail.cpp index 51089334a2..5782379955 100644 --- a/doc/examples/decorator_13.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_13.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_13 #include @@ -43,4 +43,4 @@ BOOST_AUTO_TEST_CASE(test5, BOOST_TEST( 0.001 == 0.000 ); BOOST_TEST( 1.100 == 1.101 ); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_20.output b/doc/modules/ROOT/examples/decorator_20.output similarity index 87% rename from doc/examples/decorator_20.output rename to doc/modules/ROOT/examples/decorator_20.output index ce3725c2e9..3fec3f697b 100644 --- a/doc/examples/decorator_20.output +++ b/doc/modules/ROOT/examples/decorator_20.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_20 Running 2 test cases... test.cpp(18): error: in "suite1/test_2": check 2 != 2 has failed [2 == 2] @@ -12,4 +12,4 @@ suite1* test_2* test_io* test_db -//] +// end::example_output[] diff --git a/doc/examples/decorator_20.run-fail.cpp b/doc/modules/ROOT/examples/decorator_20.run-fail.cpp similarity index 95% rename from doc/examples/decorator_20.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_20.run-fail.cpp index 0c4bd73596..fd2c572f91 100644 --- a/doc/examples/decorator_20.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_20.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_20 #include @@ -39,4 +39,4 @@ BOOST_AUTO_TEST_SUITE(suite1, * utf::disabled()) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/decorator_21.output b/doc/modules/ROOT/examples/decorator_21.output similarity index 92% rename from doc/examples/decorator_21.output rename to doc/modules/ROOT/examples/decorator_21.output index 961626b8c0..d1d7919714 100644 --- a/doc/examples/decorator_21.output +++ b/doc/modules/ROOT/examples/decorator_21.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_21 --log_level=test_suite --run_test=test_2,test_3 Including test case test_1 as a dependency of test case test_2 Running 3 test cases... @@ -11,4 +11,4 @@ test.cpp(20): Test case "test_2" is skipped because dependency test case "test_1 Leaving test module "decorator_21"; testing time: 17ms *** 1 failure is detected in the test module "decorator_21" -//] +// end::example_output[] diff --git a/doc/examples/decorator_21.run-fail.cpp b/doc/modules/ROOT/examples/decorator_21.run-fail.cpp similarity index 94% rename from doc/examples/decorator_21.run-fail.cpp rename to doc/modules/ROOT/examples/decorator_21.run-fail.cpp index 7999eaf0c4..eab32c5c88 100644 --- a/doc/examples/decorator_21.run-fail.cpp +++ b/doc/modules/ROOT/examples/decorator_21.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_21 #include @@ -35,4 +35,4 @@ BOOST_AUTO_TEST_CASE(test_3, { BOOST_TEST(true); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_22.output b/doc/modules/ROOT/examples/decorator_22.output similarity index 93% rename from doc/examples/decorator_22.output rename to doc/modules/ROOT/examples/decorator_22.output index 579784e30a..9c9954fa77 100644 --- a/doc/examples/decorator_22.output +++ b/doc/modules/ROOT/examples/decorator_22.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_22 --list_content test_1* test_net : requires network @@ -24,4 +24,4 @@ test.cpp(13): Leaving test case "test_net"; testing time: 1ms Leaving test module "decorator_22"; testing time: 16ms *** No errors detected -//] +// end::example_output[] diff --git a/doc/examples/decorator_22.run.cpp b/doc/modules/ROOT/examples/decorator_22.run.cpp similarity index 92% rename from doc/examples/decorator_22.run.cpp rename to doc/modules/ROOT/examples/decorator_22.run.cpp index 770c596358..065b283ac4 100644 --- a/doc/examples/decorator_22.run.cpp +++ b/doc/modules/ROOT/examples/decorator_22.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_22 #include @@ -22,4 +22,4 @@ BOOST_AUTO_TEST_CASE(test_net, { BOOST_TEST(true); } -//] +// end::example_code[] diff --git a/doc/examples/decorator_23.output b/doc/modules/ROOT/examples/decorator_23.output similarity index 93% rename from doc/examples/decorator_23.output rename to doc/modules/ROOT/examples/decorator_23.output index bb31c42654..1fb30122c1 100644 --- a/doc/examples/decorator_23.output +++ b/doc/modules/ROOT/examples/decorator_23.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > decorator_23 --list_content test_1* test_net*: requires network @@ -22,4 +22,4 @@ Entering test module "decorator_23" test.cpp(6): Entering test case "test_1" test.cpp(6): Leaving test case "test_1" Leaving test module "decorator_23"; testing time: 5ms -//] +// end::example_output[] diff --git a/doc/examples/decorator_23.run.cpp b/doc/modules/ROOT/examples/decorator_23.run.cpp similarity index 92% rename from doc/examples/decorator_23.run.cpp rename to doc/modules/ROOT/examples/decorator_23.run.cpp index 79f6aa62c9..7aa6822b23 100644 --- a/doc/examples/decorator_23.run.cpp +++ b/doc/modules/ROOT/examples/decorator_23.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE decorator_23 #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE(test_net, { BOOST_TEST(true); } -//] +// end::example_code[] diff --git a/doc/examples/example01.output b/doc/modules/ROOT/examples/example01.output similarity index 90% rename from doc/examples/example01.output rename to doc/modules/ROOT/examples/example01.output index 73bdb1563c..ff71dd848f 100644 --- a/doc/examples/example01.output +++ b/doc/modules/ROOT/examples/example01.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=unit_scope Running 2 test cases... Entering test module "Master Test Suite" @@ -9,4 +9,4 @@ example.cpp:22: Leaving test case "second-check-free-test-function"; testing tim Leaving test module "Master Test Suite"; testing time: 158us *** No errors detected -//] +// end::example_output[] diff --git a/doc/examples/example01.run.cpp b/doc/modules/ROOT/examples/example01.run.cpp similarity index 94% rename from doc/examples/example01.run.cpp rename to doc/modules/ROOT/examples/example01.run.cpp index 0f855a7186..e2da2aea6f 100644 --- a/doc/examples/example01.run.cpp +++ b/doc/modules/ROOT/examples/example01.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include using namespace boost::unit_test; @@ -22,4 +22,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) add( BOOST_TEST_CASE_NAME( &free_test_function, "second-check-free-test-function" ) ); return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example03.output b/doc/modules/ROOT/examples/example03.output similarity index 80% rename from doc/examples/example03.output rename to doc/modules/ROOT/examples/example03.output index c6f54b6a80..be4abd26e1 100644 --- a/doc/examples/example03.output +++ b/doc/modules/ROOT/examples/example03.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 2 test cases... test.cpp(22): error: in "boost::bind( &test_class::test_method2, tester )": check false has failed *** 1 failure is detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example03.run-fail.cpp b/doc/modules/ROOT/examples/example03.run-fail.cpp similarity index 95% rename from doc/examples/example03.run-fail.cpp rename to doc/modules/ROOT/examples/example03.run-fail.cpp index a5bfc454a5..096f382d18 100644 --- a/doc/examples/example03.run-fail.cpp +++ b/doc/modules/ROOT/examples/example03.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include using namespace boost::unit_test; @@ -33,4 +33,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) add( BOOST_TEST_CASE( boost::bind( &test_class::test_method2, tester ))); return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example06.output b/doc/modules/ROOT/examples/example06.output similarity index 53% rename from doc/examples/example06.output rename to doc/modules/ROOT/examples/example06.output index 4d3388d0b1..a6dd3fd63e 100644 --- a/doc/examples/example06.output +++ b/doc/modules/ROOT/examples/example06.output @@ -1,6 +1,6 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example06.run.cpp b/doc/modules/ROOT/examples/example06.run.cpp similarity index 91% rename from doc/examples/example06.run.cpp rename to doc/modules/ROOT/examples/example06.run.cpp index 8082cb4768..35f540dac7 100644 --- a/doc/examples/example06.run.cpp +++ b/doc/modules/ROOT/examples/example06.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -14,4 +14,4 @@ BOOST_AUTO_TEST_CASE( free_test_function ) { BOOST_TEST( true /* test assertion */ ); } -//] +// end::example_code[] diff --git a/doc/examples/example07.output b/doc/modules/ROOT/examples/example07.output similarity index 84% rename from doc/examples/example07.output rename to doc/modules/ROOT/examples/example07.output index edc68f6647..09b1dcc1ec 100644 --- a/doc/examples/example07.output +++ b/doc/modules/ROOT/examples/example07.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 5 test cases... test.cpp(15): error: in "free_test_function": check i < 4 has failed [4 >= 4] test.cpp(15): error: in "free_test_function": check i < 4 has failed [5 >= 4] *** 2 failures are detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example07.run-fail.cpp b/doc/modules/ROOT/examples/example07.run-fail.cpp similarity index 93% rename from doc/examples/example07.run-fail.cpp rename to doc/modules/ROOT/examples/example07.run-fail.cpp index cdc09a064b..ba913dcac0 100644 --- a/doc/examples/example07.run-fail.cpp +++ b/doc/modules/ROOT/examples/example07.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include using namespace boost::unit_test; @@ -24,4 +24,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example08.output b/doc/modules/ROOT/examples/example08.output similarity index 89% rename from doc/examples/example08.output rename to doc/modules/ROOT/examples/example08.output index 498bc3e00d..0454171235 100644 --- a/doc/examples/example08.output +++ b/doc/modules/ROOT/examples/example08.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 5 test cases... test.cpp(23): error: in "test_method": check d * 100 == (double)(int)(d*100) has failed [1.0001 * 100 != 100]. Relative difference exceeds tolerance [0.001 > 0.0001] test.cpp(23): error: in "test_method": check d * 100 == (double)(int)(d*100) has failed [1.0001 * 100 != 100]. Relative difference exceeds tolerance [0.0001 > 0.0001] *** 2 failures are detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example08.run-fail.cpp b/doc/modules/ROOT/examples/example08.run-fail.cpp similarity index 95% rename from doc/examples/example08.run-fail.cpp rename to doc/modules/ROOT/examples/example08.run-fail.cpp index a4d3a3379e..9a7239abda 100644 --- a/doc/examples/example08.run-fail.cpp +++ b/doc/modules/ROOT/examples/example08.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_ALTERNATIVE_INIT_API #include #include @@ -36,4 +36,4 @@ bool init_unit_test() return true; } -//] +// end::example_code[] diff --git a/doc/examples/example09.output b/doc/modules/ROOT/examples/example09.output similarity index 79% rename from doc/examples/example09.output rename to doc/modules/ROOT/examples/example09.output index 120a01dc2b..e5109fd9a1 100644 --- a/doc/examples/example09.output +++ b/doc/modules/ROOT/examples/example09.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 3 test cases... test.cpp(15): error: in "my_test": check sizeof(T) == 4U has failed [1 != 4] *** 1 failure is detected in the test module "Master Test Suite" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example09.run-fail.cpp b/doc/modules/ROOT/examples/example09.run-fail.cpp similarity index 93% rename from doc/examples/example09.run-fail.cpp rename to doc/modules/ROOT/examples/example09.run-fail.cpp index 2bbeabbfcf..ade3ecf022 100644 --- a/doc/examples/example09.run-fail.cpp +++ b/doc/modules/ROOT/examples/example09.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include using namespace boost::unit_test; @@ -24,4 +24,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example10.output b/doc/modules/ROOT/examples/example10.output similarity index 79% rename from doc/examples/example10.output rename to doc/modules/ROOT/examples/example10.output index 75b9e297eb..5201991144 100644 --- a/doc/examples/example10.output +++ b/doc/modules/ROOT/examples/example10.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 3 test cases... test.cpp(17): error: in "my_test": check sizeof(T) == (unsigned)4 has failed [1 != 4] *** 1 failure is detected in the test module "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example10.run-fail.cpp b/doc/modules/ROOT/examples/example10.run-fail.cpp similarity index 94% rename from doc/examples/example10.run-fail.cpp rename to doc/modules/ROOT/examples/example10.run-fail.cpp index 8a1cabe27e..ac43a4fa93 100644 --- a/doc/examples/example10.run-fail.cpp +++ b/doc/modules/ROOT/examples/example10.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -23,4 +23,4 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( my_tuple_test, T, test_types_w_tuples ) { BOOST_TEST( sizeof(T) == (unsigned)4 ); } -//] +// end::example_code[] diff --git a/doc/examples/example11.output b/doc/modules/ROOT/examples/example11.output similarity index 91% rename from doc/examples/example11.output rename to doc/modules/ROOT/examples/example11.output index f3ee56df6f..2bca676fee 100644 --- a/doc/examples/example11.output +++ b/doc/modules/ROOT/examples/example11.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=test_suite Running 4 test cases... Entering test suite "Master Test Suite" @@ -17,4 +17,4 @@ Leaving test suite "test_suite2" Leaving test suite "Master Test Suite" *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example11.run.cpp b/doc/modules/ROOT/examples/example11.run.cpp similarity index 95% rename from doc/examples/example11.run.cpp rename to doc/modules/ROOT/examples/example11.run.cpp index 5ff53ce040..c9e275c59a 100644 --- a/doc/examples/example11.run.cpp +++ b/doc/modules/ROOT/examples/example11.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include using namespace boost::unit_test; @@ -29,4 +29,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example12.output b/doc/modules/ROOT/examples/example12.output similarity index 84% rename from doc/examples/example12.output rename to doc/modules/ROOT/examples/example12.output index ec43278787..cd2a8aa460 100644 --- a/doc/examples/example12.output +++ b/doc/modules/ROOT/examples/example12.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 4 test cases... test.cpp(21): fatal error: in "test_suite1/test_case2": critical check 1 == 2 has failed [1 != 2] test.cpp(35): error: in "test_suite2/test_case4": check false has failed *** 2 failures are detected in the test module "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example12.run-fail.cpp b/doc/modules/ROOT/examples/example12.run-fail.cpp similarity index 94% rename from doc/examples/example12.run-fail.cpp rename to doc/modules/ROOT/examples/example12.run-fail.cpp index fcc2465d24..5a349548c9 100644 --- a/doc/examples/example12.run-fail.cpp +++ b/doc/modules/ROOT/examples/example12.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -36,4 +36,4 @@ BOOST_AUTO_TEST_CASE( test_case4 ) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/example13.output b/doc/modules/ROOT/examples/example13.output similarity index 50% rename from doc/examples/example13.output rename to doc/modules/ROOT/examples/example13.output index dbdce96feb..31825ca959 100644 --- a/doc/examples/example13.output +++ b/doc/modules/ROOT/examples/example13.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example 1 Test setup error: test tree is empty -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example13.run.cpp b/doc/modules/ROOT/examples/example13.run.cpp similarity index 93% rename from doc/examples/example13.run.cpp rename to doc/modules/ROOT/examples/example13.run.cpp index 628178ca43..7f191943e5 100644 --- a/doc/examples/example13.run.cpp +++ b/doc/modules/ROOT/examples/example13.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include using namespace boost::unit_test; @@ -24,4 +24,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example14.output b/doc/modules/ROOT/examples/example14.output similarity index 84% rename from doc/examples/example14.output rename to doc/modules/ROOT/examples/example14.output index 39e6ce3619..ca1d01546b 100644 --- a/doc/examples/example14.output +++ b/doc/modules/ROOT/examples/example14.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=test_suite Running 1 test case... Entering test suite "my master test suite name" @@ -7,4 +7,4 @@ Leaving test case "free_test_function"; testing time: 1ms Leaving test suite "my master test suite name" *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example14.run.cpp b/doc/modules/ROOT/examples/example14.run.cpp similarity index 90% rename from doc/examples/example14.run.cpp rename to doc/modules/ROOT/examples/example14.run.cpp index c893ba050a..d1b3026fd0 100644 --- a/doc/examples/example14.run.cpp +++ b/doc/modules/ROOT/examples/example14.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE my master test suite name #include @@ -13,4 +13,4 @@ BOOST_AUTO_TEST_CASE( free_test_function ) { BOOST_TEST( true /* test assertion */ ); } -//] +// end::example_code[] diff --git a/doc/examples/example15.output b/doc/modules/ROOT/examples/example15.output similarity index 84% rename from doc/examples/example15.output rename to doc/modules/ROOT/examples/example15.output index 39e6ce3619..ca1d01546b 100644 --- a/doc/examples/example15.output +++ b/doc/modules/ROOT/examples/example15.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=test_suite Running 1 test case... Entering test suite "my master test suite name" @@ -7,4 +7,4 @@ Leaving test case "free_test_function"; testing time: 1ms Leaving test suite "my master test suite name" *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example15.run.cpp b/doc/modules/ROOT/examples/example15.run.cpp similarity index 92% rename from doc/examples/example15.run.cpp rename to doc/modules/ROOT/examples/example15.run.cpp index 3ca5486362..75beb45c71 100644 --- a/doc/examples/example15.run.cpp +++ b/doc/modules/ROOT/examples/example15.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include using namespace boost::unit_test; @@ -19,4 +19,4 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) framework::master_test_suite().p_name.value = "my master test suite name"; return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example16.output b/doc/modules/ROOT/examples/example16.output similarity index 79% rename from doc/examples/example16.output rename to doc/modules/ROOT/examples/example16.output index 30fa7c1929..2f56a60e62 100644 --- a/doc/examples/example16.output +++ b/doc/modules/ROOT/examples/example16.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example --log_level=message Running 1 test case... test.cpp(8): error in "free_test_function": check 2 == 1 has failed Test case has less failures then expected *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example16.run.cpp b/doc/modules/ROOT/examples/example16.run.cpp similarity index 92% rename from doc/examples/example16.run.cpp rename to doc/modules/ROOT/examples/example16.run.cpp index 46dd5dc2c0..c02fbfbe8a 100644 --- a/doc/examples/example16.run.cpp +++ b/doc/modules/ROOT/examples/example16.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include using namespace boost::unit_test; @@ -21,4 +21,4 @@ test_suite* init_unit_test_suite( int, char* [] ) return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example17.output b/doc/modules/ROOT/examples/example17.output similarity index 89% rename from doc/examples/example17.output rename to doc/modules/ROOT/examples/example17.output index b106d6b6a8..abe3de240f 100644 --- a/doc/examples/example17.output +++ b/doc/modules/ROOT/examples/example17.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --report_level=short Running 2 test cases... test.cpp(10): error in "my_test1": check 2 == 1 has failed @@ -9,4 +9,4 @@ Test suite "example" passed with: 3 assertions out of 3 failed 3 failures expected 2 test cases out of 2 passed -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example17.run.cpp b/doc/modules/ROOT/examples/example17.run.cpp similarity index 94% rename from doc/examples/example17.run.cpp rename to doc/modules/ROOT/examples/example17.run.cpp index a0eee54d59..be86606ad1 100644 --- a/doc/examples/example17.run.cpp +++ b/doc/modules/ROOT/examples/example17.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -27,4 +27,4 @@ BOOST_AUTO_TEST_CASE( my_test1 ) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/example18.output b/doc/modules/ROOT/examples/example18.output similarity index 85% rename from doc/examples/example18.output rename to doc/modules/ROOT/examples/example18.output index 2fbe3d8c30..9692d713cc 100644 --- a/doc/examples/example18.output +++ b/doc/modules/ROOT/examples/example18.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=message Running 3 test cases... setup fixture @@ -9,4 +9,4 @@ test.cpp(19): error in "test_case2": check i == 1 has failed [0 != 1] teardown fixture *** 2 failures are detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example18.run-fail.cpp b/doc/modules/ROOT/examples/example18.run-fail.cpp similarity index 93% rename from doc/examples/example18.run-fail.cpp rename to doc/modules/ROOT/examples/example18.run-fail.cpp index 5251faa286..c7f4a6367f 100644 --- a/doc/examples/example18.run-fail.cpp +++ b/doc/modules/ROOT/examples/example18.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -31,4 +31,4 @@ BOOST_AUTO_TEST_CASE( test_case3 ) { BOOST_TEST( true ); } -//] +// end::example_code[] diff --git a/doc/examples/example20.output b/doc/modules/ROOT/examples/example20.output similarity index 63% rename from doc/examples/example20.output rename to doc/modules/ROOT/examples/example20.output index 92affa9963..ddb89fc4d3 100644 --- a/doc/examples/example20.output +++ b/doc/modules/ROOT/examples/example20.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example global setup Running 1 test case... global teardown *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example20.run.cpp b/doc/modules/ROOT/examples/example20.run.cpp similarity index 94% rename from doc/examples/example20.run.cpp rename to doc/modules/ROOT/examples/example20.run.cpp index be9b1fdf74..e4ed1cc34c 100644 --- a/doc/examples/example20.run.cpp +++ b/doc/modules/ROOT/examples/example20.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -25,4 +25,4 @@ BOOST_AUTO_TEST_CASE( test_case ) { BOOST_TEST( true ); } -//] +// end::example_code[] diff --git a/doc/examples/example21.output b/doc/modules/ROOT/examples/example21.output similarity index 76% rename from doc/examples/example21.output rename to doc/modules/ROOT/examples/example21.output index a0ca7b4497..a0055ee456 100644 --- a/doc/examples/example21.output +++ b/doc/modules/ROOT/examples/example21.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=message Running 2 test cases... Testing initialization : @@ -7,4 +7,4 @@ Testing update : Update Volume with 100 *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example21.run.cpp b/doc/modules/ROOT/examples/example21.run.cpp similarity index 94% rename from doc/examples/example21.run.cpp rename to doc/modules/ROOT/examples/example21.run.cpp index 15ed8ab6c5..be3ec9324a 100644 --- a/doc/examples/example21.run.cpp +++ b/doc/modules/ROOT/examples/example21.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -25,4 +25,4 @@ BOOST_AUTO_TEST_CASE( test_update ) BOOST_TEST_MESSAGE( "Testing update :" ); BOOST_TEST_MESSAGE( "Update " << field_name << " with " << value ); } -//] +// end::example_code[] diff --git a/doc/examples/example22.output b/doc/modules/ROOT/examples/example22.output similarity index 57% rename from doc/examples/example22.output rename to doc/modules/ROOT/examples/example22.output index a246f683f9..208cbaa6f2 100644 --- a/doc/examples/example22.output +++ b/doc/modules/ROOT/examples/example22.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... unknown location(0): fatal error: in "test_external_interface": std::runtime_error: Undefined Behaviour ahead! -../doc/examples/example22.run-fail.cpp(17): last checkpoint: Calling 'foo' with i=1 +../doc/modules/ROOT/examples/example22.run-fail.cpp(17): last checkpoint: Calling 'foo' with i=1 *** 1 failure is detected in the test module "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example22.run-fail.cpp b/doc/modules/ROOT/examples/example22.run-fail.cpp similarity index 95% rename from doc/examples/example22.run-fail.cpp rename to doc/modules/ROOT/examples/example22.run-fail.cpp index 2ae3b5489c..1ee03c272c 100644 --- a/doc/examples/example22.run-fail.cpp +++ b/doc/modules/ROOT/examples/example22.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -32,4 +32,4 @@ void foo( int i ) // Undefined Behaviour is implementation specific goo( 2/(i-1) ); } -//] +// end::example_code[] diff --git a/doc/examples/example23.output b/doc/modules/ROOT/examples/example23.output similarity index 83% rename from doc/examples/example23.output rename to doc/modules/ROOT/examples/example23.output index 6db3dcb9f8..a4069e7ea4 100644 --- a/doc/examples/example23.output +++ b/doc/modules/ROOT/examples/example23.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... unknown location(0): fatal error in "test_case": memory access violation at address: 0x00000008: no mapping at fault address test.cpp(16): last checkpoint *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example23.run-fail.cpp b/doc/modules/ROOT/examples/example23.run-fail.cpp similarity index 93% rename from doc/examples/example23.run-fail.cpp rename to doc/modules/ROOT/examples/example23.run-fail.cpp index 6e934f9005..9c87ba79e1 100644 --- a/doc/examples/example23.run-fail.cpp +++ b/doc/modules/ROOT/examples/example23.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -26,4 +26,4 @@ BOOST_AUTO_TEST_CASE( test_case ) BOOST_TEST_PASSPOINT(); foo( *p ); } -//] +// end::example_code[] diff --git a/doc/modules/ROOT/examples/example24.output b/doc/modules/ROOT/examples/example24.output new file mode 100644 index 0000000000..25020513be --- /dev/null +++ b/doc/modules/ROOT/examples/example24.output @@ -0,0 +1,5 @@ +// tag::example_output[] +Hello, world + +no errors detected +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example24.run.cpp b/doc/modules/ROOT/examples/example24.run.cpp similarity index 90% rename from doc/examples/example24.run.cpp rename to doc/modules/ROOT/examples/example24.run.cpp index ffbbf39be9..e5a462d64f 100644 --- a/doc/examples/example24.run.cpp +++ b/doc/modules/ROOT/examples/example24.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include @@ -15,4 +15,4 @@ int cpp_main( int, char* [] ) // note name cpp_main, not main. return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example25.output b/doc/modules/ROOT/examples/example25.output similarity index 71% rename from doc/examples/example25.output rename to doc/modules/ROOT/examples/example25.output index 95e47706f8..951ad3537a 100644 --- a/doc/examples/example25.output +++ b/doc/modules/ROOT/examples/example25.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] **** exception(205): std::runtime_error: big trouble ******** errors detected; see standard output for details ******** -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example25.run-fail.cpp b/doc/modules/ROOT/examples/example25.run-fail.cpp similarity index 91% rename from doc/examples/example25.run-fail.cpp rename to doc/modules/ROOT/examples/example25.run-fail.cpp index 5a244bdd16..e016c43fe0 100644 --- a/doc/examples/example25.run-fail.cpp +++ b/doc/modules/ROOT/examples/example25.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include #include @@ -17,4 +17,4 @@ int cpp_main( int, char* [] ) // note the name return 0; } -//] +// end::example_code[] diff --git a/doc/examples/example26.output b/doc/modules/ROOT/examples/example26.output similarity index 65% rename from doc/examples/example26.output rename to doc/modules/ROOT/examples/example26.output index b9f307436e..91ea1d1d92 100644 --- a/doc/examples/example26.output +++ b/doc/modules/ROOT/examples/example26.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] **** error return code: 5 ******** errors detected; see standard output for details ******** -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example26.run-fail.cpp b/doc/modules/ROOT/examples/example26.run-fail.cpp similarity index 90% rename from doc/examples/example26.run-fail.cpp rename to doc/modules/ROOT/examples/example26.run-fail.cpp index 05366889f8..e94d7277fd 100644 --- a/doc/examples/example26.run-fail.cpp +++ b/doc/modules/ROOT/examples/example26.run-fail.cpp @@ -5,11 +5,11 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #include // this header is optional int cpp_main( int, char* [] ) // note the name { return 5; } -//] +// end::example_code[] diff --git a/doc/examples/example28.output b/doc/modules/ROOT/examples/example28.output similarity index 78% rename from doc/examples/example28.output rename to doc/modules/ROOT/examples/example28.output index 15a1369e33..8795312394 100644 --- a/doc/examples/example28.output +++ b/doc/modules/ROOT/examples/example28.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(15): error in "test": check output.is_equal( "i=3" ) has failed. Output content: "i=2" *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example28.run-fail.cpp b/doc/modules/ROOT/examples/example28.run-fail.cpp similarity index 93% rename from doc/examples/example28.run-fail.cpp rename to doc/modules/ROOT/examples/example28.run-fail.cpp index 3c1aa1b008..59639abd18 100644 --- a/doc/examples/example28.run-fail.cpp +++ b/doc/modules/ROOT/examples/example28.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -20,4 +20,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_TEST( output.check_length( 3, false ) ); BOOST_TEST( output.is_equal( "i=3" ) ); } -//] +// end::example_code[] diff --git a/doc/examples/example29.output b/doc/modules/ROOT/examples/example29.output similarity index 80% rename from doc/examples/example29.output rename to doc/modules/ROOT/examples/example29.output index 8193fa651c..db113baf06 100644 --- a/doc/examples/example29.output +++ b/doc/modules/ROOT/examples/example29.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(16): error in "test": check output.match_pattern() has failed. Mismatch at position 23 @@ -6,4 +6,4 @@ test.cpp(16): error in "test": check output.match_pattern() has failed. Mismatch ...4... *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example29.run-fail.cpp b/doc/modules/ROOT/examples/example29.run-fail.cpp similarity index 94% rename from doc/examples/example29.run-fail.cpp rename to doc/modules/ROOT/examples/example29.run-fail.cpp index fa220b1226..8f71db36e8 100644 --- a/doc/examples/example29.run-fail.cpp +++ b/doc/modules/ROOT/examples/example29.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE( test ) output << "\nFile: " << __FILE__ << " Line:YYY"; BOOST_TEST( output.match_pattern() ); /*< This line generates the error Line:YYY != Line:XXX >*/ } -//] +// end::example_code[] diff --git a/doc/examples/example30.output b/doc/modules/ROOT/examples/example30.output similarity index 77% rename from doc/examples/example30.output rename to doc/modules/ROOT/examples/example30.output index 79f995d616..51e389f468 100644 --- a/doc/examples/example30.output +++ b/doc/modules/ROOT/examples/example30.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(13): error in "test_is_even": check is_even( i ) has failed for ( 17 ) *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example30.run-fail.cpp b/doc/modules/ROOT/examples/example30.run-fail.cpp similarity index 92% rename from doc/examples/example30.run-fail.cpp rename to doc/modules/ROOT/examples/example30.run-fail.cpp index d2eec03e8b..2abb8c77a1 100644 --- a/doc/examples/example30.run-fail.cpp +++ b/doc/modules/ROOT/examples/example30.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE( test_is_even ) int i = 17; BOOST_CHECK_PREDICATE( is_even, (i) ); } -//] +// end::example_code[] diff --git a/doc/examples/example31.output b/doc/modules/ROOT/examples/example31.output similarity index 79% rename from doc/examples/example31.output rename to doc/modules/ROOT/examples/example31.output index e1ba29040d..239587e7bf 100644 --- a/doc/examples/example31.output +++ b/doc/modules/ROOT/examples/example31.output @@ -1,6 +1,6 @@ -//[example_output +// tag::example_output[] Running 1 test case... test.cpp(28): error in "test_list_comparizon": check compare_lists( l1, l2 ) has failed. Different sizes [2!=0] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example31.run-fail.cpp b/doc/modules/ROOT/examples/example31.run-fail.cpp similarity index 94% rename from doc/examples/example31.run-fail.cpp rename to doc/modules/ROOT/examples/example31.run-fail.cpp index 4ea31868bf..13dc24227e 100644 --- a/doc/examples/example31.run-fail.cpp +++ b/doc/modules/ROOT/examples/example31.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -31,4 +31,4 @@ BOOST_AUTO_TEST_CASE( test_list_comparison ) BOOST_TEST( compare_lists( l1, l2 ) ); } -//] +// end::example_code[] diff --git a/doc/examples/example32.output b/doc/modules/ROOT/examples/example32.output similarity index 74% rename from doc/examples/example32.output rename to doc/modules/ROOT/examples/example32.output index f835e3408c..edf7a99b6a 100644 --- a/doc/examples/example32.output +++ b/doc/modules/ROOT/examples/example32.output @@ -1,6 +1,6 @@ -//[example_output +// tag::example_output[] Running 1 test case... test.cpp(16): error in "test_list": check p1 == p2 has failed [ != ] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example32.run-fail.cpp b/doc/modules/ROOT/examples/example32.run-fail.cpp similarity index 92% rename from doc/examples/example32.run-fail.cpp rename to doc/modules/ROOT/examples/example32.run-fail.cpp index 0a57d2aa7c..88503766ed 100644 --- a/doc/examples/example32.run-fail.cpp +++ b/doc/modules/ROOT/examples/example32.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -22,4 +22,4 @@ BOOST_AUTO_TEST_CASE( test_list ) BOOST_CHECK_EQUAL( p1, p2 ); } -//] +// end::example_code[] diff --git a/doc/examples/example33.output b/doc/modules/ROOT/examples/example33.output similarity index 91% rename from doc/examples/example33.output rename to doc/modules/ROOT/examples/example33.output index 4f35eaba86..5fdba2071f 100644 --- a/doc/examples/example33.output +++ b/doc/modules/ROOT/examples/example33.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(8): error in "test": check (char)0x26 =.= 0x04 failed. @@ -7,4 +7,4 @@ Mismatch in a position 5 Operands bit sizes mismatch: 8 != 32 *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example33.run-fail.cpp b/doc/modules/ROOT/examples/example33.run-fail.cpp similarity index 90% rename from doc/examples/example33.run-fail.cpp rename to doc/modules/ROOT/examples/example33.run-fail.cpp index a26fa3f916..b0420f3894 100644 --- a/doc/examples/example33.run-fail.cpp +++ b/doc/modules/ROOT/examples/example33.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -13,4 +13,4 @@ BOOST_AUTO_TEST_CASE( test ) { BOOST_CHECK_BITWISE_EQUAL( (char)0x26, 0x04 ); } -//] +// end::example_code[] diff --git a/doc/examples/example34.output b/doc/modules/ROOT/examples/example34.output similarity index 86% rename from doc/examples/example34.output rename to doc/modules/ROOT/examples/example34.output index f7e1d93cf9..ab85956622 100644 --- a/doc/examples/example34.output +++ b/doc/modules/ROOT/examples/example34.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=warning Running 1 test case... test.cpp(9): warning in "test": condition sizeof(int) == sizeof(short) is not satisfied @@ -6,4 +6,4 @@ test.cpp(10): error in "test": check i == 1 has failed test.cpp(11): fatal error in "test": critical check i > 5 has failed *** 2 failures are detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example34.run-fail.cpp b/doc/modules/ROOT/examples/example34.run-fail.cpp similarity index 92% rename from doc/examples/example34.run-fail.cpp rename to doc/modules/ROOT/examples/example34.run-fail.cpp index 36aa05239d..704de548f1 100644 --- a/doc/examples/example34.run-fail.cpp +++ b/doc/modules/ROOT/examples/example34.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -17,4 +17,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_REQUIRE( i > 5 ); BOOST_CHECK( i == 6 ); // will never reach this check } -//] +// end::example_code[] diff --git a/doc/examples/example35.output b/doc/modules/ROOT/examples/example35.output similarity index 76% rename from doc/examples/example35.output rename to doc/modules/ROOT/examples/example35.output index 4658b75c13..5e182c401f 100644 --- a/doc/examples/example35.output +++ b/doc/modules/ROOT/examples/example35.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(10): fatal error in "test": critical check i == j has failed [2 != 1] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example35.run-fail.cpp b/doc/modules/ROOT/examples/example35.run-fail.cpp similarity index 90% rename from doc/examples/example35.run-fail.cpp rename to doc/modules/ROOT/examples/example35.run-fail.cpp index e3a77e24eb..02e233458b 100644 --- a/doc/examples/example35.run-fail.cpp +++ b/doc/modules/ROOT/examples/example35.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 1; BOOST_REQUIRE_EQUAL( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example36.output b/doc/modules/ROOT/examples/example36.output similarity index 82% rename from doc/examples/example36.output rename to doc/modules/ROOT/examples/example36.output index c94d420fb3..e48141e67c 100644 --- a/doc/examples/example36.output +++ b/doc/modules/ROOT/examples/example36.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(11): error in "test": check { col1, col1+7 } == { col2, col2+7 } has failed. @@ -6,4 +6,4 @@ Mismatch in a position 2: 3 != 4 Mismatch in a position 5: 6 != 7 *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example36.run-fail.cpp b/doc/modules/ROOT/examples/example36.run-fail.cpp similarity index 92% rename from doc/examples/example36.run-fail.cpp rename to doc/modules/ROOT/examples/example36.run-fail.cpp index 1b31f86bf7..fce9c21f64 100644 --- a/doc/examples/example36.run-fail.cpp +++ b/doc/modules/ROOT/examples/example36.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -16,4 +16,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_CHECK_EQUAL_COLLECTIONS( col1, col1+7, col2, col2+7 ); } -//] +// end::example_code[] diff --git a/doc/examples/example38.output b/doc/modules/ROOT/examples/example38.output similarity index 76% rename from doc/examples/example38.output rename to doc/modules/ROOT/examples/example38.output index 4c31f2a219..adcf88ee40 100644 --- a/doc/examples/example38.output +++ b/doc/modules/ROOT/examples/example38.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example --log_level=warning Running 1 test case... test.cpp(12): warning in "test": sin(45){0.850904} is > 0.71. Arg is not in radian? *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example38.run.cpp b/doc/modules/ROOT/examples/example38.run.cpp similarity index 93% rename from doc/examples/example38.run.cpp rename to doc/modules/ROOT/examples/example38.run.cpp index a9682ef2ec..780ea0acd0 100644 --- a/doc/examples/example38.run.cpp +++ b/doc/modules/ROOT/examples/example38.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -19,4 +19,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_WARN_MESSAGE( res < 0.71, "sin(45){" << res << "} is > 0.71. Arg is not in radian?" ); } -//] +// end::example_code[] diff --git a/doc/examples/example40.output b/doc/modules/ROOT/examples/example40.output similarity index 82% rename from doc/examples/example40.output rename to doc/modules/ROOT/examples/example40.output index 020a03726f..57ea4341c8 100644 --- a/doc/examples/example40.output +++ b/doc/modules/ROOT/examples/example40.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(14): warning in "test": condition moo( 12,i,j ) is not satisfied test.cpp(15): warning in "test": condition moo( 12, i, j ) is not satisfied for ( 12, 17, 15 ) *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example40.run.cpp b/doc/modules/ROOT/examples/example40.run.cpp similarity index 93% rename from doc/examples/example40.run.cpp rename to doc/modules/ROOT/examples/example40.run.cpp index 27e36abef3..eeb662e748 100644 --- a/doc/examples/example40.run.cpp +++ b/doc/modules/ROOT/examples/example40.run.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include using namespace boost::unit_test; @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_WARN( moo( 12,i,j ) ); BOOST_WARN_PREDICATE( moo, (12)(i)(j) ); } -//] +// end::example_code[] diff --git a/doc/examples/example41.output b/doc/modules/ROOT/examples/example41.output similarity index 76% rename from doc/examples/example41.output rename to doc/modules/ROOT/examples/example41.output index a1b08ae15e..2e09ab21af 100644 --- a/doc/examples/example41.output +++ b/doc/modules/ROOT/examples/example41.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(11): error in "test": absolute value of v{-0.00123456} exceeds 1e-006 *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example41.run-fail.cpp b/doc/modules/ROOT/examples/example41.run-fail.cpp similarity index 91% rename from doc/examples/example41.run-fail.cpp rename to doc/modules/ROOT/examples/example41.run-fail.cpp index 02712f5ab7..1696cb5395 100644 --- a/doc/examples/example41.run-fail.cpp +++ b/doc/modules/ROOT/examples/example41.run-fail.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -16,4 +16,4 @@ BOOST_AUTO_TEST_CASE( test ) double v = -1.23456e-3; BOOST_CHECK_SMALL( v, 0.000001 ); } -//] +// end::example_code[] diff --git a/doc/examples/example42.output b/doc/modules/ROOT/examples/example42.output similarity index 79% rename from doc/examples/example42.output rename to doc/modules/ROOT/examples/example42.output index 04cdc6b44e..d39c831eff 100644 --- a/doc/examples/example42.output +++ b/doc/modules/ROOT/examples/example42.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(12): error in "test": difference between v1{1.23456e-010} and v2{1.23457e-010} exceeds 0.0001% *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example42.run-fail.cpp b/doc/modules/ROOT/examples/example42.run-fail.cpp similarity index 94% rename from doc/examples/example42.run-fail.cpp rename to doc/modules/ROOT/examples/example42.run-fail.cpp index 5feb3eb54b..9a001f263d 100644 --- a/doc/examples/example42.run-fail.cpp +++ b/doc/modules/ROOT/examples/example42.run-fail.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE( test ) // to be very close. But we want to checks that these values differ no more then 0.0001% // of their value. And this test will fail at tolerance supplied. } -//] +// end::example_code[] diff --git a/doc/examples/example43.output b/doc/modules/ROOT/examples/example43.output similarity index 53% rename from doc/examples/example43.output rename to doc/modules/ROOT/examples/example43.output index 4d3388d0b1..a6dd3fd63e 100644 --- a/doc/examples/example43.output +++ b/doc/modules/ROOT/examples/example43.output @@ -1,6 +1,6 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example43.run.cpp b/doc/modules/ROOT/examples/example43.run.cpp similarity index 94% rename from doc/examples/example43.run.cpp rename to doc/modules/ROOT/examples/example43.run.cpp index 4a9ce38676..2b8a1ab55b 100644 --- a/doc/examples/example43.run.cpp +++ b/doc/modules/ROOT/examples/example43.run.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE( test ) // But we are interested only that it does not exeed 0.001% of a values compared // And this test will pass. } -//] +// end::example_code[] diff --git a/doc/examples/example44.output b/doc/modules/ROOT/examples/example44.output similarity index 79% rename from doc/examples/example44.output rename to doc/modules/ROOT/examples/example44.output index 57672e73a7..0b4dfa87aa 100644 --- a/doc/examples/example44.output +++ b/doc/modules/ROOT/examples/example44.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(12): error in "test": difference between v1{1.111e-010} and v2{1.112e-010} exceeds 0.0008999 *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example44.run-fail.cpp b/doc/modules/ROOT/examples/example44.run-fail.cpp similarity index 92% rename from doc/examples/example44.run-fail.cpp rename to doc/modules/ROOT/examples/example44.run-fail.cpp index c8d62f9f6f..15c17e11a2 100644 --- a/doc/examples/example44.run-fail.cpp +++ b/doc/modules/ROOT/examples/example44.run-fail.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -18,4 +18,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_CHECK_CLOSE_FRACTION( v1, v2, 0.0008999 ); } -//] +// end::example_code[] diff --git a/doc/examples/example46.output b/doc/modules/ROOT/examples/example46.output similarity index 72% rename from doc/examples/example46.output rename to doc/modules/ROOT/examples/example46.output index 60813fb490..e6929942eb 100644 --- a/doc/examples/example46.output +++ b/doc/modules/ROOT/examples/example46.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(8): error in "test": Nothing to test *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example46.run-fail.cpp b/doc/modules/ROOT/examples/example46.run-fail.cpp similarity index 90% rename from doc/examples/example46.run-fail.cpp rename to doc/modules/ROOT/examples/example46.run-fail.cpp index b07bfdec87..22f476bc1f 100644 --- a/doc/examples/example46.run-fail.cpp +++ b/doc/modules/ROOT/examples/example46.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -13,4 +13,4 @@ BOOST_AUTO_TEST_CASE( test ) { BOOST_ERROR( "Nothing to test" ); } -//] +// end::example_code[] diff --git a/doc/examples/example47.output b/doc/modules/ROOT/examples/example47.output similarity index 74% rename from doc/examples/example47.output rename to doc/modules/ROOT/examples/example47.output index 3aec5cdee2..164e98911e 100644 --- a/doc/examples/example47.output +++ b/doc/modules/ROOT/examples/example47.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(8): fatal error in "test": Test is not ready yet *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example47.run-fail.cpp b/doc/modules/ROOT/examples/example47.run-fail.cpp similarity index 90% rename from doc/examples/example47.run-fail.cpp rename to doc/modules/ROOT/examples/example47.run-fail.cpp index 53e18621a4..4f7e19e6cd 100644 --- a/doc/examples/example47.run-fail.cpp +++ b/doc/modules/ROOT/examples/example47.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -13,4 +13,4 @@ BOOST_AUTO_TEST_CASE( test ) { BOOST_FAIL( "Test is not ready yet" ); } -//] +// end::example_code[] diff --git a/doc/examples/example48.output b/doc/modules/ROOT/examples/example48.output similarity index 87% rename from doc/examples/example48.output rename to doc/modules/ROOT/examples/example48.output index 7cb134a41b..2b08293851 100644 --- a/doc/examples/example48.output +++ b/doc/modules/ROOT/examples/example48.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(8): error in "test": check ::boost::test_tools::tt_detail::is_defined_impl( "SYMBOL1", "= SYMBOL1" ) failed test.cpp(9): error in "test": check ::boost::test_tools::tt_detail::is_defined_impl( "SYMBOL2(arg)", "= SYMBOL2(arg)" ) failed *** 2 failures are detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example48.run-fail.cpp b/doc/modules/ROOT/examples/example48.run-fail.cpp similarity index 91% rename from doc/examples/example48.run-fail.cpp rename to doc/modules/ROOT/examples/example48.run-fail.cpp index 5aa791549f..576830e61a 100644 --- a/doc/examples/example48.run-fail.cpp +++ b/doc/modules/ROOT/examples/example48.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -14,4 +14,4 @@ BOOST_AUTO_TEST_CASE( test ) BOOST_TEST( BOOST_IS_DEFINED(SYMBOL1) ); BOOST_TEST( BOOST_IS_DEFINED(SYMBOL2(arg)) ); } -//] +// end::example_code[] diff --git a/doc/examples/example49.output b/doc/modules/ROOT/examples/example49.output similarity index 82% rename from doc/examples/example49.output rename to doc/modules/ROOT/examples/example49.output index 374c88141d..da8d57db6e 100644 --- a/doc/examples/example49.output +++ b/doc/modules/ROOT/examples/example49.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --show_progress=yes --log_level=nothing 0% 10 20 30 40 50 60 70 80 90 100% @@ -6,4 +6,4 @@ *************************************************** *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example49.run.cpp b/doc/modules/ROOT/examples/example49.run.cpp similarity index 92% rename from doc/examples/example49.run.cpp rename to doc/modules/ROOT/examples/example49.run.cpp index 495c2a2192..3c4f100168 100644 --- a/doc/examples/example49.run.cpp +++ b/doc/modules/ROOT/examples/example49.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example49 #include #include @@ -16,4 +16,4 @@ BOOST_DATA_TEST_CASE( free_test_function, boost::unit_test::data::xrange(1000) ) // sleep(1); BOOST_TEST( true /* test assertion */ ); } -//] +// end::example_code[] diff --git a/doc/examples/example50.output b/doc/modules/ROOT/examples/example50.output similarity index 75% rename from doc/examples/example50.output rename to doc/modules/ROOT/examples/example50.output index 91275646eb..1722b25258 100644 --- a/doc/examples/example50.output +++ b/doc/modules/ROOT/examples/example50.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > example *** 1 failures is detected in test suite "example" > cat example.log Running 1 test case... test.cpp(26): error in "test_case": check false failed -//] +// end::example_output[] diff --git a/doc/examples/example50.run-fail.cpp b/doc/modules/ROOT/examples/example50.run-fail.cpp similarity index 93% rename from doc/examples/example50.run-fail.cpp rename to doc/modules/ROOT/examples/example50.run-fail.cpp index f1382e998a..4b5be86e4c 100644 --- a/doc/examples/example50.run-fail.cpp +++ b/doc/modules/ROOT/examples/example50.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -25,4 +25,4 @@ BOOST_TEST_GLOBAL_CONFIGURATION( MyConfig ); BOOST_AUTO_TEST_CASE( test_case ) { BOOST_TEST( false ); } -//] +// end::example_code[] diff --git a/doc/examples/example51.output b/doc/modules/ROOT/examples/example51.output similarity index 73% rename from doc/examples/example51.output rename to doc/modules/ROOT/examples/example51.output index 00f085c2e1..0beb070173 100644 --- a/doc/examples/example51.output +++ b/doc/modules/ROOT/examples/example51.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(13): warning in "test_case0": condition sizeof(int) > 4 is not satisfied *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example51.run.cpp b/doc/modules/ROOT/examples/example51.run.cpp similarity index 93% rename from doc/examples/example51.run.cpp rename to doc/modules/ROOT/examples/example51.run.cpp index 073d2d49ac..516d252e9d 100644 --- a/doc/examples/example51.run.cpp +++ b/doc/modules/ROOT/examples/example51.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -18,4 +18,4 @@ BOOST_AUTO_TEST_CASE( test_case0 ) BOOST_WARN( sizeof(int) > 4 ); } -//] +// end::example_code[] diff --git a/doc/examples/example52.output b/doc/modules/ROOT/examples/example52.output similarity index 68% rename from doc/examples/example52.output rename to doc/modules/ROOT/examples/example52.output index b8ed121034..d7f4e2117a 100644 --- a/doc/examples/example52.output +++ b/doc/modules/ROOT/examples/example52.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --report_level=no check false failed -//] +// end::example_output[] diff --git a/doc/examples/example52.run-fail.cpp b/doc/modules/ROOT/examples/example52.run-fail.cpp similarity index 92% rename from doc/examples/example52.run-fail.cpp rename to doc/modules/ROOT/examples/example52.run-fail.cpp index 9700327d3d..c574655089 100644 --- a/doc/examples/example52.run-fail.cpp +++ b/doc/modules/ROOT/examples/example52.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include using namespace boost::unit_test; @@ -22,4 +22,4 @@ BOOST_TEST_GLOBAL_CONFIGURATION( MyConfig ); BOOST_AUTO_TEST_CASE( test_case0 ) { BOOST_TEST( false ); } -//] +// end::example_code[] diff --git a/doc/examples/example53.output b/doc/modules/ROOT/examples/example53.output similarity index 93% rename from doc/examples/example53.output rename to doc/modules/ROOT/examples/example53.output index fa86b1a867..52253b4817 100644 --- a/doc/examples/example53.output +++ b/doc/modules/ROOT/examples/example53.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] >example --report_level=detailed Running 3 test cases... test.cpp(8): error in "test_case1": some error 1 @@ -22,4 +22,4 @@ Test suite "example" failed with: Test case "test_case_on_file_scope" passed with: 1 assertion out of 1 passed -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example53.run-fail.cpp b/doc/modules/ROOT/examples/example53.run-fail.cpp similarity index 93% rename from doc/examples/example53.run-fail.cpp rename to doc/modules/ROOT/examples/example53.run-fail.cpp index cf8ff536d3..fd822c905a 100644 --- a/doc/examples/example53.run-fail.cpp +++ b/doc/modules/ROOT/examples/example53.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -32,4 +32,4 @@ BOOST_AUTO_TEST_CASE( test_case2 ) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/example54.output b/doc/modules/ROOT/examples/example54.output similarity index 74% rename from doc/examples/example54.output rename to doc/modules/ROOT/examples/example54.output index 06cafb6d5d..ec7349604e 100644 --- a/doc/examples/example54.output +++ b/doc/modules/ROOT/examples/example54.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] >example Running 1 test case... test.cpp(10): error in "test": check i != j failed [3 == 3] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example54.run-fail.cpp b/doc/modules/ROOT/examples/example54.run-fail.cpp similarity index 90% rename from doc/examples/example54.run-fail.cpp rename to doc/modules/ROOT/examples/example54.run-fail.cpp index 51cd2a1e0a..8a18ffbbd9 100644 --- a/doc/examples/example54.run-fail.cpp +++ b/doc/modules/ROOT/examples/example54.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 3; BOOST_CHECK_NE( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example55.output b/doc/modules/ROOT/examples/example55.output similarity index 74% rename from doc/examples/example55.output rename to doc/modules/ROOT/examples/example55.output index 8cf1f121f4..b0f609bbef 100644 --- a/doc/examples/example55.output +++ b/doc/modules/ROOT/examples/example55.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] >example Running 1 test case... test.cpp(10): error in "test": check i <= j failed [9 > 6] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example55.run-fail.cpp b/doc/modules/ROOT/examples/example55.run-fail.cpp similarity index 90% rename from doc/examples/example55.run-fail.cpp rename to doc/modules/ROOT/examples/example55.run-fail.cpp index 3aacaacb19..d60758e8ca 100644 --- a/doc/examples/example55.run-fail.cpp +++ b/doc/modules/ROOT/examples/example55.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 6; BOOST_CHECK_LE( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example56.output b/doc/modules/ROOT/examples/example56.output similarity index 74% rename from doc/examples/example56.output rename to doc/modules/ROOT/examples/example56.output index 4ebe4d4720..1a4b674a55 100644 --- a/doc/examples/example56.output +++ b/doc/modules/ROOT/examples/example56.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] >example Running 1 test case... test.cpp(10): error in "test": check i < j failed [7 >= 7] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example56.run-fail.cpp b/doc/modules/ROOT/examples/example56.run-fail.cpp similarity index 90% rename from doc/examples/example56.run-fail.cpp rename to doc/modules/ROOT/examples/example56.run-fail.cpp index cfd078ea64..f6ea6856d0 100644 --- a/doc/examples/example56.run-fail.cpp +++ b/doc/modules/ROOT/examples/example56.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 7; BOOST_CHECK_LT( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example57.output b/doc/modules/ROOT/examples/example57.output similarity index 74% rename from doc/examples/example57.output rename to doc/modules/ROOT/examples/example57.output index fa8e5f1d88..70174e21c0 100644 --- a/doc/examples/example57.output +++ b/doc/modules/ROOT/examples/example57.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] >example Running 1 test case... test.cpp(10): error in "test": check i >= j failed [1 < 4] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example57.run-fail.cpp b/doc/modules/ROOT/examples/example57.run-fail.cpp similarity index 90% rename from doc/examples/example57.run-fail.cpp rename to doc/modules/ROOT/examples/example57.run-fail.cpp index b16193ab61..629691260e 100644 --- a/doc/examples/example57.run-fail.cpp +++ b/doc/modules/ROOT/examples/example57.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 4; BOOST_CHECK_GE( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example58.output b/doc/modules/ROOT/examples/example58.output similarity index 74% rename from doc/examples/example58.output rename to doc/modules/ROOT/examples/example58.output index 017bee8ae2..1c80c7f12c 100644 --- a/doc/examples/example58.output +++ b/doc/modules/ROOT/examples/example58.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] >example Running 1 test case... test.cpp(10): error in "test": check i > j failed [2 < 14] *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example58.run-fail.cpp b/doc/modules/ROOT/examples/example58.run-fail.cpp similarity index 90% rename from doc/examples/example58.run-fail.cpp rename to doc/modules/ROOT/examples/example58.run-fail.cpp index 9295b5dbde..13b5c68c19 100644 --- a/doc/examples/example58.run-fail.cpp +++ b/doc/modules/ROOT/examples/example58.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -15,4 +15,4 @@ BOOST_AUTO_TEST_CASE( test ) int j = 14; BOOST_CHECK_GT( i, j ); } -//] +// end::example_code[] diff --git a/doc/examples/example80_contexts.output b/doc/modules/ROOT/examples/example80_contexts.output similarity index 81% rename from doc/examples/example80_contexts.output rename to doc/modules/ROOT/examples/example80_contexts.output index 45254db5eb..2d105a299c 100644 --- a/doc/examples/example80_contexts.output +++ b/doc/modules/ROOT/examples/example80_contexts.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(14): error: in "test_case1": check false has failed @@ -8,4 +8,4 @@ Failure occurred in a following context: *** 1 failures is detected in test module "example80" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example80_contexts.run-fail.cpp b/doc/modules/ROOT/examples/example80_contexts.run-fail.cpp similarity index 92% rename from doc/examples/example80_contexts.run-fail.cpp rename to doc/modules/ROOT/examples/example80_contexts.run-fail.cpp index f878db6a55..a008106bf1 100644 --- a/doc/examples/example80_contexts.run-fail.cpp +++ b/doc/modules/ROOT/examples/example80_contexts.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example80 #include @@ -25,4 +25,4 @@ BOOST_AUTO_TEST_CASE(test_case1) BOOST_TEST_INFO("Delt" << a); test(); } -//] +// end::example_code[] diff --git a/doc/examples/example81_contexts.output b/doc/modules/ROOT/examples/example81_contexts.output similarity index 91% rename from doc/examples/example81_contexts.output rename to doc/modules/ROOT/examples/example81_contexts.output index a08bf08298..1c14846391 100644 --- a/doc/examples/example81_contexts.output +++ b/doc/modules/ROOT/examples/example81_contexts.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(20): error: in "test_case1": check 1 != 1 has failed [1 == 1] @@ -14,4 +14,4 @@ Failure occurred in a following context: test.cpp(29): error: in "test_case1": check 5 != 5 has failed [5 == 5] *** 4 failures are detected in test module "example81" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example81_contexts.run-fail.cpp b/doc/modules/ROOT/examples/example81_contexts.run-fail.cpp similarity index 93% rename from doc/examples/example81_contexts.run-fail.cpp rename to doc/modules/ROOT/examples/example81_contexts.run-fail.cpp index 346c8ab2c3..c0720bfc3a 100644 --- a/doc/examples/example81_contexts.run-fail.cpp +++ b/doc/modules/ROOT/examples/example81_contexts.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example81 #include @@ -28,4 +28,4 @@ BOOST_AUTO_TEST_CASE(test_case1) BOOST_TEST(5 != 5); } -//] +// end::example_code[] diff --git a/doc/examples/example82_contexts.output b/doc/modules/ROOT/examples/example82_contexts.output similarity index 94% rename from doc/examples/example82_contexts.output rename to doc/modules/ROOT/examples/example82_contexts.output index fd52945032..2f35e15e68 100644 --- a/doc/examples/example82_contexts.output +++ b/doc/modules/ROOT/examples/example82_contexts.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(27): error: in "test1": check processor.op2(i, j) has failed @@ -21,4 +21,4 @@ Failure occurred in a following context: With parameter j = 0 *** 4 failures are detected in the test module "example82" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/example82_contexts.run-fail.cpp b/doc/modules/ROOT/examples/example82_contexts.run-fail.cpp similarity index 96% rename from doc/examples/example82_contexts.run-fail.cpp rename to doc/modules/ROOT/examples/example82_contexts.run-fail.cpp index cbe15c7fc4..2fd6d22c27 100644 --- a/doc/examples/example82_contexts.run-fail.cpp +++ b/doc/modules/ROOT/examples/example82_contexts.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example82 #include @@ -41,4 +41,4 @@ BOOST_AUTO_TEST_CASE(test1) } } } -//] +// end::example_code[] diff --git a/doc/examples/example83_contexts.output b/doc/modules/ROOT/examples/example83_contexts.output similarity index 92% rename from doc/examples/example83_contexts.output rename to doc/modules/ROOT/examples/example83_contexts.output index 1596f05397..9c4c5f4fe6 100644 --- a/doc/examples/example83_contexts.output +++ b/doc/modules/ROOT/examples/example83_contexts.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(19): error: in "test_multi_context": check level < rand_value has failed [7 >= 5] @@ -15,4 +15,4 @@ Failure occurred in a following context: Random value=21 *** 3 failures are detected in the test module "example83 multicontext" -//] +// end::example_output[] diff --git a/doc/examples/example83_contexts.run-fail.cpp b/doc/modules/ROOT/examples/example83_contexts.run-fail.cpp similarity index 93% rename from doc/examples/example83_contexts.run-fail.cpp rename to doc/modules/ROOT/examples/example83_contexts.run-fail.cpp index d71dfe0c5b..22ca04e8a5 100644 --- a/doc/examples/example83_contexts.run-fail.cpp +++ b/doc/modules/ROOT/examples/example83_contexts.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example83 multicontext #include #include @@ -22,4 +22,4 @@ BOOST_AUTO_TEST_CASE(test_multi_context) } } } -//] +// end::example_code[] diff --git a/doc/examples/example84_contexts.output b/doc/modules/ROOT/examples/example84_contexts.output similarity index 94% rename from doc/examples/example84_contexts.output rename to doc/modules/ROOT/examples/example84_contexts.output index 157c983e96..1b43bb9c14 100644 --- a/doc/examples/example84_contexts.output +++ b/doc/modules/ROOT/examples/example84_contexts.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=message Seed = 162981956 test.cpp(34): error: in "quadratic_estimation": check minus_b * minus_b >= 4*c has failed [-13.999999999999998 * -13.999999999999998 < 195.99999999999997] @@ -20,4 +20,4 @@ Failure occurred in a following context: root2 = -7 *** 3 failures are detected in the test module "example84" -//] +// end::example_output[] diff --git a/doc/examples/example84_contexts.run-fail.cpp b/doc/modules/ROOT/examples/example84_contexts.run-fail.cpp similarity index 98% rename from doc/examples/example84_contexts.run-fail.cpp rename to doc/modules/ROOT/examples/example84_contexts.run-fail.cpp index f516237996..3bf321b5d5 100644 --- a/doc/examples/example84_contexts.run-fail.cpp +++ b/doc/modules/ROOT/examples/example84_contexts.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example84 #include #include @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(quadratic_estimation) BOOST_TEST(estimated.second == double(root2), 10. % boost::test_tools::tolerance()); } } -//] +// end::example_code[] BOOST_AUTO_TEST_CASE(making_it_fail) { diff --git a/doc/examples/exception_api.output b/doc/modules/ROOT/examples/exception_api.output similarity index 92% rename from doc/examples/exception_api.output rename to doc/modules/ROOT/examples/exception_api.output index c1d758dcfb..d586b16124 100644 --- a/doc/examples/exception_api.output +++ b/doc/modules/ROOT/examples/exception_api.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=all Running 1 test case... Entering test module "example" @@ -11,4 +11,4 @@ test.cpp:47: Leaving test case "test_throw_behaviour"; testing time: 533us Leaving test module "example"; testing time: 643us *** 1 failure is detected in the test module "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/exception_api.run-fail.cpp b/doc/modules/ROOT/examples/exception_api.run-fail.cpp similarity index 97% rename from doc/examples/exception_api.run-fail.cpp rename to doc/modules/ROOT/examples/exception_api.run-fail.cpp index efe2bc2481..c32f5d6009 100644 --- a/doc/examples/exception_api.run-fail.cpp +++ b/doc/modules/ROOT/examples/exception_api.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include #include @@ -62,4 +62,4 @@ BOOST_AUTO_TEST_CASE( test_throw_behaviour ) BOOST_CHECK_THROW(instance.result(), std::logic_error); } } -//] +// end::example_code[] diff --git a/doc/examples/exception_check.output b/doc/modules/ROOT/examples/exception_check.output similarity index 75% rename from doc/examples/exception_check.output rename to doc/modules/ROOT/examples/exception_check.output index d4458d43a2..613d93c5f5 100644 --- a/doc/examples/exception_check.output +++ b/doc/modules/ROOT/examples/exception_check.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > example Running 1 test case... test.cpp(11): error in "test": exception my_exception is expected *** 1 failures is detected in test suite "example" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/exception_check.run-fail.cpp b/doc/modules/ROOT/examples/exception_check.run-fail.cpp similarity index 91% rename from doc/examples/exception_check.run-fail.cpp rename to doc/modules/ROOT/examples/exception_check.run-fail.cpp index 4df22e2314..817c3d956f 100644 --- a/doc/examples/exception_check.run-fail.cpp +++ b/doc/modules/ROOT/examples/exception_check.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -16,4 +16,4 @@ BOOST_AUTO_TEST_CASE( test ) int i = 0; BOOST_CHECK_THROW( i++, my_exception ); } -//] +// end::example_code[] diff --git a/doc/examples/exception_check_predicate.output b/doc/modules/ROOT/examples/exception_check_predicate.output similarity index 92% rename from doc/examples/exception_check_predicate.output rename to doc/modules/ROOT/examples/exception_check_predicate.output index 8f57fd7df2..8b73484c74 100644 --- a/doc/examples/exception_check_predicate.output +++ b/doc/modules/ROOT/examples/exception_check_predicate.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=success Running 1 test case... Entering test module "example" @@ -9,4 +9,4 @@ test:24: Leaving test case "test_exception_predicate"; testing time: 203us Leaving test module "example"; testing time: 271us *** 1 failure is detected in the test module "example" -//] +// end::example_output[] diff --git a/doc/examples/exception_check_predicate.run-fail.cpp b/doc/modules/ROOT/examples/exception_check_predicate.run-fail.cpp similarity index 94% rename from doc/examples/exception_check_predicate.run-fail.cpp rename to doc/modules/ROOT/examples/exception_check_predicate.run-fail.cpp index 1229c0a096..2e2e08c064 100644 --- a/doc/examples/exception_check_predicate.run-fail.cpp +++ b/doc/modules/ROOT/examples/exception_check_predicate.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -26,4 +26,4 @@ BOOST_AUTO_TEST_CASE( test_exception_predicate ) BOOST_CHECK_EXCEPTION( some_func(0), my_exception, !is_critical ); BOOST_CHECK_EXCEPTION( some_func(1), my_exception, is_critical ); } -//] +// end::example_code[] diff --git a/doc/modules/ROOT/examples/exception_nothrow.output b/doc/modules/ROOT/examples/exception_nothrow.output new file mode 100644 index 0000000000..c9d54bf0c3 --- /dev/null +++ b/doc/modules/ROOT/examples/exception_nothrow.output @@ -0,0 +1,9 @@ +// tag::example_output[] +> example +Running 1 test case... +../doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp:18: error: in "test": exception thrown by some_func(-1) +../doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp:24: error: in "test": exception thrown by do { int i(-2); some_func(i); + } while(0) + +*** 2 failures are detected in the test module "example" +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/exception_nothrow.run-fail.cpp b/doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp similarity index 93% rename from doc/examples/exception_nothrow.run-fail.cpp rename to doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp index 1f3c76dc37..aa0dfb175d 100644 --- a/doc/examples/exception_nothrow.run-fail.cpp +++ b/doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -23,4 +23,4 @@ BOOST_AUTO_TEST_CASE( test ) } while(0) ); } -//] +// end::example_code[] diff --git a/doc/examples/exception_uncaught.output b/doc/modules/ROOT/examples/exception_uncaught.output similarity index 91% rename from doc/examples/exception_uncaught.output rename to doc/modules/ROOT/examples/exception_uncaught.output index 429d939e9b..dfc5406b1e 100644 --- a/doc/examples/exception_uncaught.output +++ b/doc/modules/ROOT/examples/exception_uncaught.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > example --log_level=all Running 2 test cases... Entering test module "example" @@ -12,4 +12,4 @@ test.cpp:26: Leaving test case "test2"; testing time: 103us Leaving test module "example"; testing time: 492us *** 1 failure is detected in the test module "example" -//] +// end::example_output[] diff --git a/doc/examples/exception_uncaught.run-fail.cpp b/doc/modules/ROOT/examples/exception_uncaught.run-fail.cpp similarity index 93% rename from doc/examples/exception_uncaught.run-fail.cpp rename to doc/modules/ROOT/examples/exception_uncaught.run-fail.cpp index 80d405b84d..0b224a8223 100644 --- a/doc/examples/exception_uncaught.run-fail.cpp +++ b/doc/modules/ROOT/examples/exception_uncaught.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE example #include @@ -27,4 +27,4 @@ BOOST_AUTO_TEST_CASE( test2 ) { BOOST_TEST(true); } -//] +// end::example_code[] diff --git a/doc/examples/fixture_02.output b/doc/modules/ROOT/examples/fixture_02.output similarity index 78% rename from doc/examples/fixture_02.output rename to doc/modules/ROOT/examples/fixture_02.output index e5dcbd696e..752825dd27 100644 --- a/doc/examples/fixture_02.output +++ b/doc/modules/ROOT/examples/fixture_02.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > fixture_02 --log_level=message Running 2 test cases... setup fixture @@ -9,4 +9,4 @@ running test_case2 teardown fixture *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/fixture_02.run.cpp b/doc/modules/ROOT/examples/fixture_02.run.cpp similarity index 94% rename from doc/examples/fixture_02.run.cpp rename to doc/modules/ROOT/examples/fixture_02.run.cpp index 31753113d7..05337dadbe 100644 --- a/doc/examples/fixture_02.run.cpp +++ b/doc/modules/ROOT/examples/fixture_02.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE fixture_02 #include @@ -31,4 +31,4 @@ BOOST_FIXTURE_TEST_SUITE(s, F) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/fixture_03.output b/doc/modules/ROOT/examples/fixture_03.output similarity index 75% rename from doc/examples/fixture_03.output rename to doc/modules/ROOT/examples/fixture_03.output index 3b1833ee51..ff73e788b2 100644 --- a/doc/examples/fixture_03.output +++ b/doc/modules/ROOT/examples/fixture_03.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > fixture_03 --log_level=message Running 2 test cases... setup fixture @@ -7,4 +7,4 @@ running test_case2 teardown fixture *** No errors detected -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/fixture_03.run.cpp b/doc/modules/ROOT/examples/fixture_03.run.cpp similarity index 94% rename from doc/examples/fixture_03.run.cpp rename to doc/modules/ROOT/examples/fixture_03.run.cpp index 18163d5fc4..2450c57949 100644 --- a/doc/examples/fixture_03.run.cpp +++ b/doc/modules/ROOT/examples/fixture_03.run.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE fixture_03 #include namespace utf = boost::unit_test; @@ -30,4 +30,4 @@ BOOST_AUTO_TEST_SUITE(s, * utf::fixture()) } BOOST_AUTO_TEST_SUITE_END() -//] +// end::example_code[] diff --git a/doc/examples/fixture_04.output b/doc/modules/ROOT/examples/fixture_04.output similarity index 86% rename from doc/examples/fixture_04.output rename to doc/modules/ROOT/examples/fixture_04.output index 9f3322735e..45f80e7ad5 100644 --- a/doc/examples/fixture_04.output +++ b/doc/modules/ROOT/examples/fixture_04.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > fixture_04 --log_level=message Running 2 test cases... ctor fixture i=0 @@ -10,4 +10,4 @@ teardown fixture i=1 dtor fixture i=3 *** 1 failure is detected in the test module "fixture_04" -//] +// end::example_output[] diff --git a/doc/examples/fixture_04.run-fail.cpp b/doc/modules/ROOT/examples/fixture_04.run-fail.cpp similarity index 95% rename from doc/examples/fixture_04.run-fail.cpp rename to doc/modules/ROOT/examples/fixture_04.run-fail.cpp index c41d3f48be..f976029d20 100644 --- a/doc/examples/fixture_04.run-fail.cpp +++ b/doc/modules/ROOT/examples/fixture_04.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE fixture_04 #include @@ -41,4 +41,4 @@ BOOST_AUTO_TEST_CASE(test_case2) BOOST_TEST_MESSAGE("running test_case2"); BOOST_TEST(MyGlobalFixture::i == 3); } -//] +// end::example_code[] diff --git a/doc/examples/logger-customization-point.output b/doc/modules/ROOT/examples/logger-customization-point.output similarity index 91% rename from doc/examples/logger-customization-point.output rename to doc/modules/ROOT/examples/logger-customization-point.output index 5317f0334f..e105127864 100644 --- a/doc/examples/logger-customization-point.output +++ b/doc/modules/ROOT/examples/logger-customization-point.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > logger-customization-point --log_level=all Running 1 test case... Entering test module "logger-customization-point" @@ -9,4 +9,4 @@ test.cpp(36): Leaving test case "test1"; testing time: 125us Leaving test module "logger-example-customization-point"; testing time: 157us *** 1 failure is detected in the test module "logger-customization-point" -//] +// end::example_output[] diff --git a/doc/examples/logger-customization-point.run-fail.cpp b/doc/modules/ROOT/examples/logger-customization-point.run-fail.cpp similarity index 96% rename from doc/examples/logger-customization-point.run-fail.cpp rename to doc/modules/ROOT/examples/logger-customization-point.run-fail.cpp index 8106a05715..f19b20f4d9 100644 --- a/doc/examples/logger-customization-point.run-fail.cpp +++ b/doc/modules/ROOT/examples/logger-customization-point.run-fail.cpp @@ -9,7 +9,7 @@ //! Customization point for printing user defined types // ***************************************************************************** -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE logger-customization-point #include @@ -42,4 +42,4 @@ BOOST_AUTO_TEST_CASE(test1) user_defined_type t2(11); BOOST_TEST(t2 == 11); } -//] +// end::example_code[] diff --git a/doc/examples/runtime-configuration_1.output b/doc/modules/ROOT/examples/runtime-configuration_1.output similarity index 93% rename from doc/examples/runtime-configuration_1.output rename to doc/modules/ROOT/examples/runtime-configuration_1.output index 3a76e1cc9b..07fdca9b40 100644 --- a/doc/examples/runtime-configuration_1.output +++ b/doc/modules/ROOT/examples/runtime-configuration_1.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > runtime_configuration1 --log_level=all --no_color -- --specific-param "'additional value with quotes'" Running 1 test case... Entering test module "runtime_configuration" @@ -11,4 +11,4 @@ test.cpp:14: Leaving test case "test_accessing_command_line"; testing time: 178u Leaving test module "runtime_configuration"; testing time: 220us *** No errors detected -//] +// end::example_output[] diff --git a/doc/examples/runtime-configuration_1.run-fail.cpp b/doc/modules/ROOT/examples/runtime-configuration_1.run-fail.cpp similarity index 94% rename from doc/examples/runtime-configuration_1.run-fail.cpp rename to doc/modules/ROOT/examples/runtime-configuration_1.run-fail.cpp index 3fb533f581..65508a024e 100644 --- a/doc/examples/runtime-configuration_1.run-fail.cpp +++ b/doc/modules/ROOT/examples/runtime-configuration_1.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE runtime_configuration1 #include using namespace boost::unit_test; @@ -17,4 +17,4 @@ BOOST_AUTO_TEST_CASE(test_accessing_command_line) BOOST_TEST( framework::master_test_suite().argv[2] == "'additional value with quotes'" ); BOOST_TEST_MESSAGE( "'argv[0]' contains " << framework::master_test_suite().argv[0] ); } -//] +// end::example_code[] diff --git a/doc/examples/runtime-configuration_2.output b/doc/modules/ROOT/examples/runtime-configuration_2.output similarity index 96% rename from doc/examples/runtime-configuration_2.output rename to doc/modules/ROOT/examples/runtime-configuration_2.output index c3ecc0570d..6d387979a6 100644 --- a/doc/examples/runtime-configuration_2.output +++ b/doc/modules/ROOT/examples/runtime-configuration_2.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] # Example run 1 > runtime_configuration2 --log_level=all -- --some-wrong-random-string mock_device Running 1 test case... @@ -25,4 +25,4 @@ test.cpp:62: info: check 'Cannot tear-down the device mock_device' has passed Leaving test module "runtime_configuration2"; testing time: 177us *** No errors detected -//] +// end::example_output[] diff --git a/doc/examples/runtime-configuration_2.run-fail.cpp b/doc/modules/ROOT/examples/runtime-configuration_2.run-fail.cpp similarity index 97% rename from doc/examples/runtime-configuration_2.run-fail.cpp rename to doc/modules/ROOT/examples/runtime-configuration_2.run-fail.cpp index 17ab1dca2a..a3243d6a6a 100644 --- a/doc/examples/runtime-configuration_2.run-fail.cpp +++ b/doc/modules/ROOT/examples/runtime-configuration_2.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE runtime_configuration2 #include using namespace boost::unit_test; @@ -73,4 +73,4 @@ BOOST_AUTO_TEST_CASE(check_device_has_meaningful_name) { BOOST_TEST(CommandLineDeviceInit::device->get_device_name() != ""); } -//] +// end::example_code[] diff --git a/doc/examples/runtime-configuration_3.output b/doc/modules/ROOT/examples/runtime-configuration_3.output similarity index 95% rename from doc/examples/runtime-configuration_3.output rename to doc/modules/ROOT/examples/runtime-configuration_3.output index d670dcc0f6..eb503b65b5 100644 --- a/doc/examples/runtime-configuration_3.output +++ b/doc/modules/ROOT/examples/runtime-configuration_3.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] # Example run 1 > runtime_configuration3 --log_level=all -- --create-parametrized 3 Running 3 test cases... @@ -24,4 +24,4 @@ Test setup error: std::runtime_error: test module initialization failed # Example run 3 > runtime_configuration3 --log_level=all -- --create-parametrized dummy Test setup error: boost::unit_test::framework::setup_error: Argument 'dummy' not integer -//] +// end::example_output[] diff --git a/doc/examples/runtime-configuration_3.run-fail.cpp b/doc/modules/ROOT/examples/runtime-configuration_3.run-fail.cpp similarity index 97% rename from doc/examples/runtime-configuration_3.run-fail.cpp rename to doc/modules/ROOT/examples/runtime-configuration_3.run-fail.cpp index 371b1d5e36..7b8e8cef6f 100644 --- a/doc/examples/runtime-configuration_3.run-fail.cpp +++ b/doc/modules/ROOT/examples/runtime-configuration_3.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_ALTERNATIVE_INIT_API #include #include @@ -61,4 +61,4 @@ bool init_unit_test() } return true; } -//] +// end::example_code[] diff --git a/doc/examples/runtime-configuration_4-test-fail.txt b/doc/modules/ROOT/examples/runtime-configuration_4-test-fail.txt similarity index 100% rename from doc/examples/runtime-configuration_4-test-fail.txt rename to doc/modules/ROOT/examples/runtime-configuration_4-test-fail.txt diff --git a/doc/examples/runtime-configuration_4-test.txt b/doc/modules/ROOT/examples/runtime-configuration_4-test.txt similarity index 100% rename from doc/examples/runtime-configuration_4-test.txt rename to doc/modules/ROOT/examples/runtime-configuration_4-test.txt diff --git a/doc/examples/runtime-configuration_4.output b/doc/modules/ROOT/examples/runtime-configuration_4.output similarity index 96% rename from doc/examples/runtime-configuration_4.output rename to doc/modules/ROOT/examples/runtime-configuration_4.output index 88e929084a..c71558e390 100644 --- a/doc/examples/runtime-configuration_4.output +++ b/doc/modules/ROOT/examples/runtime-configuration_4.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] # content of the file > more test_file.txt 10.2 30.4 @@ -33,4 +33,4 @@ Test setup error: Cannot open the file 'non-existant.txt' # Example run 3 > runtime_configuration4 --log_level=all Test setup error: Incorrect number of arguments -//] +// end::example_output[] diff --git a/doc/examples/runtime-configuration_4.run-fail.cpp b/doc/modules/ROOT/examples/runtime-configuration_4.run-fail.cpp similarity index 98% rename from doc/examples/runtime-configuration_4.run-fail.cpp rename to doc/modules/ROOT/examples/runtime-configuration_4.run-fail.cpp index 78a974f3b5..2453ec4417 100644 --- a/doc/examples/runtime-configuration_4.run-fail.cpp +++ b/doc/modules/ROOT/examples/runtime-configuration_4.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE runtime_configuration4 #include @@ -107,4 +107,4 @@ BOOST_DATA_TEST_CASE(command_line_test_file, input, expected) { BOOST_TEST(input <= expected); } -//] +// end::example_code[] diff --git a/doc/snippet/const_string.hpp b/doc/modules/ROOT/examples/snippets/const_string.hpp similarity index 100% rename from doc/snippet/const_string.hpp rename to doc/modules/ROOT/examples/snippets/const_string.hpp diff --git a/doc/snippet/const_string_test.cpp b/doc/modules/ROOT/examples/snippets/const_string_test.cpp similarity index 100% rename from doc/snippet/const_string_test.cpp rename to doc/modules/ROOT/examples/snippets/const_string_test.cpp diff --git a/doc/snippet/dataset_1/CMakeLists.txt b/doc/modules/ROOT/examples/snippets/dataset_1/CMakeLists.txt similarity index 100% rename from doc/snippet/dataset_1/CMakeLists.txt rename to doc/modules/ROOT/examples/snippets/dataset_1/CMakeLists.txt diff --git a/doc/snippet/dataset_1/test_file.cpp b/doc/modules/ROOT/examples/snippets/dataset_1/test_file.cpp similarity index 91% rename from doc/snippet/dataset_1/test_file.cpp rename to doc/modules/ROOT/examples/snippets/dataset_1/test_file.cpp index 7fcb020a75..6161aed652 100644 --- a/doc/snippet/dataset_1/test_file.cpp +++ b/doc/modules/ROOT/examples/snippets/dataset_1/test_file.cpp @@ -21,21 +21,21 @@ namespace data=boost::unit_test::data; -//[snippet_dataset1_1 +// tag::snippet_dataset1_1[] BOOST_DATA_TEST_CASE( test_case_arity1_implicit, data::xrange(5) ) { BOOST_TEST((sample <= 4 && sample >= 0)); } -//] +// end::snippet_dataset1_1[] -//[snippet_dataset1_2 +// tag::snippet_dataset1_2[] BOOST_DATA_TEST_CASE( test_case_arity1, data::xrange(5), my_var ) { BOOST_TEST((my_var <= 4 && my_var >= 0)); } -//] +// end::snippet_dataset1_2[] -//[snippet_dataset1_3 +// tag::snippet_dataset1_3[] // The following definition of the dataset test case throws an exception before the // test module starts (zip of non infinite or singleton datasets of different length) BOOST_DATA_TEST_CASE( test_case_arity2, data::xrange(2) ^ data::xrange(5), apples, potatoes) @@ -43,12 +43,12 @@ BOOST_DATA_TEST_CASE( test_case_arity2, data::xrange(2) ^ data::xrange(5), apple BOOST_TEST((apples <= 1 && apples >= 0)); BOOST_TEST((potatoes <= 4 && potatoes >= 0)); } -//] +// end::snippet_dataset1_3[] -//[snippet_dataset1_4 +// tag::snippet_dataset1_4[] std::vector generate() { std::vector out; @@ -64,7 +64,7 @@ BOOST_DATA_TEST_CASE( test_case_3, data::make(v), var1) BOOST_TEST_MESSAGE(var1); BOOST_CHECK(true); } -//] +// end::snippet_dataset1_4[] #include diff --git a/doc/modules/ROOT/examples/snippets/snippet12.cpp b/doc/modules/ROOT/examples/snippets/snippet12.cpp new file mode 100644 index 0000000000..b6a47220b1 --- /dev/null +++ b/doc/modules/ROOT/examples/snippets/snippet12.cpp @@ -0,0 +1,50 @@ +// (C) Copyright Gennadiy Rozental 2001-2015. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/test for the library home page. +// + +// tag::snippet12[] +#define BOOST_TEST_MODULE MyTest +#include + +int add( int i, int j ) { return i + j; } + +BOOST_AUTO_TEST_CASE(my_test) +{ + // six ways to detect and report the same error: + + // continues on error + BOOST_TEST( add(2, 2) == 4 ); <1> + + // throws on error + BOOST_TEST_REQUIRE( add(2, 2) == 4 ); <2> + + //continues on error + if (add(2, 2) != 4) + BOOST_ERROR( "Ouch..." ); <3> + + // throws on error + if (add(2, 2) != 4) + BOOST_FAIL( "Ouch..." ); <4> + + // throws on error + if (add(2, 2) != 4) + throw "Ouch..."; <5> + + // continues on error + BOOST_TEST( add(2, 2) == 4, <6> + "2 plus 2 is not 4 but " << add(2, 2)); +} +// end::snippet12[] + +/* tag::snippet12-callouts[] +<1> This approach uses tool BOOST_TEST, which displays an error message (by default on `std::cout`) that includes the expression that failed, as well as the values on the two side of the equation, the source file name, and the source file line number. It also increments the error count. At program termination, the error count will be displayed automatically by the Unit Test Framework. +<2> This approach uses tool BOOST_TEST_REQUIRE, is similar to approach #1, except that after displaying the error, an exception is thrown, to be caught by the Unit Test Framework. This approach is suitable when writing an explicit test program, and the error would be so severe as to make further testing impractical. +<3> This approach is similar to approach #1, except that the error detection and error reporting are coded separately. This is most useful when the specific condition being tested requires several independent statements and/or is not indicative of the reason for failure. +<4> This approach is similar to approach #2, except that the error detection and error reporting are coded separately. This is most useful when the specific condition being tested requires several independent statements and/or is not indicative of the reason for failure. +<5> This approach throws an exception, which will be caught and reported by the Unit Test Framework. The error message displayed when the exception is caught will be most meaningful if the exception is derived from `std::exception`, or is a `char*` or `std::string`. +<6> This approach uses tool BOOST_TEST with additional message argument, is similar to approach #1, except that similar to the approach #3 displays an alternative error message specified as a second argument. +end::snippet12-callouts[] */ diff --git a/doc/snippet/snippet13.cpp b/doc/modules/ROOT/examples/snippets/snippet13.cpp similarity index 79% rename from doc/snippet/snippet13.cpp rename to doc/modules/ROOT/examples/snippets/snippet13.cpp index e7827320f4..71535f2eee 100644 --- a/doc/snippet/snippet13.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet13.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. // -//[snippet13 -#define __BOOST_TEST_MODULE__ const_string test +// tag::snippet13[] +#define BOOST_TEST_MODULE const_string test #include -//] +// end::snippet13[] diff --git a/doc/snippet/snippet14.cpp b/doc/modules/ROOT/examples/snippets/snippet14.cpp similarity index 94% rename from doc/snippet/snippet14.cpp rename to doc/modules/ROOT/examples/snippets/snippet14.cpp index c02e62eb07..ccea0defcd 100644 --- a/doc/snippet/snippet14.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet14.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. // -//[snippet14 +// tag::snippet14[] class const_string { public: // Constructors @@ -23,4 +23,4 @@ class const_string { // ... }; -//] +// end::snippet14[] diff --git a/doc/snippet/snippet15.cpp b/doc/modules/ROOT/examples/snippets/snippet15.cpp similarity index 56% rename from doc/snippet/snippet15.cpp rename to doc/modules/ROOT/examples/snippets/snippet15.cpp index 043df1f48f..a181336a62 100644 --- a/doc/snippet/snippet15.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet15.cpp @@ -6,39 +6,39 @@ // See http://www.boost.org/libs/test for the library home page. // -//[snippet15 -#define __BOOST_TEST_MODULE__ const_string test +// tag::snippet15[] +#define BOOST_TEST_MODULE const_string test #include -__BOOST_AUTO_TEST_CASE__( constructors_test ) +BOOST_AUTO_TEST_CASE( constructors_test ) { const_string cs0( "" ); // 1 // - __BOOST_TEST__( cs0.length() == (size_t)0 ); - __BOOST_TEST__( cs0.is_empty() ); + BOOST_TEST( cs0.length() == (size_t)0 ); + BOOST_TEST( cs0.is_empty() ); const_string cs01( NULL ); // 2 // - __BOOST_TEST__( cs01.length() == (size_t)0 ); - __BOOST_TEST__( cs01.is_empty() ); + BOOST_TEST( cs01.length() == (size_t)0 ); + BOOST_TEST( cs01.is_empty() ); const_string cs1( "test_string" ); // 3 // - __BOOST_TEST__( std::strcmp( cs1.data(), "test_string" ) == 0 ); - __BOOST_TEST__( cs1.length() == std::strlen("test_string") ); + BOOST_TEST( std::strcmp( cs1.data(), "test_string" ) == 0 ); + BOOST_TEST( cs1.length() == std::strlen("test_string") ); std::string s( "test_string" ); // 4 // const_string cs2( s ); - __BOOST_TEST__( std::strcmp( cs2.data(), "test_string" ) == 0 ); + BOOST_TEST( std::strcmp( cs2.data(), "test_string" ) == 0 ); const_string cs3( cs1 ); // 5 // - __BOOST_TEST__( std::strcmp( cs3.data(), "test_string" ) == 0 ); + BOOST_TEST( std::strcmp( cs3.data(), "test_string" ) == 0 ); const_string cs4( "test_string", 4 ); // 6 // - __BOOST_TEST__( std::strncmp( cs4.data(), "test", cs4.length() ) == 0 ); + BOOST_TEST( std::strncmp( cs4.data(), "test", cs4.length() ) == 0 ); const_string cs5( s.data(), s.data() + s.length() ); // 7 // - __BOOST_TEST__( std::strncmp( cs5.data(), "test_string", cs5.length() ) == 0 ); + BOOST_TEST( std::strncmp( cs5.data(), "test_string", cs5.length() ) == 0 ); const_string cs_array[] = { "str1", "str2" }; // 8 // - __BOOST_TEST__( cs_array[0] == "str1" ); - __BOOST_TEST__( cs_array[1] == "str2" ); + BOOST_TEST( cs_array[0] == "str1" ); + BOOST_TEST( cs_array[1] == "str2" ); } -//] +// end::snippet15[] diff --git a/doc/snippet/snippet16.cpp b/doc/modules/ROOT/examples/snippets/snippet16.cpp similarity index 90% rename from doc/snippet/snippet16.cpp rename to doc/modules/ROOT/examples/snippets/snippet16.cpp index 8095e2cca3..12d8c56fb7 100644 --- a/doc/snippet/snippet16.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet16.cpp @@ -6,7 +6,7 @@ // See http://www.boost.org/libs/test for the library home page. // -//[snippet16 +// tag::snippet16[] class const_string { public: //... @@ -14,4 +14,4 @@ class const_string { char at( size_t index ) const; //... }; -//] +// end::snippet16[] diff --git a/doc/snippet/snippet17.cpp b/doc/modules/ROOT/examples/snippets/snippet17.cpp similarity index 50% rename from doc/snippet/snippet17.cpp rename to doc/modules/ROOT/examples/snippets/snippet17.cpp index f5842f6191..b652b5d46d 100644 --- a/doc/snippet/snippet17.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet17.cpp @@ -6,26 +6,26 @@ // See http://www.boost.org/libs/test for the library home page. // -//[snippet17 -#define __BOOST_TEST_MODULE__ const_string test +// tag::snippet17[] +#define BOOST_TEST_MODULE const_string test #include -__BOOST_AUTO_TEST_CASE__( constructors_test ) +BOOST_AUTO_TEST_CASE( constructors_test ) { //... } -__BOOST_AUTO_TEST_CASE__( data_access_test ) +BOOST_AUTO_TEST_CASE( data_access_test ) { const_string cs1( "test_string" ); // 1 // - __BOOST_TEST__( cs1[(size_t)0] == 't' ); - __BOOST_TEST__( cs1[(size_t)4] == '_' ); - __BOOST_TEST__( cs1[cs1.length()-1] == 'g' ); + BOOST_TEST( cs1[(size_t)0] == 't' ); + BOOST_TEST( cs1[(size_t)4] == '_' ); + BOOST_TEST( cs1[cs1.length()-1] == 'g' ); - __BOOST_TEST__( cs1[(size_t)0] == cs1.at( 0 ) ); // 2 // - __BOOST_TEST__( cs1[(size_t)2] == cs1.at( 5 ) ); - __BOOST_TEST__( cs1.at( cs1.length() - 1 ) == 'g' ); + BOOST_TEST( cs1[(size_t)0] == cs1.at( 0 ) ); // 2 // + BOOST_TEST( cs1[(size_t)2] == cs1.at( 5 ) ); + BOOST_TEST( cs1.at( cs1.length() - 1 ) == 'g' ); BOOST_CHECK_THROW( cs1.at( cs1.length() ), std::out_of_range ); // 3 // } -//] +// end::snippet17[] diff --git a/doc/snippet/snippet8.cpp b/doc/modules/ROOT/examples/snippets/snippet8.cpp similarity index 96% rename from doc/snippet/snippet8.cpp rename to doc/modules/ROOT/examples/snippets/snippet8.cpp index c0aa217fd0..910b2612e4 100644 --- a/doc/snippet/snippet8.cpp +++ b/doc/modules/ROOT/examples/snippets/snippet8.cpp @@ -7,7 +7,7 @@ // -//[snippet8 +// tag::snippet8[] double find_root( double (*f)(double), double low_guess, double high_guess, @@ -44,4 +44,4 @@ double find_root( double (*f)(double), return solution; } -//] +// end::snippet8[] diff --git a/doc/examples/tolerance_01.output b/doc/modules/ROOT/examples/tolerance_01.output similarity index 83% rename from doc/examples/tolerance_01.output rename to doc/modules/ROOT/examples/tolerance_01.output index 415f8efee6..8ed0901121 100644 --- a/doc/examples/tolerance_01.output +++ b/doc/modules/ROOT/examples/tolerance_01.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > tolerance_01 Running 1 test case... test.cpp(11): error: in "test1": check x == z has failed [10 != 10.000999999999999]. Relative difference exceeds tolerance [0.0001 > 1e-005] *** 1 failure is detected in the test module "tolerance_01" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_01.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_01.run-fail.cpp similarity index 92% rename from doc/examples/tolerance_01.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_01.run-fail.cpp index a236d843b8..e719ca8c34 100644 --- a/doc/examples/tolerance_01.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_01.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_01 #include namespace utf = boost::unit_test; @@ -18,4 +18,4 @@ BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(0.00001)) BOOST_TEST(x == y); // irrelevant difference BOOST_TEST(x == z); // relevant difference } -//] +// end::example_code[] diff --git a/doc/examples/tolerance_02.output b/doc/modules/ROOT/examples/tolerance_02.output similarity index 86% rename from doc/examples/tolerance_02.output rename to doc/modules/ROOT/examples/tolerance_02.output index a12a1921ff..edb9be1c07 100644 --- a/doc/examples/tolerance_02.output +++ b/doc/modules/ROOT/examples/tolerance_02.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > tolerance_02 Running 1 test case... test.cpp(12): error: in "test1": check x == y has failed [10 != 10.000000099999999] test.cpp(14): error: in "test1": check x == z has failed [10 != 10.000999999999999]. Relative difference exceeds tolerance [0.0001 > 1e-005] *** 2 failures are detected in the test module "tolerance_02" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_02.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_02.run-fail.cpp similarity index 94% rename from doc/examples/tolerance_02.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_02.run-fail.cpp index 1917f0da13..7d2b6a2fd6 100644 --- a/doc/examples/tolerance_02.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_02.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_02 #include namespace utf = boost::unit_test; @@ -22,4 +22,4 @@ BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(0.00001)) BOOST_TEST(x == z); // relevant by default BOOST_TEST(x == z, tt::tolerance(0.001)); } -//] +// end::example_code[] diff --git a/doc/examples/tolerance_03.output b/doc/modules/ROOT/examples/tolerance_03.output similarity index 92% rename from doc/examples/tolerance_03.output rename to doc/modules/ROOT/examples/tolerance_03.output index 0cb05f06c3..1102f223df 100644 --- a/doc/examples/tolerance_03.output +++ b/doc/modules/ROOT/examples/tolerance_03.output @@ -1,4 +1,4 @@ -//[example_output +// tag::example_output[] > tolerance_03 Running 2 test cases... test.cpp(18): error: in "failing": check x - d < x has failed [10 - 1.0000000000000001e-05 >= 10]. Relative difference is within tolerance [1e-06 < 0.001] @@ -7,4 +7,4 @@ test.cpp(21): error: in "failing": check d > .0 has failed [1.0000000000000001e- test.cpp(22): error: in "failing": check d < .0 has failed [1.0000000000000001e-05 >= 0] *** 4 failures are detected in the test module "tolerance_03" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_03.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_03.run-fail.cpp similarity index 95% rename from doc/examples/tolerance_03.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_03.run-fail.cpp index 38ee23797d..349bef922a 100644 --- a/doc/examples/tolerance_03.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_03.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_03 #include namespace utf = boost::unit_test; @@ -29,4 +29,4 @@ BOOST_AUTO_TEST_CASE(failing, * utf::tolerance(0.0001)) BOOST_TEST(d > .0); // positive, but too small BOOST_TEST(d < .0); // not sufficiently negative } -//] +// end::example_code[] diff --git a/doc/examples/tolerance_04.output b/doc/modules/ROOT/examples/tolerance_04.output similarity index 88% rename from doc/examples/tolerance_04.output rename to doc/modules/ROOT/examples/tolerance_04.output index 5a3b12a2ee..68a2d04624 100644 --- a/doc/examples/tolerance_04.output +++ b/doc/modules/ROOT/examples/tolerance_04.output @@ -1,8 +1,8 @@ -//[example_output +// tag::example_output[] > tolerance_04 Running 1 test case... test.cpp(23): error: in "test1": check x == y has failed [501/50 != 1001/100]. Relative difference exceeds tolerance [1/1001 > 1/2000] test.cpp(26): error: in "test1": check x != z has failed [501/50 == 10/1]. Relative difference is within tolerance [1/501 < 1/500] *** 2 failures are detected in the test module "tolerance_04" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_04.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_04.run-fail.cpp similarity index 95% rename from doc/examples/tolerance_04.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_04.run-fail.cpp index a8008c622e..ebc4ee19c5 100644 --- a/doc/examples/tolerance_04.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_04.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_04 #include #include @@ -33,4 +33,4 @@ BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(ratio(1, 1000))) BOOST_TEST(x != z); // relevant diff by default BOOST_TEST(x != z, tt::tolerance(ratio(2, 1000))); } -//] +// end::example_code[] diff --git a/doc/modules/ROOT/examples/tolerance_05.output b/doc/modules/ROOT/examples/tolerance_05.output new file mode 100644 index 0000000000..1699249cc2 --- /dev/null +++ b/doc/modules/ROOT/examples/tolerance_05.output @@ -0,0 +1,8 @@ +// tag::example_output[] +> tolerance_05 +Running 1 test case... +../doc/modules/ROOT/examples/tolerance_05.run.cpp(20): error: in "test": check o1 == o2 has failed [ 1 != 0.99] +../doc/modules/ROOT/examples/tolerance_05.run.cpp(21): error: in "test": check o1 == d2 has failed [ 1 != 0.98999999999999999] + +*** 2 failures are detected in the test module "tolerance_05" +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_05.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_05.run-fail.cpp similarity index 94% rename from doc/examples/tolerance_05.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_05.run-fail.cpp index dc964c2216..244ba443b7 100644 --- a/doc/examples/tolerance_05.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_05.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_05 #include #include @@ -21,4 +21,4 @@ BOOST_AUTO_TEST_CASE(test, * boost::unit_test::tolerance(0.02)) BOOST_TEST(o1 == d2); // without tolerance (optional vs. double) BOOST_TEST(*o1 == *o2); // with tolerance (double vs. double) } -//] +// end::example_code[] diff --git a/doc/examples/tolerance_06.output b/doc/modules/ROOT/examples/tolerance_06.output similarity index 83% rename from doc/examples/tolerance_06.output rename to doc/modules/ROOT/examples/tolerance_06.output index 4f3116356a..510990529e 100644 --- a/doc/examples/tolerance_06.output +++ b/doc/modules/ROOT/examples/tolerance_06.output @@ -1,7 +1,7 @@ -//[example_output +// tag::example_output[] > tolerance_06 Running 1 test case... test.cpp(21): error: in "test1": check x == 3 has failed [3.1415924049158361 != 3]. Relative difference exceeds tolerance [0.0471975 > 0.0471667] *** 1 failure is detected in the test module "tolerance_06" -//] \ No newline at end of file +// end::example_output[] \ No newline at end of file diff --git a/doc/examples/tolerance_06.run-fail.cpp b/doc/modules/ROOT/examples/tolerance_06.run-fail.cpp similarity index 94% rename from doc/examples/tolerance_06.run-fail.cpp rename to doc/modules/ROOT/examples/tolerance_06.run-fail.cpp index 04389d4fd4..9ca8afc229 100644 --- a/doc/examples/tolerance_06.run-fail.cpp +++ b/doc/modules/ROOT/examples/tolerance_06.run-fail.cpp @@ -5,7 +5,7 @@ // See http://www.boost.org/libs/test for the library home page. -//[example_code +// tag::example_code[] #define BOOST_TEST_MODULE tolerance_06 #include namespace utf = boost::unit_test; @@ -20,4 +20,4 @@ BOOST_AUTO_TEST_CASE(test1, * utf::tolerance(0.1415 / 3)) // == 0.047166667 // Value for this tolerance type is set by the decorator. BOOST_TEST(x == 3); } -//] +// end::example_code[] diff --git a/doc/modules/ROOT/partials/bt_example.adoc b/doc/modules/ROOT/partials/bt_example.adoc new file mode 100644 index 0000000000..863959fadd --- /dev/null +++ b/doc/modules/ROOT/partials/bt_example.adoc @@ -0,0 +1,26 @@ +// Replacement for the QuickBook `bt_example` template: shows a documentation +// example's source next to the output it produces. Both files live under +// modules/ROOT/examples and are compiled and run by the test suite, so what is +// shown here is what the example actually does. +// +// Callers set three attributes and include this partial: +// +// :bt-name: example22 <- basename under modules/ROOT/examples +// :bt-rule: run-fail <- `run` or `run-fail`, part of the filename +// :bt-descr: BOOST_TEST_CHECKPOINT usage +// include::partial$bt_example.adoc[] +// +[#{bt-name}] +.Example: {bt-descr} +==== +.Code +[source,cpp] +---- +include::example${bt-name}.{bt-rule}.cpp[tag=example_code] +---- + +.Output +.... +include::example${bt-name}.output[tag=example_output] +.... +==== diff --git a/doc/snippet/snippet12.cpp b/doc/snippet/snippet12.cpp deleted file mode 100644 index 48709fddb4..0000000000 --- a/doc/snippet/snippet12.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// (C) Copyright Gennadiy Rozental 2001-2015. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/test for the library home page. -// - -//[snippet12 -#define __BOOST_TEST_MODULE__ MyTest -#include - -int add( int i, int j ) { return i + j; } - -__BOOST_AUTO_TEST_CASE__(my_test) -{ - // six ways to detect and report the same error: - - // continues on error - __BOOST_TEST__( add(2, 2) == 4 ); /*< - This approach uses tool __BOOST_TEST__, which displays an error message (by default on `std::cout`) that includes - the expression that failed, as well as the values on the two side of the equation, the source file name, - and the source file line number. It also increments the error count. At program termination, - the error count will be displayed automatically by the __UTF__.>*/ - - // throws on error - __BOOST_TEST_REQUIRE__( add(2, 2) == 4 ); /*< - This approach uses tool __BOOST_TEST_REQUIRE__, is similar to approach #1, except that after displaying the error, - an exception is thrown, to be caught by the __UTF__. This approach is suitable when writing an - explicit test program, and the error would be so severe as to make further testing impractical. - >*/ - - //continues on error - if (add(2, 2) != 4) - __BOOST_ERROR__( "Ouch..." ); /*< - This approach is similar to approach #1, except that the error detection and error reporting are coded separately. - This is most useful when the specific condition being tested requires several independent statements and/or is - not indicative of the reason for failure. - >*/ - - // throws on error - if (add(2, 2) != 4) - __BOOST_FAIL__( "Ouch..." ); /*< - This approach is similar to approach #2, except that the error detection and error reporting are coded separately. - This is most useful when the specific condition being tested requires several independent statements and/or is - not indicative of the reason for failure. - >*/ - - // throws on error - if (add(2, 2) != 4) - throw "Ouch..."; /*< - This approach throws an exception, which will be caught and reported by the __UTF__. The error - message displayed when the exception is caught will be most meaningful if the exception is derived from - `std::exception`, or is a `char*` or `std::string`. - >*/ - - // continues on error - __BOOST_TEST__( add(2, 2) == 4, /*< - This approach uses tool __BOOST_TEST__ with additional message argument, is similar to approach #1, - except that similar to the approach #3 displays an alternative error message specified as a second argument. - >*/ - "2 plus 2 is not 4 but " << add(2, 2)); -} -//] diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py index 7509453974..20d0cb037a 100644 --- a/doc/tools/qbk2adoc.py +++ b/doc/tools/qbk2adoc.py @@ -779,32 +779,38 @@ def bt_example(self, rest, page): "include::partial$bt_example.adoc[]\n\n" % (name, rule, name, rule, self.inline(descr, page).strip())) - def register_import(self, target): - """Record an [import] and the //[callout] ids the file defines. + # doc/snippet and doc/examples are now both under modules/ROOT/examples, so + # the paths in the QuickBook [import]s have to be remapped. + EXAMPLES_ROOT = os.path.join(DOC, "modules", "ROOT", "examples") + IMPORT_REMAP = (("snippet/", "snippets/"), ("examples/", "")) - doc/snippet moves to modules/ROOT/examples/snippets; doc/examples is - already the examples root, and those files are pulled in by bt_example - rather than by a bare callout. - """ + def register_import(self, target): + """Record an [import] and the tag ids the imported file defines.""" self.imports.add(target) - path = os.path.normpath(os.path.join(DOC, target.replace("../", "", 1))) + rel = target.lstrip("./") + for old, new in self.IMPORT_REMAP: + if rel.startswith(old): + rel = new + rel[len(old):] + break + path = os.path.normpath(os.path.join(self.EXAMPLES_ROOT, rel)) if not os.path.isfile(path): self.fixmes["import-missing"] += 1 + sys.stderr.write(" missing import: %s\n" % target) return - rel = os.path.relpath(path, DOC) - if rel.startswith("snippet" + os.sep): - resource = "snippets/" + rel.split(os.sep, 1)[1].replace(os.sep, "/") - else: - resource = rel.replace(os.sep, "/") - for m in re.finditer(r"^\s*//\[([A-Za-z_]\w*)", + for m in re.finditer(r"^\s*(?://|/\*)\s*tag::([\w-]+)\[\]", open(path, encoding="utf-8", errors="replace").read(), re.M): - self.snippets[m.group(1)] = resource + self.snippets[m.group(1)] = rel.replace(os.sep, "/") def snippet_include(self, name): resource = self.snippets[name] - return ("[source,cpp]\n----\ninclude::example$%s[tag=%s]\n----\n\n" - % (resource, name)) + out = ("[source,cpp]\n----\ninclude::example$%s[tag=%s]\n----\n" + % (resource, name)) + # Snippets carrying AsciiDoc callouts keep the colist beside the code, + # in a `-callouts` region of the same file. + if name + "-callouts" in self.snippets: + out += "include::example$%s[tag=%s-callouts]\n" % (resource, name) + return out + "\n" def table(self, inner, page): m = re.match(r"table(?::(\S+))?\s*", inner) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7133a93b93..105cf99bc3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,13 +18,13 @@ set(BOOST_TEST_EXAMPLES_FOLDER ${BOOST_TEST_ROOT_DIR}/example) file(GLOB_RECURSE BOOST_UTF_DOC_EXAMPLES CONFIGURE_DEPENDS - ${BOOST_TEST_ROOT_DIR}/doc/examples/*.cpp) + ${BOOST_TEST_ROOT_DIR}/doc/modules/ROOT/examples/*.cpp) foreach(_h IN LISTS BOOST_UTF_DOC_EXAMPLES) get_filename_component(_hh ${_h} NAME_WE) add_executable(doc-${_hh} ${_h} - ${BOOST_TEST_ROOT_DIR}/doc/examples/${_hh}.output) + ${BOOST_TEST_ROOT_DIR}/doc/modules/ROOT/examples/${_hh}.output) set_target_properties(doc-${_hh} PROPERTIES FOLDER "Doc examples" diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2b8d007fd5..d756b1c87f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -96,7 +96,7 @@ rule docs-example-as-test ( test-file ) return [ boost.test-self-test $(test-name-rule[2]) - : ../doc/examples + : ../doc/modules/ROOT/examples : doc-$(test-name-rule[1]) : included : @@ -248,7 +248,7 @@ import sequence ; test-suite "doc-examples-ts" : - [ sequence.transform docs-example-as-test : [ glob ../doc/examples/*.cpp ] ] + [ sequence.transform docs-example-as-test : [ glob ../doc/modules/ROOT/examples/*.cpp ] ] ; #_________________________________________________________________________________________________# @@ -441,12 +441,12 @@ alias "smoke-ts" [ run smoke-ts-included-4 : \"--run_test=some_suite/test>,test>\" \"--run_test=test>\" : : : cla-template-test-case-sanity-15 ] ; -alias custom-command-line-binary-1 : ../doc/examples/runtime-configuration_1.run-fail.cpp ; -alias custom-command-line-binary-2 : ../doc/examples/runtime-configuration_2.run-fail.cpp +alias custom-command-line-binary-1 : ../doc/modules/ROOT/examples/runtime-configuration_1.run-fail.cpp ; +alias custom-command-line-binary-2 : ../doc/modules/ROOT/examples/runtime-configuration_2.run-fail.cpp : $(requirements_boost_test_full_support) ; -alias custom-command-line-binary-3 : ../doc/examples/runtime-configuration_3.run-fail.cpp +alias custom-command-line-binary-3 : ../doc/modules/ROOT/examples/runtime-configuration_3.run-fail.cpp : $(requirements_boost_test_full_support) ; -alias custom-command-line-binary-4 : ../doc/examples/runtime-configuration_4.run-fail.cpp +alias custom-command-line-binary-4 : ../doc/modules/ROOT/examples/runtime-configuration_4.run-fail.cpp : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) ; alias "custom-command-line-ts" @@ -466,10 +466,10 @@ alias "custom-command-line-ts" [ run-fail custom-command-line-binary-4 : -- : : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-0 ] [ run-fail custom-command-line-binary-4 : -- --test-file : : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-1 ] -[ run-fail custom-command-line-binary-4 : -- --test-file : ../doc/examples/runtime-configuration_4-test-fail.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-2 ] -[ run-fail custom-command-line-binary-4 : --log_level=all --no_color -- --test-file : ../doc/examples/runtime-configuration_4-test-fail.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-3 ] -[ run custom-command-line-binary-4 : -- --test-file : ../doc/examples/runtime-configuration_4-test.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-4 ] -[ run custom-command-line-binary-4 : --log_level=all --no_color -- --test-file : ../doc/examples/runtime-configuration_4-test.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-5 ] +[ run-fail custom-command-line-binary-4 : -- --test-file : ../doc/modules/ROOT/examples/runtime-configuration_4-test-fail.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-2 ] +[ run-fail custom-command-line-binary-4 : --log_level=all --no_color -- --test-file : ../doc/modules/ROOT/examples/runtime-configuration_4-test-fail.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-3 ] +[ run custom-command-line-binary-4 : -- --test-file : ../doc/modules/ROOT/examples/runtime-configuration_4-test.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-4 ] +[ run custom-command-line-binary-4 : --log_level=all --no_color -- --test-file : ../doc/modules/ROOT/examples/runtime-configuration_4-test.txt : $(requirements_datasets) [ requires cxx11_trailing_result_types cxx11_auto_declarations ] $(l_gcc_c11_rvalue_full_support) : cla-specific-api1-test-4-5 ] ; From b4fbb0cc8b46824145d3b2f83af7feb27aea841c Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 11:54:10 -0400 Subject: [PATCH 04/10] doc: convert the QuickBook chapters to AsciiDoc Generated by doc/tools/qbk2adoc.py: 210 QuickBook sections become 76 Antora pages under modules/ROOT/pages, one per chapter or per included .qbk file, with deeper sections as in-page headings carrying their original ids. The 85 [def] macros become AsciiDoc attributes in antora.yml rather than ~2000 expanded xrefs, so a reference page can still be renamed in one place. nav.adoc mirrors the old chapter tree. Every page also carries :page-aliases: with its old BoostBook path, which gets deep links to the right page. The #fragment is lost through a redirect; Antora has no mechanism to preserve it. Two defects in the sources are fixed rather than reproduced: one table row carried an extra cell that DocBook silently dropped, and two different tables shared the id id_range_parameter_table -- the second, which lists the random generator's parameters, becomes id_random_parameter_table. doc/Jamfile.v2 now drives build_antora.sh; the doxygen, quickbook and boostbook targets are gone. boostdoc/boostrelease still work for the superproject. The .qbk sources are now unreferenced and are deleted at the end of the port. Antora builds the site with no warnings beyond MrDocs not being wired up yet. Co-Authored-By: Claude Opus 5 (1M context) --- doc/Jamfile.v2 | 198 ++-- doc/antora.yml | 85 ++ doc/modules/ROOT/nav.adoc | 77 +- doc/modules/ROOT/pages/acknowledgments.adoc | 23 + .../ROOT/pages/adv_scenarios/build_utf.adoc | 63 ++ .../adv_scenarios/entry_point_overview.adoc | 32 + .../adv_scenarios/external_test_runner.adoc | 15 + .../ROOT/pages/adv_scenarios/index.adoc | 28 + .../adv_scenarios/obsolete_init_func.adoc | 45 + .../shared_lib_customizations.adoc | 120 +++ .../single_header_customizations.adoc | 84 ++ .../static_lib_customizations.adoc | 145 +++ .../test_module_init_overview.adoc | 45 + .../test_module_runner_overview.adoc | 52 ++ doc/modules/ROOT/pages/change_log.adoc | 606 ++++++++++++ doc/modules/ROOT/pages/index.adoc | 61 +- .../ROOT/pages/intro/design_rationale.adoc | 36 + doc/modules/ROOT/pages/intro/how_to_read.adoc | 23 + .../ROOT/pages/runtime_config/index.adoc | 43 + .../pages/runtime_config/runtime_custom.adoc | 151 +++ .../ROOT/pages/runtime_config/summary.adoc | 87 ++ .../runtime_config/test_unit_filtering.adoc | 321 +++++++ doc/modules/ROOT/pages/section_faq.adoc | 189 ++++ doc/modules/ROOT/pages/section_glossary.adoc | 117 +++ .../ROOT/pages/test_output/checkpoints.adoc | 60 ++ .../ROOT/pages/test_output/contexts.adoc | 203 +++++ doc/modules/ROOT/pages/test_output/index.adoc | 42 + .../test_output/log_floating_points.adoc | 30 + .../ROOT/pages/test_output/log_formats.adoc | 222 +++++ .../ROOT/pages/test_output/logging_api.adoc | 149 +++ .../pages/test_output/report_formats.adoc | 90 ++ .../ROOT/pages/test_output/summary.adoc | 30 + .../test_output/test_output_progress.adoc | 36 + .../test_tools_support_for_logging.adoc | 87 ++ .../ROOT/pages/testing_tools/bitwise.adoc | 15 + .../boost_test_universal_macro.adoc | 105 +++ .../ROOT/pages/testing_tools/collections.adoc | 262 ++++++ .../testing_tools/custom_predicates.adoc | 34 + .../ROOT/pages/testing_tools/debugging.adoc | 39 + .../testing_tools/exception_correctness.adoc | 49 + .../testing_tools/expected_failures.adoc | 93 ++ .../pages/testing_tools/floating_point.adoc | 487 ++++++++++ .../ROOT/pages/testing_tools/index.adoc | 26 + .../pages/testing_tools/internal_details.adoc | 75 ++ .../testing_tools/output_stream_testing.adoc | 90 ++ .../ROOT/pages/testing_tools/reports.adoc | 61 ++ .../ROOT/pages/testing_tools/strings.adoc | 23 + .../ROOT/pages/testing_tools/summary.adoc | 104 +++ .../ROOT/pages/testing_tools/timeout.adoc | 36 + .../tools_assertion_severity_level.adoc | 62 ++ .../pages/tests_organization/decorators.adoc | 221 +++++ .../pages/tests_organization/enabling.adoc | 82 ++ .../pages/tests_organization/fixtures.adoc | 330 +++++++ .../ROOT/pages/tests_organization/index.adoc | 49 + .../tests_organization/master_test_suite.adoc | 89 ++ .../pages/tests_organization/param_test.adoc | 77 ++ .../pages/tests_organization/semantic.adoc | 20 + .../pages/tests_organization/summary.adoc | 85 ++ .../test_case_generation.adoc | 614 +++++++++++++ .../pages/tests_organization/test_cases.adoc | 49 + .../pages/tests_organization/test_naming.adoc | 46 + .../test_organization_nullary.adoc | 80 ++ .../test_organization_templates.adoc | 180 ++++ .../pages/tests_organization/test_suite.adoc | 133 +++ .../pages/tests_organization/test_tree.adoc | 31 + .../tests_organization/test_tree_content.adoc | 12 + .../tests_dependencies.adoc | 47 + .../tests_organization/tests_grouping.adoc | 29 + .../usage_recommendations/bt_and_tdd.adoc | 94 ++ .../pages/usage_recommendations/hello.adoc | 73 ++ .../pages/usage_recommendations/index.adoc | 165 ++++ .../usage_recommendations/web_wisdom.adoc | 48 + doc/modules/ROOT/pages/usage_variants.adoc | 91 ++ .../ROOT/pages/utf_reference/index.adoc | 4 + .../pages/utf_reference/link_references.adoc | 129 +++ .../utf_reference/rt_param_reference.adoc | 859 ++++++++++++++++++ .../utf_reference/test_org_reference.adoc | 301 ++++++ .../pages/utf_reference/testing_tool_ref.adoc | 745 +++++++++++++++ .../utf_reference/testout_reference.adoc | 53 ++ doc/tools/attributes.yml | 85 ++ doc/tools/nav.adoc | 76 ++ doc/tools/qbk2adoc.py | 26 +- 82 files changed, 9927 insertions(+), 152 deletions(-) create mode 100644 doc/modules/ROOT/pages/acknowledgments.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/index.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc create mode 100644 doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc create mode 100644 doc/modules/ROOT/pages/change_log.adoc create mode 100644 doc/modules/ROOT/pages/intro/design_rationale.adoc create mode 100644 doc/modules/ROOT/pages/intro/how_to_read.adoc create mode 100644 doc/modules/ROOT/pages/runtime_config/index.adoc create mode 100644 doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc create mode 100644 doc/modules/ROOT/pages/runtime_config/summary.adoc create mode 100644 doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc create mode 100644 doc/modules/ROOT/pages/section_faq.adoc create mode 100644 doc/modules/ROOT/pages/section_glossary.adoc create mode 100644 doc/modules/ROOT/pages/test_output/checkpoints.adoc create mode 100644 doc/modules/ROOT/pages/test_output/contexts.adoc create mode 100644 doc/modules/ROOT/pages/test_output/index.adoc create mode 100644 doc/modules/ROOT/pages/test_output/log_floating_points.adoc create mode 100644 doc/modules/ROOT/pages/test_output/log_formats.adoc create mode 100644 doc/modules/ROOT/pages/test_output/logging_api.adoc create mode 100644 doc/modules/ROOT/pages/test_output/report_formats.adoc create mode 100644 doc/modules/ROOT/pages/test_output/summary.adoc create mode 100644 doc/modules/ROOT/pages/test_output/test_output_progress.adoc create mode 100644 doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/bitwise.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/collections.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/debugging.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/expected_failures.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/floating_point.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/index.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/internal_details.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/reports.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/strings.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/summary.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/timeout.adoc create mode 100644 doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/decorators.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/enabling.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/fixtures.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/index.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/param_test.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/semantic.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/summary.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_cases.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_naming.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_suite.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_tree.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc create mode 100644 doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc create mode 100644 doc/modules/ROOT/pages/usage_recommendations/bt_and_tdd.adoc create mode 100644 doc/modules/ROOT/pages/usage_recommendations/hello.adoc create mode 100644 doc/modules/ROOT/pages/usage_recommendations/index.adoc create mode 100644 doc/modules/ROOT/pages/usage_recommendations/web_wisdom.adoc create mode 100644 doc/modules/ROOT/pages/usage_variants.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/index.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/link_references.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc create mode 100644 doc/modules/ROOT/pages/utf_reference/testout_reference.adoc create mode 100644 doc/tools/attributes.yml create mode 100644 doc/tools/nav.adoc diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 43690e8b5d..d26de8c60f 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -5,152 +5,64 @@ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # -using quickbook ; -using doxygen ; -using boostbook ; - -######################################################################## -# Standalone HTML documentation - -import doxygen ; - -path-constant TEST_ROOT : .. ; - -doxygen doxygen_reference_generated_doc - : - $(TEST_ROOT)/include/boost/test/debug_config.hpp - $(TEST_ROOT)/include/boost/test/detail/global_typedef.hpp - $(TEST_ROOT)/include/boost/test/debug.hpp - $(TEST_ROOT)/include/boost/test/execution_monitor.hpp - $(TEST_ROOT)/include/boost/test/framework.hpp - $(TEST_ROOT)/include/boost/test/tools/assertion_result.hpp - $(TEST_ROOT)/include/boost/test/unit_test.hpp - $(TEST_ROOT)/include/boost/test/tree/observer.hpp - - # logs and formatters - $(TEST_ROOT)/include/boost/test/unit_test_log.hpp - $(TEST_ROOT)/include/boost/test/output/xml_log_formatter.hpp - $(TEST_ROOT)/include/boost/test/output/plain_report_formatter.hpp - $(TEST_ROOT)/include/boost/test/output/compiler_log_formatter.hpp - - # reports - $(TEST_ROOT)/include/boost/test/output/xml_report_formatter.hpp - $(TEST_ROOT)/include/boost/test/unit_test_log_formatter.hpp - $(TEST_ROOT)/include/boost/test/results_reporter.hpp - $(TEST_ROOT)/include/boost/test/results_collector.hpp - - # progress monitor - $(TEST_ROOT)/include/boost/test/progress_monitor.hpp - - # test cases and suites - $(TEST_ROOT)/include/boost/test/tree/test_unit.hpp - $(TEST_ROOT)/include/boost/test/parameterized_test.hpp - - # execution monitor source files - $(TEST_ROOT)/include/boost/test/execution_monitor.hpp - - # output test stream - $(TEST_ROOT)/include/boost/test/tools/output_test_stream.hpp - - # datasets - $(TEST_ROOT)/include/boost/test/data/monomorphic/fwd.hpp - $(TEST_ROOT)/include/boost/test/data/test_case.hpp - $(TEST_ROOT)/include/boost/test/data/for_each_sample.hpp - $(TEST_ROOT)/include/boost/test/data/size.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/delayed.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/initializer_list.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/array.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/collection.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/generate.hpp - - - $(TEST_ROOT)/include/boost/test/data/monomorphic/grid.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/join.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/singleton.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/zip.hpp - - # datasets generators - $(TEST_ROOT)/include/boost/test/data/config.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/generators.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/generators/keywords.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/generators/random.hpp - $(TEST_ROOT)/include/boost/test/data/monomorphic/generators/xrange.hpp - - # utils - $(TEST_ROOT)/include/boost/test/utils/algorithm.hpp - $(TEST_ROOT)/include/boost/test/utils/named_params.hpp - $(TEST_ROOT)/include/boost/test/tools/floating_point_comparison.hpp - $(TEST_ROOT)/include/boost/test/utils/is_forward_iterable.hpp - - # BOOST_TEST related functions - $(TEST_ROOT)/include/boost/test/tools/detail/bitwise_manip.hpp - $(TEST_ROOT)/include/boost/test/tools/detail/lexicographic_manip.hpp - $(TEST_ROOT)/include/boost/test/tools/detail/per_element_manip.hpp - $(TEST_ROOT)/include/boost/test/tools/detail/tolerance_manip.hpp - - # others - $(TEST_ROOT)/include/boost/test/unit_test_parameters.hpp - : - EXTRACT_ALL=YES - "PREDEFINED=\"BOOST_TEST_DECL=\" \\ - \"BOOST_TEST_DOXYGEN_DOC__=1\" - " - HIDE_UNDOC_MEMBERS=NO - AUTOLINK_SUPPORT=YES - HIDE_UNDOC_CLASSES=NO - INLINE_INHERITED_MEMB=YES - EXTRACT_PRIVATE=NO - ENABLE_PREPROCESSING=YES - MACRO_EXPANSION=YES - EXPAND_ONLY_PREDEF=YES - SEARCH_INCLUDES=YES - INCLUDE_PATH=$(TEST_ROOT)/include - EXAMPLE_PATH=$(TEST_ROOT)/doc/examples - BRIEF_MEMBER_DESC=YES - REPEAT_BRIEF=YES - ALWAYS_DETAILED_SEC=YES - MULTILINE_CPP_IS_BRIEF=YES - CASE_SENSE_NAMES=YES - INTERNAL_DOCS=NO - SUBGROUPING=YES - SHORT_NAMES=YES - ; - - - -######################################################################## -# HTML documentation for $(BOOST_ROOT)/doc/html - -xml test_doc - : - test.qbk - ; - -explicit test_doc ; - -path-constant images_location : html ; - -boostbook standalone - : - test_doc - : - boost.root=../../../.. - html.stylesheet=boostbook.css - chapter.autolabel=0 - toc.max.depth=3 - toc.section.depth=10 - chunk.section.depth=4 - chunk.first.sections=1 - generate.section.toc.level=3 - pdf:img.src.path=$(images_location)/ - pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/test/doc/html - doxygen_reference_generated_doc +# The documentation is built by Antora, driven by build_antora.sh. The API +# reference inside it is generated by MrDocs. Neither Quickbook, Doxygen nor +# BoostBook is involved any more. + +import generate ; +import path ; +import property-set ; +import virtual-target ; + +path-constant HERE : . ; + +make html/index.html : build_antora.sh : @run-script ; +generate files-to-install : html/index.html : @delayed-glob ; +install install + : files-to-install + : html + html/test ; - -explicit test ; +explicit html/index.html files-to-install ; + +# this runs the antora script +actions run-script +{ + bash $(>) +} + +# this globs after its sources are created +rule delayed-glob ( project name : property-set : sources * ) +{ + for local src in $(sources) + { + # the next line causes the source to be generated immediately + # and not later (which it normally would) + UPDATE_NOW [ $(src).actualize ] ; + } + + # we need to construct the path to the globbed directory; + # this path would be /html + local root = [ path.root html [ $(project).location ] ] ; + local files ; + + # actual globbing happens here + for local file in [ path.glob-tree $(root) : * ] + { + # we have to skip directories, because our match expression accepts anything + if [ CHECK_IF_FILE $(file) ] + { + # we construct a list of targets to copy + files += [ virtual-target.from-file $(file:D=) : $(file:D) : $(project) ] ; + } + } + + # we prepend empty usage requirements to the result + return [ property-set.empty ] $(files) ; +} ############################################################################### alias boostdoc ; explicit boostdoc ; -alias boostrelease : standalone ; +alias boostrelease : install ; explicit boostrelease ; diff --git a/doc/antora.yml b/doc/antora.yml index c987f2c0fc..9a83344b51 100644 --- a/doc/antora.yml +++ b/doc/antora.yml @@ -28,6 +28,91 @@ asciidoc: # The QuickBook [def] macros were mostly link aliases into the reference # chapter. They are kept as attributes so a reference page can be renamed # in one place instead of at ~2000 call sites. + utf: '_Unit Test Framework_' + pem: '_Program Execution Monitor_' + ieee754: '*IEEE754*' + part_faq: 'xref:section_faq.adoc[FAQ]' + floating_points_testing_tools: 'xref:testing_tools/floating_point.adoc#floating_points_comparison_theory[Floating point comparison algorithms]' + master_test_suite: 'xref:tests_organization/master_test_suite.adoc[master test suite]' + runtime_configuration: 'xref:runtime_config/index.adoc[runtime configuration]' + output_test_stream_tool: 'xref:testing_tools/output_stream_testing.adoc[output test stream]' + auto_linking: 'automatic linking // FIXME(qbk2adoc): unresolved link ref_pem_auto_link' + boost_test_alternative_init_api: 'xref:utf_reference/link_references.adoc#link_boost_test_alternative_init_macro[`BOOST_TEST_ALTERNATIVE_INIT_API`]' + boost_test_main: 'xref:utf_reference/link_references.adoc#link_boost_test_main_macro[`BOOST_TEST_MAIN`]' + boost_test_dyn_link: 'xref:utf_reference/link_references.adoc#link_boost_test_dyn_link[`BOOST_TEST_DYN_LINK`]' + boost_test_no_lib: 'xref:utf_reference/link_references.adoc#link_boost_test_no_lib[`BOOST_TEST_NO_LIB`]' + boost_test_no_main: 'xref:utf_reference/link_references.adoc#link_boost_test_no_main[`BOOST_TEST_NO_MAIN`]' + boost_test_module: 'xref:utf_reference/link_references.adoc#link_boost_test_module_macro[`BOOST_TEST_MODULE`]' + boost_test_global_configuration: 'xref:utf_reference/link_references.adoc#link_boost_test_global_configuration[`BOOST_TEST_GLOBAL_CONFIGURATION`]' + boost_test_checkpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_checkpoint[`BOOST_TEST_CHECKPOINT`]' + boost_test_passpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_passpoint[`BOOST_TEST_PASSPOINT`]' + boost_test_message: 'xref:utf_reference/testout_reference.adoc#test_output_macro_message[`BOOST_TEST_MESSAGE`]' + boost_test_info: 'xref:utf_reference/testout_reference.adoc#test_output_macro_info[`BOOST_TEST_INFO`]' + boost_test_context: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context[`BOOST_TEST_CONTEXT`]' + boost_test_info_scope: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context_sticky[`BOOST_TEST_INFO_SCOPE`]' + boost_test_dont_print_log_value: 'xref:utf_reference/testout_reference.adoc#test_output_macro_disable_type[`BOOST_TEST_DONT_PRINT_LOG_VALUE`]' + boost_test: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST`]' + boost_test_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_`]' + boost_test_require: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_REQUIRE`]' + boost_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level[`BOOST_`]' + boost_level_message: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_message[`BOOST__MESSAGE`]' + boost_level_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq[`BOOST__EQUAL`]' + boost_level_predicate: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate[`BOOST__PREDICATE`]' + boost_level_equal_collections: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections[`BOOST__EQUAL_COLLECTIONS`]' + boost_level_ne: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne[`BOOST__NE`]' + boost_level_ge: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge[`BOOST__GE`]' + boost_level_gt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt[`BOOST__GT`]' + boost_level_le: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_le[`BOOST__LE`]' + boost_level_lt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt[`BOOST__LT`]' + boost_level_no_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw[`BOOST__NO_THROW`]' + boost_level_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST__THROW`]' + boost_level_exception: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception[`BOOST__EXCEPTION`]' + boost_level_bitwise_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq[`BOOST__BITWISE_EQUAL`]' + boost_error: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_error[`BOOST_ERROR`]' + boost_fail: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_fail[`BOOST_FAIL`]' + boost_is_defined: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined[`BOOST_IS_DEFINED`]' + boost_auto_test_case_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`]' + boost_level_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST__SMALL`]' + boost_check_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST_CHECK_SMALL`]' + boost_level_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST__CLOSE`]' + boost_check_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST_CHECK_CLOSE`]' + boost_level_close_fraction: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction[`BOOST__CLOSE_FRACTION`]' + boost_test_tools_under_debugger: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`]' + boost_test_tools_debuggable: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable[`BOOST_TEST_TOOLS_DEBUGGABLE`]' + boost_auto_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case[`BOOST_AUTO_TEST_CASE`]' + boost_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE`]' + boost_test_case_name: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE_NAME`]' + boost_auto_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template[`BOOST_AUTO_TEST_CASE_TEMPLATE`]' + boost_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template[`BOOST_TEST_CASE_TEMPLATE`]' + boost_test_case_template_function: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`]' + boost_param_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter[`BOOST_PARAM_TEST_CASE`]' + boost_data_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_DATA_TEST_CASE`]' + boost_data_test_case_f: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture[`BOOST_DATA_TEST_CASE_F`]' + boost_test_dataset_max_arity: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_TEST_DATASET_MAX_ARITY`]' + boost_auto_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite[`BOOST_AUTO_TEST_SUITE`]' + boost_auto_test_suite_end: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end[`BOOST_AUTO_TEST_SUITE_END`]' + boost_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite[`BOOST_TEST_SUITE`]' + boost_test_decorator: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_decorator[`BOOST_TEST_DECORATOR`]' + boost_fixture_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture[`BOOST_FIXTURE_TEST_CASE`]' + boost_fixture_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture[`BOOST_FIXTURE_TEST_SUITE`]' + boost_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_global_fixture[`BOOST_GLOBAL_FIXTURE`]' + boost_test_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture[`BOOST_TEST_GLOBAL_FIXTURE`]' + boost_test_log_level: 'xref:utf_reference/rt_param_reference.adoc#log_level[`BOOST_TEST_LOG_LEVEL`]' + default_run_status: 'xref:runtime_config/test_unit_filtering.adoc#ref_default_run_status[_default run status_]' + param_run_test: 'xref:utf_reference/rt_param_reference.adoc#run_test[`run_test`]' + decorator_label: 'xref:utf_reference/test_org_reference.adoc#decorator_label[`label`]' + decorator_enabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`enabled`]' + decorator_disabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`disabled`]' + decorator_enable_if: 'xref:utf_reference/test_org_reference.adoc#decorator_enable_if[`enable_if`]' + decorator_depends_on: 'xref:utf_reference/test_org_reference.adoc#decorator_depends_on[`depends_on`]' + decorator_precondition: 'xref:utf_reference/test_org_reference.adoc#decorator_precondition[`precondition`]' + decorator_fixture: 'xref:utf_reference/test_org_reference.adoc#decorator_fixture[`fixture`]' + decorator_description: 'xref:utf_reference/test_org_reference.adoc#decorator_description[`description`]' + decorator_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#decorator_expected_failures[`expected_failures`]' + decorator_timeout: 'xref:utf_reference/testing_tool_ref.adoc#decorator_timeout[`timeout`]' + decorator_tolerance: 'xref:utf_reference/testing_tool_ref.adoc#decorator_tolerance[`tolerance`]' + class_predicate_result: 'cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result]' + class_assertion_result: 'cpp:boost::test_tools::assertion_result[test_tools::assertion_result]' # >>> END GENERATED ATTRIBUTES <<< nav: diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc index 3d924122c1..10aa61185a 100644 --- a/doc/modules/ROOT/nav.adoc +++ b/doc/modules/ROOT/nav.adoc @@ -1 +1,76 @@ -* xref:index.adoc[Introduction] +* xref:index.adoc[] +** xref:intro/design_rationale.adoc[] +** xref:intro/how_to_read.adoc[] +* xref:usage_variants.adoc[] +* xref:tests_organization/index.adoc[] +** xref:tests_organization/test_cases.adoc[] +*** xref:tests_organization/test_organization_nullary.adoc[] +*** xref:tests_organization/test_case_generation.adoc[] +*** xref:tests_organization/test_organization_templates.adoc[] +*** xref:tests_organization/param_test.adoc[] +** xref:tests_organization/test_tree.adoc[] +*** xref:tests_organization/test_suite.adoc[] +*** xref:tests_organization/master_test_suite.adoc[] +*** xref:tests_organization/test_naming.adoc[] +*** xref:tests_organization/test_tree_content.adoc[] +** xref:tests_organization/decorators.adoc[] +** xref:tests_organization/fixtures.adoc[] +** xref:tests_organization/tests_dependencies.adoc[] +** xref:tests_organization/tests_grouping.adoc[] +** xref:tests_organization/enabling.adoc[] +** xref:tests_organization/semantic.adoc[] +** xref:tests_organization/summary.adoc[] +* xref:testing_tools/index.adoc[] +** xref:testing_tools/tools_assertion_severity_level.adoc[] +** xref:testing_tools/boost_test_universal_macro.adoc[] +** xref:testing_tools/reports.adoc[] +** xref:testing_tools/floating_point.adoc[] +** xref:testing_tools/strings.adoc[] +** xref:testing_tools/collections.adoc[] +** xref:testing_tools/bitwise.adoc[] +** xref:testing_tools/exception_correctness.adoc[] +** xref:testing_tools/timeout.adoc[] +** xref:testing_tools/expected_failures.adoc[] +** xref:testing_tools/custom_predicates.adoc[] +** xref:testing_tools/output_stream_testing.adoc[] +** xref:testing_tools/internal_details.adoc[] +** xref:testing_tools/debugging.adoc[] +** xref:testing_tools/summary.adoc[] +* xref:test_output/index.adoc[] +** xref:test_output/test_tools_support_for_logging.adoc[] +*** xref:test_output/checkpoints.adoc[] +*** xref:test_output/contexts.adoc[] +*** xref:test_output/log_floating_points.adoc[] +** xref:test_output/log_formats.adoc[] +** xref:test_output/report_formats.adoc[] +** xref:test_output/logging_api.adoc[] +** xref:test_output/test_output_progress.adoc[] +** xref:test_output/summary.adoc[] +* xref:runtime_config/index.adoc[] +** xref:runtime_config/test_unit_filtering.adoc[] +** xref:runtime_config/runtime_custom.adoc[] +** xref:runtime_config/summary.adoc[] +* xref:adv_scenarios/index.adoc[] +** xref:adv_scenarios/build_utf.adoc[] +** xref:adv_scenarios/entry_point_overview.adoc[] +** xref:adv_scenarios/test_module_init_overview.adoc[] +** xref:adv_scenarios/test_module_runner_overview.adoc[] +** xref:adv_scenarios/single_header_customizations.adoc[] +** xref:adv_scenarios/static_lib_customizations.adoc[] +** xref:adv_scenarios/shared_lib_customizations.adoc[] +** xref:adv_scenarios/external_test_runner.adoc[] +** xref:adv_scenarios/obsolete_init_func.adoc[] +* xref:usage_recommendations/index.adoc[] +** xref:usage_recommendations/bt_and_tdd.adoc[] +** xref:usage_recommendations/hello.adoc[] +** xref:usage_recommendations/web_wisdom.adoc[] +* xref:section_faq.adoc[] +* xref:section_glossary.adoc[] +* xref:change_log.adoc[] +* xref:acknowledgments.adoc[] +* xref:utf_reference/index.adoc[] +** xref:utf_reference/test_org_reference.adoc[] +** xref:utf_reference/testing_tool_ref.adoc[] +** xref:utf_reference/testout_reference.adoc[] +** xref:utf_reference/rt_param_reference.adoc[] +** xref:utf_reference/link_references.adoc[] diff --git a/doc/modules/ROOT/pages/acknowledgments.adoc b/doc/modules/ROOT/pages/acknowledgments.adoc new file mode 100644 index 0000000000..4b2b8922db --- /dev/null +++ b/doc/modules/ROOT/pages/acknowledgments.adoc @@ -0,0 +1,23 @@ += Acknowledgements +:page-aliases: boost_test/acknowledgments.adoc + +== Boost Test Team + +Boost.Test 3.0 is being developed and maintained by Gennadiy Rozental and Raffi Enficiaud. + +== New documentation + +Raffi Enficiaud and Andrzej Krzemienski efforts were a driving force behind the Boost.Test documentation overhaul. + +== Second incarnation including the Unit Test Framework + +Beman Dawes and Ullrich Koethe started the library. Fernando Cacciola, Jeremy Siek, Beman Dawes, Ullrich Koethe, +Dave Abrahams suggested numerous improvements during the Formal Review. Jeremy Siek was the review manager. Beman +Dawes was a great help in both final testing and merging library with rest of the boost. Gennadiy Rozental was the +developer and maintainer. + +== Original Test Library + +Ed Brey, Kevlin Henney, Ullrich Koethe, and Thomas Matelich provided very helpful comments during development. +Dave Abrahams, Ed Brey, William Kempf, Jens Maurer, and Wilka suggested numerous improvements during the Formal +Review. Jens Maurer was the review manager. Beman Dawes is the developer and maintainer. diff --git a/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc b/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc new file mode 100644 index 0000000000..1d072d6955 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc @@ -0,0 +1,63 @@ += Building the {utf} +:page-aliases: boost_test/adv_scenarios/build_utf.adoc + +In case you would like to use the xref:usage_variants.adoc#shared_lib[shared library variant] or the xref:usage_variants.adoc#static_lib[static library variant] of the {utf}, the library needs to be built. +Building the {utf} is in fact quite easy. + +In the sequel, we define + +* $`boost_path` refers to the location where the boost archive was deflated +* $`boost_installation_prefix` refers to the location where you want to install the {utf} + +More documentation about *Boost's build system* can be found http://www.boost.org/more/getting_started/index.html[here]. + +== Windows + +You need to have a compilation toolchain. _Visual Studio Express_ is such one, freely available from the +Microsoft website. Once installed, open a _Visual Studio Command Line tools_ prompt and build the Boost build program `b2` +(see the link above). You will then be able to compile the {utf} with different variants. + +=== Static variant + +For building 32bits libraries, open a console window and enter the following commands: + +[source,cpp] +---- +> cd ``$``boost_path +> bootstrap.bat +> b2 address-model=32 architecture=x86 --with-test link=static \ +> --prefix=``$``boost_installation_prefix install +---- + +For building 64bits libraries, the commands become: + +[source,cpp] +---- +> cd ``$``boost_path +> bootstrap.bat +> b2 address-model=64 architecture=x86 --with-test link=static \ +> --prefix=``$``boost_installation_prefix install +---- + +=== Shared library variant + +In order to build the shared library variant, the directive `link=static` should be replaced by `link=shared` on the above command lines. +For instance, for 64bits builds, the commands become: + +[source,cpp] +---- +> cd ``$``boost_path +> bootstrap.bat +> b2 address-model=64 architecture=x86 --with-test link=shared --prefix=``$``boost_installation_prefix install +---- + +== Linux/OSX + +For Unix/Linux/OSX operating system, the build of the {utf} is very similar to the one on Windows: + +[source,cpp] +---- +> cd ``$``boost_path +> ./bootstrap.sh +> ./b2 --with-test --prefix=``$``boost_installation_prefix install +---- diff --git a/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc new file mode 100644 index 0000000000..f811f0e660 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc @@ -0,0 +1,32 @@ += Test module's entry point +:page-aliases: boost_test/adv_scenarios/entry_point_overview.adoc + +Typically, every C++ program contains exactly one definition of function `main`: the program's _entry point_. +When using the {utf} you do not have to define one. Function `main` will be generated for you by the framework. +The only thing you are required to do in case your program consists of more than one translation unit (`cpp` file) +is to indicate to the framework in which of the files it is supposed to generate function `main`. +You do it by defining macro {boost_test_module} before the inclusion of any of the framework files. +The value of this macro is used as a name of the xref:section_glossary.adoc#ref_test_module[test module] as well as the +xref:tests_organization/master_test_suite.adoc[master test suite]. + +The reason for defining function `main` for you is twofold: + +. This allows the {utf} to perform some custom xref:adv_scenarios/test_module_init_overview.adoc[_test module initialization_]. +. This prevents you defining `main`, and accidentally forgetting to run all the test (in which case running the program would incorrectly indicate a clean run). + +By default, the test module's entry point is defined with signature: + +[source,cpp] +---- +int main(int argc, char* argv[]); +---- + +It calls xref:adv_scenarios/test_module_init_overview.adoc[_test module initialization_] function, then calls the +xref:adv_scenarios/test_module_runner_overview.adoc[_test module runner_] and forwards its return value to environment. + +The default entry point is sufficient in most of the cases. Occasionally, a need may arise to declare an entry point with a +different name or signature. For overriding the definition of the default test module's entry point: + +* xref:adv_scenarios/single_header_customizations.adoc#entry_point[see here], for header-only usage variant, +* xref:adv_scenarios/static_lib_customizations.adoc#entry_point[see here], for static library usage variant, +* xref:adv_scenarios/shared_lib_customizations.adoc#entry_point[see here], for shared library usage variant. diff --git a/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc b/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc new file mode 100644 index 0000000000..0e7fdac75c --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc @@ -0,0 +1,15 @@ += The external test runner usage variant +:page-aliases: boost_test/adv_scenarios/external_test_runner.adoc + +This usage variant does not provide any xref:adv_scenarios/test_module_runner_overview.adoc[test runner]. +You employ it when you only want to define a xref:section_glossary.adoc#ref_test_tree[test tree] and possibly an +xref:adv_scenarios/test_module_init_overview.adoc[initialization function], +and expect another (external) program to evaluate these tests. This external program will come with its own test runner. + +If you plan to use an external test runner with your test module, you need to build it as a dynamic library. +You need to define macro flag {boost_test_dyn_link} either in a makefile or before the header +`boost/test/unit_test.hpp` inclusion. An external test runner utility is required to link with dynamic library. + +The {utf} comes with an example external test runner `console_test_runner`: +Given a name of the test module (implemented as a shared library), and a name of the initialization function defined therein, +the program can run all the tests from the module's test tree. diff --git a/doc/modules/ROOT/pages/adv_scenarios/index.adoc b/doc/modules/ROOT/pages/adv_scenarios/index.adoc new file mode 100644 index 0000000000..89d09105b4 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/index.adoc @@ -0,0 +1,28 @@ += Advanced Usage Scenarios +:page-aliases: boost_test/adv_scenarios.adoc + +If you are reading this chapter, this means that the wide range of tools and interfaces covered +in the previous sections are not sufficient for the testing scenario +you have in mind. You are here to bend the {utf} to your will and ... we are not going to +stop you. Instead we'll try to guide you so that some dark corners do not look scary. + +In most cases the {utf} is going to be supplied for you either as part of your system libraries +or set of libraries used by your companies. Yet if you are facing the necessity to build your +own static or dynamic library of the {utf} or need to customize the build for any reason, section +xref:adv_scenarios/build_utf.adoc[Building the {utf}] covers all the necessary steps. + +To streamline the experience of setting up your test module, the {utf} provides some default +initialization logic for them. Usually the default test module initialization will work just fine, +but if you want to implement some custom initialization or change how default initialization +behaves you need to first look in *Test module initialization* section. Here you'll learn +about various options the {utf} provides for you to customize this behavior. + +The part of the framework which loads, initializes and executed your test module is called the +*Test Runner*. Each usage variant comes with default test runner. If, instead, you prefer to +implement your own entry point into the test module (for example if you need to implement the +`main` function yourself and not use the one provided by the {utf}, you need to learn about +{utf} interfaces involved in test runners operations. These are covered in the *Test runners* +section. Let me reiterate that you only need to this section if regular regular options for +customization of initialization logic like +xref:tests_organization/fixtures.adoc[fixtures] or xref:tests_organization/decorators.adoc[decorators] +are not sufficient for your purposes. diff --git a/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc b/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc new file mode 100644 index 0000000000..49fc604b82 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc @@ -0,0 +1,45 @@ += The obsolete initialization function +:page-aliases: boost_test/adv_scenarios/obsolete_init_func.adoc + +For backwards compatibility, the {utf} also allows the customization of an initialization function of a different type. +This is called the _obsolete initialization function_. Its signature is: + +[source,cpp] +---- +boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]); +---- + +The original design of the {utf} required of the programmer to implement it. It was intended to initialize and return +the {master_test_suite}. No xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_AUTO_TEST_CASE[automatic test case registration] was available at that +time. The null-pointer value was considered an initialization error. + +In the header-only usage variant, you fall back to the obsolete initialization function signature by omitting the +definition of macro {boost_test_alternative_init_api} in test module code. + +// tag reference: doc/modules/ROOT/examples/custom_obsolete_init.run-fail.cpp +:bt-name: custom_obsolete_init +:bt-rule: run-fail +:bt-descr: using obsolete initialization function +include::partial$bt_example.adoc[] + +In the static-library usage variant, you need to omit the definition of macro {boost_test_alternative_init_api} in test +module and compile the {utf} static library without the compilation flag {boost_test_alternative_init_api} (this is +the default). + +In the shared-library usage variant, it is not possible to use the obsolete initialization function. + +Even if you decide to us the obsolete initialization function, it is recommended that: + +. You always return a null-pointer value and install the master test suite via +cpp:boost::unit_test::test_suite::add[`test_suite::add`] as illustrated +xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_TEST_CASE[here]. The current framework does no longer treat the +null-pointer value as failure. +. You signal the failure by throwing cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] exception. +. You access the command-line arguments through the interface of the {master_test_suite}, +and ignore the function's arguments `argc` and `argv`. + +[CAUTION] +==== +The obsolete initialization function is deprecated as its name indicates. It is recommended to migrate + to the new API, and rely on the automated test unit registration and xref:tests_organization/fixtures.adoc[fixtures] (including xref:tests_organization/fixtures.adoc#global[global fixtures]) for other set-up. +==== diff --git a/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc new file mode 100644 index 0000000000..21875b738c --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc @@ -0,0 +1,120 @@ += Shared-library variant customizations +:page-aliases: boost_test/adv_scenarios/shared_lib_customizations.adoc + +[CAUTION] +==== +Macro {boost_test_dyn_link} (which instructs the compiler/linker to dynamically link against a shared +library variant) may be implicitly defined when macro `BOOST_ALL_DYN_LINK` is defined. +==== + +[CAUTION] +==== +In order to be able to run a test built with the dynamic variant, the operating system should be able + to find the dynamic library of the {utf}. This means, for example on Linux and MacOSX respectively, setting the environment + variable `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH` properly prior to the execution of the test module. +==== + +[#entry_point] +== Customizing the module's entry point + +In this variant, in one of the source files, you now have to define your custom entry point, and invoke the default +xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with the default +xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` as argument. +You need to define {boost_test_no_main} (its value is irrelevant) in the main file: + +[%header%autowidth,cols="2*"] +|=== +|In *exactly one* file +|In all other files + +a| +[source,cpp] +---- +#define BOOST_TEST_MODULE test module name +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN +#include + +// entry point: +int main(int argc, char* argv[], char* envp[]) +{ + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); +} +---- +a| +[source,cpp] +---- +#define BOOST_TEST_DYN_LINK +#include + +// +// test cases +// + +// +// test cases +// +---- + +|=== + +[#init_func] +== Customizing the module's initialization function + +In the shared-library variant, it is impossible to customize the initialization function without +xref:adv_scenarios/shared_lib_customizations.adoc#entry_point[customizing the entry point]. We have +to customize both. In one of the source files, you now have to define your custom entry point and +xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test`; next invoke +the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually +with `init_unit_test` as argument. You _do not_ define {boost_test_module} in the main file: + +[%header%autowidth,cols="2*"] +|=== +|In *exactly one* file +|In all other files + +a| +[source,cpp] +---- +#define BOOST_TEST_DYN_LINK +#include + +// initialization function: +bool init_unit_test() +{ + return true; +} + +// entry point: +int main(int argc, char* argv[]) +{ + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); +} +---- +a| +[source,cpp] +---- +#define BOOST_TEST_DYN_LINK +#include + +// +// test cases +// + +// +// test cases +// + +// +// test cases +// +---- + +|=== + +For reporting errors that may occur during the initialization, + +* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] + +An error reported in this function aborts the execution of the test module. diff --git a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc new file mode 100644 index 0000000000..d8f48d1887 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc @@ -0,0 +1,84 @@ += Header-only variant customizations +:page-aliases: boost_test/adv_scenarios/single_header_customizations.adoc + +[#multiple_translation_units] +== Header-only with multiple translation units + +It is possible to use the header-only variant of the {utf} even if the test module has multiple translation +units: + +* one translation unit should define {boost_test_module} and include `` +* all the other translation units should include `` + +An example might be the following: + +* Translation unit 1, defines {boost_test_module} +`+#define BOOST_TEST_MODULE header-only multiunit test +#include ++ +BOOST_AUTO_TEST_CASE( test1 ) +{ +int i = 1; +BOOST_CHECK( i*i == 1 ); +}+` +* Translation unit 2, includes `` instead of ``: +`+#include ++ +BOOST_AUTO_TEST_CASE( test2 ) +{ +int i = 1; +BOOST_CHECK( i*i == 1 ); +}+` + +[#entry_point] +== Customizing the module's entry point + +In this usage variant and in the translation unit containing the definition of {boost_test_module}, +you need to define the macros {boost_test_no_main} and +{boost_test_alternative_init_api} (their values are irrelevant) prior to including any of the framework's headers. +Next, you have to define your custom entry point, and invoke the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with the default xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` as argument. + +// tag reference: doc/modules/ROOT/examples/custom_main.run-fail.cpp +:bt-name: custom_main +:bt-rule: run-fail +:bt-descr: using custom entry point +include::partial$bt_example.adoc[] + +In the above example, a custom entry point was selected because the test module, in addition to command line arguments, +needs to obtain also the information about environment variables. + +[NOTE] +==== +The above example also illustrates that it makes sense to define both {boost_test_module} and +{boost_test_no_main}. This way, no `main` is generated by the framework, but the name specified by {boost_test_module} +is assigned to the xref:tests_organization/master_test_suite.adoc[Master test suite]. +==== + +NOTE: The reason for defining {boost_test_alternative_init_api} is described xref:adv_scenarios/obsolete_init_func.adoc[here]. + +[#init_func] +== Customizing the module's initialization function + +In this usage variant, you do not define macro {boost_test_module} and instead provide the definition of function +`init_unit_test`. This is going to be the custom initialization function. The default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] will use it to initialize the test module. + +// tag reference: doc/modules/ROOT/examples/custom_init.run-fail.cpp +:bt-name: custom_init +:bt-rule: run-fail +:bt-descr: using custom initialization function +include::partial$bt_example.adoc[] + +[NOTE] +==== +Because we overwrote the default initialization function, it does no longer assign any name to the xref:tests_organization/master_test_suite.adoc[master test suite]. Therefore the default name ("Master Test +Suite") is used. +==== + +For reporting errors that may occur during the initialization, + +* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] + +An error reported in this function aborts the execution of the test module. + +NOTE: The reason for defining {boost_test_alternative_init_api} is described xref:adv_scenarios/obsolete_init_func.adoc[here]. diff --git a/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc new file mode 100644 index 0000000000..7ab4ea68e3 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc @@ -0,0 +1,145 @@ += Static-library variant customizations +:page-aliases: boost_test/adv_scenarios/static_lib_customizations.adoc + +[#entry_point] +== Customizing the module's entry point + +In the static library variant, customizing the main entry point is quite troublesome, because the definition +of function `main` is already compiled into the static library. This requires you to rebuild the {utf} +static library with the defined symbol {boost_test_no_main}. In the Boost root directory you need to +invoke command + +[source,cpp] +---- +> b2 --with-test link=static define=BOOST_TEST_NO_MAIN define=BOOST_TEST_ALTERNATIVE_INIT_API install +---- + +[WARNING] +==== +This removal of entry point definition from the static library will affect everybody else who is +linking against the library. It may be less intrusive to switch to the +xref:adv_scenarios/shared_lib_customizations.adoc[shared library usage variant] instead. +==== + +In one of the source files, you now have to define your custom entry point, and invoke the default +xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with +the default xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` +as the first argument. There is no need to define {boost_test_no_main} in your source code, but you need +to define {boost_test_alternative_init_api} in the main file: + +[%header%autowidth,cols="2*"] +|=== +|In *exactly one* file +|In all other files + +a| +[source,cpp] +---- +#define BOOST_TEST_MODULE test module name +#define BOOST_TEST_ALTERNATIVE_INIT_API +#include + +// entry point: +int main(int argc, char* argv[], char* envp[]) +{ + return utf::unit_test_main(init_unit_test, argc, argv); +} +---- +a| +[source,cpp] +---- +#include + +// +// test cases +// + +// +// test cases +// +---- + +|=== + +[NOTE] +==== +The reason for defining {boost_test_alternative_init_api} is described + xref:adv_scenarios/obsolete_init_func.adoc[here]. +==== + +[#init_func] +== Customizing the module's initialization function + +In the static library variant, customizing the main entry point is quite troublesome, because the default test +runner compiled into the static library uses the obsolete initialization function signature. This requires you +to rebuild the {utf} static library with the defined symbol {boost_test_alternative_init_api}. In the Boost +root directory you need to invoke command + +[source,cpp] +---- +> b2 --with-test link=static define=BOOST_TEST_ALTERNATIVE_INIT_API install +---- + +[WARNING] +==== +This alteration of the static library will affect everybody else who is linking against the +library. Consider using the xref:adv_scenarios/obsolete_init_func.adoc[obsolete test initialization function], +which requires no rebuilding. Alternatively, it may be less intrusive to switch to the +xref:adv_scenarios/shared_lib_customizations.adoc[shared library usage variant] instead. +==== + +In one of the source files, you now have to define your custom initialization function with signature: + +[source,cpp] +---- +bool init_unit_test(); +---- + +The default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] will use it to initialize +the test module. In your source code, you no longer define macro {boost_test_module}; instead, you need to +define {boost_test_alternative_init_api} in the main file: + +[%header%autowidth,cols="2*"] +|=== +|In *exactly one* file +|In all other files + +a| +[source,cpp] +---- +#define BOOST_TEST_ALTERNATIVE_INIT_API +#include + +// init func: +bool init_unit_test() +{ + return true; +} +---- +a| +[source,cpp] +---- +#include + +// +// test cases +// + +// test cases +// +---- + +|=== + +For reporting errors that may occur during the initialization, + +* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] + +An error reported in this function aborts the execution of the test module. + +[NOTE] +==== +The reason for defining {boost_test_alternative_init_api} is described + xref:adv_scenarios/obsolete_init_func.adoc[here]. +==== diff --git a/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc new file mode 100644 index 0000000000..b67cb79677 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc @@ -0,0 +1,45 @@ += Test module's initialization +:page-aliases: boost_test/adv_scenarios/test_module_init_overview.adoc + +In order for a unit test module to successfully link and execute, it has to have access to the _test module's initialization +function_. the module's initialization function is called only once during the execution of the program, just before the +xref:adv_scenarios/test_module_runner_overview.adoc[_test module runner_] is run. By default, the {utf} provides +a default definition of initialization function. The only thing you have to do is to instruct the framework in which translation +unit (`cpp` file) it needs to provide the definition. You do it by defining macro {boost_test_module} in the designated file. +The default implementation assigns the name to the xref:section_glossary.adoc#ref_test_module[test module] as well as the +xref:tests_organization/master_test_suite.adoc[master test suite]. The name to be assigned is specified by +the value of the macro {boost_test_module}. + +[IMPORTANT] +==== +For a test module consisting of multiple source files you have to define {boost_test_module} in a single test file only. +Otherwise you end up with multiple instances of the initialization function. +==== + +There is practically no need to ever alter the default behavior of the test module's initialization function. The {utf} provides +superior tools for performing customization tasks: + +* for automatic registration of test cases and test suites in the test tree, see section xref:tests_organization/index.adoc[Tests organization]; +* in order to assign the custom name to the master test suite define macro {boost_test_module} to desired value; +* in order to access the command-line parameters (except the ones consumed by the {utf}), use the interface of the +xref:tests_organization/master_test_suite.adoc[master test suite]; +* in order to perform a global initialization of the state required by the test cases, xref:tests_organization/fixtures.adoc#global[global fixtures] +offer a superior alternative: you can specify global set-up and tear-down in one place, allow access to the global data from every test case, and guarantee +that clean-up and tear-down is repeated each time the tests are re-run during the execution of the program; +* if the need for custom module initialization is only driven by legacy code (written against old versions of the {utf}), it is recommended +to update your program's code. + +The default initialization function provided by the framework is defined with the following signature in the global namespace: + +[source,cpp] +---- +bool init_unit_test(); +---- + +Return value `true` indicates a successful initialization. Value `false` indicates initialization failure. + +For overriding the default definition: + +* xref:adv_scenarios/single_header_customizations.adoc#init_func[see here], for header-only usage variant, +* xref:adv_scenarios/static_lib_customizations.adoc#init_func[see here], for static library usage variant, +* xref:adv_scenarios/shared_lib_customizations.adoc#init_func[see here], for shared library usage variant. diff --git a/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc new file mode 100644 index 0000000000..be7937f764 --- /dev/null +++ b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc @@ -0,0 +1,52 @@ += Test module runner +:page-aliases: boost_test/adv_scenarios/test_module_runner_overview.adoc + +A _test module runner_ is an _orchestrator_ or a _driver_ that, given the test tree, ensures the test tree is initialized, +tests are executed and necessary reports generated. It performs the following operations: + +* initialize the test module using the supplied xref:adv_scenarios/test_module_init_overview.adoc[_initialization function_]; +* select output media for the test log and the test results report; +* execute test cases as specified by run-time parameters; +* produce the test results report; +* generate the appropriate return code. + +The {utf} comes with the default test runner. There is no need to call it explicitly. The default generated test module's +xref:adv_scenarios/entry_point_overview.adoc[entry point] invokes the default test runner. The default test runner is +declared with the following signature: + +[source,cpp] +---- +namespace boost { namespace unit_test { + + typedef bool (*init_unit_test_func)(); + + int unit_test_main( init_unit_test_func init_func, int argc, char* argv[] ); + +} } +---- + +The test runner may return one of the following values: + +[%header%autowidth,cols="2*"] +|=== +|Value +|Meaning + +|`boost::exit_success` +a| +* No errors occurred during testing, or +* the success result was forced with command-line argument `--[link boost_test.utf_reference.rt_param_reference.result_code`result_code`]=no`. + +|`boost::exit_test_failure` +a| +* Non-fatal errors detected and no uncaught exceptions were thrown during testing, or +* the initialization of the {utf} failed. + +|`boost::exit_exception_failure` +a| +* Fatal errors were detected, or +* uncaught exceptions thrown during testing. + +|=== + +An advanced test runner may provide additional features, including interactive GUI interfaces, test coverage and profiling support. diff --git a/doc/modules/ROOT/pages/change_log.adoc b/doc/modules/ROOT/pages/change_log.adoc new file mode 100644 index 0000000000..38ec9ca430 --- /dev/null +++ b/doc/modules/ROOT/pages/change_log.adoc @@ -0,0 +1,606 @@ += Change log +:page-aliases: boost_test/change_log.adoc + +Boost.Test releases: + +* xref:change_log.adoc#ref_CHANGE_LOG_3_15[Boost.Test v3.15 / boost 1.79] +* xref:change_log.adoc#ref_CHANGE_LOG_3_14[Boost.Test v3.14 / boost 1.74] +* xref:change_log.adoc#ref_CHANGE_LOG_3_13[Boost.Test v3.13 / boost 1.73] +* xref:change_log.adoc#ref_CHANGE_LOG_3_12[Boost.Test v3.12 / boost 1.72] +* xref:change_log.adoc#ref_CHANGE_LOG_3_11[Boost.Test v3.11 / boost 1.71] +* xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost.Test v3.10 / boost 1.70] +* xref:change_log.adoc#ref_CHANGE_LOG_3_9[Boost.Test v3.9 / boost 1.69] +* xref:change_log.adoc#ref_CHANGE_LOG_3_8[Boost.Test v3.8 / boost 1.68] +* xref:change_log.adoc#ref_CHANGE_LOG_3_7[Boost.Test v3.7 / boost 1.67] +* xref:change_log.adoc#ref_CHANGE_LOG_3_6[Boost.Test v3.6 / boost 1.65] +* xref:change_log.adoc#ref_CHANGE_LOG_3_5[Boost.Test v3.5 / boost 1.64] +* xref:change_log.adoc#ref_CHANGE_LOG_3_4[Boost.Test v3.4 / boost 1.63] +* xref:change_log.adoc#ref_CHANGE_LOG_3_3[Boost.Test v3.3 / boost 1.62] +* xref:change_log.adoc#ref_CHANGE_LOG_3_2[Boost.Test v3.2 / boost 1.61] +* xref:change_log.adoc#ref_CHANGE_LOG_3_1[Boost.Test v3.1 / boost 1.60] +* xref:change_log.adoc#ref_CHANGE_LOG_3_0[Boost.Test v3 / boost 1.59] + +[#ref_CHANGE_LOG_3_15] +== Boost.Test v3.15 / boost 1.79 + +=== New features + +=== Bugfixes and feature requests + +. {issue-url}/268[#GH-268] Clang warning generated by dataset grid operation in C++20 mode +. {issue-url}/272[#GH-272] Uninitialized memory in `framework_init_observer_t` +. {issue-url}/284[#GH-284] Undefined behavior in `basic_cstring::trim_right` +. {issue-url}/297[#GH-297] `BOOST_TEST_GLOBAL_FIXTURE` documentation misleading +. {issue-url}/305[#GH-305] boost test documentation tells users to file bugs with decommissioned Trac. +. {pr-url}/286[#PR-286] fix uninitilized variable in `framework_init_observer_t` +. {pr-url}/301[#PR-301] UB comparing unrelated pointers in `priority_order` +. {pr-url}/275[#PR-275] Replace anonymous `enum` arity with `static constexpr` +. {pr-url}/278[#PR-278] Use `boost_test_print_type` customization point in `lazy_ostream` +. {pr-url}/281[#PR-281] Export `execution_aborted` exception to allow catching it from outside the DLL + +[#ref_CHANGE_LOG_3_14] +== Boost.Test v3.14 / boost 1.74 + +=== New features + +* Now able to detect when running under a debugger on macOS/iOS. When running under a debugger, Boost.Test does not +try to catch system errors and the behaviour is the same as if the command line xref:utf_reference/rt_param_reference.adoc#catch_system[`catch_system_error`] +option was set to `no`. Thanks to https://github.com/thughes[Tom Hughes] for this feature. +* Adding support for Embarcadero C++ clang-based compilers, thanks to https://github.com/eldiener[Edward Diener] + +=== Bugfixes and feature requests + +. {issue-url}/264[#GH-264] GCC suggest-override warnings +. {issue-url}/269[#GH-269] Deprecated bind placeholders in tests +. {pr-url}/142[#PR-142] Make `under_debugger` work on apple (iOS/macOS) +. {pr-url}/266[#PR-266] Changes for Embarcadero C++ clang-based compilers +. {pr-url}/267[#PR-267] Use macOS API only on macOS + +[#ref_CHANGE_LOG_3_13] +== Boost.Test v3.13 / boost 1.73 + +=== New features + +* It is now possible to combine tolerance indication, user message and collection comparison modifier in a single `BOOST_TEST` expression ++ +`+std::vector v1 = f(); +std::vector v2{1.1, 1.19}; +BOOST_TEST(v1 == v2, boost::test_tools::tolerance( 1e-3 ) << "comparison to ground truth failed" << boost::test_tools::per_element());+` + +=== Bugfixes and feature requests + +. {issue-url}/173[#GH-173] Compare collections of floating point values with tolerance +. {issue-url}/179[#GH-179] `test_tools-test` failed on some archs +. {issue-url}/220[#GH-220] Support for cuda `nvcc` +. {issue-url}/221[#GH-221] Coverity security issue (minor) (`umask`) +. {issue-url}/235[#GH-235] Ugly GCC `-Wattributes` warnings that cannot be suppressed using _included_ variant +. {issue-url}/237[#GH-237] Clang-cl's `-Wdelete-non-abstract-non-virtual-dtor` triggered by `test_case_gen` +. {issue-url}/241[#GH-241] warning: comparing floating point with == or != is unsafe `[-Wfloat-equal]` +. {issue-url}/245[#GH-245] code coverity test defect +. {issue-url}/246[#GH-246] Incorrect usage of `BOOST_HEADER_DEPRECATED` +. {issue-url}/251[#GH-251] Context message are always printed if both HRF and Junit loggers are enabled +. {issue-url}/253[#GH-253] Invalid XML log is generated by `BOOST_AUTO_TEST_CASE_TEMPLATE` when tests are skipped +. {issue-url}/254[#GH-254] Console colors are not restored on Windows +. {issue-url}/263[#GH-263] Windows: Header-only mode with multiple translation units requires `BOOST_TEST_NO_LIB` +. {pr-url}/41[#PR-41] Fix: activate virtual destructors for all `msvc` versions +. {pr-url}/114[#PR-114] Silence unreachable code warning in MSVC (`/W4`) +. {pr-url}/187[#PR-187] enable `BOOST_TEST` with tolerance and user-message (through {issue-url}/173[#GH-173]) +. {pr-url}/239[#PR-239] Fix unused variable warning in `unit_test_main.ipp` +. {pr-url}/247[#PR-247] Use `+__linux__+` instead of `+__linux+` +. {pr-url}/252[#PR-252] Fix compilation issue due to deleted `std::basic_ostream::operator<<` from `wchar_t` +. {pr-url}/259[#PR-259] Avoid deprecated bind placeholders in global namespace +. {pr-url}/265[#PR-265] Suppress the unused parameter warning for `root_test_unit_id` +. {trac-url}/11107[#11107] A lot of warnings on MSVC due to protected destructor being non-virtual +. {trac-url}/12072[#12072] Lots of `C4265` warnings in test when using Visual Studio 2015 (duplicates {trac-url}/11107[#11107]) + +[#ref_CHANGE_LOG_3_12] +== Boost.Test v3.12 / boost 1.72 + +=== New features + +* Support for C++17 `std::string_view` has been added. +* Better diagnostic on `boost::exception` and no rtti mode (thanks to Mikhail Pilin / {pr-url}/234[#PR-234]) + +=== Bugfixes and feature requests + +. {issue-url}/206[#GH-206] compile-time disabled test not correctly handled by junit log +. {issue-url}/217[#GH-217] Data test cases fail with `bool` initializer list +. {issue-url}/223[#GH-223] Unable to filter test by name (`-t`, `--run_test`) if template type contains multiple parameters +. {issue-url}/229[#GH-229] Random shuffle deprecated +. {pr-url}/227[#PR-227] Add `printf` format checking attribute to `report_error` +. {pr-url}/231[#PR-231] OpenBSD is missing `SI_ASYNCIO` and `SI_MESGQ` +. {pr-url}/232[#PR-232] fix timeout in windows +. {pr-url}/234[#PR-234] `boost::diagnostic_information()` works in no `rtti` mode + +[#ref_CHANGE_LOG_3_11] +== Boost.Test v3.11 / boost 1.71 + +=== New features + +* Now `BOOST_TEST` can be used to compare abstract types + +=== Breaking changes + +* Marking more headers as deprecated: this might break some compilations +depending on the warning policies. + +=== Bugfixes and feature requests + +. Fixing a small bug on named timers (Windows only). The bug is visible when +several test modules are executed in parallel on the same machine. +. {issue-url}/209[#GH-209] `BOOST_TEST_CHECK` can't compare abstract classes using gcc +. {issue-url}/218[#GH-218] Default file name (for logger output files) +. {pr-url}/219[#PR-219] Commented out unused argument name (`stack_decorator::apply`) +. {pr-url}/224[#PR-224] Add `BOOST_HEADER_DEPRECATED` to deprecated headers + +[#ref_CHANGE_LOG_3_10] +== Boost.Test v3.10 / boost 1.70 + +=== New features + +* New documentation section about xref:runtime_config/runtime_custom.adoc[custom command line] +arguments +* xref:tests_organization/test_case_generation.adoc#dataset_interface[Custom datasets] +are not required to declare a inner type `sample` anymore +* Boost.Test does not depend on Boost.Timer any more (which was pulling also Boost.Chrono +and Boost.System as transitive dependencies). +* Now Boost.Test raises an exception when the test case times-out on Windows. Prior to this release, +times-out on Windows were not failing the test cases. Note that signaling is not available on Windows, +and it is not possible to interrupt a test even in case of time out. +* Time-out now applies to test-suites as well: a test-suite is marked as timed-out if it exceeds the allocated +time. The test units that were not executed at the time-point of the time-out are skipped. +* It is now possible to pass several values for the same context via the tool +{boost_test_context}. +* A new macro {boost_test_info_scope} let define a context for the current scope in a sticky way. +* It is now possible to use xref:testing_tools/floating_point.adoc[floating point] +comparison without being required to cast both operands to floating point types. Now Boost.Test uses floating +point comparisons for expressions such as ++ +`BOOST_TEST(3.0001 == 3);` ++ +See this section // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.extended_comparison.floating_point.type_promotion_of_the_operands +for more information. + +=== Breaking changes + +* Boost.Test `minimal.hpp` is now showing a deprecation warning. `minimal.hpp` has been +deprecated for a long time already, and will be removed in the near future. Please +switch to eg. the header only variable of Boost.Test. Tests using `minimal.hpp` can +readily be converted to the header variant. For instance, the following code: ++ +`+#include +int test_main( int, char *[] ) +{ +... +}+` ++ +may be rewritten as: ++ +`+#include +BOOST_AUTO_TEST_CASE(test_main) +{ +... +}+` +* The floating point comparison behavior change may use this type of comparison while previously +using straight relational operator comparison. In particular this may causes _new warnings_. +* the member function cpp:boost::unit_test::unit_test_log_formatter::log_build_info[boost::unit_test::unit_test_log_formatter::log_build_info] has slightly changed +to accept an additional boolean argument. If you have a custom logger, you will need to update its signature. + +=== Bugfixes and feature requests + +. {issue-url}/133[#GH-133] Timeout effect on Windows +. {issue-url}/138[#GH-138] expected_failures doesn't work for `BOOST_DATA_TEST_CASE` +. {issue-url}/141[#GH-141] Support for Boost.MP11 and Boost.Hana type lists +. {issue-url}/157[#GH-157] Test name should handle `const`-`volatile` specifiers +. {issue-url}/160[#GH-160] suppress `-Wformat-overflow` when optimization is enabled on GCC 8.2.0 +. {issue-url}/174[#GH-174] `UBSAN` identified a problem at exit time by `gcc-8` only +. {issue-url}/176[#GH-176] `[snippet_dataset1_3]` seems to be broken +. {issue-url}/177[#GH-177] `boost_check_equal-str-test` failed on `llvm` +. {issue-url}/180[#GH-180] Unreachable code warning on MSVC builds in test matrix +. {issue-url}/181[#GH-181] `doc_example22` (and `23`) are expected to fail, but do not on clang with release variant builds +. {issue-url}/194[#GH-194] `master_test_suite` declared twice +. {issue-url}/196[#GH-196] junit report: test error is also reported as failure +. {issue-url}/198[#GH-198] Support `BOOST_UNIT_TEST_FRAMEWORK_DYN_LINK` et al +. {issue-url}/199[#GH-199] Runtime `type_mismatch` after upgrade to `1.69` +. {issue-url}/202[#GH-202] `boost/timer.hpp` is deprecated +. {issue-url}/203[#GH-203] Test cases with datasets and fixtures don't support flexible fixture interface +. {issue-url}/204[#GH-204] Feature Request: Allow specifying timeouts for test cases with datasests. +. {issue-url}/208[#GH-208] Incorrect handling of timed-tests on Windows +. {issue-url}/211[#GH-211] `windows.h` should be lower case +. {issue-url}/212[#GH-212] Comment `ar` parameter of `assertion_result` to avoid warning +. {issue-url}/213[#GH-213] `BOOST_SYMBOL_VISIBLE` cannot be used for `enums` with Sun Studio +. {pr-url}/171[#PR-171] Correct library name in test runner help screen +. {pr-url}/172[#PR-172] Check for non-used variables when `NDEBUG` is defined +. {pr-url}/182[#PR-182] fix use of `bind1st` in `example 12` +. {pr-url}/183[#PR-183] remove superfluous semicolon in `example 04` +. {pr-url}/184[#PR-184] fix example to use the correct variable and avoid unused variable warning +. {pr-url}/185[#PR-185] Added CI framework +. {pr-url}/190[#PR-190] fix warning on gcc-7.3 in cygwin claiming `master_test_suite` is declared differently +. {pr-url}/195[#PR-195] Fix MinGW compilation problems +. {pr-url}/197[#PR-197] Feature Request: `BOOST_TEST_CONTEXT` that doesn't require introducing a new scope with braces +. {pr-url}/205[#PR-205] Fix MinGW `vsnprintf` compile errors and warnings +. {pr-url}/214[#PR-214] Fixes an issue with sun_cc lacking the __global attribute for enums +. {trac-url}/7397[#7397] Boost.Test, since boost `1.48` is using the deprecated `Boost.Timer` class (solved via {issue-url}/202[#GH-202]) +. {trac-url}/9434[#9434] error: `+namespace boost::timer {}+` re-declared as different kind of symbol (solved via {issue-url}/202[#GH-202]) +. {trac-url}/13106[#13106] `libs/test/tools/console_test_runner` does not compile +. {trac-url}/13418[#13418] Request: allow general typelist types in `BOOST_AUTO_TEST_CASE_TEMPLATE()` + +[#ref_CHANGE_LOG_3_9] +== Boost.Test v3.9 / boost 1.69 + +=== New features + +* Official support of header-only variant of Boost.Test with multiple translation units. This feature +was available but needed to be properly documented (xref:adv_scenarios/single_header_customizations.adoc#multiple_translation_units[here] +and xref:usage_variants.adoc[here]). +* It is now possible to manually add a test case by specifying its name, with {boost_test_case_name} +* Better logging of messages in `boost::exception` + +=== Bugfixes and feature requests + +. {issue-url}/149[#GH-149] Setting color_output=no does not disable the output of color format codes +. {issue-url}/150[#GH-150] Some headers fail to compile independently +. {issue-url}/156[#GH-156] `close_at_tolerance` always returns `false` for comparisons of infinity +. {issue-url}/158[#GH-158] Detecting `boost_test_print_type` does not work when testing a type with an explicit conversion to `bool` +. {issue-url}/163[#GH-163] Significant start slowdown on MSVC x64/Debug after upgrade to `v1.68.0` +. {pr-url}/147[#PR-147] Catch block for `boost::exception` appears after `std::exception` in `execution_monitor::execute()` +. {pr-url}/148[#PR-148] Colored output contradiction +. {pr-url}/151[#PR-151] Fix warning: `BOOST_CLANG` is not defined, evaluates to `0` +. {pr-url}/154[#PR-154] When specifying `--color_output=no`, don't output color codes +. {pr-url}/161[#PR-161] add a self-containment test +. {trac-url}/13380[#13380] data-driven tests' join operator `+` corrupts first column (duplicates {trac-url}/12216[#12216]) +. {trac-url}/13625[#13625] Boost.test fail to compile with `-Werror=missing-declarations` on some architectures +. {trac-url}/13637[#13637] Fix for Bug {trac-url}/12597[#12597] causes a problem with `BOOST_TEST_CASE` + +[#ref_CHANGE_LOG_3_8] +== Boost.Test v3.8 / boost 1.68 + +=== New features + +* The tests generated from a dataset are now instantiated during the framework setup. This +let the dataset generator access the `argc` and `argv` of the master test suite. For indicating +a dataset that should be instantiated in a delayed manner, a new `data::make_delayed` helper has +been introduced. +* It is now possible to create a dataset with `data::make`, with variable number of arguments. +As the datasets are monomorphic, it should be possible to cast all elements to the first element type. + +=== Breaking changes + +* the xref:tests_organization/master_test_suite.adoc[`master_test_suite_t`] is not copyable anymore. +* As datasets can now be delayed, it might be that additional copies of the dataset arguments are performed. +This is especially the case for datasets created out of an `std::initializer_list`. + +=== Bugfixes and feature requests + +. {pr-url}/143[#PR-143] Fix exception_api.run-fail.cpp doc example +. {pr-url}/145[#PR-145] Fix build of library on recent Cygwin editions +. {trac-url}/12095[#12095] disabling test with precondition leads to error +. {trac-url}/12953[#12953] access to `+master_test_suite().{argc, argv}+` +. {trac-url}/13504[#13504] `[Boost::Test]` short form of `catch_system_errors` not working +. {trac-url}/13525[#13525] Boost Test 1.67.0: Compilation error with GCC 4.6.3 +. {trac-url}/13528[#13528] Boost Test 1.67 crashes when the `--report_sink` command-line parameter is used + +[#ref_CHANGE_LOG_3_7] +== Boost.Test v3.7 / boost 1.67 + +=== Breaking changes + +* Now colour is on by default for the output streams that are either `std::cout` or `std::cerr`. This can be +disabled by passing xref:utf_reference/rt_param_reference.adoc#color_output[`--no_color_ouput`] (or just `--no_color`) +to the command line. +* Adding test cases with the same name to the same test suite is reported as an error. This impacts +xref:tests_organization/test_organization_templates.adoc[template] and +xref:tests_organization/param_test.adoc[parametrized] test cases, as well as manually +registered tests. Make sure you have no duplicate names. + +=== New features + +* Colour output on Windows +* Improved and clearer command line help +* `BOOST_AUTO_TEST_CASE_TEMPLATE` now accepts a sequence of types in an `std::tuple` + +=== Bugfixes and feature requests + +. {pr-url}/112[#PR-112] Deliberate-failure tests shouldn't be optimized +. {pr-url}/118[#PR-118] Update VxWorks support +. {pr-url}/118[#PR-118] `[clang]` Fix `[-Wc++11-narrowing]` error +. {pr-url}/121[#PR-121] fix compiler warning +. {pr-url}/122[#PR-122] Fix some fallthrough warnings with `gcc >= 7` +. {pr-url}/125[#PR-125] Prevent 2 unused parameter warnings +. {pr-url}/127[#PR-127] Silence 'unused variable' warning +. {pr-url}/134[#PR-134] Fix `stdcerr` file creation on shutdown +. {pr-url}/136[#PR-136] Change `Windows.h` include to all-lowercase (MinGW) +. {trac-url}/12092[#12092] Request: allow `std::tuple` typelists in `BOOST_AUTO_TEST_CASE_TEMPLATE` +. {trac-url}/12596[#12596] Sanitize metacharacters in test names +. {trac-url}/12597[#12597] Report tests with clashing names +. {trac-url}/12969[#12969] Problem linking `print_helper_t` under Clang +. {trac-url}/13058[#13058] `errors.hpp` in Boost Test requires warning `C4946` to be `off` +. {trac-url}/13149[#13149] Dependency decorators on parent suites +. {trac-url}/13170[#13170] `BOOST_AUTO_TEST_CASE_TEMPLATE` don't want `typedef` for list +. {trac-url}/13181[#13181] Boost test can't compare classes which have `begin` and `end` but not `const_iterator` +. {trac-url}/13371[#13371] Use-after-free with `--log_sink=file` +. {trac-url}/13387[#13387] Test header fails to compile +. {trac-url}/13398[#13398] Log format JUNIT generates invalid XML files +. {trac-url}/13407[#13407] Boost.Test appears to crash under Cygwin +. {trac-url}/13435[#13435] `BOOST_TEST_GLOBAL_CONFIGURATION` (result report shutdown time) +. {trac-url}/13443[#13443] Boost.Test data driven test fails to compile when number of samples greater than 9 + +[#ref_CHANGE_LOG_3_6] +== Boost.Test v3.6 / boost 1.65 + +=== Breaking changes + +* {boost_global_fixture} is flagged as deprecated and will be removed in a later version +* Using test assertions and macros is not allowed when used inside {boost_global_fixture}. Please use {boost_test_global_fixture} +instead (see below). +* the interface for loggers has slightly changed to take into account the current log level. This is for addressing {trac-url}/12631[#12631]. + +=== New features + +* VS2017 / C++17 compatibility (thanks to Daniela Engert) +* Deprecating {boost_global_fixture} in favor of {boost_test_global_fixture} and {boost_test_global_configuration}. This +helps separating the logic of the fixtures associated to the master test suite, from the one used for setting up the logging +and reporting facility, and results in a general cleaner design. +* It is possible to use now the {boost_test} check to comparing a collection with respect to regular arrays. See +xref:testing_tools/collections.adoc#ref_boost_test_coll_c_arrays[this section] for more details. + +=== Bugfixes and feature requests + +. {pr-url}/106[#PR-106] replace deprecated binders and adapters, and `random_shuffle` by more modern equivalents +. {trac-url}/5282[#5282] Test fixtures do not support virtual inheritance +. {trac-url}/5563[#5563] using a test macro in a global fixture crashes Boost.Test +. {trac-url}/11471[#11471] array is a sequence +. {trac-url}/11962[#11962] `BOOST_TEST_MESSAGE` in fixture constructor - invalid XML +. {trac-url}/12228[#12228] Some test headers fail to compile independently +. {trac-url}/12631[#12631] `BOOST_TEST_MESSAGE` generates incorrect output when used in `BOOST_DATA_TEST_CASE` +. {trac-url}/13011[#13011] `BOOST_TEST` broken with floating point relational operators + +[#ref_CHANGE_LOG_3_5] +== Boost.Test v3.5 / boost 1.64 + +=== New features + +* Now Boost.Test provides xref:test_output/test_tools_support_for_logging.adoc#ref_log_output_custom_customization_point[customization points] for logging user defined types: +this solution is less intrusive than forcing the definition of `operator<<` for a specific type. +* xref:test_output/log_formats.adoc#log_junit_format[JUnit output format] can now have a +xref:test_output/log_formats.adoc#test_log_output[log-level] set between `success` and +`non-fatal error`, and defaults to `general information`. +* xref:test_output/log_formats.adoc#log_junit_format[JUnit output format] is now more +efficient in case a lot of checks are done in a test module. + +=== Bugfixes and feature requests + +. {pr-url}/107[#PR-107] `BOOST_NO_EXCEPTIONS` typo making `throw_exception` unusable under some circumstances +. {pr-url}/108[#PR-108] Change capital variable names to lowercase +. {trac-url}/11756[#11756] boost.Test: non standards compliant use of `+FE_*+` macros (unable to compile boost test library on FPU-less arches) (reopened) +. {trac-url}/12540[#12540] Provide customization point for printing types in tests +. {trac-url}/12712[#12712] `BOOST_AUTO_TEST_SUITE`: Generate unique names by using `+__COUNTER__+` +. {trac-url}/12748[#12748] Boost.Test defines a variable called `VERSION` +. {trac-url}/12778[#12778] Boost.Test is broken against left shift operator in certain cases (`nullptr` issue) + +[#ref_CHANGE_LOG_3_4] +== Boost.Test v3.4 / boost 1.63 + +=== Breaking changes + +. Now colons that appear in test case names are replaced with underscores. This affect mainly the +xref:tests_organization/test_organization_templates.adoc[template/typed test cases]. +The change is needed since the colon '`:`' is interpreted as a filter separators since 1.62, and it is +otherwise not possible to execute the tests reported by `--list_content`. See {trac-url}/12531[#12531] for more details. + +=== New features + +* Now xref:testing_tools/collections.adoc#boost_test_coll_perelement[`per_element`] and xref:testing_tools/collections.adoc#boost_test_coll_default_lex[`lexicographic`] modifiers of {boost_test} +can also be applied to string comparison. See +xref:testing_tools/strings.adoc[string comparison] for more details. + +=== Bugfixes and feature requests + +. {pr-url}/103[#PR-103] Syntactic change silences latest gcc warnings +. {pr-url}/105[#PR-105] Fix unused parameter warnings/errors with gcc 6 +. {trac-url}/11756[#11756] boost.Test: non standards compliant use of `+FE_*+` macros (unable to compile boost test library on FPU-less arches) +. {trac-url}/11907[#11907] Why does `BOOST_TEST()` treat `std::string` as a collection? +. {trac-url}/12339[#12339] Propose users given way to disable blink in colour output +. {trac-url}/12506[#12506] typo in Boost.test `report_sink` description +. {trac-url}/12507[#12507] Boost.test `--report_sink` parameter broken +. {trac-url}/12530[#12530] No way to find out Boost.Test version without running any tests +. {trac-url}/12531[#12531] `--run_test` in Boost 1.62 does not accept test names which contain ':' + +[#ref_CHANGE_LOG_3_3] +== Boost.Test v3.3 / boost 1.62 + +=== New features + +* Boost.Test now treats each sample of a dataset test case as being a uniquely named test case under the same test suite, +which enables the (re)run of one particular sample from the command line interface. See +here // FIXME(qbk2adoc): unresolved link boost_test.tests_organization.test_cases.test_case_generation.datasets_auto_registration.samples_and_test_tree +for more details, +* Boost.Test learned to interpret ':' as a separator for the test filters: the string passed to +xref:utf_reference/rt_param_reference.adoc#run_test[`--run_test`] +generates tokens as if `--run_test` has been repeated, which enables the set up of several test filters +through the associated environment variable `BOOST_TEST_RUN_FILTERS` +* the {utf} learned to log the messages in the xUnit/JUNIT log format. +See xref:test_output/log_formats.adoc#log_junit_format[here] for more details. +* the {utf} learned to have several loggers at the same time, each of which with their own log level and log sink. +See the associated command line switch xref:utf_reference/rt_param_reference.adoc#logger[`--logger`] and +corresponding environment variable `BOOST_TEST_LOGGER` for more details. +* loggers are now able to indicate their default output stream and log level. + +=== Bugfixes and feature requests + +. {pr-url}/81[#PR-81] Possibility to remove the support of the alternative stack at compilation time. See +xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`] for more details. +. {trac-url}/8707[#8707] Provide Standard xUnit XML Output from Boost Test +. {trac-url}/8834[#8834] Boost Test should be able to generate report in both XML and HRF together +. {trac-url}/11128[#11128] `[bb10/qnx failures]` Build error +. {trac-url}/11845[#11845] Ability to generate the unique and stable test name for every data set in `BOOST_DATA_TEST_CASE` +. {trac-url}/11859[#11859] Wrong handling of "," in Run-Parameters +. {trac-url}/12024[#12024] boost test depends on nonexisting `+abi::__cxa_demangle+` on android +. {trac-url}/12093[#12093] Boost 1.60.0: Build fails (gcc 4.6) +. {trac-url}/12103[#12103] Fix for gcc bug 58952 (`getchar()` is defined as a macro in `uClibc`) +. {trac-url}/12224[#12224] Crash on MSVC with RTTI disabled +. {trac-url}/12241[#12241] Data-driven testing over a range of `std::tuple` has broken +. {trac-url}/12257[#12257] Incorrect line numbers in `test_units` generated from `test_case_gen` +. {trac-url}/12378[#12378] Compilation errors with clang 3.8 + +[#ref_CHANGE_LOG_3_2] +== Boost.Test v3.2 / boost 1.61 + +=== New features + +* now datasets support any xref:tests_organization/test_case_generation.adoc#datasets[arity], using the +variadic template support of the compiler. +* now datasets support fixtures through `BOOST_DATA_TEST_CASE_F`, see +xref:tests_organization/test_case_generation.adoc#datasets[here] for more details +* now datasets honors move semantics of the types used for samples + +=== Bugfixes and feature requests + +. {trac-url}/6767[#6767] Use of namespace qualifier with floating point exception functions breaks if they are macros +. {trac-url}/8905[#8905] `boost/test/impl/debug.ipp`: Ignores return value from `WaitForSingleObject` +. {trac-url}/9443[#9443] Runtime parameter Random seed for random order of test cases not respected correctly +. {trac-url}/11854[#11854] Add fixture support in `BOOST_DATA_TEST_CASE` +. {trac-url}/11887[#11887] `BOOST_TEST(3u == (std::max)(0u, 3u))` fails +. {trac-url}/11889[#11889] `BOOST_DATA_TEST_CASE` fails to compile for 4D and higher dimensional grids +. {trac-url}/11983[#11983] Boost Test XML Report contains unescaped XML characters + +[#ref_CHANGE_LOG_3_1] +== Boost.Test v3.1 / boost 1.60 + +=== New major features + +* improved API for datasets +** it is now possible to use initializer lists +** the use of `make` as top left dataset is not necessary anymore +* improved command line interface +** clearer help commands +** now proposes closest matching command in case of ambiguity +** reports invalid or ambiguous parameters: this might break existing calls when user defined commands are +provided to the test module. The following calling convention should be adopted: +*** if the test module uses user supplied commands, those should be passed after an empty token `--` +*** all boost.test related commands should be passed before `--`, if any ++ +Example: +the call +`test_module --user-arg1=xy --log_level=test_suite` +should be rewritten to +`test_module --log_level=test_suite -- --user-arg1=xy` + +=== Bugfixes and feature requests + +. {trac-url}/3384[#3384] Double-quoted arguments including spaces are divided by Boost.Test. +. {trac-url}/3897[#3897] Test framework does not include `` before testing `+__FreeBSD_version+` (fixed in 1.59) +. {trac-url}/6032[#6032] Program options within `init_unit_test_suite` are incorrect when using path and whitespaces +. {trac-url}/6859[#6859] Boost.Test eats away last empty command line parameter +. {trac-url}/7257[#7257] Boost.Test alters and does not restore `ostream` precision after any Test macro (fixed in 1.59) +. {trac-url}/9228[#9228] Patch to make Boost.Test work with RTTI disabled (fixed in 1.59) +. {trac-url}/10317[#10317] boost::test corrupts contents of `argv` if a paramter contains whitespace +. {trac-url}/11279[#11279] invalid parameters should be reported +. {trac-url}/11478[#11478] Boost Test Exception Assert Failure has poor message +. {trac-url}/11571[#11571] Can't compile `BOOST_TEST( ..., per_element() )` comparison of `vector` +. {trac-url}/11623[#11623] Clang rejects some simple `BOOST_TEST()` statements +. {trac-url}/11624[#11624] `BOOST_TEST( 0.0 == 0.0 )` fails under C++11 (GCC and Clang) +. {trac-url}/11625[#11625] `BOOST_TEST( ..., per_element() )` erroneously requires collections are comparable + +[#ref_CHANGE_LOG_3_0] +== Boost.Test v3 / boost 1.59 + +=== New major features + +* {boost_test} generic assertion +* xref:tests_organization/test_case_generation.adoc[data driven test cases]: supersedes the parametric test case (unary test cases) +* test units xref:tests_organization/decorators.adoc[attributes], that allow finer control over test units property and behavior +* logical grouping of the test units using xref:tests_organization/tests_grouping.adoc[labels] +* support for declaring xref:tests_organization/tests_dependencies.adoc[dependencies] over test cases +* attributes for xref:tests_organization/enabling.adoc[enabling or disabling] test execution based on static, compile-time or runtime rules +* extended xref:runtime_config/test_unit_filtering.adoc[unit test filtering] from the command line (negation, labels, ...) +* color output with xref:utf_reference/rt_param_reference.adoc#color_output[`color_output`] +* test bed listing with xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`] +* rewritten documentation using quickbook + +=== Bugfixes and feature requests + +. {trac-url}/2018[#2018] Error in the documentation chapter "Runtime parameters reference" +. {trac-url}/2450[#2450] equations in Floating-point comparison algorithms html are not rendered properly +. {trac-url}/2600[#2600] Unit Test Framework - missed documentation +. {trac-url}/2717[#2717] `BOOST__EQUAL_COLLECTION` docs typo +. {trac-url}/2759[#2759] Typos in test new-year-resolution.html +. {trac-url}/3182[#3182] `+_CrtSetReportFile+` can be used to redirect memory leaks report +. {trac-url}/3316[#3316] Access violation when trying to log from `init_tests_func` +. {trac-url}/3392[#3392] Boost::Test: Wrong contents for documentation of the `BOOST_TEST_PASSPOINT` macro +. {trac-url}/3402[#3402] Invalid define name in documentation (duplicates #{trac-url}/2717[#2717]) +. {trac-url}/3445[#3445] incorrect link in the docs +. {trac-url}/3463[#3463] `GT` is GREAT! +. {trac-url}/3542[#3542] Bug in documentation of detect_memory_leak parameter (duplicates #{trac-url}/2018[#2018]) +. {trac-url}/3481[#3481] Boost Testing doesn't work under Sun Solaris Containers (duplicates #{trac-url}/3592[#3592]) +. {trac-url}/3495[#3495] Boost::Test enters endless loop when running in `vserver` environment (duplicates #{trac-url}/3592[#3592]) +. {trac-url}/3592[#3592] under_debugger() goes into infinite loop +. {trac-url}/3595[#3595] Typo (duplicates #{trac-url}/2759[#2759]) +. {trac-url}/3623[#3623] Boost Test Typo (duplicates #{trac-url}/2759[#2759]) +. {trac-url}/3664[#3664] `SIGCHLD` always considered fatal error +. {trac-url}/3784[#3784] Documentation errors in Execution Monitor Compilation +. {trac-url}/3785[#3785] Documentation errors in Program Execution Monitor implementation +. {trac-url}/3811[#3811] global namespace pollution +. {trac-url}/3834[#3834] doc: probably incorrect HTML rendering (duplicates #{trac-url}/2450[#2450]) +. {trac-url}/3896[#3896] erroneous documentation in boost test command line parameter description +. {trac-url}/3932[#3932] Error in `BOOST__GT` description (duplicates #{trac-url}/3463[#3463]) +. {trac-url}/3938[#3938] doc: incorrect macro name (duplicates #{trac-url}/2759[#2759]) +. {trac-url}/3964[#3964] Documentation for `BOOST__CLOSE_FRACTION` is incorrect +. {trac-url}/3978[#3978] Failed to completely redirect TestLog to file, bugfix appended +. {trac-url}/3979[#3979] `` requires additional includes +. {trac-url}/4161[#4161] spelling mistakes... +. {trac-url}/4275[#4275] Documentation error Boost.Test (duplicates #{trac-url}/2717[#2717]) +. {trac-url}/4389[#4389] Enable boost_test to run specific tests with any required dependent tests. +. {trac-url}/4434[#4434] `BOOST_AUTO_EST_CASE` typos in docs +. {trac-url}/4587[#4587] Broken link in website +. {trac-url}/4806[#4806] Invalid link (examples not showing up in documentation) +. {trac-url}/4911[#4911] ENH: boost.test output the exception real type name. +. {trac-url}/4923[#4923] Missing semicolon in documentation example +. {trac-url}/4924[#4924] Minor typo in Boost::Test docs +. {trac-url}/4982[#4982] Boost.Test has misspelled Gennadiy Rozental e-mail address +. {trac-url}/5008[#5008] Boost.Test does not do check-pointing of entry/exit of test cases +. {trac-url}/5036[#5036] Boost.Test VC memory leak report should direct to `stderr` +. {trac-url}/5262[#5262] Run tests by name utility doesn't support negation +. {trac-url}/5374[#5374] Errors from Boost.Test are no more shown in the Error list in VS2010 +. {trac-url}/5412[#5412] XML formatter in test library processes strings with subsequences `]]>` incorrectly +. {trac-url}/5563[#5563] using a test macro in a global fixture crashes Boost.Test +. {trac-url}/5582[#5582] There is a memory leak in the `BOOST_AUTO_TEST_CASE_TEMPLATE` +. {trac-url}/5599[#5599] boost::test documentation gives poor instruction +. {trac-url}/5718[#5718] broken link to unit testing framework examples +. {trac-url}/5729[#5729] Missing static_cast in fpt_limits +. {trac-url}/5870[#5870] The warning stack is not maintained +. {trac-url}/5972[#5972] Support program option to only dump the test-tree in text to output stream +. {trac-url}/6002[#6002] Failed to completely redirect TestLog to file (duplicates) +. {trac-url}/6071[#6071] Boost Test (Boost 1.46.0) GCC 4.6.1 error: ambiguous overload for ‘operator’ +. {trac-url}/6074[#6074] warnings-as-errors not usable with Boost.test in release mode +. {trac-url}/6161[#6161] SunOS: bad `putenv` declaration (duplicates {trac-url}/6766[#6766]) +. {trac-url}/6766[#6766] incorrect declaration for `putenv` in `config.hpp` +. {trac-url}/6712[#6712] Eliminate warnings with GCC +. {trac-url}/6748[#6748] Link in the documentation points to wrong page +. {trac-url}/7046[#7046] Output full error message, not just 512 chars +. {trac-url}/7136[#7136] Correct documentation for `BOOST__CLOSE_FRACTION` is not reflected into released documents +. {trac-url}/7410[#7410] Test Units (Cases and Suites) in Boost.Test do not capture `+__FILE__+` and `+__LINE__+` at declaration point making it impossible to provide source file linking using external test management tools +. {trac-url}/7894[#7894] Boost.Test documentation contains no linking instructions +. {trac-url}/8201[#8201] Broken link in document +. {trac-url}/8272[#8272] `BOOST_REQUIRE_CLOSE` fails to compile with `boost::multiprecision::cpp_dec_float_100` (duplicates #{trac-url}/11054[#11054]) +. {trac-url}/8467[#8467] Incorrect link in document (duplicates #{trac-url}/6748[#6748]) +. {trac-url}/8679[#8679] Boost.Test pollutes boost namespace with it's own `enable_if/disable_if` templates +. {trac-url}/8862[#8862] Boost.Test typo in documentation +. {trac-url}/8895[#8895] English error in test collection comparison +. {trac-url}/9179[#9179] Documentation: broken link (unable to find =const_string.hpp/const_string_test.cpp=) +. {trac-url}/9272[#9272] boost::test `BOOST__GT` documentation bug (duplicates #{trac-url}/3463[#3463]) +. {trac-url}/9390[#9390] Incomplete `BOOST_TEST_DONT_PRINT_LOG_VALUE` +. {trac-url}/9409[#9409] Some source code examples are missing +. {trac-url}/9537[#9537] const_string_test example fails +. {trac-url}/9539[#9539] Floating-point comparison algorithms aren't formatted correctly +. {trac-url}/9581[#9581] Squassabia reference link gives 404 not found +. {trac-url}/9960[#9960] Warnings on Clang +. {trac-url}/10256[#10256] \[boost test] - issue: `sigaltstack` +. {trac-url}/10318[#10318] Minor documentation fix +. {trac-url}/10394[#10394] Broken links in Boost Test documentation +. {trac-url}/10888[#10888] Assertion failures don't show up in the errors pane in VS 2010, VS 2012 or VS 2013 (duplicates) +. {trac-url}/11054[#11054] Floating-point comparison of multiprecision values fails if expression template is on +. {trac-url}/11347[#11347] `DS` identifier causes test failures in `+doc/examples/dataset_example*.cpp+` +. {trac-url}/11358[#11358] Boost.Test v3 warning could helpfully be suppressed. +. {trac-url}/11359[#11359] `BOOST_CHECK_EQUAL_COLLECTIONS`: can't control output operator (duplicates #9390) +. {trac-url}/11425[#11425] use-of-uninitialized-value (obsolete) diff --git a/doc/modules/ROOT/pages/index.adoc b/doc/modules/ROOT/pages/index.adoc index 5381f71673..24d24f3fd2 100644 --- a/doc/modules/ROOT/pages/index.adoc +++ b/doc/modules/ROOT/pages/index.adoc @@ -1,5 +1,58 @@ -= Boost.Test += Introduction +:page-aliases: boost_test/intro.adoc -The Boost Test Library provides a matched set of components for writing test -programs, organizing tests into test cases and test suites, and controlling -their runtime execution. +[quote, XP maxim] +____ +Test everything that could possibly break +____ + +[quote, XP maxim] +____ +The acceptance test makes the customer satisfied + that the software provides the business value that + makes them willing to pay for it. The unit test makes + the programmer satisfied that the software does what + the programmer thinks it does +____ + +What is the first thing you need to do when you start working on new library/class/program? That's right - +you need to start with the unit test module (hopefully you all gave this answer!). Occasionally, you may get +away with simple test implemented using `assert`s, but any professional developer soon finds this approach +lacking. It becomes clear that it's too time-consuming and tedious for simple, but repetitive unit testing +tasks and it's too inflexible for most non-trivial ones. + +The Boost.Test library provides both an easy to use and flexible set of interfaces for writing test +programs, organizing tests into simple test cases and test suites, and controlling their runtime execution. +Some of Boost.Test's interfaces are also useful in production (non-test) environments. + +== Starter example + +This is how a minimal single-file test program looks like: + +[source,cpp] +---- +#define BOOST_TEST_MODULE My Test <1> +#include <2> + +BOOST_AUTO_TEST_CASE(first_test) <3> +{ + int i = 1; + BOOST_TEST(i); <4> + BOOST_TEST(i == 2); <5> +} +---- +<1> Macro BOOST_TEST_MODULE defines the name of our program, which will be used in messages. +<2> This includes all the Unit Test Framework in a "header-only" mode; it even defines function `main`, which will call the subsequently defined test cases. +<3> Macro BOOST_AUTO_TEST_CASE declares a _test case_ named `first_test`, which in turn will run the content of `first_test` inside the +controlled testing environment. +<4> This test checks if `i` is non-zero. +<5> This test checks if `i` has value `2` (something more than just evaluating the equality operator). + +When run, it produces the following output: + +.... +Running 1 test case... +test_file.cpp(8): error: in "first_test": check i == 2 has failed [1 != 2] + +*** 1 failure is detected in the test module "My Test" +.... diff --git a/doc/modules/ROOT/pages/intro/design_rationale.adoc b/doc/modules/ROOT/pages/intro/design_rationale.adoc new file mode 100644 index 0000000000..9a858dc6a6 --- /dev/null +++ b/doc/modules/ROOT/pages/intro/design_rationale.adoc @@ -0,0 +1,36 @@ += Design rationale +:page-aliases: boost_test/intro/design_rationale.adoc + +Unit testing tasks arise during many different stages of software development: from initial project +implementation to its maintenance and later revisions. These tasks differ in their complexity and purpose +and accordingly are approached differently by different developers. The wide spectrum of tasks in a problem +domain cause many requirements (sometimes conflicting) to be placed on a unit testing framework. These +include: + +* Writing a xref:section_glossary.adoc#ref_test_module[unit test module] should be simple and obvious for new users. +* The framework should allow advanced users to perform non-trivial tests. +* Test module should be able to have many small test cases and developer should be able to group them into +test suites. +* At the beginning of the development users want to see verbose and descriptive error messages. +* During the regression testing users just want to know if any tests failed. +* For small test modules, their execution time should prevail over compilation time: user don't want to wait a minute +to compile a test that takes a second to run. +* For long and complex tests users want to be able to see the testing progress. +* Simplest tests shouldn't require an external library. +* For long term usage users of the {utf} should be able to build it as a standalone library. + +The {utf} satisfies the requirements above, and provides versatile facilities to: + +* Easily specify all the expectations in the code being tested. +* Organize these expectations into xref:section_glossary.adoc#test_case[test cases] and xref:section_glossary.adoc#test_suite[test suites]. +* Detect different kinds of errors, failures, time-outs and report them in a uniform customizable way. + +[#why_framework] +== Why do you need a framework? + +While you can write a testing program yourself from scratch, the framework offers the following benefits: + +* You get an error report in a text format. Error reports are uniform and you can easily machine-analyze them. +* Error reporting is separated from the testing code. You can easily change the error report format without affecting the testing code. +* The framework automatically detects exceptions thrown by the tested components and time-outs, and reports them along other errors. +* You can easily filter the test cases, and call only the desired ones. This does not require changing the testing code. diff --git a/doc/modules/ROOT/pages/intro/how_to_read.adoc b/doc/modules/ROOT/pages/intro/how_to_read.adoc new file mode 100644 index 0000000000..235beacce8 --- /dev/null +++ b/doc/modules/ROOT/pages/intro/how_to_read.adoc @@ -0,0 +1,23 @@ += How to read this documentation +:page-aliases: boost_test/intro/how_to_read.adoc + +This documentation is structured by what *you*, as a user, need to know to successfully use the {utf} and the order of decisions +you have to make and order of complexity of the problems you might encounter. If you ever find yourself facing with some unclear +term feel free to jump directly to the xref:section_glossary.adoc[glossary] section, where short definitions for all used +terms were collected. + +Typically, when writing a test module using the {utf} you have to go through the following steps: + +* You decide how you want to incorporate the {utf}: `+#include+` it as a header-only library, or link with it as a static library, +or use it as a shared (or dynamically loaded) library. For details on this topic see section xref:usage_variants.adoc[Usage variants]. +* You add a xref:section_glossary.adoc#test_case[test case] into a xref:section_glossary.adoc#ref_test_tree[test tree]. +For details, see section xref:tests_organization/test_cases.adoc[Test cases]. +* You perform correctness checks of the code under tested. For details, see section xref:testing_tools/index.adoc[Writing unit tests]. +* You perform the initialization of code under test before each test case. +For details, see section xref:tests_organization/fixtures.adoc[Fixtures]. +* You might want to customize the way test failures are reported. For details, see section xref:test_output/index.adoc[Controlling output]. +* You can control the run-time behavior of the built test module (e.g., run only selected tests, change the output format). +This is covered in section xref:runtime_config/index.adoc[Runtime configuration]. + +If you can't find answer to your question in any of the section mentioned above or if you believe you need even more configuration options, +you can check xref:adv_scenarios/index.adoc[Advanced usage scenarios] section. diff --git a/doc/modules/ROOT/pages/runtime_config/index.adoc b/doc/modules/ROOT/pages/runtime_config/index.adoc new file mode 100644 index 0000000000..e5021b2ce5 --- /dev/null +++ b/doc/modules/ROOT/pages/runtime_config/index.adoc @@ -0,0 +1,43 @@ += Runtime parameters +:page-aliases: boost_test/runtime_config.adoc + +== Boost.Test runtime parameters + +The {utf} supports multiple parameters that affect test module execution. To set the parameter's value you can +either use a runtime configuration subsystem interface from within the test module initialization function or you can +specify the value at runtime during test module invocation. + +The {utf} provides two ways to set a parameter at runtime: by specifying a command line argument and by setting an +environment variable. The command line argument always overrides the corresponding environment variable. + +During test module initialization the {utf} parses the command line and excludes all parameters that belong to it and +their values from the argument list. The rest of command line is forwarded to the test module initialization function +supplied by you. The command line argument format expected by the {utf} is: + +.... +--= +.... + +The command line argument name is case sensitive. It is required to match exactly the name in parameter specification. +There should not be any spaces between '=' and either command line argument name or argument value. + +The corresponding environment variable name is also case sensitive and is required to exactly match the name in the +parameter specification. + +All information about the currently supported parameters of the {utf} is summarized in +the xref:runtime_config/summary.adoc[summary section]. + +== Test filtering + +The {utf} provides an extensive filtering facility making it easy to run a specific test or a subset of tests. The +xref:runtime_config/test_unit_filtering.adoc[section on filtering] gives all the details for the command line interface. + +Additionally, xref:tests_organization/test_suite.adoc[test-suites] and xref:tests_organization/tests_grouping.adoc[labels] +may be used in order to construct subset of tests in an efficient and easy way, while decorators +(eg. {decorator_disabled}, {decorator_precondition}) can be used to set the default run status of a test case. + +== Custom runtime parameters + +It is possible to extend further the command line interface by providing a custom command line interpretation logic. There are several +ways on how to integrate this logic in the {utf} and this is explained in details in the section +xref:runtime_config/runtime_custom.adoc[Custom runtime parameters]. diff --git a/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc b/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc new file mode 100644 index 0000000000..0973f3f439 --- /dev/null +++ b/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc @@ -0,0 +1,151 @@ += Custom command line arguments +:page-aliases: boost_test/runtime_config/runtime_custom.adoc + +It is possible to pass custom command line arguments to the test module. The general format for passing custom +arguments is the following: + +[source,cpp] +---- + [...] [-- [...] +---- + +This means that everything that is passed after "`--`" is considered as a custom parameter and will not be intercepted nor interpreted +by the {utf}. This avoids any troubleshooting between the {utf} parameters and the custom ones. + +There are several use cases for accessing the arguments passed on the command line: + +* instantiating an object used in test cases and which is dependant on parameters external to the test-module: +the name of the graphic card, the credentials for a database connection, etc. The rest of the test module would check +that the functions in test are not sensitive to this type of parametrization. One can also imagine running this same +test module with different parameters (different graphic cards...) in a batched manner, +* modifying the test tree by adding or parametrizing test cases: the arguments passed on the command line may contain +for instance a set of parameters that define test cases. + +In the first scenario, xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_test_case[test cases] or fixtures, including +xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_global_fixture[global fixtures], may be used. Since those are part of the test tree, they can benefit from the {utf} rich set of assertions +and controlled execution environment. + +In the second scenario, the command line argument interact directly with the content of the test tree: by passing specific +arguments, different set of tests are created. There are mainly two options for achieving this: using a dedicated +xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_init_function[initialization function] or using xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_dataset[data driven] test cases. +The error handling of the command line parameters needs however to be adapted. + +[#ref_consuming_cmd_test_case] +== Consuming custom arguments from a test case + +The xref:tests_organization/master_test_suite.adoc[master test suite] collects the custom arguments +passed to the test module in the following way: + +* `argv[0]`, usually set by the operating system as the executable name, remains unchanged +* any argument interpreted by the test module is removed from `argv` +* the empty token `--` is removed as well +* any additional argument passed after the empty token is reported in `argv` starting at index `1` + +// tag reference: doc/modules/ROOT/examples/runtime-configuration_1.run-fail.cpp +:bt-name: runtime-configuration_1 +:bt-rule: run-fail +:bt-descr: Basic custom command line +include::partial$bt_example.adoc[] + +[#ref_consuming_cmd_global_fixture] +== Consuming custom arguments from a global fixture + +Another possibility for consuming the custom command line arguments would be from within a +xref:tests_organization/fixtures.adoc#global[global fixture]. This is especially useful +when external parameters are needed for instantiating global objects used in the test module. + +The usage is the same as for test cases. The following example runs the test module twice with +different arguments, and illustrate the feature. + +[TIP] +==== +The global fixture can check for the correctness of the custom arguments and may abort the full run + of the test module. +==== + +// tag reference: doc/modules/ROOT/examples/runtime-configuration_2.run-fail.cpp +:bt-name: runtime-configuration_2 +:bt-rule: run-fail +:bt-descr: Command line arguments interpreted in a global fixtures +include::partial$bt_example.adoc[] + +The above example instantiates a specific device through the `DeviceInterface::factory` member function. The +name of the device to instantiate is passed via the command line argument `--device-name`, and the instantiated +device is available through the global object `CommandLineDeviceInit::device`. +The module requires `3` arguments on the command line: + +* `framework::master_test_suite().argv[0]` is the test module name as explained in the previous paragraph +* `framework::master_test_suite().argv[1]` should be equal to `--device-name` +* `framework::master_test_suite().argv[2]` should be the name of the device to instantiate + +As it can be seen in the shell outputs, any command line argument consumed by the {utf} is removed from +`argc` / `argv`. Since global fixtures are running in the {utf} controlled environment, any fatal error reported +by the fixture (through the {boost_test_require} assertion) aborts the test execution. Non fatal errors +on the other hand do not abort the test-module and are reported as assertion failure, and would not prevent the execution +of the test case `check_device_has_meaningful_name`. + +[NOTE] +==== +It is possible to have several global fixtures in a test module, spread over several compilation units. + Each of those fixture may in turn be accessing a specific part of the command line. +==== + +[#ref_consuming_cmd_init_function] +== Parametrizing the test tree from command line in the initialization function + +The initialization function are described in details in this xref:adv_scenarios/test_module_init_overview.adoc[section]. +The initialization function is called before any other test or fixture, and before entering the master test suite. The initialization +function is not considered as a test-case, although it is called under the controlled execution +environment of the {utf}. This means that: + +* the errors will be properly handled, +* loggers are not fully operational, +* it is not possible to use the {utf} assertion macros like {boost_test} as it is not a test-case. + +The following example shows how to use the command line arguments parsing described above to create/add new test cases +to the test tree. It also shows very limited support to messages (does not work for all loggers), and error handling. + +// tag reference: doc/modules/ROOT/examples/runtime-configuration_3.run-fail.cpp +:bt-name: runtime-configuration_3 +:bt-rule: run-fail +:bt-descr: Init function parametrized from the command line +include::partial$bt_example.adoc[] + +As seen in this example, the error handling is quite different than a regular test-case: + +* For the _alternative_ initialization API (see +{boost_test_alternative_init_api}), the easiest way to indicate an error would be to return `false` +in case of failure. +* For the _obsolete_ and _alternative_, raising an exception such as `std::runtime_error` or +cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] as above works as well. + +[#ref_consuming_cmd_dataset] +== Data-driven test cases parametrized from the command line + +It is possible to use the command line arguments to manipulate the dataset generated by a data-drive test case. + +By default, datasets are created before entering the `main` of the test module, and try to be efficient in the number +of copies of their arguments. It is however possible +to indicate a delay for the evaluation of the dataset by constructing the dataset with the `make_delayed` function. + +With the `make_delayed`, the construction of the dataset will happen at the same time as the construction of the +test tree during the test module initialization, and not before. It is this way possible to access the +xref:tests_organization/master_test_suite.adoc[master test suite] and its command line arguments. + +The example below shows a complex dataset generation from the content of an external file. The data contained +in the file participates to the definition of the test case. + +// tag reference: doc/modules/ROOT/examples/runtime-configuration_4.run-fail.cpp +:bt-name: runtime-configuration_4 +:bt-rule: run-fail +:bt-descr: Dataset test case parametrized from the command line +include::partial$bt_example.adoc[] + +* Using `make_delayed`, the tests generated from a dataset are instantiated during the framework setup. This +let the dataset generator access the `argc` and `argv` of the master test suite. +* The generation of the test-cases out of this dataset happens before the global fixture are reached (and before +any test cases), and after the initialization function. +* The generator of the dataset is *not* considered being a test case and the {utf} assertions are not accessible. +However, the {utf} will catch the exceptions raised during the generation of the test-cases by the dataset. +To report an error, a `std::logic_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] can be raised +and will be reported by the {utf}. diff --git a/doc/modules/ROOT/pages/runtime_config/summary.adoc b/doc/modules/ROOT/pages/runtime_config/summary.adoc new file mode 100644 index 0000000000..6c7ad9845b --- /dev/null +++ b/doc/modules/ROOT/pages/runtime_config/summary.adoc @@ -0,0 +1,87 @@ += Summary of run-time parameters +:page-aliases: boost_test/runtime_config/summary.adoc + +[%header%autowidth,cols="2*"] +|=== +|Command +|Short description + +|xref:utf_reference/rt_param_reference.adoc#auto_dbg[`auto_start_dbg`] +|Instructs the framework to automatically attach debugger in case of system failure. + +|xref:utf_reference/rt_param_reference.adoc#build_info[`build_info`] +|Instructs the framework to display library build information. + +|xref:utf_reference/rt_param_reference.adoc#catch_system[`catch_system_error`] +|Instructs the framework to catch system errors. + +|xref:utf_reference/rt_param_reference.adoc#color_output[`color_output`] +|Instructs the framework to produce color output + +|xref:utf_reference/rt_param_reference.adoc#detect_fp_exceptions[`detect_fp_exceptions`] +|Instructs the framework to trap floating point exceptions (on supported platforms). + +|xref:utf_reference/rt_param_reference.adoc#detect_memory_leaks[`detect_memory_leaks`] +|Instructs the framework to detect memory leaks (on supported platforms). + +|xref:utf_reference/rt_param_reference.adoc#help[`help`] +|Provides help on the {utf} parameters. + +|xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`] +|Lists the tests units, their organization in the test tree, their enabled/disabled state... + +|xref:utf_reference/rt_param_reference.adoc#list_labels[`list_labels`] +|Lists the labels defined in the test module. + +|xref:utf_reference/rt_param_reference.adoc#log_format[`log_format`] +|Specifies the log format + +|xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`] +|Specifies the framework's logging level + +|xref:utf_reference/rt_param_reference.adoc#log_sink[`log_sink`] +|Specifies where to write testing log to. + +|xref:utf_reference/rt_param_reference.adoc#logger[`logger`] +|Specifies the log level, format and sink of one or more loggers. + +|xref:utf_reference/rt_param_reference.adoc#output_format[`output_format`] +|Specifies the log format and the report format. + +|xref:utf_reference/rt_param_reference.adoc#random[`random`] +|Instructs the framework to run the tests in random order + +|xref:utf_reference/rt_param_reference.adoc#report_format[`report_format`] +|Specifies the report format. + +|xref:utf_reference/rt_param_reference.adoc#report_level[`report_level`] +|Specifies the level of details carried by the framework's testing result report. + +|xref:utf_reference/rt_param_reference.adoc#report_memory_leaks_to[`report_memory_leaks_to`] +|Specifies file name where memory leaks report should be re-directed to. + +|xref:utf_reference/rt_param_reference.adoc#report_sink[`report_sink`] +|Specifies where to write the testing result report to. + +|xref:utf_reference/rt_param_reference.adoc#result_code[`result_code`] +|Instructs the framework to return or ignore a result code indicating an error in the tests. + +|{param_run_test} +|Allows to filter which test units to execute at runtime. + +|xref:utf_reference/rt_param_reference.adoc#save_pattern[`save_pattern`] +|Facilitates mode switching for testing output streams. + +|xref:utf_reference/rt_param_reference.adoc#show_progress[`show_progress`] +|Instructs the framework to print progress information. More details xref:test_output/test_output_progress.adoc[here]. + +|xref:utf_reference/rt_param_reference.adoc#use_alt_stack[`use_alt_stack`] +|Instructs the framework to use an alternative stack for signal processing (on supported platforms). + +|xref:utf_reference/rt_param_reference.adoc#usage[`usage`] +|Displays short usage message. + +|xref:utf_reference/rt_param_reference.adoc#wait_for_debugger[`wait_for_debugger`] +|Instructs the framework to pause test module before testing is started to allow debugger to attach. + +|=== diff --git a/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc b/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc new file mode 100644 index 0000000000..1471185e69 --- /dev/null +++ b/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc @@ -0,0 +1,321 @@ += Test unit filtering +:page-aliases: boost_test/runtime_config/test_unit_filtering.adoc + +The {utf} offers a number of ways to run only a subset of all test cases registered in the test tree. + +[#ref_default_run_status] +== Default run status + +Each test unit (either test case or test suite) has an associated _default run status_. It can assume one of the three values: + +. _true_ -- this means that, unless some runtime parameters specify otherwise, the test unit is designated to be run. +. _false_ -- this means that, unless some runtime parameters specify otherwise, the test unit is designated _not_ to be run. +. _inherit_ -- this means that the test unit's default run status is the same as that of its immediate parent test unit. This is applied recursively. + +Initially, the master test suite has default run status set to _true_. All other test units have default run status set to _inherit_. +This implies that, unless any additional configuration is applied, all tests are designated to be run. + +You can set a different default run status in any test unit by using xref:tests_organization/decorators.adoc[decorators]: +{decorator_disabled}, {decorator_enabled} and {decorator_enable_if}. The default run status is set once, upon testing program +initialization, and cannot be changed. The disabled tests are not executed by default, but are still present in the test tree, +and are listed along with other tests when you use command-line argument +xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. + +// tag reference: doc/modules/ROOT/examples/decorator_20.run-fail.cpp +:bt-name: decorator_20 +:bt-rule: run-fail +:bt-descr: default run status +include::partial$bt_example.adoc[] + +[#ref_dynamic_test_dependency] +== Dynamic test dependencies + +Additionally, it is possible to statically associate a test unit with a condition. This associated condition is evaluated immediately +before executing the test unit. If the condition is met, the test unit is executed. Otherwise, the test unit is _skipped_. +It is possible to add two dependencies: + +. Upon another test unit. In this case the decorated test case is skipped if the test unit specified in the dependency is either +failed or skipped or disabled. This can be declared with decorator {decorator_depends_on}. +. Upon an arbitrary predicate. This can be declared with decorator {decorator_precondition}. + +[#ref_command_line_control] +== Command-line control + +Static configuration of the test-case filtering is used by default, unless command-line filtering is applied. With command-line argument +{param_run_test} it is possible to alter the static pre-set in a number of ways: + +. Ignore the static configuration and manually specify test cases to be run. +. Augment the statically defined set by enabling the disabled test cases. +. Shrink the statically defined set by disabling some of the enabled test cases. + +[#ref_command_line_control_absolute] +=== Absolute specification + +Term 'absolute' in this context means that the default run status of the test units, which has been statically set up, +is completely ignored and the tests to be run are specified manually from scratch. First, in order to learn what test +units are registered in the test tree the user needs to use command-line argument +xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. +Next, in order to specify a set of test cases, the user needs to use command-line argument +{param_run_test} with absolute value: + +[source,cpp] +---- +> test_program --run_test= +---- + +The format of `` value can assume a number of forms. Given the following program: + +[source,cpp] +---- +#define BOOST_TEST_MODULE example +#include + +using boost::unit_test::label; + +BOOST_AUTO_TEST_CASE(test_1, *label("L1")) {} +BOOST_AUTO_TEST_CASE(test_2, *label("L1")) {} + +BOOST_AUTO_TEST_SUITE(suite_1) + + BOOST_AUTO_TEST_SUITE(suite_1) + BOOST_AUTO_TEST_CASE(test_1) {} + BOOST_AUTO_TEST_CASE(test_2) {} + BOOST_AUTO_TEST_SUITE_END() + + BOOST_AUTO_TEST_SUITE(suite_2) + BOOST_AUTO_TEST_CASE(test_1, *label("L2")) {} + BOOST_AUTO_TEST_CASE(test_2, *label("L2")) {} + BOOST_AUTO_TEST_SUITE_END() + + BOOST_AUTO_TEST_CASE(test_1, *label("L1")) {} + BOOST_AUTO_TEST_CASE(test_2) {} + BOOST_AUTO_TEST_CASE(test_2A) {} + +BOOST_AUTO_TEST_SUITE_END() +---- + +The following table illustrates how different values of `` control which test cases ware run. + +[%header%autowidth,cols="3*"] +|=== +|Description +|Parameter value +|Test cases run + +|Run single top-level test case by name +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=test_1 +.... +a| +.... +test_1 +.... + +|Run single nested test case by name +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/suite_1/test_1 +.... +a| +.... +suite_1/suite_1/test_1 +.... + +|Run single test suite by name +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/suite_2 +{param_run_test}=suite_1/suite_2/* +.... +a| +.... +suite_1/suite_2/test_1 +suite_1/suite_2/test_2 +.... + +|Run multiple test units that are *siblings* of the same test suite +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/test_1,suite_2 +.... +a| +.... +suite_1/suite_2/test_1 +suite_1/suite_2/test_2 +suite_1/test_1 +.... + +|Run multiple test units that are not necessarily siblings +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/test_1:test_1 +.... +a| +.... +suite_1/test_1 +test_1 +.... + +|Run all tests matching to a given label +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=@L1 +.... +a| +.... +test_1 +test_2 +suite_1/test_1 +.... + +|Run every test case in the test tree. Note that this will also enable all disabled tests. +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=* +.... +a| +.... +test_1 +test_2 +suite_1/suite_1/test_1 +suite_1/suite_1/test_2 +suite_1/suite_2/test_1 +suite_1/suite_2/test_2 +suite_1/test_1 +suite_1/test_2 +suite_1/test_2A +.... + +|Run every test unit in a given suite with a given prefix +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/test* +.... +a| +.... +suite_1/test_1 +suite_1/test_2 +suite_1/test_2A +.... + +|Run every test unit in a given suite with a given suffix +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/*_1 +.... +a| +.... +suite_1/suite_1/test_1 +suite_1/suite_1/test_2 +suite_1/test_1 +.... + +|Run every test unit in a given suite with a given infix +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=suite_1/\*_2\* +.... +a| +.... +suite_1/suite_2/test_1 +suite_1/suite_2/test_2 +suite_1/test_2 +suite_1/test_2A +.... + +|Run test(s) with given name in any N-level suite +a| +[subs="+macros,+attributes,+quotes"] +.... +{param_run_test}=\*/\*/test_2 +.... +a| +.... +suite_1/suite_1/test_2 +suite_1/suite_2/test_2 +.... + +|=== + +For the syntax productions describing the structure of `` value see xref:utf_reference/rt_param_reference.adoc#run_test[here]. + +While using manual absolute test case specification ignores the default run status, it does not ignore the dynamic test dependencies. +If test unit `B` depends on test unit `A` and test `B` is specified to be run by {param_run_test}, `A` is also run, even +if it is not specified, and its failure may cause the execution of `B` to be skipped. Similarly, the failed check of +the {decorator_precondition} may cause the test selected test to be skipped. + +// tag reference: doc/modules/ROOT/examples/decorator_21.run-fail.cpp +:bt-name: decorator_21 +:bt-rule: run-fail +:bt-descr: run_test and dynamic dependencies +include::partial$bt_example.adoc[] + +[#ref_command_line_control_enablers] +=== Relative specification + +Term 'relative' in this context means that the configuration is based on either the default run status of the test units or +by the command-line override specified by the _absolute specification_; and atop of this, we additionally either enable +some disabled test units or disable some enabled tests units. The relative specification is controlled by command-line +argument {param_run_test}, with the value using similar syntax as in the absolute specification, but preceded with +either character `'!'` for disabling enabled test units or with character `'+'` for enabling the disabled test units. +This can be summarized with the following table: + +[%header%autowidth,cols="3*"] +|=== +|command +|specification type +|semantics + +a| +[subs="+macros,+attributes,+quotes"] +.... +> test_program --{param_run_test}=! +.... +|disabler +|Enabled test units that match `` become disabled. + +a| +[subs="+macros,+attributes,+quotes"] +.... +> test_program --{param_run_test}=+ +.... +|enabler +|Disabled test units that match `` as well as their upstream dependencies become enabled. + +|=== + +The _enabler_ specification is used to enable a set of test units which are initially disabled. + +// tag reference: doc/modules/ROOT/examples/decorator_22.run.cpp +:bt-name: decorator_22 +:bt-rule: run +:bt-descr: command-line enabler +include::partial$bt_example.adoc[] + +Conversely, the _disabler_ specification is used to disable a set of test units which are initially enabled. + +// tag reference: doc/modules/ROOT/examples/decorator_23.run.cpp +:bt-name: decorator_23 +:bt-rule: run +:bt-descr: command-line disabler +include::partial$bt_example.adoc[] + +If there are both an enabler and disabler on one command line that specify the same test, the test becomes disabled. I.e., +the disabler takes the precedence over the enabler. + +[NOTE] +==== +While enabler additionally enables the upstream dependencies (introduced with decorator {decorator_depends_on}), + disabler does not disable them. Therefore when you enable and then disable the same test, you do not disable its upstream dependencies. +==== diff --git a/doc/modules/ROOT/pages/section_faq.adoc b/doc/modules/ROOT/pages/section_faq.adoc new file mode 100644 index 0000000000..dd933f4663 --- /dev/null +++ b/doc/modules/ROOT/pages/section_faq.adoc @@ -0,0 +1,189 @@ += Frequently Asked Questions +:page-aliases: boost_test/section_faq.adoc + +== Where the latest version of the Boost Test Library is located? + +The latest version of Boost Test Library is available online at http://www.boost.org/libs/test[]. + +== Bug report of feature request: what should I do? + +You can send a bug report or a feature request to the boost users' mailing list boost-users@lists.boost.org and/or fill +a ticket on the GitHub issues of the project https://github.com/boostorg/test[]. + +== How to create test case using the Unit Test Framework? + +To create a test case, use the macro + +{boost_auto_test_case}( test_function ); + +For more details see the Unit Test Framework {boost_auto_test_case} documentation. + +== Is Boost.Test thread safe? + +Short answer: no, but we welcome patches! + +Longer answer: Boost.Test currently has no synchronization mechanisms in place to avoid any race when +multiple threads are calling the assertion macros. For instance this code + +[source,cpp] +---- +BOOST_TEST_CASE(test_parallel) +{ + std::vector vect(10); + std::for_each( + std::execution::par_unseq, + vect.begin(), + vect.end(), + [](auto const& str) + { + BOOST_TEST(str == ""); + }); +} +---- + +will not work as expected as the assertion `BOOST_TEST` will be called from multiple threads. + +== How to create test suite using the Unit Test Framework? + +To create a test suite use the macro + +{boost_auto_test_suite}( suite_name ); + +For more details see the Unit Test Framework {boost_auto_test_suite} documentation. + +== Why did I get a linker error when compiling my test program? + +Boost Test Library components provide several usage variants: to create a test program you can +link with the one of the precompiled library variants or use header-only variant. For example, to use Unit Test +Framework you may either include + +[source,cpp] +---- +#include +---- + +and link with `libunit_test_framework.lib` or you can include + +[source,cpp] +---- +#include +---- + +in which case you should not need to link with any pre-compiled component. Note also that +you should strictly follow specification on initialization function in other case some compilers may produce linker +error like this. + +[source,cpp] +---- +Unresolved external init_unit_test_suite(int, char**). +---- + +The reason for this error is that in your implementation you should specify second argument of +`init_unit_test_suite` exactly as in the specification, i.e.: `+char* []+`. + +== How can I redirect testing output? + +Use `unit_test_log::instance().set_log_output( std::ostream & )` +For more details see the {utf} {output_test_stream_tool} documentation. + +== I want different default log trace level + +Use environment variable {boost_test_log_level} to define desired log trace level. You still will be able to reset +this value from the command line. For the list of acceptable values see the {utf} +{runtime_configuration} documentation. + +== Is there DLL version of Boost.Test components available on Win32 platform? + +Yes. Starting with Boost 1.34.0. + +== How to set up a CMake project using {utf} (extended) + +Suppose, you are building a test module from one translation unit `test_file.cpp`. First, let's do it using the xref:usage_variants.adoc#single_header[header-only usage variant] of the {utf}. + +Let's paste the following content in a `CMakeLists.txt` +at the same location than our test file `test_file.cpp`: + +.... +cmake_minimum_required(VERSION 2.8.7) +project(my_first_test) +enable_testing() + +# indicates the location of the boost installation tree. +# hard-coded for our simple example. +set(BOOST_INCLUDE_DIRS $boost_installation_prefix/include) + +# creates the executable +add_executable(test_executable test_file.cpp) +# indicates the include paths +target_include_directories(test_executable PRIVATE ${BOOST_INCLUDE_DIRS}) + +# declares a test with our executable +add_test(NAME test1 COMMAND test_executable) +.... + +We will now create the build directory for this project (separate directory), +configure and build the project, as follow: + +[source,cpp] +---- +> cd ``$``test_path +> mkdir build <1> +> cd build +> cmake .. <2> +> cmake --build . <3> +> ctest <4> +---- +<1> we create a directory dedicated to the build, to avoid + any pollution of the sources with the temporary + build files +<2> configuration of the project +<3> this command builds the project, cmake drives a native + tool that is configured on the previous command line +<4> runs the tests declared in the project and prints a report + +In the case you are using the xref:usage_variants.adoc#shared_lib[shared libraries] variant of {utf}, +some modifications should be done in your CMakeLists.txt. + +.... +cmake_minimum_required(VERSION 2.8.11) +project(my_first_test) +enable_testing() + +# replace XX with the version you have +set(Boost_ADDITIONAL_VERSIONS "1.XX" "1.XX.0") + +# finds boost, triggers an error otherwise +find_package(Boost XX REQUIRED COMPONENTS unit_test_framework) + +# creates the executable +add_executable(test_executable test_file.cpp) +# indicates the include paths +target_include_directories(test_executable PRIVATE ${Boost_INCLUDE_DIRS}) +# indicates the shared library variant +target_compile_definitions(test_executable PRIVATE "BOOST_TEST_DYN_LINK=1") +# indicates the link paths +target_link_libraries(test_executable ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + +# declares a test with our executable +add_test(NAME test1 COMMAND test_executable) +.... + +We will now create the build directory for this project (separate directory), configure and build the project, +as follow: + +[source,cpp] +---- +> cd ``$``test_path +> mkdir build <1> +> cd build +> cmake -DBOOST_ROOT=``$``boost_installation_prefix .. <2> +> cmake --build . <3> +> ctest <4> +---- +<1> we create a directory dedicated to the build, to avoid any pollution of the sources with the temporary + build files +<2> configuration of the project, the `BOOST_ROOT` configuration element indicates the + Boost module of `cmake` where to find our installation +<3> this command builds the project, cmake drives a native tool that is configured on the + previous command line +<4> runs the tests declared in the project and prints a report diff --git a/doc/modules/ROOT/pages/section_glossary.adoc b/doc/modules/ROOT/pages/section_glossary.adoc new file mode 100644 index 0000000000..ea994bb5ec --- /dev/null +++ b/doc/modules/ROOT/pages/section_glossary.adoc @@ -0,0 +1,117 @@ += Glossary +:page-aliases: boost_test/section_glossary.adoc + +Here is the list of terms used throughout this documentation. + +[#ref_test_module] +== Test module + +This is a single binary that performs the test. Physically a test module consists of one or more test source files, +which can be built into an executable or a dynamic library. A test module that consists of a single test source +file is called _single-file test module_. Otherwise +it's called _multi-file test module_. Logically, each test module consists of four parts: + +. xref:section_glossary.adoc#test_setup[test setup] (or test initialization), +. xref:section_glossary.adoc#test_body[test body] +. xref:section_glossary.adoc#test_cleanup[test cleanup] +. xref:section_glossary.adoc#test_runner[test runner] + +The test runner part is optional. If a test module is built as +an executable, the test runner is built-in. If a test module is built as a dynamic library, it is run by an +xref:adv_scenarios/external_test_runner.adoc[external test runner]. + +WARNING: The test module should have at least one test-case defined, otherwise it is considered as an error. + +[#test_body] +== Test body + +This is the part of a test module that actually performs the test. +Logically test body is a collection of xref:section_glossary.adoc#test_assertion[test assertions] wrapped in +xref:section_glossary.adoc#test_case[test cases], which are organized in a xref:section_glossary.adoc#ref_test_tree[test tree]. + +[#ref_test_tree] +== Test tree + +This is a hierarchical structure of xref:section_glossary.adoc#test_suite[test suites] (non-leaf nodes) and +xref:section_glossary.adoc#test_case[test cases] (leaf nodes). More details can be found xref:tests_organization/index.adoc[here]. + +[#ref_test_unit] +== Test unit + +This is a collective name when referred to either a xref:section_glossary.adoc#test_suite[test suite] or +xref:section_glossary.adoc#test_case[test cases]. See xref:tests_organization/index.adoc[this section] for more details. + +[#test_assertion] +== Test assertion + +This is a single binary condition (binary in a sense that is has two outcomes: pass and fail) checked +by a test module. + +There are different schools of thought on how many test assertions a test case should consist of. Two polar +positions are the one advocated by TDD followers - one assertion per test case; and opposite of this - all test +assertions within single test case - advocated by those only interested in the first error in a +test module. The {utf} supports both approaches. + +[#test_case] +== Test case + +This is an independently monitored function within a test module that +consists of one or more test assertions. The term _independently monitored_ in the definition above is +used to emphasize the fact, that all test cases are monitored independently. An uncaught exception or other normal +test case execution termination doesn't cause the testing to cease. Instead the error is caught by the test +case execution monitor, reported by the {utf} and testing proceeds to the next test case. Later on you are going +to see that this is on of the primary reasons to prefer multiple small test cases to a single big test function. + +[#test_suite] +== Test suite + +This is a container for one or more test cases. The test suite gives you an ability to group +test cases into a single referable entity. There are various reasons why you may opt to do so, including: + +* To group test cases per subsystems of the unit being tested. +* To share test case setup/cleanup code. +* To run selected group of test cases only. +* To see test report split by groups of test cases. +* To skip groups of test cases based on the result of another test unit in a test tree. + +A test suite can also contain other test suites, thus allowing a hierarchical test tree structure to be formed. +The {utf} requires the test tree to contain at least one test suite with at least one test case. The top level +test suite - root node of the test tree - is called the master test suite. + +[#test_setup] +== Test setup + +This is the part of a test module that is responsible for the test +preparation. It includes the following operations that take place prior to a start of the test: + +* The {utf} initialization +* Test tree construction +* Global test module setup code +* _Per test case_ setup code, invoked for every test case it's assigned to, is also attributed to the +test initialization, even though it's executed as a part of the test case. + +[#test_cleanup] +== Test cleanup + +This is the part of test module that is responsible for cleanup operations. + +[#test_fixture] +== Test fixture + +Matching setup and cleanup operations are frequently united into a single entity called test fixture. + +[#test_runner] +== Test runner + +This is an _orchestrator_ or a _driver_ that, given the test tree, ensures the test tree is initialized, tests are executed and necessary reports generated. For more information xref:adv_scenarios/test_module_runner_overview.adoc[see here]. + +[#test_log] +== Test log + +This is the record of all events that occur during the testing. + +[#test_report] +== Test report + +This is the report produced by the {utf} after the testing is completed, that indicates which test cases/test +suites passed and which failed. diff --git a/doc/modules/ROOT/pages/test_output/checkpoints.adoc b/doc/modules/ROOT/pages/test_output/checkpoints.adoc new file mode 100644 index 0000000000..7b460e5d47 --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/checkpoints.adoc @@ -0,0 +1,60 @@ += Checkpoints for accurate failure location +:page-aliases: boost_test/test_output/test_tools_support_for_logging/checkpoints.adoc + +In most cases, the {utf} can't provide an exact location where system error occurs or uncaught C++ exception +is thrown from. To be able to pinpoint it as close as possible the {utf} keeps track of *checkpoints* - the +location a test module passed through. + +The {utf} keeps track of checkpoints at test case entrance, exit, fixture initialization, and at test tool invocation point. + +Any other checkpoints should be entered by you manually if you need more granularity in case a fatal +error occurs during the test. The {utf} provides two macros for this purpose: + +* xref:test_output/checkpoints.adoc#ref_named_checkpoint[`BOOST_TEST_CHECKPOINT`] to specify a _named_ checkpoint and +* xref:test_output/checkpoints.adoc#ref_unnamed_checkpoint[`BOOST_TEST_PASSPOINT`] to specify an _unnamed_ checkpoint. + +The checkpoints are also convenient for checks in loops as they might provide +more information about the occurrence of a failure (although superseded by +xref:test_output/contexts.adoc[contexts]). + +[#ref_named_checkpoint] +== Named checkpoints + +The macro {boost_test_checkpoint} is intended to be used to inject *named* checkpoint position. The +macro signature is as follows: + +[source,cpp] +---- +BOOST_TEST_CHECKPOINT(checkpoint_message); +---- + +The message formatted at the checkpoint position is saved and reported by the exception logging functions (if any +occurs). Similarly to the {boost_test_message} the message can be formatted from any standard +output stream compliant components. + +// tag reference: doc/modules/ROOT/examples/example22.run-fail.cpp +:bt-name: example22 +:bt-rule: run-fail +:bt-descr: {boost_test_checkpoint} usage +include::partial$bt_example.adoc[] + +[#ref_unnamed_checkpoint] +== Unnamed checkpoints + +The macro {boost_test_passpoint} is intended to be used to inject an *unnamed* checkpoint position. The +macro signature is as follows: + +[source,cpp] +---- +BOOST_TEST_PASSPOINT(); +---- + +Unlike the macro {boost_test_checkpoint} this macro doesn't require any message to be +supplied with it. It's just a simple "been there" marker that records file name and line number +code passes through. + +// tag reference: doc/modules/ROOT/examples/example23.run-fail.cpp +:bt-name: example23 +:bt-rule: run-fail +:bt-descr: {boost_test_passpoint} usage +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/test_output/contexts.adoc b/doc/modules/ROOT/pages/test_output/contexts.adoc new file mode 100644 index 0000000000..a52ac71e42 --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/contexts.adoc @@ -0,0 +1,203 @@ += Contexts +:page-aliases: boost_test/test_output/test_tools_support_for_logging/contexts.adoc + +Contexts are a facility provided by the {utf} in order to be able to trace the location of assertions better. To grasp +the idea, consider the following example: + +[source,cpp] +---- +void test_operations(Processor& processor, int limit) +{ + for (int i = 0; i < limit; ++i) { + BOOST_TEST(processor.op1(i)); + for (int j = 0; j < i; ++j) { + BOOST_TEST(processor.op2(i, j)); + } + } +} +---- + +In case of failure, in order to see in the logs at which point of the loops the failure occurred, we need some extra +information in the assertion, which can be achieved for instance the following way // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.reports.custom_messages: + +[source,cpp] +---- +BOOST_TEST(processor.op1(i)); +---- + +replaced by + +[source,cpp] +---- +BOOST_TEST(processor.op1(i), "With parameter i = " << i); +---- + +We see in this trivial example that a context, which is the variable `i` in this case, should be acknowledged by the +assertion `BOOST_CHECK` in a particular way. In the approach above, this is done by adding a message to the assertion +itself. + +What if the context is more complex than that? In case the complexity of the context increases, the fact that the +assertion and the context is tightly coupled as in the approach above is difficult to maintain: + +[source,cpp] +---- +void test_operations(Processor& processor, int limit, int level) +{ + for (int i = 0; i < limit; ++i) { + BOOST_TEST(processor.op1(i), + "With optimization level " << level << ", With parameter i = " << i); + for (int j = 0; j < i; ++j) { + BOOST_TEST(processor.op2(i, j), + "With optimization level " << level << + ", With parameter i = " << i << ", With parameter j = " << j); + } + } +} + +BOOST_AUTO_TEST_CASE(test1) +{ + Processor processor; + + for (int level = 0; level < 3; ++level) { + processor.optimization_level(level); + test_operations(processor, 2, level); + } +} +---- + +Note the length of the messages, the repetition, and the fact, that we pass argument `level` to function +`test_operations` only for the sake of generating an error message in case of a failure. + +Therefore, *loose* coupling between the context of an assertion and the assertion point is a property that is desirable. + +[#ref_BOOST_TEST_INFO] +== Assertion-bound context + +`BOOST_TEST_INFO` can be used to define an error message to be bound to the first following assertion. If (and only +if) the assertion fails, the bound message will be displayed along: + +// tag reference: doc/modules/ROOT/examples/example80_contexts.run-fail.cpp +:bt-name: example80_contexts +:bt-rule: run-fail +:bt-descr: Assertion-bound context +include::partial$bt_example.adoc[] + +The information composed inside `BOOST_TEST_INFO` is bound only to the first assertion +following the declaration. This information is only displayed if the assertion fails; otherwise the message is +discarded. The `BOOST_TEST_INFO` declaration does not have to immediately precede the assertion, it is allowed to +intertwine them with other instructions, they can even be declared in different scopes. It is also possible to +bind more than one information to a given assertion. + +With `BOOST_TEST_INFO`, we can improve our initial example as follows: + +[source,cpp] +---- +void test_operations(Processor& processor, int limit, int level) +{ + for (int i = 0; i < limit; ++i) { + BOOST_TEST_INFO("With optimization level " << level); + BOOST_TEST_INFO("With parameter i = " << i); + BOOST_TEST(processor.op1(i)); + for (int j = 0; j < i; ++j) { + BOOST_TEST_INFO("With optimization level " << level); + BOOST_TEST_INFO("With parameter i = " << i); + BOOST_TEST_INFO("With parameter j = " << j); + BOOST_TEST(processor.op2(i, j)); + } + } +} + +BOOST_AUTO_TEST_CASE(test1) +{ + Processor processor; + + for (int level = 0; level < 3; ++level) { + processor.optimization_level(level); + test_operations(processor, 2, level); + } +} +---- + +[#ref_BOOST_TEST_CONTEXT] +== Scope-bound context + +In the previous example, the information stored inside the calls to `BOOST_TEST_INFO` were all consumed by the next assertion. There are cases +where we would like this information be persistent for the current scope. {utf} provides two tools to achieve this: + +* `BOOST_TEST_CONTEXT` defines a diagnostic message and a scope. The message is bound to every assertion in that scope, +and is displayed along with every failed assertion. +* `BOOST_TEST_INFO_SCOPE` acts the same as `BOOST_TEST_INFO`, but the stored context information is bound to all the assertions +that follow the call to `BOOST_TEST_INFO_SCOPE` within the current scope. + +TIP: Since Boost xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70], `BOOST_TEST_CONTEXT` can accept multiple arguments. + +TIP: `BOOST_TEST_INFO_SCOPE` has been introduced in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70]. + +// tag reference: doc/modules/ROOT/examples/example81_contexts.run-fail.cpp +:bt-name: example81_contexts +:bt-rule: run-fail +:bt-descr: Scope-bound context +include::partial$bt_example.adoc[] + +In the previous example, there is an opening brace right after `BOOST_TEST_CONTEXT`: this pair of braces defines the scope in which +the diagnostic message is in effect. If there is no braces, the scope applies only to the following statement. +`BOOST_TEST_CONTEXT` declarations can nest. + +With `BOOST_TEST_CONTEXT`, we can further improve our initial example, by putting variable `level` into a scope-level context +and not pass it as function parameter: + +[source,cpp] +---- +void test_operations(Processor& processor, int limit) +{ + for (int i = 0; i < limit; ++i) { + BOOST_TEST_INFO("With parameter i = " << i); + BOOST_TEST(processor.op1(i)); + for (int j = 0; j < i; ++j) { + BOOST_TEST_INFO("With parameter i = " << i); + BOOST_TEST_INFO("With parameter j = " << j); + BOOST_TEST(processor.op2(i, j)); + } + } +} + +BOOST_AUTO_TEST_CASE(test1) +{ + Processor processor; + + for (int level = 0; level < 3; ++level) { + BOOST_TEST_CONTEXT("With optimization level " << level) { + processor.optimization_level(level); + test_operations(processor, 2); + } + } +} +---- + +If we observe that variable `i` also applies in a certain scope, we can improve our example further still. + +// tag reference: doc/modules/ROOT/examples/example82_contexts.run-fail.cpp +:bt-name: example82_contexts +:bt-rule: run-fail +:bt-descr: Using contexts +include::partial$bt_example.adoc[] + +Finally, it is possible to pass several arguments to `BOOST_TEST_CONTEXT`, which is more convenient than having +several scopes: + +// tag reference: doc/modules/ROOT/examples/example83_contexts.run-fail.cpp +:bt-name: example83_contexts +:bt-rule: run-fail +:bt-descr: Multiple arguments to `BOOST_TEST_CONTEXT` +include::partial$bt_example.adoc[] + +`BOOST_TEST_INFO_SCOPE` is convenient when you augment the current scope information as new information arrives. +The following example calls several time a quadratic polynomial estimation function with random polynomial. As the +random values are drawn in a loop, they are placed in the current scope with `BOOST_TEST_INFO_SCOPE`, which allows us +to easily debug the function. + +// tag reference: doc/modules/ROOT/examples/example84_contexts.run-fail.cpp +:bt-name: example84_contexts +:bt-rule: run-fail +:bt-descr: Sticky context with `BOOST_TEST_INFO_SCOPE` +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/test_output/index.adoc b/doc/modules/ROOT/pages/test_output/index.adoc new file mode 100644 index 0000000000..9df111f5f2 --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/index.adoc @@ -0,0 +1,42 @@ += Controlling outputs +:page-aliases: boost_test/test_output.adoc + +The output produced by a test module is one of the major assets the {utf} brings to users. In comparison with any +kind of manual/assert based solution the {utf} provide following services: + +[cols="1,3"] +|=== +|All test errors are reported uniformly +a| +The test execution monitor along with standardized output from all included + xref:testing_tools/index.adoc[testing tools] provides uniform reporting for all errors + including fatal errors, like memory assess violation and uncaught exceptions. + +|Detailed information on the source of an error +a| +The {utf} test tool's based assertion provides as much information as possible about cause of error, + usually allowing you to deduce what is wrong without entering the debugger or core analysis. + +|Separation of the test errors description (test log) from the results report summary (test results report) +a| +The information produced during test execution, including all error, warning and info messages from the test + tools, executed test units notification constitute the *test log*. + +Once testing is completed the {utf} may produce a summary *test report* with + different levels of detail. + +|Flexibility in what is shown in the output +a| +The {utf} provides the ability to configure what is shown in both the test log and the test report. The + configuration is supported both at runtime (from the command line) and at compile time from within a + test module. + +|Flexibility in how output is formatted +a| +The {utf} provides the ability to configure the format of the test module output. At the moment only + xref:test_output/log_formats.adoc[three formats] + are supported by the {utf} itself. However the well defined public interface allows you to + xref:test_output/logging_api.adoc#custom_log_formatter[customize] an output for + your purposes. + +|=== diff --git a/doc/modules/ROOT/pages/test_output/log_floating_points.adoc b/doc/modules/ROOT/pages/test_output/log_floating_points.adoc new file mode 100644 index 0000000000..9b00ce6eab --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/log_floating_points.adoc @@ -0,0 +1,30 @@ += Logging floating point type numbers +:page-aliases: boost_test/test_output/test_tools_support_for_logging/log_floating_points.adoc + +It may appear that floating-point numbers are displayed by the {utf} with an excessive number of decimal digits. +However the number of digits shown is chosen to avoid apparently nonsensical displays like `[1.00000 != 1.00000]` +when comparing exactly unity against a value which is increased by just one least significant binary digit using +the default precision for float of just 6 decimal digits, given by + `std::numeric_limits::digits10`. The function used for the number of decimal +digits displayed is that proposed for a future C++ Standard, +http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf[A Proposal to add a max +significant decimal digits value], to be called `std::numeric_limits::max_digits10();`. +For 32-bit floats, 9 decimal digits are needed to ensure a single bit change produces a different decimal digit +string. + +So a much more helpful display using 9 decimal digits is thus: +`[1.00000000 != 1.00000012]` showing that the two values are in fact different. + +For {ieee754} 32-bit float values - 9 decimal digits are shown. For 64-bit {ieee754} double - 17 decimal digits. For +{ieee754} extended long double using 80-bit - 21 decimal digits. For {ieee754} quadruple long double 128-bit, and SPARC +extended long double 128-bit - 36 decimal digits. For floating-point types, a convenient formula to calculate +`max_digits10` is: `2 + std::numeric_limits::digits * 3010/10000`; + +[NOTE] +==== +Note that a user defined floating point type UDFPT must define + `std::numeric_limits::is_specialized = true` and provide an appropriate value + for `std::numeric_limits::digits`, the number of bits used for the significand + or mantissa. For example, for the SPARC extended long double 128, 113 bits are used for the significand (one of + which is implicit). +==== diff --git a/doc/modules/ROOT/pages/test_output/log_formats.adoc b/doc/modules/ROOT/pages/test_output/log_formats.adoc new file mode 100644 index 0000000000..a7d34d7c4a --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/log_formats.adoc @@ -0,0 +1,222 @@ += Log formats +:page-aliases: boost_test/test_output/log_formats.adoc + +The {utf} supports several log formats: + +* xref:test_output/log_formats.adoc#log_human_readable_format[HRF]: human readable format +* xref:test_output/log_formats.adoc#log_xml_format[XML]: an machine interpretable log format +* xref:test_output/log_formats.adoc#log_junit_format[JUNIT]: a standardized log format +understandable by automated tools such as Continuous Builds + +== Design + +The following functionalities are supported by the logging framework: + +* each logger manages its own log level. The rationale is that some log format are meant for +automated processing, and by design need to carry all the information that will later be digested +by a visualization tool. +* several log format may be active at the same time. The rationale is that the user might want to +see a non-exhaustive log in his terminal using a human friendly format, while having a detailed +full log in a file with a format dedicated to automated processing. +* each logger _indicates_ its default output stream. some logger may prefer to output to one of the standard +stream while other may prefer output to a file. + +NOTE: The logger indicates the default output stream in case the default should be used. + +== Defaults + +By default the active log level threshold is set to + +* xref:test_output/log_formats.adoc#test_log_output["non fatal error messages"] and the test log output +is generated in xref:test_output/log_formats.adoc#log_human_readable_format[human readable format]. +* xref:test_output/log_formats.adoc#test_log_output["general information"] for +xref:test_output/log_formats.adoc#log_junit_format[JUNIT] log format + +The active log level threshold and the output format can be configured +at runtime during a test module invocation and at compile time from within a test module using the +xref:test_output/logging_api.adoc[test log public interfaces]. The behavior is logger specific though. + +[#test_log_output] +== Test log output + +The test log is produced during the test execution. All entries in the test log are assigned a particular log +level. Only the entries with level that exceeds the _active log level threshold_ actually +appear in the test log output. Log levels are arranged by the 'importance' of the log entries. Here is +the list of all levels in order of increasing 'importance': + +[#test_log_output_table] +[#id_messages] +.Messages +[%header%autowidth,cols="2*"] +|=== +|Notifications +|Meaning + +|Success +|This category includes messages that provide information on successfully passed assertions + +|Test tree traversal +|This category includes messages that are produced by the {utf} core and indicate which test suites/cases are currently being executed or skipped + +|General information +a| +This category includes general information messages produced in most cases by a test module author using the + macro {boost_test_message} + +|Warning +|This category includes messages produced by failed `WARNING` level assertions + +|Non fatal error +|This category includes messages produced by failed `CHECK` level assertions + +|Uncaught C++ exceptions +a| +This category includes messages that are produced by the {utf} and provide detailed information on the C++ + exceptions uncaught by the test case body. + +|Non-fatal system error +a| +This category includes messages that are produced by the {utf} itself and provides information about caught + non-fatal system error. For example it includes messages produced in the case of test case timeout or if + floating point values calculation errors are caught. + +|Fatal system error +a| +This category includes messages produced by failed require level assertions and by the {utf} itself in case of + abnormal test case termination. + +|=== + +[NOTE] +==== +The active log level works namely as threshold, not as selector. For the given active log level threshold, all + test log entries with _importance_ higher than threshold are enabled and all test log entries with + _importance_ below threshold are disabled. +==== + +In addition to the levels described above the test log defines two special log levels. The current log level can +be set to: + +* All messages + ++ +If active log level threshold is set to this value, all test log entries appear in the output. In practice +this is equivalent to setting the active log level threshold to _success information messages_ +* Nothing + ++ +If the active log level threshold is set to this value, none of test log entries appear in the output. This log level +is used to execute a _silent_ test that doesn't produce any test log and only generates a result code indicating +whether test failed or passed. + +[#log_human_readable_format] +== HRF: Human readable log format + +The human readable log format is designed to closely match an errors description produced by the Microsoft family +of C++ compilers. This format allows jumping to the error location, if test module output is redirected into IDE +output window. The rest of the log messages are designed to produce the most human friendly description of the +events occurring in test module. This is a default format generated by test modules. + +Here the list of events along with corresponding message and the condition that has to be satisfied for it to appear +in the output. + +[%header%autowidth,cols="3*"] +|=== +|Event +|Condition +|Output + +|On testing start +|threshold != log_nothing +|`Running test case(s) ...` + +|On testing start +|threshold != log_nothing, show_build_info is set +a| +.... +Platform: $BOOST_PLATFORM +Compiler: $BOOST_COMPILER +STL : $BOOST_STDLIB +Boost : $BOOST_VERSION +.... + +|On abnormal testing termination +|threshold <= log_messages +|`Test is aborted` + +|On test unit start +|threshold <= log_test_units +|`Entering test ` + +|On test unit end +|threshold <= log_test_units; testing time is reported only if elapsed time is more than 1 us. +|`Leaving test ; testing time ` + +|On skipped test unit +|threshold <= log_test_units +|`Test is skipped` + +|On uncaught C++ exception +|threshold <= log_cpp_exception_errors. Checkpoint message is reported only if provided +|`unknown location(0): fatal error in : : last checkpoint: ` + +|On resumable system error +|threshold <= log_system_errors. Checkpoint message is reported only if provided +|`unknown location(0): fatal error in : : last checkpoint: ` + +|On fatal system error +|threshold <= log_fatal_errors. Checkpoint message is reported only if provided +|`unknown location(0): fatal error in : : last checkpoint: ` + +|On passed test assertion +|threshold <= log_successful_tests +|`: info: check passed` + +|On failed WARNING level test assertion +|threshold <= log_warnings +|`: warning in : condition is not satisfied` + +|On failed CHECK level test assertion +|threshold <= log_all_errors +|`: error in : check failed` + +|On failed REQUIRE level test assertion +|threshold <= log_fatal_errors +|`: fatal error in : critical check failed` + +|On test log message +|threshold <= log_messages +|`` + +|=== + +The level of details concerning the error message depends on the xref:testing_tools/index.adoc[testing tool] producing the log entry. + +[#log_xml_format] +== XML log format + +This log format is designed for automated test results processing. The test log output XML schema depends on the +active log level threshold. + +[#log_junit_format] +== JUNIT log format + +The http://junit.org/[JUNIT format] is log format supported by a wide range of Continuous Build/Integration tools. + +This format defaults its log level to xref:test_output/log_formats.adoc#test_log_output_table[`General information`] and its default stream to a file named after +xref:tests_organization/master_test_suite.adoc[master test suite]. +The logger will attempt to not overwrite any existing output file, which is also usually understood by Continuous Build tools. + +This format is in fact both a log and a report format: most of the Continuous Build tools will summarize +the content of a JUNIT file and show an overview of the failing/succeeding tests of a module (report format) +while letting the user inspect the detailed logs (log format). + +[CAUTION] +==== +The minimal log-level for the JUnit logger is xref:test_output/log_formats.adoc#test_log_output_table[`non fatal error`]. + Any set-up to higher log level will default to that minimal log-level. +==== + +[NOTE] +==== +Until Boost 1.64, the log level was previously defaulting to `success` and was causing a heavy load + on the logging part in some circumstances. +==== diff --git a/doc/modules/ROOT/pages/test_output/logging_api.adoc b/doc/modules/ROOT/pages/test_output/logging_api.adoc new file mode 100644 index 0000000000..9c500a6fe2 --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/logging_api.adoc @@ -0,0 +1,149 @@ += Logging API +:page-aliases: boost_test/test_output/logging_api.adoc + +While many test log configuration tasks can be performed at runtime using predefined framework parameters, the +{utf} provides a compile time interface as well. The interface gives you full power over what, where and how to +log. The interface of the logger is provided by singleton class cpp:boost::unit_test::unit_test_log_t[boost::unit_test::unit_test_log_t] and is +accessible through local file scope reference to single instance of this class + +[source,cpp] +---- +boost::unit_test::unit_test_log +---- + +In order to install customization of the logger, the {utf} provides the {boost_test_global_configuration} facility +that acts in a similar fashion to a global fixture. + +[#log_ct_output_stream_redirection] +== Log output stream redirection + +If you want to redirect the test log output stream into something different from the logger default output stream +(usually `std::cout`, `std::cerr` or a file), use the following interface: + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_stream( std::ostream& ); +---- + +or for a particular log format: + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_stream( boost::unit_test::output_format, std::ostream& ); +---- + +TIP: See cpp:boost::unit_test::unit_test_log_t::set_stream[boost::unit_test::unit_test_log_t::set_stream] and cpp:boost::unit_test::output_format[boost::unit_test::output_format] for more details + +You can reset the output stream at any time both during the test module initialization and from within test +cases. There are no limitations on number of output stream resets neither. + +[WARNING] +==== +If you redirect test log output stream from global fixture setup, you are *required* to reset it back to `std::cout` + during teardown to prevent dangling references access +==== + +// tag reference: doc/modules/ROOT/examples/example50.run-fail.cpp +:bt-name: example50 +:bt-rule: run-fail +:bt-descr: Compile-time log output redirection +include::partial$bt_example.adoc[] + +[#log_ct_log_level] +== Log level configuration + +[#ref_log_level_explanations] +If you need to enforce specific log level from within your test module use the following interface: + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_level ); +---- + +or for a specific logger: + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::output_format, boost::unit_test::log_level ); +---- + +TIP: See cpp:boost::unit_test::unit_test_log_t::set_threshold_level[boost::unit_test::unit_test_log_t::set_threshold_level] and cpp:boost::unit_test::output_format[boost::unit_test::output_format] for more details + +In regular circumstances you shouldn't use this interface, since you not only override default log level, but also +the one supplied at test execution time. Prefer to use runtime parameters +xref:utf_reference/rt_param_reference.adoc#log_level[`--log_level`] or xref:utf_reference/rt_param_reference.adoc#logger[`--logger`] +for log level selection. + +// tag reference: doc/modules/ROOT/examples/example51.run.cpp +:bt-name: example51 +:bt-rule: run +:bt-descr: Compile-time log level configuration +include::partial$bt_example.adoc[] + +[#log_ct_log_format] +== Predefined log format selection + +The select at compile time the log format from the list of the formats supplied by the {utf} + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_format( boost::unit_test::output_format ); +---- + +or for adding a format: + +[source,cpp] +---- +boost::unit_test::unit_test_log.add_format( boost::unit_test::output_format ); +---- + +CAUTION: cpp:boost::unit_test::unit_test_log_t::set_format[boost::unit_test::unit_test_log_t::set_format] above disables all formatters but the one provided as argument. + +TIP: See cpp:boost::unit_test::unit_test_log_t::set_format[boost::unit_test::unit_test_log_t::set_format] and cpp:boost::unit_test::output_format[boost::unit_test::output_format] for more details + +In regular circumstances you shouldn't use this interface. Prefer to use runtime parameters +xref:utf_reference/rt_param_reference.adoc#log_format[`--log_format`] or xref:utf_reference/rt_param_reference.adoc#logger[`--logger`] +for predefined log format selection. + +// tag reference: doc/modules/ROOT/examples/example52.run-fail.cpp +:bt-name: example52 +:bt-rule: run-fail +:bt-descr: Compile-time log format selection +include::partial$bt_example.adoc[] + +[#custom_log_formatter] +== Custom log format support + +[#ref_log_formatter_api] +It is possible to implement your own formatter: it should derive from cpp:boost::unit_test::unit_test_log_formatter[boost::unit_test::unit_test_log_formatter]. + +It is possible to add a your own instance of a formatter to the set of formats using one of the two functions: + +[source,cpp] +---- +boost::unit_test::unit_test_log.set_formatter( unit_test_log_formatter* ); +boost::unit_test::unit_test_log.add_formatter( unit_test_log_formatter* ); +---- + +[TIP] +==== +See cpp:boost::unit_test::unit_test_log_t::set_formatter[boost::unit_test::unit_test_log_t::set_formatter] and cpp:boost::unit_test::unit_test_log_t::add_formatter[boost::unit_test::unit_test_log_t::add_formatter] + for more details +==== + +[WARNING] +==== +The call to `boost::unit_test::unit_test_log.set_formatter` is equivalent to + cpp:boost::unit_test::unit_test_log_t::set_format[boost::unit_test::unit_test_log_t::set_format] (xref:test_output/logging_api.adoc#log_ct_log_format[see here]) + as it disables all other formatters. +==== + +[TIP] +==== +More details about the class implementing the formatting of the logs can be found in the following reference sections: + +* cpp:boost::unit_test::unit_test_log_formatter[boost::unit_test::unit_test_log_formatter] defines the interface for all loggers. Built-in +xref:test_output/log_formats.adoc#log_human_readable_format[HRF], xref:test_output/log_formats.adoc#log_xml_format[XML] +and xref:test_output/log_formats.adoc#log_junit_format[JUNIT] loggers derive from this class +* cpp:boost::unit_test::test_results[boost::unit_test::test_results] defines the information carried by the tests to provide reports and logs. +==== diff --git a/doc/modules/ROOT/pages/test_output/report_formats.adoc b/doc/modules/ROOT/pages/test_output/report_formats.adoc new file mode 100644 index 0000000000..56de5b0d7f --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/report_formats.adoc @@ -0,0 +1,90 @@ += Report formats +:page-aliases: boost_test/test_output/report_formats.adoc + +[#report_human_readable_format] +== Human readable report format + +[#ref_report_formats] +The human readable report format is designed to produce the most human friendly description of the +results of a test module testing. This is a default format generated by test modules. + +Depending on the framework's report level the output looks like this: + +[%header%autowidth,cols="2*"] +|=== +|Level +|Output + +|no report +a| +On this level the framework does not produce result report at all. It make sense + to use this level for test modules running unattended (as part of some automated regression + testing system, for example) + +|Confirmation +a| +[cols="1,3"] +|=== +|Passing test +a| +\*** No errors detected + +|Skipped test +a| +\*** The test suite was skipped; see standard output for details + +|Aborted test +a| +\*** The test suite was aborted; see standard output for details + +|Failed test without failed assertions +a| +\*** Errors were detected in the test suite ; see standard output for details + +|Failed test +a| +\*** N failures are detected in test suite + +|Failed test with some failures expected +a| +\*** N failures are detected (M failures are expected) in test suite + +|=== + +|Detailed +a| +On this level we report result for each test units hierarchically (each test unit is reported as part of parent test unit + report. Test cases are reported like this: + +.... +Test case/suite has passed/was skipped/was aborted/has failed/ with: + N assertions out of M passed + N assertions out of M failed + N warnings out of M failed + X failures expected +.... + +Only relevant lines will appear. If test case does not have failing assertions corresponding line in the report is not shown. + +Test suite in addition to above lines also report these: + +.... +N test cases out of M passed + N test cases out of M passed with warnings + N test cases out of M failed + N test cases out of M skipped + N test cases out of M aborted +.... + +And similarly to above lines only relevant ones will appear in output. + +|Short +|Short report format is similar to detailed, but only reports information for master test suite + +|=== + +[#report_xml_format] +== XML based report output format + +This report format is designed for automated test results processing. The result report output XML schema +depends on the report level. diff --git a/doc/modules/ROOT/pages/test_output/summary.adoc b/doc/modules/ROOT/pages/test_output/summary.adoc new file mode 100644 index 0000000000..d6aab04b2d --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/summary.adoc @@ -0,0 +1,30 @@ += Summary of the API for controlling the output +:page-aliases: boost_test/test_output/summary.adoc + +[%header%autowidth,cols="2*"] +|=== +|Macro +|Short description + +|{boost_test_message} +|Custom message output + +|{boost_test_dont_print_log_value} +|Disabling the printing of a specific type in case of test failure + +|{boost_test_checkpoint} +|Indicates a named checkpoint that will be printed in case of failure + +|{boost_test_passpoint} +|Indicates an unnamed checkpoint that will be printed in case of failure + +|{boost_test_info} +|Defines a message to be printed as part of the context of the first encountered assertion, if it fails + +|{boost_test_context} +|Defines a scope and a message to be printed as part of the context of every failed assertion within the scope + +|{boost_test_info_scope} +|Defines a sticky scoped version of {boost_test_info} that is attached to all the assertions coming after this declaration and within the current scope. + +|=== diff --git a/doc/modules/ROOT/pages/test_output/test_output_progress.adoc b/doc/modules/ROOT/pages/test_output/test_output_progress.adoc new file mode 100644 index 0000000000..dd74324eae --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/test_output_progress.adoc @@ -0,0 +1,36 @@ += Progress display +:page-aliases: boost_test/test_output/test_output_progress.adoc + +In case if the test module involves lengthy computation split among multiple test cases you may be interested in +progress monitor. The test runners supplied with the {utf} support simple text progress display, implemented based +on + +[source,cpp] +---- +boost::progress_display +---- + +footnote:[The {utf} interfaces allow implementing an advanced GUI based test runner with arbitrary progress display controls]. + +The progress display output is enabled using the {utf} parameter +xref:utf_reference/rt_param_reference.adoc#show_progress[`show_progress`]. + +The {utf} has no ability to estimate how long (in time duration) the test case execution is going to take and the manual test +progress update is not supported at this point. The {utf} tracks the progress on test case level. If you want to +see more frequent progress update, you need to split the test into multiple test cases. + +In default configuration both test log and test progress outputs are directed into standard output stream. Any test +log messages are going to interfere with test progress display. To prevent this you can either set log level to +lower level or redirect either test log or test progress output into different stream during test module +initialization. Use following interface to redirect test progress output: + +[source,cpp] +---- +boost::unit_test::progress_monitor.set_stream( std::ostream& ) +---- + +// tag reference: doc/modules/ROOT/examples/example49.run.cpp +:bt-name: example49 +:bt-rule: run +:bt-descr: Progress report for the test module with large amount of test cases +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc new file mode 100644 index 0000000000..a474d29b27 --- /dev/null +++ b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc @@ -0,0 +1,87 @@ += Tools supports for logging +:page-aliases: boost_test/test_output/test_tools_support_for_logging.adoc + +[#testing_tool_output_disable] +== Logging user defined types + +Most of the xref:testing_tools/index.adoc[testing tools] print values of their +arguments to the output stream in some form of log statement. If arguments type does not support + +[source,cpp] +---- +operator<<(std::ostream&, ArgumentType const&); +---- + +interface, you will get a compilation error. + +The {utf} supports three different methods for logging user defined types: + +. through the `operator<<` for that specific type: any type that implements the above interface has direct support for +logging, +. through a customization point responsible for logging a specific type, which is less intrusive than the implementation +of `operator<<`. This is explained in more details in xref:test_output/test_tools_support_for_logging.adoc#ref_log_output_custom_customization_point[this section], +. by prohibiting the xref:testing_tools/index.adoc[testing tools] from logging argument values for +specified type through {boost_test_dont_print_log_value}. +This is explained in more details in xref:test_output/test_tools_support_for_logging.adoc#ref_log_output_custom_avoid_printing[this section]. + +[#ref_log_output_custom_customization_point] +=== User type customization point for logging + +It is possible to indicate a function, `boost_test_print_type`, to {utf} that is responsible for the printing of a user defined type, without +the need to override the `operator<<` for that specific type. This is convenient for instance when +the `operator<<` has already been defined for other needs. + +The syntax follows the `operator<<`, and this function should be in the same namespace as the type: + +[source,cpp] +---- +std::ostream& boost_test_print_type(std::ostream& ostr, ArgumentType const& right); +---- + +// tag reference: doc/modules/ROOT/examples/logger-customization-point.run-fail.cpp +:bt-name: logger-customization-point +:bt-rule: run-fail +:bt-descr: Logging customization point usage +include::partial$bt_example.adoc[] + +[#ref_log_output_custom_avoid_printing] +=== Prohibiting the printing of a specific type + +To prohibit the printing of a specific type, use the following statement on file level before first +test case that includes statement failing to compile: + +[source,cpp] +---- +BOOST_TEST_DONT_PRINT_LOG_VALUE(ArgumentType) +---- + +// tag reference: doc/modules/ROOT/examples/example32.run-fail.cpp +:bt-name: example32 +:bt-rule: run-fail +:bt-descr: BOOST_TEST_DONT_PRINT_LOG_VALUE usage +include::partial$bt_example.adoc[] + +[#test_output_macro_message] +== Custom messages + +The macro {boost_test_message} is intended to be used for the purpose of injecting an additional message into the +{utf} test log. These messages are not intended to indicate any error or warning conditions, but rather as +information/status notifications. The macro signature is as follows: + +{boost_test_message}(test_message); + +The test_message argument can be as simple as C string literal or any custom expression that you can produce with in a +manner similar to standard `std::iostream` operation. + +[IMPORTANT] +==== +Messages generated by this tool do not appear in test log output with default value of the active log level + threshold. For these messages to appear the active log level threshold has to be set to a value below or equal + to "message". +==== + +// tag reference: doc/modules/ROOT/examples/example21.run.cpp +:bt-name: example21 +:bt-rule: run +:bt-descr: {boost_test_message} usage +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/bitwise.adoc b/doc/modules/ROOT/pages/testing_tools/bitwise.adoc new file mode 100644 index 0000000000..8f133ab039 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/bitwise.adoc @@ -0,0 +1,15 @@ += Bitwise comparison +:page-aliases: boost_test/testing_tools/extended_comparison/bitwise.adoc + +CAUTION: this feature is not available for non C++11 compilers. + +The manipulator cpp:boost::test_tools::bitwise[boost::test_tools::bitwise] can be provided to the {boost_test} macro in order to have a bitwise comparison +of the operands. In that case, the {utf} indicates the bit indices where the two operands do not match. + +// tag reference: doc/modules/ROOT/examples/boost_test_bitwise.run-fail.cpp +:bt-name: boost_test_bitwise +:bt-rule: run-fail +:bt-descr: BOOST_TEST bitwise comparison +include::partial$bt_example.adoc[] + +NOTE: the indices start at least significant bit. diff --git a/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc b/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc new file mode 100644 index 0000000000..2424f2915b --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc @@ -0,0 +1,105 @@ += BOOST_TEST: universal and general purpose assertions +:page-aliases: boost_test/testing_tools/boost_test_universal_macro.adoc + +The {utf} provides an almost unique interface to a great range of test-case scenarios, through the {boost_test} +macro. The general form of `BOOST_TEST` is the following: + +BOOST_TEST(statement); + BOOST_TEST_(statement, optional_modifiers) + +An example of use might be the following: + +// tag reference: doc/modules/ROOT/examples/boost_test_macro_overview.run-fail.cpp +:bt-name: boost_test_macro_overview +:bt-rule: run-fail +:bt-descr: BOOST_TEST overview +include::partial$bt_example.adoc[] + +The major features of this tool are: + +* a great flexibility for `statement` which may be almost anything: full expression composed by several operations are supported +and handled, +* an extended reporting capability in case of failure: not only `BOOST_TEST` reports the location of the failure and a copy of `statement` itself, +but also the values of the operands that permits a rapid identification of the issues related to the failed assertion, +* the possibility to control better the behavior or the reports of the checks, in particular: +** floating point comparison: the tolerance may be provided, either using the `BOOST_TEST` +directly with `optional_modifiers`, or with _decorators_ (see xref:testing_tools/floating_point.adoc[here] +for more details), +** container/collection comparisons: different operations for comparison are provided out of the box for comparing collection of +elements (default, per-element, lexicographic), with extended diagnostic on failures (covered in +xref:testing_tools/collections.adoc[this] section), +** string comparison: C-strings operands are automatically detected and the comparisons are performed as if `std::string` objects +were used, +** optional failure message, +** bitwise comparison, providing extended diagnostic in case of failure + +[WARNING] +==== +To get all the functionalities of `BOOST_TEST` family of assertions, a C++11 capable compiler is required, especially + supporting the `auto` and `decltype` keywords and the variadic macros. The documentation focuses on these set of compilers. + For compilers not supporting all the features of `BOOST_TEST`, the macro `BOOST_TEST_MACRO_LIMITED_SUPPORT`. +==== + +[#boost_test_statement_overloads] +== Complex statements + +`BOOST_TEST` provides an enhanced reporting capability: additional details of the failing operands and operations are provided in the log, +as shown on the example below: + +// tag reference: doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp +:bt-name: boost_test_macro3 +:bt-rule: run-fail +:bt-descr: BOOST_TEST enhanced reporting +include::partial$bt_example.adoc[] + +`BOOST_TEST` parses the `statement` and constructs an expression out of it. `statement` may be a complex expressions +containing almost any of the overloadable operators in C++: + +[%header%autowidth,cols="2*"] +|=== +|Class of operation +|operators + +|binary comparisons +|`==`, `!=`, `<`, `>`, `<=`, `>=` + +|arithmetic compositions +|`+`, `-`, `+*+`, `/`, `%` + +|bitwise compositions +|`\|`, `&`, `+^+`, `<<`, `>>` + +|assignments +|`=`, `+=`, `-=`, `+*=+`, `/=`, `%=`, `<<=`, `>>=`, `&=`, `+^=+`, `\|=` + +|=== + +`statement` is evaluated and cast to `bool`, as if it would appear as argument to an `if` statement: this is the result of the assertion + +== Uniform reporting + +This tool is provided in three variants corresponding to the corresponding +xref:testing_tools/tools_assertion_severity_level.adoc[severity levels]. These three levels of assertions are +reported into the test log and output, as described in details in the section. The granularity of the +report depends on the current xref:utf_reference/rt_param_reference.adoc#log_level[log level] and +xref:utf_reference/rt_param_reference.adoc#report_level[report level]. + +[#boost_test_statement_limitations] +== Limitations & workaround + +There are a few constructions that are however unsupported, but adding an extra bracket usually solves that: + +* statements containing ternary conditions: those statement should be surrounded by parenthesis as they cannot be overloaded +* statements containing commas: those statements will be intercepted by the preprocessor +* compound statements containing any logical composition `||`, `&&`. Those are disabled intentionally and should be surrounded +by parenthesis ++ +BOOST_TEST((true || false)); ++ +The full details are given in xref:testing_tools/internal_details.adoc[this section]. + +// tag reference: doc/modules/ROOT/examples/boost_test_macro_workaround.run.cpp +:bt-name: boost_test_macro_workaround +:bt-rule: run +:bt-descr: BOOST_TEST limitation and workaround +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/collections.adoc b/doc/modules/ROOT/pages/testing_tools/collections.adoc new file mode 100644 index 0000000000..09cc76e301 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/collections.adoc @@ -0,0 +1,262 @@ += Collections comparison +:page-aliases: boost_test/testing_tools/extended_comparison/collections.adoc + +Instead of comparing a single value against another, there is often a need for comparing _collections_ of values. +A collection and indirectly the values it contains may be considered in several ways: + +* collection as a _sequence of values_: this is the case for instance when `N` values are stored in a +container. Containers in this case are used for storing several values, and iterating over the containers yields +sequences that can be compared *element-wise*. The iteration should be in an order that is _a priori_ known +footnote:[this might not be the case +for e.g. `std::unordered_map`, for which the buckets might be filled differently depending on the insertion order.], +for being able to compare the sequences. The values in the collection are independent each other, and subsets can be compared as well. +* collection as an _ensemble_: this is the case where the elements of the collection define an _entity_, +and no element can be dissociated from the others. +An example would be a collection of letters for a specific word in the natural language; in this settings +any of the character in the word/collection depends _semantically_ on the other and it is not possible to take +a subset of it without breaking the meaning of the word. Another example would be a vector of size `N` representing a +point in a `N` dimensional space, compared to another point with the relation "`<`": the comparison is application +specific and a possible comparison would be the lexicographical ordering +footnote:[in this case `v_a < v_b` means that the point `v_a` is inside the rectangle (origin, `v_b`)]. + +The following observations can be done: + +* the methods employed for comparing collections should be chosen adequately with the meaning of the collection, +* comparing sequences *element-wise* often involves writing loops in the test body, and if a dedicated tool is already in place +the test body would gain in clarity and expressiveness (including the report in case of failure), +* some comparison methods such as the lexicographical one, have good general behavior (e.g. total ordering, +defined for collections of different size), but are sometimes inappropriate. + +{boost_test} provides specific tools for comparing collections: + +* using the _native_ footnote:[either defined by the container or by the user] operator of the container of the collection, +which is mentioned as the xref:testing_tools/collections.adoc#ref_boost_test_coll_default_comp[_default behavior_]. +* using xref:testing_tools/collections.adoc#boost_test_coll_perelement[element-wise] comparison for which extended failure diagnostic is provided, +* and using xref:testing_tools/collections.adoc#boost_test_coll_default_lex[lexicographical] comparison for which extended failure diagnostic is provided, + +More details about the concept of _collection_ in the {utf} is given xref:testing_tools/collections.adoc#what_is_a_collection[_here_]. + +[#ref_boost_test_coll_default_comp] +== Default comparison + +The default comparison dispatches to the existing overloaded comparison operator. The {utf} distinguishes two use cases + +. none of the comparison operand is a C-Array, in which case we use the xref:testing_tools/collections.adoc#ref_boost_test_coll_default_comp_container[container default behavior] +. one of the comparison operand is a C-array, in which case we xref:testing_tools/collections.adoc#ref_boost_test_coll_c_arrays[mimic `std::vector`] behavior + +[#ref_boost_test_coll_default_comp_container] +=== Container default behavior + +Given two containers `c_a` and `c_b` that are not C-arrays, + +[source,cpp] +---- +BOOST_TEST(c_a op c_b) +---- + +is equivalent, in terms of test success, to + +[source,cpp] +---- +auto result = c_a op c_b; +BOOST_TEST(result); +---- + +In the example below, `operator==` is not defined for `std::vector` of different types, and the program would fail to +compile if the corresponding lines were uncommented (`std::vector` uses lexicographical comparison by default). + +[NOTE] +==== +In the case of default comparison, there is no additional diagnostic provided by the {utf}. See the section +xref:testing_tools/collections.adoc#ref_boost_test_coll_special_macro[`BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE`] below. +==== + +// tag reference: doc/modules/ROOT/examples/boost_test_container_default.run-fail.cpp +:bt-name: boost_test_container_default +:bt-rule: run-fail +:bt-descr: BOOST_TEST containers comparison default +include::partial$bt_example.adoc[] + +[#ref_boost_test_coll_c_arrays] +=== C-arrays default behavior + +As soon as one of the operands is a C-array, there is no _default behavior_ the {utf} can dispatch to. +This is why in that case, the comparison mimics the `std::vector` behavior. + +// tag reference: doc/modules/ROOT/examples/boost_test_macro_container_c_array.run-fail.cpp +:bt-name: boost_test_macro_container_c_array +:bt-rule: run-fail +:bt-descr: BOOST_TEST C-arrays +include::partial$bt_example.adoc[] + +[#boost_test_coll_perelement] +== Element-wise comparison + +By specifying the manipulator cpp:boost::test_tools::per_element[boost::test_tools::per_element], the comparison of the elements of the containers +are performed _element-wise_, in the order given by the forward iterators of the containers. This is a comparison on +the _sequences_ of elements generated by the containers, for which the {utf} provides advanced diagnostic. + +In more details, let `c_a = (a_1,... a_n)` and `c_b = (b_1,... b_n)` be two sequences of same length, but not necessarily of same type. +Those sequences correspond to the content of the respective containers, in the order given by their iterator. Let +`op` be one of the xref:testing_tools/boost_test_universal_macro.adoc#boost_test_statement_overloads[binary comparison operators]. + +[source,cpp] +---- +BOOST_TEST(c_a op c_b, boost::test_tools::per_element() ); +---- + +is equivalent to + +[source,cpp] +---- +if(c_a.size() == c_b.size()) +{ + for(int i=0; i < c_a.size(); i++) + { + BOOST_TEST_CONTEXT("index " << i) + { + BOOST_TEST(a_i op b_i); + } + } +} +else +{ + BOOST_TEST(c_a.size() == c_b.size()); +} +---- + +WARNING: this is fundamentally different from using the containers' default comparison operators (default behavior). + +[WARNING] +==== +this is not an order relationship on containers. As a side effect, it is possible to have + `BOOST_TEST(c_a == c_b)` and `BOOST_TEST(c_a != c_b)` failing at the same time +==== + +Sequences are compared using the specified operator `op`, evaluated on the left and right elements of the respective sequences. +The order of the compared elements is given by the iterators of the respective containers footnote:[the containers should yield the same +sequences for a fixed set of elements they contain]. +In case of failure, the indices of the elements failing `op` are returned. + +// tag reference: doc/modules/ROOT/examples/boost_test_sequence_per_element.run-fail.cpp +:bt-name: boost_test_sequence_per_element +:bt-rule: run-fail +:bt-descr: BOOST_TEST sequence comparison +include::partial$bt_example.adoc[] + +=== Requirements + +For the sequences to be comparable element-wise, the following conditions should be met: + +* the containers should meet the xref:testing_tools/collections.adoc#what_is_a_collection[sequence] definition, +* the containers should yield the same number of elements, +* `op` should be one of the comparison operator `==`, `!=`, `<`, `<=`, `>`, `>=` +* the `a_i op b_i` should be defined, where the type of `a_i` and `b_i` are the type returned by the dereference operator +of the respective collections. + +[CAUTION] +==== +the resulting type of "`c_a == c_b`" is an cpp:boost::test_tools::assertion_result[assertion_result]: it is not + possible to compose more that one comparison on the `BOOST_TEST` statement: + +[source,cpp] +---- +BOOST_TEST(c_a == c_b == 42, boost::test_tools::per_element() ); // does not compile +---- +==== + +[#boost_test_coll_default_lex] +== Lexicographic comparison + +By specifying the manipulator cpp:boost::test_tools::lexicographic[boost::test_tools::lexicographic], the containers are compared using the _lexicographical_ +order and for which the {utf} provides additional diagnostic in case of failure. + +[source,cpp] +---- +BOOST_TEST(c_a op c_b, boost::test_tools::lexicographic() ); +---- + +The comparison is performed in the order given by forward iterators of the containers. + +[TIP] +==== +lexicographic comparison yields a total order on the containers: the statements `c_a < c_b` and + `c_b <= c_a` are mutually exclusive. +==== + +NOTE: The equality `==` and inequality `!=` are not available for this type of comparison. + +// tag reference: doc/modules/ROOT/examples/boost_test_container_lex.run-fail.cpp +:bt-name: boost_test_container_lex +:bt-rule: run-fail +:bt-descr: BOOST_TEST container comparison using lexicographical order +include::partial$bt_example.adoc[] + +[#ref_boost_test_coll_special_macro] +== Extended diagnostic by default for specific containers + +As seen above, + +* for testing equality, the `==` relation is either explicit (using `boost::test_tools::per_element()`) or +implicit when the container overloads/implements this type of comparison, +* for testing inequality, lexicographical comparison for `<` (and derived operations) is either explicit +(using `boost::test_tools::lexicographic()`) or implicit when +the container overloads/implements uses this type of comparison. + +When the default is to using the container implementation, it is not possible to benefit from an extended failure diagnostic. +The {utf} provides a mechanism for performing the same comparisons through the {utf} instead of the container operator, +through the macro `BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE` that might be used as follow: + +// tag reference: doc/modules/ROOT/examples/boost_test_container_lex_default.run-fail.cpp +:bt-name: boost_test_container_lex_default +:bt-rule: run-fail +:bt-descr: Default `std::vector` to lexicographic with extended diagnostic +include::partial$bt_example.adoc[] + +=== Requirements + +* the containers should meet the xref:testing_tools/collections.adoc#what_is_a_collection[sequence] definition, +* the containers should be of the exact same type +* `op` should be one of the comparison operator `==`, `!=`, `<`, `<=`, `>`, `>=` + +NOTE: Note that the operation `!=` is in this case not an element-wise comparison, + +[#what_is_a_collection] +== What is a sequence? + +A _sequence_ is given by the iteration over a _forward iterable_ container. A forward iterable container is: + +* either a C-array, +* or a `class`/`struct` that implements the member functions `begin` and `end`. + +For collection comparisons, both sequences are also required to be different than `string` sequences. In that case, the sequences are +dispatched to string xref:testing_tools/strings.adoc[comparison instead]. + +[WARNING] +==== +`string` (or `wstring`) meets the sequence concept by definition, but their handling with {boost_test} is done differently. + See xref:testing_tools/strings.adoc[Strings and C-strings comparison] for more details. +==== + +[TIP] +==== +If the behavior of {boost_test} is not the one you expect, you can always use raw comparison. See xref:testing_tools/boost_test_universal_macro.adoc#boost_test_statement_limitations[this section] + for details. +==== + +[NOTE] +==== +Since xref:change_log.adoc#ref_CHANGE_LOG_3_6[Boost.Test 3.6] (Boost 1.65) the requirements for the collection concepts have been relaxed to + include C-arrays as well +==== + +[NOTE] +==== +Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[Boost.Test 3.7] (Boost 1.67) the definition of `const_iterator` and `value_type` in the collection + type is not required anymore (for the compilers properly supporting `decltype`). +==== + +The detection of the types that meet these requirements containers is delegated to the class cpp:boost::unit_test::is_forward_iterable[boost::unit_test::is_forward_iterable], +which for C++11 detects the required member functions and fields. However for C++03, the types providing the sequences should be explicitly +indicated to the {utf} by a specialization of cpp:boost::unit_test::is_forward_iterable[boost::unit_test::is_forward_iterable] +footnote:[Standard containers of the `STL` are recognized as _forward iterable_ container.]. diff --git a/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc b/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc new file mode 100644 index 0000000000..20f0758337 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc @@ -0,0 +1,34 @@ += Custom predicate support +:page-aliases: boost_test/testing_tools/custom_predicates.adoc + +Even though supplied testing tools cover wide range of possible checks and provide detailed report on cause of error in +some cases you may want to implement and use custom predicate that perform complex check and produce intelligent report +on failure. To satisfy this need testing tools implement custom predicate support. There two layers of custom predicate +support implemented by testing tools toolbox: with and without custom error message generation. + +The first layer is supported by {boost_level_predicate} family of testing tools. You can use it to check any custom +predicate that reports the result as boolean value. The values of the predicate arguments are reported by the tool +automatically in case of failure. + +// tag reference: doc/modules/ROOT/examples/example30.run-fail.cpp +:bt-name: example30 +:bt-rule: run-fail +:bt-descr: Custom predicate support using {boost_level_predicate} +include::partial$bt_example.adoc[] + +To use second layer your predicate has to return {class_predicate_result}. + +This class encapsulates boolean result value along with any error or information message you opt to report. + +Usually you construct the instance of class {class_predicate_result} inside your predicate function and return it by +value. The constructor expects one argument - the boolean result value. The constructor is implicit, so you can simply +return boolean value from your predicate and {class_predicate_result} is constructed automatically to hold your value +and empty message. You can also assign boolean value to the constructed instance. You can check the current predicate +value by using `operator!` or directly accessing public read-only property `p_predicate_value`. The error message is +stored in public read-write property `p_message`. + +// tag reference: doc/modules/ROOT/examples/example31.run-fail.cpp +:bt-name: example31 +:bt-rule: run-fail +:bt-descr: Custom predicate support using class {class_predicate_result} +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/debugging.adoc b/doc/modules/ROOT/pages/testing_tools/debugging.adoc new file mode 100644 index 0000000000..27740beecb --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/debugging.adoc @@ -0,0 +1,39 @@ += Debugging the assertions +:page-aliases: boost_test/testing_tools/debugging.adoc + +In case you observe a failure in unit tests and you are using a debugger to determine the cause, +it may get really difficult to step into the expression inside an assertion. Because {boost_test} +builds an expression tree before evaluating it, the "Step Into" function of the debugger will have +to step into every step of building the expression tree before, you can go into the evaluation of +the expression. + +In order to mitigate the problem, the test module can be build in the mode which disables the +building of expression trees inside assertions. +In this mode, the first thing the assertion does is to eagerly evaluate the tested expression. +You enable this mode by defining symbol {boost_test_tools_under_debugger} (either with `+#define+` +or with compiler option `-D`) prior to including any of the {utf} headers. + +[CAUTION] +==== +When the eager evaluation of expressions is turned on, the expressions are evaluated +_literally_: this automatically disables any special semantics, + like tolerance for floating-point types or cpp:boost::test_tools::per_element[boost::test_tools::per_element] versions + of sequence comparisons. This may turn passing assertions into failing assertions and vice-versa. + In the case of cpp:boost::test_tools::per_element[boost::test_tools::per_element] comparisons of sequences, it may render an + ill-formed program, if the sequences of different types are being compared. +==== + +The inconvenience with {boost_test_tools_under_debugger} is that you have to recompile the test module. +The {utf} gives you another option to compile two versions of the assertions and select the one to be used dynamically +depending on whether the test module is run under debugger or not. +This mode is enabled by defining symbol {boost_test_tools_debuggable} (either with `+#define+` or with +compiler option `-D`) prior to the inclusion of any of the {utf} headers. + +In order to determine if the test module is run under debugger or not, function +cpp:boost::debug::under_debugger[`boost::debug::under_debugger`] is used. + +[CAUTION] +==== +At present, function cpp:boost::debug::under_debugger[`boost::debug::under_debugger`] +can correctly detect the debugger only on MSVC and a few Linux variants. +==== diff --git a/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc b/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc new file mode 100644 index 0000000000..1e8d1db3ec --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc @@ -0,0 +1,49 @@ += Exception correctness +:page-aliases: boost_test/testing_tools/exception_correctness.adoc + +Any unexpected/uncaught exception raised in the test case body will be intercepted by the Boost.test +framework and will result in the termination of the test-case with the status `failed`. + +// tag reference: doc/modules/ROOT/examples/exception_uncaught.run-fail.cpp +:bt-name: exception_uncaught +:bt-rule: run-fail +:bt-descr: Uncaught exception +include::partial$bt_example.adoc[] + +More control over the exception correctness is often required, for instance to test that +an expression is raising a specific exception, intentionally. + +The {utf} provides several assertions for testing a code with respect to the exceptions correctness. +The following assertions are available: + +* {boost_level_no_throw} checks that no exception is raised from an expression, +* {boost_level_throw} checks that an expression raises an exception of a specific type +* {boost_level_exception} checks that an expression raises an exception of a specific type, +a passes the exception instance to a predicate function for further validation (introspection +for instance) + +The following example demonstrate how to use these tools to test the correct behavior of the API +of `FileWordHistogram`, in the constructor and the preconditions of the member function. + +// tag reference: doc/modules/ROOT/examples/exception_api.run-fail.cpp +:bt-name: exception_api +:bt-rule: run-fail +:bt-descr: Exception correctness of an API +include::partial$bt_example.adoc[] + +[NOTE] +==== +An `assert(...)` might call `abort()`: the use of the macros above may not be + suitable for testing for `assert`'s in a portable manner. +==== + +== Bibliographic references + +.Publications +[cols="1,3"] +|=== +|https://isocpp.org/wiki/faq/exceptions[Exceptions and Error Handling] +a| +Standard C++ Foundation + +|=== diff --git a/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc b/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc new file mode 100644 index 0000000000..09c4ad089e --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc @@ -0,0 +1,93 @@ += Expected failures specification +:page-aliases: boost_test/testing_tools/expected_failures.adoc + +While in a perfect world all test assertions should pass in order for a test module to pass, in some situations +it is desirable to temporarily allow particular tests to fail. For example, where a particular feature is not +implemented yet and one needs to prepare a library for the release or when particular test fails on some +platforms. To avoid a nagging red box in regression tests table, you can use the expected failures feature. + +This feature allows specifying an expected number of failed assertions per test unit. The value is specified +during test tree construction, and can't be updated during test execution. + +The feature is not intended to be used to check for expected functionality failures. To check that a particular +input is causing an exception to be thrown use {boost_level_throw} family of testing +tools. + +The usage of this feature should be limited and employed only after careful consideration. In general you should +only use this feature when it is necessary to force a test module to pass without actually fixing the problem. +Obviously, an excessive usage of expected failures defeats the purpose of the unit test. In most cases it only +needs be applied temporarily. + +You also need to remember that the expected failure specification is per test case. This means that any failed +assertion within that test case can satisfy the expected failures quota. Meaning it is possible for an +unexpected failure to occur to satisfy this quota. + +[NOTE] +==== +If an assertion at fault is fixed and passed while an expected failures specification still present, + the number of failures becomes smaller than expected. The test is going to be reported as passed; instead, + a warning message will be issued. +==== + +[#l_expected_failure] +== Expected failure specification + +The decorator {decorator_expected_failures} defines the number of assertions that are expected to fail within the corresponding test +unit. It is reported as failure when the number of failed assertions is greater than the declared expected number of +failures. If the number of failed assertions is less than the number of expected failures a message is reported. The +total number of expected failures for a given test suite `S` is the sum of the declared expected failures in `S` and the +sum of expected failures in all nested test units: + +// tag reference: doc/modules/ROOT/examples/decorator_10.run-fail.cpp +:bt-name: decorator_10 +:bt-rule: run-fail +:bt-descr: decorator expected_failures +include::partial$bt_example.adoc[] + +In the above example, we first run all test cases with four failed assertions. The total number of expected failures +is 3: 1 (for test `suite1`) + 2 (for `test1`). Because the expected failure count is exceeded, the error is reported. +In the second case, we only run test case `suite1/test1`: two failures occur, two failures are expected, therefore no +error is reported. + +== Usage with automatically registered test cases + +[CAUTION] +==== +this usage is considered as deprecated. Please consider using the xref:testing_tools/expected_failures.adoc#l_expected_failure[`expected_failures`] + decorator instead. +==== + +For backwards compatibility, it is possible to indicate the expected failures with +{boost_auto_test_case_expected_failures} footnote:[deprecated] before the test case definition. + +[source,cpp] +---- +BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(test_case_name, number_of_expected_failures); +---- + +You can use this macro both on a file scope and inside a test suite. Moreover you can use it even if name of test +units coincide in different test suites. Expected failures specification applies to the test unit belonging to the same +test suite where {boost_auto_test_case_expected_failures} resides. + +// tag reference: doc/modules/ROOT/examples/example17.run.cpp +:bt-name: example17 +:bt-rule: run +:bt-descr: Expected failures specification for automatically registered test case +include::partial$bt_example.adoc[] + +== Usage with manually registered test cases + +[CAUTION] +==== +this usage is considered as deprecated. Please consider using the xref:testing_tools/expected_failures.adoc#l_expected_failure[`expected_failures`] + decorator instead. +==== + +To set the value of expected failures for the manually registered test unit pass it as a second argument for the +xref:tests_organization/test_suite.adoc#ref_test_case_registration[`test_suite::add`] call during test unit registration. + +// tag reference: doc/modules/ROOT/examples/example16.run.cpp +:bt-name: example16 +:bt-rule: run +:bt-descr: Expected failures specification for manually registered test case +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc new file mode 100644 index 0000000000..10be1b7670 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc @@ -0,0 +1,487 @@ += Floating point comparison +:page-aliases: boost_test/testing_tools/extended_comparison/floating_point.adoc + +Unless specified otherwise, when a value of floating-point type is compared inside a {boost_test} assertion, +operators `==`, `!=` , `<` etc. defined for this type are used. However for floating point type, in most cases what is needed is not an _exact_ +equality (or inequality), but a verification that two numbers are _sufficiently close_ or _sufficiently different_. For that purpose, a *tolerance* parameter +that will instruct the framework what is considered _sufficiently close_ needs to provided. + +NOTE: How the tolerance parameter is processed in detail is described xref:testing_tools/floating_point.adoc#floating_points_comparison_impl[here]. + +== Test-unit tolerance + +It is possible to define a per-xref:section_glossary.adoc#ref_test_unit[test unit] tolerance for a given floating point type by using +xref:tests_organization/decorators.adoc[decorator] {decorator_tolerance}: + +// tag reference: doc/modules/ROOT/examples/tolerance_01.run-fail.cpp +:bt-name: tolerance_01 +:bt-rule: run-fail +:bt-descr: specifying tolerance per test case +include::partial$bt_example.adoc[] + +== Assertion tolerance + +It is possible to specify floating point comparison tolerance per single assertion, by providing the _manipulator_ cpp:boost::test_tools::tolerance[boost::test_tools::tolerance] +as the second argument to {boost_test}: + +// tag reference: doc/modules/ROOT/examples/tolerance_02.run-fail.cpp +:bt-name: tolerance_02 +:bt-rule: run-fail +:bt-descr: specifying tolerance per assertion +include::partial$bt_example.adoc[] + +[CAUTION] +==== +Manipulators requires a compiler that supports variadic macros, `auto` for type deduction + and `decltype`. These are C++11 features, but are also available on some pre-C++11 compilers. On compilers that are + lacking these features, resort to defining tolerance per test unit or to compatibility test assertions: {boost_check_close} and {boost_check_small}. +==== + +== Tolerance expressed in percentage + +It is possible to specify the tolerance as percentage. At test unit level, the decorator syntax is: + +[source,cpp] +---- +* boost::unit_test::tolerance( boost::test_tools::fpc::percent_tolerance(2.0) ) +// equivalent to: boost::unit_test::tolerance( 2.0 / 100 ) +---- + +At assertion level, the manipulator syntax is: + +[source,cpp] +---- +2.0% boost::test_tools::tolerance() +boost::test_tools::tolerance( boost::test_tools::fpc::percent_tolerance(2.0) ) +// both equivalent to: boost::test_tools::tolerance( 2.0 / 100 ) +---- + +== Type of the tolerance + +Manipulator `tolerance` specifies the tolerance only for a single floating-point type. This type is deduced from form +the numeric value passed along the manipulator: + +[%header%autowidth,cols="2*"] +|=== +|expression +|semantics + +|`tolerance(0.5)` +|tolerance for type `double` changed to 0.5 + +|`tolerance(float(0.5))` +|tolerance for type `float` changed to 0.5 + +|`tolerance(0.5f)` +|tolerance for type `float` changed to 0.5 + +|`tolerance(0.5L)` +|tolerance for type `long double` changed to 0.5 + +|`tolerance(Decimal("0.5"))` +|tolerance for a user-defined type `Decimal` changed to the supplied value + +|`5.0% tolerance()` +|tolerance for type `double` changed to 0.05 (`5.0 / 100`) + +|`5.0f% tolerance()` +|tolerance for type `float` changed to 0.05 + +|`Decimal("5.0")% tolerance()` +|tolerance for type `Decimal` changed to value `(Decimal("5.0") / 100)` + +|=== + +This is also the case for decorator `tolerance`. In the case of the decorator however, it is possible to apply multiple +decorators `tolerance` defining the tolerance for different types. + +When values of two different floating point types `T` and `U` are compared, {boost_test} uses the tolerance +specified for type `boost::common_type::type`. For instance, when setting a tolerance for mixed `float`-to-`double` comparison, +the tolerance for type `double` needs to be set. + +Given two floating point types `T` and `U` and their common type `C`, the tolerance specified for type `C` is applied only when +types `T` and `U` appear as sub-expressions of the full expression inside assertion {boost_test}. It is not applied when +`T` and `U` are compared inside a function invoked during the evaluation of the expression: + +// tag reference: doc/modules/ROOT/examples/tolerance_05.run-fail.cpp +:bt-name: tolerance_05 +:bt-rule: run-fail +:bt-descr: tolerance applied to different types +include::partial$bt_example.adoc[] + +== Type promotion of the operands + +Given two types `T` and `U` being compared inside an assertion {boost_test}, tolerance based comparison is invoked + +. whenever the types `T` and `U` are both xref:testing_tools/floating_point.adoc#customizing_for_tolerance[tolerance based] types +. whenever `T` is _tolerance_ based and `U` is _arithmetic_, in the sense that `std::numeric_limits::value` evaluates to `true` (or the other way round) + +In all cases, the type of the tolerance is deduced as `boost::common_type::type`, and both type may be cast to this tolerance type. + +[NOTE] +==== +This behavior has been introduced in Boost 1.70 / {utf} xref:change_log.adoc#ref_CHANGE_LOG_3_10[3.10]. Previously tolerance based comparison was used only when the type of the two + operands were tolerance based types, which was silently ignoring the tolerance for expressions such as + +[source,cpp] +---- +double x = 1E-9; +BOOST_TEST(x == 0); // U is int +---- +==== + +// tag reference: doc/modules/ROOT/examples/tolerance_06.run-fail.cpp +:bt-name: tolerance_06 +:bt-rule: run-fail +:bt-descr: operands type promotion +include::partial$bt_example.adoc[] + +== Other relational operators + +Finally, note that comparisons for tolerance are also applied to `operator<` with semantics _less by more than some tolerance_, +and other relational operators. Also, the tolerance-based comparisons are involved when a more complicated expression tree is +processed within the assertion body. The section on +relational operators // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.extended_comparison.floating_point.floating_points_comparison_impl.tolerance_in_operator +defines how `operator<` relates to tolerance. + +// tag reference: doc/modules/ROOT/examples/tolerance_03.run-fail.cpp +:bt-name: tolerance_03 +:bt-rule: run-fail +:bt-descr: tolerance applied in more complex expressions +include::partial$bt_example.adoc[] + +[#customizing_for_tolerance] +== Enabling tolerance for user-defined types + +The {utf} recognizes that a given type `T` is suitable for tolerance-based comparisons using the expression +cpp:boost::math::fpc::tolerance_based[boost::math::fpc::tolerance_based]`::value`. This meta-function already returns `true` for built-in +floating-point types as well as any other types that match the following compile-time expression: + +[source,cpp] +---- +boost::is_floating_point::value || + ( std::numeric_limits::is_specialized && + !std::numeric_limits::is_integer && + !std::numeric_limits::is_exact) +---- + +If you require your type to also participate in tolerance-based comparisons, regardless of the above expression, +you can just specialize cpp:boost::math::fpc::tolerance_based[boost::math::fpc::tolerance_based] for your type directly, and derive it from +`boost::true_type`. Your type does not even have to be a floating-point type provided that it models concept +xref:testing_tools/floating_point.adoc#concept_tolerance_based[`ToleranceCompatible`]. + +// tag reference: doc/modules/ROOT/examples/tolerance_04.run-fail.cpp +:bt-name: tolerance_04 +:bt-rule: run-fail +:bt-descr: adapting user-defined types for tolerance-based comparison +include::partial$bt_example.adoc[] + +[#concept_tolerance_based] +=== Concept `ToleranceCompatible` + +==== Refinement of + +https://en.cppreference.com/w/cpp/named_req/MoveConstructible[`MoveConstructible`], +https://en.cppreference.com/w/cpp/named_req/EqualityComparable[`EqualityComparable`], +https://en.cppreference.com/w/cpp/named_req/LessThanComparable[`LessThanComparable`] + +==== Notation + +[%header%autowidth,cols="2*"] +|=== +| +| + +|`T` +|A type that is a model of `ToleranceCompatible` + +|`x`, `y` +|objects of type `T` + +|`i`, `j` +|objects of type `int` + +|=== + +==== Valid expressions + +[%header%autowidth,cols="3*"] +|=== +|Name +|Expression +|Return type + +|Conversion from `int` +|`T j = i;` +| + +|Addition +|`x + y` +|`T` + +|Subtraction +|`x - y` +|`T` + +|Negation +|`-x` +|`T` + +|Multiplication +a| +`+x * y+` + +`+x * i+` +|`T` + +|Division +a| +`x / y` + +`x / i` +|`T` + +|Mixed equality +a| +`x == i` + +`x != i` +|`bool` + +|Mixed ordering +a| +`x < i` + +`x > i` + +`x <= i` + +`x >= i` +|`bool` + +|=== + +==== Invariants + +[%header%autowidth,cols="2*"] +|=== +|`T` and `int` consistency +a| +`(x == T(i)) == (x == i)` + +`(x != T(i)) == (x != i)` + +`(x < T(i)) == (x < i)` + +`(x > T(i)) == (x > i)` + +`(x / T(i)) == (x / i)` + +`+(x * T(i)) == (x * i)+` + +|=== + +[#floating_points_comparison_impl] +== Tolerance-based comparisons + +Assertions in the {utf} use two kinds of comparison. For `u` being close to zero with absolute tolerance `eps`: + +[source,cpp] +---- +abs(u) <= eps; // (abs) +---- + +For `u` and `v` being close with relative tolerance `eps`: + +[source,cpp] +---- + abs(u - v)/abs(u) <= eps +&& abs(u - v)/abs(v) <= eps; // (rel) +---- + +For rationale for choosing these formulae, see section {floating_points_testing_tools}. + +Assertion {boost_test} (when comparing floating-point numbers) uses the following algorithm: + +* When either value `u` or `v` is zero, evaluates formula (abs) on the other value. +* When the specified tolerance is zero, performs direct (native) comparison between `u` and `v`. +* Otherwise, performs formula (rel) on `u` and `v`. + +[NOTE] +==== +Therefore in order to check if a number is close to zero with tolerance, you need to type: + +[source,cpp] +---- +BOOST_TEST(v == T(0), tt::tolerance(eps)); +---- +==== + +The compatibility assertions {boost_level_close} and {boost_level_close_fraction} perform formula (rel). + +The compatibility assertion {boost_level_small} performs formula (abs). + +The {utf} also provides unary predicate cpp:boost::math::fpc::small_with_tolerance[`small_with_tolerance`] and binary predicate predicate +cpp:boost::math::fpc::close_at_tolerance[`close_at_tolerance`] that implement formula (abs) and (rel) respectively. + +=== Tolerance in `operator<` + +Tolerance-based computations also apply to `operator<` and other relational operators. The semantics are defined as follows: + +* _less-at-tolerance_ <==> _strictly-less_ and not _close-at-tolerance_ +* _greater-at-tolerance_ <==> _strictly-greater_ and not _close-at-tolerance_ +* _less-or-equal-at-tolerance_ <==> _strictly-less_ or _close-at-tolerance_ +* _greater-or-equal-at-tolerance_ <==> _strictly-greater_ or _close-at-tolerance_ + +NOTE: This implies that the exactly one of these: `u < v`, `u == v`, `u > v`, passes with {boost_test} at any given tolerance. + +[CAUTION] +==== +Relation _less-at-tolerance_ is not a _Strict Weak Ordering_ as it lacks the _transitivity of the equivalence_; + using it as predicate in `std::map` or any order-based STL + algorithm would result in undefined behavior. +==== + +[#floating_points_comparison_theory] +== Theory behind floating point comparisons + +The following is the most obvious way to compare two floating-point values `u` and `v` for being close at a given absolute tolerance `epsilon`: + +[#equ1] +[source,cpp] +---- +abs(u - v) <= epsilon; // (1) +---- + +However, in many circumstances, this is not what we want. The same absolute tolerance value `0.01` may be too small to meaningfully compare +two values of magnitude `10e12` and at the same time too little to meaningfully compare values of magnitude `10e-12`. For examples, see xref:testing_tools/floating_point.adoc#Squassabia[Squassabia]. + +We do not want to apply the same absolute tolerance for huge and tiny numbers. Instead, we would like to scale the `epsilon` with `u` and `v`. +The {utf} implements floating-point comparison algorithm that is based on the solution presented in xref:testing_tools/floating_point.adoc#KnuthII[Knuth]: + +[#equ2] +[source,cpp] +---- + abs(u - v) <= epsilon * abs(u) +&& abs(u - v) <= epsilon * abs(v)); // (2) +---- + +defines a _very close with tolerance `epsilon`_ relationship between `u` and `v`, while + +[#equ3] +[source,cpp] +---- + abs(u - v) <= epsilon * abs(u) +|| abs(u - v) <= epsilon * abs(v); // (3) +---- + +defines a _close enough with tolerance `epsilon`_ relationship between `u` and `v`. + +Both relationships are commutative but are not transitive. The relationship defined in +xref:testing_tools/floating_point.adoc#equ2[(2)] is stronger that the relationship defined in xref:testing_tools/floating_point.adoc#equ3[(3)] since xref:testing_tools/floating_point.adoc#equ2[(2)] necessarily implies xref:testing_tools/floating_point.adoc#equ3[(3)]. + +The multiplication in the right side of inequalities may cause an unwanted underflow condition. To prevent this, +the implementation is using modified version of xref:testing_tools/floating_point.adoc#equ2[(2)] and xref:testing_tools/floating_point.adoc#equ3[(3)], which scales the checked difference rather than `epsilon`: + +[#equ4] +[source,cpp] +---- + abs(u - v)/abs(u) <= epsilon +&& abs(u - v)/abs(v) <= epsilon; // (4) +---- + +[#equ5] +[source,cpp] +---- + abs(u - v)/abs(u) <= epsilon +|| abs(u - v)/abs(v) <= epsilon; // (5) +---- + +This way all underflow and overflow conditions can be guarded safely. The above however, will not work when `v` or `u` is zero. +In such cases the solution is to resort to a different algorithm, e.g. xref:testing_tools/floating_point.adoc#equ1[(1)]. + +=== Tolerance selection considerations + +In case of absence of domain specific requirements the value of tolerance can be chosen as a sum of the predicted +upper limits for "relative rounding errors" of compared values. The "rounding" is the operation by which a real +value 'x' is represented in a floating-point format with 'p' binary digits (bits) as the floating-point value *X*. +The "relative rounding error" is the difference between the real and the floating point values in relation to real +value: `abs(x-X)/abs(x)`. The discrepancy between real and floating point value may be caused by several reasons: + +* Type promotion +* Arithmetic operations +* Conversion from a decimal presentation to a binary presentation +* Non-arithmetic operation + +The first two operations proved to have a relative rounding error that does not exceed + +half_epsilon = half of the 'machine epsilon value' + +for the appropriate floating point type `FPT` footnote:[*machine epsilon value* is represented by `std::numeric_limits::epsilon()`]. +Conversion to binary presentation, sadly, does not have such requirement. So we can't assume that `float(1.1)` is close +to the real number `1.1` with tolerance `half_epsilon` for float (though for 11./10 we can). Non-arithmetic operations either do not have a +predicted upper limit relative rounding errors. + +[NOTE] +==== +Note that both arithmetic and non-arithmetic operations might also +produce others "non-rounding" errors, such as underflow/overflow, division-by-zero or "operation errors". +==== + +All theorems about the upper limit of a rounding error, including that of `half_epsilon`, refer only to +the 'rounding' operation, nothing more. This means that the 'operation error', that is, the error incurred by the +operation itself, besides rounding, isn't considered. In order for numerical software to be able to actually +predict error bounds, the {ieee754} standard requires arithmetic operations to be 'correctly or exactly rounded'. +That is, it is required that the internal computation of a given operation be such that the floating point result +is the exact result rounded to the number of working bits. In other words, it is required that the computation used +by the operation itself doesn't introduce any additional errors. The {ieee754} standard does not require same behavior +from most non-arithmetic operation. The underflow/overflow and division-by-zero errors may cause rounding errors +with unpredictable upper limits. + +At last be aware that `half_epsilon` rules are not transitive. In other words combination of two +arithmetic operations may produce rounding error that significantly exceeds `+2*half_epsilon+`. All +in all there are no generic rules on how to select the tolerance and users need to apply common sense and domain/ +problem specific knowledge to decide on tolerance value. + +To simplify things in most usage cases latest version of algorithm below opted to use percentage values for +tolerance specification (instead of fractions of related values). In other words now you use it to check that +difference between two values does not exceed x percent. + +For more reading about floating-point comparison see references below. + +==== Bibliographic references + +.Books +[cols="1,3"] +|=== +|[#KnuthII] +The art of computer programming (vol II) +a| +Donald. E. Knuth, 1998, Addison-Wesley Longman, Inc., ISBN 0-201-89684-2, Addison-Wesley Professional; 3rd edition. + (The relevant equations are in §4.2.2, Eq. 36 and 37.) + +|Rounding near zero, in http://www.amazon.com/Advanced-Arithmetic-Digital-Computer-Kulisch/dp/3211838708[Advanced Arithmetic for the Digital Computer] +a| +Ulrich W. Kulisch, 2002, Springer, Inc., ISBN 0-201-89684-2, Springer; 1st edition + +|=== + +.Periodicals +[cols="1,3"] +|=== +|[#Squassabia] +https://adtmag.com/articles/2000/03/16/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx[Comparing Floats: How To Determine if Floating Quantities Are Close Enough Once a Tolerance Has Been Reached] +a| +Alberto Squassabia, in C++ Report (March 2000) + +|The Journeyman's Shop: Trap Handlers, Sticky Bits, and Floating-Point Comparisons +a| +Pete Becker, in C/C++ Users Journal (December 2000) + +|=== + +.Publications +[cols="1,3"] +|=== +|http://dl.acm.org/citation.cfm?id=103163[What Every Computer Scientist Should Know About Floating-Point Arithmetic] +a| +David Goldberg, pages 150-230, in Computing Surveys (March 1991), Association for Computing Machinery, Inc. + +|http://hal.archives-ouvertes.fr/docs/00/07/26/81/PDF/RR-3967.pdf[From Rounding Error Estimation to Automatic Correction with Automatic Differentiation] +a| +Philippe Langlois, Technical report, INRIA + +|http://www.cs.berkeley.edu/~wkahan/[William Kahan home page] +a| +Lots of information on floating point arithmetics. + +|=== diff --git a/doc/modules/ROOT/pages/testing_tools/index.adoc b/doc/modules/ROOT/pages/testing_tools/index.adoc new file mode 100644 index 0000000000..d2b8f94d4e --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/index.adoc @@ -0,0 +1,26 @@ += Writing unit tests +:page-aliases: boost_test/testing_tools.adoc + +Once a test case has been declared, the body of this test should be written. A test case is a +sequence of operations in which *assertions* are inserted. Those assertions evaluate _statements_ that implement the expectation being validated, +and report failures and/or information in a uniform manner, depending on the xref:utf_reference/rt_param_reference.adoc#log_level[log level]. + +The {utf}'s supplies a toolbox of assertions to ease the creation and maintenance of test cases and +provide a uniform error reporting mechanism. The toolbox supplied is in most part in a form of macro declarations. +An (almost) unique interface to all of them implemented by the macro {boost_test}. + +NOTE: All macros arguments are calculated once, so it's safe to pass complex expressions in their place. + +All tools automatically supply an error location: a file name and a line number, which can also be overridden. + +[CAUTION] +==== +The testing tools are intended for unit test code rather than library or production code, where throwing exceptions, using `assert()`, +`boost::concept_check` or `BOOST_STATIC_ASSERT()` may be more suitable ways to detect and report errors. +==== + +For a list of all supplied testing tools and usage examples, see the xref:testing_tools/summary.adoc[summary] +or the xref:utf_reference/testing_tool_ref.adoc[reference]. + +[#extended_comparison] +== Extended comparisons support diff --git a/doc/modules/ROOT/pages/testing_tools/internal_details.adoc b/doc/modules/ROOT/pages/testing_tools/internal_details.adoc new file mode 100644 index 0000000000..f00140c04c --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/internal_details.adoc @@ -0,0 +1,75 @@ += `BOOST_TEST`: details on expressions +:page-aliases: boost_test/testing_tools/internal_details.adoc + +Let's consider the following example: + +// tag reference: doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp +:bt-name: boost_test_macro3 +:bt-rule: run-fail +:bt-descr: BOOST_TEST reporting +include::partial$bt_example.adoc[] + +It was already mentioned that the reporting is not symmetrical (see xref:testing_tools/reports.adoc[here]). +An expression is constructed from the `statement` appearing in the `BOOST_TEST` macro. This expression allows evaluation and reporting such +as `"13 - 1 >= 12" failed` along with a copy of the `statement`, which contains more details than `"a - 1 < b" failed`. +In details, what happens is the following: + +. a special object, the `seed` of the expression, is composed from the left side of `statement`. +This initial composition has highest precedence over the supported operations. The expression below: ++ +a op1 b op2 c op3 d ++ +is actually seen as ++ +( seed a ) op1 b op2 c op3 d +. The "`seed a`" returns an `expression` object that keep tracks of the type of `a`. This expression +has overloads for left-to-right associativity, and the +operations `op1`, `op2` ... are _chained_ to the right of this expression object: ++ +a op1 b ++ +yields to the pseudo-code ++ +expression1 = create-expression(a) +expression2 = create-expression(expression1, op1, b) ++ +`expression1` and `expression2` keep track of their left and right operands, and the operation on those operands. The +expressions keep also track of the result type of the associated sub-expression. In the above example, `expression1` and `expression2` +have result type `decltype(a)` and `decltype(a op1 b)` respectively. The result type allows for chaining +sub-expressions. +. The C++ operators precedence rules apply in any case. What is seen by the expression is what is reachable with left-to-right +composition. Any other operation that happens before it reaches the expression's right operand is not parsed as a sub-expression +and is seen as a single operand: the right operand is not developed further by the framework. +Let's suppose `op2` below has higher precedence than `op1`, then ++ +a op1 b op2 c ++ +is equivalent to: ++ +create-expression(create-expression(a), op1, (b op2 c)) ++ +In the above statement, the final expression can only see the result of `(b op2 c)` to its right, for which no further detail +can be provided in the logs. This is also the case for _right-to-left_ associative operators, such as `!`, `+~+`, `-` (unary negation) +etc. ++ +CAUTION: Since the `expression` object is composed from left-to-right, it actually observes a chain of operations and +not the full expression tree. +. Once the full expression chain is built, it is evaluated as a chain of sub-expressions from left-to-right, exactly as the +composition rule above. The evaluated elements are the ones of the expression itself. The expression ++ +a op1 b ++ +yields to the following evaluation chain: ++ +expression2.result = expression1.result op1 b +expression1.result = a ++ +The final expression of the statement is cast to a boolean, which is in turn evaluated by the {utf}. + +The example below illustrates the construction of the left-to-right _chained_ expression. + +// tag reference: doc/modules/ROOT/examples/boost_test_macro2.run-fail.cpp +:bt-name: boost_test_macro2 +:bt-rule: run-fail +:bt-descr: BOOST_TEST compound statements +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc b/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc new file mode 100644 index 0000000000..fcc92d0dad --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc @@ -0,0 +1,90 @@ += Output streams testing tool +:page-aliases: boost_test/testing_tools/output_stream_testing.adoc + +How would you perform correctness test for `operator<< ( std::ostream &, ... )` operations? + +You can print into the standard output stream and manually check that it is matching your expectations. +Unfortunately, this is not really acceptable for the regression testing and doesn't serve a long term purpose of a +unit test. + +You can use `std::stringstream` and compare resulting output buffer with the +expected pattern string, but you are required to perform several additional operations with every check you do. So it +becomes tedious very fast. + +The class cpp:boost::test_tools::output_test_stream[boost::test_tools::output_test_stream] is designed to automate these tasks for you. This is a simple, +but powerful tool for testing standard `std::ostream` based output operation. The class `output_test_stream` +complies to `std::ostream` interface so it can be used in place of any +`std::ostream` parameter. It provides several test methods to validate output content, +including test for match to expected output content or test for expected output length. Flushing, synchronizing, +string comparison and error message generation is automated by the tool implementation. + +All `output_test_stream` validation member functions by default flush the stream once the check is performed. +If you want to perform several checks with the same output, specify parameter `flush_stream` +with value `false` footnote:[This parameter is supported on all comparison methods, see the class +cpp:boost::test_tools::output_test_stream[documentation.\]]. + +In some cases manual generation of expected output is either too time consuming or is impossible at all because +of sheer volume. A possible way to address that issue is to split the test in two steps: + +. first by checking the expected output manually +. second to save this output to ensure that future checks produce the same output + +The class `output_test_stream` allows both the matching of the output content versus a _pattern file_ and generation +of this pattern file. The command line parameter xref:utf_reference/rt_param_reference.adoc#save_pattern[`save_pattern`] +may be used to either generate a new pattern file, or to check against an existing pattern. + +[#usages] +== Usage + +There are two ways to employ the class `output_test_stream`: + +. explicit output checks and +. pattern file matching + +=== Explicit output checks + +Use the instance of class `output_test_stream` as an output stream and check output content using tool's methods. + +// tag reference: doc/modules/ROOT/examples/example28.run-fail.cpp +:bt-name: example28 +:bt-rule: run-fail +:bt-descr: Explicit output checks with `output_test_stream` +include::partial$bt_example.adoc[] + +[NOTE] +==== +Use of `false` to prevent output flushing in first two invocation of check functions. Unless +you want to perform several different checks for the same output you wouldn't need to use it though. Your +test will look like a sequence of output operators followed by one check. +==== + +[TIP] +==== +Try to perform checks as +frequently as possible. It not only simplifies patterns you compare with, but also allows you to more closely +identify possible source of failure. +==== + +=== Pattern file matching + +The _pattern file_ is a companion file containing the patterns that the stream should match. Your testing will look +like a series of output operators followed by match pattern checks repeated several times. + +In the example below, the file `pattern_file` contains the patterns that should match. + +.... +i=2 +File: test.cpp Line:XXX +.... + +// tag reference: doc/modules/ROOT/examples/example29.run-fail.cpp +:bt-name: example29 +:bt-rule: run-fail +:bt-descr: Pattern file matching with `output_test_stream` +include::partial$bt_example.adoc[] + +[TIP] +==== +Try to perform checks as frequently as possible, because it allows you to more closely identify possible source + of failure +==== diff --git a/doc/modules/ROOT/pages/testing_tools/reports.adoc b/doc/modules/ROOT/pages/testing_tools/reports.adoc new file mode 100644 index 0000000000..aca264d58e --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/reports.adoc @@ -0,0 +1,61 @@ += Reported information +:page-aliases: boost_test/testing_tools/reports.adoc + +== Failure message, why? + +When an assertion fails, a message is logged containing: + +* the body of the statement that failed +* the name of the file and the line of the failed assertion +* the name of the test case containing this assertion + +The purpose of all these information is to isolate as quickly as possible the test that failed from the others. The *feedback* +that the execution of the test case provides is an important cue, for the following reasons: + +* within the scheme of a continuous build/test, the logs available from the server contain this information, which points to +a particular statement in the code +* the *cost* for reproducing an error is induced by the following steps: +** identify the test module that failed in case there are many +** compile and run the test module to reproduce the error +** identify the line of the code that failed, +** fix the test directly if all the information is enough, or start a debug session + +We can see from the scheme above that reproduction of an error is _costly_, since usually one tends to reproduce the error, +which in turn induces at least the compilation of the test module. Also, a hidden cost is the lookup at the line of code +that contains the failing statement, which triggers a sequence of back and forth lookup between the log on one hand and the code +on the other hand. + +The information extracted from the logs suggests the following fact: + +TIP: Richness of the information contained in the logs is a key for the rapid understanding and the resolution of a failed statement + +== Default reporting + +When an assertion fails, {boost_test} reports details and values on the operands of `statement` that lead to the failure. + +// tag reference: doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp +:bt-name: boost_test_macro3 +:bt-rule: run-fail +:bt-descr: BOOST_TEST reporting +include::partial$bt_example.adoc[] + +In the above example, the values of the operands are reported for inspection, which is more valuable as a copy +of the full statement. However, we can observe that they are not treated symmetrically: + +* "`a - 1 < b`" reports `"13 - 1 >= 12" failed` +* "`b > a - 1`" reports `"12 <= 12" failed` + +More details on how the {utf} parses the statement are given in xref:testing_tools/internal_details.adoc[this] section. + +== Custom messages + +While perfectly exact and precise, the file name, test case name, line number of a failed statement carry an information that +is partial with regards to the meaning of the failed statement. +Sometimes these information are not informative enough. The `BOOST_TEST` macro let you override the default message by the use of +a second argument, as shown on the following example. + +// tag reference: doc/modules/ROOT/examples/boost_test_message.run-fail.cpp +:bt-name: boost_test_message +:bt-rule: run-fail +:bt-descr: BOOST_TEST optional failure message +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/strings.adoc b/doc/modules/ROOT/pages/testing_tools/strings.adoc new file mode 100644 index 0000000000..be379b62d7 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/strings.adoc @@ -0,0 +1,23 @@ += Strings and C-strings comparison +:page-aliases: boost_test/testing_tools/extended_comparison/strings.adoc + +In the general case, pointers are compared using their value. However when type of the the pointers are `+char*+` or `+wchar_t*+`, +{boost_test} promotes them as null terminated `char` arrays and string comparison is used instead. +`std::string` (or any `std::basic_string`) and `std::string_view` (or any `std::basic_string_view`) are eligible for string comparison. + +String comparison can be used only if the operands to compare in {boost_test} can both be considered as strings type. + +[TIP] +==== +In this form, the comparison method and reporting can be overridden by providing an additional argument to {boost_test}. + See the xref:testing_tools/collections.adoc[collection comparison] section for more details, in particular + `boost::test_tools::per_element()` and `boost::test_tools::lexicographic()` modifiers. +==== + +// tag reference: doc/modules/ROOT/examples/boost_test_string.run-fail.cpp +:bt-name: boost_test_string +:bt-rule: run-fail +:bt-descr: BOOST_TEST string comparison +include::partial$bt_example.adoc[] + +NOTE: `std::string_view` support added in Boost.Test xref:change_log.adoc#ref_CHANGE_LOG_3_12[Boost 1.72]. diff --git a/doc/modules/ROOT/pages/testing_tools/summary.adoc b/doc/modules/ROOT/pages/testing_tools/summary.adoc new file mode 100644 index 0000000000..f37917d1f1 --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/summary.adoc @@ -0,0 +1,104 @@ += Summary of the API for writing tests +:page-aliases: boost_test/testing_tools/summary.adoc + +[%header%autowidth,cols="2*"] +|=== +|Assertions +|Short description + +|{boost_test}, {boost_test_level} +|General purpose assertion macro. + +|{boost_level} +|Simple validation of a boolean predicate value. + +|{boost_level_bitwise_equal} +|Bitwise equality test of two elements. + +|{boost_level_equal} +|Equality test of two elements. + +|{boost_level_equal_collections} +|Element-wise equality test of two collections. + +|{boost_level_close} +|Floating point comparison using a percentage of deviation. + +|{boost_level_close_fraction} +|Floating point comparison using the fraction of the compared operands. + +|{boost_level_exception} +|Exception detection and validation check. + +|{boost_level_ge} +|Comparison of two values (with convenient reporting). + +|{boost_level_gt} +|Comparison of two values (with convenient reporting). + +|{boost_level_le} +|Comparison of two values (with convenient reporting). + +|{boost_level_lt} +|Comparison of two values (with convenient reporting). + +|{boost_level_message} +|Same as {boost_level} with a custom message in case of failure. + +|{boost_level_ne} +|Comparison of two values (with convenient reporting). + +|{boost_level_no_throw} +|Checks an expression does not throw any exception. + +|{boost_level_predicate} +|Checks a list of arguments against a predicate functor. + +|{boost_level_small} +|Checks a value is small according to a tolerance. + +|{boost_level_throw} +|Checks an expression throws a specific type of expression. + +|{boost_auto_test_case_expected_failures} +|Indicates the number of expected failures for a test case + +|{boost_error} +|Logs an error message, fails but does not abort the current test. + +|{boost_fail} +|Logs an error message, fails and aborts the current test. + +|{boost_is_defined} +|Checks at runtime whether or not the supplied preprocessor symbol is defined. + +|=== + +[%header%autowidth,cols="2*"] +|=== +|Decorators +|Short description + +|{decorator_expected_failures} +|Indicates the expected failures of a test unit. + +|{decorator_timeout} +|Sets the maximum amount of time a test unit should take. + +|{decorator_tolerance} +|Sets the floating point comparison tolerance for a test unit. + +|=== + +[%header%autowidth,cols="2*"] +|=== +|Control macros +|Short description + +|{boost_test_tools_under_debugger} +|When defined, test assertions are compiled in debugger-friendly mode. + +|{boost_test_tools_debuggable} +|When defined, test assertions are compiled in two modes (debugger-friendly and full-featured), and the version is selected at run-time. + +|=== diff --git a/doc/modules/ROOT/pages/testing_tools/timeout.adoc b/doc/modules/ROOT/pages/testing_tools/timeout.adoc new file mode 100644 index 0000000000..34769a05bc --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/timeout.adoc @@ -0,0 +1,36 @@ += Time-out for test cases +:page-aliases: boost_test/testing_tools/timeout.adoc + +The {utf} provides the decorator {decorator_timeout} that specifies a time-out for a specific *test unit*. +The argument time is always expressed in *seconds ans wall-clock* time. + +For test-cases, the time-out value sets the maximum allowed duration for the test. If this time is +exceeded, the test case is reported as failed. On some systems, the {utf} is able to force the test-case +to stop through a `SIGALRM` signal (see below). + +For test-suites, the time-out value sets the maximum allowed duration for the entire suite to complete. This duration +is the accumulated time of all the test-cases contained in the sub-tree rooted on the test-suite, plus some extra +execution time needed by the {utf}. For each test-units under a test-suite with time-out, the maximum allowed duration +is set as being the test-suite time out minus the accumulated execution time before the execution of the test-unit. +If this test-unit is a test-case, it is equivalent to setting the decorator {decorator_timeout} to the test-case +with a time-out value expressed as before. + +In case the test-suite times out, the +suite is flagged as `timed-out` and `failed`, and all the test units (suites and cases) that have not been executed +up to the time-out point are all skipped. + +// tag reference: doc/modules/ROOT/examples/decorator_11.run-fail.cpp +:bt-name: decorator_11 +:bt-rule: run-fail +:bt-descr: decorator timeout +include::partial$bt_example.adoc[] + +[NOTE] +==== +The macro + `BOOST_SIGACTION_BASED_SIGNAL_HANDLING` is defined + if Boost.Test is able to force the test-case to stop. This feature is for instance not supported on Windows. + The {utf} will still be able to report the test-case as failed (once the test-case finishes). +==== + +NOTE: The support of test suite level time-out has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / {utf} v3.10] diff --git a/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc new file mode 100644 index 0000000000..beaa6db0cb --- /dev/null +++ b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc @@ -0,0 +1,62 @@ += Assertion severity level +:page-aliases: boost_test/testing_tools/tools_assertion_severity_level.adoc + +There are three *levels* of assertions and all the testing tools are supplied in these three flavours/levels. These levels +have different meaning on the consistency of the test case: + +* `REQUIRE` which implements a *requirements* : this is a strong condition for the operations following the assertion to be valid. +This type of assertions should be used when a pre-condition for running the test is not met or when the test-case cannot continue. +If such as assertion fails, the test case execution stops immediately, and the test-case is flagged as _failed_. +* `CHECK` for standard *checks*: this is the most commonly used assertion level. If the statement evaluates to `false`, the test case is +flagged as failed but its execution continues. +* `WARN` which stands for *warnings*: this is an assertion providing information. The test case execution continues and a warning message is logged. +The warning does not change the success status of a test case. This level of assertion can be used +to validate aspects less important then correctness: performance, portability, usability, etc. + +For example: + +* xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST_REQUIRE_THROW`], {boost_test_require} +* `BOOST_CHECK_THROW`, `BOOST_TEST` footnote:[{boost_test} is equivalent to `BOOST_TEST_CHECK`] +* `BOOST_WARN_THROW`, `BOOST_TEST_WARN` + +These three levels of assertions are filtered by the framework and reported into the test log and output: + +. If an assertion designated by the tool passes, confirmation message can be printed in log output +footnote:[to manage what messages appear in the test log stream, set the proper xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`\]]. +. If an assertion designated by the tool fails, the following will happen, depending on the assertion level +footnote:[in some cases log message can be slightly different to reflect failed tool specifics, see xref:testing_tools/reports.adoc[here\]]: + +[#assertions_severity_levels] +.Assertions severity levels +[%header%autowidth,cols="4*"] +|=== +|Level +|Test log content +|Errors counter +|Test execution + +|WARN +|warning in ``: condition `` is not satisfied +|not affected +|continues + +|CHECK +|error in ``: test `` failed +|increased +|continues + +|REQUIRE +|fatal error in ``: critical test `` failed +|increased +|aborts + +|=== + +The granularity of the report depends on the current xref:utf_reference/rt_param_reference.adoc#log_level[log level] and +xref:utf_reference/rt_param_reference.adoc#report_level[report level]. + +[NOTE] +==== +in the above table, the _test execution_ is related to the current test case _only_. Hence _"aborts"_ means + that the current test case is aborted, but other test cases in the test tree are still executed. +==== diff --git a/doc/modules/ROOT/pages/tests_organization/decorators.adoc b/doc/modules/ROOT/pages/tests_organization/decorators.adoc new file mode 100644 index 0000000000..227f71c8e7 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/decorators.adoc @@ -0,0 +1,221 @@ += Decorators +:page-aliases: boost_test/tests_organization/decorators.adoc + +"Decorator" is a uniform mechanism for updating various attributes of the automatically registered test units. These +attributes affect how the test tree is processed during the execution of the test module and include test unit +description, floating-point tolerance and the number of expected failures among others. They are listed in detail in +the following sections. + +== Test case decorators + +You can apply more than one decorator to the same test unit. A list of decorators is applied to a test case by specifying +it as the second argument to macro {boost_auto_test_case} or the third argument to macro {boost_fixture_test_case}. + +// tag reference: doc/modules/ROOT/examples/decorator_01.run.cpp +:bt-name: decorator_01 +:bt-rule: run +:bt-descr: Test unit decorators +include::partial$bt_example.adoc[] + +Each decorator in the list is preceded by an asterisk (`+*+`); the subsequent syntax resembles a function call and is +specified in detail for each decorator. If there is more than one decorator in the list, they are concatenated with no +additional separator; each asterisk indicates the beginning of a decorator. In the above example, test case `test_case1` +has one associated _decorator:_ {decorator_label}. This means that when test units are filtered based on label, this +test case will match to label `"trivial"`. Test case `test_case2` has three associated decorators: two of type `label` +and one of type `description`. + +[#suite_level_decorators] +== Suite-level decorators + +Similarly to test case it is possible to apply list of decorators to test suite. It is done by specifying a list of +decorators as the second argument to the macro {boost_auto_test_suite} or the third argument to the macro +{boost_fixture_test_suite}. + +// tag reference: doc/modules/ROOT/examples/decorator_02.run.cpp +:bt-name: decorator_02 +:bt-rule: run +:bt-descr: Test suite decorators +include::partial$bt_example.adoc[] + +How a test suite decorator affects the processing of the test units inside of it varies with the decorator +and is described for each decorator in subsequent sections. For instance, the function of the decorator in the above +example is that when tests are filtered by label `"trivial"`, every test unit in suite `suite1` will be run. + +Similar to C++ namespace test suite can be closed and reopened within the same test file or span more than one file +and you are allowed to apply different decorators in each point, where test suite is opened. If this is the case, +the list of decorators applied to the test suite is the union of decorators specified in each place. Here an example. + +// tag reference: doc/modules/ROOT/examples/decorator_03.run.cpp +:bt-name: decorator_03 +:bt-rule: run +:bt-descr: Decorators on multiple suite openings +include::partial$bt_example.adoc[] + +In the above example, the scope of test suite `suite1` is opened three times. This results in a test suite containing +three test cases and associated with two {decorator_label} decorators. Therefore running tests by label `"trivial"` as +well as by label `"simple"` both result in executing all three test cases from the suite. + +[CAUTION] +==== +The above syntax for decorators requires that the compiler supports variadic macros (added in C++11). If you +intend for your test program to also work for compilers without variadic macros, use explicit decorator syntax, +described below. +==== + +[#explicit_decorator_declaration] +== Explicit decorator declaration + +There is another way of associating a decorator set with test units. Macro {boost_test_decorator} indicates that its set +of decorators is to be applied to the test unit or _test case sequence_ that immediately follows the declaration. + +// tag reference: doc/modules/ROOT/examples/decorator_00.run.cpp +:bt-name: decorator_00 +:bt-rule: run +:bt-descr: explicit decorator declaration +include::partial$bt_example.adoc[] + +In the above example a decorator is applied to a xref:tests_organization/test_case_generation.adoc[data-driven test case]. Macro {boost_data_test_case} cannot take the decorator set as one of its arguments, therefore +the explicit decorator declaration is used. Macro {boost_data_test_case} generates a sequence of 4 test cases. The +decorator set is applied to each of them. + +Another use case for the explicit decorator declaration is when you intend for your test program to compile also on +compilers without variadic macros. In this case it is recommended that you use the more verbose syntax. It is summarized +in the following table: + +[%header%autowidth,cols="3*"] +|=== +|Test unit to register +|Concise syntax +|Universal syntax + +|test case +a| +[source,cpp] +---- +BOOST_AUTO_TEST_CASE(test_case, *decor1() *decor2()) +{ + // assertions +} +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_AUTO_TEST_CASE(test_case) +{ + // assertions +} +---- + +|test case with fixture +a| +[source,cpp] +---- +BOOST_FIXTURE_TEST_CASE(test_case, Fx, *decor1() *decor2()) +{ + // assertions +} +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_FIXTURE_TEST_CASE(test_case, Fx) +{ + // assertions +} +---- + +|test suite +a| +[source,cpp] +---- +BOOST_AUTO_TEST_SUITE(test_suite, *decor1() *decor2()) + + // test units + +BOOST_AUTO_TEST_SUITE_END() +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_AUTO_TEST_SUITE(test_suite) + + // test units + +BOOST_AUTO_TEST_SUITE_END() +---- + +|test suite with fixture +a| +[source,cpp] +---- +BOOST_FIXTURE_TEST_SUITE(test_suite, Fx, *decor1() *decor2()) + + // test units + +BOOST_AUTO_TEST_SUITE_END() +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_FIXTURE_TEST_SUITE(test_suite, Fx) + + // test units + +BOOST_AUTO_TEST_SUITE_END() +---- + +|data-driven test case +a| +[source,cpp] +---- +// not doable +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_DATA_TEST_CASE(test_case, data, var) +{ + // assertions +} +---- + +|test case template +a| +[source,cpp] +---- +// not doable +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_AUTO_TEST_CASE_TEMPLATE(test_case, T, type_list) +{ + // assertions +} +---- + +|test case template with fixture +a| +[source,cpp] +---- +// not doable +---- +a| +[source,cpp] +---- +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_case, T, type_list, Fx) +{ + // assertions +} +---- + +|=== + +Throughout the reminder of this documentation we use only the concise syntax. diff --git a/doc/modules/ROOT/pages/tests_organization/enabling.adoc b/doc/modules/ROOT/pages/tests_organization/enabling.adoc new file mode 100644 index 0000000000..cd357a7fdb --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/enabling.adoc @@ -0,0 +1,82 @@ += Enabling or disabling test unit execution +:page-aliases: boost_test/tests_organization/enabling.adoc + +The {utf} provides a way for enabling or disabling a test unit execution. If a test case is disabled, it will not be +run by the test runner. If a test suite is disabled, its status is inherited by the test units under its subtree, unless +otherwise specified. + +The run status can be overridden by the command line parameters: by providing the appropriate arguments to the command +line, a disabled test may still be executed. The xref:runtime_config/test_unit_filtering.adoc[test unit +filtering] section covers this feature in details. + +[WARNING] +==== +There is a difference between a disabled test and a skipped test: + +* a disabled test has a run status set to disabled, and is completely discarded by the {utf}. +** a skipped test is a test that has a run status set to enabled, but which execution has been skipped at runtime. +==== + +== Unconditional run status + +Decorator {decorator_disabled} indicates that the test unit's {default_run_status} is _false_. This means that that +test cases inside this test unit will not be run by default, unless otherwise specified. Decorator {decorator_enabled} +indicates that the test unit's default run status is _true_. This means that that test cases inside this test unit will +be run by default, unless otherwise specified. + +// tag reference: doc/modules/ROOT/examples/decorator_05.run-fail.cpp +:bt-name: decorator_05 +:bt-rule: run-fail +:bt-descr: decorators enabled and disabled +include::partial$bt_example.adoc[] + +Syntactically, it is possible to apply both decorators `enabled` and `disabled` to the same test unit. This is reported +as set-up error when the test program is run. + +== Compilation-time run status + +Decorator {decorator_enable_if} indicates that the test unit's {default_run_status} is either _true_ or _false_, +depending on the value of `Condition`. This means that that test cases inside this test unit will or will not be run by +default. + +// tag reference: doc/modules/ROOT/examples/decorator_06.run-fail.cpp +:bt-name: decorator_06 +:bt-rule: run-fail +:bt-descr: decorator enable_if +include::partial$bt_example.adoc[] + +Decorator `enable_if()` is equivalent to decorator `enabled()`. Similarly, `enable_if()` is equivalent to +decorator `disabled()`. + +== Runtime run status + +Decorator {decorator_precondition} associates a _predicate_ with a test unit. Before the test unit is executed, the +predicate is evaluated with the test unit's ID passed as the argument. If it evaluates to `false`, execution of the test +unit is skipped. Skipping a test suite means skipping the execution of every test unit inside. + +[TIP] +==== +The precondition may return an cpp:boost::test_tools::assertion_result[assertion_result] instead of a boolean. + In that case, the message contained in the `assertion_result` will be printed by the {utf}. +==== + +// tag reference: doc/modules/ROOT/examples/decorator_08.run-fail.cpp +:bt-name: decorator_08 +:bt-rule: run-fail +:bt-descr: decorator precondition +include::partial$bt_example.adoc[] + +In the example above, the user defined a custom predicate `if_either` that evaluates to `true` if at least one of the two +specified tests passed. (It assumes that the tests are registered in the specific order.) + +* Test case `test3` has a precondition that at either `test1` or `test2` passed. The precondition is satisfied, +therefore `test3` is run (and fails), +* test case `test4` has a precondition that either `test2` or `test3` passed. Since they both failed, the +precondition is not satisfied, therefore `test4` is skipped. + +[NOTE] +==== +A {decorator_precondition} that evaluates to `false` does not yield an error and does not fail the attached unit test. However + the {utf} returns an error if the test tree is empty (see xref:tests_organization/test_tree_content.adoc[this section] + for more details). +==== diff --git a/doc/modules/ROOT/pages/tests_organization/fixtures.adoc b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc new file mode 100644 index 0000000000..657ccae6f0 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc @@ -0,0 +1,330 @@ += Fixtures +:page-aliases: boost_test/tests_organization/fixtures.adoc + +In general terms a test fixture or test context is the collection of one or more of the following items, required +to perform the test: + +* preconditions +* particular states of tested units +* necessary cleanup procedures + +Though these tasks are encountered in many if not all test cases, what makes a test fixture different is +repetition. Where a normal test case implementation does all preparatory and cleanup work itself, a test fixture +allows it to be implemented in a separate reusable unit. + +With introduction of e*X*treme *P*rogramming (XP), the testing style, that require test setup/cleanup repetition, +has become even more popular. Single XP adopted test modules may contain hundreds of single assertion test cases, +many requiring very similar test setup/cleanup. This is the problem that the test fixture is designed to solve. + +In practice a test fixture usually is a combination of `setup` and `teardown` functions, associated with test case. +The former serves the purposes of test setup. The later is dedicated to the cleanup tasks. Ideally we'd like for a +test module author to be able to define variables used in fixtures on the stack and, at the same time, to refer to +them directly in a test case. + +It's important to understand that C++ provides a way to implement a straightforward test fixture solution +that almost satisfies our requirements without any extra support from the test framework. Here is how simple test +module with such a fixture may look like: + +[source,cpp] +---- +struct MyFixture { + MyFixture() { i = new int; *i = 0 } + ~MyFixture() { delete i; } + + int* i; +}; + +BOOST_AUTO_TEST_CASE( test_case1 ) +{ + MyFixture f; + // do something involving f.i +} + +BOOST_AUTO_TEST_CASE( test_case2 ) +{ + MyFixture f; + // do something involving f.i +} +---- + +This is a generic solution that can be used to implement any kind of shared setup or cleanup procedure. Still +there are several more or less minor practical issues with this pure C++ based fixtures solution: + +* We need to add a fixture declaration statement into each test case manually. +* Objects defined in fixture are references with `` prefix. +* There is no place to execute a _global_ fixture, which performs _global_ setup/cleanup +procedures before and after testing. + +The {utf} lets you define a fixture according to xref:tests_organization/fixtures.adoc#models[several generic interfaces], +and thus helps you with following tasks: + +* define shared setup/teardown procedures for a single or group of test cases +* define setup/teardown procedures which are performed once per test suite +* define xref:tests_organization/fixtures.adoc#global[global setup/teardown] procedures which are performed once per test module + +[#models] +== Fixture models + +Several fixture interfaces are supported by the {utf}. The choice of the interface depends +mainly on the usage of the fixture. + +=== Fixture class model + +The {utf} defines the generic fixture class model as follows: + +[source,cpp] +---- +struct { + (); // setup function + ~(); // teardown function +}; +---- + +In other words a fixture is expected to be implemented as a class where the class constructor serves as a `setup` +method and class destructor serves as `teardown` method. + +The class model above has some limitations though: + +* it is not possible to have exceptions in the teardown function, especially any test assertions that aborts the +current test case is not possible (as those use exceptions) +* it is sometimes more natural to use the constructor/destructor to perform the necessary resource allocation/release +of the fixture, and that will be consumed in the test cases, and check for the proper state of the fixture in separate functions. +Those checks are the pre-conditions for the test case to run, and the post-conditions that should be met after the test case +has been running. + +This is why the {utf} also supports (Boost 1.65 on) optional `setup` and/or `teardown` functions as follow: + +[source,cpp] +---- +struct { + (); // ctor + ~(); // dtor + void setup(); // setup, optional + void teardown(); // teardown, optional +}; +---- + +[NOTE] +==== +As mentioned, the declaration/implementation of the `setup` and `teardown` are optional: + the {utf} will check the existence of those and will call them adequately. However in C++98, + it is not possible to detect those declaration in case those are inherited (it works fine for + compiler supporting `auto` and `decltype`). +==== + +This model is expected from fixtures used with {boost_fixture_test_case} and {boost_fixture_test_suite}. + +=== Flexible models + +In addition to {boost_fixture_test_case} and {boost_fixture_test_suite} the {utf} allows to associate fixture with +test unit using the decorator {decorator_fixture}. This decorator supports additional models for declaring +the `setup` and `teardown`: + +* a fixture defined according to the fixture class model above +* a fixture defined according to the extended fixture class model, which allows for the fixture constructor to +takes one argument. For example: ++ +struct Fx +\{ +std::string s; +Fx(std::string s_ = "") : s(s_) +\{ BOOST_TEST_MESSAGE("ctor " << s); } +void setup() +\{ BOOST_TEST_MESSAGE("optional setup " << s); } +void teardown() +\{ BOOST_TEST_MESSAGE("optional teardown " << s); } +~Fx() +\{ BOOST_TEST_MESSAGE("dtor " << s); } +}; +* a fixture defined as a pair of free functions for the `setup` and `teardown` (latter optional) ++ +void setup() \{ BOOST_TEST_MESSAGE("set up"); } +void teardown() \{ BOOST_TEST_MESSAGE("tear down"); } + +For complete example of test module which uses these models please check decorator {decorator_fixture}. + +[#case] +== Test case fixture + +A _test case fixture_ is a fixture consumed by a test case: the fixture `setup` is called before the test case executes, +and the fixture `teardown` is called after the test case finished its execution, independently from its execution state. + +The {utf} provides several ways of defining fixtures for test-cases, each of which having their properties: + +* the declaration of a fixture for a single test case, letting the test case access the members of the fixture, +* the declaration of one or more fixture(s) for a single test case, without accessing the members and with a flexible interface, +* the declaration of a fixture for a group of test-cases defined by a subtree, with access to the members of the fixture. + +=== Single test case fixture + +The following two methods are available for declaring a fixture attached to one particular test case: + +* the use of the macro {boost_fixture_test_case} in place of {boost_auto_test_case}, which let access to the members of the fixture +* the use of the decorator {decorator_fixture}, which does not let access to the members but enables +the definition of several fixtures for one test case. + +[#test_case_fixture_macro] +==== Fixture with `BOOST_FIXTURE_TEST_CASE` + +`BOOST_FIXTURE_TEST_CASE` serves as a test case declaration with a fixture, and is meant be used in place of +the test case declaration with {boost_auto_test_case}: + +[source,cpp] +---- +BOOST_FIXTURE_TEST_CASE(test_case_name, fixture_name); +---- + +The only difference from the macro {boost_auto_test_case} is the presence of an extra argument `fixture_name`. +The public and protected members of the fixture are directly accessible from the test case body. Only +one fixture can be attached to a test-case footnote:[it is still possible to define a class inheriting from several +fixtures, that will act as a proxy fixture.]. + +NOTE: You can't access private members of fixture, but then why would you make anything private? + +// tag reference: doc/modules/ROOT/examples/example18.run-fail.cpp +:bt-name: example18 +:bt-rule: run-fail +:bt-descr: Per test case fixture +include::partial$bt_example.adoc[] + +In this example only `test_case1` and `test_case2` have fixture `F` assigned. +You still need to refer to the fixture name in every test case. xref:tests_organization/fixtures.adoc#test_case_fixture_subtree[This] section +explains how a same fixture can be declared for a subtree under a test suite. + +[#test_case_fixture_decorator] +==== Fixture with `fixture` decorator + +By using the decorator {decorator_fixture}, it is possible to: + +* attach several fixtures to a unique test case +* use a flexible fixture interface (see xref:tests_organization/fixtures.adoc#models[here]) + +[NOTE] +==== +Using the decorator approach, it is not possible to access the members of the fixture (in case the fixture is implemented + as a class) +==== + +[#test_case_fixture_subtree] +=== Fixture for a complete subtree + +If all test cases in a test sub tree require the same fixture (you can group test cases in a test suite based on a +fixture required) you can make another step toward an automation of a test fixture assignment. To assign the +same shared fixture for all test cases in a test suite, use the macro {boost_fixture_test_suite} in place of the +macro {boost_auto_test_suite} for automated test suite creation and registration. + +[source,cpp] +---- +BOOST_FIXTURE_TEST_SUITE(suite_name, fixture_name); +---- + +Once again the only difference from the macro {boost_auto_test_suite} usage is the presence of +an extra argument - the fixture name. And now, you not only have direct access to the public and protected members +of the fixture, but also do not need to refer to the fixture name in test case definition. All test cases assigned +the same fixture automatically. + +[TIP] +==== +If necessary you can reset the fixture for a particular test case using the macro + {boost_fixture_test_case}. Similarly you can reset the fixture for a particular sub + test suite using {boost_fixture_test_suite}. +==== + +[NOTE] +==== +The fixture assignment is _deep_. In other words unless reset by another + {boost_fixture_test_suite} or {boost_fixture_test_case} definition the + same fixture is assigned to all test cases of a test suite, including ones that belong to the sub test suites. +==== + +// tag reference: doc/modules/ROOT/examples/fixture_02.run.cpp +:bt-name: fixture_02 +:bt-rule: run +:bt-descr: Test suite level fixture +include::partial$bt_example.adoc[] + +[CAUTION] +==== +The fixture constructor/setup and teardown/destructor is called for each test cases (the state of the + fixture is not shared among the test cases). +==== + +[#per_test_suite_fixture] +== Test suite entry/exit fixture + +It is possible to define a test suite entry/exit fixture, so that the `setup` function is called only once upon entering +the test suite, prior to running any of its test cases. +Similarly the `teardown` function is also called only once +upon the test suite exit, after all the enclosed test cases have been run. This is facilitated by the +_decorator_ {decorator_fixture}. + +// tag reference: doc/modules/ROOT/examples/fixture_03.run.cpp +:bt-name: fixture_03 +:bt-rule: run +:bt-descr: Test suite entry/exit fixture +include::partial$bt_example.adoc[] + +In case of this fixture type, however, it is not possible to access any members of the fixture object. + +CAUTION: This is not equivalent to using the method described xref:tests_organization/fixtures.adoc#test_case_fixture_subtree[here]. + +[#global] +== Global fixture + +Any global initialization that needs to be performed before any test begins, or a cleanup that is to be +performed after all tests are finished is called a _global fixture_. A global fixture is equivalent to a +xref:tests_organization/fixtures.adoc#per_test_suite_fixture[test-suite +entry/exit] fixture (executed once), where in this case the test-suite is the +xref:tests_organization/master_test_suite.adoc[master test suite]. + +The {utf} global fixture design is based on the +xref:tests_organization/fixtures.adoc#models[generic test class fixture model]. The global +fixture design allows any number of global fixtures to be defined in any test file that constitutes a test module. +Though some initialization can be implemented in the xref:adv_scenarios/test_module_init_overview.adoc[test module initialization function], +there are several reasons to prefer the global fixture approach: + +* There is no place for `cleanup`/`teardown` operations in the initialization function. +* Unlike the initialization function, the global fixture construction, `setup` and `teardown` methods invocation are guarded by the +execution monitor. That means that all uncaught errors that occur during initialization are properly reported. +* Any number of different global fixtures can be defined, which allows you to split initialization code by +category. +* The fixture allows you to place matching `setup`/`teardown` code in close vicinity in your test module code. +* If the whole test tree is constructed automatically, the initialization function is empty and auto-generated by +the {utf}. Introducing the initialization function can be more work than using the global fixture facility, +while global fixture is more to the point. +* Since all fixtures follow the same generic model you can easily switch from local per test case fixtures to +the global one. + +To define a global test module fixture you need: + +. to implement a class that matches the +xref:tests_organization/fixtures.adoc#models[fixture model] +. and to pass the class as an argument to the macro {boost_test_global_fixture}. + +[source,cpp] +---- +BOOST_TEST_GLOBAL_FIXTURE( fixture_name ); + +// if your fixture is within a namespace +namespace enclosing_namespace { + struct fixture_in_namespace { /* ... */ }; +} + +namespace enclosing_namespace { + BOOST_TEST_GLOBAL_FIXTURE( fixture_in_namespace ); +} +---- + +CAUTION: The statement defining the global fixture has to reside in a single compilation unit (no header). + +[CAUTION] +==== +Beware of other fixtures in other compilation units having the same name: if the fixtures have + different definition, this leads to an ODR violation. +==== + +// tag reference: doc/modules/ROOT/examples/fixture_04.run-fail.cpp +:bt-name: fixture_04 +:bt-rule: run-fail +:bt-descr: Global fixture +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/index.adoc b/doc/modules/ROOT/pages/tests_organization/index.adoc new file mode 100644 index 0000000000..8766d5f2bb --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/index.adoc @@ -0,0 +1,49 @@ += Declaring and organizing tests +:page-aliases: boost_test/tests_organization.adoc + +If you look at many legacy test modules, big chance is that it's implemented as one big test function that +consists of a mixture of check and output statements. Is there anything wrong with it? Yes. There are various +disadvantages in single test function approach: + +* One big function tends to become really difficult to manage if the number of checks exceeds a reasonable limit +(true for any large function). What is tested and where - who knows? +* Many checks require similar preparations. This results in code repetitions within the test function. +* If a fatal error or an exception is caused by any checks within the test function the rest of tests are +skipped and there is no way to prevent this. +* No way to perform only checks for a particular subsystem of the tested unit. +* No summary of how different subsystems of the tested unit performed under in the test. + +The above points should make it clear that it's preferable to split a xref:section_glossary.adoc#ref_test_module[test module] into smaller *units*. +These units are the *test cases*, the *test suites* and the *fixtures*. + +.Subjects covered by this section +[cols="1,3"] +|=== +|Declaration +a| +The {utf} supports several methods for declaring a xref:tests_organization/test_cases.adoc[test case]. + Test cases can be implemented using free function like syntax or based on actual free function, function object, + that can be defined with or without parameters/data, or as template functions to be run against various types. + +|Organization +a| +The {utf} provides facilities to group several test cases into xref:tests_organization/test_suite.adoc[test suites]. + The test suites can be nested, and the set of test suites and test cases defines the xref:tests_organization/test_tree.adoc[test tree], + where the leaves are the test cases. + Besides hierarchical structure the {utf} allows you to organize the test tree using xref:tests_organization/tests_grouping.adoc[logical grouping] + and xref:tests_organization/tests_dependencies.adoc[dependencies] + and provides you with controls to utilize the defined test tree organization the way you want (eg. from command line). + +|Attributes +a| +It is possible to specify test unit _attributes_ by using xref:tests_organization/decorators.adoc[decorators]. + Attributes are used for a fine grained control over various aspects of test module execution, such as _logical grouping_, + _dependencies_, _expected failures_, etc. + +|Setup/teardown test unit actions +a| +When several tests shares the same set-up (environment, test data preparation, etc.), the preparation and cleanup code + may be factorized in xref:tests_organization/fixtures.adoc[fixtures]. + In the {utf}, fixtures can be associated to test cases, test suites or globally to the test module. + +|=== diff --git a/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc b/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc new file mode 100644 index 0000000000..d1269b1ce5 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc @@ -0,0 +1,89 @@ += Master test suite +:page-aliases: boost_test/tests_organization/test_tree/master_test_suite.adoc + +As defined in introduction section the master test suite is the *root* node of the test tree. Each test module built +with the {utf} always has the (unique) master test suite defined. The {utf} maintain the master test suite instance +internally. All other test units are registered as direct or indirect children of the master test suite. + +[source,cpp] +---- +namespace boost { +namespace unit_test { +class master_test_suite_t : public test_suite +{ + /// implementation details +public: + int argc; + char** argv; +}; + +} // namespace unit_test +} // namespace boost +---- + +To access single instance of the master test suite use the following interface: + +[source,cpp] +---- +namespace boost { +namespace unit_test { +namespace framework { + +master_test_suite_t& master_test_suite(); + +} // namespace framework +} // namespace unit_test +} // namespace boost +---- + +== Command line arguments access interface + +Master test suite implemented as an extension to the regular test suite, since it maintains references to the +command line arguments passed to the test module. To access the command line arguments use + +[source,cpp] +---- +boost::unit_test::framework::master_test_suite().argc +boost::unit_test::framework::master_test_suite().argv +---- + +In below example references to the command line arguments are accessible either as an initialization function +parameters or as members of the master test suite. Both references point to the same values. A test module that +uses the alternative initialization function specification can only access command line arguments through the +master test suite. + +Returning to the free function example, let's modify initialization function to check for absence of any +test module arguments. + +// tag reference: doc/modules/ROOT/examples/example13.run.cpp +:bt-name: example13 +:bt-rule: run +:bt-descr: Command line access in initialization function +include::partial$bt_example.adoc[] + +[#ref_BOOST_TEST_MODULE] +== Naming the _Master test suite_ + +The master test suite is created with default name _Master Test Suite_. There are two methods two +reset the name to a different value: using the macro {boost_test_module} +and from within the test module initialization function. Former is used for test modules that don't have the +manually implemented initialization function. Following examples illustrate these methods. + +// tag reference: doc/modules/ROOT/examples/example14.run.cpp +:bt-name: example14 +:bt-rule: run +:bt-descr: Naming master test suite using the macro {boost_test_module} +include::partial$bt_example.adoc[] + +If the macro {boost_test_module} is defined, the test module initialization +function is *automatically generated* and the +macro value becomes the name of the master test suite. The name may include spaces. + +// tag reference: doc/modules/ROOT/examples/example15.run.cpp +:bt-name: example15 +:bt-rule: run +:bt-descr: Naming master test suite explicitly in the test module initialization function +include::partial$bt_example.adoc[] + +Without the {boost_test_main} and the {boost_test_module} flags defined, the test module initialization +function has to be manually implemented. The master test suite name can be reset at any point within this function. diff --git a/doc/modules/ROOT/pages/tests_organization/param_test.adoc b/doc/modules/ROOT/pages/tests_organization/param_test.adoc new file mode 100644 index 0000000000..529f7a17ef --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/param_test.adoc @@ -0,0 +1,77 @@ += Parametrized test cases +:page-aliases: boost_test/tests_organization/test_cases/param_test.adoc + +[CAUTION] +==== +the functionalities presented on this page have been superseded by the + xref:tests_organization/test_case_generation.adoc[Data-driven test case] facility. +==== + +Some tests are required to be repeated for a series of different input parameters. One way to achieve this is +manually register a test case for each parameter as in the previous examples. You can also invoke a test function with +all parameters manually from within your test case, like this: + +[source,cpp] +---- +void single_test( int i ) +{ + BOOST_CHECK( /* test assertion */ ); +} + +void combined_test() +{ + int params[] = { 1, 2, 3, 4, 5 }; + std::for_each( params, params+5, &single_test ); +} +---- + +The {utf} presents a better solution for this problem: the unary function based test case, also referred as +_parametrized test case_. The unary test function can be a free function, unary functor (for example created +with `boost::bind`) or unary method of a class with bound test class instance). The test function is converted +into test case using the macro `BOOST_PARAM_TEST_CASE`. The macro expects a collection of parameters (passed as +two input iterators) and an unary test function: + +[source,cpp] +---- +BOOST_PARAM_TEST_CASE(test_function, params_begin, params_end); +---- + +`BOOST_PARAM_TEST_CASE` creates an instance of the test case generator. When passed to the method +cpp:boost::unit_test::test_suite::add[`test_suite::add`], the generator produces a separate sub test case +for each parameter in the parameters collection and registers it immediately in a test suite. +Each test case is based on a test function with the parameter bound by value, +even if the test function expects a parameter by reference. The fact that parameter value is stored along with +bound test function releases you from necessity to manage parameters lifetime. For example, they can be defined +in the test module initialization function scope. + +All sub test case names are deduced from the macro argument `test_function`. If you prefer to assign different +names, you have to use the underlying link:{base-url}/boost/test/parameterized_test.hpp[`make_test_case`] interface instead. Both test cases creation and +registration are performed in the test module initialization function. + +The parametrized test case facility is preferable to the approach in the example above, since execution of +each sub test case is guarded and counted independently. It produces a better test log/results report (in +example above in case of failure you can't say which parameter is at fault) and allows you to test against +all parameters even if one of them causes termination a particular sub test case. + +In comparison with a manual test case registration for each parameter approach the parametrized test case +facility is more concise and easily extensible. + +In following simple example the same test, implemented in `free_test_function`, is +performed for 5 different parameters. The parameters are defined in the test module initialization function +scope. The master test suite contains 5 independent test cases. + +// tag reference: doc/modules/ROOT/examples/example07.run-fail.cpp +:bt-name: example07 +:bt-rule: run-fail +:bt-descr: Unary free function based test case +include::partial$bt_example.adoc[] + +Next example is similar, but instead of a free function it uses a method of a class. Even though parameters are +passed into test method by reference you can still define them in the test module initialization function scope. +This example employs the alternative test module initialization function specification. + +// tag reference: doc/modules/ROOT/examples/example08.run-fail.cpp +:bt-name: example08 +:bt-rule: run-fail +:bt-descr: Unary class method based test case +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/semantic.adoc b/doc/modules/ROOT/pages/tests_organization/semantic.adoc new file mode 100644 index 0000000000..be1b01824b --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/semantic.adoc @@ -0,0 +1,20 @@ += Adding semantic to a test +:page-aliases: boost_test/tests_organization/semantic.adoc + +It is sometimes useful to add a _semantic description_ to a test unit, which may be consulted by the user during a dry +run. The user may then choose the test he/she wants to run based on this information, instead of basing his/her choice +on the test unit _name_, or instead of looking at the code. + +The {utf} provides the decorator {decorator_description} for that purpose. + +Decorator `description` attaches an arbitrary string to the test unit. All strings attached to test units can be +displayed when running a test program with parameter xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. +This can be used for conveying information from the person who composes the test tree to the person who will be +running the test program. Applying more than one decorator `description` to the same test unit means that the two +(or more) strings will be concatenated. + +// tag reference: doc/modules/ROOT/examples/decorator_09.run.cpp +:bt-name: decorator_09 +:bt-rule: run +:bt-descr: decorator description +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/summary.adoc b/doc/modules/ROOT/pages/tests_organization/summary.adoc new file mode 100644 index 0000000000..a8fbec2ee6 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/summary.adoc @@ -0,0 +1,85 @@ += Summary of the API for declaring and organizing tests +:page-aliases: boost_test/tests_organization/summary.adoc + +[%header%autowidth,cols="2*"] +|=== +|Macro +|Short description + +|{boost_test_case} / {boost_test_case_name} +|Manual registration of a test case + +|{boost_auto_test_case} +|Automatic declaration and registration of a test case + +|{boost_param_test_case} +|Automatic declaration and registration of a test case with a collection of parameters + +|{boost_auto_test_case_template} +|Automatic declaration and registration of a typed test case + +|{boost_test_case_template} +|Registration of a typed test case with an `boost::mpl` like sequence of types + +|{boost_test_case_template_function} +|Declaration of the body of a typed test case + +|{boost_data_test_case} +|Declaration of the body of a test case on datasets + +|{boost_data_test_case_f} +|Same as {boost_data_test_case} with fixtures support + +|{boost_test_dataset_max_arity} +|Controlling the maximal arity of the data test case declared with {boost_data_test_case} + +|{boost_test_suite} +|Manual creation of a test suite instance + +|{boost_auto_test_suite} +|Automatic declaration of a test suite + +|{boost_auto_test_suite_end} +|Automatic declaration of a test suite + +|{boost_test_decorator} +|Adds decorators to a test unit + +|{boost_fixture_test_case} +|Declares a test case with a fixture + +|{boost_fixture_test_suite} +|Declares a fixture for a test suite (the setup/teardown is called for each test of the test suite) + +|{boost_test_global_fixture} +|Declares a fixture globally to the test module + +|=== + +[%header%autowidth,cols="2*"] +|=== +|Decorator +|Short description + +|{decorator_depends_on} +|Creates a dependency (in the execution order and {default_run_status}) from one test case to another. + +|{decorator_description} +|Attaches a semantic string to a test unit, that is visible from the command line interface. + +|{decorator_enabled} , {decorator_disabled} +|Enables or disables unconditionally a test unit. The action of these decorators may be overridden by the command line interface + +|{decorator_enable_if} +|Enables conditionally a test unit. The action of these decorators may be overridden by the command line interface + +|{decorator_fixture} +|Attaches a fixture to a test unit + +|{decorator_label} +|Labels a test unit to form a logical group + +|{decorator_precondition} +|Enables or disables a test unit based on a predicate evaluated just before the execution of the test case. + +|=== diff --git a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc new file mode 100644 index 0000000000..79a861a427 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc @@ -0,0 +1,614 @@ += Data-driven test cases +:page-aliases: boost_test/tests_organization/test_cases/test_case_generation.adoc + +== Why data-driven test cases? + +Some tests are required to be repeated for a series of different input parameters. One way to achieve this is +manually register a test case for each parameter. You can also invoke a test function with +all parameters manually from within your test case, like this: + +[source,cpp] +---- +void single_test( int i ) +{ + BOOST_TEST( /* test assertion */ ); +} + +void combined_test() +{ + int params[] = { 1, 2, 3, 4, 5 }; + std::for_each( params, params+5, &single_test ); +} +---- + +The approach above has several drawbacks: + +* the logic for running the tests is inside a test itself: `single_test` in the above example is run from the test +case `combined_test` while its execution would be better handled by the {utf} +* in case of fatal failure for one of the values in `param` array above (say a failure in {boost_test_require}), +the test `combined_test` is aborted and the next test-case in the test tree is executed. +* in case of failure, the reporting is not accurate enough: the test should certainly be reran during debugging +sessions by a human or additional logic for reporting should be implemented in the test itself. + +== Parameter generation, scalability and composition + +In some circumstance, one would like to run a parametrized test over an _arbitrary large_ set of values. Enumerating the +parameters by hand is not a solution that scales well, especially when these parameters can be described in another +function that generates these values. However, this solution has also limitations + +* *Generating functions*: suppose we have a function `func(float f)`, where `f` is any number in 0, 1. We are not +interested that much in the exact value, but we would like to test `func`. What about, instead of writing the `f` +for which `func` will be tested against, we choose randomly `f` in 0, 1? And also what about instead of having +only one value for `f`, we run the test on arbitrarily many numbers? We easily understand from this small example +that tests requiring parameters are more powerful when, instead of writing down constant values in the test, a +generating function is provided. +* *Scalability*: suppose we have a test case on `func1`, on which we test `N` values written as constant in the test +file. What does the test ensure? We have the guaranty that `func1` is working on these `N` values. Yet in this +setting `N` is necessarily finite and usually small. How would we extend or scale `N` easily? One solution is to +be able to generate new values, and to be able to define a test on the *class* of possible inputs for `func1` on +which the function should have a defined behavior. To some extent, `N` constant written down in the test are just +an excerpt of the possible inputs of `func1`, and working on the class of inputs gives more flexibility and power +to the test. +* *Composition*: suppose we already have test cases for two functions `func1` and `func2`, taking as argument the +types `T1` and `T2` respectively. Now we would like to test a new functions `func3` that takes as argument a type +`T3` containing `T1` and `T2`, and calling `func1` and `func2` through a known algorithm. An example of such a +setting would be +`// Returns the log of x +// Precondition: x strictly positive. +double fast_log(double x); ++ +// Returns 1/(x-1) +// Precondition: x != 1 +double fast_inv(double x); ++ +struct dummy \{ +unsigned int field1; +unsigned int field2; +}; ++ +double func3(dummy value) +\{ +return 0.5 * (exp(fast_log(value.field1))/value.field1 + value.field2/fast_inv(value.field2)); +}` ++ +In this example, +** `func3` inherits from the preconditions of `fast_log` and `fast_inv`: it is defined in `(0, +infinity)` and in `[-C, +C] - \{1}` for `field1` and `field2` respectively (`C` +being a constant arbitrarily big). +** as defined above, `func3` should be close to 1 everywhere on its definition domain. +** we would like to reuse the properties of `fast_log` and `fast_inv` in the compound function `func3` and assert that `func3` is well defined over an arbitrary large definition domain. ++ +Having parametrized tests on `func3` hardly tells us about the possible numerical properties or instabilities close to the point `+{field1 = 0, field2 = 1}+`. +Indeed, the parametrized test may test for some points around (0,1), but will fail to provide an *asymptotic behavior* of the function close to this point. + +== Data driven tests in the Boost.Test framework + +The facilities provided by the {utf} addressed the issues described above: + +* the notion of *datasets* eases the description of the class of inputs for test cases. The datasets also implement several +operations that enable their combinations to create new, more complex datasets, +* two macros, {boost_data_test_case} and {boost_data_test_case_f}, respectively without and with fixture support, +are used for the declaration and registration of a test case over a collection of values (samples), +* each test case, associated to a unique value, is executed independently from others. These tests are guarded in the same +way regular test cases are, which makes the execution of the tests over each sample of a dataset isolated, robust, +repeatable and ease the debugging, +* several datasets generating functions are provided by the {utf} + +The remainder of this section covers the notions and feature provided by the {utf} about the data-driven test cases, in +particular: + +. the notion of xref:tests_organization/test_case_generation.adoc#datasets[*dataset* and *sample*] is introduced +. xref:tests_organization/test_case_generation.adoc#datasets_auto_registration[the declaration and registration] +of the data-driven test cases are explained, +. the xref:tests_organization/test_case_generation.adoc#operations[_operations_] on datasets are detailed +. and finally the built-in xref:tests_organization/test_case_generation.adoc#generators[dataset generators] +are introduced. + +[#datasets] +== Datasets + +To define properly datasets, the notion of *sample* should be introduced first. A *sample* is defined as _polymorphic tuple_. +The size of the tuple will be by definition the *arity* of the sample itself. + +A *dataset* is a _collection of samples_, that + +* is forward iterable, +* can be queried for its `size` which in turn can be infinite, +* has an arity which is the arity of the samples it contains. + +Hence the dataset implements the notion of _sequence_. + +The descriptive power of the datasets in {utf} comes from + +* the xref:tests_organization/test_case_generation.adoc#dataset_interface[interface] for creating a custom datasets, which is quite simple, +* the xref:tests_organization/test_case_generation.adoc#operations[operations] they provide for combining different datasets +* their interface with other type of collections (`stl` containers, `C` arrays) +* the available built-in xref:tests_organization/test_case_generation.adoc#generators[_dataset generators_] + +[TIP] +==== +Only "monomorphic" datasets are supported, which means that all samples within a single dataset have the same type and same arity + footnote:[polymorphic datasets will be considered in the future. Their need is mainly driven by the replacement of the + xref:tests_organization/test_organization_templates.adoc[typed parametrized test cases\] by the dataset-like API.] + . However, dataset of different sample types may be combined together with zip and cartesian product. +==== + +As we will see in the next sections, datasets representing collections of different types may be combined together (e.g.. _zip_ or _grid_). +These operations result in new datasets, in which the samples are of an augmented type. + +[#dataset_interface] +=== Dataset interface + +The interface of the _dataset_ should implement the two following functions/fields: + +* `iterator begin()` where _iterator_ is a forward iterator, +* `boost::unit_test::data::size_t size() const` indicates the size of the dataset. The returned type is a dedicated +class cpp:boost::unit_test::data::size_t[size_t] that can indicate an _infinite_ dataset size. +* a `static const int` data member called `arity` indicating the arity of the samples returned by the dataset + +Once a dataset class `D` is declared, it should be registered to the framework by specializing the template class + +[source,cpp] +---- +boost::unit_test::data::monomorphic::is_dataset +---- + +with the condition that `boost::unit_test::data::monomorphic::is_dataset::value` evaluates to `true`. + +The following example implements a custom dataset generating a Fibonacci sequence. + +// tag reference: doc/modules/ROOT/examples/dataset_example68.run-fail.cpp +:bt-name: dataset_example68 +:bt-rule: run-fail +:bt-descr: Example of custom dataset +include::partial$bt_example.adoc[] + +[#dataset_creation_and_delayed_creation] +=== Dataset creation and delayed creation + +Datasets as defined above are constructed before even the test module starts its execution as global objects. This makes impossible to access, +from within the dataset generator and during their iteration, elements like `argc` / `argv`, the +xref:tests_organization/master_test_suite.adoc[master test suite] (and the preprocessed `argc` / `argv`), or any other object +that has been instantiated after the `main` of the test module entry. + +To overcome this, a *delayed* dataset instantiation interface has been introduced. This effectively wraps the dataset inside another one, +which *lazyly* instantiates the dataset. + +To instantiate a delayed dataset, the cpp:boost::unit_test::data::monomorphic::make_delayed[boost::unit_test::data::monomorphic::make_delayed] function should be used in the +{boost_data_test_case} call. The following snippet: + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(dataset_test_case, + boost::unit_test::data::make_delayed(arg1, ... ), ...) +{ +} +---- + +creates a delayed dataset test case with a generator of type `custom_dataset`. The generator is _lazily_ constructed +with `arg1`, `...`. + +[TIP] +==== +A detailed example of delayed creation is given in the section about xref:runtime_config/runtime_custom.adoc[custom command line] + arguments. +==== + +[TIP] +==== +See the class cpp:boost::unit_test::data::monomorphic::delayed_dataset[`monomorphic::delayed_dataset`] for more details on the + wrapping object. +==== + +[#datasets_auto_registration] +== Declaring and registering test cases with datasets + +In order to declare and register a data-driven test-case, the macros {boost_data_test_case} or {boost_data_test_case_f} +should be used. Those two forms are equivalent, with the difference that `BOOST_DATA_TEST_CASE_F` supports fixtures. + +Those macros are variadic and can be used in the following forms: + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(test_case_name, dataset) { /* dataset1 of arity 1 */ } +BOOST_DATA_TEST_CASE(test_case_name, dataset, var1) { /* datasets of arity 1 */ } +BOOST_DATA_TEST_CASE(test_case_name, dataset, var1, ..., varN) { /* datasets of arity N */ } + +BOOST_DATA_TEST_CASE_F(fixture, test_case_name, dataset) { /* dataset1 of arity 1 with fixture */ } +BOOST_DATA_TEST_CASE_F(fixture, test_case_name, dataset, var1) { /* dataset1 of arity 1 with fixture */ } +BOOST_DATA_TEST_CASE_F(fixture, test_case_name, dataset, var1, ..., varN) { /* dataset1 of arity N with fixture */ } +---- + +The first form of the macro is for datasets of arity 1. The value of the sample being executed by the test body is +available through the automatic variable `sample` (`xrange` is as its name suggests a range of values): + +[source,cpp] +---- +include::example$snippets/dataset_1/test_file.cpp[tag=snippet_dataset1_1] +---- + +The second form is also for datasets of arity 1, but instead of the variable `sample`, the current sample is brought into `var1`: + +[source,cpp] +---- +include::example$snippets/dataset_1/test_file.cpp[tag=snippet_dataset1_2] +---- + +The third form is an extension of the previous form for datasets of arity `N`. The sample being a polymorphic tuple, each +of the variables `var1`, ..., `varN` corresponds to the index 1, ... `N` of the the sample: + +[source,cpp] +---- +include::example$snippets/dataset_1/test_file.cpp[tag=snippet_dataset1_3] +---- + +The next three forms of declaration, with `BOOST_DATA_TEST_CASE_F`, are equivalent to the previous ones, with the difference being in the support of +a fixture that is execute before the test body for each sample. The fixture should follow the expected interface as detailed +xref:tests_organization/fixtures.adoc#models[here]. + +The arity of the dataset and the number of variables should be exactly the same, the first form being a short-cut for the +case of arity 1. + +[TIP] +==== +A compilation-time check is performed on the coherence of the arity of the dataset and the number of variables `var1`... `varN`. + For compilers *without C++11* support, the maximal supported arity is controlled by the macro + {boost_test_dataset_max_arity}, that can be overridden _prior_ to including the {utf} headers. +==== + +CAUTION: The macros {boost_data_test_case} and {boost_data_test_case_f} are available only for compilers with support for *variadic macros*. + +=== Samples and test tree + +It should be emphasized that those macros do not declare a single test case (as {boost_auto_test_case} would do) but declare and +register as many test cases as there are samples in the dataset given in argument. Each test case runs on exactly *one* +sample of the dataset. + +More precisely, what + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(test_case_name, dataset) +---- + +does is the following: + +* it registers a *test suite* named "`test_case_name`", +* it registers as many test cases as they are in "`dataset`", each of which with the name corresponding to the index of the sample +in the database prefixed by `+_+` and starting at index `0` ("`+_0+`", "`+_1+`", ... "`+_(N-1)+`" where `N` is the size of the dataset) + +This make it easy to: + +* identify which sample is failing (say "`test_case_name/_3`"), +* replay the test for one or several samples (or the full dataset) from the command line using the xref:runtime_config/test_unit_filtering.adoc[test filtering features] provided by the {utf}, +* apply a xref:tests_organization/decorators.adoc#explicit_decorator_declaration[decorator] to each individual test cases of the +dataset, as the decorator would apply to the test suite. + +Exactly as regular test cases, each test case (associated to a specific sample) is executed in _monitored manner_: + +* the test execution are independent: if an error occurs for one sample, the remaining samples execution is not affected, +* in case of error, the xref:test_output/contexts.adoc[context] along with the index of the sample +within which the error occurred is reported in the xref:test_output/index.adoc[log]. +This context contains the sample names and values for which the test failed, which would ease the debugging. + +[#operations] +== Operations on dataset + +As mentioned earlier, one of the major aspects of using the {utf} datasets lies in the number of operations provided +for their combination. + +For that purpose, three operators are provided: + +* joins with `operator+` +* zips with `+operator^+` on datasets +* and grids or Cartesian products with `+operator*+` + +[TIP] +==== +All these operators are associative, which enables their combination without parenthesis. However, the precedence rule on the +operators for the language still apply. +==== + +[#joins] +=== Joins + +A _join_, denoted `+`, is an operation on two datasets `dsa` and `dsb` of same arity and compatible types, resulting in the *concatenation* of these two datasets `dsa` and `dsb` +from the left to the right order of the symbol `+`: + +[source,cpp] +---- +dsa = (a_1, a_2, ... a_i) +dsb = (b_1, b_2, ... b_j) +dsa + dsb = (a_1, a_2, ... a_i, b_1, b_2, ... b_j) +---- + +The following properties hold: + +* the resulting dataset is of same arity as the operand datasets, +* the size of the returned dataset is the sum of the size of the joined datasets, +* the operation is associative, and it is possible to combine more than two datasets in one expression. The following joins are equivalent for any datasets `dsa`, `dsb` and `dsc`: +`( dsa + dsb ) + dsc +== dsa + ( dsb + dsc ) +== dsa + dsb + dsc` + +[WARNING] +==== +In the expression `dsa + dsb`, `dsa` and/or `dsb` can be of infinite size. The resulting dataset will have an infinite size as well. If `dsa` is infinite, the content of + `dsb` will never be reached. +==== + +// tag reference: doc/modules/ROOT/examples/dataset_example62.run.cpp +:bt-name: dataset_example62 +:bt-rule: run +:bt-descr: Example of join on datasets +include::partial$bt_example.adoc[] + +[#zips] +=== Zips + +A _zip_, denoted `+^+` , is an operation on two datasets `dsa` and `dsb` of same arity and same size, resulting in a dataset where the `k`-th sample of `dsa` is paired with the corresponding `k`-th sample of `dsb`. +The resulting dataset samples order follows the left to right order against the symbol `+^+`. + +[source,cpp] +---- +dsa = (a_1, a_2, ... a_i) +dsb = (b_1, b_2, ... b_i) +dsa ^ dsb = ( (a_1, b_1), (a_2, b_2) ... (a_i, b_i) ) +---- + +The following properties hold: + +* the arity of the resulting dataset is the sum of the arities of the operand datasets, +* the size of the resulting dataset is equal to the size of the datasets (since they are supposed to be of the same size), +exception made for the case the operand datasets size mismatch (see below), +* the operation is associative, and it is possible to combine more than two datasets in one expression, +`+( dsa ^ dsb ) ^ dsc +== dsa ^ ( dsb ^ dsc ) +== dsa ^ dsb ^ dsc+` + +A particular handling is performed if `dsa` and `dsb` are of different size. The rule is as follow: + +* if the both zipped datasets have the same size, this is the size of the resulting dataset (this size can then be infinite). +* otherwise if one of the dataset is of size 1 (singleton) or of infinite size, the resulting size is governed by the other dataset. +* otherwise an exception is thrown at runtime + +[CAUTION] +==== +If the _zip_ operation is not supported for your compiler, the macro xref:utf_reference/link_references.adoc#config_no_zip_composition[`BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`] + will be automatically set by the {utf} +==== + +// tag reference: doc/modules/ROOT/examples/dataset_example61.run.cpp +:bt-name: dataset_example61 +:bt-rule: run +:bt-descr: Example of zip on datasets +include::partial$bt_example.adoc[] + +[#grid_cartesian_products] +=== Grid (Cartesian products) + +A _grid_, denoted `+*+` , is an operation on two any datasets `dsa` and `dsb` resulting in a dataset where each sample of `dsa` is paired with each sample of `dsb` +exactly once. The resulting dataset samples order follows the left to right order against the symbol `+*+`. The rightmost dataset samples are iterated first. + +[source,cpp] +---- +dsa = (a_1, a_2, ... a_i) +dsb = (b_1, b_2, ... b_j) +dsa * dsb = ((a_1, b_1), (a_1, b_2) ... (a_1, b_j), (a_2, b_1), ... (a_2, b_j) ... (a_i, b_1), ... (a_i, b_j)) +---- + +The grid hence is similar to the mathematical notion of Cartesian product footnote:[if the sequence is viewed as a set]. + +The following properties hold: + +* the arity of the resulting dataset is the sum of the arities of the operand datasets, +* the size of the resulting dataset is the product of the sizes of the datasets, +* the operation is associative, and it is possible to combine more than two datasets in one expression, +* as for _zip_, there is no need the dataset to have the same type of samples. + +[CAUTION] +==== +If the _grid_ operation is not supported for your compiler, the macro xref:utf_reference/link_references.adoc#config_no_grid_composition[`BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE`] + will be automatically set by the {utf} +==== + +In the following example, the random number generator is the second dataset. Its state is evaluated 6 times (3 times for the first `xrange` - first dimension - +and twice for the second `xrange` - second dimension - to which it is zipped). Note that the state of the random engine is +not copied between two successive evaluations of the first dimension. + +// tag reference: doc/modules/ROOT/examples/dataset_example64.run-fail.cpp +:bt-name: dataset_example64 +:bt-rule: run-fail +:bt-descr: Example of Cartesian product +include::partial$bt_example.adoc[] + +[#generators] +== Datasets generators + +Several _generators_ for datasets are implemented in {utf}: + +* xref:tests_organization/test_case_generation.adoc#singletons[Singletons] +* xref:tests_organization/test_case_generation.adoc#stl[`forward iterable`] containers and +xref:tests_organization/test_case_generation.adoc#c_arrays[`C` array] like datasets +* xref:tests_organization/test_case_generation.adoc#ranges[ranges] or sequences of values +* datasets made of xref:tests_organization/test_case_generation.adoc#random[random numbers] and following a particular distribution + +`stl` and `C-array` generators are merely a dataset view on existing collection, while ranges and random number sequences are +describing new datasets. + +[#singletons] +=== Singletons + +A singleton is a dataset containing a unique value. The size and arity of such a dataset is 1. This value can be + +* either consumed once +* or repeated as many times as needed in a zip operation + +As mentioned in _zip_, when zipped with a distribution of infinite size, the resulting dataset will have +a size of 1. + +The singleton is constructible through the function cpp:boost::unit_test::data::make[boost::unit_test::data::make]. + +// tag reference: doc/modules/ROOT/examples/dataset_example65.run.cpp +:bt-name: dataset_example65 +:bt-rule: run +:bt-descr: Singleton +include::partial$bt_example.adoc[] + +[#c_arrays] +=== Datasets from C arrays + +This type of datasets does not contains the logic for generating the sequence of values, and is used as a wrapper on an existing +sequence contained in a `C` array. The arity is 1 and the size is the size of the array. + +Such datasets are simply constructed from an overload of the cpp:boost::unit_test::data::make[`make`] function. + +// tag reference: doc/modules/ROOT/examples/dataset_example66.run.cpp +:bt-name: dataset_example66 +:bt-rule: run +:bt-descr: Array +include::partial$bt_example.adoc[] + +[#stl] +=== Datasets from forward iterable containers + +As for `C` arrays, this type of datasets does not contain the logic for generating sequence of values, and are used for parsing an existing sequence. +The arity is 1 and the size is the same as the one of the container. + +[TIP] +==== +C++11 implementation enables the dataset generation from any container which iterator implements the forward iterator concept. + For C++03, the feature is enabled on most STL containers. +==== + +// tag reference: doc/modules/ROOT/examples/dataset_example67.run.cpp +:bt-name: dataset_example67 +:bt-rule: run +:bt-descr: Dataset from `std::vector` and `std::map` +include::partial$bt_example.adoc[] + +[#ranges] +=== Ranges + +A range is a dataset that implements a sequence of equally spaced values, defined by a _start_, and _end_ and a _step_. + +It is possible to construct a range using the factory cpp:boost::unit_test::data::xrange[boost::unit_test::data::xrange], available in the overloads below: + +[source,cpp] +---- +#include +#include + +auto range1 = data::xrange( (data::step = 0.5, data::end = 3 ) ); // Constructs with named values, starting at 0 +auto range2 = data::xrange( begin, end ); // begin < end required +auto range5 = data::xrange( begin, end, step ); // begin < end required +auto range3 = data::xrange( end ); // begin=0, end cannot be <= 0, see above +auto range4 = data::xrange( end, (data::begin=1) ); // named value after end +---- + +TIP: The named value parameters should be declared inside parenthesis + +==== Parameters + +The details of the named value parameters is given in the table below. + +[#id_range_parameter_table] +.Range parameters +[%header%autowidth,cols="3*"] +|=== +|Name +|Default +|Description + +|`begin` +|0 +a| +Beginning of the generated sequence. The `begin` value is included in set of values returned + by the generator. + +|`end` +|{empty}+ infinity +a| +End of the generated sequence. The `end` value is not included in set of values returned + by the generator. If omitted, the generator has infinite size. + +|`step` +|1 +a| +Number indicating the step between two consecutive samples of the generated range. + The default type is the same as the input type. This value should not be 0. It should be of the same + sign as `end-begin`. + +|=== + +// tag reference: doc/modules/ROOT/examples/dataset_example59.run-fail.cpp +:bt-name: dataset_example59 +:bt-rule: run-fail +:bt-descr: Declaring a test with a range +include::partial$bt_example.adoc[] + +[#random] +=== Random value dataset + +This type of dataset generates a sequence of random numbers following a given _distribution_. The _seed_ and the _engine_ may also be +specified. + +[CAUTION] +==== +The random value generator is available only for C++11 capable compilers. If this feature is not supported for your compiler, + the macro xref:utf_reference/link_references.adoc#config_no_random_dataset[`BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`] + will be automatically set by the {utf} +==== + +It is possible to construct a random sequence using the factory cpp:boost::unit_test::data::random[boost::unit_test::data::random], available in the overloads below: + +[source,cpp] +---- +auto rdgen = random(); // uniform distribution (real) on [0, 1) +auto rdgen = random(1, 17); // uniform distribution (integer) on [1, 17] +// Default random generator engine, Gaussian distribution (mean=5, sigma=2) and seed set to 100. +auto rdgen = random( (data::seed = 100UL, + data::distribution = std::normal_distribution<>(5.,2)) ); +---- + +Since the generated datasets will have infinite size, the sequence size should be narrowed by combining the dataset with another +one through e.g. a _zip_ operation. + +[TIP] +==== +In order to be able to reproduce a failure within a randomized parameter test case, the seed that generated the failure may be +set in order to generate the same sequence of random values. +==== + +==== Parameters + +The details of the named value parameters is given in the table below. + +[#id_random_parameter_table] +.Range parameters +[%header%autowidth,cols="3*"] +|=== +|Parameter name +|Default +|Description + +|`seed` +|(not set) +|Seed for the generation of the random sequence. + +|`distribution` +|Uniform +a| +Distribution instance for generating the random number sequences. The `end` value is not included in set of values returned + by the generator for real values, and is included for integers. + +|`engine` +|`std::default_random_engine` +|Random number generator engine. + +|=== + +// tag reference: doc/modules/ROOT/examples/dataset_example63.run-fail.cpp +:bt-name: dataset_example63 +:bt-rule: run-fail +:bt-descr: Declaring a test with a random sequence +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/test_cases.adoc b/doc/modules/ROOT/pages/tests_organization/test_cases.adoc new file mode 100644 index 0000000000..4970c153b2 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_cases.adoc @@ -0,0 +1,49 @@ += Test cases +:page-aliases: boost_test/tests_organization/test_cases.adoc + +A test case is a unit of execution that is run by the xref:section_glossary.adoc#test_runner[test runner]. It contains instructions and +xref:testing_tools/boost_test_universal_macro.adoc[assertions], and its execution is monitored by the {utf}. +Information about the execution is recorded, and a log/report is produced. + +The test runner should be informed of the test case in order to run it: the test case should be *registered* for its +inclusion into the _test tree_. + +The {utf} covers the following test case scenarios: + +* *test cases without parameters*: those are similar to the run of a function in the controlled environment of the test runner. +* *test cases with parameters*: this usage is intended to run the same function with potentially many different parameters, +each call with a different parameter being handled by the test runner. +* *test cases on template*: the scenario is to test the same template implementation against several type. + +The test case have a different *declaration* APIs for each of the above scenarios. Preferred APIs will declare the test case +and register it automatically in a test tree without a necessity to perform manual registration. + +== Manual registration + +While automatic registration is preferred test case declaration API, it is also possible to declare tests manually. +For this APIs, {utf} opted for a least intrusive design based on _generic callback_ approach, which signatures +depends on the king of test case being declared. + +The single test module may mix both automated and manual test case +registration. In other words, within the same test module you can have both test cases implemented remotely and +registered manually in the test module initialization function and test cases that are registered automatically at +implementation point. + +[CAUTION] +==== +The design of manual test case declaration API in {utf} assumes the test case implementation (test function body) +and test case creation/registration points are remote. As a result you may forget to register the test case +and it's never going to be executed, even though it's present in test file. +==== + +You need to be sure you exhausted all possible ways to employ automatic registration APIs first before you opt +to use manual registration. Specifically: + +* If you need optionally include/exclude some of the test cases, consider using +{decorator_enabled} _ {decorator_disabled} _ {decorator_enable_if} decorators instead +* If you need to register some parametrized test cases based on some data, consider +xref:tests_organization/test_case_generation.adoc[data-driven] test cases instead +* If you need to specify complicated test unit dependencies, you can use {decorator_depends_on} +decorator instead +* if you need to share the logic between the test units consider using +xref:tests_organization/fixtures.adoc[fixtures] instead diff --git a/doc/modules/ROOT/pages/tests_organization/test_naming.adoc b/doc/modules/ROOT/pages/tests_organization/test_naming.adoc new file mode 100644 index 0000000000..006c2f418a --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_naming.adoc @@ -0,0 +1,46 @@ += Tests naming +:page-aliases: boost_test/tests_organization/test_tree/test_naming.adoc + +== Acceptable characters for names + +The {utf} is flexible on the naming the test units (test cases/suites) and +it is possible to use a wide variety of characters. However there are scenarios +where the name of a test unit may collide with other features +of the {utf}. For instance: + +* a character may collide with specific command line filters for selecting a +subset of the test tree. Among those characters: `'@'`, `'+'` or `'/'` +(see xref:runtime_config/test_unit_filtering.adoc[this section] for +more details) +* a name containing a character that is reserved for the shell/terminal, such as +'!', '\*' ..., may prevent the test name to be passed on the command line *as is*. + +To prevent any conflicting declaration, the {utf} *sanitizes* the name given to +a test unit (case or suite), prior to adding the test to the test tree. Any +conflicting character is replaced by an underscore `'_'`. + +[NOTE] +==== +*Spaces* are not considered as _special chars_ and are preserved, except for the + leading and trailing spaces which are removed. +==== + +NOTE: The sanitization of the test unit names has been introduced in xref:change_log.adoc#ref_CHANGE_LOG_3_7[Boost 1.67]. + +== Constraints on test names + +The {utf} considers an error if two sibling test cases have the same name. This consistency check is performed +at runtime and is not sensitive to test filtering. + +For test-cases registered automatically, and within the same compilation unit, a compilation error should be raised by +the compiler in case of name conflict. +For manual registration of test cases and in case of conflicts, the too {boost_test_case_name} may be used. + +The data driven tests are automatically created in an isolated test-suite and with a name that is indexed on the +sample. + +[NOTE] +==== +This constraints does not apply to test-suites: Opening/closing a test-suite declaration + adds the test-cases to an existing or newly created test-suite of that name. +==== diff --git a/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc new file mode 100644 index 0000000000..26eab982b8 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc @@ -0,0 +1,80 @@ += Test cases without parameters +:page-aliases: boost_test/tests_organization/test_cases/test_organization_nullary.adoc + +The most common scenario is that you want to write test case without any parameters. The {utf} provides you with both +automatic and manual registration APIs to declare such test case. + +[#ref_BOOST_AUTO_TEST_CASE] +== Automated registration + +To declare a test case without parameters, which is registered in place of implementation, employ the +macro {boost_auto_test_case}. + +[source,cpp] +---- +BOOST_AUTO_TEST_CASE(test_case_name); +---- + +This API is designed to closely mimic nullary free function declaration syntax. +In comparison with free function all you need to do is to skip result type and brackets and wrap test +case name into BOOST_AUTO_TEST_CASE: + +// tag reference: doc/modules/ROOT/examples/example06.run.cpp +:bt-name: example06 +:bt-rule: run +:bt-descr: Nullary function based test case with automated registration +include::partial$bt_example.adoc[] + +With this macro you don't need to implement any other registration steps. The macro creates and +registers the test case with the name `free_test_function` automatically. + +[#ref_BOOST_TEST_CASE] +== Manual registration + +The {utf} allows to manually create test case without parameters based on nullary free functions, nullary +function objects (including those created with `boost::bind` and nullary `boost::function` +instances). To do this, employ the macro {boost_test_case}: + +[source,cpp] +---- +BOOST_TEST_CASE(test_function); +---- + +{boost_test_case} creates an instance of the class cpp:boost::unit_test::test_case[boost::unit_test::test_case] and returns a pointer to the +constructed instance. The test case name is deduced from the macro argument test_function. If you prefer to +assign a different test case name, you have either to + +* use the macro {boost_test_case_name} instead +* or use the underlying link:{base-url}/boost/test/tree/test_unit.hpp[`make_test_case`] interface instead. + +To register a new test case, employ the method cpp:boost::unit_test::test_suite::add[`test_suite::add`]. +Both test case creation and registration are performed in the +xref:adv_scenarios/test_module_init_overview.adoc[test module initialization function]. + +Here is the simplest example of manually registered test case. A single test case is created and registered inside +the test module initialization routine. Note that the free function name is passed by address to the macro {boost_test_case}\`. + +[#ref_bt_example01] +// tag reference: doc/modules/ROOT/examples/example01.run.cpp +:bt-name: example01 +:bt-rule: run +:bt-descr: Nullary free function manually registered +include::partial$bt_example.adoc[] + +A test case can be implemented as a method of a class. In this case a pointer to the class instance has to be +bound to the test method to create a test case. You can use the same instance of the class for multiple test +cases. The {utf} doesn't take an ownership of the class instance and you are required to manage the class +instance lifetime yourself. + +[WARNING] +==== +The class instance can't be defined in the initialization function scope, since it becomes invalid as + soon as the test execution exits it. It needs to be either defined statically/globally or managed using a + shared pointer. +==== + +// tag reference: doc/modules/ROOT/examples/example03.run-fail.cpp +:bt-name: example03 +:bt-rule: run-fail +:bt-descr: Nullary method of a class bound to shared class instance and manually registered +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc b/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc new file mode 100644 index 0000000000..fe58da963d --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc @@ -0,0 +1,180 @@ += Template test cases +:page-aliases: boost_test/tests_organization/test_cases/test_organization_templates.adoc + +In order to test a template based component, it is frequently necessary to perform the same set of checks for a +component instantiated with different template parameters. + +One way to perform the same set of checks for a component instantiated with different template parameters would be: + +[source,cpp] +---- +template +void single_test() +{ + BOOST_CHECK( /* test assertion */ ); +} + +void combined_test() +{ + single_test(); + single_test(); + single_test(); +} +---- + +There several problems/inconveniences with above approach, including: + +* Fatal error in one of the invocation will stop whole test case and will skip invocations with different types +* You need to repeat function invocation manually for all the parameters you are interested in +* You need two functions to implement the test + +The {utf} provides a facility, the *template test case*, to create a series of +test cases based on a list of desired types and _nullary_ function. This facility comes with an +xref:tests_organization/test_organization_templates.adoc#ref_BOOST_AUTO_TEST_CASE_TEMPLATE[automatic] and +xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[manual] registration interface. + +[TIP] +==== +The test case template facility is preferable to the approach in example above, since execution of each sub test +case is guarded and counted separately. It produces a better test log/results report (in example above in case of +failure you can't say which type is at fault) and allows you to test all types even if one of them causes termination of +the sub test case. +==== + +[#ref_BOOST_AUTO_TEST_CASE_TEMPLATE] +== Template test case with automated registration + +A template test case, registered automatically and in place of its implementation, is declared through the macro +{boost_auto_test_case_template}: + +[source,cpp] +---- +BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types); +---- + +The arguments are as follow: + +. `test_case_name`: the test case template name: unique test cases template identifier +. `formal_type_parameter_name`: the name of a formal template parameter: +name of the type the test case template is instantiated with +. `collection_of_types`: the collection of types to instantiate test case template with. +This is an *arbitrary MPL sequence* or a sequence of types wrapped in a `std::tuple` +(since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], if supported by the compiler) + +The resulting name of the test is a composition of the `test_case_name` parameter and the current +type being tested. Since xref:change_log.adoc#ref_CHANGE_LOG_3_12[{utf} v3.12], the framework tries to unify +the name of the resulting type across various platforms such that they are easier to reference +from the xref:runtime_config/test_unit_filtering.adoc[command line filter]. + +// tag reference: doc/modules/ROOT/examples/example10.run-fail.cpp +:bt-name: example10 +:bt-rule: run-fail +:bt-descr: Test case template with automated registration +include::partial$bt_example.adoc[] + +[WARNING] +==== +Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], the {utf} does not allow for duplicate test case name + under the same test suite. As test names are derived from the types in the `collection_of_types`, + this indirectly means that *having a duplicate type* in the + `collection_of_types` *yields an error*. +==== + +[NOTE] +==== +If you prefer having the template parameter list directly in the declaration of {boost_auto_test_case_template}, + you may use the macro http://www.boost.org/doc/libs/release/libs/utility/identity_type/doc/html/index.html[`BOOST_IDENTITY_TYPE`]. + The previous example gives (note the double parenthesis around the MPL list): + +[source,cpp] +---- +#include + +BOOST_AUTO_TEST_CASE_TEMPLATE( + my_test, + T, + BOOST_IDENTITY_TYPE((boost::mpl::list< + int, + long, + unsigned char + >)) ) +{ + BOOST_TEST( sizeof(T) == (unsigned)4 ); +} +---- +==== + +[#ref_BOOST_TEST_CASE_TEMPLATE] +== Test case template with manual registration + +To manually register template test cases, two macros should be used: + +* {boost_test_case_template_function} to define the template test case body +* {boost_test_case_template} to register the test case based on the previous declaration + +The macro {boost_test_case_template_function} requires two arguments: + +. the name of the test case template and +. the name of the format type parameter + +[source,cpp] +---- +BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_case_name, type_name); +---- + +[source,cpp] +---- +BOOST_TEST_CASE_TEMPLATE_FUNCTION( test_case_name, type_name ) +{ + // test case template body +} +---- + +The macro {boost_test_case_template_function} is intended to be used in place of nullary function template +signature: + +[source,cpp] +---- +template +void test_case_name() +{ + // test case template body +} +---- + +The only difference is that the {boost_test_case_template_function} makes the test case template name usable in +the template argument list. + +{boost_test_case_template} requires two arguments: + +. the name of the test case template and +. Boost.MPL compatible collection of types to instantiate it with. + +The names passed to both macros should be the same. + +[source,cpp] +---- +BOOST_TEST_CASE_TEMPLATE(test_case_name, collection_of_types); +---- + +// tag reference: doc/modules/ROOT/examples/example09.run-fail.cpp +:bt-name: example09 +:bt-rule: run-fail +:bt-descr: Manually registered test case template +include::partial$bt_example.adoc[] + +{boost_test_case_template} creates an instance of the test case generator. When passed to the method cpp:boost::unit_test::test_suite::add[`test_suite::add`], the generator produces a separate sub test case for each type in +the supplied collection of types and registers it immediately in the test suite. Each test case is based on the test +case template body instantiated with a particular test type. + +The names for the _sub test cases_ are deduced from the macro argument `test_case_name`. If you prefer to assign +different test case names, you need to use the underlying link:{base-url}/boost/test/tree/test_unit.hpp[`make_test_case`] interface instead. +Both test cases creation and registration is performed in the test module initialization function. + +[WARNING] +==== +Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], the {utf} does not allow for duplicate test case name + under the same test suite. As test names are derived from the types in the `collection_of_types`, + this indirectly means that having a duplicate of types in the + `collection_of_types` will yield an error. +==== diff --git a/doc/modules/ROOT/pages/tests_organization/test_suite.adoc b/doc/modules/ROOT/pages/tests_organization/test_suite.adoc new file mode 100644 index 0000000000..62d6b5694a --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_suite.adoc @@ -0,0 +1,133 @@ += Test suite +:page-aliases: boost_test/tests_organization/test_tree/test_suite.adoc + +If you consider test cases as leaves on the test tree, the test suite can be considered as branch and the _master +test suite_ as the _root_. Unlike real trees though, our tree in many cases consists only of leaves attached +directly to the root. This is common for all test cases to reside directly in the master test suite. If you do +want to construct a hierarchical test suite structure the {utf} provides both manual and automated +test suite creation and registration facilities: + +. Test suite with automated registration +. Manually registered test suite + +In addition the {utf} presents a notion of the +xref:tests_organization/master_test_suite.adoc[Master test suite]. +The most important reason to learn about this component is that it provides an ability to access +command line arguments supplied to a test module. + +[#ref_BOOST_AUTO_TEST_SUITE] +== Automated registration + +The solution the {utf} presents for automated test suite creation and registration is designed to facilitate +multiple points of definition, arbitrary test suites depth and smooth integration with automated test case creation +and registration. This facility should significantly simplify a test tree construction process in comparison with +manual explicit registration case. + +The implementation is based on the order of file scope variables definitions within a single compilation unit. +The semantic of this facility is very similar to the namespace feature of C++, including support for test suite +extension. To start test suite use the macro {boost_auto_test_suite}. To end test suite use the macro +{boost_auto_test_suite_end}. The same test suite can be restarted multiple times inside the same test file or in a +different test files. In a result all test units will be part of the same test suite in a constructed test tree. + +[source,cpp] +---- +BOOST_AUTO_TEST_SUITE(test_suite_name); +BOOST_AUTO_TEST_SUITE_END(); +---- + +Test units defined in between test suite start and end declarations become members of the test suite. A test +unit always becomes the member of the closest test suite declared. Test units declared at a test file scope +become members of the master test suite. There is no limit on depth of test suite inclusion. + +This example creates a test tree that matches exactly the one created in the manual test suite registration +example. + +// tag reference: doc/modules/ROOT/examples/example12.run-fail.cpp +:bt-name: example12 +:bt-rule: run-fail +:bt-descr: Test suites with automated registration +include::partial$bt_example.adoc[] + +As you can see test tree construction in this example is more straightforward and automated. + +In the example below, the test suite `test_suite` consists of two parts. Their definition is remote and is separated by another +test case. In fact these parts may even reside in different test files. The resulting test tree remains the same. As +you can see from the output both `test_case1` and `test_case2` reside in the same test suite `test_suite`. + +// tag reference: doc/modules/ROOT/examples/example53.run-fail.cpp +:bt-name: example53 +:bt-rule: run-fail +:bt-descr: Test suite extension using automated registration facility +include::partial$bt_example.adoc[] + +== Test suites with manual registration + +To create a test suite manually you need to + +. create an instance of cpp:boost::unit_test::test_suite[boost::unit_test::test_suite] class, +. register it in test tree, and +. populate it with test cases (or lower level test suites). + +[#ref_test_case_registration] +=== Test unit registration interface + +The {utf} models the notion of test case container - test suite - using class cpp:boost::unit_test::test_suite[boost::unit_test::test_suite]. For +complete class interface reference check advanced section of this documentation. Here you should only be +interested in a single test unit registration interface: + +[source,cpp] +---- +void test_suite::add( test_unit* tc, counter_t expected_failures = 0, int timeout = 0 ); +---- + +The first parameter is a pointer to a newly created test unit. The second optional parameter - +expected_failures - defines the number of test assertions that are expected to fail within the test unit. By +default no errors are expected. + +[CAUTION] +==== +Be careful when supplying a number of expected failures for test suites. By default the {utf} calculates the + number of expected failures in test suite as the sum of appropriate values in all test units that constitute + it. And it rarely makes sense to change this. +==== + +The third optional parameter - `timeout` - defines the timeout value for the test unit. As of now the {utf} +isn't able to set a timeout for the test suite execution, so this parameter makes sense only for test case +registration. By default no timeout is set. See the method +cpp:boost::unit_test::test_suite::add[boost::unit_test::test_suite::add] for more details about the timeout value. + +To register group of test units in one function call, the cpp:boost::unit_test::test_suite[`test_suite`] class provides another +cpp:boost::unit_test::test_suite::add[`add`] interface covered in the advanced section of this documentation. + +[#ref_BOOST_TEST_SUITE] +=== Test suite instance construction + +To create a test suite instance manually, employ the macro {boost_test_suite}. It hides all implementation +details and you only required to specify the test suite name: + +[source,cpp] +---- +BOOST_TEST_SUITE(test_suite_name); +---- + +{boost_test_suite} creates an instance of the class `boost::unit_test::test_suite` and returns a pointer to the +constructed instance. Alternatively you can create an instance of class `boost::unit_test::test_suite` yourself. + +[CAUTION] +==== +`boost::unit_test::test_suite` instances have to be allocated on the heap and the compiler won't allow you + to create one on the stack. +==== + +Newly created test suite has to be registered in a parent one using the `add` interface. Both test suite creation and +registration is performed in the test module initialization function. + +The example below creates a test tree, which can be represented by the following hierarchy: + +image::class-hier.jpg[] + +// tag reference: doc/modules/ROOT/examples/example11.run.cpp +:bt-name: example11 +:bt-rule: run +:bt-descr: Manually registered test suites +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/tests_organization/test_tree.adoc b/doc/modules/ROOT/pages/tests_organization/test_tree.adoc new file mode 100644 index 0000000000..014dec8d23 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_tree.adoc @@ -0,0 +1,31 @@ += Test tree +:page-aliases: boost_test/tests_organization/test_tree.adoc + +The test tree is the hierarchy of test cases and test suites, along with all the fixtures (global, case or +suite level), and the respective dependencies within all those elements. + +A test tree is composed with: + +* Test cases: those are the elements in the tree that contain the body of the tests, and they constitute +the *leaves* of the tree. +* Test suites: those are the are internal nodes of the tree. These elements that do not have any body or executable code themselves, +but fixtures that execute code and tests can be attached to them. +* The master test suite: this is the root of the tree, and is by definition a test suite. Fixtures attached to the master test suite +are *global* fixtures. +* fixtures: those are units of code that are executed before and/or after the test units above. + +The following hierarchy represents a test tree (further detailed in the xref:tests_organization/test_suite.adoc[test-suite] +section) *without* any fixture: + +image::class-hier.jpg[] + +xref:tests_organization/decorators.adoc[Decoration] can be added to test suites and cases except for the master test suite. Those +decoration may modify the way the {utf} +handles the tree. For instance, there is no defined order in the execution of test cases enforced by the tree itself, except for the fixtures +and the elements they relate to (suite, case); decoration may be used to instruct a specific order among the elements of the tree. + +[NOTE] +==== +The test-tree by itself does not give any particular order in the execution of the test-cases. The only implicit order + is given by the fixtures. To indicate a particular order, specific decorators should be used. +==== diff --git a/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc b/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc new file mode 100644 index 0000000000..cb9a731340 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc @@ -0,0 +1,12 @@ += Test tree content +:page-aliases: boost_test/tests_organization/test_tree/test_tree_content.adoc + +The test module, and hence the test tree, should have at least one test-case scheduled for execution, otherwise the {utf} +returns an error. + +This check is performed *after* the filtering of the tests has occurred. The sections about +xref:tests_organization/enabling.adoc[tests enabling/disabling], xref:tests_organization/tests_dependencies.adoc[tests dependencies] +and xref:runtime_config/test_unit_filtering.adoc[runtime filtering] +explain various methods that modify the tests that are being run. + +NOTE: A xref:tests_organization/fixtures.adoc#global[global fixture] is not considered as a test case. diff --git a/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc b/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc new file mode 100644 index 0000000000..518f4889f4 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc @@ -0,0 +1,47 @@ += Managing test dependencies +:page-aliases: boost_test/tests_organization/tests_dependencies.adoc + +In general, it is a good practice to write any test as independent as possible from any other, there are however +cases where a dependency cannot be avoided and an order for executing the tests is needed. + +In the general setup and for any two test cases `TA` and `TB`, `TB` should not take for granted that `TA` has already +executed, even if `TA` is declared before `TB` in the same translation unit. +The only ordering-related guarantee that {utf} makes by default is that if test cases `TA` and `TB` are declared in the +same test suite, no test case (call it `TX`) from any other test suite is executed between `TA` and `TB`, even if the +declaration of `TX` appears between the declarations of `TA` and `TB`. In other words, all tests from a suite are +executed in one go, even if the test suite namespace is opened multiple times. + +Even though the order is not guaranteed, it may accidentally be preserved across the different runs. In order to make +sure the test cases do not depend on one another, the test module may be called with an additional command-line argument, +xref:utf_reference/rt_param_reference.adoc#random[`random`], to shuffle the tests unit ordering and to be more +robust against an erroneous implicit ordering. + +== Declaring a test case dependency + +If there exist a dependency between test units, and an ordering is required between the execution of those tests, +it has to be declared explicitly. +Dependencies in the {utf} affect two dimensions of test units, which are: + +* the order of execution of these units +* the execution of a test unit, which is conditioned by the state of its parents + +xref:tests_organization/decorators.adoc[Decorator] {decorator_depends_on} associates the decorated test case +(call it `TB`) with another test case (call it `TA`) specified by name. This affects the processing the test tree in two +ways: + +. first, test case `TA` is ordered to be run before `TB`, irrespective of the order in which they were declared or +added to the test tree, +. second, the execution of `TB` is skipped if `TA` is either disabled or skipped or is executed +and marked as failed. + +// tag reference: doc/modules/ROOT/examples/decorator_07.run-fail.cpp +:bt-name: decorator_07 +:bt-rule: run-fail +:bt-descr: decorator depends_on +include::partial$bt_example.adoc[] + +In the above scenario: + +* test case `test3` is run (and fails) because `s1/test1` has been run and succeeded, +* `test4` is skipped because `test3` has failed, +* `test5` is skipped because `s1/test2` is disabled. diff --git a/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc b/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc new file mode 100644 index 0000000000..491da951f8 --- /dev/null +++ b/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc @@ -0,0 +1,29 @@ += Grouping tests into logical units by labels +:page-aliases: boost_test/tests_organization/tests_grouping.adoc + +Test-suites and test cases define a hierarchy called the _test tree_, which is useful for organizing tests. These +organization defines an implicit grouping of test unit following the _subtrees_ extracted from the test tree, by just +designing a node on the test tree. Being able to design a group of tests enable, for instance, to execute this group of +test only (covered in xref:runtime_config/test_unit_filtering.adoc[this section]). + +However, the subtrees might not reflect all the possible grouping of test units the usage of the test module would +require footnote:[For instance, selecting two siblings without the parent node]. + +The {utf} provides a flexible way of grouping test units by the use of _labels_, using the decorator +{decorator_label}. It is possible to associate more than one label with a test unit. + +Labels can be associated to test cases and test suites. For the latter, the label is inherited by all the nodes in the +subtree defined by the labelled test suite: decorating a test suite with label `L` is equivalent to decorating every test +unit inside with `L`. + +[TIP] +==== +it is possible to list all labels of a test module from the CLI by using the + xref:utf_reference/rt_param_reference.adoc#list_labels[`--list_labels`] switch +==== + +// tag reference: doc/modules/ROOT/examples/decorator_04.run-fail.cpp +:bt-name: decorator_04 +:bt-rule: run-fail +:bt-descr: decorator label +include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/usage_recommendations/bt_and_tdd.adoc b/doc/modules/ROOT/pages/usage_recommendations/bt_and_tdd.adoc new file mode 100644 index 0000000000..396e62a806 --- /dev/null +++ b/doc/modules/ROOT/pages/usage_recommendations/bt_and_tdd.adoc @@ -0,0 +1,94 @@ += Test driven development with Boost.Test +:page-aliases: boost_test/usage_recommendations/tutorials/bt_and_tdd.adoc + +Today is a momentous day - first day of new year. Today I am going to start a new life. I am going to stop eating a +greasy food, start attending a fitness club and ... today I am going to test programs I am writing. I can start right +after the last line of a program is completed or, even better, I can write tests while I am coding. And maybe next time +I will write tests before the coding, during the design stage. I have read a lot of literature on how to write the +tests, I have the unit test framework in hand and an idea of new class. So let's get started. + +Let say I want to encapsulate an unchangeable C character buffer with a length into the simple class `const_string`. +Rationale: a string class that does not allocate a memory and provide a convenient read-only access to the pre-allocated +character buffer. I will probably want `const_string` to have an interface similar to the class std::string. What will I +do first? In my new life I will start with writing a test module for future class `const_string`. It will look like +this: + +[source,cpp] +---- +include::example$snippets/snippet13.cpp[tag=snippet13] +---- + +Now I can compile it and link with the unit test framework. Done! I have a working test program. It is empty, so when I +run the program it produces following output: + +[source,cpp] +---- +*** No errors detected +---- + +Well, now it could be a good time to start a work on `const_string`. First thing I imagine would be good to have is a +constructors and trivial access methods. So my class initial version looks like this: + +[source,cpp] +---- +include::example$snippets/snippet14.cpp[tag=snippet14] +---- + +Now I am able to write a first test case - constructors testing - and add it to a test suite. My test program became to +look like this: + +[source,cpp] +---- +include::example$snippets/snippet15.cpp[tag=snippet15] +---- + +The constructors_test test case is intended to check a simple feature of the class `const_string`: an ability to +construct itself properly based on different arguments. To test this feature I am using such characteristics of +constructed object as a data it contains and a length. The specification of the class `const_string` does not contain +any expected failures, so, though the constructor can fail if I would pass a pointer to an invalid memory, error check +control is not performed (can't require what was not promised :-)). But for any valid input it should work. So I am +trying to check a construction for an empty string (1), a NULL string (2) a regular C string(3), an STL string(4), a +copy construction(5) and so on. Well, after fixing all the errors in the implementation (do you write programs without +errors from scratch?) I am able to pass this test case and the unit test framework gives me the following report: + +[source,cpp] +---- +Running 1 test case... + +*** No errors detected +---- + +Encouraged I am moving on and adding more access methods: + +[source,cpp] +---- +include::example$snippets/snippet16.cpp[tag=snippet16] +---- + +I added the new feature - I need a new test case to check it. As a result my test suite became to look like this: + +[source,cpp] +---- +include::example$snippets/snippet17.cpp[tag=snippet17] +---- + +In the data_access_test test case I am trying to check the class `const_string` character access correctness. While tests +(1) checks valid access using `const_string::operator[]` and test (2) checks valid access using method +`const_string::at()`, there is one more thing to test. The specification of the method `const_string::at()` contains +validation for the out of bound access. That was test (3) is intended to do: check that the validation is working. A +testing of a validation and error handling code is an important part of a unit testing and should not be left for a +production stage. The data_access_test test case passed and I am ready for the next step. + +Continuing my effort I am able to complete class `const_string` (see ../snippet/const_string.hpp[Listing 1 +=const_string.hpp=]) and testing module for it (see ../snippet/const_string_test.cpp[Listing 2 =const_string_test.cpp=]) +that is checking all features that are presented in the class `const_string` specification. + +Well, I am step closer to fulfilling my new year resolution (we should see about this fitness club sometime next ...). +What about you? Your testing habits could be a little different. You could start with a class/library development and +then at some point start writing test cases on feature basis. Or you can, given a detailed specification for the future +product, including expected interfaces, immediately start with writing all test cases (or it could be a different +person, while you working on implementation at the same time). In any case you should not have any problems to use +facilities provided by the Boost.Test unit test framework and, let me hope, be able to write a stable, bulletproof code. +And what is even more important is your confidence in an ability to make changes of any complexity without involving a +lengthy regression testing of your whole product. Your test module and the unit test framework will stay behind your +back to help you with any occasional errors. diff --git a/doc/modules/ROOT/pages/usage_recommendations/hello.adoc b/doc/modules/ROOT/pages/usage_recommendations/hello.adoc new file mode 100644 index 0000000000..e1105cd40b --- /dev/null +++ b/doc/modules/ROOT/pages/usage_recommendations/hello.adoc @@ -0,0 +1,73 @@ += A testing framework, what for? +:page-aliases: boost_test/usage_recommendations/tutorials/hello.adoc + +How should a test program report errors? Displaying an error message is an obvious possibility: + +[source,cpp] +---- +if( something_bad_detected ) + std::cout << "something bad has been detected" << std::endl; +---- + +But that requires inspection of the program's output after each run to determine if an error occurred. Since test +programs are often run as part of a regression test suite, human inspection of output to detect error messages is time +consuming and unreliable. Test frameworks like GNU/expect can do the inspections automatically, but are overly complex +for simple testing. + +A better simple way to report errors is for the test program to return `EXIT_SUCCESS` (normally 0) if the test program +completes satisfactorily, and `EXIT_FAILURE` if an error is detected. This allows a simple regression test script to +automatically and unambiguously detect success or failure. Further appropriate actions such as creating an HTML table or +emailing an alert can be taken by the script, and can be modified as desired without having to change the actual C++ +test programs. + +A testing protocol based on a policy of test programs returning `EXIT_SUCCESS` or `EXIT_FAILURE` does not require any +supporting tools; the C++ language and standard library are sufficient. The programmer must remember, however, to catch +all exceptions and convert them to program exits with non-zero return codes. The programmer must also remember to not +use the standard library `assert()` macro for test code, because on some systems it results in undesirable side effects +like a message requiring manual intervention. + +The Boost Test Library's Unit Test Framework is designed to automate those tasks. The library supplied `main()` relieves +users from messy error detection and reporting duties. Users could use supplied testing tools to perform complex +validation tasks. Let's take a look on the following simple test program: + +[source,cpp] +---- +#include + +int main( int, char* [] ) +{ + my_class test_object( "qwerty" ); + return test_object.is_valid() ? EXIT_SUCCESS : EXIT_FAILURE; +} +---- + +There are several issues with above test. + +. You need to convert `is_valid` result in proper result code. +. Would exception happen in test_object construction of method `is_valid` invocation, the program will crash. +. You won't see any output, would you run this test manually. + +The {utf} solves all these issues. To integrate with it above program needs to be changed to: + +[source,cpp] +---- +#include +#define BOOST_TEST_MODULE MyTest +#include + +BOOST_AUTO_TEST_CASE( my_test ) +{ + my_class test_object( "qwerty" ); + BOOST_TEST( test_object.is_valid() ); +} +---- + +Now, you not only receive uniform result code, even in case of exception, but also nicely formatted output from +{boost_test} tool, would you choose to see it. Is there any other ways to perform checks? The following example test +program shows several different ways to detect and report an error in the `add()` function. + +[source,cpp] +---- +include::example$snippets/snippet12.cpp[tag=snippet12] +---- +include::example$snippets/snippet12.cpp[tag=snippet12-callouts] diff --git a/doc/modules/ROOT/pages/usage_recommendations/index.adoc b/doc/modules/ROOT/pages/usage_recommendations/index.adoc new file mode 100644 index 0000000000..55caf60dcb --- /dev/null +++ b/doc/modules/ROOT/pages/usage_recommendations/index.adoc @@ -0,0 +1,165 @@ += Practical usage recommendations +:page-aliases: boost_test/usage_recommendations.adoc + +[#ref_usage_recommendations] +Following pages present tips and recommendations on how to use and apply the {utf} in your real life practice. +You don't necessarily need to follow them, but we found them handy. + +Here you will also find some tutorials from Boost.Test authors and world wide. + +[#general] +== General + +=== Prefer offline compiled libraries to the inline included components + +If you are just want to write quick simple test in environment where you never used Boost.Test before - yes, +use included components. But if you plan to use Boost.Test on permanent basis, small investment of time needed +to build (if not build yet), install and change you makefiles/project settings will soon return to you in a +form of shorter compilation time. Why do you need to make your compiler do the same work over and over again? + +=== If you use only free function based test cases advance to the automatic registration facility + +It's really easy to switch to automatic registration. And you don't need to worry about forgotten test cases. + +=== To find location of first error reported by test tool within reused template function, use special hook within framework headers + +In some cases you are reusing the same template based code from within one test case (actually we recommend +better solution in such case - see below). Now if an error gets reported by the test tool within that reused +code you may have difficulty locating were exactly error occurred. To address this issue you could either a add +{boost_test_message} statements in templated code that log current type id of template parameters or you can use special hook located in +`unit_test_result.hpp` called `first_failed_assertion()`. If you set a breakpoint right on the line where this +function is defined you will be able to unroll the stack and see where error actually occurred. + +=== To test reusable template base component with different template parameter use test case template facility + +If you writing unit test for generic reusable component you may have a need to test it against set of different +template parameter types . Most probably you will end up with a code like this: + +[source,cpp] +---- +template +void specific_type_test( TestType* = 0 ) +{ + MyComponent c; + // ... here we perform actual testing +} + +void my_component_test() +{ + specific_type_test( (int*)0 ); + specific_type_test( (float*)0 ); + specific_type_test( (UDT*)0 ); + // ... +} +---- + +This is namely the situation where you would use test case template facility. It not only simplifies this kind +of unit testing by automating some of the work, in addition every argument type gets tested separately under +unit test monitor. As a result if one of types produce exception or non-fatal error you may still continue and +get results from testing with other types. + +[#ide_usage_recommendations] +== IDE usage recommendations + +This recommendation is shown using Microsoft Visual Studio as an example, but you can apply similar steps in +different IDEs. + +=== Use custom build step to automatically start test program after compilation + +I found it most convenient to put test program execution as a post-build step in compilation. To do so use +project property page: + +image::post_build_event.jpg[] + +Full command you need in "Command Line" field is: + +[subs="+macros,+attributes,+quotes"] +.... +"$(TargetDir)\$(TargetName).exe" --xref:utf_reference/rt_param_reference.adoc#result_code[`result_code`]=no --xref:utf_reference/rt_param_reference.adoc#report_level[`report_level`]=no +.... + +Note that both report level and result code are suppressed. This way the only output you may see from this +command are possible runtime errors. But the best part is that you could jump through these errors using usual +keyboard shortcuts/mouse clicks you use for compilation error analysis: + +image::post_build_out.jpg[] + +=== If you got fatal exception somewhere within test case, make debugger break at the point the failure by adding + extra command line argument + +If you got "memory access violation" message (or any other message indication fatal or system error) when you +run you test, to get more information of error location add + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#catch_system[catch_system_error]=no +.... + +to the test run command line: + +image::run_args.jpg[] + +Now run the test again under debugger and it will break at the point of failure. + +[#command_line_usage_recommendations] +== Command line usage recommendations + +=== If you got fatal exception somewhere within test case, make program generate core-dump by adding extra command + line argument + +If you got "memory access violation" message (or any other message indication fatal or system error) when you +run you test, to get more information about the error location add + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#catch_system[catch_system_error]=no +.... + +to the test run command line. Now run the test again and it will create a core-dump you could analyze using you preferable +debugger. Or run it under debugger in a first place and it will break at the point of failure. + +=== How to use test module build with Boost.Test framework under management of automated regression test facilities? + +My first recommendation is to make sure that the test framework catches all fatal errors by adding argument + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#catch_system[catch_system_error]=yes +.... + +to all test modules invocations. Otherwise test program may produce unwanted dialogs (depends on compiler and OS) that will halt you +regression tests run. The second recommendation is to suppress result report output by adding + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#report_level[report_level]=no +.... + +argument and test log output by adding + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#log_level[log_level]=nothing +.... + +argument, so that test module won't produce undesirable output no one is going to look at +anyway. We recommend relying only on result code that will be consistent for all test programs. An +alternative to my second recommendation is direct both log and report to separate file you could analyze +later on. Moreover you can make Boost.Test to produce them in XML or JUNIT format using + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#output_format[output_format]=XML +.... + +or + +[subs="+macros,+attributes,+quotes"] +.... +--xref:utf_reference/rt_param_reference.adoc#log_format[log_format]=JUNIT +.... + +and use some automated tool that will format this information as you like. + +[#tutorials] +== Tutorials diff --git a/doc/modules/ROOT/pages/usage_recommendations/web_wisdom.adoc b/doc/modules/ROOT/pages/usage_recommendations/web_wisdom.adoc new file mode 100644 index 0000000000..97f367b64a --- /dev/null +++ b/doc/modules/ROOT/pages/usage_recommendations/web_wisdom.adoc @@ -0,0 +1,48 @@ += Web Wisdom +:page-aliases: boost_test/usage_recommendations/web_wisdom.adoc + +If you can't find answer to the question you have on these pages, it is quite possible someone already faced an issue similar to yours +and posted about this online. This page gathers a few of the additional materials you may review. + +[NOTE] +==== +The following material is provided "as is". The views, implementation or methods expressed are their respective authors and + do not necessarily represent positions of the Boost.Test contributors, and might be outdated. +==== + +* http://stackoverflow.com/search?q=boost+test[Stack overflow Boost.Test related questions] +* http://www.ibm.com/developerworks/aix/library/au-ctools1_boost/?S_TACT=105AGY20&S_CMP=HP[Get to know the Boost unit test framework (from IBM)] +* http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/[C++ Unit Testing With Boost.Test] +* http://www.beroux.com/english/articles/boost_unit_testing/[C++ Unit Testing Framework: A Boost Test Tutorial] +* http://praveen.kumar.in/2010/04/30/introduction-to-test-driven-development-in-c-using-boost-test-library/[Introduction to Test-Driven Development in C++ using Boost Test Library] +* C++ Unit Tests With Boost.Test: +https://legalizeadulthood.wordpress.com/2009/07/04/c-unit-tests-with-boost-test-part-1/[part 1], +https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-2/[part 2], +https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-3/[part 3], +https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-4/[part 4], +https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-5/[part 5] +* http://alexott.net/en/cpp/CppTestingIntro.html[Test-driven development and unit testing with examples in C++] +* http://www.hpfsc.de/default.php?url=./boosttest/index.html[How to use Boost Test for automated testing] +* http://www.abauchu.net/blog/post/2009/12/02/Unit-tests-with-BoostTest[Unit tests with Boost.Test] +* http://richarddingwall.name/2008/06/08/boost-how-do-i-write-a-unit-test-for-a-signal/[Boost: How do I write a unit test for a signal?] +* https://chuckaknight.wordpress.com/2013/04/18/testing-using-the-boost-unit-test-framework[Testing Using the Boost Unit Test Framework] +* https://sanecpp.wordpress.com/2014/10/08/introduction-to-unit-testing/[Introduction to unit testing] +* http://www.alittlemadness.com/2009/12/04/using-boost-test-with-boost-build/[Using Boost.Test with Boost.Build] +* http://www.alittlemadness.com/2009/12/10/boost-test-xml-reports-with-boost-build/[Boost.Test XML Reports with Boost.Build] +* http://edn.embarcadero.com/article/32703[Boost Unit Testing with C++BuilderX] +* http://www.sharprobotica.com/2010/04/including-boost-test-in-your-c-project/[Including Boost.Test in Your C++ Project] +* http://bitten.edgewall.org/wiki/BoostTest[Using Boost.Test in Bitten] +* http://seandenigris.com/blog/?p=187[Automate acceptance/unit testing C++ in Xcode (using Boost.Test)] +* http://www.codeproject.com/Articles/368966/Automation-of-running-Boost-Test-with-Visual-Studi[Automation of running Boost.Test with Visual Studio macros] +* http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/[Using the Boost Unit Test Framework with Xcode 3] +* http://www.lonecpluspluscoder.com/2014/09/some-boost-test-notes/[Some Boost.Test notes] +* http://www.devexp.ru/2010/01/boost-test-yunit-testirovanie-i-cmake/[Boost.Test tutorial (in Russian)] +* Boost Test. Setup and usage (http://blog.yastrebkov.com/2009/07/boost-test.html[Russian], +http://blog.yastrebkov.com/2010/07/boost-test-setup-and-usage.html[English]) +* http://www.ncbi.nlm.nih.gov/toolkit/doc/book/ch_boost/[Using the Boost Unit Test Framework] +* http://endl.ch/content/gallio-adapter-boosttest[Gallio adapter for Boost.Test] +* http://sindicollo.blogspot.com/2008/11/boosttest.html[Russian translation of small tutorial to Boost.Test] +* http://www.eld.leidenuniv.nl/~moene/Home/projects/testdox/boosttest/[Customizing the output log and report format] +* https://github.com/etas/vs-boost-unit-test-adapter[Boost Test Adapter] (Boost.Test extension for Microsoft Visual Studio, also +available from https://visualstudiogallery.msdn.microsoft.com/5f4ae1bd-b769-410e-8238-fb30beda987f[here]). +* https://marketplace.visualstudio.com/items?itemName=VisualCPPTeam.TestAdapterforBoostTest[Microsoft Boost Test Adapter] diff --git a/doc/modules/ROOT/pages/usage_variants.adoc b/doc/modules/ROOT/pages/usage_variants.adoc new file mode 100644 index 0000000000..67f8552e32 --- /dev/null +++ b/doc/modules/ROOT/pages/usage_variants.adoc @@ -0,0 +1,91 @@ += Usage variants +:page-aliases: boost_test/usage_variants.adoc + +The {utf} supports three different usage variants: + +. xref:usage_variants.adoc#single_header[The header-only variant] +. xref:usage_variants.adoc#static_lib[The static library variant] +. xref:usage_variants.adoc#shared_lib[The shared library variant] + +In most cases you shouldn't have problems deciding which one to use, since there are +clear reasons why would you prefer each one. Following sections should help you with the decision. + +[#single_header] +== Header-only usage variant + +If you prefer to avoid the compilation of standalone library, you should use the +header-only variant of the {utf}. This variant only requires you to include +the unique header: `+#include +` +and there is no need to link with any library. There are several ways to perform +the initialization, but the simplest way is the following: + +[source,cpp] +---- +#define BOOST_TEST_MODULE test module name +#include /* path is different than the other variants! */ +---- + +{boost_test_module} macro needs to be defined *before* the include and should indicate +the name of the test module. This name can include spaces and does not need to be wrapped in quotes. + +xref:adv_scenarios/single_header_customizations.adoc[This section] +gives additional details on how to customize this usage variant. In particular, +it is possible to have several compilation units with this variant, as explained in the section +xref:adv_scenarios/single_header_customizations.adoc#multiple_translation_units[Header-only with multiple translation units]. + +[#static_lib] +== Static library usage variant + +For most users, who has an access to pre-built static library footnote:[these files are distributed +with the packaging systems on Linux and OSX for instance] of the {utf} or can +xref:adv_scenarios/build_utf.adoc[build it] themselves, following usage can be most versatile + and simple approach. This usage variant entails two steps. + +. First, the following line needs to be added to all translation units in the test module: +`+#include +` +One and *only one* translation unit should include following lines: +`+#define {boost_test_module} test module name +#include +` +{boost_test_module} macro needs to be defined *before* the include and should indicate the +name of the test module. This name can include spaces and does not need to be wrapped in quotes. +. The second step is to link with the {utf} *static* library. + +NOTE: Header `` is an _aggregate_ header: it includes most of the other headers that contains the Unit Test Framework definitions. + +The flip side of this usage variant is that each test module following this usage variant is going +to be statically linked with {utf}, which might be something you want to avoid (to save space +for example). For more information about these configuration options check +xref:adv_scenarios/static_lib_customizations.adoc[this section]. + +[#shared_lib] +== Shared library usage variant + +In the project with large number of test modules the static library variant of the {utf} may +cause you to waste a lot of disk space. The solution is to link test module dynamically with the +{utf} built as a shared library. +This usage variant entails two steps. + +. First you need to add following lines to all translation units in a test module: +`+#define {boost_test_dyn_link} +#include +` +and *only one* translation unit should include following lines +`+#define {boost_test_module} test module name +#define {boost_test_dyn_link} +#include +` +`BOOST_TEST_MODULE` and `BOOST_TEST_DYN_LINK` macros needs to be defined *before* the include. +`BOOST_TEST_MODULE` should be set to test module name. This name can include spaces and does +not need to be wrapped in quotes. +. The second step is to link with the {utf} *shared* library. + +The flip side of this usage variant is that you will need to make sure the {utf} shared library +is accessible at runtime to a test module. + +In addition shared library usage variant facilitates custom test runners. For more information about this +check xref:adv_scenarios/shared_lib_customizations.adoc[this section]. + +[CAUTION] +==== +On Windows, the test module and the {utf} shared library should link to the same CRT. Not doing + so (for instance {utf} shared library in _release_ mode while the test module is in _debug_) will + lead to crashes. +==== diff --git a/doc/modules/ROOT/pages/utf_reference/index.adoc b/doc/modules/ROOT/pages/utf_reference/index.adoc new file mode 100644 index 0000000000..30c29e5e9b --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/index.adoc @@ -0,0 +1,4 @@ += {utf} API reference +:page-aliases: boost_test/utf_reference.adoc + +// The Doxygen-generated reference is replaced by the MrDocs `reference` module. diff --git a/doc/modules/ROOT/pages/utf_reference/link_references.adoc b/doc/modules/ROOT/pages/utf_reference/link_references.adoc new file mode 100644 index 0000000000..de00ae2186 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/link_references.adoc @@ -0,0 +1,129 @@ += Build scenarios and behaviors +:page-aliases: boost_test/utf_reference/link_references.adoc + +[#link_boost_test_main_macro] +== `BOOST_TEST_MAIN` + +When defined, this macro creates a stub for the test module initialization (the main entry part). This +macro also expands properly into a `main` function in case the shared library variant of the {utf} is used. + +[CAUTION] +==== +This macro should + +. be defined before any inclusion directive to {utf} headers +. be defined exactly for one compilation unit of your test module +==== + +TIP: The macro {boost_test_module} should be preferred + +[#link_boost_test_module_macro] +== `BOOST_TEST_MODULE` + +Serves the same purpose as the macro {boost_test_main} but, in addition, defines the name of the master test suite. + +[CAUTION] +==== +As {boost_test_main}, this macro should + +. be defined before any inclusion directive to {utf} headers +. be defined exactly for one compilation unit of your test module +==== + +An example may be found xref:tests_organization/master_test_suite.adoc#ref_BOOST_TEST_MODULE[here]. + +[#link_boost_test_alternative_init_macro] +== `BOOST_TEST_ALTERNATIVE_INIT_API` + +[WARNING] +==== +This macro should be defined before any include directive to the {utf} headers and is +mutually exclusive with the {boost_test_module} macro. +==== + +In case of custom initialization of the test module entry point, this macro indicates the {utf} to +use the new API. The differences between the new and old APIs are described in xref:adv_scenarios/obsolete_init_func.adoc[this section]. + +The way to customize the entry point of the test-module depends on the variant of the {utf} in use. +Several sections in the documentation are devoted to this: + +* xref:adv_scenarios/single_header_customizations.adoc#entry_point[this section] for single header variant, +* xref:adv_scenarios/static_lib_customizations.adoc#init_func[this section] for static link variant, +* xref:adv_scenarios/shared_lib_customizations.adoc#init_func[this section] for shared link variant + +[#link_boost_test_no_lib] +== `BOOST_TEST_NO_LIB` + +Define this flag to prevent auto-linking. + +NOTE: The same flag is used for the {utf} and the {pem} components. + +[#link_boost_test_dyn_link] +== `BOOST_TEST_DYN_LINK` + +Define this flag to link against the {utf} shared library. + +NOTE: The same flag is used for the {utf} and the {pem} components. + +[#link_boost_test_no_main] +== `BOOST_TEST_NO_MAIN` + +Prevents the auto generation of the test module initialization functions. This macro is particularly relevant for +manually registered tests in conjunction with dynamic variant of the {utf}. When defined, a `main` function +registering all the tests should be implemented. + +An example of a module initialization would be + +[source,cpp] +---- +#define BOOST_TEST_NO_MAIN +#include + +// a function in another compilation unit registering tests under the master test suite. +void register_some_tests_manually(test_suite* test); + +bool registering_all_tests() +{ + test_suite* test_master_suite = &boost::unit_test::framework::master_test_suite(); + register_some_tests_manually(test_master_suite); + + // register any other tests function or test suite to the master test suite + // ... + return true; +} + +int main(int argc, char* argv[]) +{ + return ::boost::unit_test::unit_test_main(®istering_all_tests, argc, argv); +} +---- + +[#link_boost_test_global_configuration] +== `BOOST_TEST_GLOBAL_CONFIGURATION` + +Declares a class that will be constructed during the initialization of the test framework, and destructed afterwards. +The framework will not call any other member function than the constructor and destructor. +In particular the constructor and destructor will be called prior and after to the xref:tests_organization/fixtures.adoc#global[global fixtures] +setup and teardown. + +This facility is provided to perform additional configuration, in particular programmatic configuration +of the loggers and reporters. See xref:test_output/logging_api.adoc[this section] for more details. + +[WARNING] +==== +No logging or any other call to the framework assertion is allowed in the constructor and destructor, as its purpose is + to set-up the loggers/reporters, and the assertions are calling the logging/reporting facility. + Any such assertion during the execution of the will result in the abortion of the test module . +==== + +[#config_disable_alt_stack] +== `BOOST_TEST_DISABLE_ALT_STACK` + +Disables the support of the alternative stack. + +Define this macro before the inclusion of any {utf} header to disable the support +of the http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html[alternative stack], +in case your compiler does not support it and the {utf} cannot automatically guess the lack of support. + +See xref:utf_reference/rt_param_reference.adoc#use_alt_stack[`use_alt_stack`] +and xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`] for more details. diff --git a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc new file mode 100644 index 0000000000..49739c7447 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc @@ -0,0 +1,859 @@ += Runtime parameters reference +:page-aliases: boost_test/utf_reference/rt_param_reference.adoc + +Following sections provide detailed specification for all {utf} runtime parameters. Each parameter specification includes: + +* The full parameter name. +* Description of parameter semantic and default value. +* Acceptable argument values. The default value for the parameter is bold in the acceptable values list. +* Command line syntax. The format of all command line arguments is: `[]`. +For example: `--param=`. +`[]` around separator and value indicate that argument value is optional. For example: `-q[ ]`. +* Corresponding environment variable name. + +[NOTE] +==== +All command line argument formats support parameter name guessing. What this means is that is if command like +format is like this: + +.... +--long_parameter_name= +.... + +you can in fact use any unambiguous prefix of the parameter name to specify the argument. For example: + +.... +--long_param=123 +.... + +or + +.... +--long_p=123. +.... + +If parameter name prefix you chose is ambiguous the framework lets you know which parameters match specified +prefix. For example, try + +.... +--log=all +.... +==== + +== Parameter value formats + +The {utf} runtime parameters take value of the following types: string, boolean, enumeration, +unsigned, long. Formats required for values of these types are following: + +=== String, unsigned, long + +[#regular_param_value] +Values of these types are expected in the same format they are represented in C++. + +=== Boolean + +[#boolean_param_value] +Values of these types are options with yes/no or true/false meaning. True values are represented +by case insensitive strings: "Y", "YES", "TRUE", "1". False values are represented by case +insensitive strings: "N", "NO", "FALSE", "0". + +=== Enumeration + +[#enum_param_value] +Values of an enumeration type are expected as case sensitive strings representing +enumeration value names. Each parameter with an enumeration value lists all valid names in a +parameter\`s description. + +[#auto_dbg] +== `auto_start_dbg` + +Option _auto_start_dbg_ specifies whether Boost.Test should attempt to attach a debugger when a fatal system +error occurs. At the moment this feature is only available on a few selected platforms: Win32 and *nix. There is a +default debugger configured for these platforms. You can manually configure a different debugger. +For more details on how to configure a debugger see the link:{base-url}/boost/test/debug.hpp[Boost.Test debug API], +specifically the function cpp:boost::debug::set_debugger[boost::debug::set_debugger]. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--auto_debug[=]` +* `-d []` + +=== Environment variable + +BOOST_TEST_AUTO_START_DBG + +[#build_info] +== `build_info` + +Option _build_info_ instructs the {utf} to display the build information before testing begins. +This information includes: + +* platform +* compiler +* STL implementation in use +* boost version + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--build_info[=]` +* `-i []` + +=== Environment variable + +BOOST_TEST_BUILD_INFO + +[#catch_system] +== `catch_system_errors` + +If option _catch_system_errors_ has value "no" the {utf} does not attempt to catch asynchronous system failures +(signals on *NIX platforms or structured exceptions on Windows). This can be used for test programs executed +within an IDE or to get a coredump for a stack analysis. See +xref:usage_recommendations/index.adoc#ref_usage_recommendations[usage recommendations] pages for more details. + +[NOTE] +==== +If the {utf} detects that the current process is being run under a debugger, the `catch_system_errors` is + automatically disabled. +==== + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +NOTE: The {utf} can be built with flag `BOOST_TEST_DEFAULTS_TO_CORE_DUMP` in which case default changes to *yes* + +=== Command line syntax + +* `--catch_system_errors[=]` +* `-s []` + +=== Environment variable + +BOOST_TEST_CATCH_SYSTEM_ERRORS + +[#color_output] +== `color_output` + +The {utf} is able to produce color output on systems which support it. To disable this behavior, set this option to +`no`. By default the framework produces color output. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *yes*. + +=== Command line syntax + +* `--color_output[=]` +* `-x []` + +=== Environment variable + +BOOST_TEST_COLOR_OUTPUT + +[#detect_fp_exceptions] +== `detect_fp_exceptions` + +Option _build_info_ enables/disables hardware traps for the floating point exceptions (if supported on your platform). + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--detect_fp_exceptions[=]` + +=== Environment variable + +BOOST_TEST_DETECT_FP_EXCEPTIONS + +[#detect_memory_leaks] +== `detect_memory_leaks` + +Parameter _detect_memory_leaks_ enables/disables memory leaks detection (if present in your build configuration). +This parameter has an optional long integer value. The default value is 1, which enables memory leak detection. +The value 0 disables memory leak detection. Any value N greater than 1 is treated as leak allocation number and tells the +framework to setup runtime breakpoint at Nth heap allocation. If value is omitted the default value is assumed. + +NOTE: The only platform which supports memory leak detection is Microsoft Visual Studio family of compilers in debug builds. + +=== Acceptable values + +* 0 +* *1* (default) +* xref:utf_reference/rt_param_reference.adoc#regular_param_value[long integer value] > 1 + +=== Command line syntax + +* `--detect_memory_leaks[=]` + +=== Environment variable + +BOOST_TEST_DETECT_MEMORY_LEAK + +[#help] +== `help` + +Parameter _help_ displays help on the framework's parameters. The parameter accepts an optional +argument value: + +* if present, the argument value is interpreted as a parameter name. Name guessing +works as well (so for example `--help=rand` displays help on the parameter `random`). +* if the parameter name is unknown or ambiguous, an error is reported, +* if the argument value is absent, a summary of all framework's parameter is displayed. + +=== Acceptable values + +An optional parameter name xref:utf_reference/rt_param_reference.adoc#regular_param_value[string]. + +=== Command line syntax + +* `--help[=]` + +[#list_content] +== `list_content` + +Lists the name of the xref:section_glossary.adoc#ref_test_unit[test units] contained in the xref:section_glossary.adoc#ref_test_module[test module] and exits (no test is run). + +This command line parameter accepts an _optional_ string value indicating the format of the output. +The framework supports the following two formats: + +. HRF (default), standing for _Human Readable Format_, +. DOT, standing for the http://www.graphviz.org/doc/info/lang.html[Graphviz graph format]. This format may be automatically parsed or rendered. + +=== HRF + +For HRF, the xref:section_glossary.adoc#ref_test_tree[test tree] (test suites and test cases) is presented in a tree like form with +each test unit name on a separate line with horizontal indentation in relation to the parent test suite. +In addition, test units which are enabled by default have an asterisk `+*+` next to the test unit name. For example, the following output: + +testsuite1* + testcase1* + testcase2 + testsuite2* + testcase3* + +represents test module consisting of two test suites: `testsuite1` and `testsuite2`, and three test cases: `testcase1`, +`testcase2`, and `testcase3`. The formatting reflects the test-tree: the first two test cases belong to the first test suite +and last one belongs to the second. Out of three test cases only two are enabled by default: +`testcase1` and `testcase3`. `testcase2` is not enabled by default, but can be enabled by using the parameter {param_run_test}. + +=== DOT + +DOT output generates a graph representing the module's xref:section_glossary.adoc#ref_test_tree[test tree] in a +http://www.graphviz.org/doc/info/lang.html[dot format]. +This output includes much more information about the test tree including labels, timeouts, expected failures, and dependencies. + +The legend is as follow: + +* the master test suite is represented as an ellipse +* a test unit (suite, case) is in a rounded rectangle +* test unit declaration location, xref:tests_organization/tests_grouping.adoc[labels], +xref:testing_tools/expected_failures.adoc[expected failures], xref:testing_tools/timeout.adoc[timeouts] are appended, +* a green box indicates that the test unit that is enabled, otherwise its color is yellow, +* a plain black arrow goes from a test unit to each of its children, following the test tree (the arrow pointing to the child), +* a dashed red arrow indicates a runtime dependence on test units, the arrow pointing to the parent in the dependency graph. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#enum_param_value[Enumeration] names: + +* *HRF* (default) +* DOT + +=== Command line syntax + +* `--list_content[=]` + +=== Environment variable + +BOOST_TEST_LIST_CONTENT + +=== Example + +The following _deliberately_ complicated example illustrates the purpose of the `--list_content` +directive. The SVG generated from the produced Graphviz/dot file can be downloaded +images/boost_runtime_list_content.svg[here]. + +// tag reference: doc/modules/ROOT/examples/boost_runtime_list_content.run.cpp +:bt-name: boost_runtime_list_content +:bt-rule: run +:bt-descr: `--list_content` illustration +include::partial$bt_example.adoc[] + +image::boost_runtime_list_content.png[width=70%] + +[#list_labels] +== `list_labels` + +Lists the labels associated to the xref:section_glossary.adoc#ref_test_unit[test units] in the current +xref:section_glossary.adoc#ref_test_module[test module] and exits (no test is run). + +[TIP] +==== +See xref:tests_organization/tests_grouping.adoc[this section] for more details on labels and logical grouping +of test cases. +==== + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--list_labels[=]` + +=== Environment variable + +BOOST_TEST_LIST_LABELS + +=== Example + +The previous example from xref:utf_reference/rt_param_reference.adoc#list_content[`--list_content`] gives + +[source,cpp] +---- +> ./boost_runtime_list_content --list_labels +Available labels: + label1 + label2 +---- + +[#log_format] +== `log_format` + +Parameter _log_format_ allows to set the {utf} log format to one of the formats supplied by the framework. +To specify custom log format use the xref:test_output/logging_api.adoc#ref_log_formatter_api[custom log formatting API]. + +The only acceptable values for this parameter are the names of the output formats supplied by the +framework. By default the framework uses human readable format (HRF) for the testing log. This format +is similar to a compiler error format. Alternatively you can specify XML or JUNIT as a log format which are +easier to process by testing automation tools. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#enum_param_value[Enumeration] names: + +* *HRF* (default) +* XML +* JUNIT + +=== Command line syntax + +* `--log_format=` +* `-f ` + +=== Environment variable + +BOOST_TEST_LOG_FORMAT + +[#log_level] +== `log_level` + +Parameter _log_level_ allows to set the {utf} xref:test_output/logging_api.adoc#ref_log_level_explanations[log level]. Log level defines +the verbosity of the testing log produced by a testing module. The verbosity ranges from a complete log, when all +assertions (both successful and failing) are reported and all notifications about test units start and finish +are included, to an empty log, when nothing is reported to a testing log stream. + +Log level is set to one of the predefined levels which are organized hierarchically, where each level includes +all the messages on that level as well as all the messages from levels below. Levels are identified by string +names, which are listed next. + +=== Acceptable values + +Following is the list of xref:utf_reference/rt_param_reference.adoc#enum_param_value[enumeration] log_level names ordered from higher to lower level. +Thus each level includes messages on that level as well as all the messages on levels defined below. + +[%header%autowidth,cols="2*"] +|=== +|Value +|Included messages + +|all (default for JUNIT) +|All log messages including the passed assertions notification + +|success +|The same as all + +|test_suite +|Test units start/finish notifications + +|message +|User generated messages (using {boost_test_message} tool) + +|warning +a| +Messages describing failed assertion on `WARN` level ( + xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_WARN`] + / `BOOST_WARN_...` + tools) + +|*error* (default for HRF and XML) +|Messages describing failed assertion on `CHECK` level ({boost_test} / `BOOST_CHECK_...` tools) + +|cpp_exception +|Messages reporting uncaught C++ exception + +|system_error +|Messages reporting system originated non-fatal errors. For example, timeout or floating point exception. + +|fatal_error +a| +Messages reporting user or system originated fatal errors. For example, memory access violation. Also + all the messages describing failed assertion on `REQUIRE` level ({boost_test_require} / `BOOST_REQUIRE_...` tools) + +|nothing +|No messages are reported. + +|=== + +[CAUTION] +==== +the JUNIT log format does not accept the log level to change: anything specified by `log_level` will be ignored + for the JUNIT format. +==== + +=== Command line syntax + +* `--log_level=` +* `-l ` + +=== Environment variable + +BOOST_TEST_LOG_LEVEL + +[#log_sink] +== `log_sink` + +Parameter _log_sink_ allows to set the log sink - location where framework writes the testing log to, +thus it allows to easily redirect the testing log to file or standard streams. By default testing log +is directed to the standard output stream. + +=== Acceptable values + +Case sensitive xref:utf_reference/rt_param_reference.adoc#regular_param_value[string]: + +[%header%autowidth,cols="2*"] +|=== +|Value +|Meaning + +|*`stdout`* (default for HRF and XML) +|Testing log is redirected into standard output stream + +|stderr +|Testing log is redirected into standard error stream + +|File name (default for JUNIT) +|Testing log is redirected into this file + +|=== + +[NOTE] +==== +For JUnit and if not specified, the log file is generated after the name of the + xref:tests_organization/master_test_suite.adoc[master test suite]. +==== + +=== Command line syntax + +* `--log_sink=` +* `-k ` + +=== Environment variable + +BOOST_TEST_LOG_SINK + +[#logger] +== `logger` + +The _logger_ parameter allows to fully specify (log format, level and sink) one or several loggers in one command. +If this parameter is specified, it has precedence over xref:utf_reference/rt_param_reference.adoc#log_format[`log_format`], +xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`] and xref:utf_reference/rt_param_reference.adoc#log_sink[`log_sink`]. + +The parameter is _repeatable_: it may appear several times on the command line. It is possible to indicate a set of loggers using the separator ':', +which is the only way for repeating a logger description through the environment variable. + +The parameter is composed of three fields separated by a coma ',' and indicating respectively the log format, level and sink. The log +format is mandatory. The log level and sink are both optional: if omitted, the default for the specified format will +be used. The log level and sink accept the same value as their respective command line switch (see +xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`] and xref:utf_reference/rt_param_reference.adoc#log_sink[`log_sink`] +for more information). + +=== Acceptable values + +Case sensitive xref:utf_reference/rt_param_reference.adoc#regular_param_value[string]: + +[source,cpp] +---- +logger_set ::= (logger ':')* logger +logger ::= logger_format (',' log_level? (',' log_sink? )? )? +logger_format ::= 'HRF' | 'XML' | 'JUNIT' +log_level ::= 'all' | 'success' | 'test_suite' | 'message' | 'warning' | 'error' | 'cpp_exception' | 'system_error' | 'fatal_error' | 'nothing' +log_sink ::= 'stdout' | 'stderr' | filename +---- + +Examples: + +* `--logger=HRF,all` will set the `all` log level for the `HRF` log format, and will use the default sink associated to `HRF` (`stdout`) +* `--logger=JUNIT,,somefile.xml:HRF,warning` will use the default log level associated to the `JUNIT` log format, and will use the file `somefile.xml` +as the log sink. It will also enable the `HRF` format with log level `warning`. The corresponding sink will be set to the `HRF` default (`stdout`). + +=== Command line syntax + +* `--logger=` + +=== Environment variable + +BOOST_TEST_LOGGER + +[#output_format] +== `output_format` + +Parameter _output_format_ combines an effect of +xref:utf_reference/rt_param_reference.adoc#report_format[`report_format`] and +xref:utf_reference/rt_param_reference.adoc#log_format[`log_format`] +parameters. This parameter does not have +a default value. The only acceptable values are string names of output formats (see below). + +NOTE: This parameter has precedence over _report_format_ and _log_format_ on the command line. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#enum_param_value[Enumeration] name: + +* HRF +* XML + +_HRF_ stands for human readable format, while _XML_ is dedicated to automated output processing + +=== Command line syntax + +* `--output_format=` +* `-o ` + +=== Environment variable + +BOOST_TEST_OUTPUT_FORMAT + +[#random] +== `random` + +Parameter _random_ instructs the {utf} to execute the test cases in random order. This parameter +accepts an optional `unsigned integer` argument for the seed of the random generator: + +* By default (value `0`), the test cases are executed in some specific order +defined by the order of test units in the test files, and the dependencies between test units. +* If the parameter is specified without the argument value, or with value `1`, the testing order is randomized based on current time. +* Alternatively, any positive value greater than `1` will be used as random seed for the run. + +[TIP] +==== +in case `--random` is specified, the value of the seed is logged using {boost_test_message}, so that it is possible to replay + exactly the same sequence of unit test in case of failure. For the seed to be visible in the logs, + make sure the proper xref:utf_reference/rt_param_reference.adoc#log_level[`--log_level`] is set. +==== + +=== Acceptable values + +* *0* (default): no randomization +* `1`: random seed based on the current time +* xref:utf_reference/rt_param_reference.adoc#regular_param_value[integer] `value > 1` : seed for the random number generator + +=== Command line syntax + +* `--random=` + +=== Environment variable + +BOOST_TEST_RANDOM + +[#report_format] +== `report_format` + +Parameter _report_format_ allows to set the {utf} report format to one of the formats supplied +by the framework. To specify a custom report format use unit_test_report API. + +The only acceptable values for this parameter are the names of the output formats. By default the +framework uses human readable format (HRF) for results reporting. Alternatively you can specify +XML as report format. This format is easier to process by testing automation tools. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#enum_param_value[Enumeration] names: + +* *HRF* (default) +* XML + +=== Command line syntax + +* `--report_format=` +* `-m ` + +=== Environment variable + +BOOST_TEST_REPORT_FORMAT + +[#report_level] +== `report_level` + +Parameter _report_level_ allows to set the verbosity level of the testing result report generated by +the {utf}. Use value "no" to eliminate the results report completely. See the +xref:test_output/report_formats.adoc#ref_report_formats[report formats] section for description of report formats on different levels. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#enum_param_value[Enumeration] report_level names: + +* *confirm* (default) +* no +* short +* detailed + +=== Command line syntax + +* `--report_level=` +* `-r ` + +=== Environment variable + +BOOST_TEST_REPORT_LEVEL + +[#report_memory_leaks_to] +== `report_memory_leaks_to` + +Parameter _report_memory_leaks_to_ allows to specify a file where to report memory leaks to. The +parameter does not have default value. If it is not specified, memory leaks (if any) are reported +to the standard error stream. + +=== Acceptable values + +Arbitrary file name xref:utf_reference/rt_param_reference.adoc#regular_param_value[string]. + +=== Command line syntax + +* `--report_memory_leaks_to=` + +=== Environment variable + +BOOST_TEST_REPORT_MEMORY_LEAKS_TO + +[#report_sink] +== `report_sink` + +Parameter _report_sink_ allows to set the result report sink - the location where the framework writes +the result report to, thus it allows to easily redirect the result report to a file or a standard stream. +By default the testing result report is directed to the standard error stream. + +=== Acceptable values + +Case sensitive xref:utf_reference/rt_param_reference.adoc#regular_param_value[string]: + +* *`stderr`* (default) +* `stdout` +* arbitrary file name + +=== Command line syntax + +* `--report_sink=` +* `-e ` + +=== Environment variable + +BOOST_TEST_REPORT_SINK + +[#result_code] +== `result_code` + +The "no" argument value for the option \`result_code instructs the {utf} to always return zero +result code. This could be used for test programs executed within IDE. By default this parameter has +value "yes". See the xref:usage_recommendations/index.adoc#ref_usage_recommendations[usage recommendations] section for more details. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *yes*. + +=== Command line syntax + +* `--result_code[=]` +* `-c []` + +=== Environment variable + +BOOST_TEST_RESULT_CODE + +[#run_test] +== `run_test` + +Parameter _run_test_ allows to filter which test units to execute during testing. The {utf} supports +both "selection filters", which allow to select which test units to enable from the set of available +test units, and "disabler filters", which allow to disable some test units. The {utf} also supports +enabling/disabling test units at compile time. These settings identify the default set of test units +to run. Parameter _run_test_ is used to change this default. This parameter is repeatable, so you can +specify more than one filter if necessary. +It is also possible to use the ':' for separating each filter +which can be used for filtering the tests with the environment variable `BOOST_TEST_RUN_FILTERS` (as it cannot be +repeated like `--run_test`). + +More details about practical application of this parameter resides in xref:runtime_config/test_unit_filtering.adoc[test unit +filtering] section. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#regular_param_value[String] value representing single filter or a set of filters separated by ':'. +The following grammar productions describe the syntax of filters: + +[source,cpp] +---- +filter_set ::= (filter ':')* filter +filter ::= relative_spec? test_set +relative_spec ::= '+' | '!' +test_set ::= label | path +label ::= '@' identifier +path ::= (suite '/')? pattern_list +pattern_list ::= (pattern ',')* pattern +suite ::= (pattern '/')* pattern +pattern ::= '*'? identifier '*'? +---- + +[CAUTION] +==== +the `pattern_list` above indicates test unit inside the same test suite given by `suite`. This means that the syntax + "`--run_test=suite1/suite2/A,B,C`" runs the test cases `A`, `B` and `C` that are *inside* `suite1/suite2`. In order to indicate + several test units that are not siblings, either repeat the `--run_test` or use `:` to separate the filters. +==== + +Regarding the meaning of these values xref:runtime_config/test_unit_filtering.adoc#ref_command_line_control[see here]. + +=== Command line syntax + +* `--run_test=` +* `-t ` + +=== Environment variable + +BOOST_TEST_RUN_FILTERS + +[#save_pattern] +== `save_pattern` + +Option _save_pattern_ facilitates switching mode of operation for testing output streams. See {output_test_stream_tool} +section for details on these tests. + +This parameter serves no particular purpose within the framework itself. It can be used by test modules relying +on cpp:boost::test_tools::output_test_stream[boost::test_tools::output_test_stream] to implement testing logic. It has two modes of operation: + +* save the pattern file (true). +* and match against a previously stored pattern file (false). + +Default mode is 'match' (false). + +You can use this parameter to switch between these modes, by passing the parameter value to the `output_test_stream` constructor. +The value of the command line parameter is available using call like this: + +[source,cpp] +---- +bool is_save_pattern_flag_set = boost::unit_test::runtime_config::save_pattern(); +---- + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--save_pattern[=]` + +=== Environment variable + +BOOST_TEST_SAVE_PATTERN + +[#show_progress] +== `show_progress` + +Option _show_progress_ instructs the {utf} to display test progress information. By default the +parameter test progress is not shown. More details xref:test_output/test_output_progress.adoc[here]. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--show_progress[=]` +* `-p []` + +=== Environment variable + +BOOST_TEST_SHOW_PROGRESS + +[#use_alt_stack] +== `use_alt_stack` + +Option _use_alt_stack_ instructs the {utf} to use alternative stack for signals processing, on +platforms where they are supported. More information about this feature is available +http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html[here]. The feature is enabled +by default, but can be disabled using this parameter. + +NOTE: If this feature is not supported by your compiler, this command line option will be silently ignored. + +[NOTE] +==== +it is possible to remove the support of the alternative stack with the macro +xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`] +==== + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *yes*. + +=== Command line syntax + +* `--use_alt_stack[=]` + +=== Environment variable + +BOOST_TEST_USE_ALT_STACK + +[#usage] +== `usage` + +If specified option _usage_ instructs the {utf} to displays short usage message about the +framework's parameters. + +=== Command line syntax + +* `-? []` + +NOTE: The parameter name is not part of command line format, only short '-?'. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +[#wait_for_debugger] +== `wait_for_debugger` + +Option _wait_for_debugger_ instructs the {utf} to pause before starting test units execution, +so that you can attach a debugger to running test module. By default this parameters turned off. + +=== Acceptable values + +xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. + +=== Command line syntax + +* `--wait_for_debugger[=]` +* `-w []` + +=== Environment variable + +BOOST_TEST_WAIT_FOR_DEBUGGER diff --git a/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc new file mode 100644 index 0000000000..ba78ef9ed0 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc @@ -0,0 +1,301 @@ += Tests declaration and organization +:page-aliases: boost_test/utf_reference/test_org_reference.adoc + +[#test_org_boost_test_case] +== `BOOST_TEST_CASE` and `BOOST_TEST_CASE_NAME` + +Creates a test case for manual registration. The registration in the test tree should be performed manually. + +See xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_TEST_CASE[here] for more details. + +[#test_org_boost_auto_test_case] +== `BOOST_AUTO_TEST_CASE` + +Declares and registers automatically a test case. + +See xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_AUTO_TEST_CASE[here] for more details. + +[#test_org_boost_test_case_auto_template] +== `BOOST_AUTO_TEST_CASE_TEMPLATE` + +Declares and registers automatically a typed test case. + +See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_AUTO_TEST_CASE_TEMPLATE[here] for more details. + +[#test_org_boost_test_case_template] +== `BOOST_TEST_CASE_TEMPLATE` + +Creates a typed test case. The test case should have been declared with the macro {boost_test_case_template_function}. +The registration in the test tree should be performed manually. + +See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[here] for more details. + +[#test_org_boost_test_case_template_function] +== `BOOST_TEST_CASE_TEMPLATE_FUNCTION` + +Declares a typed test case. The registration in the test tree should be performed manually, using the macro +{boost_test_case_template}. + +See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[here] for more details. + +[#test_org_boost_test_case_parameter] +== `BOOST_PARAM_TEST_CASE` + +Declares and registers automatically a test case with one parameter. + +See xref:tests_organization/param_test.adoc[here] for more details. + +[#test_org_boost_test_dataset] +== `BOOST_DATA_TEST_CASE` + +Declares and registers a data-driven test case, using a particular dataset. + +Several forms of the macro are available. + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(test_case_name, dataset) +{ + BOOST_TEST(sample != 0); +} +---- + +should be used for datasets with arity 1. In the body of the test case, the samples of the dataset are taken by the variable `sample`. + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(test_case_name, dataset, var1) +{ + BOOST_TEST(var1 != 0); +} +---- + +same as the first form, but the samples are taken by the variable `var1` instead of the variable `sample` + +[source,cpp] +---- +BOOST_DATA_TEST_CASE(test_case_name, dataset, var1, var2..., varN) +{ + BOOST_TEST(var1 != 0); + //... + BOOST_TEST(varN != 0); +} +---- + +same as the second form, but for dataset of arity `N`. + +For compilers *lacking the variadic template* support, the maximal arity (the maximal value of `N`) is controlled by the macro +`BOOST_TEST_DATASET_MAX_ARITY` which is set to `10` by default. If you need a greater value, define `BOOST_TEST_DATASET_MAX_ARITY` +to the desired value *before* including the {utf} headers. + +See xref:tests_organization/test_case_generation.adoc#datasets_auto_registration[here] for more details. + +[#test_org_boost_test_dataset_fixture] +== `BOOST_DATA_TEST_CASE_F` + +Declares and registers a data-driven test case, using a particular dataset and a fixture. This is basically the same as +{boost_data_test_case} with fixture support added. + +[source,cpp] +---- +struct my_fixture { + my_fixture() : some_string("environment X") { + } + std::string some_string; +}; + +BOOST_DATA_TEST_CASE_F(my_fixture, test_case_name, dataset, var1, var2..., varN) +{ + BOOST_TEST(var1 != 0); + //... + BOOST_TEST(varN != 0); +} +---- + +The fixture should implement the appropriate xref:tests_organization/fixtures.adoc#models[interface]. +As any fixture, it is possible to have test assertions in the fixture class. + +See xref:tests_organization/fixtures.adoc#case[here] for more details on fixtures and +xref:tests_organization/test_case_generation.adoc#datasets_auto_registration[here] for more details on datasets +declaration. + +[#test_org_boost_test_suite] +== `BOOST_TEST_SUITE` + +Creates a test suite. The created test suite should be added to the test tree manually. + +See xref:tests_organization/test_suite.adoc#ref_BOOST_TEST_SUITE[here] for more details. + +[#test_org_boost_auto_test_suite] +== `BOOST_AUTO_TEST_SUITE` + +Indicates the beginning of a test suite. Test suites can be nested. + +See xref:tests_organization/test_suite.adoc#ref_BOOST_AUTO_TEST_SUITE[here] for more details. + +[#test_org_boost_auto_test_suite_end] +== `BOOST_AUTO_TEST_SUITE_END` + +Indicates the end of a test suite. Test suites can be nested. This macro should appear as many times as there is a +{boost_auto_test_suite}. + +See xref:tests_organization/test_suite.adoc#ref_BOOST_AUTO_TEST_SUITE[here] for more details. + +[#test_org_boost_test_case_fixture] +== `BOOST_FIXTURE_TEST_CASE` + +Declares and registers a test case that uses a fixture. The class implementing the fixture should have the appropriate +xref:tests_organization/fixtures.adoc#models[interface]. +As any fixture, it is possible to have test assertions in the fixture class. + +See xref:tests_organization/fixtures.adoc#case[here] for more details. + +[#test_org_boost_test_suite_fixture] +== `BOOST_FIXTURE_TEST_SUITE` + +Declares and registers a fixture used by all test cases under a test suite. +Each test case in the subtree of the test suite uses the fixture. +The class implementing the fixture should have the appropriate xref:tests_organization/fixtures.adoc#models[interface]. +As any fixture, it is possible to have test assertions in the fixture class. + +See xref:tests_organization/fixtures.adoc#case[here] for more details. + +[#test_org_boost_global_fixture] +== `BOOST_GLOBAL_FIXTURE` + +This macro is deprecated in favor of {boost_test_global_fixture} and {boost_test_global_configuration}. + +[#test_org_boost_test_global_fixture] +== `BOOST_TEST_GLOBAL_FIXTURE` + +Declares and registers a global fixture. The global fixture acts exactly as a suite fixture attached to the +xref:tests_organization/master_test_suite.adoc[master test suite], +and is called before any of the test case in the test tree is executed. + +The class implementing the fixture should have the appropriate xref:tests_organization/fixtures.adoc#models[interface]. +As any fixture, it is possible to have test assertions in the global fixture. + +See xref:tests_organization/fixtures.adoc#global[here] for more details. + +[#test_org_boost_test_decorator] +== `BOOST_TEST_DECORATOR` + +Defines _decorators_ for a test unit. + +See xref:tests_organization/decorators.adoc[here] for more details. + +[#decorator_depends_on] +== depends_on (decorator) + +[source,cpp] +---- +depends_on(const_string dependent_test_name); +---- + +Indicates a dependency from the decorated test unit (the child) to the designed test unit `dependent_test_name` (the parent). +See xref:tests_organization/tests_dependencies.adoc[here] for more details. + +[#decorator_description] +== description (decorator) + +[source,cpp] +---- +description(const_string message); +---- + +Attaches an arbitrary string to the test unit. +See xref:tests_organization/semantic.adoc[here] for more details. + +[#decorator_enabled] +== enabled / disabled (decorator) + +[source,cpp] +---- +enabled(); +disabled(); +---- + +Sets the test unit's {default_run_status} to _true_ or _false_. +See xref:tests_organization/enabling.adoc[here] for more details. + +[#decorator_enable_if] +== enable_if (decorator) + +[source,cpp] +---- +template enable_if(); +---- + +Sets the test unit's {default_run_status} to _true_ or _false_, depending on a compilation-time +constant. +See xref:tests_organization/enabling.adoc[here] for more details. + +[#decorator_fixture] +== fixture (decorator) + +[source,cpp] +---- +fixture(const boost::function& setup, const boost::function& teardown = {}); + +template + fixture(); + +template + fixture(const Arg& arg); +---- + +Decorator `fixture` specifies a pair of functions (like `set_up` and `tear_down`) to be called before and after the +corresponding test unit. At the suite level the `set_up` function is called once -- before the suite execution starts +-- and `tear_down` function is called once -- after the suite execution ends. It comes in three forms. + +First expects two +functions for set-up and tear-down (the second one can be skipped). + +The second expects a `DefaultConstructible` class. +Its default constructor will be used as set-up function and its destructor as a tear-down function. + +The third form requires a +class with one-argument public constructor. Argument `arg` is forwarded to the constructor. + +For the second and third form, the framework detects if there is a `setup` and/or `teardown` function implemented in the class, +with the same declaration as described in the xref:tests_organization/fixtures.adoc#models[fixture model]. +If those member function are declared, they will be called right after construction and just +before destruction respectively. + +[NOTE] +==== +There is no way to get access to the members of these fixtures from +within the test case or test suite. +==== + +// tag reference: doc/modules/ROOT/examples/decorator_12.run.cpp +:bt-name: decorator_12 +:bt-rule: run +:bt-descr: decorator fixture +include::partial$bt_example.adoc[] + +For other ways of using fixtures, see xref:tests_organization/fixtures.adoc[here]. + +[#decorator_label] +== label (decorator) + +[source,cpp] +---- +label(const_string label_name); +---- + +Associates a test unit with label `label_name`. It is possible to associate more than one label with a test unit. +See xref:tests_organization/tests_grouping.adoc[here] for more details. + +[#decorator_precondition] +== precondition (decorator) + +[source,cpp] +---- +typedef boost::function<[classref boost::test_tools::assertion_result test_tools::assertion_result] (test_unit_id)> predicate_t; + +precondition(predicate_t predicate); +---- + +Associates a _predicate_ with a test unit that will determine its {default_run_status} at run-time. +See xref:tests_organization/enabling.adoc[here] for more details. diff --git a/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc new file mode 100644 index 0000000000..43ba3c8ce0 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc @@ -0,0 +1,745 @@ += Reference API for writing tests +:page-aliases: boost_test/utf_reference/testing_tool_ref.adoc + +[#assertion_boost_test_universal_macro] +== `BOOST_TEST` + +[source,cpp] +---- +BOOST_TEST(statement); +BOOST_TEST_(statement); + +// replacement failure message, requires variadic macros +BOOST_TEST(statement, "failure message"); + +// Floating point comparison, requires variadic macros, auto and decltype +BOOST_TEST(statement, floating_point_comparison_manipulation); + +// bitwise comparison, requires variadic macros, auto and decltype +BOOST_TEST(statement, boost::test_tools::bitwise() ); + +// element-wise comparison, for containers +BOOST_TEST(statement, boost::test_tools::per_element() ); + +// lexicographic comparison, for containers +BOOST_TEST(statement, boost::test_tools::lexicographic() ); +---- + +The full documentation of this macro is located xref:testing_tools/boost_test_universal_macro.adoc[here]. + +The macro is available in three variants, corresponding to different xref:testing_tools/tools_assertion_severity_level.adoc[assertion severity levels]: + +[source,cpp] +---- +BOOST_TEST // or BOOST_TEST_CHECK +BOOST_TEST_REQUIRE +BOOST_TEST_WARN +---- + +* `"failure message"` is a C-string printed in case of failure in place of the default message. +See xref:testing_tools/reports.adoc[this section] for +more details. +* `floating_point_comparison_manipulation` is one of the floating point comparison manipulators. +See xref:testing_tools/boost_test_universal_macro.adoc[this section] +for more details. +* cpp:boost::test_tools::bitwise[boost::test_tools::bitwise] is a manipulator indicating that the comparison should be performed bitwise. See +xref:testing_tools/bitwise.adoc[this section] for more details +* cpp:boost::test_tools::per_element[boost::test_tools::per_element] is a manipulator indicating that the comparison should be performed on each element, in sequence, rather +than on containers. See +xref:testing_tools/collections.adoc#boost_test_coll_perelement[this section] for more details +* cpp:boost::test_tools::lexicographic[boost::test_tools::lexicographic] is a manipulator indicating that the comparison should be performed with the lexicographic order. See +xref:testing_tools/collections.adoc#boost_test_coll_default_lex[this section] for more details + +=== Limitations and workaround + +There are some restrictions on the statements that are supported by this tool. Those are explained in details in +xref:testing_tools/boost_test_universal_macro.adoc#boost_test_statement_limitations[this] section. + +[#decorator_expected_failures] +== expected_failures (decorator) + +[source,cpp] +---- +expected_failures(counter_t number); +---- + +Indicates the expected failures for a test unit. +See xref:testing_tools/expected_failures.adoc[here] for more details. + +[#decorator_timeout] +== timeout (decorator) + +[source,cpp] +---- +timeout(unsigned int seconds); +---- + +Specifies a time-out for a *test-case* or a *test-suite*, in wall-clock time. + +If a test-case lasts longer than the timeout, the test is flagged as failed. On some systems (see below), +the test-case is forced to stop. + +For test-suites, the mechanism is similar: every test-unit under the test-suite is allocated a maximum +duration time that is the remainder of the timeout after the previous tests have been executed. If a timeout occurs +during the execution of the suite, the suite is flagged as timed-out and the remaining test-units are skipped. + +See xref:testing_tools/timeout.adoc[here] for more details. + +[NOTE] +==== +The macro + `BOOST_SIGACTION_BASED_SIGNAL_HANDLING` is defined + if Boost.Test is able to force the test-case to stop. +==== + +NOTE: The support for test suites has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / {utf} v3.10] + +[#decorator_tolerance] +== tolerance (decorator) + +[source,cpp] +---- +template + tolerance(FPT eps); + +template + tolerance(test_tools::fpc::percent_tolerance_t eps) +---- + +Decorator `tolerance` specifies the default comparison tolerance for floating point type `FTP` in the decorated test +unit. The default tolerance only applies to a particular type, so it makes sense to provide more than one `tolerance` +decorator if we are comparing different floating point types. +The variant with `percent_tolerance` uses value `eps / 100` as tolerance. + +[NOTE] +==== +For more details see the + xref:testing_tools/floating_point.adoc[floating points comparison] section. +==== + +// tag reference: doc/modules/ROOT/examples/decorator_13.run-fail.cpp +:bt-name: decorator_13 +:bt-rule: run-fail +:bt-descr: decorator tolerance +include::partial$bt_example.adoc[] + +In the above example, in `test1`, checks on `double`s fail because they differ by more what tolerance for `double`s +specifies. In `test2` the tolerance for `double`s is greater and therefore the checks succeed. In `test3`, we specify +only tolerance for type `float`, and since the checks use type `double` the specified tolerance does not apply. Tolerance +in `test4` is equivalent to that in `test1`, therefore its checks also fail. Tolerance in `test5` is equivalent to +that in `test2`, therefore its checks also succeed. + +[#assertion_boost_level] +== `BOOST_` + +[#ref_BOOST_level] +[source,cpp] +---- +BOOST_WARN(predicate); +BOOST_CHECK(predicate); +BOOST_REQUIRE(predicate); +---- + +These tools are used to validate the predicate value. The only parameter for these tools is a boolean predicate +value that gets validated. It could be any expression that could be evaluated and converted to boolean value. The +expression gets evaluated only once, so it's safe to pass complex expression for validation. + +// tag reference: doc/modules/ROOT/examples/example34.run-fail.cpp +:bt-name: example34 +:bt-rule: run-fail +:bt-descr: BOOST_ usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_message} + +[#assertion_boost_level_bitwise_eq] +== `BOOST__BITWISE_EQUAL` + +[source,cpp] +---- +BOOST_WARN_BITWISE_EQUAL(left, right); +BOOST_CHECK_BITWISE_EQUAL(left, right); +BOOST_REQUIRE_BITWISE_EQUAL(left, right); +---- + +These tools are used to perform bitwise comparison of two values. The check shows all positions where left and +right value's bits mismatch. + +The first parameter is the left compared value. The second parameter is the right compared value. Parameters are +not required to be of the same type, but warning is issued if their type's size does not coincide. + +// tag reference: doc/modules/ROOT/examples/example33.run-fail.cpp +:bt-name: example33 +:bt-rule: run-fail +:bt-descr: BOOST__BITWISE_EQUAL usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_equal} + +[#assertion_boost_level_eq] +== `BOOST__EQUAL` + +[source,cpp] +---- +BOOST_WARN_EQUAL(left, right); +BOOST_CHECK_EQUAL(left, right); +BOOST_REQUIRE_EQUAL(left, right); +---- + +Check performed by these tools is the same as the one performed by `{boost_level}(left == right)`. +The difference is that the mismatched values are reported as well. + +[NOTE] +==== +It is bad idea to use these tools to compare floating point values. Use {boost_level_close} or + {boost_level_close_fraction} tools instead. +==== + +// tag reference: doc/modules/ROOT/examples/example35.run-fail.cpp +:bt-name: example35 +:bt-rule: run-fail +:bt-descr: BOOST__EQUAL usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level} +* {boost_level_close} +* {boost_level_ne} +* {boost_level_equal_collections} + +[#assertion_boost_level_eq_collections] +== `BOOST__EQUAL_COLLECTIONS` + +[source,cpp] +---- +BOOST_WARN_EQUAL_COLLECTIONS(left_begin, left_end, right_begin, right_end); +BOOST_CHECK_EQUAL_COLLECTIONS(left_begin, left_end, right_begin, right_end); +BOOST_REQUIRE_EQUAL_COLLECTIONS(left_begin, left_end, right_begin, right_end); +---- + +These tools are used to perform an element by element comparison of two collections. They print all mismatched +positions, collection elements at these positions and check that the collections have the same size. The first two +parameters designate begin and end of the first collection. The two last parameters designate begin and end of the +second collection. + +// tag reference: doc/modules/ROOT/examples/example36.run-fail.cpp +:bt-name: example36 +:bt-rule: run-fail +:bt-descr: BOOST__EQUAL_COLLECTIONS usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_equal} + +[#assertion_boost_level_close] +== `BOOST__CLOSE` + +[source,cpp] +---- +BOOST_WARN_CLOSE(left, right, tolerance); +BOOST_CHECK_CLOSE(left, right, tolerance); +BOOST_REQUIRE_CLOSE(left, right, tolerance); +---- + +These tools are used to check on closeness using strong relationship defined by the predicate + +[source,cpp] +---- +check_is_close( left, right, tolerance ) +---- + +To check for the weak relationship use +{boost_level_predicate} family of tools with explicit `check_is_close` invocation. + +The first parameter is the _left_ compared value. The second parameter is the +_right_ compared value. Last third parameter defines the tolerance for the comparison in +xref:testing_tools/floating_point.adoc[*percentage units*]. + +[NOTE] +==== +It is required for left and right parameters to be of the same floating point type. You will need to explicitly + resolve any type mismatch to select which type to use for comparison. +==== + +[NOTE] +==== +The floating point comparison tools are automatically added if the {utf} + is included as indicated in the previous sections. The tools are implemented is in the header + link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. +==== + +// tag reference: doc/modules/ROOT/examples/example42.run-fail.cpp +:bt-name: example42 +:bt-rule: run-fail +:bt-descr: BOOST__CLOSE usage with small values +include::partial$bt_example.adoc[] + +// tag reference: doc/modules/ROOT/examples/example43.run.cpp +:bt-name: example43 +:bt-rule: run +:bt-descr: BOOST__CLOSE usage with big values +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_close_fraction} +* {boost_level_small} +* {boost_level_equal} +* {floating_points_testing_tools} + +[#assertion_boost_level_close_fraction] +== `BOOST__CLOSE_FRACTION` + +[source,cpp] +---- +BOOST_WARN_CLOSE_FRACTION(left, right, tolerance); +BOOST_CHECK_CLOSE_FRACTION(left, right, tolerance); +BOOST_REQUIRE_CLOSE_FRACTION(left, right, tolerance); +---- + +These tools are used to check on closeness using strong relationship defined by the predicate + +[source,cpp] +---- +check_is_close(left, right, tolerance) +---- + +To check for the weak relationship use {boost_level_predicate} family of tools with explicit `check_is_close` invocation. + +The first parameter is the _left_ compared value. The second parameter is the +_right_ compared value. Last third parameter defines the tolerance for the comparison as +xref:testing_tools/floating_point.adoc[*fraction of absolute values being compared*]. + +[NOTE] +==== +It is required for left and right parameters to be of the same floating point type. You will need to explicitly + resolve any type mismatch to select which type to use for comparison. +==== + +[NOTE] +==== +The floating point comparison tools are automatically added if the {utf} + is included as indicated in the previous sections. The tools are implemented is in the header + link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. +==== + +// tag reference: doc/modules/ROOT/examples/example44.run-fail.cpp +:bt-name: example44 +:bt-rule: run-fail +:bt-descr: BOOST__CLOSE_FRACTION usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_close} +* {boost_level_small} +* {boost_level_equal} +* {floating_points_testing_tools} + +[#assertion_boost_level_ge] +== `BOOST__GE` + +[source,cpp] +---- +BOOST_WARN_GE(left, right); +BOOST_CHECK_GE(left, right); +BOOST_REQUIRE_GE(left, right); +---- + +Check performed by these tools is the same as the one performed by `{boost_level}( left >= right )`. +The difference is that the argument values are reported as well. + +// tag reference: doc/modules/ROOT/examples/example57.run-fail.cpp +:bt-name: example57 +:bt-rule: run-fail +:bt-descr: BOOST__GE usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_le} +* {boost_level_lt} +* {boost_level_gt} + +[#assertion_boost_level_gt] +== `BOOST__GT` + +[source,cpp] +---- +BOOST_WARN_GT(left, right); +BOOST_CHECK_GT(left, right); +BOOST_REQUIRE_GT(left, right); +---- + +Check performed by these tools is the same as the one performed by {boost_level}`( left > right )`. +The difference is that the argument values are reported as well. + +// tag reference: doc/modules/ROOT/examples/example58.run-fail.cpp +:bt-name: example58 +:bt-rule: run-fail +:bt-descr: BOOST__GT usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_le} +* {boost_level_lt} +* {boost_level_ge} + +[#assertion_boost_level_le] +== `BOOST__LE` + +[source,cpp] +---- +BOOST_WARN_LE(left, right); +BOOST_CHECK_LE(left, right); +BOOST_REQUIRE_LE(left, right); +---- + +Check performed by these tools is the same as the one performed by `{boost_level}( left <= right )`. +The difference is that the argument values are reported as well. + +// tag reference: doc/modules/ROOT/examples/example55.run-fail.cpp +:bt-name: example55 +:bt-rule: run-fail +:bt-descr: BOOST__LE usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_le} +* {boost_level_ge} +* {boost_level_gt} + +[#assertion_boost_level_lt] +== `BOOST__LT` + +[source,cpp] +---- +BOOST_WARN_LT(left, right); +BOOST_CHECK_LT(left, right); +BOOST_REQUIRE_LT(left, right); +---- + +Check performed by these tools is the same as the one performed by `{boost_level}( left < right )`. +The difference is that the argument values are reported as well. + +// tag reference: doc/modules/ROOT/examples/example56.run-fail.cpp +:bt-name: example56 +:bt-rule: run-fail +:bt-descr: BOOST__LT usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_le} +* {boost_level_ge} +* {boost_level_gt} + +[#assertion_boost_level_message] +== `BOOST__MESSAGE` + +[source,cpp] +---- +BOOST_WARN_MESSAGE(predicate, message); +BOOST_CHECK_MESSAGE(predicate, message); +BOOST_REQUIRE_MESSAGE(predicate, message); +---- + +These tools perform exactly the same check as {boost_level} tools. The only difference is that +instead of generating an error/confirm message these use the supplied one. + +The first parameter is the boolean expression. The second parameter is the message reported in case of check +failure. The message argument can be constructed of components of any type supporting the +`std::ostream& operator<<(std::ostream&)`. + +// tag reference: doc/modules/ROOT/examples/example38.run.cpp +:bt-name: example38 +:bt-rule: run +:bt-descr: BOOST__MESSAGE usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level} + +[#assertion_boost_level_ne] +== `BOOST__NE` + +[source,cpp] +---- +BOOST_WARN_NE(left, right); +BOOST_CHECK_NE(left, right); +BOOST_REQUIRE_NE(left, right); +---- + +Check performed by these tools is the same as the one performed by `{boost_level}( left != right )`. +The difference is that the matched values are reported as well. + +// tag reference: doc/modules/ROOT/examples/example54.run-fail.cpp +:bt-name: example54 +:bt-rule: run-fail +:bt-descr: BOOST__NE usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_equal} + +[#assertion_boost_level_predicate] +== `BOOST__PREDICATE` + +[source,cpp] +---- +BOOST_WARN_PREDICATE(predicate, arguments_list); +BOOST_CHECK_PREDICATE(predicate, arguments_list); +BOOST_REQUIRE_PREDICATE(predicate, arguments_list); +---- + +These are generic tools used to validate an arbitrary supplied predicate functor (there is a compile time limit on +predicate arity defined by the configurable macro `BOOST_TEST_MAX_PREDICATE_ARITY`). To +validate zero arity predicate use {boost_level} tools. In other cases prefer theses tools. The +advantage of these tools is that they show arguments values in case of predicate failure. + +The first parameter is the predicate itself. The second parameter is the list of predicate arguments each wrapped +in round brackets (`BOOST_PP` sequence format). + +// tag reference: doc/modules/ROOT/examples/example40.run.cpp +:bt-name: example40 +:bt-rule: run +:bt-descr: BOOST__PREDICATE usage +include::partial$bt_example.adoc[] + +NOTE: Note difference in error log from {boost_level} + +See also: + +* {boost_level} + +[#assertion_boost_level_no_throw] +== `BOOST__NO_THROW` + +[source,cpp] +---- +BOOST_WARN_NO_THROW(expression); +BOOST_CHECK_NO_THROW(expression); +BOOST_REQUIRE_NO_THROW(expression); +---- + +These assertions validate that the execution of `expression` does not throw any exception. +To that extent, all possible exception are caught by assertion itself and no exception is propagated to +the test body. + +TIP: It is possible to test for complex expressions with the use of constructs such as `+do { /* ... */} while(0)+` block. + +// tag reference: doc/modules/ROOT/examples/exception_nothrow.run-fail.cpp +:bt-name: exception_nothrow +:bt-rule: run-fail +:bt-descr: BOOST__NO_THROW usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_throw} +* xref:testing_tools/exception_correctness.adoc[Exception correctness] section + +[#assertion_boost_level_throw] +== `BOOST__THROW` + +[source,cpp] +---- +BOOST_WARN_THROW(expression, exception_type); +BOOST_CHECK_THROW(expression, exception_type); +BOOST_REQUIRE_THROW(expression, exception_type); +---- + +These assertions validate that the execution of `expression` raises an _expected_ exception, which means an exception of +the supplied `exception_type` type or of any child type. + +* If `expression` raises an unexpected exception, this exception is not caught by `BOOST__THROW` assertion and +might propagate to the test body. If not caught at all, the framework will catch it and terminate the test case +with the status _failed_. +* If `expression` does not raise any exception, the the assertion fails. + +WARNING: the assertion catches only the expected exceptions. + +TIP: It is possible to test for complex expressions with the use of constructs such as `+do { /* ... */} while(0)+` block. + +// tag reference: doc/modules/ROOT/examples/exception_check.run-fail.cpp +:bt-name: exception_check +:bt-rule: run-fail +:bt-descr: BOOST__THROW usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_no_throw} +* xref:testing_tools/exception_correctness.adoc[Exception correctness] section + +[#assertion_boost_level_exception] +== `BOOST__EXCEPTION` + +[source,cpp] +---- +BOOST_WARN_EXCEPTION(expression, exception_type, predicate); +BOOST_CHECK_EXCEPTION(expression, exception_type, predicate); +BOOST_REQUIRE_EXCEPTION(expression, exception_type, predicate); +---- + +As for {boost_level_throw}, these assertions validate that `expression` raises an exception of the +type specified by `exception_type` or any of its child type, with additional checks on the exception instance. + +* If an expected exception is raised by `expression`, the instance of the exception is passed to `predicate` +for further validation. +* It behaves like {boost_level_throw} if `expression` does not raise any exception, or an unrelated exception is raised. + +`predicate` should be a unary function accepting an instance of `exception_type` or any of its child, and that should return +a boolean indicating a success (`true`) or a failure (`false`). + +WARNING: the assertion catches only the expected exceptions. + +TIP: It is possible to test for complex expressions with the use of constructs such as `+do { /* ... */} while(0)+` block. + +The example below checks that the exception carries the proper error code. + +// tag reference: doc/modules/ROOT/examples/exception_check_predicate.run-fail.cpp +:bt-name: exception_check_predicate +:bt-rule: run-fail +:bt-descr: BOOST__EXCEPTION usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_throw} +* xref:testing_tools/exception_correctness.adoc[Exception correctness] section + +[#assertion_boost_level_small] +== `BOOST__SMALL` + +[source,cpp] +---- +BOOST_WARN_SMALL(value, tolerance); +BOOST_CHECK_SMALL(value, tolerance); +BOOST_REQUIRE_SMALL(value, tolerance); +---- + +These tools are used to check that supplied value is small enough. The "smallness" is defined by absolute value +of the tolerance supplied as a second argument. Use these tools with caution. To compare to values on closeness +it's preferable to use {boost_level_close} tools instead. + +The first parameter is the value to check. The second parameter is the tolerance. + +[NOTE] +==== +The floating point comparison tools are automatically added if the {utf} + is included as indicated in the previous sections. The tools are implemented is in the header + link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. +==== + +// tag reference: doc/modules/ROOT/examples/example41.run-fail.cpp +:bt-name: example41 +:bt-rule: run-fail +:bt-descr: BOOST__SMALL usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level_close} +* {boost_level_close_fraction} +* {floating_points_testing_tools} + +[#test_org_boost_test_case_expected_failure] +== `BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES` + +Indicates the number of failures for a test case. + +See xref:testing_tools/expected_failures.adoc[here] for more details. + +[#assertion_boost_error] +== `BOOST_ERROR` + +[source,cpp] +---- +BOOST_ERROR(message); +---- + +{boost_error} tool behave the same way as `{boost_test}(false, message)`. This tool is used for +an unconditional error counter increasing and message logging. + +The tool's only parameter is an error message to log. + +// tag reference: doc/modules/ROOT/examples/example46.run-fail.cpp +:bt-name: example46 +:bt-rule: run-fail +:bt-descr: BOOST_ERROR usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_test} + +[#assertion_boost_fail] +== `BOOST_FAIL` + +[source,cpp] +---- +BOOST_FAIL(message); +---- + +`{boost_fail}(message)` behave the same way as `{boost_test_require}(false, message)`. This tool is used for an +unconditional error counter increasing, message logging and the current test case aborting. + +The tool's only parameter is an error message to log. + +// tag reference: doc/modules/ROOT/examples/example47.run-fail.cpp +:bt-name: example47 +:bt-rule: run-fail +:bt-descr: BOOST_FAIL usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_test} + +* + +[#assertion_boost_is_defined] +== `BOOST_IS_DEFINED` + +[source,cpp] +---- +BOOST_IS_DEFINED(symbol); +---- + +Unlike the rest of the tools in the toolbox this tool does not perform the logging itself. Its only purpose +is to check at runtime whether or not the supplied preprocessor symbol is defined. Use it in combination with +{boost_level} to perform and log validation. Macros of any arity could be checked. To check the +macro definition with non-zero arity specify dummy arguments for it. See below for example. + +The only tool's parameter is a preprocessor symbol that gets validated. + +// tag reference: doc/modules/ROOT/examples/example48.run-fail.cpp +:bt-name: example48 +:bt-rule: run-fail +:bt-descr: BOOST_IS_DEFINED usage +include::partial$bt_example.adoc[] + +See also: + +* {boost_level} + +[#assertion_control_under_debugger] +== `BOOST_TEST_TOOLS_UNDER_DEBUGGER` + +When defined, assertions evaluate their expression eagerly, as described xref:testing_tools/debugging.adoc[here]. + +[#assertion_control_under_debuggable] +== `BOOST_TEST_TOOLS_DEBUGGABLE` + +When defined, test assertions are compiled in two modes (debugger-friendly and full-featured) and the version is selected at run-time, as described xref:testing_tools/debugging.adoc[here]. diff --git a/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc new file mode 100644 index 0000000000..076d7f3510 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc @@ -0,0 +1,53 @@ += Controlling tests outputs +:page-aliases: boost_test/utf_reference/testout_reference.adoc + +[#test_output_macro_checkpoint] +== `BOOST_TEST_CHECKPOINT` + +Sets up a named check point. + +TIP: See the xref:test_output/checkpoints.adoc[checkpoint] section for more details. + +[#test_output_macro_passpoint] +== `BOOST_TEST_PASSPOINT` + +Sets up an unnamed check point. + +TIP: See the xref:test_output/checkpoints.adoc[checkpoint] section for more details. + +[#test_output_macro_message] +== `BOOST_TEST_MESSAGE` + +Outputs a custom message into the test log. + +TIP: See the xref:test_output/test_tools_support_for_logging.adoc#test_output_macro_message[corresponding] section for more details. + +[#test_output_macro_info] +== `BOOST_TEST_INFO` + +Defines a message to be printed as part of the context of the first encountered assertion, if it fails. +For more details see xref:test_output/contexts.adoc[here]. + +[#test_output_macro_context] +== `BOOST_TEST_CONTEXT` + +Defines a scope and a message to be printed as part of the context of every failed assertion within the scope. +For more details see xref:test_output/contexts.adoc[here]. + +[#test_output_macro_context_sticky] +== `BOOST_TEST_INFO_SCOPE` + +Defines a sticky version of {boost_test_info}: the message stored in `BOOST_TEST_INFO_SCOPE` is printed for all failed assertions that come +after the declaration of `BOOST_TEST_INFO_SCOPE` and within the current scope. +For more details see xref:test_output/contexts.adoc[here]. + +[#test_output_macro_disable_type] +== `BOOST_TEST_DONT_PRINT_LOG_VALUE` + +Disables the automatic printing of a value. This macro is relevant + +* a type is used in a comparison assertion (such as {boost_level_ge} for instance) +* when the type being compared does not implement a suitable `operator <<` for streaming out the value into the +test log stream + +TIP: See the xref:test_output/test_tools_support_for_logging.adoc#testing_tool_output_disable[corresponding] section for more details. diff --git a/doc/tools/attributes.yml b/doc/tools/attributes.yml new file mode 100644 index 0000000000..cc67d531b8 --- /dev/null +++ b/doc/tools/attributes.yml @@ -0,0 +1,85 @@ + utf: '_Unit Test Framework_' + pem: '_Program Execution Monitor_' + ieee754: '*IEEE754*' + part_faq: 'xref:section_faq.adoc[FAQ]' + floating_points_testing_tools: 'xref:testing_tools/floating_point.adoc#floating_points_comparison_theory[Floating point comparison algorithms]' + master_test_suite: 'xref:tests_organization/master_test_suite.adoc[master test suite]' + runtime_configuration: 'xref:runtime_config/index.adoc[runtime configuration]' + output_test_stream_tool: 'xref:testing_tools/output_stream_testing.adoc[output test stream]' + auto_linking: 'automatic linking // FIXME(qbk2adoc): unresolved link ref_pem_auto_link' + boost_test_alternative_init_api: 'xref:utf_reference/link_references.adoc#link_boost_test_alternative_init_macro[`BOOST_TEST_ALTERNATIVE_INIT_API`]' + boost_test_main: 'xref:utf_reference/link_references.adoc#link_boost_test_main_macro[`BOOST_TEST_MAIN`]' + boost_test_dyn_link: 'xref:utf_reference/link_references.adoc#link_boost_test_dyn_link[`BOOST_TEST_DYN_LINK`]' + boost_test_no_lib: 'xref:utf_reference/link_references.adoc#link_boost_test_no_lib[`BOOST_TEST_NO_LIB`]' + boost_test_no_main: 'xref:utf_reference/link_references.adoc#link_boost_test_no_main[`BOOST_TEST_NO_MAIN`]' + boost_test_module: 'xref:utf_reference/link_references.adoc#link_boost_test_module_macro[`BOOST_TEST_MODULE`]' + boost_test_global_configuration: 'xref:utf_reference/link_references.adoc#link_boost_test_global_configuration[`BOOST_TEST_GLOBAL_CONFIGURATION`]' + boost_test_checkpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_checkpoint[`BOOST_TEST_CHECKPOINT`]' + boost_test_passpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_passpoint[`BOOST_TEST_PASSPOINT`]' + boost_test_message: 'xref:utf_reference/testout_reference.adoc#test_output_macro_message[`BOOST_TEST_MESSAGE`]' + boost_test_info: 'xref:utf_reference/testout_reference.adoc#test_output_macro_info[`BOOST_TEST_INFO`]' + boost_test_context: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context[`BOOST_TEST_CONTEXT`]' + boost_test_info_scope: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context_sticky[`BOOST_TEST_INFO_SCOPE`]' + boost_test_dont_print_log_value: 'xref:utf_reference/testout_reference.adoc#test_output_macro_disable_type[`BOOST_TEST_DONT_PRINT_LOG_VALUE`]' + boost_test: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST`]' + boost_test_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_`]' + boost_test_require: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_REQUIRE`]' + boost_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level[`BOOST_`]' + boost_level_message: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_message[`BOOST__MESSAGE`]' + boost_level_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq[`BOOST__EQUAL`]' + boost_level_predicate: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate[`BOOST__PREDICATE`]' + boost_level_equal_collections: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections[`BOOST__EQUAL_COLLECTIONS`]' + boost_level_ne: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne[`BOOST__NE`]' + boost_level_ge: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge[`BOOST__GE`]' + boost_level_gt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt[`BOOST__GT`]' + boost_level_le: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_le[`BOOST__LE`]' + boost_level_lt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt[`BOOST__LT`]' + boost_level_no_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw[`BOOST__NO_THROW`]' + boost_level_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST__THROW`]' + boost_level_exception: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception[`BOOST__EXCEPTION`]' + boost_level_bitwise_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq[`BOOST__BITWISE_EQUAL`]' + boost_error: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_error[`BOOST_ERROR`]' + boost_fail: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_fail[`BOOST_FAIL`]' + boost_is_defined: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined[`BOOST_IS_DEFINED`]' + boost_auto_test_case_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`]' + boost_level_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST__SMALL`]' + boost_check_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST_CHECK_SMALL`]' + boost_level_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST__CLOSE`]' + boost_check_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST_CHECK_CLOSE`]' + boost_level_close_fraction: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction[`BOOST__CLOSE_FRACTION`]' + boost_test_tools_under_debugger: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`]' + boost_test_tools_debuggable: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable[`BOOST_TEST_TOOLS_DEBUGGABLE`]' + boost_auto_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case[`BOOST_AUTO_TEST_CASE`]' + boost_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE`]' + boost_test_case_name: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE_NAME`]' + boost_auto_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template[`BOOST_AUTO_TEST_CASE_TEMPLATE`]' + boost_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template[`BOOST_TEST_CASE_TEMPLATE`]' + boost_test_case_template_function: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`]' + boost_param_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter[`BOOST_PARAM_TEST_CASE`]' + boost_data_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_DATA_TEST_CASE`]' + boost_data_test_case_f: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture[`BOOST_DATA_TEST_CASE_F`]' + boost_test_dataset_max_arity: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_TEST_DATASET_MAX_ARITY`]' + boost_auto_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite[`BOOST_AUTO_TEST_SUITE`]' + boost_auto_test_suite_end: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end[`BOOST_AUTO_TEST_SUITE_END`]' + boost_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite[`BOOST_TEST_SUITE`]' + boost_test_decorator: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_decorator[`BOOST_TEST_DECORATOR`]' + boost_fixture_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture[`BOOST_FIXTURE_TEST_CASE`]' + boost_fixture_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture[`BOOST_FIXTURE_TEST_SUITE`]' + boost_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_global_fixture[`BOOST_GLOBAL_FIXTURE`]' + boost_test_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture[`BOOST_TEST_GLOBAL_FIXTURE`]' + boost_test_log_level: 'xref:utf_reference/rt_param_reference.adoc#log_level[`BOOST_TEST_LOG_LEVEL`]' + default_run_status: 'xref:runtime_config/test_unit_filtering.adoc#ref_default_run_status[_default run status_]' + param_run_test: 'xref:utf_reference/rt_param_reference.adoc#run_test[`run_test`]' + decorator_label: 'xref:utf_reference/test_org_reference.adoc#decorator_label[`label`]' + decorator_enabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`enabled`]' + decorator_disabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`disabled`]' + decorator_enable_if: 'xref:utf_reference/test_org_reference.adoc#decorator_enable_if[`enable_if`]' + decorator_depends_on: 'xref:utf_reference/test_org_reference.adoc#decorator_depends_on[`depends_on`]' + decorator_precondition: 'xref:utf_reference/test_org_reference.adoc#decorator_precondition[`precondition`]' + decorator_fixture: 'xref:utf_reference/test_org_reference.adoc#decorator_fixture[`fixture`]' + decorator_description: 'xref:utf_reference/test_org_reference.adoc#decorator_description[`description`]' + decorator_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#decorator_expected_failures[`expected_failures`]' + decorator_timeout: 'xref:utf_reference/testing_tool_ref.adoc#decorator_timeout[`timeout`]' + decorator_tolerance: 'xref:utf_reference/testing_tool_ref.adoc#decorator_tolerance[`tolerance`]' + class_predicate_result: 'cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result]' + class_assertion_result: 'cpp:boost::test_tools::assertion_result[test_tools::assertion_result]' diff --git a/doc/tools/nav.adoc b/doc/tools/nav.adoc new file mode 100644 index 0000000000..10aa61185a --- /dev/null +++ b/doc/tools/nav.adoc @@ -0,0 +1,76 @@ +* xref:index.adoc[] +** xref:intro/design_rationale.adoc[] +** xref:intro/how_to_read.adoc[] +* xref:usage_variants.adoc[] +* xref:tests_organization/index.adoc[] +** xref:tests_organization/test_cases.adoc[] +*** xref:tests_organization/test_organization_nullary.adoc[] +*** xref:tests_organization/test_case_generation.adoc[] +*** xref:tests_organization/test_organization_templates.adoc[] +*** xref:tests_organization/param_test.adoc[] +** xref:tests_organization/test_tree.adoc[] +*** xref:tests_organization/test_suite.adoc[] +*** xref:tests_organization/master_test_suite.adoc[] +*** xref:tests_organization/test_naming.adoc[] +*** xref:tests_organization/test_tree_content.adoc[] +** xref:tests_organization/decorators.adoc[] +** xref:tests_organization/fixtures.adoc[] +** xref:tests_organization/tests_dependencies.adoc[] +** xref:tests_organization/tests_grouping.adoc[] +** xref:tests_organization/enabling.adoc[] +** xref:tests_organization/semantic.adoc[] +** xref:tests_organization/summary.adoc[] +* xref:testing_tools/index.adoc[] +** xref:testing_tools/tools_assertion_severity_level.adoc[] +** xref:testing_tools/boost_test_universal_macro.adoc[] +** xref:testing_tools/reports.adoc[] +** xref:testing_tools/floating_point.adoc[] +** xref:testing_tools/strings.adoc[] +** xref:testing_tools/collections.adoc[] +** xref:testing_tools/bitwise.adoc[] +** xref:testing_tools/exception_correctness.adoc[] +** xref:testing_tools/timeout.adoc[] +** xref:testing_tools/expected_failures.adoc[] +** xref:testing_tools/custom_predicates.adoc[] +** xref:testing_tools/output_stream_testing.adoc[] +** xref:testing_tools/internal_details.adoc[] +** xref:testing_tools/debugging.adoc[] +** xref:testing_tools/summary.adoc[] +* xref:test_output/index.adoc[] +** xref:test_output/test_tools_support_for_logging.adoc[] +*** xref:test_output/checkpoints.adoc[] +*** xref:test_output/contexts.adoc[] +*** xref:test_output/log_floating_points.adoc[] +** xref:test_output/log_formats.adoc[] +** xref:test_output/report_formats.adoc[] +** xref:test_output/logging_api.adoc[] +** xref:test_output/test_output_progress.adoc[] +** xref:test_output/summary.adoc[] +* xref:runtime_config/index.adoc[] +** xref:runtime_config/test_unit_filtering.adoc[] +** xref:runtime_config/runtime_custom.adoc[] +** xref:runtime_config/summary.adoc[] +* xref:adv_scenarios/index.adoc[] +** xref:adv_scenarios/build_utf.adoc[] +** xref:adv_scenarios/entry_point_overview.adoc[] +** xref:adv_scenarios/test_module_init_overview.adoc[] +** xref:adv_scenarios/test_module_runner_overview.adoc[] +** xref:adv_scenarios/single_header_customizations.adoc[] +** xref:adv_scenarios/static_lib_customizations.adoc[] +** xref:adv_scenarios/shared_lib_customizations.adoc[] +** xref:adv_scenarios/external_test_runner.adoc[] +** xref:adv_scenarios/obsolete_init_func.adoc[] +* xref:usage_recommendations/index.adoc[] +** xref:usage_recommendations/bt_and_tdd.adoc[] +** xref:usage_recommendations/hello.adoc[] +** xref:usage_recommendations/web_wisdom.adoc[] +* xref:section_faq.adoc[] +* xref:section_glossary.adoc[] +* xref:change_log.adoc[] +* xref:acknowledgments.adoc[] +* xref:utf_reference/index.adoc[] +** xref:utf_reference/test_org_reference.adoc[] +** xref:utf_reference/testing_tool_ref.adoc[] +** xref:utf_reference/testout_reference.adoc[] +** xref:utf_reference/rt_param_reference.adoc[] +** xref:utf_reference/link_references.adoc[] diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py index 20d0cb037a..ffd720e85f 100644 --- a/doc/tools/qbk2adoc.py +++ b/doc/tools/qbk2adoc.py @@ -89,6 +89,10 @@ } MACROREF_PAGE = "utf_reference/link_references.adoc" +# parametric_test_case_generation.qbk gives two different tables the same id. +# The second one lists the random generator's parameters. +DUPLICATE_TABLE_IDS = {"id_range_parameter_table": "id_random_parameter_table"} + # --------------------------------------------------------------------------- # Lexing helpers @@ -448,6 +452,7 @@ def __init__(self, index, outdir): self.examples = set() self.imports = set() self.snippets = {} # callout id -> example$ resource path + self.table_ids = {} # table anchor -> times seen self.plain = {} # def name -> plain text, for use inside code for name, value in index.defs.items(): self.plain[name] = self._plain_text(value) @@ -822,14 +827,29 @@ def table(self, inner, page): rows = [r for r in rows if r] if not rows: return self.fixme("empty-table", title) - ncols = max(len(r) for r in rows) + # The header row fixes the column count. One source table has a row + # with an extra cell; fold the surplus into the first column rather + # than let Asciidoctor drop it. + ncols = len(rows[0]) + for row in rows: + while len(row) > ncols: + row[0:2] = [row[0] + " / " + row[1]] + self.fixmes["table-row-overfull"] += 1 + while len(row) < ncols: + row.append("") + self.fixmes["table-row-short"] += 1 out = [] if anchor: + if anchor in self.table_ids: + anchor = DUPLICATE_TABLE_IDS.get( + anchor, "%s-%d" % (anchor, self.table_ids[anchor] + 1)) + self.fixmes["duplicate-table-id"] += 1 + self.table_ids[anchor] = self.table_ids.get(anchor, 0) + 1 out.append("[#%s]\n" % anchor) if title: out.append(".%s\n" % self.inline(title, page).strip()) out.append('[%%header%%autowidth,cols="%d*"]\n|===\n' % ncols) - for idx, row in enumerate(rows): + for row in rows: for cell in row: rendered = self.render_body(cell, page, 6, []).strip() if "\n" in rendered: @@ -837,8 +857,6 @@ def table(self, inner, page): else: out.append("|%s\n" % rendered.replace("|", "\\|")) out.append("\n") - if idx == 0 and len(rows) > 1: - pass out.append("|===\n\n") return "".join(out) From 290304b2b2e82d8e6acebc87f81c845d2bab04aa Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 12:14:16 -0400 Subject: [PATCH 05/10] doc: generate the API reference with MrDocs Replaces the Doxygen target the QuickBook build used. doc/CMakeLists.txt is a standalone project that gives MrDocs a compilation database for doc/mrdocs.cpp, an umbrella translation unit including the same ~50 public headers the Doxygen target curated. The library's own CMakeLists.txt cannot serve: it is a modular Boost library that only configures from the superproject. BOOST_TEST_DOXYGEN_DOC__ is deliberately not defined, although the Doxygen target set it. It exists for a tool that does not compile what it reads, and MrDocs does: with it set, data/monomorphic/fwd.hpp hides the forward declarations that make_delayed() needs and the header does not compile, and data/config.hpp defines BOOST_TEST_NO_{RANDOM_DATASET,GRID_COMPOSITION, ZIP_COMPOSITION}_AVAILABLE, which would drop those datasets from the reference. The macros it reveals carry no doc comments and are documented by hand. mrdocs-addons overrides one template. Antora ignores files whose name starts with an underscore, and MrDocs names a page after its symbol, so the unnamed enum behind `enum { type = TUT_CASE };` in tree/test_unit.hpp produced links to pages Antora never published. The override drops the link and keeps the row. The [def]-derived attributes are restructured at the same time. They used to hold a whole xref including its label, which renders the backticks visible: Asciidoctor substitutes quotes before attributes, and an API attribute -- which is what antora.yml sets -- is inserted without further substitution. They now hold only the link target, with the label at the call site. The site builds with no warnings: 1665 pages, of which 1520 are reference. Co-Authored-By: Claude Opus 5 (1M context) --- doc/CMakeLists.txt | 51 +++++ doc/antora.yml | 183 +++++++++--------- doc/modules/ROOT/nav.adoc | 1 + .../ROOT/pages/adv_scenarios/build_utf.adoc | 12 +- .../adv_scenarios/entry_point_overview.adoc | 6 +- .../adv_scenarios/external_test_runner.adoc | 4 +- .../ROOT/pages/adv_scenarios/index.adoc | 16 +- .../adv_scenarios/obsolete_init_func.adoc | 14 +- .../shared_lib_customizations.adoc | 10 +- .../single_header_customizations.adoc | 24 +-- .../static_lib_customizations.adoc | 20 +- .../test_module_init_overview.adoc | 16 +- .../test_module_runner_overview.adoc | 4 +- doc/modules/ROOT/pages/change_log.adoc | 22 +-- .../ROOT/pages/intro/design_rationale.adoc | 4 +- doc/modules/ROOT/pages/intro/how_to_read.adoc | 6 +- .../ROOT/pages/runtime_config/index.adoc | 16 +- .../pages/runtime_config/runtime_custom.adoc | 22 +-- .../ROOT/pages/runtime_config/summary.adoc | 4 +- .../runtime_config/test_unit_filtering.adoc | 48 ++--- doc/modules/ROOT/pages/section_faq.adoc | 22 +-- doc/modules/ROOT/pages/section_glossary.adoc | 10 +- .../ROOT/pages/test_output/checkpoints.adoc | 20 +- .../ROOT/pages/test_output/contexts.adoc | 4 +- doc/modules/ROOT/pages/test_output/index.adoc | 14 +- .../test_output/log_floating_points.adoc | 6 +- .../ROOT/pages/test_output/log_formats.adoc | 12 +- .../ROOT/pages/test_output/logging_api.adoc | 6 +- .../ROOT/pages/test_output/summary.adoc | 16 +- .../test_output/test_output_progress.adoc | 10 +- .../test_tools_support_for_logging.adoc | 14 +- .../ROOT/pages/testing_tools/bitwise.adoc | 4 +- .../boost_test_universal_macro.adoc | 2 +- .../ROOT/pages/testing_tools/collections.adoc | 22 +-- .../testing_tools/custom_predicates.adoc | 12 +- .../ROOT/pages/testing_tools/debugging.adoc | 14 +- .../testing_tools/exception_correctness.adoc | 8 +- .../testing_tools/expected_failures.adoc | 8 +- .../pages/testing_tools/floating_point.adoc | 38 ++-- .../ROOT/pages/testing_tools/index.adoc | 4 +- .../pages/testing_tools/internal_details.adoc | 2 +- .../ROOT/pages/testing_tools/reports.adoc | 4 +- .../ROOT/pages/testing_tools/strings.adoc | 6 +- .../ROOT/pages/testing_tools/summary.adoc | 56 +++--- .../ROOT/pages/testing_tools/timeout.adoc | 12 +- .../tools_assertion_severity_level.adoc | 4 +- .../pages/tests_organization/decorators.adoc | 16 +- .../pages/tests_organization/enabling.adoc | 18 +- .../pages/tests_organization/fixtures.adoc | 50 ++--- .../ROOT/pages/tests_organization/index.adoc | 8 +- .../tests_organization/master_test_suite.adoc | 10 +- .../pages/tests_organization/param_test.adoc | 2 +- .../pages/tests_organization/semantic.adoc | 2 +- .../pages/tests_organization/summary.adoc | 52 ++--- .../test_case_generation.adoc | 36 ++-- .../pages/tests_organization/test_cases.adoc | 12 +- .../pages/tests_organization/test_naming.adoc | 10 +- .../test_organization_nullary.adoc | 16 +- .../test_organization_templates.adoc | 28 +-- .../pages/tests_organization/test_suite.adoc | 20 +- .../pages/tests_organization/test_tree.adoc | 2 +- .../tests_organization/test_tree_content.adoc | 2 +- .../tests_dependencies.adoc | 6 +- .../tests_organization/tests_grouping.adoc | 4 +- .../pages/usage_recommendations/hello.adoc | 4 +- .../pages/usage_recommendations/index.adoc | 4 +- doc/modules/ROOT/pages/usage_variants.adoc | 34 ++-- .../ROOT/pages/utf_reference/index.adoc | 40 +++- .../pages/utf_reference/link_references.adoc | 32 +-- .../utf_reference/rt_param_reference.adoc | 50 ++--- .../utf_reference/test_org_reference.adoc | 18 +- .../pages/utf_reference/testing_tool_ref.adoc | 124 ++++++------ .../utf_reference/testout_reference.adoc | 4 +- .../generator/adoc/partials/markup/a.adoc.hbs | 44 +++++ doc/mrdocs.cpp | 101 ++++++++++ doc/mrdocs.yml | 104 ++++++++++ doc/tools/attributes.yml | 164 ++++++++-------- doc/tools/qbk2adoc.py | 71 ++++--- 78 files changed, 1127 insertions(+), 774 deletions(-) create mode 100644 doc/CMakeLists.txt create mode 100644 doc/mrdocs-addons/generator/adoc/partials/markup/a.adoc.hbs create mode 100644 doc/mrdocs.cpp create mode 100644 doc/mrdocs.yml diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000000..ad8ac2eb96 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# Copyright (c) 2003 Boost.Test contributors +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Standalone project whose only purpose is to give MrDocs a compilation +# database for mrdocs.cpp, the umbrella translation unit that includes the +# public headers. Nothing is built: MrDocs only configures this project and +# reads compile_commands.json. +# +# The library's own CMakeLists.txt cannot serve this purpose because it is a +# modular-Boost library that has to be added from the superproject. So this +# project adds the superproject instead, restricted to Boost.Test and its +# dependencies, and picks up the include paths from the Boost::unit_test_framework +# target's interface. + +cmake_minimum_required(VERSION 3.8...3.22) + +project(boost_test_mrdocs LANGUAGES CXX) + +# MrDocs forces CMAKE_EXPORT_COMPILE_COMMANDS=ON, which would dump every target +# of the superproject into the compilation database. Turn it off globally and +# switch it on for our target alone. +set(CMAKE_EXPORT_COMPILE_COMMANDS OFF) + +if(NOT DEFINED ENV{BOOST_SRC_DIR}) + message(FATAL_ERROR + "BOOST_SRC_DIR is not set. It normally comes from the cpp-reference " + "extension's `dependencies` block in the Antora playbook; build_antora.sh " + "also derives it from a surrounding Boost superproject checkout.") +endif() + +# Configure only what Boost.Test needs; the superproject resolves the +# dependencies listed in ../CMakeLists.txt for us. +set(BOOST_INCLUDE_LIBRARIES test) +add_subdirectory($ENV{BOOST_SRC_DIR} deps/boost EXCLUDE_FROM_ALL) + +# An object library, not an executable: unit_test.hpp brings in a main() +# that wants init_unit_test_suite(), and there is nothing here to link. +add_library(mrdocs OBJECT mrdocs.cpp) + +# This worktree's headers must win over whatever the Boost checkout carries, +# which matters when BOOST_SRC_DIR is a clone rather than the superproject this +# library sits in. +target_include_directories(mrdocs BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include) +target_link_libraries(mrdocs PRIVATE Boost::unit_test_framework) +set_target_properties(mrdocs PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + EXPORT_COMPILE_COMMANDS ON) diff --git a/doc/antora.yml b/doc/antora.yml index 9a83344b51..f2788954f0 100644 --- a/doc/antora.yml +++ b/doc/antora.yml @@ -25,105 +25,102 @@ asciidoc: pr-url: https://github.com/boostorg/test/pull issue-url: https://github.com/boostorg/test/issues # >>> BEGIN GENERATED ATTRIBUTES (doc/tools/qbk2adoc.py) <<< - # The QuickBook [def] macros were mostly link aliases into the reference - # chapter. They are kept as attributes so a reference page can be renamed - # in one place instead of at ~2000 call sites. - utf: '_Unit Test Framework_' - pem: '_Program Execution Monitor_' - ieee754: '*IEEE754*' - part_faq: 'xref:section_faq.adoc[FAQ]' - floating_points_testing_tools: 'xref:testing_tools/floating_point.adoc#floating_points_comparison_theory[Floating point comparison algorithms]' - master_test_suite: 'xref:tests_organization/master_test_suite.adoc[master test suite]' - runtime_configuration: 'xref:runtime_config/index.adoc[runtime configuration]' - output_test_stream_tool: 'xref:testing_tools/output_stream_testing.adoc[output test stream]' - auto_linking: 'automatic linking // FIXME(qbk2adoc): unresolved link ref_pem_auto_link' - boost_test_alternative_init_api: 'xref:utf_reference/link_references.adoc#link_boost_test_alternative_init_macro[`BOOST_TEST_ALTERNATIVE_INIT_API`]' - boost_test_main: 'xref:utf_reference/link_references.adoc#link_boost_test_main_macro[`BOOST_TEST_MAIN`]' - boost_test_dyn_link: 'xref:utf_reference/link_references.adoc#link_boost_test_dyn_link[`BOOST_TEST_DYN_LINK`]' - boost_test_no_lib: 'xref:utf_reference/link_references.adoc#link_boost_test_no_lib[`BOOST_TEST_NO_LIB`]' - boost_test_no_main: 'xref:utf_reference/link_references.adoc#link_boost_test_no_main[`BOOST_TEST_NO_MAIN`]' - boost_test_module: 'xref:utf_reference/link_references.adoc#link_boost_test_module_macro[`BOOST_TEST_MODULE`]' - boost_test_global_configuration: 'xref:utf_reference/link_references.adoc#link_boost_test_global_configuration[`BOOST_TEST_GLOBAL_CONFIGURATION`]' - boost_test_checkpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_checkpoint[`BOOST_TEST_CHECKPOINT`]' - boost_test_passpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_passpoint[`BOOST_TEST_PASSPOINT`]' - boost_test_message: 'xref:utf_reference/testout_reference.adoc#test_output_macro_message[`BOOST_TEST_MESSAGE`]' - boost_test_info: 'xref:utf_reference/testout_reference.adoc#test_output_macro_info[`BOOST_TEST_INFO`]' - boost_test_context: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context[`BOOST_TEST_CONTEXT`]' - boost_test_info_scope: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context_sticky[`BOOST_TEST_INFO_SCOPE`]' - boost_test_dont_print_log_value: 'xref:utf_reference/testout_reference.adoc#test_output_macro_disable_type[`BOOST_TEST_DONT_PRINT_LOG_VALUE`]' - boost_test: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST`]' - boost_test_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_`]' - boost_test_require: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_REQUIRE`]' - boost_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level[`BOOST_`]' - boost_level_message: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_message[`BOOST__MESSAGE`]' - boost_level_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq[`BOOST__EQUAL`]' - boost_level_predicate: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate[`BOOST__PREDICATE`]' - boost_level_equal_collections: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections[`BOOST__EQUAL_COLLECTIONS`]' - boost_level_ne: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne[`BOOST__NE`]' - boost_level_ge: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge[`BOOST__GE`]' - boost_level_gt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt[`BOOST__GT`]' - boost_level_le: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_le[`BOOST__LE`]' - boost_level_lt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt[`BOOST__LT`]' - boost_level_no_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw[`BOOST__NO_THROW`]' - boost_level_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST__THROW`]' - boost_level_exception: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception[`BOOST__EXCEPTION`]' - boost_level_bitwise_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq[`BOOST__BITWISE_EQUAL`]' - boost_error: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_error[`BOOST_ERROR`]' - boost_fail: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_fail[`BOOST_FAIL`]' - boost_is_defined: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined[`BOOST_IS_DEFINED`]' - boost_auto_test_case_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`]' - boost_level_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST__SMALL`]' - boost_check_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST_CHECK_SMALL`]' - boost_level_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST__CLOSE`]' - boost_check_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST_CHECK_CLOSE`]' - boost_level_close_fraction: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction[`BOOST__CLOSE_FRACTION`]' - boost_test_tools_under_debugger: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`]' - boost_test_tools_debuggable: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable[`BOOST_TEST_TOOLS_DEBUGGABLE`]' - boost_auto_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case[`BOOST_AUTO_TEST_CASE`]' - boost_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE`]' - boost_test_case_name: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE_NAME`]' - boost_auto_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template[`BOOST_AUTO_TEST_CASE_TEMPLATE`]' - boost_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template[`BOOST_TEST_CASE_TEMPLATE`]' - boost_test_case_template_function: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`]' - boost_param_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter[`BOOST_PARAM_TEST_CASE`]' - boost_data_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_DATA_TEST_CASE`]' - boost_data_test_case_f: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture[`BOOST_DATA_TEST_CASE_F`]' - boost_test_dataset_max_arity: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_TEST_DATASET_MAX_ARITY`]' - boost_auto_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite[`BOOST_AUTO_TEST_SUITE`]' - boost_auto_test_suite_end: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end[`BOOST_AUTO_TEST_SUITE_END`]' - boost_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite[`BOOST_TEST_SUITE`]' - boost_test_decorator: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_decorator[`BOOST_TEST_DECORATOR`]' - boost_fixture_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture[`BOOST_FIXTURE_TEST_CASE`]' - boost_fixture_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture[`BOOST_FIXTURE_TEST_SUITE`]' - boost_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_global_fixture[`BOOST_GLOBAL_FIXTURE`]' - boost_test_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture[`BOOST_TEST_GLOBAL_FIXTURE`]' - boost_test_log_level: 'xref:utf_reference/rt_param_reference.adoc#log_level[`BOOST_TEST_LOG_LEVEL`]' - default_run_status: 'xref:runtime_config/test_unit_filtering.adoc#ref_default_run_status[_default run status_]' - param_run_test: 'xref:utf_reference/rt_param_reference.adoc#run_test[`run_test`]' - decorator_label: 'xref:utf_reference/test_org_reference.adoc#decorator_label[`label`]' - decorator_enabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`enabled`]' - decorator_disabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`disabled`]' - decorator_enable_if: 'xref:utf_reference/test_org_reference.adoc#decorator_enable_if[`enable_if`]' - decorator_depends_on: 'xref:utf_reference/test_org_reference.adoc#decorator_depends_on[`depends_on`]' - decorator_precondition: 'xref:utf_reference/test_org_reference.adoc#decorator_precondition[`precondition`]' - decorator_fixture: 'xref:utf_reference/test_org_reference.adoc#decorator_fixture[`fixture`]' - decorator_description: 'xref:utf_reference/test_org_reference.adoc#decorator_description[`description`]' - decorator_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#decorator_expected_failures[`expected_failures`]' - decorator_timeout: 'xref:utf_reference/testing_tool_ref.adoc#decorator_timeout[`timeout`]' - decorator_tolerance: 'xref:utf_reference/testing_tool_ref.adoc#decorator_tolerance[`tolerance`]' - class_predicate_result: 'cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result]' - class_assertion_result: 'cpp:boost::test_tools::assertion_result[test_tools::assertion_result]' + # Most of the QuickBook [def] macros were link aliases into the reference + # chapter. Only the link *target* lives here, so a reference page can be + # renamed in one place instead of at ~2000 call sites; the label stays at + # the call site. It has to: Asciidoctor substitutes quotes before + # attributes, and a value coming from an API attribute -- which is what + # this file sets -- is inserted without further substitution, so `code` + # formatting inside an attribute value would render its backticks. + part_faq: 'section_faq.adoc' + floating_points_testing_tools: 'testing_tools/floating_point.adoc#floating_points_comparison_theory' + master_test_suite: 'tests_organization/master_test_suite.adoc' + runtime_configuration: 'runtime_config/index.adoc' + output_test_stream_tool: 'testing_tools/output_stream_testing.adoc' + boost_test_alternative_init_api: 'utf_reference/link_references.adoc#link_boost_test_alternative_init_macro' + boost_test_main: 'utf_reference/link_references.adoc#link_boost_test_main_macro' + boost_test_dyn_link: 'utf_reference/link_references.adoc#link_boost_test_dyn_link' + boost_test_no_lib: 'utf_reference/link_references.adoc#link_boost_test_no_lib' + boost_test_no_main: 'utf_reference/link_references.adoc#link_boost_test_no_main' + boost_test_module: 'utf_reference/link_references.adoc#link_boost_test_module_macro' + boost_test_global_configuration: 'utf_reference/link_references.adoc#link_boost_test_global_configuration' + boost_test_checkpoint: 'utf_reference/testout_reference.adoc#test_output_macro_checkpoint' + boost_test_passpoint: 'utf_reference/testout_reference.adoc#test_output_macro_passpoint' + boost_test_message: 'utf_reference/testout_reference.adoc#test_output_macro_message' + boost_test_info: 'utf_reference/testout_reference.adoc#test_output_macro_info' + boost_test_context: 'utf_reference/testout_reference.adoc#test_output_macro_context' + boost_test_info_scope: 'utf_reference/testout_reference.adoc#test_output_macro_context_sticky' + boost_test_dont_print_log_value: 'utf_reference/testout_reference.adoc#test_output_macro_disable_type' + boost_test: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_test_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_test_require: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level' + boost_level_message: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_message' + boost_level_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq' + boost_level_predicate: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate' + boost_level_equal_collections: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections' + boost_level_ne: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne' + boost_level_ge: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge' + boost_level_gt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt' + boost_level_le: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_le' + boost_level_lt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt' + boost_level_no_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw' + boost_level_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw' + boost_level_exception: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception' + boost_level_bitwise_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq' + boost_error: 'utf_reference/testing_tool_ref.adoc#assertion_boost_error' + boost_fail: 'utf_reference/testing_tool_ref.adoc#assertion_boost_fail' + boost_is_defined: 'utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined' + boost_auto_test_case_expected_failures: 'utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure' + boost_level_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' + boost_check_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' + boost_level_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' + boost_check_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' + boost_level_close_fraction: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction' + boost_test_tools_under_debugger: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger' + boost_test_tools_debuggable: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable' + boost_auto_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case' + boost_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' + boost_test_case_name: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' + boost_auto_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template' + boost_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template' + boost_test_case_template_function: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function' + boost_param_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter' + boost_data_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' + boost_data_test_case_f: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture' + boost_test_dataset_max_arity: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' + boost_auto_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite' + boost_auto_test_suite_end: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end' + boost_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite' + boost_test_decorator: 'utf_reference/test_org_reference.adoc#test_org_boost_test_decorator' + boost_fixture_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture' + boost_fixture_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture' + boost_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_global_fixture' + boost_test_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture' + boost_test_log_level: 'utf_reference/rt_param_reference.adoc#log_level' + default_run_status: 'runtime_config/test_unit_filtering.adoc#ref_default_run_status' + param_run_test: 'utf_reference/rt_param_reference.adoc#run_test' + decorator_label: 'utf_reference/test_org_reference.adoc#decorator_label' + decorator_enabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' + decorator_disabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' + decorator_enable_if: 'utf_reference/test_org_reference.adoc#decorator_enable_if' + decorator_depends_on: 'utf_reference/test_org_reference.adoc#decorator_depends_on' + decorator_precondition: 'utf_reference/test_org_reference.adoc#decorator_precondition' + decorator_fixture: 'utf_reference/test_org_reference.adoc#decorator_fixture' + decorator_description: 'utf_reference/test_org_reference.adoc#decorator_description' + decorator_expected_failures: 'utf_reference/testing_tool_ref.adoc#decorator_expected_failures' + decorator_timeout: 'utf_reference/testing_tool_ref.adoc#decorator_timeout' + decorator_tolerance: 'utf_reference/testing_tool_ref.adoc#decorator_tolerance' # >>> END GENERATED ATTRIBUTES <<< nav: - modules/ROOT/nav.adoc ext: - # Re-enabled once doc/mrdocs.yml, doc/CMakeLists.txt and doc/mrdocs.cpp land. - # Commenting this out is also the fast inner loop when editing prose: it skips - # MrDocs entirely. - # cpp-reference: - # config: doc/mrdocs.yml + # Commenting this stanza out is the fast inner loop when editing prose: it + # skips MrDocs, and with it the reference module, entirely. + cpp-reference: + config: doc/mrdocs.yml cpp-tagfiles: using-namespaces: - boost::unit_test diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc index 10aa61185a..55cbf3b669 100644 --- a/doc/modules/ROOT/nav.adoc +++ b/doc/modules/ROOT/nav.adoc @@ -74,3 +74,4 @@ ** xref:utf_reference/testout_reference.adoc[] ** xref:utf_reference/rt_param_reference.adoc[] ** xref:utf_reference/link_references.adoc[] +** xref:reference:index.adoc[C++ API reference] diff --git a/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc b/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc index 1d072d6955..05bbc8e4d4 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/build_utf.adoc @@ -1,13 +1,13 @@ -= Building the {utf} += Building the _Unit Test Framework_ :page-aliases: boost_test/adv_scenarios/build_utf.adoc -In case you would like to use the xref:usage_variants.adoc#shared_lib[shared library variant] or the xref:usage_variants.adoc#static_lib[static library variant] of the {utf}, the library needs to be built. -Building the {utf} is in fact quite easy. +In case you would like to use the xref:usage_variants.adoc#shared_lib[shared library variant] or the xref:usage_variants.adoc#static_lib[static library variant] of the _Unit Test Framework_, the library needs to be built. +Building the _Unit Test Framework_ is in fact quite easy. In the sequel, we define * $`boost_path` refers to the location where the boost archive was deflated -* $`boost_installation_prefix` refers to the location where you want to install the {utf} +* $`boost_installation_prefix` refers to the location where you want to install the _Unit Test Framework_ More documentation about *Boost's build system* can be found http://www.boost.org/more/getting_started/index.html[here]. @@ -15,7 +15,7 @@ More documentation about *Boost's build system* can be found http://www.boost.or You need to have a compilation toolchain. _Visual Studio Express_ is such one, freely available from the Microsoft website. Once installed, open a _Visual Studio Command Line tools_ prompt and build the Boost build program `b2` -(see the link above). You will then be able to compile the {utf} with different variants. +(see the link above). You will then be able to compile the _Unit Test Framework_ with different variants. === Static variant @@ -53,7 +53,7 @@ For instance, for 64bits builds, the commands become: == Linux/OSX -For Unix/Linux/OSX operating system, the build of the {utf} is very similar to the one on Windows: +For Unix/Linux/OSX operating system, the build of the _Unit Test Framework_ is very similar to the one on Windows: [source,cpp] ---- diff --git a/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc index f811f0e660..5654938832 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/entry_point_overview.adoc @@ -2,16 +2,16 @@ :page-aliases: boost_test/adv_scenarios/entry_point_overview.adoc Typically, every C++ program contains exactly one definition of function `main`: the program's _entry point_. -When using the {utf} you do not have to define one. Function `main` will be generated for you by the framework. +When using the _Unit Test Framework_ you do not have to define one. Function `main` will be generated for you by the framework. The only thing you are required to do in case your program consists of more than one translation unit (`cpp` file) is to indicate to the framework in which of the files it is supposed to generate function `main`. -You do it by defining macro {boost_test_module} before the inclusion of any of the framework files. +You do it by defining macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] before the inclusion of any of the framework files. The value of this macro is used as a name of the xref:section_glossary.adoc#ref_test_module[test module] as well as the xref:tests_organization/master_test_suite.adoc[master test suite]. The reason for defining function `main` for you is twofold: -. This allows the {utf} to perform some custom xref:adv_scenarios/test_module_init_overview.adoc[_test module initialization_]. +. This allows the _Unit Test Framework_ to perform some custom xref:adv_scenarios/test_module_init_overview.adoc[_test module initialization_]. . This prevents you defining `main`, and accidentally forgetting to run all the test (in which case running the program would incorrectly indicate a clean run). By default, the test module's entry point is defined with signature: diff --git a/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc b/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc index 0e7fdac75c..6711549a35 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/external_test_runner.adoc @@ -7,9 +7,9 @@ xref:adv_scenarios/test_module_init_overview.adoc[initialization function], and expect another (external) program to evaluate these tests. This external program will come with its own test runner. If you plan to use an external test runner with your test module, you need to build it as a dynamic library. -You need to define macro flag {boost_test_dyn_link} either in a makefile or before the header +You need to define macro flag xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] either in a makefile or before the header `boost/test/unit_test.hpp` inclusion. An external test runner utility is required to link with dynamic library. -The {utf} comes with an example external test runner `console_test_runner`: +The _Unit Test Framework_ comes with an example external test runner `console_test_runner`: Given a name of the test module (implemented as a shared library), and a name of the initialization function defined therein, the program can run all the tests from the module's test tree. diff --git a/doc/modules/ROOT/pages/adv_scenarios/index.adoc b/doc/modules/ROOT/pages/adv_scenarios/index.adoc index 89d09105b4..f0f1237ef2 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/index.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/index.adoc @@ -3,25 +3,25 @@ If you are reading this chapter, this means that the wide range of tools and interfaces covered in the previous sections are not sufficient for the testing scenario -you have in mind. You are here to bend the {utf} to your will and ... we are not going to +you have in mind. You are here to bend the _Unit Test Framework_ to your will and ... we are not going to stop you. Instead we'll try to guide you so that some dark corners do not look scary. -In most cases the {utf} is going to be supplied for you either as part of your system libraries +In most cases the _Unit Test Framework_ is going to be supplied for you either as part of your system libraries or set of libraries used by your companies. Yet if you are facing the necessity to build your -own static or dynamic library of the {utf} or need to customize the build for any reason, section -xref:adv_scenarios/build_utf.adoc[Building the {utf}] covers all the necessary steps. +own static or dynamic library of the _Unit Test Framework_ or need to customize the build for any reason, section +xref:adv_scenarios/build_utf.adoc[Building the _Unit Test Framework_] covers all the necessary steps. -To streamline the experience of setting up your test module, the {utf} provides some default +To streamline the experience of setting up your test module, the _Unit Test Framework_ provides some default initialization logic for them. Usually the default test module initialization will work just fine, but if you want to implement some custom initialization or change how default initialization behaves you need to first look in *Test module initialization* section. Here you'll learn -about various options the {utf} provides for you to customize this behavior. +about various options the _Unit Test Framework_ provides for you to customize this behavior. The part of the framework which loads, initializes and executed your test module is called the *Test Runner*. Each usage variant comes with default test runner. If, instead, you prefer to implement your own entry point into the test module (for example if you need to implement the -`main` function yourself and not use the one provided by the {utf}, you need to learn about -{utf} interfaces involved in test runners operations. These are covered in the *Test runners* +`main` function yourself and not use the one provided by the _Unit Test Framework_, you need to learn about +_Unit Test Framework_ interfaces involved in test runners operations. These are covered in the *Test runners* section. Let me reiterate that you only need to this section if regular regular options for customization of initialization logic like xref:tests_organization/fixtures.adoc[fixtures] or xref:tests_organization/decorators.adoc[decorators] diff --git a/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc b/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc index 49fc604b82..a4c31263a2 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/obsolete_init_func.adoc @@ -1,7 +1,7 @@ = The obsolete initialization function :page-aliases: boost_test/adv_scenarios/obsolete_init_func.adoc -For backwards compatibility, the {utf} also allows the customization of an initialization function of a different type. +For backwards compatibility, the _Unit Test Framework_ also allows the customization of an initialization function of a different type. This is called the _obsolete initialization function_. Its signature is: [source,cpp] @@ -9,12 +9,12 @@ This is called the _obsolete initialization function_. Its signature is: boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]); ---- -The original design of the {utf} required of the programmer to implement it. It was intended to initialize and return -the {master_test_suite}. No xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_AUTO_TEST_CASE[automatic test case registration] was available at that +The original design of the _Unit Test Framework_ required of the programmer to implement it. It was intended to initialize and return +the xref:{master_test_suite}[master test suite]. No xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_AUTO_TEST_CASE[automatic test case registration] was available at that time. The null-pointer value was considered an initialization error. In the header-only usage variant, you fall back to the obsolete initialization function signature by omitting the -definition of macro {boost_test_alternative_init_api} in test module code. +definition of macro xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] in test module code. // tag reference: doc/modules/ROOT/examples/custom_obsolete_init.run-fail.cpp :bt-name: custom_obsolete_init @@ -22,8 +22,8 @@ definition of macro {boost_test_alternative_init_api} in test module code. :bt-descr: using obsolete initialization function include::partial$bt_example.adoc[] -In the static-library usage variant, you need to omit the definition of macro {boost_test_alternative_init_api} in test -module and compile the {utf} static library without the compilation flag {boost_test_alternative_init_api} (this is +In the static-library usage variant, you need to omit the definition of macro xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] in test +module and compile the _Unit Test Framework_ static library without the compilation flag xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] (this is the default). In the shared-library usage variant, it is not possible to use the obsolete initialization function. @@ -35,7 +35,7 @@ cpp:boost::unit_test::test_suite::add[`test_suite::add`] as illustrated xref:tests_organization/test_organization_nullary.adoc#ref_BOOST_TEST_CASE[here]. The current framework does no longer treat the null-pointer value as failure. . You signal the failure by throwing cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] exception. -. You access the command-line arguments through the interface of the {master_test_suite}, +. You access the command-line arguments through the interface of the xref:{master_test_suite}[master test suite], and ignore the function's arguments `argc` and `argv`. [CAUTION] diff --git a/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc index 21875b738c..5c709a8c9b 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc @@ -3,14 +3,14 @@ [CAUTION] ==== -Macro {boost_test_dyn_link} (which instructs the compiler/linker to dynamically link against a shared +Macro xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] (which instructs the compiler/linker to dynamically link against a shared library variant) may be implicitly defined when macro `BOOST_ALL_DYN_LINK` is defined. ==== [CAUTION] ==== In order to be able to run a test built with the dynamic variant, the operating system should be able - to find the dynamic library of the {utf}. This means, for example on Linux and MacOSX respectively, setting the environment + to find the dynamic library of the _Unit Test Framework_. This means, for example on Linux and MacOSX respectively, setting the environment variable `LD_LIBRARY_PATH` or `DYLD_LIBRARY_PATH` properly prior to the execution of the test module. ==== @@ -20,7 +20,7 @@ In order to be able to run a test built with the dynamic variant, the operating In this variant, in one of the source files, you now have to define your custom entry point, and invoke the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with the default xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` as argument. -You need to define {boost_test_no_main} (its value is irrelevant) in the main file: +You need to define xref:{boost_test_no_main}[`BOOST_TEST_NO_MAIN`] (its value is irrelevant) in the main file: [%header%autowidth,cols="2*"] |=== @@ -66,7 +66,7 @@ xref:adv_scenarios/shared_lib_customizations.adoc#entry_point[customizing the en to customize both. In one of the source files, you now have to define your custom entry point and xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test`; next invoke the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually -with `init_unit_test` as argument. You _do not_ define {boost_test_module} in the main file: +with `init_unit_test` as argument. You _do not_ define xref:{boost_test_module}[`BOOST_TEST_MODULE`] in the main file: [%header%autowidth,cols="2*"] |=== @@ -114,7 +114,7 @@ a| For reporting errors that may occur during the initialization, -* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* either you return `false` (valid only for the new API only, see xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`]) * or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] An error reported in this function aborts the execution of the test module. diff --git a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc index d8f48d1887..2020dd33bc 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc @@ -4,15 +4,15 @@ [#multiple_translation_units] == Header-only with multiple translation units -It is possible to use the header-only variant of the {utf} even if the test module has multiple translation +It is possible to use the header-only variant of the _Unit Test Framework_ even if the test module has multiple translation units: -* one translation unit should define {boost_test_module} and include `` +* one translation unit should define xref:{boost_test_module}[`BOOST_TEST_MODULE`] and include `` * all the other translation units should include `` An example might be the following: -* Translation unit 1, defines {boost_test_module} +* Translation unit 1, defines xref:{boost_test_module}[`BOOST_TEST_MODULE`] `+#define BOOST_TEST_MODULE header-only multiunit test #include + @@ -33,9 +33,9 @@ BOOST_CHECK( i*i == 1 ); [#entry_point] == Customizing the module's entry point -In this usage variant and in the translation unit containing the definition of {boost_test_module}, -you need to define the macros {boost_test_no_main} and -{boost_test_alternative_init_api} (their values are irrelevant) prior to including any of the framework's headers. +In this usage variant and in the translation unit containing the definition of xref:{boost_test_module}[`BOOST_TEST_MODULE`], +you need to define the macros xref:{boost_test_no_main}[`BOOST_TEST_NO_MAIN`] and +xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] (their values are irrelevant) prior to including any of the framework's headers. Next, you have to define your custom entry point, and invoke the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with the default xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` as argument. // tag reference: doc/modules/ROOT/examples/custom_main.run-fail.cpp @@ -49,17 +49,17 @@ needs to obtain also the information about environment variables. [NOTE] ==== -The above example also illustrates that it makes sense to define both {boost_test_module} and -{boost_test_no_main}. This way, no `main` is generated by the framework, but the name specified by {boost_test_module} +The above example also illustrates that it makes sense to define both xref:{boost_test_module}[`BOOST_TEST_MODULE`] and +xref:{boost_test_no_main}[`BOOST_TEST_NO_MAIN`]. This way, no `main` is generated by the framework, but the name specified by xref:{boost_test_module}[`BOOST_TEST_MODULE`] is assigned to the xref:tests_organization/master_test_suite.adoc[Master test suite]. ==== -NOTE: The reason for defining {boost_test_alternative_init_api} is described xref:adv_scenarios/obsolete_init_func.adoc[here]. +NOTE: The reason for defining xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] is described xref:adv_scenarios/obsolete_init_func.adoc[here]. [#init_func] == Customizing the module's initialization function -In this usage variant, you do not define macro {boost_test_module} and instead provide the definition of function +In this usage variant, you do not define macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] and instead provide the definition of function `init_unit_test`. This is going to be the custom initialization function. The default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] will use it to initialize the test module. // tag reference: doc/modules/ROOT/examples/custom_init.run-fail.cpp @@ -76,9 +76,9 @@ Suite") is used. For reporting errors that may occur during the initialization, -* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* either you return `false` (valid only for the new API only, see xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`]) * or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] An error reported in this function aborts the execution of the test module. -NOTE: The reason for defining {boost_test_alternative_init_api} is described xref:adv_scenarios/obsolete_init_func.adoc[here]. +NOTE: The reason for defining xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] is described xref:adv_scenarios/obsolete_init_func.adoc[here]. diff --git a/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc index 7ab4ea68e3..8689d995ec 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc @@ -5,8 +5,8 @@ == Customizing the module's entry point In the static library variant, customizing the main entry point is quite troublesome, because the definition -of function `main` is already compiled into the static library. This requires you to rebuild the {utf} -static library with the defined symbol {boost_test_no_main}. In the Boost root directory you need to +of function `main` is already compiled into the static library. This requires you to rebuild the _Unit Test Framework_ +static library with the defined symbol xref:{boost_test_no_main}[`BOOST_TEST_NO_MAIN`]. In the Boost root directory you need to invoke command [source,cpp] @@ -24,8 +24,8 @@ xref:adv_scenarios/shared_lib_customizations.adoc[shared library usage variant] In one of the source files, you now have to define your custom entry point, and invoke the default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] `unit_test_main` manually with the default xref:adv_scenarios/test_module_init_overview.adoc[initialization function] `init_unit_test` -as the first argument. There is no need to define {boost_test_no_main} in your source code, but you need -to define {boost_test_alternative_init_api} in the main file: +as the first argument. There is no need to define xref:{boost_test_no_main}[`BOOST_TEST_NO_MAIN`] in your source code, but you need +to define xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] in the main file: [%header%autowidth,cols="2*"] |=== @@ -63,7 +63,7 @@ a| [NOTE] ==== -The reason for defining {boost_test_alternative_init_api} is described +The reason for defining xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] is described xref:adv_scenarios/obsolete_init_func.adoc[here]. ==== @@ -72,7 +72,7 @@ The reason for defining {boost_test_alternative_init_api} is described In the static library variant, customizing the main entry point is quite troublesome, because the default test runner compiled into the static library uses the obsolete initialization function signature. This requires you -to rebuild the {utf} static library with the defined symbol {boost_test_alternative_init_api}. In the Boost +to rebuild the _Unit Test Framework_ static library with the defined symbol xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`]. In the Boost root directory you need to invoke command [source,cpp] @@ -96,8 +96,8 @@ bool init_unit_test(); ---- The default xref:adv_scenarios/test_module_runner_overview.adoc[test runner] will use it to initialize -the test module. In your source code, you no longer define macro {boost_test_module}; instead, you need to -define {boost_test_alternative_init_api} in the main file: +the test module. In your source code, you no longer define macro xref:{boost_test_module}[`BOOST_TEST_MODULE`]; instead, you need to +define xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] in the main file: [%header%autowidth,cols="2*"] |=== @@ -133,13 +133,13 @@ a| For reporting errors that may occur during the initialization, -* either you return `false` (valid only for the new API only, see {boost_test_alternative_init_api}) +* either you return `false` (valid only for the new API only, see xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`]) * or you raise an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] An error reported in this function aborts the execution of the test module. [NOTE] ==== -The reason for defining {boost_test_alternative_init_api} is described +The reason for defining xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`] is described xref:adv_scenarios/obsolete_init_func.adoc[here]. ==== diff --git a/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc index b67cb79677..4eba7298f6 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/test_module_init_overview.adoc @@ -3,30 +3,30 @@ In order for a unit test module to successfully link and execute, it has to have access to the _test module's initialization function_. the module's initialization function is called only once during the execution of the program, just before the -xref:adv_scenarios/test_module_runner_overview.adoc[_test module runner_] is run. By default, the {utf} provides +xref:adv_scenarios/test_module_runner_overview.adoc[_test module runner_] is run. By default, the _Unit Test Framework_ provides a default definition of initialization function. The only thing you have to do is to instruct the framework in which translation -unit (`cpp` file) it needs to provide the definition. You do it by defining macro {boost_test_module} in the designated file. +unit (`cpp` file) it needs to provide the definition. You do it by defining macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] in the designated file. The default implementation assigns the name to the xref:section_glossary.adoc#ref_test_module[test module] as well as the xref:tests_organization/master_test_suite.adoc[master test suite]. The name to be assigned is specified by -the value of the macro {boost_test_module}. +the value of the macro xref:{boost_test_module}[`BOOST_TEST_MODULE`]. [IMPORTANT] ==== -For a test module consisting of multiple source files you have to define {boost_test_module} in a single test file only. +For a test module consisting of multiple source files you have to define xref:{boost_test_module}[`BOOST_TEST_MODULE`] in a single test file only. Otherwise you end up with multiple instances of the initialization function. ==== -There is practically no need to ever alter the default behavior of the test module's initialization function. The {utf} provides +There is practically no need to ever alter the default behavior of the test module's initialization function. The _Unit Test Framework_ provides superior tools for performing customization tasks: * for automatic registration of test cases and test suites in the test tree, see section xref:tests_organization/index.adoc[Tests organization]; -* in order to assign the custom name to the master test suite define macro {boost_test_module} to desired value; -* in order to access the command-line parameters (except the ones consumed by the {utf}), use the interface of the +* in order to assign the custom name to the master test suite define macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] to desired value; +* in order to access the command-line parameters (except the ones consumed by the _Unit Test Framework_), use the interface of the xref:tests_organization/master_test_suite.adoc[master test suite]; * in order to perform a global initialization of the state required by the test cases, xref:tests_organization/fixtures.adoc#global[global fixtures] offer a superior alternative: you can specify global set-up and tear-down in one place, allow access to the global data from every test case, and guarantee that clean-up and tear-down is repeated each time the tests are re-run during the execution of the program; -* if the need for custom module initialization is only driven by legacy code (written against old versions of the {utf}), it is recommended +* if the need for custom module initialization is only driven by legacy code (written against old versions of the _Unit Test Framework_), it is recommended to update your program's code. The default initialization function provided by the framework is defined with the following signature in the global namespace: diff --git a/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc index be7937f764..ec1ceff505 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc @@ -10,7 +10,7 @@ tests are executed and necessary reports generated. It performs the following op * produce the test results report; * generate the appropriate return code. -The {utf} comes with the default test runner. There is no need to call it explicitly. The default generated test module's +The _Unit Test Framework_ comes with the default test runner. There is no need to call it explicitly. The default generated test module's xref:adv_scenarios/entry_point_overview.adoc[entry point] invokes the default test runner. The default test runner is declared with the following signature: @@ -40,7 +40,7 @@ a| |`boost::exit_test_failure` a| * Non-fatal errors detected and no uncaught exceptions were thrown during testing, or -* the initialization of the {utf} failed. +* the initialization of the _Unit Test Framework_ failed. |`boost::exit_exception_failure` a| diff --git a/doc/modules/ROOT/pages/change_log.adoc b/doc/modules/ROOT/pages/change_log.adoc index 38ec9ca430..e2937459e0 100644 --- a/doc/modules/ROOT/pages/change_log.adoc +++ b/doc/modules/ROOT/pages/change_log.adoc @@ -150,8 +150,8 @@ and it is not possible to interrupt a test even in case of time out. * Time-out now applies to test-suites as well: a test-suite is marked as timed-out if it exceeds the allocated time. The test units that were not executed at the time-point of the time-out are skipped. * It is now possible to pass several values for the same context via the tool -{boost_test_context}. -* A new macro {boost_test_info_scope} let define a context for the current scope in a sticky way. +xref:{boost_test_context}[`BOOST_TEST_CONTEXT`]. +* A new macro xref:{boost_test_info_scope}[`BOOST_TEST_INFO_SCOPE`] let define a context for the current scope in a sticky way. * It is now possible to use xref:testing_tools/floating_point.adoc[floating point] comparison without being required to cast both operands to floating point types. Now Boost.Test uses floating point comparisons for expressions such as @@ -233,7 +233,7 @@ to accept an additional boolean argument. If you have a custom logger, you will * Official support of header-only variant of Boost.Test with multiple translation units. This feature was available but needed to be properly documented (xref:adv_scenarios/single_header_customizations.adoc#multiple_translation_units[here] and xref:usage_variants.adoc[here]). -* It is now possible to manually add a test case by specifying its name, with {boost_test_case_name} +* It is now possible to manually add a test case by specifying its name, with xref:{boost_test_case_name}[`BOOST_TEST_CASE_NAME`] * Better logging of messages in `boost::exception` === Bugfixes and feature requests @@ -330,18 +330,18 @@ registered tests. Make sure you have no duplicate names. === Breaking changes -* {boost_global_fixture} is flagged as deprecated and will be removed in a later version -* Using test assertions and macros is not allowed when used inside {boost_global_fixture}. Please use {boost_test_global_fixture} +* xref:{boost_global_fixture}[`BOOST_GLOBAL_FIXTURE`] is flagged as deprecated and will be removed in a later version +* Using test assertions and macros is not allowed when used inside xref:{boost_global_fixture}[`BOOST_GLOBAL_FIXTURE`]. Please use xref:{boost_test_global_fixture}[`BOOST_TEST_GLOBAL_FIXTURE`] instead (see below). * the interface for loggers has slightly changed to take into account the current log level. This is for addressing {trac-url}/12631[#12631]. === New features * VS2017 / C++17 compatibility (thanks to Daniela Engert) -* Deprecating {boost_global_fixture} in favor of {boost_test_global_fixture} and {boost_test_global_configuration}. This +* Deprecating xref:{boost_global_fixture}[`BOOST_GLOBAL_FIXTURE`] in favor of xref:{boost_test_global_fixture}[`BOOST_TEST_GLOBAL_FIXTURE`] and xref:{boost_test_global_configuration}[`BOOST_TEST_GLOBAL_CONFIGURATION`]. This helps separating the logic of the fixtures associated to the master test suite, from the one used for setting up the logging and reporting facility, and results in a general cleaner design. -* It is possible to use now the {boost_test} check to comparing a collection with respect to regular arrays. See +* It is possible to use now the xref:{boost_test}[`BOOST_TEST`] check to comparing a collection with respect to regular arrays. See xref:testing_tools/collections.adoc#ref_boost_test_coll_c_arrays[this section] for more details. === Bugfixes and feature requests @@ -390,7 +390,7 @@ otherwise not possible to execute the tests reported by `--list_content`. See {t === New features -* Now xref:testing_tools/collections.adoc#boost_test_coll_perelement[`per_element`] and xref:testing_tools/collections.adoc#boost_test_coll_default_lex[`lexicographic`] modifiers of {boost_test} +* Now xref:testing_tools/collections.adoc#boost_test_coll_perelement[`per_element`] and xref:testing_tools/collections.adoc#boost_test_coll_default_lex[`lexicographic`] modifiers of xref:{boost_test}[`BOOST_TEST`] can also be applied to string comparison. See xref:testing_tools/strings.adoc[string comparison] for more details. @@ -419,9 +419,9 @@ for more details, xref:utf_reference/rt_param_reference.adoc#run_test[`--run_test`] generates tokens as if `--run_test` has been repeated, which enables the set up of several test filters through the associated environment variable `BOOST_TEST_RUN_FILTERS` -* the {utf} learned to log the messages in the xUnit/JUNIT log format. +* the _Unit Test Framework_ learned to log the messages in the xUnit/JUNIT log format. See xref:test_output/log_formats.adoc#log_junit_format[here] for more details. -* the {utf} learned to have several loggers at the same time, each of which with their own log level and log sink. +* the _Unit Test Framework_ learned to have several loggers at the same time, each of which with their own log level and log sink. See the associated command line switch xref:utf_reference/rt_param_reference.adoc#logger[`--logger`] and corresponding environment variable `BOOST_TEST_LOGGER` for more details. * loggers are now able to indicate their default output stream and log level. @@ -507,7 +507,7 @@ should be rewritten to === New major features -* {boost_test} generic assertion +* xref:{boost_test}[`BOOST_TEST`] generic assertion * xref:tests_organization/test_case_generation.adoc[data driven test cases]: supersedes the parametric test case (unary test cases) * test units xref:tests_organization/decorators.adoc[attributes], that allow finer control over test units property and behavior * logical grouping of the test units using xref:tests_organization/tests_grouping.adoc[labels] diff --git a/doc/modules/ROOT/pages/intro/design_rationale.adoc b/doc/modules/ROOT/pages/intro/design_rationale.adoc index 9a858dc6a6..d2eefb5fbc 100644 --- a/doc/modules/ROOT/pages/intro/design_rationale.adoc +++ b/doc/modules/ROOT/pages/intro/design_rationale.adoc @@ -17,9 +17,9 @@ test suites. to compile a test that takes a second to run. * For long and complex tests users want to be able to see the testing progress. * Simplest tests shouldn't require an external library. -* For long term usage users of the {utf} should be able to build it as a standalone library. +* For long term usage users of the _Unit Test Framework_ should be able to build it as a standalone library. -The {utf} satisfies the requirements above, and provides versatile facilities to: +The _Unit Test Framework_ satisfies the requirements above, and provides versatile facilities to: * Easily specify all the expectations in the code being tested. * Organize these expectations into xref:section_glossary.adoc#test_case[test cases] and xref:section_glossary.adoc#test_suite[test suites]. diff --git a/doc/modules/ROOT/pages/intro/how_to_read.adoc b/doc/modules/ROOT/pages/intro/how_to_read.adoc index 235beacce8..8973a5326e 100644 --- a/doc/modules/ROOT/pages/intro/how_to_read.adoc +++ b/doc/modules/ROOT/pages/intro/how_to_read.adoc @@ -1,14 +1,14 @@ = How to read this documentation :page-aliases: boost_test/intro/how_to_read.adoc -This documentation is structured by what *you*, as a user, need to know to successfully use the {utf} and the order of decisions +This documentation is structured by what *you*, as a user, need to know to successfully use the _Unit Test Framework_ and the order of decisions you have to make and order of complexity of the problems you might encounter. If you ever find yourself facing with some unclear term feel free to jump directly to the xref:section_glossary.adoc[glossary] section, where short definitions for all used terms were collected. -Typically, when writing a test module using the {utf} you have to go through the following steps: +Typically, when writing a test module using the _Unit Test Framework_ you have to go through the following steps: -* You decide how you want to incorporate the {utf}: `+#include+` it as a header-only library, or link with it as a static library, +* You decide how you want to incorporate the _Unit Test Framework_: `+#include+` it as a header-only library, or link with it as a static library, or use it as a shared (or dynamically loaded) library. For details on this topic see section xref:usage_variants.adoc[Usage variants]. * You add a xref:section_glossary.adoc#test_case[test case] into a xref:section_glossary.adoc#ref_test_tree[test tree]. For details, see section xref:tests_organization/test_cases.adoc[Test cases]. diff --git a/doc/modules/ROOT/pages/runtime_config/index.adoc b/doc/modules/ROOT/pages/runtime_config/index.adoc index e5021b2ce5..bab0eb531b 100644 --- a/doc/modules/ROOT/pages/runtime_config/index.adoc +++ b/doc/modules/ROOT/pages/runtime_config/index.adoc @@ -3,16 +3,16 @@ == Boost.Test runtime parameters -The {utf} supports multiple parameters that affect test module execution. To set the parameter's value you can +The _Unit Test Framework_ supports multiple parameters that affect test module execution. To set the parameter's value you can either use a runtime configuration subsystem interface from within the test module initialization function or you can specify the value at runtime during test module invocation. -The {utf} provides two ways to set a parameter at runtime: by specifying a command line argument and by setting an +The _Unit Test Framework_ provides two ways to set a parameter at runtime: by specifying a command line argument and by setting an environment variable. The command line argument always overrides the corresponding environment variable. -During test module initialization the {utf} parses the command line and excludes all parameters that belong to it and +During test module initialization the _Unit Test Framework_ parses the command line and excludes all parameters that belong to it and their values from the argument list. The rest of command line is forwarded to the test module initialization function -supplied by you. The command line argument format expected by the {utf} is: +supplied by you. The command line argument format expected by the _Unit Test Framework_ is: .... --= @@ -24,20 +24,20 @@ There should not be any spaces between '=' and either command line argument name The corresponding environment variable name is also case sensitive and is required to exactly match the name in the parameter specification. -All information about the currently supported parameters of the {utf} is summarized in +All information about the currently supported parameters of the _Unit Test Framework_ is summarized in the xref:runtime_config/summary.adoc[summary section]. == Test filtering -The {utf} provides an extensive filtering facility making it easy to run a specific test or a subset of tests. The +The _Unit Test Framework_ provides an extensive filtering facility making it easy to run a specific test or a subset of tests. The xref:runtime_config/test_unit_filtering.adoc[section on filtering] gives all the details for the command line interface. Additionally, xref:tests_organization/test_suite.adoc[test-suites] and xref:tests_organization/tests_grouping.adoc[labels] may be used in order to construct subset of tests in an efficient and easy way, while decorators -(eg. {decorator_disabled}, {decorator_precondition}) can be used to set the default run status of a test case. +(eg. xref:{decorator_disabled}[`disabled`], xref:{decorator_precondition}[`precondition`]) can be used to set the default run status of a test case. == Custom runtime parameters It is possible to extend further the command line interface by providing a custom command line interpretation logic. There are several -ways on how to integrate this logic in the {utf} and this is explained in details in the section +ways on how to integrate this logic in the _Unit Test Framework_ and this is explained in details in the section xref:runtime_config/runtime_custom.adoc[Custom runtime parameters]. diff --git a/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc b/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc index 0973f3f439..f3c92952bc 100644 --- a/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc +++ b/doc/modules/ROOT/pages/runtime_config/runtime_custom.adoc @@ -10,7 +10,7 @@ arguments is the following: ---- This means that everything that is passed after "`--`" is considered as a custom parameter and will not be intercepted nor interpreted -by the {utf}. This avoids any troubleshooting between the {utf} parameters and the custom ones. +by the _Unit Test Framework_. This avoids any troubleshooting between the _Unit Test Framework_ parameters and the custom ones. There are several use cases for accessing the arguments passed on the command line: @@ -22,7 +22,7 @@ test module with different parameters (different graphic cards...) in a batched for instance a set of parameters that define test cases. In the first scenario, xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_test_case[test cases] or fixtures, including -xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_global_fixture[global fixtures], may be used. Since those are part of the test tree, they can benefit from the {utf} rich set of assertions +xref:runtime_config/runtime_custom.adoc#ref_consuming_cmd_global_fixture[global fixtures], may be used. Since those are part of the test tree, they can benefit from the _Unit Test Framework_ rich set of assertions and controlled execution environment. In the second scenario, the command line argument interact directly with the content of the test tree: by passing specific @@ -78,9 +78,9 @@ The module requires `3` arguments on the command line: * `framework::master_test_suite().argv[1]` should be equal to `--device-name` * `framework::master_test_suite().argv[2]` should be the name of the device to instantiate -As it can be seen in the shell outputs, any command line argument consumed by the {utf} is removed from -`argc` / `argv`. Since global fixtures are running in the {utf} controlled environment, any fatal error reported -by the fixture (through the {boost_test_require} assertion) aborts the test execution. Non fatal errors +As it can be seen in the shell outputs, any command line argument consumed by the _Unit Test Framework_ is removed from +`argc` / `argv`. Since global fixtures are running in the _Unit Test Framework_ controlled environment, any fatal error reported +by the fixture (through the xref:{boost_test_require}[`BOOST_TEST_REQUIRE`] assertion) aborts the test execution. Non fatal errors on the other hand do not abort the test-module and are reported as assertion failure, and would not prevent the execution of the test case `check_device_has_meaningful_name`. @@ -96,11 +96,11 @@ It is possible to have several global fixtures in a test module, spread over sev The initialization function are described in details in this xref:adv_scenarios/test_module_init_overview.adoc[section]. The initialization function is called before any other test or fixture, and before entering the master test suite. The initialization function is not considered as a test-case, although it is called under the controlled execution -environment of the {utf}. This means that: +environment of the _Unit Test Framework_. This means that: * the errors will be properly handled, * loggers are not fully operational, -* it is not possible to use the {utf} assertion macros like {boost_test} as it is not a test-case. +* it is not possible to use the _Unit Test Framework_ assertion macros like xref:{boost_test}[`BOOST_TEST`] as it is not a test-case. The following example shows how to use the command line arguments parsing described above to create/add new test cases to the test tree. It also shows very limited support to messages (does not work for all loggers), and error handling. @@ -114,7 +114,7 @@ include::partial$bt_example.adoc[] As seen in this example, the error handling is quite different than a regular test-case: * For the _alternative_ initialization API (see -{boost_test_alternative_init_api}), the easiest way to indicate an error would be to return `false` +xref:{boost_test_alternative_init_api}[`BOOST_TEST_ALTERNATIVE_INIT_API`]), the easiest way to indicate an error would be to return `false` in case of failure. * For the _obsolete_ and _alternative_, raising an exception such as `std::runtime_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] as above works as well. @@ -145,7 +145,7 @@ include::partial$bt_example.adoc[] let the dataset generator access the `argc` and `argv` of the master test suite. * The generation of the test-cases out of this dataset happens before the global fixture are reached (and before any test cases), and after the initialization function. -* The generator of the dataset is *not* considered being a test case and the {utf} assertions are not accessible. -However, the {utf} will catch the exceptions raised during the generation of the test-cases by the dataset. +* The generator of the dataset is *not* considered being a test case and the _Unit Test Framework_ assertions are not accessible. +However, the _Unit Test Framework_ will catch the exceptions raised during the generation of the test-cases by the dataset. To report an error, a `std::logic_error` or cpp:boost::unit_test::framework::setup_error[boost::unit_test::framework::setup_error] can be raised -and will be reported by the {utf}. +and will be reported by the _Unit Test Framework_. diff --git a/doc/modules/ROOT/pages/runtime_config/summary.adoc b/doc/modules/ROOT/pages/runtime_config/summary.adoc index 6c7ad9845b..6638319306 100644 --- a/doc/modules/ROOT/pages/runtime_config/summary.adoc +++ b/doc/modules/ROOT/pages/runtime_config/summary.adoc @@ -25,7 +25,7 @@ |Instructs the framework to detect memory leaks (on supported platforms). |xref:utf_reference/rt_param_reference.adoc#help[`help`] -|Provides help on the {utf} parameters. +|Provides help on the _Unit Test Framework_ parameters. |xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`] |Lists the tests units, their organization in the test tree, their enabled/disabled state... @@ -66,7 +66,7 @@ |xref:utf_reference/rt_param_reference.adoc#result_code[`result_code`] |Instructs the framework to return or ignore a result code indicating an error in the tests. -|{param_run_test} +|xref:{param_run_test}[`run_test`] |Allows to filter which test units to execute at runtime. |xref:utf_reference/rt_param_reference.adoc#save_pattern[`save_pattern`] diff --git a/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc b/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc index 1471185e69..9c46ac23cf 100644 --- a/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc +++ b/doc/modules/ROOT/pages/runtime_config/test_unit_filtering.adoc @@ -1,7 +1,7 @@ = Test unit filtering :page-aliases: boost_test/runtime_config/test_unit_filtering.adoc -The {utf} offers a number of ways to run only a subset of all test cases registered in the test tree. +The _Unit Test Framework_ offers a number of ways to run only a subset of all test cases registered in the test tree. [#ref_default_run_status] == Default run status @@ -16,7 +16,7 @@ Initially, the master test suite has default run status set to _true_. All other This implies that, unless any additional configuration is applied, all tests are designated to be run. You can set a different default run status in any test unit by using xref:tests_organization/decorators.adoc[decorators]: -{decorator_disabled}, {decorator_enabled} and {decorator_enable_if}. The default run status is set once, upon testing program +xref:{decorator_disabled}[`disabled`], xref:{decorator_enabled}[`enabled`] and xref:{decorator_enable_if}[`enable_if`]. The default run status is set once, upon testing program initialization, and cannot be changed. The disabled tests are not executed by default, but are still present in the test tree, and are listed along with other tests when you use command-line argument xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. @@ -35,14 +35,14 @@ before executing the test unit. If the condition is met, the test unit is execut It is possible to add two dependencies: . Upon another test unit. In this case the decorated test case is skipped if the test unit specified in the dependency is either -failed or skipped or disabled. This can be declared with decorator {decorator_depends_on}. -. Upon an arbitrary predicate. This can be declared with decorator {decorator_precondition}. +failed or skipped or disabled. This can be declared with decorator xref:{decorator_depends_on}[`depends_on`]. +. Upon an arbitrary predicate. This can be declared with decorator xref:{decorator_precondition}[`precondition`]. [#ref_command_line_control] == Command-line control Static configuration of the test-case filtering is used by default, unless command-line filtering is applied. With command-line argument -{param_run_test} it is possible to alter the static pre-set in a number of ways: +xref:{param_run_test}[`run_test`] it is possible to alter the static pre-set in a number of ways: . Ignore the static configuration and manually specify test cases to be run. . Augment the statically defined set by enabling the disabled test cases. @@ -56,7 +56,7 @@ is completely ignored and the tests to be run are specified manually from scratc units are registered in the test tree the user needs to use command-line argument xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. Next, in order to specify a set of test cases, the user needs to use command-line argument -{param_run_test} with absolute value: +xref:{param_run_test}[`run_test`] with absolute value: [source,cpp] ---- @@ -106,7 +106,7 @@ The following table illustrates how different values of `` control whi a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=test_1 +xref:{param_run_test}[`run_test`]=test_1 .... a| .... @@ -117,7 +117,7 @@ test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/suite_1/test_1 +xref:{param_run_test}[`run_test`]=suite_1/suite_1/test_1 .... a| .... @@ -128,8 +128,8 @@ suite_1/suite_1/test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/suite_2 -{param_run_test}=suite_1/suite_2/* +xref:{param_run_test}[`run_test`]=suite_1/suite_2 +xref:{param_run_test}[`run_test`]=suite_1/suite_2/* .... a| .... @@ -141,7 +141,7 @@ suite_1/suite_2/test_2 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/test_1,suite_2 +xref:{param_run_test}[`run_test`]=suite_1/test_1,suite_2 .... a| .... @@ -154,7 +154,7 @@ suite_1/test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/test_1:test_1 +xref:{param_run_test}[`run_test`]=suite_1/test_1:test_1 .... a| .... @@ -166,7 +166,7 @@ test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=@L1 +xref:{param_run_test}[`run_test`]=@L1 .... a| .... @@ -179,7 +179,7 @@ suite_1/test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=* +xref:{param_run_test}[`run_test`]=* .... a| .... @@ -198,7 +198,7 @@ suite_1/test_2A a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/test* +xref:{param_run_test}[`run_test`]=suite_1/test* .... a| .... @@ -211,7 +211,7 @@ suite_1/test_2A a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/*_1 +xref:{param_run_test}[`run_test`]=suite_1/*_1 .... a| .... @@ -224,7 +224,7 @@ suite_1/test_1 a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=suite_1/\*_2\* +xref:{param_run_test}[`run_test`]=suite_1/\*_2\* .... a| .... @@ -238,7 +238,7 @@ suite_1/test_2A a| [subs="+macros,+attributes,+quotes"] .... -{param_run_test}=\*/\*/test_2 +xref:{param_run_test}[`run_test`]=\*/\*/test_2 .... a| .... @@ -251,9 +251,9 @@ suite_1/suite_2/test_2 For the syntax productions describing the structure of `` value see xref:utf_reference/rt_param_reference.adoc#run_test[here]. While using manual absolute test case specification ignores the default run status, it does not ignore the dynamic test dependencies. -If test unit `B` depends on test unit `A` and test `B` is specified to be run by {param_run_test}, `A` is also run, even +If test unit `B` depends on test unit `A` and test `B` is specified to be run by xref:{param_run_test}[`run_test`], `A` is also run, even if it is not specified, and its failure may cause the execution of `B` to be skipped. Similarly, the failed check of -the {decorator_precondition} may cause the test selected test to be skipped. +the xref:{decorator_precondition}[`precondition`] may cause the test selected test to be skipped. // tag reference: doc/modules/ROOT/examples/decorator_21.run-fail.cpp :bt-name: decorator_21 @@ -267,7 +267,7 @@ include::partial$bt_example.adoc[] Term 'relative' in this context means that the configuration is based on either the default run status of the test units or by the command-line override specified by the _absolute specification_; and atop of this, we additionally either enable some disabled test units or disable some enabled tests units. The relative specification is controlled by command-line -argument {param_run_test}, with the value using similar syntax as in the absolute specification, but preceded with +argument xref:{param_run_test}[`run_test`], with the value using similar syntax as in the absolute specification, but preceded with either character `'!'` for disabling enabled test units or with character `'+'` for enabling the disabled test units. This can be summarized with the following table: @@ -280,7 +280,7 @@ This can be summarized with the following table: a| [subs="+macros,+attributes,+quotes"] .... -> test_program --{param_run_test}=! +> test_program --xref:{param_run_test}[`run_test`]=! .... |disabler |Enabled test units that match `` become disabled. @@ -288,7 +288,7 @@ a| a| [subs="+macros,+attributes,+quotes"] .... -> test_program --{param_run_test}=+ +> test_program --xref:{param_run_test}[`run_test`]=+ .... |enabler |Disabled test units that match `` as well as their upstream dependencies become enabled. @@ -316,6 +316,6 @@ the disabler takes the precedence over the enabler. [NOTE] ==== -While enabler additionally enables the upstream dependencies (introduced with decorator {decorator_depends_on}), +While enabler additionally enables the upstream dependencies (introduced with decorator xref:{decorator_depends_on}[`depends_on`]), disabler does not disable them. Therefore when you enable and then disable the same test, you do not disable its upstream dependencies. ==== diff --git a/doc/modules/ROOT/pages/section_faq.adoc b/doc/modules/ROOT/pages/section_faq.adoc index dd933f4663..4a740adc90 100644 --- a/doc/modules/ROOT/pages/section_faq.adoc +++ b/doc/modules/ROOT/pages/section_faq.adoc @@ -14,9 +14,9 @@ a ticket on the GitHub issues of the project https://github.com/boostorg/test[]. To create a test case, use the macro -{boost_auto_test_case}( test_function ); +xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`]( test_function ); -For more details see the Unit Test Framework {boost_auto_test_case} documentation. +For more details see the Unit Test Framework xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] documentation. == Is Boost.Test thread safe? @@ -47,9 +47,9 @@ will not work as expected as the assertion `BOOST_TEST` will be called from mult To create a test suite use the macro -{boost_auto_test_suite}( suite_name ); +xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`]( suite_name ); -For more details see the Unit Test Framework {boost_auto_test_suite} documentation. +For more details see the Unit Test Framework xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`] documentation. == Why did I get a linker error when compiling my test program? @@ -84,21 +84,21 @@ The reason for this error is that in your implementation you should specify seco == How can I redirect testing output? Use `unit_test_log::instance().set_log_output( std::ostream & )` -For more details see the {utf} {output_test_stream_tool} documentation. +For more details see the _Unit Test Framework_ xref:{output_test_stream_tool}[output test stream] documentation. == I want different default log trace level -Use environment variable {boost_test_log_level} to define desired log trace level. You still will be able to reset -this value from the command line. For the list of acceptable values see the {utf} -{runtime_configuration} documentation. +Use environment variable xref:{boost_test_log_level}[`BOOST_TEST_LOG_LEVEL`] to define desired log trace level. You still will be able to reset +this value from the command line. For the list of acceptable values see the _Unit Test Framework_ +xref:{runtime_configuration}[runtime configuration] documentation. == Is there DLL version of Boost.Test components available on Win32 platform? Yes. Starting with Boost 1.34.0. -== How to set up a CMake project using {utf} (extended) +== How to set up a CMake project using _Unit Test Framework_ (extended) -Suppose, you are building a test module from one translation unit `test_file.cpp`. First, let's do it using the xref:usage_variants.adoc#single_header[header-only usage variant] of the {utf}. +Suppose, you are building a test module from one translation unit `test_file.cpp`. First, let's do it using the xref:usage_variants.adoc#single_header[header-only usage variant] of the _Unit Test Framework_. Let's paste the following content in a `CMakeLists.txt` at the same location than our test file `test_file.cpp`: @@ -141,7 +141,7 @@ configure and build the project, as follow: tool that is configured on the previous command line <4> runs the tests declared in the project and prints a report -In the case you are using the xref:usage_variants.adoc#shared_lib[shared libraries] variant of {utf}, +In the case you are using the xref:usage_variants.adoc#shared_lib[shared libraries] variant of _Unit Test Framework_, some modifications should be done in your CMakeLists.txt. .... diff --git a/doc/modules/ROOT/pages/section_glossary.adoc b/doc/modules/ROOT/pages/section_glossary.adoc index ea994bb5ec..797c8c8b99 100644 --- a/doc/modules/ROOT/pages/section_glossary.adoc +++ b/doc/modules/ROOT/pages/section_glossary.adoc @@ -50,7 +50,7 @@ by a test module. There are different schools of thought on how many test assertions a test case should consist of. Two polar positions are the one advocated by TDD followers - one assertion per test case; and opposite of this - all test assertions within single test case - advocated by those only interested in the first error in a -test module. The {utf} supports both approaches. +test module. The _Unit Test Framework_ supports both approaches. [#test_case] == Test case @@ -59,7 +59,7 @@ This is an independently monitored function within a test module that consists of one or more test assertions. The term _independently monitored_ in the definition above is used to emphasize the fact, that all test cases are monitored independently. An uncaught exception or other normal test case execution termination doesn't cause the testing to cease. Instead the error is caught by the test -case execution monitor, reported by the {utf} and testing proceeds to the next test case. Later on you are going +case execution monitor, reported by the _Unit Test Framework_ and testing proceeds to the next test case. Later on you are going to see that this is on of the primary reasons to prefer multiple small test cases to a single big test function. [#test_suite] @@ -75,7 +75,7 @@ test cases into a single referable entity. There are various reasons why you may * To skip groups of test cases based on the result of another test unit in a test tree. A test suite can also contain other test suites, thus allowing a hierarchical test tree structure to be formed. -The {utf} requires the test tree to contain at least one test suite with at least one test case. The top level +The _Unit Test Framework_ requires the test tree to contain at least one test suite with at least one test case. The top level test suite - root node of the test tree - is called the master test suite. [#test_setup] @@ -84,7 +84,7 @@ test suite - root node of the test tree - is called the master test suite. This is the part of a test module that is responsible for the test preparation. It includes the following operations that take place prior to a start of the test: -* The {utf} initialization +* The _Unit Test Framework_ initialization * Test tree construction * Global test module setup code * _Per test case_ setup code, invoked for every test case it's assigned to, is also attributed to the @@ -113,5 +113,5 @@ This is the record of all events that occur during the testing. [#test_report] == Test report -This is the report produced by the {utf} after the testing is completed, that indicates which test cases/test +This is the report produced by the _Unit Test Framework_ after the testing is completed, that indicates which test cases/test suites passed and which failed. diff --git a/doc/modules/ROOT/pages/test_output/checkpoints.adoc b/doc/modules/ROOT/pages/test_output/checkpoints.adoc index 7b460e5d47..42450832bb 100644 --- a/doc/modules/ROOT/pages/test_output/checkpoints.adoc +++ b/doc/modules/ROOT/pages/test_output/checkpoints.adoc @@ -1,14 +1,14 @@ = Checkpoints for accurate failure location :page-aliases: boost_test/test_output/test_tools_support_for_logging/checkpoints.adoc -In most cases, the {utf} can't provide an exact location where system error occurs or uncaught C++ exception -is thrown from. To be able to pinpoint it as close as possible the {utf} keeps track of *checkpoints* - the +In most cases, the _Unit Test Framework_ can't provide an exact location where system error occurs or uncaught C++ exception +is thrown from. To be able to pinpoint it as close as possible the _Unit Test Framework_ keeps track of *checkpoints* - the location a test module passed through. -The {utf} keeps track of checkpoints at test case entrance, exit, fixture initialization, and at test tool invocation point. +The _Unit Test Framework_ keeps track of checkpoints at test case entrance, exit, fixture initialization, and at test tool invocation point. Any other checkpoints should be entered by you manually if you need more granularity in case a fatal -error occurs during the test. The {utf} provides two macros for this purpose: +error occurs during the test. The _Unit Test Framework_ provides two macros for this purpose: * xref:test_output/checkpoints.adoc#ref_named_checkpoint[`BOOST_TEST_CHECKPOINT`] to specify a _named_ checkpoint and * xref:test_output/checkpoints.adoc#ref_unnamed_checkpoint[`BOOST_TEST_PASSPOINT`] to specify an _unnamed_ checkpoint. @@ -20,7 +20,7 @@ xref:test_output/contexts.adoc[contexts]). [#ref_named_checkpoint] == Named checkpoints -The macro {boost_test_checkpoint} is intended to be used to inject *named* checkpoint position. The +The macro xref:{boost_test_checkpoint}[`BOOST_TEST_CHECKPOINT`] is intended to be used to inject *named* checkpoint position. The macro signature is as follows: [source,cpp] @@ -29,19 +29,19 @@ BOOST_TEST_CHECKPOINT(checkpoint_message); ---- The message formatted at the checkpoint position is saved and reported by the exception logging functions (if any -occurs). Similarly to the {boost_test_message} the message can be formatted from any standard +occurs). Similarly to the xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] the message can be formatted from any standard output stream compliant components. // tag reference: doc/modules/ROOT/examples/example22.run-fail.cpp :bt-name: example22 :bt-rule: run-fail -:bt-descr: {boost_test_checkpoint} usage +:bt-descr: xref:{boost_test_checkpoint}[`BOOST_TEST_CHECKPOINT`] usage include::partial$bt_example.adoc[] [#ref_unnamed_checkpoint] == Unnamed checkpoints -The macro {boost_test_passpoint} is intended to be used to inject an *unnamed* checkpoint position. The +The macro xref:{boost_test_passpoint}[`BOOST_TEST_PASSPOINT`] is intended to be used to inject an *unnamed* checkpoint position. The macro signature is as follows: [source,cpp] @@ -49,12 +49,12 @@ macro signature is as follows: BOOST_TEST_PASSPOINT(); ---- -Unlike the macro {boost_test_checkpoint} this macro doesn't require any message to be +Unlike the macro xref:{boost_test_checkpoint}[`BOOST_TEST_CHECKPOINT`] this macro doesn't require any message to be supplied with it. It's just a simple "been there" marker that records file name and line number code passes through. // tag reference: doc/modules/ROOT/examples/example23.run-fail.cpp :bt-name: example23 :bt-rule: run-fail -:bt-descr: {boost_test_passpoint} usage +:bt-descr: xref:{boost_test_passpoint}[`BOOST_TEST_PASSPOINT`] usage include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/test_output/contexts.adoc b/doc/modules/ROOT/pages/test_output/contexts.adoc index a52ac71e42..4b6fba7455 100644 --- a/doc/modules/ROOT/pages/test_output/contexts.adoc +++ b/doc/modules/ROOT/pages/test_output/contexts.adoc @@ -1,7 +1,7 @@ = Contexts :page-aliases: boost_test/test_output/test_tools_support_for_logging/contexts.adoc -Contexts are a facility provided by the {utf} in order to be able to trace the location of assertions better. To grasp +Contexts are a facility provided by the _Unit Test Framework_ in order to be able to trace the location of assertions better. To grasp the idea, consider the following example: [source,cpp] @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(test1) == Scope-bound context In the previous example, the information stored inside the calls to `BOOST_TEST_INFO` were all consumed by the next assertion. There are cases -where we would like this information be persistent for the current scope. {utf} provides two tools to achieve this: +where we would like this information be persistent for the current scope. _Unit Test Framework_ provides two tools to achieve this: * `BOOST_TEST_CONTEXT` defines a diagnostic message and a scope. The message is bound to every assertion in that scope, and is displayed along with every failed assertion. diff --git a/doc/modules/ROOT/pages/test_output/index.adoc b/doc/modules/ROOT/pages/test_output/index.adoc index 9df111f5f2..f839767725 100644 --- a/doc/modules/ROOT/pages/test_output/index.adoc +++ b/doc/modules/ROOT/pages/test_output/index.adoc @@ -1,8 +1,8 @@ = Controlling outputs :page-aliases: boost_test/test_output.adoc -The output produced by a test module is one of the major assets the {utf} brings to users. In comparison with any -kind of manual/assert based solution the {utf} provide following services: +The output produced by a test module is one of the major assets the _Unit Test Framework_ brings to users. In comparison with any +kind of manual/assert based solution the _Unit Test Framework_ provide following services: [cols="1,3"] |=== @@ -14,7 +14,7 @@ The test execution monitor along with standardized output from all included |Detailed information on the source of an error a| -The {utf} test tool's based assertion provides as much information as possible about cause of error, +The _Unit Test Framework_ test tool's based assertion provides as much information as possible about cause of error, usually allowing you to deduce what is wrong without entering the debugger or core analysis. |Separation of the test errors description (test log) from the results report summary (test results report) @@ -22,20 +22,20 @@ a| The information produced during test execution, including all error, warning and info messages from the test tools, executed test units notification constitute the *test log*. -Once testing is completed the {utf} may produce a summary *test report* with +Once testing is completed the _Unit Test Framework_ may produce a summary *test report* with different levels of detail. |Flexibility in what is shown in the output a| -The {utf} provides the ability to configure what is shown in both the test log and the test report. The +The _Unit Test Framework_ provides the ability to configure what is shown in both the test log and the test report. The configuration is supported both at runtime (from the command line) and at compile time from within a test module. |Flexibility in how output is formatted a| -The {utf} provides the ability to configure the format of the test module output. At the moment only +The _Unit Test Framework_ provides the ability to configure the format of the test module output. At the moment only xref:test_output/log_formats.adoc[three formats] - are supported by the {utf} itself. However the well defined public interface allows you to + are supported by the _Unit Test Framework_ itself. However the well defined public interface allows you to xref:test_output/logging_api.adoc#custom_log_formatter[customize] an output for your purposes. diff --git a/doc/modules/ROOT/pages/test_output/log_floating_points.adoc b/doc/modules/ROOT/pages/test_output/log_floating_points.adoc index 9b00ce6eab..bfe851def0 100644 --- a/doc/modules/ROOT/pages/test_output/log_floating_points.adoc +++ b/doc/modules/ROOT/pages/test_output/log_floating_points.adoc @@ -1,7 +1,7 @@ = Logging floating point type numbers :page-aliases: boost_test/test_output/test_tools_support_for_logging/log_floating_points.adoc -It may appear that floating-point numbers are displayed by the {utf} with an excessive number of decimal digits. +It may appear that floating-point numbers are displayed by the _Unit Test Framework_ with an excessive number of decimal digits. However the number of digits shown is chosen to avoid apparently nonsensical displays like `[1.00000 != 1.00000]` when comparing exactly unity against a value which is increased by just one least significant binary digit using the default precision for float of just 6 decimal digits, given by @@ -15,8 +15,8 @@ string. So a much more helpful display using 9 decimal digits is thus: `[1.00000000 != 1.00000012]` showing that the two values are in fact different. -For {ieee754} 32-bit float values - 9 decimal digits are shown. For 64-bit {ieee754} double - 17 decimal digits. For -{ieee754} extended long double using 80-bit - 21 decimal digits. For {ieee754} quadruple long double 128-bit, and SPARC +For *IEEE754* 32-bit float values - 9 decimal digits are shown. For 64-bit *IEEE754* double - 17 decimal digits. For +*IEEE754* extended long double using 80-bit - 21 decimal digits. For *IEEE754* quadruple long double 128-bit, and SPARC extended long double 128-bit - 36 decimal digits. For floating-point types, a convenient formula to calculate `max_digits10` is: `2 + std::numeric_limits::digits * 3010/10000`; diff --git a/doc/modules/ROOT/pages/test_output/log_formats.adoc b/doc/modules/ROOT/pages/test_output/log_formats.adoc index a7d34d7c4a..cd373f5185 100644 --- a/doc/modules/ROOT/pages/test_output/log_formats.adoc +++ b/doc/modules/ROOT/pages/test_output/log_formats.adoc @@ -1,7 +1,7 @@ = Log formats :page-aliases: boost_test/test_output/log_formats.adoc -The {utf} supports several log formats: +The _Unit Test Framework_ supports several log formats: * xref:test_output/log_formats.adoc#log_human_readable_format[HRF]: human readable format * xref:test_output/log_formats.adoc#log_xml_format[XML]: an machine interpretable log format @@ -56,12 +56,12 @@ the list of all levels in order of increasing 'importance': |This category includes messages that provide information on successfully passed assertions |Test tree traversal -|This category includes messages that are produced by the {utf} core and indicate which test suites/cases are currently being executed or skipped +|This category includes messages that are produced by the _Unit Test Framework_ core and indicate which test suites/cases are currently being executed or skipped |General information a| This category includes general information messages produced in most cases by a test module author using the - macro {boost_test_message} + macro xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] |Warning |This category includes messages produced by failed `WARNING` level assertions @@ -71,18 +71,18 @@ This category includes general information messages produced in most cases by a |Uncaught C++ exceptions a| -This category includes messages that are produced by the {utf} and provide detailed information on the C++ +This category includes messages that are produced by the _Unit Test Framework_ and provide detailed information on the C++ exceptions uncaught by the test case body. |Non-fatal system error a| -This category includes messages that are produced by the {utf} itself and provides information about caught +This category includes messages that are produced by the _Unit Test Framework_ itself and provides information about caught non-fatal system error. For example it includes messages produced in the case of test case timeout or if floating point values calculation errors are caught. |Fatal system error a| -This category includes messages produced by failed require level assertions and by the {utf} itself in case of +This category includes messages produced by failed require level assertions and by the _Unit Test Framework_ itself in case of abnormal test case termination. |=== diff --git a/doc/modules/ROOT/pages/test_output/logging_api.adoc b/doc/modules/ROOT/pages/test_output/logging_api.adoc index 9c500a6fe2..b5fc20ab94 100644 --- a/doc/modules/ROOT/pages/test_output/logging_api.adoc +++ b/doc/modules/ROOT/pages/test_output/logging_api.adoc @@ -2,7 +2,7 @@ :page-aliases: boost_test/test_output/logging_api.adoc While many test log configuration tasks can be performed at runtime using predefined framework parameters, the -{utf} provides a compile time interface as well. The interface gives you full power over what, where and how to +_Unit Test Framework_ provides a compile time interface as well. The interface gives you full power over what, where and how to log. The interface of the logger is provided by singleton class cpp:boost::unit_test::unit_test_log_t[boost::unit_test::unit_test_log_t] and is accessible through local file scope reference to single instance of this class @@ -11,7 +11,7 @@ accessible through local file scope reference to single instance of this class boost::unit_test::unit_test_log ---- -In order to install customization of the logger, the {utf} provides the {boost_test_global_configuration} facility +In order to install customization of the logger, the _Unit Test Framework_ provides the xref:{boost_test_global_configuration}[`BOOST_TEST_GLOBAL_CONFIGURATION`] facility that acts in a similar fashion to a global fixture. [#log_ct_output_stream_redirection] @@ -83,7 +83,7 @@ include::partial$bt_example.adoc[] [#log_ct_log_format] == Predefined log format selection -The select at compile time the log format from the list of the formats supplied by the {utf} +The select at compile time the log format from the list of the formats supplied by the _Unit Test Framework_ [source,cpp] ---- diff --git a/doc/modules/ROOT/pages/test_output/summary.adoc b/doc/modules/ROOT/pages/test_output/summary.adoc index d6aab04b2d..2b74438da1 100644 --- a/doc/modules/ROOT/pages/test_output/summary.adoc +++ b/doc/modules/ROOT/pages/test_output/summary.adoc @@ -6,25 +6,25 @@ |Macro |Short description -|{boost_test_message} +|xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] |Custom message output -|{boost_test_dont_print_log_value} +|xref:{boost_test_dont_print_log_value}[`BOOST_TEST_DONT_PRINT_LOG_VALUE`] |Disabling the printing of a specific type in case of test failure -|{boost_test_checkpoint} +|xref:{boost_test_checkpoint}[`BOOST_TEST_CHECKPOINT`] |Indicates a named checkpoint that will be printed in case of failure -|{boost_test_passpoint} +|xref:{boost_test_passpoint}[`BOOST_TEST_PASSPOINT`] |Indicates an unnamed checkpoint that will be printed in case of failure -|{boost_test_info} +|xref:{boost_test_info}[`BOOST_TEST_INFO`] |Defines a message to be printed as part of the context of the first encountered assertion, if it fails -|{boost_test_context} +|xref:{boost_test_context}[`BOOST_TEST_CONTEXT`] |Defines a scope and a message to be printed as part of the context of every failed assertion within the scope -|{boost_test_info_scope} -|Defines a sticky scoped version of {boost_test_info} that is attached to all the assertions coming after this declaration and within the current scope. +|xref:{boost_test_info_scope}[`BOOST_TEST_INFO_SCOPE`] +|Defines a sticky scoped version of xref:{boost_test_info}[`BOOST_TEST_INFO`] that is attached to all the assertions coming after this declaration and within the current scope. |=== diff --git a/doc/modules/ROOT/pages/test_output/test_output_progress.adoc b/doc/modules/ROOT/pages/test_output/test_output_progress.adoc index dd74324eae..76747f2c42 100644 --- a/doc/modules/ROOT/pages/test_output/test_output_progress.adoc +++ b/doc/modules/ROOT/pages/test_output/test_output_progress.adoc @@ -2,7 +2,7 @@ :page-aliases: boost_test/test_output/test_output_progress.adoc In case if the test module involves lengthy computation split among multiple test cases you may be interested in -progress monitor. The test runners supplied with the {utf} support simple text progress display, implemented based +progress monitor. The test runners supplied with the _Unit Test Framework_ support simple text progress display, implemented based on [source,cpp] @@ -10,13 +10,13 @@ on boost::progress_display ---- -footnote:[The {utf} interfaces allow implementing an advanced GUI based test runner with arbitrary progress display controls]. +footnote:[The _Unit Test Framework_ interfaces allow implementing an advanced GUI based test runner with arbitrary progress display controls]. -The progress display output is enabled using the {utf} parameter +The progress display output is enabled using the _Unit Test Framework_ parameter xref:utf_reference/rt_param_reference.adoc#show_progress[`show_progress`]. -The {utf} has no ability to estimate how long (in time duration) the test case execution is going to take and the manual test -progress update is not supported at this point. The {utf} tracks the progress on test case level. If you want to +The _Unit Test Framework_ has no ability to estimate how long (in time duration) the test case execution is going to take and the manual test +progress update is not supported at this point. The _Unit Test Framework_ tracks the progress on test case level. If you want to see more frequent progress update, you need to split the test into multiple test cases. In default configuration both test log and test progress outputs are directed into standard output stream. Any test diff --git a/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc index a474d29b27..ddce00652e 100644 --- a/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc +++ b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc @@ -14,20 +14,20 @@ operator<<(std::ostream&, ArgumentType const&); interface, you will get a compilation error. -The {utf} supports three different methods for logging user defined types: +The _Unit Test Framework_ supports three different methods for logging user defined types: . through the `operator<<` for that specific type: any type that implements the above interface has direct support for logging, . through a customization point responsible for logging a specific type, which is less intrusive than the implementation of `operator<<`. This is explained in more details in xref:test_output/test_tools_support_for_logging.adoc#ref_log_output_custom_customization_point[this section], . by prohibiting the xref:testing_tools/index.adoc[testing tools] from logging argument values for -specified type through {boost_test_dont_print_log_value}. +specified type through xref:{boost_test_dont_print_log_value}[`BOOST_TEST_DONT_PRINT_LOG_VALUE`]. This is explained in more details in xref:test_output/test_tools_support_for_logging.adoc#ref_log_output_custom_avoid_printing[this section]. [#ref_log_output_custom_customization_point] === User type customization point for logging -It is possible to indicate a function, `boost_test_print_type`, to {utf} that is responsible for the printing of a user defined type, without +It is possible to indicate a function, `boost_test_print_type`, to _Unit Test Framework_ that is responsible for the printing of a user defined type, without the need to override the `operator<<` for that specific type. This is convenient for instance when the `operator<<` has already been defined for other needs. @@ -64,11 +64,11 @@ include::partial$bt_example.adoc[] [#test_output_macro_message] == Custom messages -The macro {boost_test_message} is intended to be used for the purpose of injecting an additional message into the -{utf} test log. These messages are not intended to indicate any error or warning conditions, but rather as +The macro xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] is intended to be used for the purpose of injecting an additional message into the +_Unit Test Framework_ test log. These messages are not intended to indicate any error or warning conditions, but rather as information/status notifications. The macro signature is as follows: -{boost_test_message}(test_message); +xref:{boost_test_message}[`BOOST_TEST_MESSAGE`](test_message); The test_message argument can be as simple as C string literal or any custom expression that you can produce with in a manner similar to standard `std::iostream` operation. @@ -83,5 +83,5 @@ Messages generated by this tool do not appear in test log output with default va // tag reference: doc/modules/ROOT/examples/example21.run.cpp :bt-name: example21 :bt-rule: run -:bt-descr: {boost_test_message} usage +:bt-descr: xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] usage include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/bitwise.adoc b/doc/modules/ROOT/pages/testing_tools/bitwise.adoc index 8f133ab039..980bcb06e8 100644 --- a/doc/modules/ROOT/pages/testing_tools/bitwise.adoc +++ b/doc/modules/ROOT/pages/testing_tools/bitwise.adoc @@ -3,8 +3,8 @@ CAUTION: this feature is not available for non C++11 compilers. -The manipulator cpp:boost::test_tools::bitwise[boost::test_tools::bitwise] can be provided to the {boost_test} macro in order to have a bitwise comparison -of the operands. In that case, the {utf} indicates the bit indices where the two operands do not match. +The manipulator cpp:boost::test_tools::bitwise[boost::test_tools::bitwise] can be provided to the xref:{boost_test}[`BOOST_TEST`] macro in order to have a bitwise comparison +of the operands. In that case, the _Unit Test Framework_ indicates the bit indices where the two operands do not match. // tag reference: doc/modules/ROOT/examples/boost_test_bitwise.run-fail.cpp :bt-name: boost_test_bitwise diff --git a/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc b/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc index 2424f2915b..dbba9d2ad0 100644 --- a/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc +++ b/doc/modules/ROOT/pages/testing_tools/boost_test_universal_macro.adoc @@ -1,7 +1,7 @@ = BOOST_TEST: universal and general purpose assertions :page-aliases: boost_test/testing_tools/boost_test_universal_macro.adoc -The {utf} provides an almost unique interface to a great range of test-case scenarios, through the {boost_test} +The _Unit Test Framework_ provides an almost unique interface to a great range of test-case scenarios, through the xref:{boost_test}[`BOOST_TEST`] macro. The general form of `BOOST_TEST` is the following: BOOST_TEST(statement); diff --git a/doc/modules/ROOT/pages/testing_tools/collections.adoc b/doc/modules/ROOT/pages/testing_tools/collections.adoc index 09cc76e301..cb4df16f93 100644 --- a/doc/modules/ROOT/pages/testing_tools/collections.adoc +++ b/doc/modules/ROOT/pages/testing_tools/collections.adoc @@ -27,19 +27,19 @@ the test body would gain in clarity and expressiveness (including the report in * some comparison methods such as the lexicographical one, have good general behavior (e.g. total ordering, defined for collections of different size), but are sometimes inappropriate. -{boost_test} provides specific tools for comparing collections: +xref:{boost_test}[`BOOST_TEST`] provides specific tools for comparing collections: * using the _native_ footnote:[either defined by the container or by the user] operator of the container of the collection, which is mentioned as the xref:testing_tools/collections.adoc#ref_boost_test_coll_default_comp[_default behavior_]. * using xref:testing_tools/collections.adoc#boost_test_coll_perelement[element-wise] comparison for which extended failure diagnostic is provided, * and using xref:testing_tools/collections.adoc#boost_test_coll_default_lex[lexicographical] comparison for which extended failure diagnostic is provided, -More details about the concept of _collection_ in the {utf} is given xref:testing_tools/collections.adoc#what_is_a_collection[_here_]. +More details about the concept of _collection_ in the _Unit Test Framework_ is given xref:testing_tools/collections.adoc#what_is_a_collection[_here_]. [#ref_boost_test_coll_default_comp] == Default comparison -The default comparison dispatches to the existing overloaded comparison operator. The {utf} distinguishes two use cases +The default comparison dispatches to the existing overloaded comparison operator. The _Unit Test Framework_ distinguishes two use cases . none of the comparison operand is a C-Array, in which case we use the xref:testing_tools/collections.adoc#ref_boost_test_coll_default_comp_container[container default behavior] . one of the comparison operand is a C-array, in which case we xref:testing_tools/collections.adoc#ref_boost_test_coll_c_arrays[mimic `std::vector`] behavior @@ -67,7 +67,7 @@ compile if the corresponding lines were uncommented (`std::vector` uses lexicogr [NOTE] ==== -In the case of default comparison, there is no additional diagnostic provided by the {utf}. See the section +In the case of default comparison, there is no additional diagnostic provided by the _Unit Test Framework_. See the section xref:testing_tools/collections.adoc#ref_boost_test_coll_special_macro[`BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE`] below. ==== @@ -80,7 +80,7 @@ include::partial$bt_example.adoc[] [#ref_boost_test_coll_c_arrays] === C-arrays default behavior -As soon as one of the operands is a C-array, there is no _default behavior_ the {utf} can dispatch to. +As soon as one of the operands is a C-array, there is no _default behavior_ the _Unit Test Framework_ can dispatch to. This is why in that case, the comparison mimics the `std::vector` behavior. // tag reference: doc/modules/ROOT/examples/boost_test_macro_container_c_array.run-fail.cpp @@ -94,7 +94,7 @@ include::partial$bt_example.adoc[] By specifying the manipulator cpp:boost::test_tools::per_element[boost::test_tools::per_element], the comparison of the elements of the containers are performed _element-wise_, in the order given by the forward iterators of the containers. This is a comparison on -the _sequences_ of elements generated by the containers, for which the {utf} provides advanced diagnostic. +the _sequences_ of elements generated by the containers, for which the _Unit Test Framework_ provides advanced diagnostic. In more details, let `c_a = (a_1,... a_n)` and `c_b = (b_1,... b_n)` be two sequences of same length, but not necessarily of same type. Those sequences correspond to the content of the respective containers, in the order given by their iterator. Let @@ -169,7 +169,7 @@ BOOST_TEST(c_a == c_b == 42, boost::test_tools::per_element() ); // does not com == Lexicographic comparison By specifying the manipulator cpp:boost::test_tools::lexicographic[boost::test_tools::lexicographic], the containers are compared using the _lexicographical_ -order and for which the {utf} provides additional diagnostic in case of failure. +order and for which the _Unit Test Framework_ provides additional diagnostic in case of failure. [source,cpp] ---- @@ -204,7 +204,7 @@ implicit when the container overloads/implements this type of comparison, the container overloads/implements uses this type of comparison. When the default is to using the container implementation, it is not possible to benefit from an extended failure diagnostic. -The {utf} provides a mechanism for performing the same comparisons through the {utf} instead of the container operator, +The _Unit Test Framework_ provides a mechanism for performing the same comparisons through the _Unit Test Framework_ instead of the container operator, through the macro `BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE` that might be used as follow: // tag reference: doc/modules/ROOT/examples/boost_test_container_lex_default.run-fail.cpp @@ -234,13 +234,13 @@ dispatched to string xref:testing_tools/strings.adoc[comparison instead]. [WARNING] ==== -`string` (or `wstring`) meets the sequence concept by definition, but their handling with {boost_test} is done differently. +`string` (or `wstring`) meets the sequence concept by definition, but their handling with xref:{boost_test}[`BOOST_TEST`] is done differently. See xref:testing_tools/strings.adoc[Strings and C-strings comparison] for more details. ==== [TIP] ==== -If the behavior of {boost_test} is not the one you expect, you can always use raw comparison. See xref:testing_tools/boost_test_universal_macro.adoc#boost_test_statement_limitations[this section] +If the behavior of xref:{boost_test}[`BOOST_TEST`] is not the one you expect, you can always use raw comparison. See xref:testing_tools/boost_test_universal_macro.adoc#boost_test_statement_limitations[this section] for details. ==== @@ -258,5 +258,5 @@ Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[Boost.Test 3.7] (Boost 1.67) the d The detection of the types that meet these requirements containers is delegated to the class cpp:boost::unit_test::is_forward_iterable[boost::unit_test::is_forward_iterable], which for C++11 detects the required member functions and fields. However for C++03, the types providing the sequences should be explicitly -indicated to the {utf} by a specialization of cpp:boost::unit_test::is_forward_iterable[boost::unit_test::is_forward_iterable] +indicated to the _Unit Test Framework_ by a specialization of cpp:boost::unit_test::is_forward_iterable[boost::unit_test::is_forward_iterable] footnote:[Standard containers of the `STL` are recognized as _forward iterable_ container.]. diff --git a/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc b/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc index 20f0758337..73e0485e6e 100644 --- a/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc +++ b/doc/modules/ROOT/pages/testing_tools/custom_predicates.adoc @@ -6,23 +6,23 @@ some cases you may want to implement and use custom predicate that perform compl on failure. To satisfy this need testing tools implement custom predicate support. There two layers of custom predicate support implemented by testing tools toolbox: with and without custom error message generation. -The first layer is supported by {boost_level_predicate} family of testing tools. You can use it to check any custom +The first layer is supported by xref:{boost_level_predicate}[`BOOST__PREDICATE`] family of testing tools. You can use it to check any custom predicate that reports the result as boolean value. The values of the predicate arguments are reported by the tool automatically in case of failure. // tag reference: doc/modules/ROOT/examples/example30.run-fail.cpp :bt-name: example30 :bt-rule: run-fail -:bt-descr: Custom predicate support using {boost_level_predicate} +:bt-descr: Custom predicate support using xref:{boost_level_predicate}[`BOOST__PREDICATE`] include::partial$bt_example.adoc[] -To use second layer your predicate has to return {class_predicate_result}. +To use second layer your predicate has to return cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result]. This class encapsulates boolean result value along with any error or information message you opt to report. -Usually you construct the instance of class {class_predicate_result} inside your predicate function and return it by +Usually you construct the instance of class cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result] inside your predicate function and return it by value. The constructor expects one argument - the boolean result value. The constructor is implicit, so you can simply -return boolean value from your predicate and {class_predicate_result} is constructed automatically to hold your value +return boolean value from your predicate and cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result] is constructed automatically to hold your value and empty message. You can also assign boolean value to the constructed instance. You can check the current predicate value by using `operator!` or directly accessing public read-only property `p_predicate_value`. The error message is stored in public read-write property `p_message`. @@ -30,5 +30,5 @@ stored in public read-write property `p_message`. // tag reference: doc/modules/ROOT/examples/example31.run-fail.cpp :bt-name: example31 :bt-rule: run-fail -:bt-descr: Custom predicate support using class {class_predicate_result} +:bt-descr: Custom predicate support using class cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result] include::partial$bt_example.adoc[] diff --git a/doc/modules/ROOT/pages/testing_tools/debugging.adoc b/doc/modules/ROOT/pages/testing_tools/debugging.adoc index 27740beecb..e8dcd686a2 100644 --- a/doc/modules/ROOT/pages/testing_tools/debugging.adoc +++ b/doc/modules/ROOT/pages/testing_tools/debugging.adoc @@ -2,7 +2,7 @@ :page-aliases: boost_test/testing_tools/debugging.adoc In case you observe a failure in unit tests and you are using a debugger to determine the cause, -it may get really difficult to step into the expression inside an assertion. Because {boost_test} +it may get really difficult to step into the expression inside an assertion. Because xref:{boost_test}[`BOOST_TEST`] builds an expression tree before evaluating it, the "Step Into" function of the debugger will have to step into every step of building the expression tree before, you can go into the evaluation of the expression. @@ -10,8 +10,8 @@ the expression. In order to mitigate the problem, the test module can be build in the mode which disables the building of expression trees inside assertions. In this mode, the first thing the assertion does is to eagerly evaluate the tested expression. -You enable this mode by defining symbol {boost_test_tools_under_debugger} (either with `+#define+` -or with compiler option `-D`) prior to including any of the {utf} headers. +You enable this mode by defining symbol xref:{boost_test_tools_under_debugger}[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`] (either with `+#define+` +or with compiler option `-D`) prior to including any of the _Unit Test Framework_ headers. [CAUTION] ==== @@ -23,11 +23,11 @@ _literally_: this automatically disables any special semantics, ill-formed program, if the sequences of different types are being compared. ==== -The inconvenience with {boost_test_tools_under_debugger} is that you have to recompile the test module. -The {utf} gives you another option to compile two versions of the assertions and select the one to be used dynamically +The inconvenience with xref:{boost_test_tools_under_debugger}[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`] is that you have to recompile the test module. +The _Unit Test Framework_ gives you another option to compile two versions of the assertions and select the one to be used dynamically depending on whether the test module is run under debugger or not. -This mode is enabled by defining symbol {boost_test_tools_debuggable} (either with `+#define+` or with -compiler option `-D`) prior to the inclusion of any of the {utf} headers. +This mode is enabled by defining symbol xref:{boost_test_tools_debuggable}[`BOOST_TEST_TOOLS_DEBUGGABLE`] (either with `+#define+` or with +compiler option `-D`) prior to the inclusion of any of the _Unit Test Framework_ headers. In order to determine if the test module is run under debugger or not, function cpp:boost::debug::under_debugger[`boost::debug::under_debugger`] is used. diff --git a/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc b/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc index 1e8d1db3ec..fbb9f88925 100644 --- a/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc +++ b/doc/modules/ROOT/pages/testing_tools/exception_correctness.adoc @@ -13,12 +13,12 @@ include::partial$bt_example.adoc[] More control over the exception correctness is often required, for instance to test that an expression is raising a specific exception, intentionally. -The {utf} provides several assertions for testing a code with respect to the exceptions correctness. +The _Unit Test Framework_ provides several assertions for testing a code with respect to the exceptions correctness. The following assertions are available: -* {boost_level_no_throw} checks that no exception is raised from an expression, -* {boost_level_throw} checks that an expression raises an exception of a specific type -* {boost_level_exception} checks that an expression raises an exception of a specific type, +* xref:{boost_level_no_throw}[`BOOST__NO_THROW`] checks that no exception is raised from an expression, +* xref:{boost_level_throw}[`BOOST__THROW`] checks that an expression raises an exception of a specific type +* xref:{boost_level_exception}[`BOOST__EXCEPTION`] checks that an expression raises an exception of a specific type, a passes the exception instance to a predicate function for further validation (introspection for instance) diff --git a/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc b/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc index 09c4ad089e..2a72dc20d9 100644 --- a/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc +++ b/doc/modules/ROOT/pages/testing_tools/expected_failures.adoc @@ -10,7 +10,7 @@ This feature allows specifying an expected number of failed assertions per test during test tree construction, and can't be updated during test execution. The feature is not intended to be used to check for expected functionality failures. To check that a particular -input is causing an exception to be thrown use {boost_level_throw} family of testing +input is causing an exception to be thrown use xref:{boost_level_throw}[`BOOST__THROW`] family of testing tools. The usage of this feature should be limited and employed only after careful consideration. In general you should @@ -32,7 +32,7 @@ If an assertion at fault is fixed and passed while an expected failures specific [#l_expected_failure] == Expected failure specification -The decorator {decorator_expected_failures} defines the number of assertions that are expected to fail within the corresponding test +The decorator xref:{decorator_expected_failures}[`expected_failures`] defines the number of assertions that are expected to fail within the corresponding test unit. It is reported as failure when the number of failed assertions is greater than the declared expected number of failures. If the number of failed assertions is less than the number of expected failures a message is reported. The total number of expected failures for a given test suite `S` is the sum of the declared expected failures in `S` and the @@ -58,7 +58,7 @@ this usage is considered as deprecated. Please consider using the xref:testing_t ==== For backwards compatibility, it is possible to indicate the expected failures with -{boost_auto_test_case_expected_failures} footnote:[deprecated] before the test case definition. +xref:{boost_auto_test_case_expected_failures}[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`] footnote:[deprecated] before the test case definition. [source,cpp] ---- @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(test_case_name, number_of_expected_failur You can use this macro both on a file scope and inside a test suite. Moreover you can use it even if name of test units coincide in different test suites. Expected failures specification applies to the test unit belonging to the same -test suite where {boost_auto_test_case_expected_failures} resides. +test suite where xref:{boost_auto_test_case_expected_failures}[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`] resides. // tag reference: doc/modules/ROOT/examples/example17.run.cpp :bt-name: example17 diff --git a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc index 10be1b7670..37a168e906 100644 --- a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc +++ b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc @@ -1,7 +1,7 @@ = Floating point comparison :page-aliases: boost_test/testing_tools/extended_comparison/floating_point.adoc -Unless specified otherwise, when a value of floating-point type is compared inside a {boost_test} assertion, +Unless specified otherwise, when a value of floating-point type is compared inside a xref:{boost_test}[`BOOST_TEST`] assertion, operators `==`, `!=` , `<` etc. defined for this type are used. However for floating point type, in most cases what is needed is not an _exact_ equality (or inequality), but a verification that two numbers are _sufficiently close_ or _sufficiently different_. For that purpose, a *tolerance* parameter that will instruct the framework what is considered _sufficiently close_ needs to provided. @@ -11,7 +11,7 @@ NOTE: How the tolerance parameter is processed in detail is described xref:testi == Test-unit tolerance It is possible to define a per-xref:section_glossary.adoc#ref_test_unit[test unit] tolerance for a given floating point type by using -xref:tests_organization/decorators.adoc[decorator] {decorator_tolerance}: +xref:tests_organization/decorators.adoc[decorator] xref:{decorator_tolerance}[`tolerance`]: // tag reference: doc/modules/ROOT/examples/tolerance_01.run-fail.cpp :bt-name: tolerance_01 @@ -22,7 +22,7 @@ include::partial$bt_example.adoc[] == Assertion tolerance It is possible to specify floating point comparison tolerance per single assertion, by providing the _manipulator_ cpp:boost::test_tools::tolerance[boost::test_tools::tolerance] -as the second argument to {boost_test}: +as the second argument to xref:{boost_test}[`BOOST_TEST`]: // tag reference: doc/modules/ROOT/examples/tolerance_02.run-fail.cpp :bt-name: tolerance_02 @@ -34,7 +34,7 @@ include::partial$bt_example.adoc[] ==== Manipulators requires a compiler that supports variadic macros, `auto` for type deduction and `decltype`. These are C++11 features, but are also available on some pre-C++11 compilers. On compilers that are - lacking these features, resort to defining tolerance per test unit or to compatibility test assertions: {boost_check_close} and {boost_check_small}. + lacking these features, resort to defining tolerance per test unit or to compatibility test assertions: xref:{boost_check_close}[`BOOST_CHECK_CLOSE`] and xref:{boost_check_small}[`BOOST_CHECK_SMALL`]. ==== == Tolerance expressed in percentage @@ -95,12 +95,12 @@ the numeric value passed along the manipulator: This is also the case for decorator `tolerance`. In the case of the decorator however, it is possible to apply multiple decorators `tolerance` defining the tolerance for different types. -When values of two different floating point types `T` and `U` are compared, {boost_test} uses the tolerance +When values of two different floating point types `T` and `U` are compared, xref:{boost_test}[`BOOST_TEST`] uses the tolerance specified for type `boost::common_type::type`. For instance, when setting a tolerance for mixed `float`-to-`double` comparison, the tolerance for type `double` needs to be set. Given two floating point types `T` and `U` and their common type `C`, the tolerance specified for type `C` is applied only when -types `T` and `U` appear as sub-expressions of the full expression inside assertion {boost_test}. It is not applied when +types `T` and `U` appear as sub-expressions of the full expression inside assertion xref:{boost_test}[`BOOST_TEST`]. It is not applied when `T` and `U` are compared inside a function invoked during the evaluation of the expression: // tag reference: doc/modules/ROOT/examples/tolerance_05.run-fail.cpp @@ -111,7 +111,7 @@ include::partial$bt_example.adoc[] == Type promotion of the operands -Given two types `T` and `U` being compared inside an assertion {boost_test}, tolerance based comparison is invoked +Given two types `T` and `U` being compared inside an assertion xref:{boost_test}[`BOOST_TEST`], tolerance based comparison is invoked . whenever the types `T` and `U` are both xref:testing_tools/floating_point.adoc#customizing_for_tolerance[tolerance based] types . whenever `T` is _tolerance_ based and `U` is _arithmetic_, in the sense that `std::numeric_limits::value` evaluates to `true` (or the other way round) @@ -120,7 +120,7 @@ In all cases, the type of the tolerance is deduced as `boost::common_type: [NOTE] ==== -This behavior has been introduced in Boost 1.70 / {utf} xref:change_log.adoc#ref_CHANGE_LOG_3_10[3.10]. Previously tolerance based comparison was used only when the type of the two +This behavior has been introduced in Boost 1.70 / _Unit Test Framework_ xref:change_log.adoc#ref_CHANGE_LOG_3_10[3.10]. Previously tolerance based comparison was used only when the type of the two operands were tolerance based types, which was silently ignoring the tolerance for expressions such as [source,cpp] @@ -153,7 +153,7 @@ include::partial$bt_example.adoc[] [#customizing_for_tolerance] == Enabling tolerance for user-defined types -The {utf} recognizes that a given type `T` is suitable for tolerance-based comparisons using the expression +The _Unit Test Framework_ recognizes that a given type `T` is suitable for tolerance-based comparisons using the expression cpp:boost::math::fpc::tolerance_based[boost::math::fpc::tolerance_based]`::value`. This meta-function already returns `true` for built-in floating-point types as well as any other types that match the following compile-time expression: @@ -273,7 +273,7 @@ a| [#floating_points_comparison_impl] == Tolerance-based comparisons -Assertions in the {utf} use two kinds of comparison. For `u` being close to zero with absolute tolerance `eps`: +Assertions in the _Unit Test Framework_ use two kinds of comparison. For `u` being close to zero with absolute tolerance `eps`: [source,cpp] ---- @@ -288,9 +288,9 @@ For `u` and `v` being close with relative tolerance `eps`: && abs(u - v)/abs(v) <= eps; // (rel) ---- -For rationale for choosing these formulae, see section {floating_points_testing_tools}. +For rationale for choosing these formulae, see section xref:{floating_points_testing_tools}[Floating point comparison algorithms]. -Assertion {boost_test} (when comparing floating-point numbers) uses the following algorithm: +Assertion xref:{boost_test}[`BOOST_TEST`] (when comparing floating-point numbers) uses the following algorithm: * When either value `u` or `v` is zero, evaluates formula (abs) on the other value. * When the specified tolerance is zero, performs direct (native) comparison between `u` and `v`. @@ -306,11 +306,11 @@ BOOST_TEST(v == T(0), tt::tolerance(eps)); ---- ==== -The compatibility assertions {boost_level_close} and {boost_level_close_fraction} perform formula (rel). +The compatibility assertions xref:{boost_level_close}[`BOOST__CLOSE`] and xref:{boost_level_close_fraction}[`BOOST__CLOSE_FRACTION`] perform formula (rel). -The compatibility assertion {boost_level_small} performs formula (abs). +The compatibility assertion xref:{boost_level_small}[`BOOST__SMALL`] performs formula (abs). -The {utf} also provides unary predicate cpp:boost::math::fpc::small_with_tolerance[`small_with_tolerance`] and binary predicate predicate +The _Unit Test Framework_ also provides unary predicate cpp:boost::math::fpc::small_with_tolerance[`small_with_tolerance`] and binary predicate predicate cpp:boost::math::fpc::close_at_tolerance[`close_at_tolerance`] that implement formula (abs) and (rel) respectively. === Tolerance in `operator<` @@ -322,7 +322,7 @@ Tolerance-based computations also apply to `operator<` and other relational oper * _less-or-equal-at-tolerance_ <==> _strictly-less_ or _close-at-tolerance_ * _greater-or-equal-at-tolerance_ <==> _strictly-greater_ or _close-at-tolerance_ -NOTE: This implies that the exactly one of these: `u < v`, `u == v`, `u > v`, passes with {boost_test} at any given tolerance. +NOTE: This implies that the exactly one of these: `u < v`, `u == v`, `u > v`, passes with xref:{boost_test}[`BOOST_TEST`] at any given tolerance. [CAUTION] ==== @@ -346,7 +346,7 @@ However, in many circumstances, this is not what we want. The same absolute tole two values of magnitude `10e12` and at the same time too little to meaningfully compare values of magnitude `10e-12`. For examples, see xref:testing_tools/floating_point.adoc#Squassabia[Squassabia]. We do not want to apply the same absolute tolerance for huge and tiny numbers. Instead, we would like to scale the `epsilon` with `u` and `v`. -The {utf} implements floating-point comparison algorithm that is based on the solution presented in xref:testing_tools/floating_point.adoc#KnuthII[Knuth]: +The _Unit Test Framework_ implements floating-point comparison algorithm that is based on the solution presented in xref:testing_tools/floating_point.adoc#KnuthII[Knuth]: [#equ2] [source,cpp] @@ -420,10 +420,10 @@ produce others "non-rounding" errors, such as underflow/overflow, division-by-ze All theorems about the upper limit of a rounding error, including that of `half_epsilon`, refer only to the 'rounding' operation, nothing more. This means that the 'operation error', that is, the error incurred by the operation itself, besides rounding, isn't considered. In order for numerical software to be able to actually -predict error bounds, the {ieee754} standard requires arithmetic operations to be 'correctly or exactly rounded'. +predict error bounds, the *IEEE754* standard requires arithmetic operations to be 'correctly or exactly rounded'. That is, it is required that the internal computation of a given operation be such that the floating point result is the exact result rounded to the number of working bits. In other words, it is required that the computation used -by the operation itself doesn't introduce any additional errors. The {ieee754} standard does not require same behavior +by the operation itself doesn't introduce any additional errors. The *IEEE754* standard does not require same behavior from most non-arithmetic operation. The underflow/overflow and division-by-zero errors may cause rounding errors with unpredictable upper limits. diff --git a/doc/modules/ROOT/pages/testing_tools/index.adoc b/doc/modules/ROOT/pages/testing_tools/index.adoc index d2b8f94d4e..ab9102fcec 100644 --- a/doc/modules/ROOT/pages/testing_tools/index.adoc +++ b/doc/modules/ROOT/pages/testing_tools/index.adoc @@ -5,9 +5,9 @@ Once a test case has been declared, the body of this test should be written. A t sequence of operations in which *assertions* are inserted. Those assertions evaluate _statements_ that implement the expectation being validated, and report failures and/or information in a uniform manner, depending on the xref:utf_reference/rt_param_reference.adoc#log_level[log level]. -The {utf}'s supplies a toolbox of assertions to ease the creation and maintenance of test cases and +The _Unit Test Framework_'s supplies a toolbox of assertions to ease the creation and maintenance of test cases and provide a uniform error reporting mechanism. The toolbox supplied is in most part in a form of macro declarations. -An (almost) unique interface to all of them implemented by the macro {boost_test}. +An (almost) unique interface to all of them implemented by the macro xref:{boost_test}[`BOOST_TEST`]. NOTE: All macros arguments are calculated once, so it's safe to pass complex expressions in their place. diff --git a/doc/modules/ROOT/pages/testing_tools/internal_details.adoc b/doc/modules/ROOT/pages/testing_tools/internal_details.adoc index f00140c04c..92a73759f3 100644 --- a/doc/modules/ROOT/pages/testing_tools/internal_details.adoc +++ b/doc/modules/ROOT/pages/testing_tools/internal_details.adoc @@ -64,7 +64,7 @@ yields to the following evaluation chain: expression2.result = expression1.result op1 b expression1.result = a + -The final expression of the statement is cast to a boolean, which is in turn evaluated by the {utf}. +The final expression of the statement is cast to a boolean, which is in turn evaluated by the _Unit Test Framework_. The example below illustrates the construction of the left-to-right _chained_ expression. diff --git a/doc/modules/ROOT/pages/testing_tools/reports.adoc b/doc/modules/ROOT/pages/testing_tools/reports.adoc index aca264d58e..6491d3f7d3 100644 --- a/doc/modules/ROOT/pages/testing_tools/reports.adoc +++ b/doc/modules/ROOT/pages/testing_tools/reports.adoc @@ -31,7 +31,7 @@ TIP: Richness of the information contained in the logs is a key for the rapid un == Default reporting -When an assertion fails, {boost_test} reports details and values on the operands of `statement` that lead to the failure. +When an assertion fails, xref:{boost_test}[`BOOST_TEST`] reports details and values on the operands of `statement` that lead to the failure. // tag reference: doc/modules/ROOT/examples/boost_test_macro3.run-fail.cpp :bt-name: boost_test_macro3 @@ -45,7 +45,7 @@ of the full statement. However, we can observe that they are not treated symmetr * "`a - 1 < b`" reports `"13 - 1 >= 12" failed` * "`b > a - 1`" reports `"12 <= 12" failed` -More details on how the {utf} parses the statement are given in xref:testing_tools/internal_details.adoc[this] section. +More details on how the _Unit Test Framework_ parses the statement are given in xref:testing_tools/internal_details.adoc[this] section. == Custom messages diff --git a/doc/modules/ROOT/pages/testing_tools/strings.adoc b/doc/modules/ROOT/pages/testing_tools/strings.adoc index be379b62d7..32ee17e611 100644 --- a/doc/modules/ROOT/pages/testing_tools/strings.adoc +++ b/doc/modules/ROOT/pages/testing_tools/strings.adoc @@ -2,14 +2,14 @@ :page-aliases: boost_test/testing_tools/extended_comparison/strings.adoc In the general case, pointers are compared using their value. However when type of the the pointers are `+char*+` or `+wchar_t*+`, -{boost_test} promotes them as null terminated `char` arrays and string comparison is used instead. +xref:{boost_test}[`BOOST_TEST`] promotes them as null terminated `char` arrays and string comparison is used instead. `std::string` (or any `std::basic_string`) and `std::string_view` (or any `std::basic_string_view`) are eligible for string comparison. -String comparison can be used only if the operands to compare in {boost_test} can both be considered as strings type. +String comparison can be used only if the operands to compare in xref:{boost_test}[`BOOST_TEST`] can both be considered as strings type. [TIP] ==== -In this form, the comparison method and reporting can be overridden by providing an additional argument to {boost_test}. +In this form, the comparison method and reporting can be overridden by providing an additional argument to xref:{boost_test}[`BOOST_TEST`]. See the xref:testing_tools/collections.adoc[collection comparison] section for more details, in particular `boost::test_tools::per_element()` and `boost::test_tools::lexicographic()` modifiers. ==== diff --git a/doc/modules/ROOT/pages/testing_tools/summary.adoc b/doc/modules/ROOT/pages/testing_tools/summary.adoc index f37917d1f1..09748be992 100644 --- a/doc/modules/ROOT/pages/testing_tools/summary.adoc +++ b/doc/modules/ROOT/pages/testing_tools/summary.adoc @@ -6,70 +6,70 @@ |Assertions |Short description -|{boost_test}, {boost_test_level} +|xref:{boost_test}[`BOOST_TEST`], xref:{boost_test_level}[`BOOST_TEST_`] |General purpose assertion macro. -|{boost_level} +|xref:{boost_level}[`BOOST_`] |Simple validation of a boolean predicate value. -|{boost_level_bitwise_equal} +|xref:{boost_level_bitwise_equal}[`BOOST__BITWISE_EQUAL`] |Bitwise equality test of two elements. -|{boost_level_equal} +|xref:{boost_level_equal}[`BOOST__EQUAL`] |Equality test of two elements. -|{boost_level_equal_collections} +|xref:{boost_level_equal_collections}[`BOOST__EQUAL_COLLECTIONS`] |Element-wise equality test of two collections. -|{boost_level_close} +|xref:{boost_level_close}[`BOOST__CLOSE`] |Floating point comparison using a percentage of deviation. -|{boost_level_close_fraction} +|xref:{boost_level_close_fraction}[`BOOST__CLOSE_FRACTION`] |Floating point comparison using the fraction of the compared operands. -|{boost_level_exception} +|xref:{boost_level_exception}[`BOOST__EXCEPTION`] |Exception detection and validation check. -|{boost_level_ge} +|xref:{boost_level_ge}[`BOOST__GE`] |Comparison of two values (with convenient reporting). -|{boost_level_gt} +|xref:{boost_level_gt}[`BOOST__GT`] |Comparison of two values (with convenient reporting). -|{boost_level_le} +|xref:{boost_level_le}[`BOOST__LE`] |Comparison of two values (with convenient reporting). -|{boost_level_lt} +|xref:{boost_level_lt}[`BOOST__LT`] |Comparison of two values (with convenient reporting). -|{boost_level_message} -|Same as {boost_level} with a custom message in case of failure. +|xref:{boost_level_message}[`BOOST__MESSAGE`] +|Same as xref:{boost_level}[`BOOST_`] with a custom message in case of failure. -|{boost_level_ne} +|xref:{boost_level_ne}[`BOOST__NE`] |Comparison of two values (with convenient reporting). -|{boost_level_no_throw} +|xref:{boost_level_no_throw}[`BOOST__NO_THROW`] |Checks an expression does not throw any exception. -|{boost_level_predicate} +|xref:{boost_level_predicate}[`BOOST__PREDICATE`] |Checks a list of arguments against a predicate functor. -|{boost_level_small} +|xref:{boost_level_small}[`BOOST__SMALL`] |Checks a value is small according to a tolerance. -|{boost_level_throw} +|xref:{boost_level_throw}[`BOOST__THROW`] |Checks an expression throws a specific type of expression. -|{boost_auto_test_case_expected_failures} +|xref:{boost_auto_test_case_expected_failures}[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`] |Indicates the number of expected failures for a test case -|{boost_error} +|xref:{boost_error}[`BOOST_ERROR`] |Logs an error message, fails but does not abort the current test. -|{boost_fail} +|xref:{boost_fail}[`BOOST_FAIL`] |Logs an error message, fails and aborts the current test. -|{boost_is_defined} +|xref:{boost_is_defined}[`BOOST_IS_DEFINED`] |Checks at runtime whether or not the supplied preprocessor symbol is defined. |=== @@ -79,13 +79,13 @@ |Decorators |Short description -|{decorator_expected_failures} +|xref:{decorator_expected_failures}[`expected_failures`] |Indicates the expected failures of a test unit. -|{decorator_timeout} +|xref:{decorator_timeout}[`timeout`] |Sets the maximum amount of time a test unit should take. -|{decorator_tolerance} +|xref:{decorator_tolerance}[`tolerance`] |Sets the floating point comparison tolerance for a test unit. |=== @@ -95,10 +95,10 @@ |Control macros |Short description -|{boost_test_tools_under_debugger} +|xref:{boost_test_tools_under_debugger}[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`] |When defined, test assertions are compiled in debugger-friendly mode. -|{boost_test_tools_debuggable} +|xref:{boost_test_tools_debuggable}[`BOOST_TEST_TOOLS_DEBUGGABLE`] |When defined, test assertions are compiled in two modes (debugger-friendly and full-featured), and the version is selected at run-time. |=== diff --git a/doc/modules/ROOT/pages/testing_tools/timeout.adoc b/doc/modules/ROOT/pages/testing_tools/timeout.adoc index 34769a05bc..1ff4607cb6 100644 --- a/doc/modules/ROOT/pages/testing_tools/timeout.adoc +++ b/doc/modules/ROOT/pages/testing_tools/timeout.adoc @@ -1,18 +1,18 @@ = Time-out for test cases :page-aliases: boost_test/testing_tools/timeout.adoc -The {utf} provides the decorator {decorator_timeout} that specifies a time-out for a specific *test unit*. +The _Unit Test Framework_ provides the decorator xref:{decorator_timeout}[`timeout`] that specifies a time-out for a specific *test unit*. The argument time is always expressed in *seconds ans wall-clock* time. For test-cases, the time-out value sets the maximum allowed duration for the test. If this time is -exceeded, the test case is reported as failed. On some systems, the {utf} is able to force the test-case +exceeded, the test case is reported as failed. On some systems, the _Unit Test Framework_ is able to force the test-case to stop through a `SIGALRM` signal (see below). For test-suites, the time-out value sets the maximum allowed duration for the entire suite to complete. This duration is the accumulated time of all the test-cases contained in the sub-tree rooted on the test-suite, plus some extra -execution time needed by the {utf}. For each test-units under a test-suite with time-out, the maximum allowed duration +execution time needed by the _Unit Test Framework_. For each test-units under a test-suite with time-out, the maximum allowed duration is set as being the test-suite time out minus the accumulated execution time before the execution of the test-unit. -If this test-unit is a test-case, it is equivalent to setting the decorator {decorator_timeout} to the test-case +If this test-unit is a test-case, it is equivalent to setting the decorator xref:{decorator_timeout}[`timeout`] to the test-case with a time-out value expressed as before. In case the test-suite times out, the @@ -30,7 +30,7 @@ include::partial$bt_example.adoc[] The macro `BOOST_SIGACTION_BASED_SIGNAL_HANDLING` is defined if Boost.Test is able to force the test-case to stop. This feature is for instance not supported on Windows. - The {utf} will still be able to report the test-case as failed (once the test-case finishes). + The _Unit Test Framework_ will still be able to report the test-case as failed (once the test-case finishes). ==== -NOTE: The support of test suite level time-out has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / {utf} v3.10] +NOTE: The support of test suite level time-out has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / _Unit Test Framework_ v3.10] diff --git a/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc index beaa6db0cb..873d8b18c1 100644 --- a/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc +++ b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc @@ -15,8 +15,8 @@ to validate aspects less important then correctness: performance, portability, u For example: -* xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST_REQUIRE_THROW`], {boost_test_require} -* `BOOST_CHECK_THROW`, `BOOST_TEST` footnote:[{boost_test} is equivalent to `BOOST_TEST_CHECK`] +* xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST_REQUIRE_THROW`], xref:{boost_test_require}[`BOOST_TEST_REQUIRE`] +* `BOOST_CHECK_THROW`, `BOOST_TEST` footnote:[xref:{boost_test}[`BOOST_TEST`\] is equivalent to `BOOST_TEST_CHECK`] * `BOOST_WARN_THROW`, `BOOST_TEST_WARN` These three levels of assertions are filtered by the framework and reported into the test log and output: diff --git a/doc/modules/ROOT/pages/tests_organization/decorators.adoc b/doc/modules/ROOT/pages/tests_organization/decorators.adoc index 227f71c8e7..6eea127474 100644 --- a/doc/modules/ROOT/pages/tests_organization/decorators.adoc +++ b/doc/modules/ROOT/pages/tests_organization/decorators.adoc @@ -9,7 +9,7 @@ the following sections. == Test case decorators You can apply more than one decorator to the same test unit. A list of decorators is applied to a test case by specifying -it as the second argument to macro {boost_auto_test_case} or the third argument to macro {boost_fixture_test_case}. +it as the second argument to macro xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] or the third argument to macro xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`]. // tag reference: doc/modules/ROOT/examples/decorator_01.run.cpp :bt-name: decorator_01 @@ -20,7 +20,7 @@ include::partial$bt_example.adoc[] Each decorator in the list is preceded by an asterisk (`+*+`); the subsequent syntax resembles a function call and is specified in detail for each decorator. If there is more than one decorator in the list, they are concatenated with no additional separator; each asterisk indicates the beginning of a decorator. In the above example, test case `test_case1` -has one associated _decorator:_ {decorator_label}. This means that when test units are filtered based on label, this +has one associated _decorator:_ xref:{decorator_label}[`label`]. This means that when test units are filtered based on label, this test case will match to label `"trivial"`. Test case `test_case2` has three associated decorators: two of type `label` and one of type `description`. @@ -28,8 +28,8 @@ and one of type `description`. == Suite-level decorators Similarly to test case it is possible to apply list of decorators to test suite. It is done by specifying a list of -decorators as the second argument to the macro {boost_auto_test_suite} or the third argument to the macro -{boost_fixture_test_suite}. +decorators as the second argument to the macro xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`] or the third argument to the macro +xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`]. // tag reference: doc/modules/ROOT/examples/decorator_02.run.cpp :bt-name: decorator_02 @@ -52,7 +52,7 @@ the list of decorators applied to the test suite is the union of decorators spec include::partial$bt_example.adoc[] In the above example, the scope of test suite `suite1` is opened three times. This results in a test suite containing -three test cases and associated with two {decorator_label} decorators. Therefore running tests by label `"trivial"` as +three test cases and associated with two xref:{decorator_label}[`label`] decorators. Therefore running tests by label `"trivial"` as well as by label `"simple"` both result in executing all three test cases from the suite. [CAUTION] @@ -65,7 +65,7 @@ described below. [#explicit_decorator_declaration] == Explicit decorator declaration -There is another way of associating a decorator set with test units. Macro {boost_test_decorator} indicates that its set +There is another way of associating a decorator set with test units. Macro xref:{boost_test_decorator}[`BOOST_TEST_DECORATOR`] indicates that its set of decorators is to be applied to the test unit or _test case sequence_ that immediately follows the declaration. // tag reference: doc/modules/ROOT/examples/decorator_00.run.cpp @@ -74,8 +74,8 @@ of decorators is to be applied to the test unit or _test case sequence_ that imm :bt-descr: explicit decorator declaration include::partial$bt_example.adoc[] -In the above example a decorator is applied to a xref:tests_organization/test_case_generation.adoc[data-driven test case]. Macro {boost_data_test_case} cannot take the decorator set as one of its arguments, therefore -the explicit decorator declaration is used. Macro {boost_data_test_case} generates a sequence of 4 test cases. The +In the above example a decorator is applied to a xref:tests_organization/test_case_generation.adoc[data-driven test case]. Macro xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] cannot take the decorator set as one of its arguments, therefore +the explicit decorator declaration is used. Macro xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] generates a sequence of 4 test cases. The decorator set is applied to each of them. Another use case for the explicit decorator declaration is when you intend for your test program to compile also on diff --git a/doc/modules/ROOT/pages/tests_organization/enabling.adoc b/doc/modules/ROOT/pages/tests_organization/enabling.adoc index cd357a7fdb..b740c9eace 100644 --- a/doc/modules/ROOT/pages/tests_organization/enabling.adoc +++ b/doc/modules/ROOT/pages/tests_organization/enabling.adoc @@ -1,7 +1,7 @@ = Enabling or disabling test unit execution :page-aliases: boost_test/tests_organization/enabling.adoc -The {utf} provides a way for enabling or disabling a test unit execution. If a test case is disabled, it will not be +The _Unit Test Framework_ provides a way for enabling or disabling a test unit execution. If a test case is disabled, it will not be run by the test runner. If a test suite is disabled, its status is inherited by the test units under its subtree, unless otherwise specified. @@ -13,14 +13,14 @@ filtering] section covers this feature in details. ==== There is a difference between a disabled test and a skipped test: -* a disabled test has a run status set to disabled, and is completely discarded by the {utf}. +* a disabled test has a run status set to disabled, and is completely discarded by the _Unit Test Framework_. ** a skipped test is a test that has a run status set to enabled, but which execution has been skipped at runtime. ==== == Unconditional run status -Decorator {decorator_disabled} indicates that the test unit's {default_run_status} is _false_. This means that that -test cases inside this test unit will not be run by default, unless otherwise specified. Decorator {decorator_enabled} +Decorator xref:{decorator_disabled}[`disabled`] indicates that the test unit's xref:{default_run_status}[_default run status_] is _false_. This means that that +test cases inside this test unit will not be run by default, unless otherwise specified. Decorator xref:{decorator_enabled}[`enabled`] indicates that the test unit's default run status is _true_. This means that that test cases inside this test unit will be run by default, unless otherwise specified. @@ -35,7 +35,7 @@ as set-up error when the test program is run. == Compilation-time run status -Decorator {decorator_enable_if} indicates that the test unit's {default_run_status} is either _true_ or _false_, +Decorator xref:{decorator_enable_if}[`enable_if`] indicates that the test unit's xref:{default_run_status}[_default run status_] is either _true_ or _false_, depending on the value of `Condition`. This means that that test cases inside this test unit will or will not be run by default. @@ -50,14 +50,14 @@ decorator `disabled()`. == Runtime run status -Decorator {decorator_precondition} associates a _predicate_ with a test unit. Before the test unit is executed, the +Decorator xref:{decorator_precondition}[`precondition`] associates a _predicate_ with a test unit. Before the test unit is executed, the predicate is evaluated with the test unit's ID passed as the argument. If it evaluates to `false`, execution of the test unit is skipped. Skipping a test suite means skipping the execution of every test unit inside. [TIP] ==== The precondition may return an cpp:boost::test_tools::assertion_result[assertion_result] instead of a boolean. - In that case, the message contained in the `assertion_result` will be printed by the {utf}. + In that case, the message contained in the `assertion_result` will be printed by the _Unit Test Framework_. ==== // tag reference: doc/modules/ROOT/examples/decorator_08.run-fail.cpp @@ -76,7 +76,7 @@ precondition is not satisfied, therefore `test4` is skipped. [NOTE] ==== -A {decorator_precondition} that evaluates to `false` does not yield an error and does not fail the attached unit test. However - the {utf} returns an error if the test tree is empty (see xref:tests_organization/test_tree_content.adoc[this section] +A xref:{decorator_precondition}[`precondition`] that evaluates to `false` does not yield an error and does not fail the attached unit test. However + the _Unit Test Framework_ returns an error if the test tree is empty (see xref:tests_organization/test_tree_content.adoc[this section] for more details). ==== diff --git a/doc/modules/ROOT/pages/tests_organization/fixtures.adoc b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc index 657ccae6f0..58500f5c52 100644 --- a/doc/modules/ROOT/pages/tests_organization/fixtures.adoc +++ b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc @@ -55,7 +55,7 @@ there are several more or less minor practical issues with this pure C++ based f * There is no place to execute a _global_ fixture, which performs _global_ setup/cleanup procedures before and after testing. -The {utf} lets you define a fixture according to xref:tests_organization/fixtures.adoc#models[several generic interfaces], +The _Unit Test Framework_ lets you define a fixture according to xref:tests_organization/fixtures.adoc#models[several generic interfaces], and thus helps you with following tasks: * define shared setup/teardown procedures for a single or group of test cases @@ -65,12 +65,12 @@ and thus helps you with following tasks: [#models] == Fixture models -Several fixture interfaces are supported by the {utf}. The choice of the interface depends +Several fixture interfaces are supported by the _Unit Test Framework_. The choice of the interface depends mainly on the usage of the fixture. === Fixture class model -The {utf} defines the generic fixture class model as follows: +The _Unit Test Framework_ defines the generic fixture class model as follows: [source,cpp] ---- @@ -92,7 +92,7 @@ of the fixture, and that will be consumed in the test cases, and check for the p Those checks are the pre-conditions for the test case to run, and the post-conditions that should be met after the test case has been running. -This is why the {utf} also supports (Boost 1.65 on) optional `setup` and/or `teardown` functions as follow: +This is why the _Unit Test Framework_ also supports (Boost 1.65 on) optional `setup` and/or `teardown` functions as follow: [source,cpp] ---- @@ -107,17 +107,17 @@ struct { [NOTE] ==== As mentioned, the declaration/implementation of the `setup` and `teardown` are optional: - the {utf} will check the existence of those and will call them adequately. However in C++98, + the _Unit Test Framework_ will check the existence of those and will call them adequately. However in C++98, it is not possible to detect those declaration in case those are inherited (it works fine for compiler supporting `auto` and `decltype`). ==== -This model is expected from fixtures used with {boost_fixture_test_case} and {boost_fixture_test_suite}. +This model is expected from fixtures used with xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`] and xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`]. === Flexible models -In addition to {boost_fixture_test_case} and {boost_fixture_test_suite} the {utf} allows to associate fixture with -test unit using the decorator {decorator_fixture}. This decorator supports additional models for declaring +In addition to xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`] and xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`] the _Unit Test Framework_ allows to associate fixture with +test unit using the decorator xref:{decorator_fixture}[`fixture`]. This decorator supports additional models for declaring the `setup` and `teardown`: * a fixture defined according to the fixture class model above @@ -141,7 +141,7 @@ void teardown() void setup() \{ BOOST_TEST_MESSAGE("set up"); } void teardown() \{ BOOST_TEST_MESSAGE("tear down"); } -For complete example of test module which uses these models please check decorator {decorator_fixture}. +For complete example of test module which uses these models please check decorator xref:{decorator_fixture}[`fixture`]. [#case] == Test case fixture @@ -149,7 +149,7 @@ For complete example of test module which uses these models please check decorat A _test case fixture_ is a fixture consumed by a test case: the fixture `setup` is called before the test case executes, and the fixture `teardown` is called after the test case finished its execution, independently from its execution state. -The {utf} provides several ways of defining fixtures for test-cases, each of which having their properties: +The _Unit Test Framework_ provides several ways of defining fixtures for test-cases, each of which having their properties: * the declaration of a fixture for a single test case, letting the test case access the members of the fixture, * the declaration of one or more fixture(s) for a single test case, without accessing the members and with a flexible interface, @@ -159,22 +159,22 @@ The {utf} provides several ways of defining fixtures for test-cases, each of whi The following two methods are available for declaring a fixture attached to one particular test case: -* the use of the macro {boost_fixture_test_case} in place of {boost_auto_test_case}, which let access to the members of the fixture -* the use of the decorator {decorator_fixture}, which does not let access to the members but enables +* the use of the macro xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`] in place of xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`], which let access to the members of the fixture +* the use of the decorator xref:{decorator_fixture}[`fixture`], which does not let access to the members but enables the definition of several fixtures for one test case. [#test_case_fixture_macro] ==== Fixture with `BOOST_FIXTURE_TEST_CASE` `BOOST_FIXTURE_TEST_CASE` serves as a test case declaration with a fixture, and is meant be used in place of -the test case declaration with {boost_auto_test_case}: +the test case declaration with xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`]: [source,cpp] ---- BOOST_FIXTURE_TEST_CASE(test_case_name, fixture_name); ---- -The only difference from the macro {boost_auto_test_case} is the presence of an extra argument `fixture_name`. +The only difference from the macro xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] is the presence of an extra argument `fixture_name`. The public and protected members of the fixture are directly accessible from the test case body. Only one fixture can be attached to a test-case footnote:[it is still possible to define a class inheriting from several fixtures, that will act as a proxy fixture.]. @@ -194,7 +194,7 @@ explains how a same fixture can be declared for a subtree under a test suite. [#test_case_fixture_decorator] ==== Fixture with `fixture` decorator -By using the decorator {decorator_fixture}, it is possible to: +By using the decorator xref:{decorator_fixture}[`fixture`], it is possible to: * attach several fixtures to a unique test case * use a flexible fixture interface (see xref:tests_organization/fixtures.adoc#models[here]) @@ -210,15 +210,15 @@ Using the decorator approach, it is not possible to access the members of the fi If all test cases in a test sub tree require the same fixture (you can group test cases in a test suite based on a fixture required) you can make another step toward an automation of a test fixture assignment. To assign the -same shared fixture for all test cases in a test suite, use the macro {boost_fixture_test_suite} in place of the -macro {boost_auto_test_suite} for automated test suite creation and registration. +same shared fixture for all test cases in a test suite, use the macro xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`] in place of the +macro xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`] for automated test suite creation and registration. [source,cpp] ---- BOOST_FIXTURE_TEST_SUITE(suite_name, fixture_name); ---- -Once again the only difference from the macro {boost_auto_test_suite} usage is the presence of +Once again the only difference from the macro xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`] usage is the presence of an extra argument - the fixture name. And now, you not only have direct access to the public and protected members of the fixture, but also do not need to refer to the fixture name in test case definition. All test cases assigned the same fixture automatically. @@ -226,14 +226,14 @@ the same fixture automatically. [TIP] ==== If necessary you can reset the fixture for a particular test case using the macro - {boost_fixture_test_case}. Similarly you can reset the fixture for a particular sub - test suite using {boost_fixture_test_suite}. + xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`]. Similarly you can reset the fixture for a particular sub + test suite using xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`]. ==== [NOTE] ==== The fixture assignment is _deep_. In other words unless reset by another - {boost_fixture_test_suite} or {boost_fixture_test_case} definition the + xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`] or xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`] definition the same fixture is assigned to all test cases of a test suite, including ones that belong to the sub test suites. ==== @@ -256,7 +256,7 @@ It is possible to define a test suite entry/exit fixture, so that the `setup` fu the test suite, prior to running any of its test cases. Similarly the `teardown` function is also called only once upon the test suite exit, after all the enclosed test cases have been run. This is facilitated by the -_decorator_ {decorator_fixture}. +_decorator_ xref:{decorator_fixture}[`fixture`]. // tag reference: doc/modules/ROOT/examples/fixture_03.run.cpp :bt-name: fixture_03 @@ -277,7 +277,7 @@ xref:tests_organization/fixtures.adoc#per_test_suite_fixture[test-suite entry/exit] fixture (executed once), where in this case the test-suite is the xref:tests_organization/master_test_suite.adoc[master test suite]. -The {utf} global fixture design is based on the +The _Unit Test Framework_ global fixture design is based on the xref:tests_organization/fixtures.adoc#models[generic test class fixture model]. The global fixture design allows any number of global fixtures to be defined in any test file that constitutes a test module. Though some initialization can be implemented in the xref:adv_scenarios/test_module_init_overview.adoc[test module initialization function], @@ -290,7 +290,7 @@ execution monitor. That means that all uncaught errors that occur during initial category. * The fixture allows you to place matching `setup`/`teardown` code in close vicinity in your test module code. * If the whole test tree is constructed automatically, the initialization function is empty and auto-generated by -the {utf}. Introducing the initialization function can be more work than using the global fixture facility, +the _Unit Test Framework_. Introducing the initialization function can be more work than using the global fixture facility, while global fixture is more to the point. * Since all fixtures follow the same generic model you can easily switch from local per test case fixtures to the global one. @@ -299,7 +299,7 @@ To define a global test module fixture you need: . to implement a class that matches the xref:tests_organization/fixtures.adoc#models[fixture model] -. and to pass the class as an argument to the macro {boost_test_global_fixture}. +. and to pass the class as an argument to the macro xref:{boost_test_global_fixture}[`BOOST_TEST_GLOBAL_FIXTURE`]. [source,cpp] ---- diff --git a/doc/modules/ROOT/pages/tests_organization/index.adoc b/doc/modules/ROOT/pages/tests_organization/index.adoc index 8766d5f2bb..07a561a82a 100644 --- a/doc/modules/ROOT/pages/tests_organization/index.adoc +++ b/doc/modules/ROOT/pages/tests_organization/index.adoc @@ -21,16 +21,16 @@ These units are the *test cases*, the *test suites* and the *fixtures*. |=== |Declaration a| -The {utf} supports several methods for declaring a xref:tests_organization/test_cases.adoc[test case]. +The _Unit Test Framework_ supports several methods for declaring a xref:tests_organization/test_cases.adoc[test case]. Test cases can be implemented using free function like syntax or based on actual free function, function object, that can be defined with or without parameters/data, or as template functions to be run against various types. |Organization a| -The {utf} provides facilities to group several test cases into xref:tests_organization/test_suite.adoc[test suites]. +The _Unit Test Framework_ provides facilities to group several test cases into xref:tests_organization/test_suite.adoc[test suites]. The test suites can be nested, and the set of test suites and test cases defines the xref:tests_organization/test_tree.adoc[test tree], where the leaves are the test cases. - Besides hierarchical structure the {utf} allows you to organize the test tree using xref:tests_organization/tests_grouping.adoc[logical grouping] + Besides hierarchical structure the _Unit Test Framework_ allows you to organize the test tree using xref:tests_organization/tests_grouping.adoc[logical grouping] and xref:tests_organization/tests_dependencies.adoc[dependencies] and provides you with controls to utilize the defined test tree organization the way you want (eg. from command line). @@ -44,6 +44,6 @@ It is possible to specify test unit _attributes_ by using xref:tests_organizatio a| When several tests shares the same set-up (environment, test data preparation, etc.), the preparation and cleanup code may be factorized in xref:tests_organization/fixtures.adoc[fixtures]. - In the {utf}, fixtures can be associated to test cases, test suites or globally to the test module. + In the _Unit Test Framework_, fixtures can be associated to test cases, test suites or globally to the test module. |=== diff --git a/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc b/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc index d1269b1ce5..8d06e4d4ba 100644 --- a/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc +++ b/doc/modules/ROOT/pages/tests_organization/master_test_suite.adoc @@ -2,7 +2,7 @@ :page-aliases: boost_test/tests_organization/test_tree/master_test_suite.adoc As defined in introduction section the master test suite is the *root* node of the test tree. Each test module built -with the {utf} always has the (unique) master test suite defined. The {utf} maintain the master test suite instance +with the _Unit Test Framework_ always has the (unique) master test suite defined. The _Unit Test Framework_ maintain the master test suite instance internally. All other test units are registered as direct or indirect children of the master test suite. [source,cpp] @@ -65,17 +65,17 @@ include::partial$bt_example.adoc[] == Naming the _Master test suite_ The master test suite is created with default name _Master Test Suite_. There are two methods two -reset the name to a different value: using the macro {boost_test_module} +reset the name to a different value: using the macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] and from within the test module initialization function. Former is used for test modules that don't have the manually implemented initialization function. Following examples illustrate these methods. // tag reference: doc/modules/ROOT/examples/example14.run.cpp :bt-name: example14 :bt-rule: run -:bt-descr: Naming master test suite using the macro {boost_test_module} +:bt-descr: Naming master test suite using the macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] include::partial$bt_example.adoc[] -If the macro {boost_test_module} is defined, the test module initialization +If the macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] is defined, the test module initialization function is *automatically generated* and the macro value becomes the name of the master test suite. The name may include spaces. @@ -85,5 +85,5 @@ macro value becomes the name of the master test suite. The name may include spac :bt-descr: Naming master test suite explicitly in the test module initialization function include::partial$bt_example.adoc[] -Without the {boost_test_main} and the {boost_test_module} flags defined, the test module initialization +Without the xref:{boost_test_main}[`BOOST_TEST_MAIN`] and the xref:{boost_test_module}[`BOOST_TEST_MODULE`] flags defined, the test module initialization function has to be manually implemented. The master test suite name can be reset at any point within this function. diff --git a/doc/modules/ROOT/pages/tests_organization/param_test.adoc b/doc/modules/ROOT/pages/tests_organization/param_test.adoc index 529f7a17ef..d8362cde01 100644 --- a/doc/modules/ROOT/pages/tests_organization/param_test.adoc +++ b/doc/modules/ROOT/pages/tests_organization/param_test.adoc @@ -25,7 +25,7 @@ void combined_test() } ---- -The {utf} presents a better solution for this problem: the unary function based test case, also referred as +The _Unit Test Framework_ presents a better solution for this problem: the unary function based test case, also referred as _parametrized test case_. The unary test function can be a free function, unary functor (for example created with `boost::bind`) or unary method of a class with bound test class instance). The test function is converted into test case using the macro `BOOST_PARAM_TEST_CASE`. The macro expects a collection of parameters (passed as diff --git a/doc/modules/ROOT/pages/tests_organization/semantic.adoc b/doc/modules/ROOT/pages/tests_organization/semantic.adoc index be1b01824b..391f493164 100644 --- a/doc/modules/ROOT/pages/tests_organization/semantic.adoc +++ b/doc/modules/ROOT/pages/tests_organization/semantic.adoc @@ -5,7 +5,7 @@ It is sometimes useful to add a _semantic description_ to a test unit, which may run. The user may then choose the test he/she wants to run based on this information, instead of basing his/her choice on the test unit _name_, or instead of looking at the code. -The {utf} provides the decorator {decorator_description} for that purpose. +The _Unit Test Framework_ provides the decorator xref:{decorator_description}[`description`] for that purpose. Decorator `description` attaches an arbitrary string to the test unit. All strings attached to test units can be displayed when running a test program with parameter xref:utf_reference/rt_param_reference.adoc#list_content[`list_content`]. diff --git a/doc/modules/ROOT/pages/tests_organization/summary.adoc b/doc/modules/ROOT/pages/tests_organization/summary.adoc index a8fbec2ee6..5a3f023739 100644 --- a/doc/modules/ROOT/pages/tests_organization/summary.adoc +++ b/doc/modules/ROOT/pages/tests_organization/summary.adoc @@ -6,52 +6,52 @@ |Macro |Short description -|{boost_test_case} / {boost_test_case_name} +|xref:{boost_test_case}[`BOOST_TEST_CASE`] / xref:{boost_test_case_name}[`BOOST_TEST_CASE_NAME`] |Manual registration of a test case -|{boost_auto_test_case} +|xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] |Automatic declaration and registration of a test case -|{boost_param_test_case} +|xref:{boost_param_test_case}[`BOOST_PARAM_TEST_CASE`] |Automatic declaration and registration of a test case with a collection of parameters -|{boost_auto_test_case_template} +|xref:{boost_auto_test_case_template}[`BOOST_AUTO_TEST_CASE_TEMPLATE`] |Automatic declaration and registration of a typed test case -|{boost_test_case_template} +|xref:{boost_test_case_template}[`BOOST_TEST_CASE_TEMPLATE`] |Registration of a typed test case with an `boost::mpl` like sequence of types -|{boost_test_case_template_function} +|xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`] |Declaration of the body of a typed test case -|{boost_data_test_case} +|xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] |Declaration of the body of a test case on datasets -|{boost_data_test_case_f} -|Same as {boost_data_test_case} with fixtures support +|xref:{boost_data_test_case_f}[`BOOST_DATA_TEST_CASE_F`] +|Same as xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] with fixtures support -|{boost_test_dataset_max_arity} -|Controlling the maximal arity of the data test case declared with {boost_data_test_case} +|xref:{boost_test_dataset_max_arity}[`BOOST_TEST_DATASET_MAX_ARITY`] +|Controlling the maximal arity of the data test case declared with xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] -|{boost_test_suite} +|xref:{boost_test_suite}[`BOOST_TEST_SUITE`] |Manual creation of a test suite instance -|{boost_auto_test_suite} +|xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`] |Automatic declaration of a test suite -|{boost_auto_test_suite_end} +|xref:{boost_auto_test_suite_end}[`BOOST_AUTO_TEST_SUITE_END`] |Automatic declaration of a test suite -|{boost_test_decorator} +|xref:{boost_test_decorator}[`BOOST_TEST_DECORATOR`] |Adds decorators to a test unit -|{boost_fixture_test_case} +|xref:{boost_fixture_test_case}[`BOOST_FIXTURE_TEST_CASE`] |Declares a test case with a fixture -|{boost_fixture_test_suite} +|xref:{boost_fixture_test_suite}[`BOOST_FIXTURE_TEST_SUITE`] |Declares a fixture for a test suite (the setup/teardown is called for each test of the test suite) -|{boost_test_global_fixture} +|xref:{boost_test_global_fixture}[`BOOST_TEST_GLOBAL_FIXTURE`] |Declares a fixture globally to the test module |=== @@ -61,25 +61,25 @@ |Decorator |Short description -|{decorator_depends_on} -|Creates a dependency (in the execution order and {default_run_status}) from one test case to another. +|xref:{decorator_depends_on}[`depends_on`] +|Creates a dependency (in the execution order and xref:{default_run_status}[_default run status_]) from one test case to another. -|{decorator_description} +|xref:{decorator_description}[`description`] |Attaches a semantic string to a test unit, that is visible from the command line interface. -|{decorator_enabled} , {decorator_disabled} +|xref:{decorator_enabled}[`enabled`] , xref:{decorator_disabled}[`disabled`] |Enables or disables unconditionally a test unit. The action of these decorators may be overridden by the command line interface -|{decorator_enable_if} +|xref:{decorator_enable_if}[`enable_if`] |Enables conditionally a test unit. The action of these decorators may be overridden by the command line interface -|{decorator_fixture} +|xref:{decorator_fixture}[`fixture`] |Attaches a fixture to a test unit -|{decorator_label} +|xref:{decorator_label}[`label`] |Labels a test unit to form a logical group -|{decorator_precondition} +|xref:{decorator_precondition}[`precondition`] |Enables or disables a test unit based on a predicate evaluated just before the execution of the test case. |=== diff --git a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc index 79a861a427..2cd222b0f5 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc @@ -24,8 +24,8 @@ void combined_test() The approach above has several drawbacks: * the logic for running the tests is inside a test itself: `single_test` in the above example is run from the test -case `combined_test` while its execution would be better handled by the {utf} -* in case of fatal failure for one of the values in `param` array above (say a failure in {boost_test_require}), +case `combined_test` while its execution would be better handled by the _Unit Test Framework_ +* in case of fatal failure for one of the values in `param` array above (say a failure in xref:{boost_test_require}[`BOOST_TEST_REQUIRE`]), the test `combined_test` is aborted and the next test-case in the test tree is executed. * in case of failure, the reporting is not accurate enough: the test should certainly be reran during debugging sessions by a human or additional logic for reporting should be implemented in the test itself. @@ -82,18 +82,18 @@ Indeed, the parametrized test may test for some points around (0,1), but will fa == Data driven tests in the Boost.Test framework -The facilities provided by the {utf} addressed the issues described above: +The facilities provided by the _Unit Test Framework_ addressed the issues described above: * the notion of *datasets* eases the description of the class of inputs for test cases. The datasets also implement several operations that enable their combinations to create new, more complex datasets, -* two macros, {boost_data_test_case} and {boost_data_test_case_f}, respectively without and with fixture support, +* two macros, xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] and xref:{boost_data_test_case_f}[`BOOST_DATA_TEST_CASE_F`], respectively without and with fixture support, are used for the declaration and registration of a test case over a collection of values (samples), * each test case, associated to a unique value, is executed independently from others. These tests are guarded in the same way regular test cases are, which makes the execution of the tests over each sample of a dataset isolated, robust, repeatable and ease the debugging, -* several datasets generating functions are provided by the {utf} +* several datasets generating functions are provided by the _Unit Test Framework_ -The remainder of this section covers the notions and feature provided by the {utf} about the data-driven test cases, in +The remainder of this section covers the notions and feature provided by the _Unit Test Framework_ about the data-driven test cases, in particular: . the notion of xref:tests_organization/test_case_generation.adoc#datasets[*dataset* and *sample*] is introduced @@ -117,7 +117,7 @@ A *dataset* is a _collection of samples_, that Hence the dataset implements the notion of _sequence_. -The descriptive power of the datasets in {utf} comes from +The descriptive power of the datasets in _Unit Test Framework_ comes from * the xref:tests_organization/test_case_generation.adoc#dataset_interface[interface] for creating a custom datasets, which is quite simple, * the xref:tests_organization/test_case_generation.adoc#operations[operations] they provide for combining different datasets @@ -174,7 +174,7 @@ To overcome this, a *delayed* dataset instantiation interface has been introduce which *lazyly* instantiates the dataset. To instantiate a delayed dataset, the cpp:boost::unit_test::data::monomorphic::make_delayed[boost::unit_test::data::monomorphic::make_delayed] function should be used in the -{boost_data_test_case} call. The following snippet: +xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] call. The following snippet: [source,cpp] ---- @@ -202,7 +202,7 @@ See the class cpp:boost::unit_test::data::monomorphic::delayed_dataset[`monomorp [#datasets_auto_registration] == Declaring and registering test cases with datasets -In order to declare and register a data-driven test-case, the macros {boost_data_test_case} or {boost_data_test_case_f} +In order to declare and register a data-driven test-case, the macros xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] or xref:{boost_data_test_case_f}[`BOOST_DATA_TEST_CASE_F`] should be used. Those two forms are equivalent, with the difference that `BOOST_DATA_TEST_CASE_F` supports fixtures. Those macros are variadic and can be used in the following forms: @@ -252,14 +252,14 @@ case of arity 1. ==== A compilation-time check is performed on the coherence of the arity of the dataset and the number of variables `var1`... `varN`. For compilers *without C++11* support, the maximal supported arity is controlled by the macro - {boost_test_dataset_max_arity}, that can be overridden _prior_ to including the {utf} headers. + xref:{boost_test_dataset_max_arity}[`BOOST_TEST_DATASET_MAX_ARITY`], that can be overridden _prior_ to including the _Unit Test Framework_ headers. ==== -CAUTION: The macros {boost_data_test_case} and {boost_data_test_case_f} are available only for compilers with support for *variadic macros*. +CAUTION: The macros xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] and xref:{boost_data_test_case_f}[`BOOST_DATA_TEST_CASE_F`] are available only for compilers with support for *variadic macros*. === Samples and test tree -It should be emphasized that those macros do not declare a single test case (as {boost_auto_test_case} would do) but declare and +It should be emphasized that those macros do not declare a single test case (as xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] would do) but declare and register as many test cases as there are samples in the dataset given in argument. Each test case runs on exactly *one* sample of the dataset. @@ -279,7 +279,7 @@ in the database prefixed by `+_+` and starting at index `0` ("`+_0+`", "`+_1+`", This make it easy to: * identify which sample is failing (say "`test_case_name/_3`"), -* replay the test for one or several samples (or the full dataset) from the command line using the xref:runtime_config/test_unit_filtering.adoc[test filtering features] provided by the {utf}, +* replay the test for one or several samples (or the full dataset) from the command line using the xref:runtime_config/test_unit_filtering.adoc[test filtering features] provided by the _Unit Test Framework_, * apply a xref:tests_organization/decorators.adoc#explicit_decorator_declaration[decorator] to each individual test cases of the dataset, as the decorator would apply to the test suite. @@ -293,7 +293,7 @@ This context contains the sample names and values for which the test failed, whi [#operations] == Operations on dataset -As mentioned earlier, one of the major aspects of using the {utf} datasets lies in the number of operations provided +As mentioned earlier, one of the major aspects of using the _Unit Test Framework_ datasets lies in the number of operations provided for their combination. For that purpose, three operators are provided: @@ -374,7 +374,7 @@ A particular handling is performed if `dsa` and `dsb` are of different size. The [CAUTION] ==== If the _zip_ operation is not supported for your compiler, the macro xref:utf_reference/link_references.adoc#config_no_zip_composition[`BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`] - will be automatically set by the {utf} + will be automatically set by the _Unit Test Framework_ ==== // tag reference: doc/modules/ROOT/examples/dataset_example61.run.cpp @@ -408,7 +408,7 @@ The following properties hold: [CAUTION] ==== If the _grid_ operation is not supported for your compiler, the macro xref:utf_reference/link_references.adoc#config_no_grid_composition[`BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE`] - will be automatically set by the {utf} + will be automatically set by the _Unit Test Framework_ ==== In the following example, the random number generator is the second dataset. Its state is evaluated 6 times (3 times for the first `xrange` - first dimension - @@ -424,7 +424,7 @@ include::partial$bt_example.adoc[] [#generators] == Datasets generators -Several _generators_ for datasets are implemented in {utf}: +Several _generators_ for datasets are implemented in _Unit Test Framework_: * xref:tests_organization/test_case_generation.adoc#singletons[Singletons] * xref:tests_organization/test_case_generation.adoc#stl[`forward iterable`] containers and @@ -556,7 +556,7 @@ specified. ==== The random value generator is available only for C++11 capable compilers. If this feature is not supported for your compiler, the macro xref:utf_reference/link_references.adoc#config_no_random_dataset[`BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`] - will be automatically set by the {utf} + will be automatically set by the _Unit Test Framework_ ==== It is possible to construct a random sequence using the factory cpp:boost::unit_test::data::random[boost::unit_test::data::random], available in the overloads below: diff --git a/doc/modules/ROOT/pages/tests_organization/test_cases.adoc b/doc/modules/ROOT/pages/tests_organization/test_cases.adoc index 4970c153b2..e615b70b5c 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_cases.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_cases.adoc @@ -2,13 +2,13 @@ :page-aliases: boost_test/tests_organization/test_cases.adoc A test case is a unit of execution that is run by the xref:section_glossary.adoc#test_runner[test runner]. It contains instructions and -xref:testing_tools/boost_test_universal_macro.adoc[assertions], and its execution is monitored by the {utf}. +xref:testing_tools/boost_test_universal_macro.adoc[assertions], and its execution is monitored by the _Unit Test Framework_. Information about the execution is recorded, and a log/report is produced. The test runner should be informed of the test case in order to run it: the test case should be *registered* for its inclusion into the _test tree_. -The {utf} covers the following test case scenarios: +The _Unit Test Framework_ covers the following test case scenarios: * *test cases without parameters*: those are similar to the run of a function in the controlled environment of the test runner. * *test cases with parameters*: this usage is intended to run the same function with potentially many different parameters, @@ -21,7 +21,7 @@ and register it automatically in a test tree without a necessity to perform manu == Manual registration While automatic registration is preferred test case declaration API, it is also possible to declare tests manually. -For this APIs, {utf} opted for a least intrusive design based on _generic callback_ approach, which signatures +For this APIs, _Unit Test Framework_ opted for a least intrusive design based on _generic callback_ approach, which signatures depends on the king of test case being declared. The single test module may mix both automated and manual test case @@ -31,7 +31,7 @@ implementation point. [CAUTION] ==== -The design of manual test case declaration API in {utf} assumes the test case implementation (test function body) +The design of manual test case declaration API in _Unit Test Framework_ assumes the test case implementation (test function body) and test case creation/registration points are remote. As a result you may forget to register the test case and it's never going to be executed, even though it's present in test file. ==== @@ -40,10 +40,10 @@ You need to be sure you exhausted all possible ways to employ automatic registra to use manual registration. Specifically: * If you need optionally include/exclude some of the test cases, consider using -{decorator_enabled} _ {decorator_disabled} _ {decorator_enable_if} decorators instead +xref:{decorator_enabled}[`enabled`] _ xref:{decorator_disabled}[`disabled`] _ xref:{decorator_enable_if}[`enable_if`] decorators instead * If you need to register some parametrized test cases based on some data, consider xref:tests_organization/test_case_generation.adoc[data-driven] test cases instead -* If you need to specify complicated test unit dependencies, you can use {decorator_depends_on} +* If you need to specify complicated test unit dependencies, you can use xref:{decorator_depends_on}[`depends_on`] decorator instead * if you need to share the logic between the test units consider using xref:tests_organization/fixtures.adoc[fixtures] instead diff --git a/doc/modules/ROOT/pages/tests_organization/test_naming.adoc b/doc/modules/ROOT/pages/tests_organization/test_naming.adoc index 006c2f418a..8fc2f6c7bc 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_naming.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_naming.adoc @@ -3,10 +3,10 @@ == Acceptable characters for names -The {utf} is flexible on the naming the test units (test cases/suites) and +The _Unit Test Framework_ is flexible on the naming the test units (test cases/suites) and it is possible to use a wide variety of characters. However there are scenarios where the name of a test unit may collide with other features -of the {utf}. For instance: +of the _Unit Test Framework_. For instance: * a character may collide with specific command line filters for selecting a subset of the test tree. Among those characters: `'@'`, `'+'` or `'/'` @@ -15,7 +15,7 @@ more details) * a name containing a character that is reserved for the shell/terminal, such as '!', '\*' ..., may prevent the test name to be passed on the command line *as is*. -To prevent any conflicting declaration, the {utf} *sanitizes* the name given to +To prevent any conflicting declaration, the _Unit Test Framework_ *sanitizes* the name given to a test unit (case or suite), prior to adding the test to the test tree. Any conflicting character is replaced by an underscore `'_'`. @@ -29,12 +29,12 @@ NOTE: The sanitization of the test unit names has been introduced in xref:change == Constraints on test names -The {utf} considers an error if two sibling test cases have the same name. This consistency check is performed +The _Unit Test Framework_ considers an error if two sibling test cases have the same name. This consistency check is performed at runtime and is not sensitive to test filtering. For test-cases registered automatically, and within the same compilation unit, a compilation error should be raised by the compiler in case of name conflict. -For manual registration of test cases and in case of conflicts, the too {boost_test_case_name} may be used. +For manual registration of test cases and in case of conflicts, the too xref:{boost_test_case_name}[`BOOST_TEST_CASE_NAME`] may be used. The data driven tests are automatically created in an isolated test-suite and with a name that is indexed on the sample. diff --git a/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc index 26eab982b8..ee304d2240 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc @@ -1,14 +1,14 @@ = Test cases without parameters :page-aliases: boost_test/tests_organization/test_cases/test_organization_nullary.adoc -The most common scenario is that you want to write test case without any parameters. The {utf} provides you with both +The most common scenario is that you want to write test case without any parameters. The _Unit Test Framework_ provides you with both automatic and manual registration APIs to declare such test case. [#ref_BOOST_AUTO_TEST_CASE] == Automated registration To declare a test case without parameters, which is registered in place of implementation, employ the -macro {boost_auto_test_case}. +macro xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`]. [source,cpp] ---- @@ -31,20 +31,20 @@ registers the test case with the name `free_test_function` automatically. [#ref_BOOST_TEST_CASE] == Manual registration -The {utf} allows to manually create test case without parameters based on nullary free functions, nullary +The _Unit Test Framework_ allows to manually create test case without parameters based on nullary free functions, nullary function objects (including those created with `boost::bind` and nullary `boost::function` -instances). To do this, employ the macro {boost_test_case}: +instances). To do this, employ the macro xref:{boost_test_case}[`BOOST_TEST_CASE`]: [source,cpp] ---- BOOST_TEST_CASE(test_function); ---- -{boost_test_case} creates an instance of the class cpp:boost::unit_test::test_case[boost::unit_test::test_case] and returns a pointer to the +xref:{boost_test_case}[`BOOST_TEST_CASE`] creates an instance of the class cpp:boost::unit_test::test_case[boost::unit_test::test_case] and returns a pointer to the constructed instance. The test case name is deduced from the macro argument test_function. If you prefer to assign a different test case name, you have either to -* use the macro {boost_test_case_name} instead +* use the macro xref:{boost_test_case_name}[`BOOST_TEST_CASE_NAME`] instead * or use the underlying link:{base-url}/boost/test/tree/test_unit.hpp[`make_test_case`] interface instead. To register a new test case, employ the method cpp:boost::unit_test::test_suite::add[`test_suite::add`]. @@ -52,7 +52,7 @@ Both test case creation and registration are performed in the xref:adv_scenarios/test_module_init_overview.adoc[test module initialization function]. Here is the simplest example of manually registered test case. A single test case is created and registered inside -the test module initialization routine. Note that the free function name is passed by address to the macro {boost_test_case}\`. +the test module initialization routine. Note that the free function name is passed by address to the macro xref:{boost_test_case}[`BOOST_TEST_CASE`]\`. [#ref_bt_example01] // tag reference: doc/modules/ROOT/examples/example01.run.cpp @@ -63,7 +63,7 @@ include::partial$bt_example.adoc[] A test case can be implemented as a method of a class. In this case a pointer to the class instance has to be bound to the test method to create a test case. You can use the same instance of the class for multiple test -cases. The {utf} doesn't take an ownership of the class instance and you are required to manage the class +cases. The _Unit Test Framework_ doesn't take an ownership of the class instance and you are required to manage the class instance lifetime yourself. [WARNING] diff --git a/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc b/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc index fe58da963d..cce8730659 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_organization_templates.adoc @@ -28,7 +28,7 @@ There several problems/inconveniences with above approach, including: * You need to repeat function invocation manually for all the parameters you are interested in * You need two functions to implement the test -The {utf} provides a facility, the *template test case*, to create a series of +The _Unit Test Framework_ provides a facility, the *template test case*, to create a series of test cases based on a list of desired types and _nullary_ function. This facility comes with an xref:tests_organization/test_organization_templates.adoc#ref_BOOST_AUTO_TEST_CASE_TEMPLATE[automatic] and xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[manual] registration interface. @@ -45,7 +45,7 @@ the sub test case. == Template test case with automated registration A template test case, registered automatically and in place of its implementation, is declared through the macro -{boost_auto_test_case_template}: +xref:{boost_auto_test_case_template}[`BOOST_AUTO_TEST_CASE_TEMPLATE`]: [source,cpp] ---- @@ -59,10 +59,10 @@ The arguments are as follow: name of the type the test case template is instantiated with . `collection_of_types`: the collection of types to instantiate test case template with. This is an *arbitrary MPL sequence* or a sequence of types wrapped in a `std::tuple` -(since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], if supported by the compiler) +(since xref:change_log.adoc#ref_CHANGE_LOG_3_7[_Unit Test Framework_ v3.7], if supported by the compiler) The resulting name of the test is a composition of the `test_case_name` parameter and the current -type being tested. Since xref:change_log.adoc#ref_CHANGE_LOG_3_12[{utf} v3.12], the framework tries to unify +type being tested. Since xref:change_log.adoc#ref_CHANGE_LOG_3_12[_Unit Test Framework_ v3.12], the framework tries to unify the name of the resulting type across various platforms such that they are easier to reference from the xref:runtime_config/test_unit_filtering.adoc[command line filter]. @@ -74,7 +74,7 @@ include::partial$bt_example.adoc[] [WARNING] ==== -Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], the {utf} does not allow for duplicate test case name +Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[_Unit Test Framework_ v3.7], the _Unit Test Framework_ does not allow for duplicate test case name under the same test suite. As test names are derived from the types in the `collection_of_types`, this indirectly means that *having a duplicate type* in the `collection_of_types` *yields an error*. @@ -82,7 +82,7 @@ Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], the {utf} does not al [NOTE] ==== -If you prefer having the template parameter list directly in the declaration of {boost_auto_test_case_template}, +If you prefer having the template parameter list directly in the declaration of xref:{boost_auto_test_case_template}[`BOOST_AUTO_TEST_CASE_TEMPLATE`], you may use the macro http://www.boost.org/doc/libs/release/libs/utility/identity_type/doc/html/index.html[`BOOST_IDENTITY_TYPE`]. The previous example gives (note the double parenthesis around the MPL list): @@ -109,10 +109,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( To manually register template test cases, two macros should be used: -* {boost_test_case_template_function} to define the template test case body -* {boost_test_case_template} to register the test case based on the previous declaration +* xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`] to define the template test case body +* xref:{boost_test_case_template}[`BOOST_TEST_CASE_TEMPLATE`] to register the test case based on the previous declaration -The macro {boost_test_case_template_function} requires two arguments: +The macro xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`] requires two arguments: . the name of the test case template and . the name of the format type parameter @@ -130,7 +130,7 @@ BOOST_TEST_CASE_TEMPLATE_FUNCTION( test_case_name, type_name ) } ---- -The macro {boost_test_case_template_function} is intended to be used in place of nullary function template +The macro xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`] is intended to be used in place of nullary function template signature: [source,cpp] @@ -142,10 +142,10 @@ void test_case_name() } ---- -The only difference is that the {boost_test_case_template_function} makes the test case template name usable in +The only difference is that the xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`] makes the test case template name usable in the template argument list. -{boost_test_case_template} requires two arguments: +xref:{boost_test_case_template}[`BOOST_TEST_CASE_TEMPLATE`] requires two arguments: . the name of the test case template and . Boost.MPL compatible collection of types to instantiate it with. @@ -163,7 +163,7 @@ BOOST_TEST_CASE_TEMPLATE(test_case_name, collection_of_types); :bt-descr: Manually registered test case template include::partial$bt_example.adoc[] -{boost_test_case_template} creates an instance of the test case generator. When passed to the method cpp:boost::unit_test::test_suite::add[`test_suite::add`], the generator produces a separate sub test case for each type in +xref:{boost_test_case_template}[`BOOST_TEST_CASE_TEMPLATE`] creates an instance of the test case generator. When passed to the method cpp:boost::unit_test::test_suite::add[`test_suite::add`], the generator produces a separate sub test case for each type in the supplied collection of types and registers it immediately in the test suite. Each test case is based on the test case template body instantiated with a particular test type. @@ -173,7 +173,7 @@ Both test cases creation and registration is performed in the test module initia [WARNING] ==== -Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[{utf} v3.7], the {utf} does not allow for duplicate test case name +Since xref:change_log.adoc#ref_CHANGE_LOG_3_7[_Unit Test Framework_ v3.7], the _Unit Test Framework_ does not allow for duplicate test case name under the same test suite. As test names are derived from the types in the `collection_of_types`, this indirectly means that having a duplicate of types in the `collection_of_types` will yield an error. diff --git a/doc/modules/ROOT/pages/tests_organization/test_suite.adoc b/doc/modules/ROOT/pages/tests_organization/test_suite.adoc index 62d6b5694a..17a8ff689d 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_suite.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_suite.adoc @@ -4,13 +4,13 @@ If you consider test cases as leaves on the test tree, the test suite can be considered as branch and the _master test suite_ as the _root_. Unlike real trees though, our tree in many cases consists only of leaves attached directly to the root. This is common for all test cases to reside directly in the master test suite. If you do -want to construct a hierarchical test suite structure the {utf} provides both manual and automated +want to construct a hierarchical test suite structure the _Unit Test Framework_ provides both manual and automated test suite creation and registration facilities: . Test suite with automated registration . Manually registered test suite -In addition the {utf} presents a notion of the +In addition the _Unit Test Framework_ presents a notion of the xref:tests_organization/master_test_suite.adoc[Master test suite]. The most important reason to learn about this component is that it provides an ability to access command line arguments supplied to a test module. @@ -18,15 +18,15 @@ command line arguments supplied to a test module. [#ref_BOOST_AUTO_TEST_SUITE] == Automated registration -The solution the {utf} presents for automated test suite creation and registration is designed to facilitate +The solution the _Unit Test Framework_ presents for automated test suite creation and registration is designed to facilitate multiple points of definition, arbitrary test suites depth and smooth integration with automated test case creation and registration. This facility should significantly simplify a test tree construction process in comparison with manual explicit registration case. The implementation is based on the order of file scope variables definitions within a single compilation unit. The semantic of this facility is very similar to the namespace feature of C++, including support for test suite -extension. To start test suite use the macro {boost_auto_test_suite}. To end test suite use the macro -{boost_auto_test_suite_end}. The same test suite can be restarted multiple times inside the same test file or in a +extension. To start test suite use the macro xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`]. To end test suite use the macro +xref:{boost_auto_test_suite_end}[`BOOST_AUTO_TEST_SUITE_END`]. The same test suite can be restarted multiple times inside the same test file or in a different test files. In a result all test units will be part of the same test suite in a constructed test tree. [source,cpp] @@ -71,7 +71,7 @@ To create a test suite manually you need to [#ref_test_case_registration] === Test unit registration interface -The {utf} models the notion of test case container - test suite - using class cpp:boost::unit_test::test_suite[boost::unit_test::test_suite]. For +The _Unit Test Framework_ models the notion of test case container - test suite - using class cpp:boost::unit_test::test_suite[boost::unit_test::test_suite]. For complete class interface reference check advanced section of this documentation. Here you should only be interested in a single test unit registration interface: @@ -86,12 +86,12 @@ default no errors are expected. [CAUTION] ==== -Be careful when supplying a number of expected failures for test suites. By default the {utf} calculates the +Be careful when supplying a number of expected failures for test suites. By default the _Unit Test Framework_ calculates the number of expected failures in test suite as the sum of appropriate values in all test units that constitute it. And it rarely makes sense to change this. ==== -The third optional parameter - `timeout` - defines the timeout value for the test unit. As of now the {utf} +The third optional parameter - `timeout` - defines the timeout value for the test unit. As of now the _Unit Test Framework_ isn't able to set a timeout for the test suite execution, so this parameter makes sense only for test case registration. By default no timeout is set. See the method cpp:boost::unit_test::test_suite::add[boost::unit_test::test_suite::add] for more details about the timeout value. @@ -102,7 +102,7 @@ cpp:boost::unit_test::test_suite::add[`add`] interface covered in the advanced s [#ref_BOOST_TEST_SUITE] === Test suite instance construction -To create a test suite instance manually, employ the macro {boost_test_suite}. It hides all implementation +To create a test suite instance manually, employ the macro xref:{boost_test_suite}[`BOOST_TEST_SUITE`]. It hides all implementation details and you only required to specify the test suite name: [source,cpp] @@ -110,7 +110,7 @@ details and you only required to specify the test suite name: BOOST_TEST_SUITE(test_suite_name); ---- -{boost_test_suite} creates an instance of the class `boost::unit_test::test_suite` and returns a pointer to the +xref:{boost_test_suite}[`BOOST_TEST_SUITE`] creates an instance of the class `boost::unit_test::test_suite` and returns a pointer to the constructed instance. Alternatively you can create an instance of class `boost::unit_test::test_suite` yourself. [CAUTION] diff --git a/doc/modules/ROOT/pages/tests_organization/test_tree.adoc b/doc/modules/ROOT/pages/tests_organization/test_tree.adoc index 014dec8d23..3a8c92bca0 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_tree.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_tree.adoc @@ -20,7 +20,7 @@ section) *without* any fixture: image::class-hier.jpg[] xref:tests_organization/decorators.adoc[Decoration] can be added to test suites and cases except for the master test suite. Those -decoration may modify the way the {utf} +decoration may modify the way the _Unit Test Framework_ handles the tree. For instance, there is no defined order in the execution of test cases enforced by the tree itself, except for the fixtures and the elements they relate to (suite, case); decoration may be used to instruct a specific order among the elements of the tree. diff --git a/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc b/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc index cb9a731340..8e5cd9e20d 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_tree_content.adoc @@ -1,7 +1,7 @@ = Test tree content :page-aliases: boost_test/tests_organization/test_tree/test_tree_content.adoc -The test module, and hence the test tree, should have at least one test-case scheduled for execution, otherwise the {utf} +The test module, and hence the test tree, should have at least one test-case scheduled for execution, otherwise the _Unit Test Framework_ returns an error. This check is performed *after* the filtering of the tests has occurred. The sections about diff --git a/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc b/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc index 518f4889f4..093cfe6051 100644 --- a/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc +++ b/doc/modules/ROOT/pages/tests_organization/tests_dependencies.adoc @@ -6,7 +6,7 @@ cases where a dependency cannot be avoided and an order for executing the tests In the general setup and for any two test cases `TA` and `TB`, `TB` should not take for granted that `TA` has already executed, even if `TA` is declared before `TB` in the same translation unit. -The only ordering-related guarantee that {utf} makes by default is that if test cases `TA` and `TB` are declared in the +The only ordering-related guarantee that _Unit Test Framework_ makes by default is that if test cases `TA` and `TB` are declared in the same test suite, no test case (call it `TX`) from any other test suite is executed between `TA` and `TB`, even if the declaration of `TX` appears between the declarations of `TA` and `TB`. In other words, all tests from a suite are executed in one go, even if the test suite namespace is opened multiple times. @@ -20,12 +20,12 @@ robust against an erroneous implicit ordering. If there exist a dependency between test units, and an ordering is required between the execution of those tests, it has to be declared explicitly. -Dependencies in the {utf} affect two dimensions of test units, which are: +Dependencies in the _Unit Test Framework_ affect two dimensions of test units, which are: * the order of execution of these units * the execution of a test unit, which is conditioned by the state of its parents -xref:tests_organization/decorators.adoc[Decorator] {decorator_depends_on} associates the decorated test case +xref:tests_organization/decorators.adoc[Decorator] xref:{decorator_depends_on}[`depends_on`] associates the decorated test case (call it `TB`) with another test case (call it `TA`) specified by name. This affects the processing the test tree in two ways: diff --git a/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc b/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc index 491da951f8..4a6b865625 100644 --- a/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc +++ b/doc/modules/ROOT/pages/tests_organization/tests_grouping.adoc @@ -9,8 +9,8 @@ test only (covered in xref:runtime_config/test_unit_filtering.adoc[this section] However, the subtrees might not reflect all the possible grouping of test units the usage of the test module would require footnote:[For instance, selecting two siblings without the parent node]. -The {utf} provides a flexible way of grouping test units by the use of _labels_, using the decorator -{decorator_label}. It is possible to associate more than one label with a test unit. +The _Unit Test Framework_ provides a flexible way of grouping test units by the use of _labels_, using the decorator +xref:{decorator_label}[`label`]. It is possible to associate more than one label with a test unit. Labels can be associated to test cases and test suites. For the latter, the label is inherited by all the nodes in the subtree defined by the labelled test suite: decorating a test suite with label `L` is equivalent to decorating every test diff --git a/doc/modules/ROOT/pages/usage_recommendations/hello.adoc b/doc/modules/ROOT/pages/usage_recommendations/hello.adoc index e1105cd40b..d59b415ba7 100644 --- a/doc/modules/ROOT/pages/usage_recommendations/hello.adoc +++ b/doc/modules/ROOT/pages/usage_recommendations/hello.adoc @@ -47,7 +47,7 @@ There are several issues with above test. . Would exception happen in test_object construction of method `is_valid` invocation, the program will crash. . You won't see any output, would you run this test manually. -The {utf} solves all these issues. To integrate with it above program needs to be changed to: +The _Unit Test Framework_ solves all these issues. To integrate with it above program needs to be changed to: [source,cpp] ---- @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE( my_test ) ---- Now, you not only receive uniform result code, even in case of exception, but also nicely formatted output from -{boost_test} tool, would you choose to see it. Is there any other ways to perform checks? The following example test +xref:{boost_test}[`BOOST_TEST`] tool, would you choose to see it. Is there any other ways to perform checks? The following example test program shows several different ways to detect and report an error in the `add()` function. [source,cpp] diff --git a/doc/modules/ROOT/pages/usage_recommendations/index.adoc b/doc/modules/ROOT/pages/usage_recommendations/index.adoc index 55caf60dcb..bd26fb748d 100644 --- a/doc/modules/ROOT/pages/usage_recommendations/index.adoc +++ b/doc/modules/ROOT/pages/usage_recommendations/index.adoc @@ -2,7 +2,7 @@ :page-aliases: boost_test/usage_recommendations.adoc [#ref_usage_recommendations] -Following pages present tips and recommendations on how to use and apply the {utf} in your real life practice. +Following pages present tips and recommendations on how to use and apply the _Unit Test Framework_ in your real life practice. You don't necessarily need to follow them, but we found them handy. Here you will also find some tutorials from Boost.Test authors and world wide. @@ -26,7 +26,7 @@ It's really easy to switch to automatic registration. And you don't need to worr In some cases you are reusing the same template based code from within one test case (actually we recommend better solution in such case - see below). Now if an error gets reported by the test tool within that reused code you may have difficulty locating were exactly error occurred. To address this issue you could either a add -{boost_test_message} statements in templated code that log current type id of template parameters or you can use special hook located in +xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] statements in templated code that log current type id of template parameters or you can use special hook located in `unit_test_result.hpp` called `first_failed_assertion()`. If you set a breakpoint right on the line where this function is defined you will be able to unroll the stack and see where error actually occurred. diff --git a/doc/modules/ROOT/pages/usage_variants.adoc b/doc/modules/ROOT/pages/usage_variants.adoc index 67f8552e32..e1e32fa062 100644 --- a/doc/modules/ROOT/pages/usage_variants.adoc +++ b/doc/modules/ROOT/pages/usage_variants.adoc @@ -1,7 +1,7 @@ = Usage variants :page-aliases: boost_test/usage_variants.adoc -The {utf} supports three different usage variants: +The _Unit Test Framework_ supports three different usage variants: . xref:usage_variants.adoc#single_header[The header-only variant] . xref:usage_variants.adoc#static_lib[The static library variant] @@ -14,7 +14,7 @@ clear reasons why would you prefer each one. Following sections should help you == Header-only usage variant If you prefer to avoid the compilation of standalone library, you should use the -header-only variant of the {utf}. This variant only requires you to include +header-only variant of the _Unit Test Framework_. This variant only requires you to include the unique header: `+#include +` and there is no need to link with any library. There are several ways to perform the initialization, but the simplest way is the following: @@ -25,7 +25,7 @@ the initialization, but the simplest way is the following: #include /* path is different than the other variants! */ ---- -{boost_test_module} macro needs to be defined *before* the include and should indicate +xref:{boost_test_module}[`BOOST_TEST_MODULE`] macro needs to be defined *before* the include and should indicate the name of the test module. This name can include spaces and does not need to be wrapped in quotes. xref:adv_scenarios/single_header_customizations.adoc[This section] @@ -37,47 +37,47 @@ xref:adv_scenarios/single_header_customizations.adoc#multiple_translation_units[ == Static library usage variant For most users, who has an access to pre-built static library footnote:[these files are distributed -with the packaging systems on Linux and OSX for instance] of the {utf} or can +with the packaging systems on Linux and OSX for instance] of the _Unit Test Framework_ or can xref:adv_scenarios/build_utf.adoc[build it] themselves, following usage can be most versatile and simple approach. This usage variant entails two steps. . First, the following line needs to be added to all translation units in the test module: `+#include +` One and *only one* translation unit should include following lines: -`+#define {boost_test_module} test module name +`+#define BOOST_TEST_MODULE test module name #include +` -{boost_test_module} macro needs to be defined *before* the include and should indicate the +xref:{boost_test_module}[`BOOST_TEST_MODULE`] macro needs to be defined *before* the include and should indicate the name of the test module. This name can include spaces and does not need to be wrapped in quotes. -. The second step is to link with the {utf} *static* library. +. The second step is to link with the _Unit Test Framework_ *static* library. NOTE: Header `` is an _aggregate_ header: it includes most of the other headers that contains the Unit Test Framework definitions. The flip side of this usage variant is that each test module following this usage variant is going -to be statically linked with {utf}, which might be something you want to avoid (to save space +to be statically linked with _Unit Test Framework_, which might be something you want to avoid (to save space for example). For more information about these configuration options check xref:adv_scenarios/static_lib_customizations.adoc[this section]. [#shared_lib] == Shared library usage variant -In the project with large number of test modules the static library variant of the {utf} may +In the project with large number of test modules the static library variant of the _Unit Test Framework_ may cause you to waste a lot of disk space. The solution is to link test module dynamically with the -{utf} built as a shared library. +_Unit Test Framework_ built as a shared library. This usage variant entails two steps. . First you need to add following lines to all translation units in a test module: -`+#define {boost_test_dyn_link} +`+#define BOOST_TEST_DYN_LINK #include +` and *only one* translation unit should include following lines -`+#define {boost_test_module} test module name -#define {boost_test_dyn_link} +`+#define BOOST_TEST_MODULE test module name +#define BOOST_TEST_DYN_LINK #include +` `BOOST_TEST_MODULE` and `BOOST_TEST_DYN_LINK` macros needs to be defined *before* the include. `BOOST_TEST_MODULE` should be set to test module name. This name can include spaces and does not need to be wrapped in quotes. -. The second step is to link with the {utf} *shared* library. +. The second step is to link with the _Unit Test Framework_ *shared* library. -The flip side of this usage variant is that you will need to make sure the {utf} shared library +The flip side of this usage variant is that you will need to make sure the _Unit Test Framework_ shared library is accessible at runtime to a test module. In addition shared library usage variant facilitates custom test runners. For more information about this @@ -85,7 +85,7 @@ check xref:adv_scenarios/shared_lib_customizations.adoc[this section]. [CAUTION] ==== -On Windows, the test module and the {utf} shared library should link to the same CRT. Not doing - so (for instance {utf} shared library in _release_ mode while the test module is in _debug_) will +On Windows, the test module and the _Unit Test Framework_ shared library should link to the same CRT. Not doing + so (for instance _Unit Test Framework_ shared library in _release_ mode while the test module is in _debug_) will lead to crashes. ==== diff --git a/doc/modules/ROOT/pages/utf_reference/index.adoc b/doc/modules/ROOT/pages/utf_reference/index.adoc index 30c29e5e9b..f6af2cd783 100644 --- a/doc/modules/ROOT/pages/utf_reference/index.adoc +++ b/doc/modules/ROOT/pages/utf_reference/index.adoc @@ -1,4 +1,40 @@ -= {utf} API reference += _Unit Test Framework_ API reference :page-aliases: boost_test/utf_reference.adoc -// The Doxygen-generated reference is replaced by the MrDocs `reference` module. +The reference has two halves. + +The pages below document the macros and the command-line parameters, which is +what most test code is written against. They are maintained by hand: the macros +carry no documentation comments in the sources, so no generator can produce +them. + +* xref:utf_reference/test_org_reference.adoc[] -- declaring test cases, test + suites and fixtures, and the decorators that annotate them +* xref:utf_reference/testing_tool_ref.adoc[] -- the assertion macros +* xref:utf_reference/testout_reference.adoc[] -- controlling what a test + reports +* xref:utf_reference/rt_param_reference.adoc[] -- one section per runtime + parameter, with its command-line syntax and environment variable +* xref:utf_reference/link_references.adoc[] -- the macros that select a build + variant and the behaviours they switch on + +The C++ API -- classes, functions and types -- is generated from the headers by +https://www.mrdocs.com[MrDocs] and lives in +xref:reference:index.adoc[the reference module]: + +* xref:reference:boost/unit_test.adoc[`boost::unit_test`] -- the framework + itself: the test tree, the runner, logging and reporting +* xref:reference:boost/unit_test/data.adoc[`boost::unit_test::data`] -- datasets + for data-driven test cases +* xref:reference:boost/test_tools.adoc[`boost::test_tools`] -- the types the + assertion macros are built on, such as + xref:reference:boost/test_tools/assertion_result.adoc[`assertion_result`] and + xref:reference:boost/test_tools/output_test_stream.adoc[`output_test_stream`] +* xref:reference:boost/debug.adoc[`boost::debug`] -- debugger detection and + attachment +* xref:reference:boost/execution_monitor.adoc[`boost::execution_monitor`] -- + the lower-level component that runs a function in a controlled environment + +Which headers to include for what is covered by +xref:usage_variants.adoc[the usage variants] and by +xref:adv_scenarios/index.adoc[the advanced usage scenarios]. diff --git a/doc/modules/ROOT/pages/utf_reference/link_references.adoc b/doc/modules/ROOT/pages/utf_reference/link_references.adoc index de00ae2186..3f7a59167e 100644 --- a/doc/modules/ROOT/pages/utf_reference/link_references.adoc +++ b/doc/modules/ROOT/pages/utf_reference/link_references.adoc @@ -5,28 +5,28 @@ == `BOOST_TEST_MAIN` When defined, this macro creates a stub for the test module initialization (the main entry part). This -macro also expands properly into a `main` function in case the shared library variant of the {utf} is used. +macro also expands properly into a `main` function in case the shared library variant of the _Unit Test Framework_ is used. [CAUTION] ==== This macro should -. be defined before any inclusion directive to {utf} headers +. be defined before any inclusion directive to _Unit Test Framework_ headers . be defined exactly for one compilation unit of your test module ==== -TIP: The macro {boost_test_module} should be preferred +TIP: The macro xref:{boost_test_module}[`BOOST_TEST_MODULE`] should be preferred [#link_boost_test_module_macro] == `BOOST_TEST_MODULE` -Serves the same purpose as the macro {boost_test_main} but, in addition, defines the name of the master test suite. +Serves the same purpose as the macro xref:{boost_test_main}[`BOOST_TEST_MAIN`] but, in addition, defines the name of the master test suite. [CAUTION] ==== -As {boost_test_main}, this macro should +As xref:{boost_test_main}[`BOOST_TEST_MAIN`], this macro should -. be defined before any inclusion directive to {utf} headers +. be defined before any inclusion directive to _Unit Test Framework_ headers . be defined exactly for one compilation unit of your test module ==== @@ -37,14 +37,14 @@ An example may be found xref:tests_organization/master_test_suite.adoc#ref_BOOST [WARNING] ==== -This macro should be defined before any include directive to the {utf} headers and is -mutually exclusive with the {boost_test_module} macro. +This macro should be defined before any include directive to the _Unit Test Framework_ headers and is +mutually exclusive with the xref:{boost_test_module}[`BOOST_TEST_MODULE`] macro. ==== -In case of custom initialization of the test module entry point, this macro indicates the {utf} to +In case of custom initialization of the test module entry point, this macro indicates the _Unit Test Framework_ to use the new API. The differences between the new and old APIs are described in xref:adv_scenarios/obsolete_init_func.adoc[this section]. -The way to customize the entry point of the test-module depends on the variant of the {utf} in use. +The way to customize the entry point of the test-module depends on the variant of the _Unit Test Framework_ in use. Several sections in the documentation are devoted to this: * xref:adv_scenarios/single_header_customizations.adoc#entry_point[this section] for single header variant, @@ -56,20 +56,20 @@ Several sections in the documentation are devoted to this: Define this flag to prevent auto-linking. -NOTE: The same flag is used for the {utf} and the {pem} components. +NOTE: The same flag is used for the _Unit Test Framework_ and the _Program Execution Monitor_ components. [#link_boost_test_dyn_link] == `BOOST_TEST_DYN_LINK` -Define this flag to link against the {utf} shared library. +Define this flag to link against the _Unit Test Framework_ shared library. -NOTE: The same flag is used for the {utf} and the {pem} components. +NOTE: The same flag is used for the _Unit Test Framework_ and the _Program Execution Monitor_ components. [#link_boost_test_no_main] == `BOOST_TEST_NO_MAIN` Prevents the auto generation of the test module initialization functions. This macro is particularly relevant for -manually registered tests in conjunction with dynamic variant of the {utf}. When defined, a `main` function +manually registered tests in conjunction with dynamic variant of the _Unit Test Framework_. When defined, a `main` function registering all the tests should be implemented. An example of a module initialization would be @@ -121,9 +121,9 @@ No logging or any other call to the framework assertion is allowed in the constr Disables the support of the alternative stack. -Define this macro before the inclusion of any {utf} header to disable the support +Define this macro before the inclusion of any _Unit Test Framework_ header to disable the support of the http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html[alternative stack], -in case your compiler does not support it and the {utf} cannot automatically guess the lack of support. +in case your compiler does not support it and the _Unit Test Framework_ cannot automatically guess the lack of support. See xref:utf_reference/rt_param_reference.adoc#use_alt_stack[`use_alt_stack`] and xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`] for more details. diff --git a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc index 49739c7447..de763c4067 100644 --- a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc @@ -1,7 +1,7 @@ = Runtime parameters reference :page-aliases: boost_test/utf_reference/rt_param_reference.adoc -Following sections provide detailed specification for all {utf} runtime parameters. Each parameter specification includes: +Following sections provide detailed specification for all _Unit Test Framework_ runtime parameters. Each parameter specification includes: * The full parameter name. * Description of parameter semantic and default value. @@ -42,7 +42,7 @@ prefix. For example, try == Parameter value formats -The {utf} runtime parameters take value of the following types: string, boolean, enumeration, +The _Unit Test Framework_ runtime parameters take value of the following types: string, boolean, enumeration, unsigned, long. Formats required for values of these types are following: === String, unsigned, long @@ -89,7 +89,7 @@ BOOST_TEST_AUTO_START_DBG [#build_info] == `build_info` -Option _build_info_ instructs the {utf} to display the build information before testing begins. +Option _build_info_ instructs the _Unit Test Framework_ to display the build information before testing begins. This information includes: * platform @@ -113,14 +113,14 @@ BOOST_TEST_BUILD_INFO [#catch_system] == `catch_system_errors` -If option _catch_system_errors_ has value "no" the {utf} does not attempt to catch asynchronous system failures +If option _catch_system_errors_ has value "no" the _Unit Test Framework_ does not attempt to catch asynchronous system failures (signals on *NIX platforms or structured exceptions on Windows). This can be used for test programs executed within an IDE or to get a coredump for a stack analysis. See xref:usage_recommendations/index.adoc#ref_usage_recommendations[usage recommendations] pages for more details. [NOTE] ==== -If the {utf} detects that the current process is being run under a debugger, the `catch_system_errors` is +If the _Unit Test Framework_ detects that the current process is being run under a debugger, the `catch_system_errors` is automatically disabled. ==== @@ -128,7 +128,7 @@ If the {utf} detects that the current process is being run under a debugger, the xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with default value *no*. -NOTE: The {utf} can be built with flag `BOOST_TEST_DEFAULTS_TO_CORE_DUMP` in which case default changes to *yes* +NOTE: The _Unit Test Framework_ can be built with flag `BOOST_TEST_DEFAULTS_TO_CORE_DUMP` in which case default changes to *yes* === Command line syntax @@ -142,7 +142,7 @@ BOOST_TEST_CATCH_SYSTEM_ERRORS [#color_output] == `color_output` -The {utf} is able to produce color output on systems which support it. To disable this behavior, set this option to +The _Unit Test Framework_ is able to produce color output on systems which support it. To disable this behavior, set this option to `no`. By default the framework produces color output. === Acceptable values @@ -244,7 +244,7 @@ testsuite1* represents test module consisting of two test suites: `testsuite1` and `testsuite2`, and three test cases: `testcase1`, `testcase2`, and `testcase3`. The formatting reflects the test-tree: the first two test cases belong to the first test suite and last one belongs to the second. Out of three test cases only two are enabled by default: -`testcase1` and `testcase3`. `testcase2` is not enabled by default, but can be enabled by using the parameter {param_run_test}. +`testcase1` and `testcase3`. `testcase2` is not enabled by default, but can be enabled by using the parameter xref:{param_run_test}[`run_test`]. === DOT @@ -330,7 +330,7 @@ Available labels: [#log_format] == `log_format` -Parameter _log_format_ allows to set the {utf} log format to one of the formats supplied by the framework. +Parameter _log_format_ allows to set the _Unit Test Framework_ log format to one of the formats supplied by the framework. To specify custom log format use the xref:test_output/logging_api.adoc#ref_log_formatter_api[custom log formatting API]. The only acceptable values for this parameter are the names of the output formats supplied by the @@ -358,7 +358,7 @@ BOOST_TEST_LOG_FORMAT [#log_level] == `log_level` -Parameter _log_level_ allows to set the {utf} xref:test_output/logging_api.adoc#ref_log_level_explanations[log level]. Log level defines +Parameter _log_level_ allows to set the _Unit Test Framework_ xref:test_output/logging_api.adoc#ref_log_level_explanations[log level]. Log level defines the verbosity of the testing log produced by a testing module. The verbosity ranges from a complete log, when all assertions (both successful and failing) are reported and all notifications about test units start and finish are included, to an empty log, when nothing is reported to a testing log stream. @@ -387,7 +387,7 @@ Thus each level includes messages on that level as well as all the messages on l |Test units start/finish notifications |message -|User generated messages (using {boost_test_message} tool) +|User generated messages (using xref:{boost_test_message}[`BOOST_TEST_MESSAGE`] tool) |warning a| @@ -397,7 +397,7 @@ Messages describing failed assertion on `WARN` level ( tools) |*error* (default for HRF and XML) -|Messages describing failed assertion on `CHECK` level ({boost_test} / `BOOST_CHECK_...` tools) +|Messages describing failed assertion on `CHECK` level (xref:{boost_test}[`BOOST_TEST`] / `BOOST_CHECK_...` tools) |cpp_exception |Messages reporting uncaught C++ exception @@ -408,7 +408,7 @@ Messages describing failed assertion on `WARN` level ( |fatal_error a| Messages reporting user or system originated fatal errors. For example, memory access violation. Also - all the messages describing failed assertion on `REQUIRE` level ({boost_test_require} / `BOOST_REQUIRE_...` tools) + all the messages describing failed assertion on `REQUIRE` level (xref:{boost_test_require}[`BOOST_TEST_REQUIRE`] / `BOOST_REQUIRE_...` tools) |nothing |No messages are reported. @@ -547,7 +547,7 @@ BOOST_TEST_OUTPUT_FORMAT [#random] == `random` -Parameter _random_ instructs the {utf} to execute the test cases in random order. This parameter +Parameter _random_ instructs the _Unit Test Framework_ to execute the test cases in random order. This parameter accepts an optional `unsigned integer` argument for the seed of the random generator: * By default (value `0`), the test cases are executed in some specific order @@ -557,7 +557,7 @@ defined by the order of test units in the test files, and the dependencies betwe [TIP] ==== -in case `--random` is specified, the value of the seed is logged using {boost_test_message}, so that it is possible to replay +in case `--random` is specified, the value of the seed is logged using xref:{boost_test_message}[`BOOST_TEST_MESSAGE`], so that it is possible to replay exactly the same sequence of unit test in case of failure. For the seed to be visible in the logs, make sure the proper xref:utf_reference/rt_param_reference.adoc#log_level[`--log_level`] is set. ==== @@ -579,7 +579,7 @@ BOOST_TEST_RANDOM [#report_format] == `report_format` -Parameter _report_format_ allows to set the {utf} report format to one of the formats supplied +Parameter _report_format_ allows to set the _Unit Test Framework_ report format to one of the formats supplied by the framework. To specify a custom report format use unit_test_report API. The only acceptable values for this parameter are the names of the output formats. By default the @@ -606,7 +606,7 @@ BOOST_TEST_REPORT_FORMAT == `report_level` Parameter _report_level_ allows to set the verbosity level of the testing result report generated by -the {utf}. Use value "no" to eliminate the results report completely. See the +the _Unit Test Framework_. Use value "no" to eliminate the results report completely. See the xref:test_output/report_formats.adoc#ref_report_formats[report formats] section for description of report formats on different levels. === Acceptable values @@ -673,7 +673,7 @@ BOOST_TEST_REPORT_SINK [#result_code] == `result_code` -The "no" argument value for the option \`result_code instructs the {utf} to always return zero +The "no" argument value for the option \`result_code instructs the _Unit Test Framework_ to always return zero result code. This could be used for test programs executed within IDE. By default this parameter has value "yes". See the xref:usage_recommendations/index.adoc#ref_usage_recommendations[usage recommendations] section for more details. @@ -693,9 +693,9 @@ BOOST_TEST_RESULT_CODE [#run_test] == `run_test` -Parameter _run_test_ allows to filter which test units to execute during testing. The {utf} supports +Parameter _run_test_ allows to filter which test units to execute during testing. The _Unit Test Framework_ supports both "selection filters", which allow to select which test units to enable from the set of available -test units, and "disabler filters", which allow to disable some test units. The {utf} also supports +test units, and "disabler filters", which allow to disable some test units. The _Unit Test Framework_ also supports enabling/disabling test units at compile time. These settings identify the default set of test units to run. Parameter _run_test_ is used to change this default. This parameter is repeatable, so you can specify more than one filter if necessary. @@ -745,7 +745,7 @@ BOOST_TEST_RUN_FILTERS [#save_pattern] == `save_pattern` -Option _save_pattern_ facilitates switching mode of operation for testing output streams. See {output_test_stream_tool} +Option _save_pattern_ facilitates switching mode of operation for testing output streams. See xref:{output_test_stream_tool}[output test stream] section for details on these tests. This parameter serves no particular purpose within the framework itself. It can be used by test modules relying @@ -779,7 +779,7 @@ BOOST_TEST_SAVE_PATTERN [#show_progress] == `show_progress` -Option _show_progress_ instructs the {utf} to display test progress information. By default the +Option _show_progress_ instructs the _Unit Test Framework_ to display test progress information. By default the parameter test progress is not shown. More details xref:test_output/test_output_progress.adoc[here]. === Acceptable values @@ -798,7 +798,7 @@ BOOST_TEST_SHOW_PROGRESS [#use_alt_stack] == `use_alt_stack` -Option _use_alt_stack_ instructs the {utf} to use alternative stack for signals processing, on +Option _use_alt_stack_ instructs the _Unit Test Framework_ to use alternative stack for signals processing, on platforms where they are supported. More information about this feature is available http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html[here]. The feature is enabled by default, but can be disabled using this parameter. @@ -826,7 +826,7 @@ BOOST_TEST_USE_ALT_STACK [#usage] == `usage` -If specified option _usage_ instructs the {utf} to displays short usage message about the +If specified option _usage_ instructs the _Unit Test Framework_ to displays short usage message about the framework's parameters. === Command line syntax @@ -842,7 +842,7 @@ xref:utf_reference/rt_param_reference.adoc#boolean_param_value[Boolean] with def [#wait_for_debugger] == `wait_for_debugger` -Option _wait_for_debugger_ instructs the {utf} to pause before starting test units execution, +Option _wait_for_debugger_ instructs the _Unit Test Framework_ to pause before starting test units execution, so that you can attach a debugger to running test module. By default this parameters turned off. === Acceptable values diff --git a/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc index ba78ef9ed0..1bd2e12a5d 100644 --- a/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc @@ -25,7 +25,7 @@ See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_AUTO_TEST [#test_org_boost_test_case_template] == `BOOST_TEST_CASE_TEMPLATE` -Creates a typed test case. The test case should have been declared with the macro {boost_test_case_template_function}. +Creates a typed test case. The test case should have been declared with the macro xref:{boost_test_case_template_function}[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`]. The registration in the test tree should be performed manually. See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[here] for more details. @@ -34,7 +34,7 @@ See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE == `BOOST_TEST_CASE_TEMPLATE_FUNCTION` Declares a typed test case. The registration in the test tree should be performed manually, using the macro -{boost_test_case_template}. +xref:{boost_test_case_template}[`BOOST_TEST_CASE_TEMPLATE`]. See xref:tests_organization/test_organization_templates.adoc#ref_BOOST_TEST_CASE_TEMPLATE[here] for more details. @@ -86,7 +86,7 @@ same as the second form, but for dataset of arity `N`. For compilers *lacking the variadic template* support, the maximal arity (the maximal value of `N`) is controlled by the macro `BOOST_TEST_DATASET_MAX_ARITY` which is set to `10` by default. If you need a greater value, define `BOOST_TEST_DATASET_MAX_ARITY` -to the desired value *before* including the {utf} headers. +to the desired value *before* including the _Unit Test Framework_ headers. See xref:tests_organization/test_case_generation.adoc#datasets_auto_registration[here] for more details. @@ -94,7 +94,7 @@ See xref:tests_organization/test_case_generation.adoc#datasets_auto_registration == `BOOST_DATA_TEST_CASE_F` Declares and registers a data-driven test case, using a particular dataset and a fixture. This is basically the same as -{boost_data_test_case} with fixture support added. +xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] with fixture support added. [source,cpp] ---- @@ -137,7 +137,7 @@ See xref:tests_organization/test_suite.adoc#ref_BOOST_AUTO_TEST_SUITE[here] for == `BOOST_AUTO_TEST_SUITE_END` Indicates the end of a test suite. Test suites can be nested. This macro should appear as many times as there is a -{boost_auto_test_suite}. +xref:{boost_auto_test_suite}[`BOOST_AUTO_TEST_SUITE`]. See xref:tests_organization/test_suite.adoc#ref_BOOST_AUTO_TEST_SUITE[here] for more details. @@ -163,7 +163,7 @@ See xref:tests_organization/fixtures.adoc#case[here] for more details. [#test_org_boost_global_fixture] == `BOOST_GLOBAL_FIXTURE` -This macro is deprecated in favor of {boost_test_global_fixture} and {boost_test_global_configuration}. +This macro is deprecated in favor of xref:{boost_test_global_fixture}[`BOOST_TEST_GLOBAL_FIXTURE`] and xref:{boost_test_global_configuration}[`BOOST_TEST_GLOBAL_CONFIGURATION`]. [#test_org_boost_test_global_fixture] == `BOOST_TEST_GLOBAL_FIXTURE` @@ -215,7 +215,7 @@ enabled(); disabled(); ---- -Sets the test unit's {default_run_status} to _true_ or _false_. +Sets the test unit's xref:{default_run_status}[_default run status_] to _true_ or _false_. See xref:tests_organization/enabling.adoc[here] for more details. [#decorator_enable_if] @@ -226,7 +226,7 @@ See xref:tests_organization/enabling.adoc[here] for more details. template enable_if(); ---- -Sets the test unit's {default_run_status} to _true_ or _false_, depending on a compilation-time +Sets the test unit's xref:{default_run_status}[_default run status_] to _true_ or _false_, depending on a compilation-time constant. See xref:tests_organization/enabling.adoc[here] for more details. @@ -297,5 +297,5 @@ typedef boost::function<[classref boost::test_tools::assertion_result test_tools precondition(predicate_t predicate); ---- -Associates a _predicate_ with a test unit that will determine its {default_run_status} at run-time. +Associates a _predicate_ with a test unit that will determine its xref:{default_run_status}[_default run status_] at run-time. See xref:tests_organization/enabling.adoc[here] for more details. diff --git a/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc index 43ba3c8ce0..3d2fc25ed2 100644 --- a/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc +++ b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc @@ -92,7 +92,7 @@ The macro if Boost.Test is able to force the test-case to stop. ==== -NOTE: The support for test suites has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / {utf} v3.10] +NOTE: The support for test suites has been added in xref:change_log.adoc#ref_CHANGE_LOG_3_10[Boost 1.70 / _Unit Test Framework_ v3.10] [#decorator_tolerance] == tolerance (decorator) @@ -152,7 +152,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_message} +* xref:{boost_level_message}[`BOOST__MESSAGE`] [#assertion_boost_level_bitwise_eq] == `BOOST__BITWISE_EQUAL` @@ -178,7 +178,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_equal} +* xref:{boost_level_equal}[`BOOST__EQUAL`] [#assertion_boost_level_eq] == `BOOST__EQUAL` @@ -190,13 +190,13 @@ BOOST_CHECK_EQUAL(left, right); BOOST_REQUIRE_EQUAL(left, right); ---- -Check performed by these tools is the same as the one performed by `{boost_level}(left == right)`. +Check performed by these tools is the same as the one performed by `BOOST_(left == right)`. The difference is that the mismatched values are reported as well. [NOTE] ==== -It is bad idea to use these tools to compare floating point values. Use {boost_level_close} or - {boost_level_close_fraction} tools instead. +It is bad idea to use these tools to compare floating point values. Use xref:{boost_level_close}[`BOOST__CLOSE`] or + xref:{boost_level_close_fraction}[`BOOST__CLOSE_FRACTION`] tools instead. ==== // tag reference: doc/modules/ROOT/examples/example35.run-fail.cpp @@ -207,10 +207,10 @@ include::partial$bt_example.adoc[] See also: -* {boost_level} -* {boost_level_close} -* {boost_level_ne} -* {boost_level_equal_collections} +* xref:{boost_level}[`BOOST_`] +* xref:{boost_level_close}[`BOOST__CLOSE`] +* xref:{boost_level_ne}[`BOOST__NE`] +* xref:{boost_level_equal_collections}[`BOOST__EQUAL_COLLECTIONS`] [#assertion_boost_level_eq_collections] == `BOOST__EQUAL_COLLECTIONS` @@ -235,7 +235,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_equal} +* xref:{boost_level_equal}[`BOOST__EQUAL`] [#assertion_boost_level_close] == `BOOST__CLOSE` @@ -255,7 +255,7 @@ check_is_close( left, right, tolerance ) ---- To check for the weak relationship use -{boost_level_predicate} family of tools with explicit `check_is_close` invocation. +xref:{boost_level_predicate}[`BOOST__PREDICATE`] family of tools with explicit `check_is_close` invocation. The first parameter is the _left_ compared value. The second parameter is the _right_ compared value. Last third parameter defines the tolerance for the comparison in @@ -269,7 +269,7 @@ It is required for left and right parameters to be of the same floating point ty [NOTE] ==== -The floating point comparison tools are automatically added if the {utf} +The floating point comparison tools are automatically added if the _Unit Test Framework_ is included as indicated in the previous sections. The tools are implemented is in the header link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. ==== @@ -288,10 +288,10 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_close_fraction} -* {boost_level_small} -* {boost_level_equal} -* {floating_points_testing_tools} +* xref:{boost_level_close_fraction}[`BOOST__CLOSE_FRACTION`] +* xref:{boost_level_small}[`BOOST__SMALL`] +* xref:{boost_level_equal}[`BOOST__EQUAL`] +* xref:{floating_points_testing_tools}[Floating point comparison algorithms] [#assertion_boost_level_close_fraction] == `BOOST__CLOSE_FRACTION` @@ -310,7 +310,7 @@ These tools are used to check on closeness using strong relationship defined by check_is_close(left, right, tolerance) ---- -To check for the weak relationship use {boost_level_predicate} family of tools with explicit `check_is_close` invocation. +To check for the weak relationship use xref:{boost_level_predicate}[`BOOST__PREDICATE`] family of tools with explicit `check_is_close` invocation. The first parameter is the _left_ compared value. The second parameter is the _right_ compared value. Last third parameter defines the tolerance for the comparison as @@ -324,7 +324,7 @@ It is required for left and right parameters to be of the same floating point ty [NOTE] ==== -The floating point comparison tools are automatically added if the {utf} +The floating point comparison tools are automatically added if the _Unit Test Framework_ is included as indicated in the previous sections. The tools are implemented is in the header link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. ==== @@ -337,10 +337,10 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_close} -* {boost_level_small} -* {boost_level_equal} -* {floating_points_testing_tools} +* xref:{boost_level_close}[`BOOST__CLOSE`] +* xref:{boost_level_small}[`BOOST__SMALL`] +* xref:{boost_level_equal}[`BOOST__EQUAL`] +* xref:{floating_points_testing_tools}[Floating point comparison algorithms] [#assertion_boost_level_ge] == `BOOST__GE` @@ -352,7 +352,7 @@ BOOST_CHECK_GE(left, right); BOOST_REQUIRE_GE(left, right); ---- -Check performed by these tools is the same as the one performed by `{boost_level}( left >= right )`. +Check performed by these tools is the same as the one performed by `BOOST_( left >= right )`. The difference is that the argument values are reported as well. // tag reference: doc/modules/ROOT/examples/example57.run-fail.cpp @@ -363,9 +363,9 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_le} -* {boost_level_lt} -* {boost_level_gt} +* xref:{boost_level_le}[`BOOST__LE`] +* xref:{boost_level_lt}[`BOOST__LT`] +* xref:{boost_level_gt}[`BOOST__GT`] [#assertion_boost_level_gt] == `BOOST__GT` @@ -377,7 +377,7 @@ BOOST_CHECK_GT(left, right); BOOST_REQUIRE_GT(left, right); ---- -Check performed by these tools is the same as the one performed by {boost_level}`( left > right )`. +Check performed by these tools is the same as the one performed by xref:{boost_level}[`BOOST_`]`( left > right )`. The difference is that the argument values are reported as well. // tag reference: doc/modules/ROOT/examples/example58.run-fail.cpp @@ -388,9 +388,9 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_le} -* {boost_level_lt} -* {boost_level_ge} +* xref:{boost_level_le}[`BOOST__LE`] +* xref:{boost_level_lt}[`BOOST__LT`] +* xref:{boost_level_ge}[`BOOST__GE`] [#assertion_boost_level_le] == `BOOST__LE` @@ -402,7 +402,7 @@ BOOST_CHECK_LE(left, right); BOOST_REQUIRE_LE(left, right); ---- -Check performed by these tools is the same as the one performed by `{boost_level}( left <= right )`. +Check performed by these tools is the same as the one performed by `BOOST_( left <= right )`. The difference is that the argument values are reported as well. // tag reference: doc/modules/ROOT/examples/example55.run-fail.cpp @@ -413,9 +413,9 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_le} -* {boost_level_ge} -* {boost_level_gt} +* xref:{boost_level_le}[`BOOST__LE`] +* xref:{boost_level_ge}[`BOOST__GE`] +* xref:{boost_level_gt}[`BOOST__GT`] [#assertion_boost_level_lt] == `BOOST__LT` @@ -427,7 +427,7 @@ BOOST_CHECK_LT(left, right); BOOST_REQUIRE_LT(left, right); ---- -Check performed by these tools is the same as the one performed by `{boost_level}( left < right )`. +Check performed by these tools is the same as the one performed by `BOOST_( left < right )`. The difference is that the argument values are reported as well. // tag reference: doc/modules/ROOT/examples/example56.run-fail.cpp @@ -438,9 +438,9 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_le} -* {boost_level_ge} -* {boost_level_gt} +* xref:{boost_level_le}[`BOOST__LE`] +* xref:{boost_level_ge}[`BOOST__GE`] +* xref:{boost_level_gt}[`BOOST__GT`] [#assertion_boost_level_message] == `BOOST__MESSAGE` @@ -452,7 +452,7 @@ BOOST_CHECK_MESSAGE(predicate, message); BOOST_REQUIRE_MESSAGE(predicate, message); ---- -These tools perform exactly the same check as {boost_level} tools. The only difference is that +These tools perform exactly the same check as xref:{boost_level}[`BOOST_`] tools. The only difference is that instead of generating an error/confirm message these use the supplied one. The first parameter is the boolean expression. The second parameter is the message reported in case of check @@ -467,7 +467,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level} +* xref:{boost_level}[`BOOST_`] [#assertion_boost_level_ne] == `BOOST__NE` @@ -479,7 +479,7 @@ BOOST_CHECK_NE(left, right); BOOST_REQUIRE_NE(left, right); ---- -Check performed by these tools is the same as the one performed by `{boost_level}( left != right )`. +Check performed by these tools is the same as the one performed by `BOOST_( left != right )`. The difference is that the matched values are reported as well. // tag reference: doc/modules/ROOT/examples/example54.run-fail.cpp @@ -490,7 +490,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_equal} +* xref:{boost_level_equal}[`BOOST__EQUAL`] [#assertion_boost_level_predicate] == `BOOST__PREDICATE` @@ -504,7 +504,7 @@ BOOST_REQUIRE_PREDICATE(predicate, arguments_list); These are generic tools used to validate an arbitrary supplied predicate functor (there is a compile time limit on predicate arity defined by the configurable macro `BOOST_TEST_MAX_PREDICATE_ARITY`). To -validate zero arity predicate use {boost_level} tools. In other cases prefer theses tools. The +validate zero arity predicate use xref:{boost_level}[`BOOST_`] tools. In other cases prefer theses tools. The advantage of these tools is that they show arguments values in case of predicate failure. The first parameter is the predicate itself. The second parameter is the list of predicate arguments each wrapped @@ -516,11 +516,11 @@ in round brackets (`BOOST_PP` sequence format). :bt-descr: BOOST__PREDICATE usage include::partial$bt_example.adoc[] -NOTE: Note difference in error log from {boost_level} +NOTE: Note difference in error log from xref:{boost_level}[`BOOST_`] See also: -* {boost_level} +* xref:{boost_level}[`BOOST_`] [#assertion_boost_level_no_throw] == `BOOST__NO_THROW` @@ -546,7 +546,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_throw} +* xref:{boost_level_throw}[`BOOST__THROW`] * xref:testing_tools/exception_correctness.adoc[Exception correctness] section [#assertion_boost_level_throw] @@ -579,7 +579,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_no_throw} +* xref:{boost_level_no_throw}[`BOOST__NO_THROW`] * xref:testing_tools/exception_correctness.adoc[Exception correctness] section [#assertion_boost_level_exception] @@ -592,12 +592,12 @@ BOOST_CHECK_EXCEPTION(expression, exception_type, predicate); BOOST_REQUIRE_EXCEPTION(expression, exception_type, predicate); ---- -As for {boost_level_throw}, these assertions validate that `expression` raises an exception of the +As for xref:{boost_level_throw}[`BOOST__THROW`], these assertions validate that `expression` raises an exception of the type specified by `exception_type` or any of its child type, with additional checks on the exception instance. * If an expected exception is raised by `expression`, the instance of the exception is passed to `predicate` for further validation. -* It behaves like {boost_level_throw} if `expression` does not raise any exception, or an unrelated exception is raised. +* It behaves like xref:{boost_level_throw}[`BOOST__THROW`] if `expression` does not raise any exception, or an unrelated exception is raised. `predicate` should be a unary function accepting an instance of `exception_type` or any of its child, and that should return a boolean indicating a success (`true`) or a failure (`false`). @@ -616,7 +616,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_throw} +* xref:{boost_level_throw}[`BOOST__THROW`] * xref:testing_tools/exception_correctness.adoc[Exception correctness] section [#assertion_boost_level_small] @@ -631,13 +631,13 @@ BOOST_REQUIRE_SMALL(value, tolerance); These tools are used to check that supplied value is small enough. The "smallness" is defined by absolute value of the tolerance supplied as a second argument. Use these tools with caution. To compare to values on closeness -it's preferable to use {boost_level_close} tools instead. +it's preferable to use xref:{boost_level_close}[`BOOST__CLOSE`] tools instead. The first parameter is the value to check. The second parameter is the tolerance. [NOTE] ==== -The floating point comparison tools are automatically added if the {utf} +The floating point comparison tools are automatically added if the _Unit Test Framework_ is included as indicated in the previous sections. The tools are implemented is in the header link:{base-url}/boost/test/tools/floating_point_comparison.hpp[`boost/test/tools/floating_point_comparison.hpp`]. ==== @@ -650,9 +650,9 @@ include::partial$bt_example.adoc[] See also: -* {boost_level_close} -* {boost_level_close_fraction} -* {floating_points_testing_tools} +* xref:{boost_level_close}[`BOOST__CLOSE`] +* xref:{boost_level_close_fraction}[`BOOST__CLOSE_FRACTION`] +* xref:{floating_points_testing_tools}[Floating point comparison algorithms] [#test_org_boost_test_case_expected_failure] == `BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES` @@ -669,7 +669,7 @@ See xref:testing_tools/expected_failures.adoc[here] for more details. BOOST_ERROR(message); ---- -{boost_error} tool behave the same way as `{boost_test}(false, message)`. This tool is used for +xref:{boost_error}[`BOOST_ERROR`] tool behave the same way as `BOOST_TEST(false, message)`. This tool is used for an unconditional error counter increasing and message logging. The tool's only parameter is an error message to log. @@ -682,7 +682,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_test} +* xref:{boost_test}[`BOOST_TEST`] [#assertion_boost_fail] == `BOOST_FAIL` @@ -692,7 +692,7 @@ See also: BOOST_FAIL(message); ---- -`{boost_fail}(message)` behave the same way as `{boost_test_require}(false, message)`. This tool is used for an +`BOOST_FAIL(message)` behave the same way as `BOOST_TEST_REQUIRE(false, message)`. This tool is used for an unconditional error counter increasing, message logging and the current test case aborting. The tool's only parameter is an error message to log. @@ -705,7 +705,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_test} +* xref:{boost_test}[`BOOST_TEST`] * @@ -719,7 +719,7 @@ BOOST_IS_DEFINED(symbol); Unlike the rest of the tools in the toolbox this tool does not perform the logging itself. Its only purpose is to check at runtime whether or not the supplied preprocessor symbol is defined. Use it in combination with -{boost_level} to perform and log validation. Macros of any arity could be checked. To check the +xref:{boost_level}[`BOOST_`] to perform and log validation. Macros of any arity could be checked. To check the macro definition with non-zero arity specify dummy arguments for it. See below for example. The only tool's parameter is a preprocessor symbol that gets validated. @@ -732,7 +732,7 @@ include::partial$bt_example.adoc[] See also: -* {boost_level} +* xref:{boost_level}[`BOOST_`] [#assertion_control_under_debugger] == `BOOST_TEST_TOOLS_UNDER_DEBUGGER` diff --git a/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc index 076d7f3510..7103988f73 100644 --- a/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc @@ -37,7 +37,7 @@ For more details see xref:test_output/contexts.adoc[here]. [#test_output_macro_context_sticky] == `BOOST_TEST_INFO_SCOPE` -Defines a sticky version of {boost_test_info}: the message stored in `BOOST_TEST_INFO_SCOPE` is printed for all failed assertions that come +Defines a sticky version of xref:{boost_test_info}[`BOOST_TEST_INFO`]: the message stored in `BOOST_TEST_INFO_SCOPE` is printed for all failed assertions that come after the declaration of `BOOST_TEST_INFO_SCOPE` and within the current scope. For more details see xref:test_output/contexts.adoc[here]. @@ -46,7 +46,7 @@ For more details see xref:test_output/contexts.adoc[here]. Disables the automatic printing of a value. This macro is relevant -* a type is used in a comparison assertion (such as {boost_level_ge} for instance) +* a type is used in a comparison assertion (such as xref:{boost_level_ge}[`BOOST__GE`] for instance) * when the type being compared does not implement a suitable `operator <<` for streaming out the value into the test log stream diff --git a/doc/mrdocs-addons/generator/adoc/partials/markup/a.adoc.hbs b/doc/mrdocs-addons/generator/adoc/partials/markup/a.adoc.hbs new file mode 100644 index 0000000000..29d9fd02e3 --- /dev/null +++ b/doc/mrdocs-addons/generator/adoc/partials/markup/a.adoc.hbs @@ -0,0 +1,44 @@ +{{! + Overrides the built-in markup/a partial, wrapping the upstream body in the + guard below. Everything inside the guard is the upstream template verbatim; + keep it that way so the file is easy to diff against a newer MrDocs. + + Why the guard: Antora ignores files whose name begins with an underscore, + and MrDocs names a page after the symbol it documents. An unnamed enum + becomes `_04enum.adoc`, and the enums Boost.Test spells `enum _ { ... }` in + utils/setcolor.hpp become `_.adoc`. MrDocs writes those pages and links to + them, Antora never publishes them, and the build reports "target of xref + not found". + + Boost.Test reaches this through `enum { type = TUT_CASE };`, the internal + tag constant in tree/test_unit.hpp, which puts an unnamed enum in the + member table of test_case, test_suite, test_unit, is_forward_iterable and + is_container_forward_iterable. + + So when the target page would start with an underscore, emit the link text + alone: the member keeps its row in the table and only the dead link goes + away. This partial is the one chokepoint every generated link passes + through. The test is spelled with `replace` because `contains` only matches + within arrays, not within a string. + + Delete this file once MrDocs stops emitting underscore-prefixed page names. + + Do not relativize links as asciidoc does not support it. + + https://gitlab.com/antora/antora/-/issues/428 +}} +{{#if (eq (replace href "/_" "/") href)~}} + {{~#if (eq href @root.symbol.url)~}} + {{{> @partial-block }}} + {{~else if (starts_with href "#")~}} + link:{{{ href }}}[{{> @partial-block }}] + {{~else if (starts_with href "/")~}} + xref:{{{remove_prefix href "/"}}}[{{> @partial-block }}] + {{~else if (starts_with href ".")~}} + xref:{{{href}}}[{{> @partial-block }}] + {{~else~}} + {{{href}}}[{{> @partial-block }}{{#if blank}}^{{/if}}] + {{~/if~}} +{{~else~}} + {{> @partial-block }} +{{~/if~}} diff --git a/doc/mrdocs.cpp b/doc/mrdocs.cpp new file mode 100644 index 0000000000..6595e32148 --- /dev/null +++ b/doc/mrdocs.cpp @@ -0,0 +1,101 @@ +// +// Copyright (c) 2003 Boost.Test contributors +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Documentation-only translation unit: the single target MrDocs analyses. +// +// It exists because no Boost.Test header transitively includes everything that +// belongs in the reference -- unit_test.hpp pulls in neither the datasets, nor +// the output formatters, nor the tools/detail manipulators. The list below is +// the one the Doxygen target in doc/Jamfile.v2 curated before the Antora port, +// carried over unchanged; it is the public surface, and is the place to add a +// header that should appear in the reference. +// +// Compiling one umbrella TU rather than the whole library is also what keeps +// MrDocs fast: it has the entire public API in a single compilation database +// entry. +// +// Deliberately absent: boost/test/included/*, minimal.hpp, auto_unit_test.hpp, +// test_exec_monitor.hpp and the top-level floating_point_comparison.hpp and +// output_test_stream.hpp shims. The first pulls in the .ipp definitions; the +// rest are deprecated forwarding headers that emit #pragma message or #error. + +// BOOST_TEST_DOXYGEN_DOC__ is deliberately NOT defined here, even though the +// Doxygen target that preceded this one set it. It exists for a tool that does +// not compile what it reads, and MrDocs does: +// +// - data/monomorphic/fwd.hpp hides its forward declarations behind +// `#if !defined(BOOST_TEST_DOXYGEN_DOC__)`, so with the macro set, +// make_delayed() refers to an undeclared delayed_dataset and the header +// does not compile; +// - data/config.hpp defines BOOST_TEST_NO_{RANDOM_DATASET,GRID_COMPOSITION, +// ZIP_COMPOSITION}_AVAILABLE when it is set, which would drop the random, +// grid and zip datasets from the reference entirely. +// +// The three configuration macros it also reveals -- those and +// BOOST_TEST_DISABLE_ALT_STACK in execution_monitor.hpp -- carry no doc +// comments MrDocs could use anyway; they are documented by hand in +// modules/ROOT/pages/utf_reference/link_references.adoc. + +// Core +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Test tree +#include +#include + +// Logs, reports and formatters +#include +#include +#include +#include +#include +#include +#include +#include + +// Assertion support +#include +#include +#include +#include +#include +#include +#include + +// Datasets +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Dataset generators +#include +#include +#include +#include + +// Utilities +#include +#include +#include diff --git a/doc/mrdocs.yml b/doc/mrdocs.yml new file mode 100644 index 0000000000..f375abdd6e --- /dev/null +++ b/doc/mrdocs.yml @@ -0,0 +1,104 @@ +# +# Copyright (c) 2003 Boost.Test contributors +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# + +# Input. CMakeLists.txt in this directory configures a single umbrella +# translation unit, mrdocs.cpp, that includes the public headers; see the +# comment at the top of that file for what is in it and why. +source-root: .. +input: + - ../include +file-patterns: + - '*.hpp' +exclude: + # Definitions, not declarations: pulled in only by the header-only variant. + - '../include/boost/test/impl' + - '../include/boost/test/included' + # Assembly headers and internal plumbing with no public API of their own. + - '../include/boost/test/detail' + - '../include/boost/test/utils/runtime' +compilation-database: ./CMakeLists.txt + +# Filters +include-symbols: + - 'boost::unit_test::**' + - 'boost::test_tools::**' + - 'boost::debug::**' + - 'boost::execution_exception' + - 'boost::execution_monitor' + - 'boost::execution_aborted' + - 'boost::system_error' +implementation-defined: + - 'boost::unit_test::ut_detail' + - 'boost::unit_test::**::ut_detail' + - 'boost::unit_test::**::ds_detail' + - 'boost::unit_test::utils::nfp_detail' + - 'boost::unit_test::**::detail' + - 'boost::test_tools::tt_detail' + - 'boost::test_tools::**::detail' +exclude-symbols: + # Internal helpers that happen to sit in a public namespace rather than in + # one of the detail namespaces above. + - 'boost::unit_test::data::invoke_action_impl' + - 'boost::unit_test::data::index_sequence' + - 'boost::unit_test::data::make_index_sequence' + - 'boost::unit_test::data::index_sequence_for' +see-below: + # Heavily SFINAE-constrained; the signatures are noise for a reader. + - 'boost::unit_test::data::monomorphic::**::iterator' +inaccessible-members: never +inaccessible-bases: never +inherit-base-members: never +private-bases: false +extract-friends: false +auto-function-metadata: false +sort-members: false + +# Macros. Boost.Test's public macros carry no doc comments in the sources -- the +# Doxygen target that preceded this one only surfaced them because it ran with +# EXTRACT_ALL=YES -- so with extract-all-macros off (the default) almost none +# will be extracted. The authoritative macro reference is the hand-written +# utf_reference/ pages. These patterns are here so that a macro which does +# acquire a doc comment lands in the reference, and internals never do. +include-macros: + - 'BOOST_TEST_*' + - 'BOOST_AUTO_TEST_*' + - 'BOOST_FIXTURE_TEST_*' + - 'BOOST_DATA_TEST_*' + - 'BOOST_PARAM_TEST_CASE' + - 'BOOST_GLOBAL_FIXTURE' + - 'BOOST_CHECK*' + - 'BOOST_REQUIRE*' + - 'BOOST_WARN*' + - 'BOOST_ERROR' + - 'BOOST_FAIL' + - 'BOOST_IS_DEFINED' +exclude-macros: + - 'BOOST_TEST_DETAIL_*' + - 'BOOST_TEST_TOOL_*' + - 'BOOST_TEST_PP_*' + - '*_IMPL' + - '*_IMPL_' + # Documented in the sources but not public API. + - 'BOOST_TEST_SYS_ASSERT' + - 'BOOST_TEST_INVOKE_IF_N_ARGS' + +# Template overrides layered on top of the built-in addons. See the header +# comment in the overridden file for what it changes and why. +addons-supplemental: + - mrdocs-addons + +# Generator +generate: adoc +multipage: true +base-url: https://www.github.com/boostorg/test/blob/master/ + +# Diagnostics. Most symbols are undocumented today; warning on each of them +# would bury anything actionable. +verbose: true +warn-if-undocumented: false +warn-no-paramdoc: false +warn-as-error: false diff --git a/doc/tools/attributes.yml b/doc/tools/attributes.yml index cc67d531b8..f317d7bb10 100644 --- a/doc/tools/attributes.yml +++ b/doc/tools/attributes.yml @@ -1,85 +1,79 @@ - utf: '_Unit Test Framework_' - pem: '_Program Execution Monitor_' - ieee754: '*IEEE754*' - part_faq: 'xref:section_faq.adoc[FAQ]' - floating_points_testing_tools: 'xref:testing_tools/floating_point.adoc#floating_points_comparison_theory[Floating point comparison algorithms]' - master_test_suite: 'xref:tests_organization/master_test_suite.adoc[master test suite]' - runtime_configuration: 'xref:runtime_config/index.adoc[runtime configuration]' - output_test_stream_tool: 'xref:testing_tools/output_stream_testing.adoc[output test stream]' - auto_linking: 'automatic linking // FIXME(qbk2adoc): unresolved link ref_pem_auto_link' - boost_test_alternative_init_api: 'xref:utf_reference/link_references.adoc#link_boost_test_alternative_init_macro[`BOOST_TEST_ALTERNATIVE_INIT_API`]' - boost_test_main: 'xref:utf_reference/link_references.adoc#link_boost_test_main_macro[`BOOST_TEST_MAIN`]' - boost_test_dyn_link: 'xref:utf_reference/link_references.adoc#link_boost_test_dyn_link[`BOOST_TEST_DYN_LINK`]' - boost_test_no_lib: 'xref:utf_reference/link_references.adoc#link_boost_test_no_lib[`BOOST_TEST_NO_LIB`]' - boost_test_no_main: 'xref:utf_reference/link_references.adoc#link_boost_test_no_main[`BOOST_TEST_NO_MAIN`]' - boost_test_module: 'xref:utf_reference/link_references.adoc#link_boost_test_module_macro[`BOOST_TEST_MODULE`]' - boost_test_global_configuration: 'xref:utf_reference/link_references.adoc#link_boost_test_global_configuration[`BOOST_TEST_GLOBAL_CONFIGURATION`]' - boost_test_checkpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_checkpoint[`BOOST_TEST_CHECKPOINT`]' - boost_test_passpoint: 'xref:utf_reference/testout_reference.adoc#test_output_macro_passpoint[`BOOST_TEST_PASSPOINT`]' - boost_test_message: 'xref:utf_reference/testout_reference.adoc#test_output_macro_message[`BOOST_TEST_MESSAGE`]' - boost_test_info: 'xref:utf_reference/testout_reference.adoc#test_output_macro_info[`BOOST_TEST_INFO`]' - boost_test_context: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context[`BOOST_TEST_CONTEXT`]' - boost_test_info_scope: 'xref:utf_reference/testout_reference.adoc#test_output_macro_context_sticky[`BOOST_TEST_INFO_SCOPE`]' - boost_test_dont_print_log_value: 'xref:utf_reference/testout_reference.adoc#test_output_macro_disable_type[`BOOST_TEST_DONT_PRINT_LOG_VALUE`]' - boost_test: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST`]' - boost_test_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_`]' - boost_test_require: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro[`BOOST_TEST_REQUIRE`]' - boost_level: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level[`BOOST_`]' - boost_level_message: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_message[`BOOST__MESSAGE`]' - boost_level_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq[`BOOST__EQUAL`]' - boost_level_predicate: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate[`BOOST__PREDICATE`]' - boost_level_equal_collections: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections[`BOOST__EQUAL_COLLECTIONS`]' - boost_level_ne: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne[`BOOST__NE`]' - boost_level_ge: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge[`BOOST__GE`]' - boost_level_gt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt[`BOOST__GT`]' - boost_level_le: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_le[`BOOST__LE`]' - boost_level_lt: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt[`BOOST__LT`]' - boost_level_no_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw[`BOOST__NO_THROW`]' - boost_level_throw: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST__THROW`]' - boost_level_exception: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception[`BOOST__EXCEPTION`]' - boost_level_bitwise_equal: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq[`BOOST__BITWISE_EQUAL`]' - boost_error: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_error[`BOOST_ERROR`]' - boost_fail: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_fail[`BOOST_FAIL`]' - boost_is_defined: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined[`BOOST_IS_DEFINED`]' - boost_auto_test_case_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure[`BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES`]' - boost_level_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST__SMALL`]' - boost_check_small: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_small[`BOOST_CHECK_SMALL`]' - boost_level_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST__CLOSE`]' - boost_check_close: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close[`BOOST_CHECK_CLOSE`]' - boost_level_close_fraction: 'xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction[`BOOST__CLOSE_FRACTION`]' - boost_test_tools_under_debugger: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger[`BOOST_TEST_TOOLS_UNDER_DEBUGGER`]' - boost_test_tools_debuggable: 'xref:utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable[`BOOST_TEST_TOOLS_DEBUGGABLE`]' - boost_auto_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case[`BOOST_AUTO_TEST_CASE`]' - boost_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE`]' - boost_test_case_name: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case[`BOOST_TEST_CASE_NAME`]' - boost_auto_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template[`BOOST_AUTO_TEST_CASE_TEMPLATE`]' - boost_test_case_template: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template[`BOOST_TEST_CASE_TEMPLATE`]' - boost_test_case_template_function: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function[`BOOST_TEST_CASE_TEMPLATE_FUNCTION`]' - boost_param_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter[`BOOST_PARAM_TEST_CASE`]' - boost_data_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_DATA_TEST_CASE`]' - boost_data_test_case_f: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture[`BOOST_DATA_TEST_CASE_F`]' - boost_test_dataset_max_arity: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_dataset[`BOOST_TEST_DATASET_MAX_ARITY`]' - boost_auto_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite[`BOOST_AUTO_TEST_SUITE`]' - boost_auto_test_suite_end: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end[`BOOST_AUTO_TEST_SUITE_END`]' - boost_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite[`BOOST_TEST_SUITE`]' - boost_test_decorator: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_decorator[`BOOST_TEST_DECORATOR`]' - boost_fixture_test_case: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture[`BOOST_FIXTURE_TEST_CASE`]' - boost_fixture_test_suite: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture[`BOOST_FIXTURE_TEST_SUITE`]' - boost_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_global_fixture[`BOOST_GLOBAL_FIXTURE`]' - boost_test_global_fixture: 'xref:utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture[`BOOST_TEST_GLOBAL_FIXTURE`]' - boost_test_log_level: 'xref:utf_reference/rt_param_reference.adoc#log_level[`BOOST_TEST_LOG_LEVEL`]' - default_run_status: 'xref:runtime_config/test_unit_filtering.adoc#ref_default_run_status[_default run status_]' - param_run_test: 'xref:utf_reference/rt_param_reference.adoc#run_test[`run_test`]' - decorator_label: 'xref:utf_reference/test_org_reference.adoc#decorator_label[`label`]' - decorator_enabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`enabled`]' - decorator_disabled: 'xref:utf_reference/test_org_reference.adoc#decorator_enabled[`disabled`]' - decorator_enable_if: 'xref:utf_reference/test_org_reference.adoc#decorator_enable_if[`enable_if`]' - decorator_depends_on: 'xref:utf_reference/test_org_reference.adoc#decorator_depends_on[`depends_on`]' - decorator_precondition: 'xref:utf_reference/test_org_reference.adoc#decorator_precondition[`precondition`]' - decorator_fixture: 'xref:utf_reference/test_org_reference.adoc#decorator_fixture[`fixture`]' - decorator_description: 'xref:utf_reference/test_org_reference.adoc#decorator_description[`description`]' - decorator_expected_failures: 'xref:utf_reference/testing_tool_ref.adoc#decorator_expected_failures[`expected_failures`]' - decorator_timeout: 'xref:utf_reference/testing_tool_ref.adoc#decorator_timeout[`timeout`]' - decorator_tolerance: 'xref:utf_reference/testing_tool_ref.adoc#decorator_tolerance[`tolerance`]' - class_predicate_result: 'cpp:boost::test_tools::predicate_result[boost::test_tools::predicate_result]' - class_assertion_result: 'cpp:boost::test_tools::assertion_result[test_tools::assertion_result]' + part_faq: 'section_faq.adoc' + floating_points_testing_tools: 'testing_tools/floating_point.adoc#floating_points_comparison_theory' + master_test_suite: 'tests_organization/master_test_suite.adoc' + runtime_configuration: 'runtime_config/index.adoc' + output_test_stream_tool: 'testing_tools/output_stream_testing.adoc' + boost_test_alternative_init_api: 'utf_reference/link_references.adoc#link_boost_test_alternative_init_macro' + boost_test_main: 'utf_reference/link_references.adoc#link_boost_test_main_macro' + boost_test_dyn_link: 'utf_reference/link_references.adoc#link_boost_test_dyn_link' + boost_test_no_lib: 'utf_reference/link_references.adoc#link_boost_test_no_lib' + boost_test_no_main: 'utf_reference/link_references.adoc#link_boost_test_no_main' + boost_test_module: 'utf_reference/link_references.adoc#link_boost_test_module_macro' + boost_test_global_configuration: 'utf_reference/link_references.adoc#link_boost_test_global_configuration' + boost_test_checkpoint: 'utf_reference/testout_reference.adoc#test_output_macro_checkpoint' + boost_test_passpoint: 'utf_reference/testout_reference.adoc#test_output_macro_passpoint' + boost_test_message: 'utf_reference/testout_reference.adoc#test_output_macro_message' + boost_test_info: 'utf_reference/testout_reference.adoc#test_output_macro_info' + boost_test_context: 'utf_reference/testout_reference.adoc#test_output_macro_context' + boost_test_info_scope: 'utf_reference/testout_reference.adoc#test_output_macro_context_sticky' + boost_test_dont_print_log_value: 'utf_reference/testout_reference.adoc#test_output_macro_disable_type' + boost_test: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_test_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_test_require: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' + boost_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level' + boost_level_message: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_message' + boost_level_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq' + boost_level_predicate: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate' + boost_level_equal_collections: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections' + boost_level_ne: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne' + boost_level_ge: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge' + boost_level_gt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt' + boost_level_le: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_le' + boost_level_lt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt' + boost_level_no_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw' + boost_level_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw' + boost_level_exception: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception' + boost_level_bitwise_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq' + boost_error: 'utf_reference/testing_tool_ref.adoc#assertion_boost_error' + boost_fail: 'utf_reference/testing_tool_ref.adoc#assertion_boost_fail' + boost_is_defined: 'utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined' + boost_auto_test_case_expected_failures: 'utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure' + boost_level_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' + boost_check_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' + boost_level_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' + boost_check_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' + boost_level_close_fraction: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction' + boost_test_tools_under_debugger: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger' + boost_test_tools_debuggable: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable' + boost_auto_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case' + boost_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' + boost_test_case_name: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' + boost_auto_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template' + boost_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template' + boost_test_case_template_function: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function' + boost_param_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter' + boost_data_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' + boost_data_test_case_f: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture' + boost_test_dataset_max_arity: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' + boost_auto_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite' + boost_auto_test_suite_end: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end' + boost_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite' + boost_test_decorator: 'utf_reference/test_org_reference.adoc#test_org_boost_test_decorator' + boost_fixture_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture' + boost_fixture_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture' + boost_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_global_fixture' + boost_test_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture' + boost_test_log_level: 'utf_reference/rt_param_reference.adoc#log_level' + default_run_status: 'runtime_config/test_unit_filtering.adoc#ref_default_run_status' + param_run_test: 'utf_reference/rt_param_reference.adoc#run_test' + decorator_label: 'utf_reference/test_org_reference.adoc#decorator_label' + decorator_enabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' + decorator_disabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' + decorator_enable_if: 'utf_reference/test_org_reference.adoc#decorator_enable_if' + decorator_depends_on: 'utf_reference/test_org_reference.adoc#decorator_depends_on' + decorator_precondition: 'utf_reference/test_org_reference.adoc#decorator_precondition' + decorator_fixture: 'utf_reference/test_org_reference.adoc#decorator_fixture' + decorator_description: 'utf_reference/test_org_reference.adoc#decorator_description' + decorator_expected_failures: 'utf_reference/testing_tool_ref.adoc#decorator_expected_failures' + decorator_timeout: 'utf_reference/testing_tool_ref.adoc#decorator_timeout' + decorator_tolerance: 'utf_reference/testing_tool_ref.adoc#decorator_tolerance' diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py index ffd720e85f..275ccf6958 100644 --- a/doc/tools/qbk2adoc.py +++ b/doc/tools/qbk2adoc.py @@ -454,8 +454,11 @@ def __init__(self, index, outdir): self.snippets = {} # callout id -> example$ resource path self.table_ids = {} # table anchor -> times seen self.plain = {} # def name -> plain text, for use inside code + self.def_repl = {} # def name -> the AsciiDoc it expands to in prose + self.attributes = OrderedDict() # antora.yml attribute -> value for name, value in index.defs.items(): self.plain[name] = self._plain_text(value) + self.build_def_table(index.root) # -- helpers ------------------------------------------------------------ @@ -489,25 +492,51 @@ def fixme(self, kind, detail=""): self.fixmes[kind] += 1 return "// FIXME(qbk2adoc): %s %s\n" % (kind, detail) - # `{` is escaped in prose so stray braces in the sources cannot look like - # attribute references. Substituted [def]s therefore go in as sentinels and - # become real braces on the way out of inline(). - ATTR_OPEN, ATTR_CLOSE = "\x01", "\x02" + DEF_RE = re.compile(r"__[A-Za-z0-9_]+?__") def subst_defs(self, text, code=False): + """Expand [def] macros to their plain text, for code blocks.""" def repl(m): name = m.group(0) - if name not in self.index.defs: - return name - if code: - return self.plain[name] - return "%s%s%s" % (self.ATTR_OPEN, attr_name(name), self.ATTR_CLOSE) - return re.sub(r"__[A-Za-z0-9_]+?__", repl, text) + return self.plain[name] if name in self.index.defs else name + return self.DEF_RE.sub(repl, text) if code else text + + def build_def_table(self, page): + """Decide, once, what each [def] becomes in prose and in antora.yml. + + Asciidoctor substitutes quotes *before* attributes, and a value coming + from an API attribute -- which is what antora.yml sets -- is inserted + without further substitution. So no formatting inside an attribute + value is ever processed: an attribute holding + `xref:page.adoc#a[\`BOOST_TEST\`]` renders with the backticks visible. + + The ~80 defs that are link aliases therefore put only the link *target* + in the attribute and spell the macro name at each call site. That is + what keeps a reference page renameable in one place, and the label is + formatted normally because it is literal in the page. The three prose + defs carry no target worth naming and are expanded in place. + """ + for name, value in self.index.defs.items(): + attr = attr_name(name) + m = re.match(r"\[link\s+(\S+)\s+(.*)\]$", value.strip(), re.S) + hit = self.index.resolve(m.group(1)) if m else None + if hit and hit[0] is not None and hit[0].page is not None: + owner, anchor = hit + target = owner.page + ("#" + anchor if anchor else "") + self.attributes[attr] = target + label = self.inline(m.group(2).strip(), page) + self.def_repl[name] = "xref:{%s}[%s]" % (attr, label) + else: + rendered = re.sub(r"\s+", " ", self.inline(value, page).strip()) + # QuickBook's /slash italics/ survive only in the [def] bodies. + rendered = re.sub(r"(? Date: Thu, 30 Jul 2026 12:20:32 -0400 Subject: [PATCH 06/10] doc: resolve every cross-reference All 556 QuickBook links now resolve. What it took: The Program Execution Monitor chapter comes back into the book. It had been commented out of test.qbk with a [/TOFIX] marker while a live [def] still linked into it, so __auto_linking__ has been dangling on the published site. The component still ships. Its bt_example named example24 with the run-fail rule, but the file is example24.run.cpp, which is why nobody noticed: the chapter was never built. Links written against `boost_test.components.*`, a chapter that no longer exists, still name a real section by their last component, so the resolver falls back to that. The one with no successor at all, the Execution Monitor, now points at the class MrDocs generates. Four links target a plain [hN] heading by the id QuickBook derived from its title. Those ids are emitted now -- but only where something links to them. Emitting them everywhere collides, since each of the 25 runtime parameters has an "Acceptable values" heading and they share one page. BOOST_TEST_NO_{RANDOM_DATASET,ZIP_COMPOSITION,GRID_COMPOSITION}_AVAILABLE were referenced by [macroref] but documented nowhere, and MrDocs cannot emit them. They are now written up in the build-scenarios reference alongside BOOST_TEST_DISABLE_ALT_STACK. Also fixes three stray unpaired backticks in the sources, and a `[boost test]` that QuickBook rendered as a literal bracket. Co-Authored-By: Claude Opus 5 (1M context) --- doc/adv_scenarios/link_reference.qbk | 41 ++- doc/antora.yml | 1 + doc/closing_chapters/change_log.qbk | 2 +- doc/modules/ROOT/nav.adoc | 1 + doc/modules/ROOT/pages/change_log.adoc | 6 +- .../ROOT/pages/program_execution_monitor.adoc | 281 ++++++++++++++++++ doc/modules/ROOT/pages/section_glossary.adoc | 7 + .../ROOT/pages/test_output/contexts.adoc | 2 +- .../pages/testing_tools/floating_point.adoc | 4 +- .../ROOT/pages/testing_tools/reports.adoc | 1 + .../test_case_generation.adoc | 1 + .../test_organization_nullary.adoc | 2 +- .../pages/utf_reference/link_references.adoc | 42 ++- .../utf_reference/rt_param_reference.adoc | 4 +- doc/prod_use/program_execution_monitor.qbk | 2 +- .../runtime_config_reference.qbk | 4 +- doc/test.qbk | 3 +- doc/test_organization/nullary_tests.qbk | 2 +- .../__pycache__/qbk2adoc.cpython-312.pyc | Bin 53660 -> 62627 bytes doc/tools/qbk2adoc.py | 65 +++- 20 files changed, 443 insertions(+), 28 deletions(-) create mode 100644 doc/modules/ROOT/pages/program_execution_monitor.adoc diff --git a/doc/adv_scenarios/link_reference.qbk b/doc/adv_scenarios/link_reference.qbk index 0d9a8449d3..3872b7b113 100644 --- a/doc/adv_scenarios/link_reference.qbk +++ b/doc/adv_scenarios/link_reference.qbk @@ -127,8 +127,45 @@ Define this macro before the inclusion of any __UTF__ header to disable the supp of the [@http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html alternative stack], in case your compiler does not support it and the __UTF__ cannot automatically guess the lack of support. -See [link boost_test.utf_reference.rt_param_reference.use_alt_stack `use_alt_stack`] -and [macroref BOOST_TEST_DISABLE_ALT_STACK `BOOST_TEST_DISABLE_ALT_STACK`] for more details. +See [link boost_test.utf_reference.rt_param_reference.use_alt_stack `use_alt_stack`] for more details. +[endsect] + +[/-----------------------------------------------------------------] +[section:config_no_random_dataset `BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`] +Indicates that the [link boost_test.tests_organization.test_cases.test_case_generation.generators.random random dataset] +is not available. + +Unlike the other macros in this section, this one is not defined by you: the __UTF__ defines it +for you when the standard library in use provides no `` header, which the random dataset +generator needs. Test it to guard code that would otherwise fail to compile: + +`` +#include + +#ifndef BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE +// use data::random(...) here +#endif +`` +[endsect] + +[/-----------------------------------------------------------------] +[section:config_no_zip_composition `BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`] +Indicates that the [link boost_test.tests_organization.test_cases.test_case_generation.operations zip operation] +on datasets is not available. + +As for `BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`, the __UTF__ defines this macro for you: zipping +datasets needs the `` header, and the macro appears when the standard library in use does +not provide one. +[endsect] + +[/-----------------------------------------------------------------] +[section:config_no_grid_composition `BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE`] +Indicates that the [link boost_test.tests_organization.test_cases.test_case_generation.operations grid operation] +on datasets is not available. + +Defined by the __UTF__ under the same condition as +[link boost_test.utf_reference.link_references.config_no_zip_composition `BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`]: +the grid, or Cartesian product, of two datasets needs the `` header. [endsect] [endsect] diff --git a/doc/antora.yml b/doc/antora.yml index f2788954f0..b5675beaf6 100644 --- a/doc/antora.yml +++ b/doc/antora.yml @@ -37,6 +37,7 @@ asciidoc: master_test_suite: 'tests_organization/master_test_suite.adoc' runtime_configuration: 'runtime_config/index.adoc' output_test_stream_tool: 'testing_tools/output_stream_testing.adoc' + auto_linking: 'program_execution_monitor.adoc#ref_pem_auto_link' boost_test_alternative_init_api: 'utf_reference/link_references.adoc#link_boost_test_alternative_init_macro' boost_test_main: 'utf_reference/link_references.adoc#link_boost_test_main_macro' boost_test_dyn_link: 'utf_reference/link_references.adoc#link_boost_test_dyn_link' diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 90c4fc4d30..89908e02f4 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -598,7 +598,7 @@ Boost.Test releases: # [ticket 9539] Floating-point comparison algorithms aren't formatted correctly # [ticket 9581] Squassabia reference link gives 404 not found # [ticket 9960] Warnings on Clang -# [ticket 10256] [boost test] - issue: `sigaltstack` +# [ticket 10256] Boost.Test issue: `sigaltstack` # [ticket 10318] Minor documentation fix # [ticket 10394] Broken links in Boost Test documentation # [ticket 10888] Assertion failures don't show up in the errors pane in VS 2010, VS 2012 or VS 2013 (duplicates) diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc index 55cbf3b669..d8c692c9db 100644 --- a/doc/modules/ROOT/nav.adoc +++ b/doc/modules/ROOT/nav.adoc @@ -60,6 +60,7 @@ ** xref:adv_scenarios/shared_lib_customizations.adoc[] ** xref:adv_scenarios/external_test_runner.adoc[] ** xref:adv_scenarios/obsolete_init_func.adoc[] +* xref:program_execution_monitor.adoc[] * xref:usage_recommendations/index.adoc[] ** xref:usage_recommendations/bt_and_tdd.adoc[] ** xref:usage_recommendations/hello.adoc[] diff --git a/doc/modules/ROOT/pages/change_log.adoc b/doc/modules/ROOT/pages/change_log.adoc index e2937459e0..c30d2b38ca 100644 --- a/doc/modules/ROOT/pages/change_log.adoc +++ b/doc/modules/ROOT/pages/change_log.adoc @@ -158,7 +158,7 @@ point comparisons for expressions such as + `BOOST_TEST(3.0001 == 3);` + -See this section // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.extended_comparison.floating_point.type_promotion_of_the_operands +See xref:testing_tools/floating_point.adoc#type_promotion_of_the_operands[this section] for more information. === Breaking changes @@ -413,7 +413,7 @@ xref:testing_tools/strings.adoc[string comparison] for more details. * Boost.Test now treats each sample of a dataset test case as being a uniquely named test case under the same test suite, which enables the (re)run of one particular sample from the command line interface. See -here // FIXME(qbk2adoc): unresolved link boost_test.tests_organization.test_cases.test_case_generation.datasets_auto_registration.samples_and_test_tree +xref:tests_organization/test_case_generation.adoc#samples_and_test_tree[here] for more details, * Boost.Test learned to interpret ':' as a separator for the test filters: the string passed to xref:utf_reference/rt_param_reference.adoc#run_test[`--run_test`] @@ -595,7 +595,7 @@ should be rewritten to . {trac-url}/9539[#9539] Floating-point comparison algorithms aren't formatted correctly . {trac-url}/9581[#9581] Squassabia reference link gives 404 not found . {trac-url}/9960[#9960] Warnings on Clang -. {trac-url}/10256[#10256] \[boost test] - issue: `sigaltstack` +. {trac-url}/10256[#10256] Boost.Test issue: `sigaltstack` . {trac-url}/10318[#10318] Minor documentation fix . {trac-url}/10394[#10394] Broken links in Boost Test documentation . {trac-url}/10888[#10888] Assertion failures don't show up in the errors pane in VS 2010, VS 2012 or VS 2013 (duplicates) diff --git a/doc/modules/ROOT/pages/program_execution_monitor.adoc b/doc/modules/ROOT/pages/program_execution_monitor.adoc new file mode 100644 index 0000000000..adc39431d0 --- /dev/null +++ b/doc/modules/ROOT/pages/program_execution_monitor.adoc @@ -0,0 +1,281 @@ += Program Execution Monitor +:page-aliases: boost_test/pem.adoc + +The components of a C++ program may report user-detected errors in several ways, such as via a return value or +throwing an exception. System-detected errors such as dereferencing an invalid pointer are reported in other ways, +totally operating system and compiler dependent. + +Yet many C++ programs, both production and test, must run in an environment where uniform reporting of errors is +necessary. For example, converting otherwise uncaught exceptions to non-zero program return codes allows many +command line, script, or batch environments to continue processing in a controlled manner. Even some +_GUI_ environments benefit from the unification of errors into program return codes. + +The Boost.Test Library's *Program Execution Monitor* relieves users from messy error +detection and reporting duties by providing a replacement function `main()` which calls a user-supplied `cpp_main()` +function within a monitored environment. The supplied `main()` then uniformly detects and reports the occurrence of +several types of errors, reducing them to a uniform return code which is returned to the host environment. + +Uniform error reporting is particularly useful for programs running unattended under control of scripts or batch +files. Some operating systems pop up message boxes if an uncaught exception occurs, and this requires manual +intervention. By converting such exceptions into non-zero program return codes, the library makes the program a +better citizen. More uniform reporting of errors isn't a benefit to some programs, particularly programs always +run by hand of a knowledgeable person. So the _Program Execution Monitor_ wouldn't be worth using in that environment. + +Uniform error reporting can be also useful in test environments such as the Boost +regression tests. Be aware though in such case it might be preferable to use the +_Unit Test Framework_, because it allows one to use the +xref:testing_tools/index.adoc[testing tools] and generate more detailed +error information. + +[#usage] +== Usage + +To facilitate uniform error reporting the _Program Execution Monitor_ supplies function `main()` as part if it's implementation. To use the +_Program Execution Monitor_ instead of regular function `main` your program is required to supply a function `cpp_main()` with same signature. + +Here is the traditional _Hello World_ program implemented using the _Program Execution Monitor_: + +// tag reference: doc/modules/ROOT/examples/example24.run.cpp +:bt-name: example24 +:bt-rule: run +:bt-descr: Hello World with the Program Execution Monitor +include::partial$bt_example.adoc[] + +It really is that simple - just change the name of your initial function from `main()` to `cpp_main()`. Do make sure +the `argc` and `argv` parameters are specified (although you don't have to name them if you don't use them). + +The _Program Execution Monitor_ treats as errors: + +* Exceptions thrown from `cpp_main()` +* Non-zero return from `cpp_main()` + +So what if some function had thrown a `std::runtime_error` with the message "big trouble" and it is not trapped by any +catch clause? Like in a following example: + +// tag reference: doc/modules/ROOT/examples/example25.run-fail.cpp +:bt-name: example25 +:bt-rule: run-fail +:bt-descr: Standard exception detection within the _Program Execution Monitor_ +include::partial$bt_example.adoc[] + +[NOTE] +==== +Note that in both examples above we used xref:program_execution_monitor.adoc#section_pem_full_include[header-only variant] +of the _Program Execution Monitor_. Alternatively the binaries may be built and linked with +a xref:program_execution_monitor.adoc#section_pem_standalone[standalone library] (in case of static library we are not required to include any _Program Execution Monitor_ related headers). +==== + +Let's consider an example where function `cpp_main()` had bubbled up a return code of 5: + +// tag reference: doc/modules/ROOT/examples/example26.run-fail.cpp +:bt-name: example26 +:bt-rule: run-fail +:bt-descr: Error return code detection of the _Program Execution Monitor_ +include::partial$bt_example.adoc[] + +The _Program Execution Monitor_ reports errors to both `std::cout` (details) and `std::cerr` (summary). Primary detailed error +messages appear on standard output stream so that it is properly interlaced with other output, thus aiding error +analysis. While the final error notification message appears on standard error stream. This increases the +visibility of error notification if standard output and error streams are directed to different devices or files. + +The _Program Execution Monitor_'s supplied `main()` will return following result codes: + +* `boost::exit_success` - no errors +* `boost::exit_failure` - non-zero and `non-boost::exit_success` return code from `cpp_main()` +* `boost::exit_exception_failure` - `cpp_main()` throw an exception + +[#runtime_configuration] +== Runtime configuration + +There are two aspects of the _Program Execution Monitor_ behavior that you can customize at runtime. Customization is performed using +environment variables. + +[#id_pem_env] +.The _Program Execution Monitor_ configuration environment variables +[%header%autowidth,cols="2*"] +|=== +|Flag +|Usage + +|`BOOST_TEST_CATCH_SYSTEM_ERRORS` +a| +allows customizing behavior of the _Program Execution Monitor_ in regards of catching system errors. For more details about the + meaning of this option see the cpp:boost::execution_monitor[execution_monitor] class. If you + want to prevent the _Program Execution Monitor_ from catching system exception, set the value of this + variable to "no". The default value is "yes". + +|`BOOST_PRG_MON_CONFIRM` +a| +allows avoiding success confirmation message. Some users prefer to see a confirmation message in case if program + successfully executed. While others don't like the clutter or any output is prohibited by organization standards. + To avoid the message set the value of this variable to "no". The default value is "yes". + +|=== + +[NOTE] +==== +`BOOST_TEST_CATCH_SYSTEM_ERRORS` is similar to the _Unit Test Framework_'s + xref:utf_reference/rt_param_reference.adoc#catch_system[`catch_system_error`] command line parameter. +==== + +[#implementation] +== Implementation + +[#ref_pem_implementation] +To monitor execution of user supplied function `cpp_main()` the _Program Execution Monitor_ relies on the Boost.Test's +xref:reference:boost/execution_monitor.adoc[Execution Monitor]. Also the _Program Execution Monitor_ supplies the function `main()` to facilitate +uniform error reporting. Following files constitute the _Program Execution Monitor_ implementation: + +[#pem_implementation_file] +._Program Execution Monitor_ implementation files +[%header%autowidth,cols="2*"] +|=== +|File name +|Content + +|`boost/test/impl/execution_monitor.ipp` +|provides __EM__ implementation for all supported configurations + +|`boost/test/impl/cpp_main.ipp` +|supplies function `main()` for static library build + +|`boost/test/included/prg_exec_monitor.hpp` +|combines all implementation files into single header to be use as inlined version of component + +|`boost/test/prg_exec_monitor.hpp` +|contains definitions for `main()` function for dynamic library build and pragmas for auto-linking feature support + +|=== + +The _Program Execution Monitor_ implementation wraps several system headers and is intended to be used as standalone library. While there +exist an alternative variant to xref:program_execution_monitor.adoc#ref_pem_direct_include[include the whole implementation +directly] into your program, for the long term usage the preferable solution is to +xref:program_execution_monitor.adoc#ref_pem_stanlone[build library once] and reuse it. + +[#section_pem_compilation] +== Compilation + +In comparison with many other boost libraries, which are completely implemented in header files, compilation and +linking with the _Program Execution Monitor_ may require additional steps. The _Program Execution Monitor_ presents you with options to either + +. built and link with a xref:program_execution_monitor.adoc#ref_pem_stanlone[standalone library] or +. include the implementation xref:program_execution_monitor.adoc#ref_pem_direct_include[directly] into your program. + +If you opt to use the library the _Program Execution Monitor_ header implements the +*auto-linking support* and following flags can be used to configure +compilation of the _Program Execution Monitor_ library and your program: + +[%header%autowidth,cols="2*"] +|=== +|Variable +|Usage + +|xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] +|Define this flag to build/use dynamic library + +|xref:{boost_test_no_lib}[`BOOST_TEST_NO_LIB`] +|Define this flag to prevent auto-linking + +|=== + +[#section_pem_standalone] +=== Standalone library compilation + +[#ref_pem_stanlone] +If you opted to link your program with the standalone library, you need to build it first. To build a standalone +library all C++ files (.cpp), that constitute _Program Execution Monitor_ xref:program_execution_monitor.adoc#ref_pem_implementation[implementation] need to be +listed as source files in your makefile footnote:[There are varieties of make systems that can be used. To name +a few: _GNU_ make (and other make clones) and build systems integrated into _IDE_s +(for example _Microsoft Visual Studio_). The Boost preferred solution is Boost.Build system that is based on top of +`b2` tool. Make systems require some kind of configuration file that lists all files that constitute the library +and all build options. For example the makefile that is used by make, or the Microsoft Visual Studio project file, +Jamfile is used by Boost.Build. For the sake of simplicity let's call this file the makefile.]. + +The makefile for use with Boost.Build system is supplied in + +[source,cpp] +---- +libs/test/build +---- + +directory. The _Program Execution Monitor_ can be built as either xref:program_execution_monitor.adoc#ref_pem_static[static] or xref:program_execution_monitor.adoc#ref_pem_dynamic[dynamic] library. + +[#section_pem_compilation_static] +==== Static library compilation + +[#ref_pem_static] +There are no additional build defines or options required to build static library. Using Boost.Build system you +can build the static library with a following command from `libs/test/build` directory: + +[source,cpp] +---- +b2 -sTOOLS= -sBUILD=boost_prg_exec_monitor +---- + +Also on Windows you can use the Microsoft Visual Studio .NET project file provided. + +[#section_pem_compilation_dynamic] +==== Dynamic library compilation + +[#ref_pem_dynamic] +To build the dynamic library footnote:[What is meant by the term dynamic library is a _dynamically +loaded library_, alternatively called a _shared library_.] you +need to add xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] to the list of macro definitions in the + +[source,cpp] +---- +libs/test/build +---- + +directory: + +[source,cpp] +---- +b2 -sTOOLS= -sBUILD=boost_prg_exec_monitor +---- + +Also on Windows you can use the Microsoft Visual Studio .NET project file provided. + +[CAUTION] +==== +For your program to successfully link with the dynamic library the flag + xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] needs to be defined both during dynamic library + build and during your program compilation. +==== + +[#support_of_the_auto_linking_feature] +=== Support of the auto-linking feature + +[#ref_pem_auto_link] +For the Microsoft family of compilers the _Program Execution Monitor_ provides an ability to automatically select proper library name +and add it to the list of objects to be linked with. To employ this feature you required to include either header + +[source,cpp] +---- +#include +---- + +or header + +[source,cpp] +---- +#include +---- + +By default the feature is enabled. To disable it you have to define the flag xref:{boost_test_no_lib}[`BOOST_TEST_NO_LIB`]. + +[#section_pem_full_include] +=== Including the _Program Execution Monitor_ directly into your program + +[#ref_pem_direct_include] +If you prefer to avoid the standalone library compilation you have two alternative usage variants: you can either +include all files that constitute the static library in your program's makefile or include them as a part of +your program's source file. To facilitate the later variant the _Program Execution Monitor_ implementation presents the header + +[source,cpp] +---- +#include +---- + +In both variants neither xref:{boost_test_dyn_link}[`BOOST_TEST_DYN_LINK`] nor xref:{boost_test_no_lib}[`BOOST_TEST_NO_LIB`] are applicable. This solution may not be the best choice +in a long run, since it requires the _Program Execution Monitor_ sources recompilation for every program you use it with. diff --git a/doc/modules/ROOT/pages/section_glossary.adoc b/doc/modules/ROOT/pages/section_glossary.adoc index 797c8c8b99..e246cbc043 100644 --- a/doc/modules/ROOT/pages/section_glossary.adoc +++ b/doc/modules/ROOT/pages/section_glossary.adoc @@ -22,6 +22,7 @@ xref:adv_scenarios/external_test_runner.adoc[external test runner]. WARNING: The test module should have at least one test-case defined, otherwise it is considered as an error. +[#test_body] [#test_body] == Test body @@ -41,6 +42,7 @@ xref:section_glossary.adoc#test_case[test cases] (leaf nodes). More details can This is a collective name when referred to either a xref:section_glossary.adoc#test_suite[test suite] or xref:section_glossary.adoc#test_case[test cases]. See xref:tests_organization/index.adoc[this section] for more details. +[#test_assertion] [#test_assertion] == Test assertion @@ -52,6 +54,7 @@ positions are the one advocated by TDD followers - one assertion per test case; assertions within single test case - advocated by those only interested in the first error in a test module. The _Unit Test Framework_ supports both approaches. +[#test_case] [#test_case] == Test case @@ -62,6 +65,7 @@ test case execution termination doesn't cause the testing to cease. Instead the case execution monitor, reported by the _Unit Test Framework_ and testing proceeds to the next test case. Later on you are going to see that this is on of the primary reasons to prefer multiple small test cases to a single big test function. +[#test_suite] [#test_suite] == Test suite @@ -78,6 +82,7 @@ A test suite can also contain other test suites, thus allowing a hierarchical te The _Unit Test Framework_ requires the test tree to contain at least one test suite with at least one test case. The top level test suite - root node of the test tree - is called the master test suite. +[#test_setup] [#test_setup] == Test setup @@ -90,6 +95,7 @@ preparation. It includes the following operations that take place prior to a sta * _Per test case_ setup code, invoked for every test case it's assigned to, is also attributed to the test initialization, even though it's executed as a part of the test case. +[#test_cleanup] [#test_cleanup] == Test cleanup @@ -100,6 +106,7 @@ This is the part of test module that is responsible for cleanup operations. Matching setup and cleanup operations are frequently united into a single entity called test fixture. +[#test_runner] [#test_runner] == Test runner diff --git a/doc/modules/ROOT/pages/test_output/contexts.adoc b/doc/modules/ROOT/pages/test_output/contexts.adoc index 4b6fba7455..7ad9ee1281 100644 --- a/doc/modules/ROOT/pages/test_output/contexts.adoc +++ b/doc/modules/ROOT/pages/test_output/contexts.adoc @@ -18,7 +18,7 @@ void test_operations(Processor& processor, int limit) ---- In case of failure, in order to see in the logs at which point of the loops the failure occurred, we need some extra -information in the assertion, which can be achieved for instance the following way // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.reports.custom_messages: +information in the assertion, which can be achieved for instance xref:testing_tools/reports.adoc#custom_messages[the following way]: [source,cpp] ---- diff --git a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc index 37a168e906..990c00495a 100644 --- a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc +++ b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc @@ -109,6 +109,7 @@ types `T` and `U` appear as sub-expressions of the full expression inside assert :bt-descr: tolerance applied to different types include::partial$bt_example.adoc[] +[#type_promotion_of_the_operands] == Type promotion of the operands Given two types `T` and `U` being compared inside an assertion xref:{boost_test}[`BOOST_TEST`], tolerance based comparison is invoked @@ -141,7 +142,7 @@ include::partial$bt_example.adoc[] Finally, note that comparisons for tolerance are also applied to `operator<` with semantics _less by more than some tolerance_, and other relational operators. Also, the tolerance-based comparisons are involved when a more complicated expression tree is processed within the assertion body. The section on -relational operators // FIXME(qbk2adoc): unresolved link boost_test.testing_tools.extended_comparison.floating_point.floating_points_comparison_impl.tolerance_in_operator +xref:testing_tools/floating_point.adoc#tolerance_in_operator[relational operators] defines how `operator<` relates to tolerance. // tag reference: doc/modules/ROOT/examples/tolerance_03.run-fail.cpp @@ -313,6 +314,7 @@ The compatibility assertion xref:{boost_level_small}[`BOOST__SMALL`] perf The _Unit Test Framework_ also provides unary predicate cpp:boost::math::fpc::small_with_tolerance[`small_with_tolerance`] and binary predicate predicate cpp:boost::math::fpc::close_at_tolerance[`close_at_tolerance`] that implement formula (abs) and (rel) respectively. +[#tolerance_in_operator] === Tolerance in `operator<` Tolerance-based computations also apply to `operator<` and other relational operators. The semantics are defined as follows: diff --git a/doc/modules/ROOT/pages/testing_tools/reports.adoc b/doc/modules/ROOT/pages/testing_tools/reports.adoc index 6491d3f7d3..6f940e06e7 100644 --- a/doc/modules/ROOT/pages/testing_tools/reports.adoc +++ b/doc/modules/ROOT/pages/testing_tools/reports.adoc @@ -47,6 +47,7 @@ of the full statement. However, we can observe that they are not treated symmetr More details on how the _Unit Test Framework_ parses the statement are given in xref:testing_tools/internal_details.adoc[this] section. +[#custom_messages] == Custom messages While perfectly exact and precise, the file name, test case name, line number of a failed statement carry an information that diff --git a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc index 2cd222b0f5..f19078c0cf 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc @@ -257,6 +257,7 @@ A compilation-time check is performed on the coherence of the arity of the datas CAUTION: The macros xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] and xref:{boost_data_test_case_f}[`BOOST_DATA_TEST_CASE_F`] are available only for compilers with support for *variadic macros*. +[#samples_and_test_tree] === Samples and test tree It should be emphasized that those macros do not declare a single test case (as xref:{boost_auto_test_case}[`BOOST_AUTO_TEST_CASE`] would do) but declare and diff --git a/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc index ee304d2240..cc6174a0ac 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_organization_nullary.adoc @@ -52,7 +52,7 @@ Both test case creation and registration are performed in the xref:adv_scenarios/test_module_init_overview.adoc[test module initialization function]. Here is the simplest example of manually registered test case. A single test case is created and registered inside -the test module initialization routine. Note that the free function name is passed by address to the macro xref:{boost_test_case}[`BOOST_TEST_CASE`]\`. +the test module initialization routine. Note that the free function name is passed by address to the macro xref:{boost_test_case}[`BOOST_TEST_CASE`]. [#ref_bt_example01] // tag reference: doc/modules/ROOT/examples/example01.run.cpp diff --git a/doc/modules/ROOT/pages/utf_reference/link_references.adoc b/doc/modules/ROOT/pages/utf_reference/link_references.adoc index 3f7a59167e..6c935b7259 100644 --- a/doc/modules/ROOT/pages/utf_reference/link_references.adoc +++ b/doc/modules/ROOT/pages/utf_reference/link_references.adoc @@ -125,5 +125,43 @@ Define this macro before the inclusion of any _Unit Test Framework_ header to di of the http://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html[alternative stack], in case your compiler does not support it and the _Unit Test Framework_ cannot automatically guess the lack of support. -See xref:utf_reference/rt_param_reference.adoc#use_alt_stack[`use_alt_stack`] -and xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`] for more details. +See xref:utf_reference/rt_param_reference.adoc#use_alt_stack[`use_alt_stack`] for more details. + +[#config_no_random_dataset] +== `BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE` + +Indicates that the xref:tests_organization/test_case_generation.adoc#random[random dataset] +is not available. + +Unlike the other macros in this section, this one is not defined by you: the _Unit Test Framework_ defines it +for you when the standard library in use provides no `` header, which the random dataset +generator needs. Test it to guard code that would otherwise fail to compile: + +[source,cpp] +---- +#include + +#ifndef BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE +// use data::random(...) here +#endif +---- + +[#config_no_zip_composition] +== `BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE` + +Indicates that the xref:tests_organization/test_case_generation.adoc#operations[zip operation] +on datasets is not available. + +As for `BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`, the _Unit Test Framework_ defines this macro for you: zipping +datasets needs the `` header, and the macro appears when the standard library in use does +not provide one. + +[#config_no_grid_composition] +== `BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE` + +Indicates that the xref:tests_organization/test_case_generation.adoc#operations[grid operation] +on datasets is not available. + +Defined by the _Unit Test Framework_ under the same condition as +xref:utf_reference/link_references.adoc#config_no_zip_composition[`BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`]: +the grid, or Cartesian product, of two datasets needs the `` header. diff --git a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc index de763c4067..b5ae37f1c8 100644 --- a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc @@ -62,7 +62,7 @@ insensitive strings: "N", "NO", "FALSE", "0". [#enum_param_value] Values of an enumeration type are expected as case sensitive strings representing enumeration value names. Each parameter with an enumeration value lists all valid names in a -parameter\`s description. +parameter's description. [#auto_dbg] == `auto_start_dbg` @@ -673,7 +673,7 @@ BOOST_TEST_REPORT_SINK [#result_code] == `result_code` -The "no" argument value for the option \`result_code instructs the _Unit Test Framework_ to always return zero +The "no" argument value for the option `result_code` instructs the _Unit Test Framework_ to always return zero result code. This could be used for test programs executed within IDE. By default this parameter has value "yes". See the xref:usage_recommendations/index.adoc#ref_usage_recommendations[usage recommendations] section for more details. diff --git a/doc/prod_use/program_execution_monitor.qbk b/doc/prod_use/program_execution_monitor.qbk index 465ecea6ea..96cca27391 100644 --- a/doc/prod_use/program_execution_monitor.qbk +++ b/doc/prod_use/program_execution_monitor.qbk @@ -43,7 +43,7 @@ __PEM__ instead of regular function `main` your program is required to supply a Here is the traditional ['Hello World] program implemented using the __PEM__: -[bt_example example24..Hello World with the Program Execution Monitor..run-fail] +[bt_example example24..Hello World with the Program Execution Monitor..run] It really is that simple - just change the name of your initial function from `main()` to `cpp_main()`. Do make sure the `argc` and `argv` parameters are specified (although you don't have to name them if you don't use them). diff --git a/doc/runtime_configuration/runtime_config_reference.qbk b/doc/runtime_configuration/runtime_config_reference.qbk index ed16b23bc1..b1d515dea3 100644 --- a/doc/runtime_configuration/runtime_config_reference.qbk +++ b/doc/runtime_configuration/runtime_config_reference.qbk @@ -49,7 +49,7 @@ insensitive strings: "N", "NO", "FALSE", "0". Values of an enumeration type are expected as case sensitive strings representing enumeration value names. Each parameter with an enumeration value lists all valid names in a -parameter`s description. +parameter's description. [/ ###############################################################################################] @@ -695,7 +695,7 @@ Case sensitive [link regular_param_value string]: [/ ###############################################################################################] [section:result_code `result_code`] -The "no" argument value for the option [`result_code] instructs the __UTF__ to always return zero +The "no" argument value for the option `result_code` instructs the __UTF__ to always return zero result code. This could be used for test programs executed within IDE. By default this parameter has value "yes". See the [link ref_usage_recommendations usage recommendations] section for more details. diff --git a/doc/test.qbk b/doc/test.qbk index fdcf531a78..85b97b516a 100644 --- a/doc/test.qbk +++ b/doc/test.qbk @@ -215,8 +215,7 @@ [/=============================================================================] -[/TOFIX ] -[/include program_execution_monitor.qbk] +[include prod_use/program_execution_monitor.qbk] [/=============================================================================] diff --git a/doc/test_organization/nullary_tests.qbk b/doc/test_organization/nullary_tests.qbk index ccc69a3520..9cbf00e681 100644 --- a/doc/test_organization/nullary_tests.qbk +++ b/doc/test_organization/nullary_tests.qbk @@ -50,7 +50,7 @@ Both test case creation and registration are performed in the [link boost_test.adv_scenarios.test_module_init_overview test module initialization function]. Here is the simplest example of manually registered test case. A single test case is created and registered inside -the test module initialization routine. Note that the free function name is passed by address to the macro __BOOST_TEST_CASE__`. +the test module initialization routine. Note that the free function name is passed by address to the macro __BOOST_TEST_CASE__. [#ref_bt_example01] [bt_example example01..Nullary free function manually registered..run] diff --git a/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc b/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc index 57d6bb5b7ae6bc6170da20990e0f8f0251825483..60de38a9f76ddde1c9b980946bd592b7555734e0 100644 GIT binary patch delta 22661 zcmb7s30Pa#nW(Pz4Yac_Vn?iA@P>^6o7D?824}%wS>_5O7J=^-USwgBCY?ay#Nd+* zxN&0Kq!Zk@4Jk=OmNrhOZPI4iqTtj-<9T&D{bt%u7mPF0#%*8T|DP)f?B;#%d)MaI zy=S{;`Om+fd*OM>^S_Zqe-IU=7Qr=tqPy$-t7Fk|%&M`RKl{b3j1`Ce8ClbX=oTGo zW-V;Y1#yd>jcqZoacn%Bz$UUuZ1M$Ji;+!XQ&}sU#-?A8wwTzA7Bid4X1SOa3!Ba6 zz;6tj`-rF|mbC$lWAgyUv-toM*aCowY$3oTwg_M{Tf82AQpBQK5xeRU5xd%%`jP}Y zDH63ohV>z{PT_iP=wg7KnH>_wOi`@wC%w{(M z%wbCb<~nWc=I&gPh*Ls4xi1NgiWt#J@kz05%S@H{*HW@x!EG@?j#uq+v(6Jm4z{n| zo6^tq9pN0kcIOFa`+&#Q=eGCuxm}(wK|z2d(sN8b~SbFp^L;XdND_dB3FPLGqb zdmM**oWXb@hwbadtlX7(?c&ft@ka)KIPv#2Y^u~JeJNCW zQ09}dOgB7nVxQQ}_+*1JC=>6O`efm?8ceM=7n<*oHi=lqNB=FS z_@r3FC#J3L_lbP+cqq$?yEi}!LS2~0LHQXI%M2=@qypOtmCwZTK7}8XLe+37<9!Nv z0am-Wf>x+-PkH7H)bL3t8mN4sP75!>PScmtPDDD&oY_yy!8AY#xyUASEQ)8$n%5cs zW~;->4Y=(+PWKT{r`ifvUx#&-wb$uz^Hxu%(|Xv^-tBR;4aB)u7>Tt7G zzO!$jhqWGdT0NZ8;lWhi+T(&1b@W(0&J&&@+FUcV!S@Yt?M~j>-sko>TyCr9c%PLY zXz#T8c@O6}$y;*|MbP08Z)Kf)JLl?0EInj(xoI=dNsp`7X@@2{Tu1B?bSpY~xSMvz zVeNJC{XLF$=*V)P-B$NNPmhB;NfDXH(zeaC!Q(DZXJ6ZZ2L=fvJ2K$lSS#Q-4j+cy zYvqqSdV2bf3zNXXE(qmVJ6t_ZVQ3s;+8yT5Z*X_t5v$cUaZmy?8I*Rw*0U+e@3pZ; zS&ysNFUo9Eoacxv4jgtHx9l*^^oG`rKjJ zf+b<1@!W%B%w#n@X!U37N9sr0C)Po>Hg}j=$jP0m{OYk$W^~;|+C<}|;r#wNUB;Yp z`*h{>(b=@w#;b-m_Rp=|4kn9=lL4h%Y&8dDO7yR!B7O%`aqeh5 zc_IGw8rsq>tS;dmpw;Q@2W3aNzJY$gN14m*c5+-9 zW`38jgOSq}*+sS_r7;hXgGup4E%*j#%;WL^sh09R14r&^P0{PHAO}>`o zg64F|uar6AIVfSB9WXp>gmYm_Oi&3)b~g}t9`{ZNb5stGhoh++ZjD9qx8z)CXOA_W zl&5?o@51`EBq6mjTe!vNV+f8TI01lH0HBMGb4MOZO=a$oOR0^}%I(zr)qcpmEaEEQ zhvF*7;T?j{;Ez^*M08uMmc;`;hLb|e8S$IoHI-spPD zZ|!y$Fjl)=$&jC<`{B*gPsb}?fQ~&Xe$-6d8LuRpS=pds*gP!m5VP_}l!Hp2%qK^d zGAiL5WJ_i$V%qDh(mYKPjHOlDT_i5QE$`CgA zG+n7EbCAZIrn*taeFn00G)oLmUxp_=K8-S5rC8)sE{hN&;;sT1#XT4IWlYBgQw@}7 zNhvha7W+NL;o@DZu#C(UE}bltmSO1#L)QEBT%AwfwU%~J*QGN0MD~Pm6Ra^@*|4HA zD}o9e$m*d4WrC5y!aA!lIH*S(SBRoZ!Tx zk~5CG*XpFm7SnJ?HsI+f+{kr8e=duIN)W#KSeN@qP!9XOkK+XbvxeyN&aR~tJVYkE zP@YmWZV%ic%Q`&J5mdAfa3H^VC|VB}t)SB5>;+Z~qCf|xeGV5TZg)(%tp_p=9BgfC<=gUG+ib0TUM4x7 zZvc4AOjL;egoc7VvH1vdk_I7C{Ms$Q0eaDdix!~ns7`(1?%FF zxNwhRF*;yM9Ob;z!L@gCc1%8lpcIRnP~zmBcHZf4r=oGE)4>X~p%x3BM1bVQX5o+u zaQ}qhJOWCxC7iQo1wWwF=qs38hX4_kI|Lvo0h$|>1CKr8^aQ2Y!JzDzqi4WL$uoCa zB&rv2NZNqMbh>(2ZUXLkl*z5uLm{fR{8J&2FdV;E6Cyo5eGb+FTY-OU=640R7(dyw zV2PX9@u4OAV{;td*3VnAJ~qccRl6t`#ifp)K6iR5=jEcyMYG00-j>&24SUM|8<8%Ck`h z&0T;z?jitN)C!>i*O@yAAjmWc>rAl(>D-DHmvdAa2x{xA?0fF3-nXy5s=A3XFA#U= z5+A}Qs--CS;lhZ7CBntISK#5UK%zH3v;tvFT1KS9WPZ)>fepO7_P5&+J2@YM#}H7& zdJ^vj0Du@qd5na2whJisElB010C3fX<$jXu@BTVxMHh@h9wcG0| z_cmAWvscycYYIvL&1l2H=)IM-)hh;i3JaU;4xV=%aRc%naq{-VPLOsfJH>vGx()fM zD9&+b0eDTJ(XFiEC+9Z&BlN+xv7Bl84wM36j1GvhWE>EO@8RARvgoY71@}Qsd#9rx z6+fP9=l&Us&~e@^uW|2^w>G6PkCWgglqIT4k7aqVA+gXX-Hl>lsj$%qHzvO*&0wA) zlFb{EDj>Z*#24UJB+|eiRUN-2C4YFLi0I$e%$(hvDwd8iZ3$$$tep81SuFcC868a} z72}$OD$!YGyZDHxUEG!gY(?pbrOf~!6+qgC4x$+dh*V1~R^T6uD^*}81X?|NCGN0r@@=~ZQ)EvZHE`xJAjDCzI(w<&~Gd>ONFzi@MyB?WD~C&=(Ykl#UPbMkk~&rpO& ztK#Hu;`;uTq*t*lET}%_?BK}YMAKy2ye@NcUqF{TEL}*?elh=2{`K^dKzhl1`ud+6 zYbP3K)85H^BlBwJTLq)5$Jdc{bH>_X1%Mlx=;7m!Z<$#Ap(bg;7&D$fmOpXiV)yy( zXLWTDUUEeqxkr52p&dIfq)|Lm+=mP0>_B+^@wOmtdgm$O9?v}nSQB-{O_tHeX6YN z_BO^KGYeI}Ol;L_HF7A8*X>z`9H~y1gGo-_6-`CI!6PbV3)<+y3E$bOifK`?GBDz) z*&LAinHJ4*cAp}QBQ07smsLV;6sv-=(X1Mvj@1Cvvs!=#HVUATjRt6PN?F|_BIIp& zfqhdCsTS4%Forb(jAcy#<5)Amc-8_i!I{{#5hYyvW}((f=uBZ_*jP61CFD79wWPA~ zEmk%G>ZP%X0MpqdfEjEuz)Us;U>2JSFq^dk%wf|2<}Qy*mJSoJ4}^CU`P({0TuUCC z0R{5eOn?P!7Qn)j*)|*5P-A6YAP>~Mw$%kPy&S9UcJls32s1fT%@Bqkg zc2sm}Ym`(2kED$76DZF862UZrR{-$K3^1MICgQc%un(*sU|Hpg!g}R(#MBo^OKlue`j3aeh;Z$ z^K#FZX9Z1Vd^co+$xAMZ(w(gvsU!cr!_i)WRn`>emZ!Dm*?`*>x4PR-tu9!s#h? zW_2zv1CuY~g>4L`Ua5~c#()u6Mt^0jJdz_Jd+KA!f9=$g+9yph;Dk_x8HZ5SruLQ) z>#icdqX+DVMa`F)pcFJQ=N;*xEdJ0PCZA5NSAHlzi_eGWQ+LFzr#KeI3nnEsKX4eV z?0_UZo#tTl{)VQ?nreG}gMIs+s%j2VJv`YIbDAI_BJIF^P=znE^Zn$Xcg4u>;QVsr z7rRoDb*AgO^nfn?y3Q8R*`_kD>53Oj@e@^JWpi39`RlIDAXaVM-3~Z#VRv%%PV5iE z{X70h1RR~m*5#}dnFNnm9~MG`vJTgYUZ*!YvcmLPA}0TPw+&kTd`~Q?tci(5o$XOD z{tb&d7?uG;hr}o5l19iw>te{RJX1FqrJ3+tg5jEJ0*vx*sy@+==H&x0CvDbVM?2RC zHrPHi%DOl!#UyH7F0gj=abQtq!9?BD*WS$+-6iW`f6)ta8zsf38PYZzN8WDGF=EQ& zZ#GzDB2EW7IK!LCAD@z!hu_~o)n*WZDXM=0m4*HNTeyRXDZ>Q1WpOb=vx3_4BYO(` zK+#3~T1fx%kZ8eV9^WvwVPZ8Y9j;o)$)EDP?7i%L*?-v|$k{qtGG01XI>81^8FSjY zt5pCfV*zDcUR7OV-&ajHSx6zEQX;p6Zw5joC ze!Ce2WpzHt$S`DTUl9*VJPK%+UcQL+WKil+(Ij&9zE~+ZPbB10y&&OultjBaDLUeI z0fCCkBSY(A!3JXz`(!8yEyk0GsPd`6J`)3s!K_4%01xrV9~jz&tBGn9|E$YsIjClp zKIt&__ZBxr zvC%%wa(>u+r_+U}0{laot~6{qEt1A7S-nq#GHikfiO`_NrwRAVkNpBQWC+v{iOt~H z06U?|+3sSU1>oOk2Y9^G;jua$;C>PI*kLCa#lbrRjv4S0@=oebfd_{h+=Gsylf6Af zYBk^+y(;;3mkT_KkOeLrpj|ExGC}Lnfj<1nJM4GDzI5hUmlt!&0S^}MWJ~WVZSCyq zL8Duw)*(N2hoVkRJ)Rkk1FeU)?b*}RY;Ue^YHmH$cF4+6mJTBWN6TG4Hr{&7#k;^8 zx?;l7e|CD~DsYN*pf3uR&cQjs&*lcVSC7lV!=&R#>8xA(2RwdQ<(`wYSz0Jhus7vJ zdWilvXfrZkx;lJ6I5lWGrMOl!PC*d?P1?Z|X5~RYEV4FZ2V8ulF}gV2PG>)Fb-=j5 z2kb{DuocITNjWPLbf0S3G!t+YbAY zyC1<{0CS z?-xuYzk}zX+~tP8JGuYDOe(n5U@{nsS?cElZ3-EgP$MFW2BnA{l-UI(ouE?AVVR#J zKn*e|qYD>Q3W)4vsg@?t2dkg{3fk2lps+U%c@t$#_Xxy#W1Dpt{hX&#g|MwU+;dUd#3mM z``&AQw|QQ_W4Q9;l69m0%<;Ujyz9oyfH8Bj@x}Wu-9Od%e9JZCs@am^?H}umqx{6` zv14_wW{gFR%0`bZ#HU&5Sbt)dY2_$2JsHEZdim-G50t` zItXSE5PS)vwu-q2$>)0$NLgb(`DKfVe0yVz3Wa2-qevj17-PtEW14^1{mR#10P zhbM~sqA^Xagop|-lW;a48GG9zW|idDeX)#$e9~gksb7Ni#)}cTGeAK2q{U1u`$}@b zH+2~r($I>f9+ceZg)aPO~K!SCK(6^K&rM5Z+9d38v@io zX@mk*TDZ^fu^vDW;+~M^f!2M5W3Z`%m_;ezJ9uZuLJ}ZKg7H(^w5zhI&R*YKxvPFV zC&LPRpaggoC}muaRZdaucrV^=K(G-(9RifLxJ>|p;&vYXoLm&PP$nXc)0Ql%$77RT zU4#k>y<3aK&kkTnM7o@ttEk=d7#d&8w#y1LpPcyI_tT z-!ZmhV&Efl*3Hnp=i=$}r>EHIHPeTuy600%ubDSPv2!GEf0_RrvtTfewx5ez(3{59 zW9o@@*Ys%%dc$brm^_jal84I~MN5 zrL|WMzubAbbNa+p)75?N#=dWS-*h$UT2TYMPI%RIbAG^_KUFoIHg7H&Wj;2U!y`U6 zC4E_QSu3q-3(gT!0GoIOwKm z91=f&Qmztc>nETRO=hbh1^_o= zc*F8Gv^YQm7K4mcgel2#v!;8Rm4UuWKL3FY>=@*w`{HBJOnT2XltSq*`Qv?S87;}U zzgQCLV&&hrWs7PMwk8TIV4rC7%4ry15j8*Gk+%2umwLserD31)mHYGjoCK!kj*Ln= zHf7M*1RJQ@zN@}rr@gsyUu|`Bldwfm;NXT4e1d?ADW~x6R{$X3hwd_Jm{vi9f+V8E zyNJ*c1P5z}5IYqTGC;f_l@DaB#|^~afp$RQ))=l?asry18>y?Ov*%McEu>~%96Ucb z)ij;;QR+r8gqcehMNAaBA7|gqbO{TnLEt^7qVb355_9}lWO;NE{sw}2asCyPyNy4Uw z@-k>@=3RMNp}cIGnsZlPF3n?3+I$j^6<$p*z`lazC!a*XJ~5jIT^V4~QBU;e`y?kA z9z0NN0e1O>_yo8ZfW^=#!*)r#7>O2J7`AZPiW=xzdgTWWWbtj_e}e2FljoJ@W$}5` zQYDaNq}E>jfuaGF=a9s_z+P9VW8|Y+^EMr2z{E zc&FUmAVLDb^waUmj%66aQYMB*RRxOzd& zuv3kNizPLOGmjvF4@T{-+`ezmJ}{)9-;?4Q_iN11@opD{lX)OQhlVT!HI-Gn_cYWu z*Y9a)5^P@~dH4_%7f|t=csGl+B?DX!M{)FJ^48(RQj~{RO1>)uUoDJVFv?KDcLhU2 zgne~J-+ozKpg+5LWb@-?6IB;?pWhwO*cME&6Pec&iUJ8mQv)a=zBD+WP!=$Oy{?SB z?)-NFWoKUP$Yf|BAN7EHmB(GIr?V`Jr;`tEL7WrrRqS64 zM^w=$OAL9wA-by{{Ld-41Ir>sWvCGF5!bgW?2gVShdSe#E5zH`l~@6#+d<5XTuQi; zz~AjPsdz91_Td$aYWr6#q1<;-N&R0F$h9bc)lMr zPeFu0AwfVdN}8xd(Lw^fS&8M46I4@sD#g~IVplyV?qH5PNDS^oKa~rNE9C;LAnO4O zK~GSLQ6r#J@*K(uK?Q~_!Xx_Mcp+j^NyQQrJdR@*sGx8N?Pv<;z zlXJybo)QTp7fph&NLM-^o^2{&`RJ4%!k$xJv>hu|A;7K9?Z>+&xZ}~H8Cd~At1Tlp zkEbxdo%#IutBkw?^4n!7DnO*+&ARNFPfx}(%|L!NjA(@uSQ%#Yg9^E|FrnU%SEi@}=!)uTgl(-X>Uo~gLC8fwG z=IZbs*-ALtXC6C=>%C$eYA6&Tc;P-ifPJLac1qZn(KHsiNnSWzon8U0v?J9EUlA&J z6&B)A)uU?gMIR7oa>(#eaD=E84DqO2<77G@P!BDnOJn#HIC z^{^V=rFjGbPf6uba|xKNsUK`m?y-csJ)&Zx!X2y=q!7-aYiQl(;P18%z|+jQXoP&SHioPQ z^TKx;R75dJ1+Q+9WW>uJhY=>cnL-XYNrRwZ%B)+m*sb6-p(LGRFqIuphlDMGI2lx; zF%vArp$Kbm-C(LBloHmc@4_?y&YpbU%ueddD3)lp3%|m& zDsfh=kOsy=^fn3ff*KQ%UI?+6-^M%I^N;cF5WHN7#Z)=n10Z2wFeuXFFx3cewrUaA zfn{lLQ78n5I^~~osCF14l91DIPAuXEa5v?ss1PV}Il1{r+;$M&Mf?^h^cgId&Lnua zrZR{9^Sa_;DFi&4V}_OJ2+RKzqF9V)kBuCgiz%2oGVS^Pn)gcHExD$vBZXi7nm@W| z+8l^pH!Qi4lr`Bo&CDmQfxslyPG)4+aLs7df>t-W8O(T@FXvy*pJr#P=JP7A=hX)C zYUlIn=hAirOgjSF9V6S(^}dt22~4+n#5<>q|7+Nd6TrB zdC*UL5J6^v5B~@BDkyQVtbhz5?T_+YLe(!tIfahFONN z>L>%Opv8whaJbC@amUVTM1-eF$rE3_4z(47K?pk^^+Do&`4W|MoJ)-42%K$&~m2Ahj6ht zu$qcJ$n@ytlY|KvD+UK1qz!_y=4Pbiv$w725hZ7yR1@iUEMvz_XmvEBzmfd)HD$zl z3Mbj_yuFqr533}6sgLxH#$-q$Y95si!fKu;A@ovIY=!U`P!Urh%mImKxF2|e(32J^ znNAw-Gbeen!U@P`SmhN}*iYG&gH}!LvL4!%i$OjnL}0jJDuAkj|5n_UPrOei;R%Aq z0~Sq)-NA^8NTAg$?pjTQrNA^2y#=bBsQ{Oy*rxH8k+!i!KbY^V5P(A+MS^?>?ioCJ zfvzy56GdKeQE`JeTF5Mf<6k_;+XBt9Sn)U*K3j$CQY2vB^n(~eTwYpS>;t-t@x<_! z($ZWoJ{E!_ru6_sUlQmF=$C$gPvPwk0odZX|HS)afO4D*07MS&-n(ZX>ISuDdWdyk6f>G5ERPNrptGdaKI0!VE$6-)?GbrIt@8o;^KsdZPU!UHU>y{KWPbB$L~pS5B%X8UitSqmqyHmPG}W7N{+l*RJbQ1G>}~ z#4jo?DPGiGGH9oouNRgF3d^sW=B?H9x*9T1aIb(3Y(DJdLlL#%qw8-hp+)LTJL-eK>4#WD%waOogU`| zp<78bPZ#+?$fWGjt11jj6<$Ngv`|_aq9mDKO(eHXO-VY$+58&UPKfswXdU>{1U4)P z$Wq8hY9~-SRB2ZD(Lw}^oPJu_bOhJ14oYLlN$hypSlOf*d_^P5Um6p>QUyFnpFS*s zs7`!6@!V2;hIgR5}cUJ-aZiH9`T2Giij9kE0knkO0FppIx zVkCwU$-#bAgpi4G-Xnx;xfl1g&z#x#e|bAl93a0B_%vkb+h!8orIs_oiy9A@YyQ99 z11)jPnGI(~rRYS{`lQ?_5Os7Wfwhp?2KI_nm6X+l(jdGf1&1hTbb@>w7N#-KSQu)e z_KUkfn*~};Uhg(rq-@0d6VeYu@hftqnLaI!Ow2}+v2hESdEo)2b5U0^d3U^CNXTP# zKK0$yo-W%-TsEHu7SI8AQBVoZohDV3Pt59%h+dMCp%*hW(X7E24co#Zyb9toXXHJEaquH3{WEPHSV|1pLTt1)b zk8SXpXzV1AY~cimtsH1JCGmpohf2^?D$>A_BhSe~THGtK7Fz}Ln2{zFa(%}O`yh^^ z15N{bb<1gRh?(%iNAxxlliZaTVs7{SS6Gr0UQ5HOx5@b+Rf)mR@8Jq;`;lXMS2Rf)M zEyZ)F993v_P!b8tic6p|Xl7Xv(MPA~C=!>S!W<8YZfK)1R&&lmR2N?K14%cSN2|cQ zQcJXOGT9WnB$BJZ!G6PN8Eq%I6Z=0jrY|I=PBQ0fCila6pQdTU<@*9jYv&S6MkS+_ zqYm(E!&zs|m}V|%)w~|PT>AC!`>9N1iV<3vH>N{~=!&PXBWul5{^&^M!g+nsbXq{a z7JgS$zGh5cR6&mxqeVKyu;gQnVL@k^FkehLpAyjJ+=wr@9=|FOziPppFi|^s3>@;O zFQ1<62ozVp&jgC$+|!Og(vI73P+=D{D#t_FcXu=gdb*Hhd-33 zS=+8Q2C`~~tIjrzG)$}yXw%927j~-YEnpDXRx$X?eM9o{eyb~om35+bdD$t7*P1TG)GZOchvgd3(|^ zwLm>8rGcykJKo9OFLp9 zEf8dR#VEt$zX}@4{Ie?tqW#8E$(ueEso0XFW+kjD0okIS@-izq{f#mi<38n6g$}5Y z3*Si7V87|LocybAm||nX$;U)|J{UCB@SEd_C(++bmS~oX?)aun*#Y){IQ0Ut`CF1D zzu%_vg2B~b}1Rm&?_ExGwkiy{gdF#r#Mh!KBum^nZ+r_QHEp#jUXdb|Tm zlkl|;F$iUbP>2HEEEK7>LlGgconqEbeB6wyhd2hJbHudF?ZZ@5D7j_?)c$)v+21<;$nH5{N!<~Vv3!96A>i6Lz5oz&L!7huCLhFjSme8%)BuYza+xd#l

I()Lq)Gr7-m682n0n9 zXG1O62IRs6uof!5;o^WshN!~BdWr;{>yC0ukE8c6>)7hej+nbbD@dbGx4@wTM-RWX zC{%9k)-+JsXuSPHqJ{W`i?QcpCk@XeT#vT};%y(r=ZE8EzR?0&S?s1EIEF@cy^-of zssuQUWG<+y-dkV0uX1mly|TG^U;Q>AWb+kmp zfND%2;x`X~v*qBMueQAj4S5w=JPmUetRxcQ*x`eaBcONaBnj=_0Z6^;7zsBGeOpJiuCHUr5XCF(CNKv{5z6bca7TSZN zu}^=-@}D928v+K?sL}lo_((A!7Sk}ofXhcfsm@lo^K)hROnrXnr{c;Hpv6|;Z1>E~ z6gGGoa|aP%Ag-C~T$oHDuwkHyTTG|iiuhjxKwC&oIuZ@gu! zWzM>8-m-qEVM(fxZD(#9#j>qn(uj^5-gmZTq-8Fya6YPNsK$R=DwCBhMW@P&mui?i zS<=!2aAdQBS<2ohvo3iUsjP-s(ig~*7F!wG1DVVm>H*v>MJEH;s+F0RlBCdrHb$1P zv??0jw`5hx8kofdktKG#cC2=M*VwK})1+%UW;S8oTs5?N!Bjc4Ye}j>rVaX*y#yH_CVDN3DW56#$ zj04M-BS}Ve;m<&mEpg+mW35Xfg(_pXdO>GC>wV0-ptp=`$F$R?>4BNVS?4=lZ*|Qj z*I(1`_*icq-9J%1S$V$xBYpNQKWO9@O!!Ejehc)=3;}Vd82oMMfMC{s9qt;y#W;ff zLP8i+Qqic=Q<< zm9^1B)&DJ3$}(=5MKaZ}u9yke|WNZwV*D)oxHJYtwf zrH`9%GcNK# z&NWruqDU;;!Au=qNX)pNSQJPsx}I1PNGzF8T#ru59gJ{ZVgb!HkJWwM43T7mmj`E? zu4aBzTsvo}`$$_4u|ZJoPZDhBPqejL6yD*r26)}sN=;>^i-=#CHXhYJq9^0^lP|&j} z+=vfz1WT<6#a#>&CF_4=VrVL}8Qo;0<;NPGd{FVl?~$3|V~%n%`D1e?G=?VKdoHfy zi!16Z%lL~m=`@93sQcoHfwS-zew>^T)8LgA7UC!KyojRk1s)Oi27+#~@MD`E@_3PSmjp$z(zID8`SjTw@N{ff~YYe zj#CvBJNn@q6L#nmEKGMJCE9eTFJoE*f_VU65atz>_QJV;4uzLy+=)W0{tcCZ-1wIV z;%i^nhewNEY`xU_YR2^OtLpizokM%BNq3QgpFFR>A=M7=AFYGv`p)y6*Q7Z!Kl{lB zCa(fs6ja(FUeyK4nJq7!+gHFn0EJ z1m8t)6+r=3T!o+zK@kGPQtn9vtZLHksM72!n$~@_s0Z|5&R0a?PSdBu$`W_&)_gCEox5 delta 15627 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 I3^tDc1)imQ^#A|> diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py index 275ccf6958..9e2d62aa1d 100644 --- a/doc/tools/qbk2adoc.py +++ b/doc/tools/qbk2adoc.py @@ -55,7 +55,7 @@ "test_output": "test_output", "runtime_config": "runtime_config", "adv_scenarios": "adv_scenarios", - "pem": "prod_use", + "pem": None, "usage_recommendations": "usage_recommendations", "section_faq": None, "section_glossary": None, @@ -65,7 +65,10 @@ } # The introduction is the component's landing page. -PAGE_OVERRIDES = {"intro": "index.adoc"} +PAGE_OVERRIDES = { + "intro": "index.adoc", + "pem": "program_execution_monitor.adoc", +} # QuickBook tags naming a C++ entity documented by MrDocs; they all become the # `cpp:` macro contributed by antora-cpp-tagfiles-extension. @@ -89,6 +92,14 @@ } MACROREF_PAGE = "utf_reference/link_references.adoc" +# Link targets naming a chapter that no longer exists and has no successor in +# the narrative. The Execution Monitor lost its chapter long ago; MrDocs now +# documents the class, so that is where the link goes. +STALE_LINK_TARGETS = { + "boost_test.components.execution_monitor": + "xref:reference:boost/execution_monitor.adoc", +} + # parametric_test_case_generation.qbk gives two different tables the same id. # The second one lists the random generator's parameters. DUPLICATE_TABLE_IDS = {"id_range_parameter_table": "id_random_parameter_table"} @@ -260,6 +271,7 @@ def __init__(self, root_file): self._assign_qids(self.root, [LIBRARY_ID]) self._assign_pages() self._collect_anchors() + self.link_targets = self.collect_link_targets() # -- loading ------------------------------------------------------------ @@ -418,12 +430,25 @@ def _collect_anchors(self): found = [m.group(1) for m in re.finditer(r"\[#([^\]\s]+)\]", chunk)] found += [m.group(1) for m in re.finditer(r"\[h[1-6]:([^\]\s]+)[\s\]]", chunk)] + # QuickBook derives an id from the title of a plain [hN] + # heading, and links do target those. + found += [make_id(m.group(1)) + for m in re.finditer(r"\[h[1-6]\s+([^\]]*)\]", chunk)] for anchor in found: self.anchors[anchor] = (owner, anchor) # links also address these as . self.anchors.setdefault("%s.%s" % (sec.qid, anchor), (owner, anchor)) + def collect_link_targets(self): + targets = set() + for sec in self.by_qid.values(): + for kind, chunk in sec.chunks: + if kind == "text": + for m in re.finditer(r"\[links?\s+(\S+)", chunk): + targets.add(m.group(1)) + return targets + def resolve(self, target): """Map a QuickBook link target to (page-section, anchor) or None.""" if target in self.anchors: @@ -432,6 +457,15 @@ def resolve(self, target): if sec is not None: owner = self.owning_page(sec) return (owner, None if owner is sec else sec.id) + # The chapter tree was reorganised at some point without the links + # being updated: `boost_test.components.section_pem...` still names a + # real section by its last component. Accept that when unambiguous. + tail = target.rsplit(".", 1)[-1] + matches = {s.qid for s in self.by_qid.values() if s.id == tail} + if len(matches) == 1: + sec = self.by_qid[matches.pop()] + owner = self.owning_page(sec) + return (owner, None if owner is sec else sec.id) return None @@ -502,7 +536,7 @@ def repl(m): return self.DEF_RE.sub(repl, text) if code else text def build_def_table(self, page): - """Decide, once, what each [def] becomes in prose and in antora.yml. + r"""Decide, once, what each [def] becomes in prose and in antora.yml. Asciidoctor substitutes quotes *before* attributes, and a value coming from an API attribute -- which is what antora.yml sets -- is inserted @@ -581,6 +615,9 @@ def inline(self, text, page): return "".join(out) def link_macro(self, target, label, page): + if target in STALE_LINK_TARGETS: + return "%s[%s]" % (STALE_LINK_TARGETS[target], + label.replace("]", "\\]")) # `boost.debug.under_debugger` and friends address the Doxygen-generated # reference, which MrDocs now owns; route them through the cpp: macro. if target.startswith("boost.") and not target.startswith(LIBRARY_ID + "."): @@ -662,7 +699,7 @@ def image_macro(self, spec, block): # -- blocks ------------------------------------------------------------- - def render_body(self, text, page, level, headings): + def render_body(self, text, page, level, headings, sec=None): """Render a section body (no nested [section]s) at AsciiDoc `level`.""" out = [] pending = [] # anchors waiting to attach to the next block @@ -684,7 +721,7 @@ def render_body(self, text, page, level, headings): pending.append("[#%s]" % inner[1:].strip()) pos = end continue - block = self.render_block_tag(tag, inner, page, level, headings) + block = self.render_block_tag(tag, inner, page, level, headings, sec) if block is not None: out.append(self.flush_anchors(pending) + block) pos = end @@ -716,10 +753,10 @@ def flush_anchors(pending): del pending[:] return text - def render_block_tag(self, tag, inner, page, level, headings): + def render_block_tag(self, tag, inner, page, level, headings, sec=None): rest = inner[len(tag):].strip() if tag else inner if re.match(r"^h[1-6]([\s:])", inner) or tag == "heading": - return self.heading(inner, page, level, headings) + return self.heading(inner, page, level, headings, sec) if tag in ADMONITIONS: return self.admonition(ADMONITIONS[tag], rest, page, level) if tag == "table": @@ -747,7 +784,7 @@ def render_block_tag(self, tag, inner, page, level, headings): return self.image_macro(inner[1:].strip(), block=True) + "\n\n" return None - def heading(self, inner, page, level, headings): + def heading(self, inner, page, level, headings, sec=None): m = re.match(r"h([1-6])(?::(\S+))?\s*(.*)", inner, re.S) if m: depth, anchor, title = int(m.group(1)), m.group(2), m.group(3) @@ -755,6 +792,16 @@ def heading(self, inner, page, level, headings): depth, anchor = 3, None title = inner[len("heading"):].strip() rank = headings.index(depth) if depth in headings else 0 + if anchor is None: + # QuickBook derives an id from a plain [hN] title, but scoped to the + # enclosing section. Flattened onto one page those ids collide -- 25 + # runtime parameters each have an "Acceptable values" heading -- so + # only emit the ones something actually links to. + auto = make_id(title) + qualified = "%s.%s" % (sec.qid, auto) if sec is not None else auto + if auto in self.index.link_targets or ( + qualified in self.index.link_targets): + anchor = auto out = "[#%s]\n" % anchor if anchor else "" out += "%s %s\n\n" % ("=" * min(level + 1 + rank, 6), self.inline(title.strip(), page).strip()) @@ -1009,7 +1056,7 @@ def render_section(self, sec, page, level): headings = self.heading_ranks(sec) for kind, chunk in sec.chunks: if kind == "text": - out.append(self.render_body(chunk, page, level, headings)) + out.append(self.render_body(chunk, page, level, headings, sec)) elif chunk.page is None: out.append("[#%s]\n%s %s\n\n" % ( chunk.id, "=" * (level + 1), From 0941594455f96c71f345c4c7ba8371e3b02f9b0c Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 12:24:14 -0400 Subject: [PATCH 07/10] doc: polish the converted pages A rendering pass over the built site: no QuickBook markup, attribute reference, xref or include survives unrendered anywhere in the narrative pages, and no paragraph starts indented, which AsciiDoc would turn into a literal block. Three things the converter could not decide: - test_module_runner_overview had a [link] inside a code span, which QuickBook rendered literally too, so the sentence read `--[link ...]=no`. It now points at the result_code parameter and says what the value does. - The "Notation" table in the floating point chapter had an empty header row. - The SVG behind --list_content was linked as a bare relative path, which is not a link macro and rendered as text. The file moves to attachments, where Antora publishes and resolves it. All 118 example blocks resolve to files that exist; example20 remains unreferenced, as it was in the QuickBook. Co-Authored-By: Claude Opus 5 (1M context) --- .../{images => attachments}/boost_runtime_list_content.svg | 0 .../pages/adv_scenarios/test_module_runner_overview.adoc | 3 ++- doc/modules/ROOT/pages/testing_tools/floating_point.adoc | 5 +---- doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) rename doc/modules/ROOT/{images => attachments}/boost_runtime_list_content.svg (100%) diff --git a/doc/modules/ROOT/images/boost_runtime_list_content.svg b/doc/modules/ROOT/attachments/boost_runtime_list_content.svg similarity index 100% rename from doc/modules/ROOT/images/boost_runtime_list_content.svg rename to doc/modules/ROOT/attachments/boost_runtime_list_content.svg diff --git a/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc index ec1ceff505..b4def0b616 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/test_module_runner_overview.adoc @@ -35,7 +35,8 @@ The test runner may return one of the following values: |`boost::exit_success` a| * No errors occurred during testing, or -* the success result was forced with command-line argument `--[link boost_test.utf_reference.rt_param_reference.result_code`result_code`]=no`. +* the success result was forced by passing `no` to the + xref:utf_reference/rt_param_reference.adoc#result_code[`result_code`] parameter. |`boost::exit_test_failure` a| diff --git a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc index 990c00495a..d914376141 100644 --- a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc +++ b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc @@ -188,11 +188,8 @@ https://en.cppreference.com/w/cpp/named_req/LessThanComparable[`LessThanComparab ==== Notation -[%header%autowidth,cols="2*"] +[%autowidth,cols="2*"] |=== -| -| - |`T` |A type that is a model of `ToleranceCompatible` diff --git a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc index b5ae37f1c8..1bd6df1702 100644 --- a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc @@ -281,7 +281,7 @@ BOOST_TEST_LIST_CONTENT The following _deliberately_ complicated example illustrates the purpose of the `--list_content` directive. The SVG generated from the produced Graphviz/dot file can be downloaded -images/boost_runtime_list_content.svg[here]. +xref:attachment$boost_runtime_list_content.svg[here]. // tag reference: doc/modules/ROOT/examples/boost_runtime_list_content.run.cpp :bt-name: boost_runtime_list_content From 30ba40f550bd02d87c65786d179aecd7e916f013 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 12:27:22 -0400 Subject: [PATCH 08/10] doc: wire up CI, old URLs and metadata The CI workflow gains an `antora` job. It clones Boost, because MrDocs compiles an umbrella translation unit against it, and uploads the built site as an artifact. It does not deploy to Pages: boost.org builds the published docs, and the point here is to catch a broken build. build_antora.sh passes --log-failure-level=warn when CI is set, so an unresolved xref or include fails the job -- Antora exits zero otherwise -- and the explicit `[ -d html ]` check stays as a second net. Every page already carried the alias of the section it came from. BoostBook chunked to depth 4, so sections that are now in-page headings had their own HTML file as well; 145 further aliases point those at the page that absorbed them. That is 222 redirects in total. The #fragment does not survive a meta-refresh, so a deep link lands on the right page but not the right heading; Antora offers no way around that. libs/test/index.html and the new documentation key in meta/libraries.json point at doc/html/test/index.html, where Antora writes the site. doc/README.md is rewritten for the new toolchain: no more Docbook, xsltproc or Doxygen, and it now covers the prose-only fast path, the CI failure level and how to add an example. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 59 +++++++++ doc/README.md | 118 ++++++++++++------ .../shared_lib_customizations.adoc | 2 +- .../single_header_customizations.adoc | 2 +- .../static_lib_customizations.adoc | 2 +- .../ROOT/pages/program_execution_monitor.adoc | 2 +- .../ROOT/pages/test_output/log_formats.adoc | 2 +- .../ROOT/pages/test_output/logging_api.adoc | 2 +- .../pages/test_output/report_formats.adoc | 2 +- .../test_tools_support_for_logging.adoc | 2 +- .../pages/testing_tools/floating_point.adoc | 2 +- .../ROOT/pages/testing_tools/index.adoc | 2 +- .../pages/tests_organization/decorators.adoc | 2 +- .../pages/tests_organization/fixtures.adoc | 2 +- .../test_case_generation.adoc | 2 +- .../pages/usage_recommendations/index.adoc | 2 +- .../pages/utf_reference/link_references.adoc | 2 +- .../utf_reference/rt_param_reference.adoc | 2 +- .../utf_reference/test_org_reference.adoc | 2 +- .../pages/utf_reference/testing_tool_ref.adoc | 2 +- .../utf_reference/testout_reference.adoc | 2 +- .../__pycache__/qbk2adoc.cpython-312.pyc | Bin 62627 -> 63608 bytes index.html | 4 +- meta/libraries.json | 1 + 24 files changed, 158 insertions(+), 62 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47ea6a7d9f..c2be717ab4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,3 +62,62 @@ jobs: # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} Disabled: Too many issues with lcov COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + + antora: + name: Antora docs + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Install packages + uses: alandefreitas/cpp-actions/package-install@v1.8.8 + with: + apt-get: git cmake + + - name: Clone Boost.Test + uses: actions/checkout@v4 + + # MrDocs compiles an umbrella translation unit against the rest of Boost, + # so the dependencies have to be on disk. `scan-modules-ignore: test` + # keeps the clone from bringing in a second copy of this library. + - name: Clone Boost + uses: alandefreitas/cpp-actions/boost-clone@v1.8.8 + id: boost-clone + with: + branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }} + boost-dir: ../boost-source + scan-modules-dir: . + scan-modules-ignore: test + + - uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Build Antora docs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config --global --add safe.directory "$(pwd)" + + cd .. + BOOST_SRC_DIR="$(pwd)/boost-source" + export BOOST_SRC_DIR + + cd test/doc + bash ./build_antora.sh + + # Antora returns zero even when it fails, so check the site exists. + # build_antora.sh additionally passes --log-failure-level=warn when + # CI is set, which makes an unresolved xref or include fatal. + if [ ! -d "html" ] + then + echo "Antora build failed" + exit 1 + fi + + - name: Create Antora docs artifact + uses: actions/upload-artifact@v4 + with: + name: antora-docs + path: doc/html diff --git a/doc/README.md b/doc/README.md index 4d8ad89c88..5b6e678ac3 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,64 +1,100 @@ This folder contains the documentation for the Boost.Test library. Any contribution or submission to the library should be accompanied by the corresponding documentation. -The format of the documentation uses [Quickbook](http://www.boost.org/tools/quickbook/index.html). +The narrative chapters are written in [AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/) +and assembled by [Antora](https://antora.org). The API reference is generated from the +headers by [MrDocs](https://www.mrdocs.com). -How to build the documentation -============================== - -In order to generate the documentation, the following is needed: - -* Docbook -* Doxygen -* xsltproc - -Doxygen -------- -Part of the documentation needs [Doxygen](http://www.doxygen.org). `doxygen` should be accessible from the `PATH`. +Layout +====== -Docbook -------- -Quickbook needs Docbook (XSL and XML) to be installed. Download and untar the docbook archives: - -* Docbook XSL that can be found here: http://sourceforge.net/projects/docbook/files/docbook-xsl/ -* Docbook DTD that can be found here: http://www.docbook.org/schemas/ - -The directories `$docbook_xsl_directory` and `$docbook_dtd_directory`, respectively, will refer to the location -of the deflated archive. +``` +doc/ +├── antora.yml component descriptor; also defines the +│ attributes the pages use for reference links +├── local-playbook.yml site playbook, used for local builds and CI +├── build_antora.sh the entry point: npm ci, then Antora +├── mrdocs.yml what MrDocs extracts, and how +├── mrdocs.cpp umbrella translation unit: the public headers +├── CMakeLists.txt gives MrDocs a compilation database for it +├── mrdocs-addons/ template overrides, each explaining itself +└── modules/ROOT/ + ├── nav.adoc the navigation tree + ├── pages/ the chapters + ├── partials/bt_example.adoc renders an example's code beside its output + ├── images/, attachments/ + └── examples/ example programs, compiled and run by the + └── snippets/ test suite; included into the pages by tag +``` -Download xsltproc ------------------ -This program is needed by Docbook, in order to be able to transform XMLs into HTMLs. -`xsltproc` should be accessible from the `PATH`. +How to build the documentation +============================== -**note**: `xsltproc` seems to be distributed with macOS. +You need [Node.js](https://nodejs.org) 18 or later, CMake and a C++ compiler. +MrDocs itself is downloaded automatically. -Construct b2 ------------- +``` +> cd $boost_root/libs/test/doc +> npm ci +> ./build_antora.sh +``` -Simply by typing in a console at the root of the Boost repository: +The site lands in `doc/html`; open `doc/html/test/index.html`. To serve it +rather than opening the files directly: ``` -> ./bootstrap.[sh|bat] +> python3 -m http.server -d html 8080 ``` -Build the documentation ------------------------ +The build needs the rest of Boost, because MrDocs compiles `mrdocs.cpp` against +it. `build_antora.sh` finds a surrounding superproject checkout by itself; +otherwise set `BOOST_SRC_DIR`, or let the playbook clone Boost for you. -Running the following commands will construct the documentation with `b2` and -all the needed dependencies: +Antora exits successfully even when a cross-reference or an include fails to +resolve. `build_antora.sh` passes `--log-failure-level=warn` when `CI` is set, +which makes those fatal. To get the same locally: ``` -> cd $boost_root/libs/test/doc -> ../../../b2 -sDOCBOOK_XSL_DIR=$docbook_xsl_directory -sDOCBOOK_DTD_DIR=$docbook_dtd_directory +> CI=1 ./build_antora.sh ``` -It is possible to run directly +Working on the prose alone +-------------------------- + +Regenerating the reference dominates the build time. Comment out the +`cpp-reference` stanza in `antora.yml` and run Antora directly: + ``` -> ../../../b2 +> npx antora --clean local-playbook.yml ``` -but this results in a download from the Internet of the Docbook XLS and DTD, which is much slower. +Nothing else changes; only the reference module disappears. + +If the cached MrDocs nightly goes stale, `./refresh_mrdocs_cache.sh` clears it +so that the next build downloads a current one. + +Writing documentation +===================== + +- Cross-references into the reference chapter go through the attributes defined + in `antora.yml`, for example ``xref:{boost_test}[`BOOST_TEST`]``. The + attribute holds only the target, so a reference page can be renamed in one + place; the label stays at the call site, because Asciidoctor does not apply + formatting to text that arrives from an attribute. +- References to a C++ entity use the `cpp:` macro, which resolves against what + MrDocs generated: `cpp:boost::test_tools::assertion_result[assertion_result]`. +- Examples live in `modules/ROOT/examples` as complete programs named + `.run.cpp` or `.run-fail.cpp`, with their expected output in + `.output`. The test suite compiles and runs every one of them, so an + example that stops working breaks the build rather than just the docs. Show + one with: + + ``` + :bt-name: example22 + :bt-rule: run-fail + :bt-descr: BOOST_TEST_CHECKPOINT usage + include::partial$bt_example.adoc[] + ``` Recommendations =============== @@ -66,6 +102,6 @@ Recommendations - Documentation is part of the "definition of done". A feature does not exist until it is implemented, tested, documented and reviewed. - It is highly recommended that each of your pull request comes with an updated documentation. Not doing so put this work on the shoulders of the maintainers and as a result, it would be likely that the pull request is not addressed in a timely manner. -- Please also update the changelog in the file [`change_log.qbk`](closing_chapters/change_log.qbk) +- Please also update the changelog in [`modules/ROOT/pages/change_log.adoc`](modules/ROOT/pages/change_log.adoc) indicating your contribution - Every file should come with a copyright notice at their very beginning diff --git a/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc index 5c709a8c9b..7afc05f56a 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/shared_lib_customizations.adoc @@ -1,5 +1,5 @@ = Shared-library variant customizations -:page-aliases: boost_test/adv_scenarios/shared_lib_customizations.adoc +:page-aliases: boost_test/adv_scenarios/shared_lib_customizations.adoc, boost_test/adv_scenarios/shared_lib_customizations/entry_point.adoc, boost_test/adv_scenarios/shared_lib_customizations/init_func.adoc [CAUTION] ==== diff --git a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc index 2020dd33bc..c5855d5886 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc @@ -1,5 +1,5 @@ = Header-only variant customizations -:page-aliases: boost_test/adv_scenarios/single_header_customizations.adoc +:page-aliases: boost_test/adv_scenarios/single_header_customizations.adoc, boost_test/adv_scenarios/single_header_customizations/entry_point.adoc, boost_test/adv_scenarios/single_header_customizations/init_func.adoc, boost_test/adv_scenarios/single_header_customizations/multiple_translation_units.adoc [#multiple_translation_units] == Header-only with multiple translation units diff --git a/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc index 8689d995ec..3bc1f86dac 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/static_lib_customizations.adoc @@ -1,5 +1,5 @@ = Static-library variant customizations -:page-aliases: boost_test/adv_scenarios/static_lib_customizations.adoc +:page-aliases: boost_test/adv_scenarios/static_lib_customizations.adoc, boost_test/adv_scenarios/static_lib_customizations/entry_point.adoc, boost_test/adv_scenarios/static_lib_customizations/init_func.adoc [#entry_point] == Customizing the module's entry point diff --git a/doc/modules/ROOT/pages/program_execution_monitor.adoc b/doc/modules/ROOT/pages/program_execution_monitor.adoc index adc39431d0..fb0fb27a34 100644 --- a/doc/modules/ROOT/pages/program_execution_monitor.adoc +++ b/doc/modules/ROOT/pages/program_execution_monitor.adoc @@ -1,5 +1,5 @@ = Program Execution Monitor -:page-aliases: boost_test/pem.adoc +:page-aliases: boost_test/pem.adoc, boost_test/pem/implementation.adoc, boost_test/pem/runtime_configuration.adoc, boost_test/pem/section_pem_compilation.adoc, boost_test/pem/section_pem_compilation/section_pem_full_include.adoc, boost_test/pem/section_pem_compilation/section_pem_standalone.adoc, boost_test/pem/section_pem_compilation/section_pem_standalone/section_pem_compilation_dynamic.adoc, boost_test/pem/section_pem_compilation/section_pem_standalone/section_pem_compilation_static.adoc, boost_test/pem/section_pem_compilation/support_of_the_auto_linking_feature.adoc, boost_test/pem/usage.adoc The components of a C++ program may report user-detected errors in several ways, such as via a return value or throwing an exception. System-detected errors such as dereferencing an invalid pointer are reported in other ways, diff --git a/doc/modules/ROOT/pages/test_output/log_formats.adoc b/doc/modules/ROOT/pages/test_output/log_formats.adoc index cd373f5185..5f127657ef 100644 --- a/doc/modules/ROOT/pages/test_output/log_formats.adoc +++ b/doc/modules/ROOT/pages/test_output/log_formats.adoc @@ -1,5 +1,5 @@ = Log formats -:page-aliases: boost_test/test_output/log_formats.adoc +:page-aliases: boost_test/test_output/log_formats.adoc, boost_test/test_output/log_formats/log_human_readable_format.adoc, boost_test/test_output/log_formats/log_junit_format.adoc, boost_test/test_output/log_formats/log_xml_format.adoc, boost_test/test_output/log_formats/test_log_output.adoc The _Unit Test Framework_ supports several log formats: diff --git a/doc/modules/ROOT/pages/test_output/logging_api.adoc b/doc/modules/ROOT/pages/test_output/logging_api.adoc index b5fc20ab94..1d3f3042be 100644 --- a/doc/modules/ROOT/pages/test_output/logging_api.adoc +++ b/doc/modules/ROOT/pages/test_output/logging_api.adoc @@ -1,5 +1,5 @@ = Logging API -:page-aliases: boost_test/test_output/logging_api.adoc +:page-aliases: boost_test/test_output/logging_api.adoc, boost_test/test_output/logging_api/custom_log_formatter.adoc, boost_test/test_output/logging_api/log_ct_log_format.adoc, boost_test/test_output/logging_api/log_ct_log_level.adoc, boost_test/test_output/logging_api/log_ct_output_stream_redirection.adoc While many test log configuration tasks can be performed at runtime using predefined framework parameters, the _Unit Test Framework_ provides a compile time interface as well. The interface gives you full power over what, where and how to diff --git a/doc/modules/ROOT/pages/test_output/report_formats.adoc b/doc/modules/ROOT/pages/test_output/report_formats.adoc index 56de5b0d7f..cb51c78f01 100644 --- a/doc/modules/ROOT/pages/test_output/report_formats.adoc +++ b/doc/modules/ROOT/pages/test_output/report_formats.adoc @@ -1,5 +1,5 @@ = Report formats -:page-aliases: boost_test/test_output/report_formats.adoc +:page-aliases: boost_test/test_output/report_formats.adoc, boost_test/test_output/report_formats/report_human_readable_format.adoc, boost_test/test_output/report_formats/report_xml_format.adoc [#report_human_readable_format] == Human readable report format diff --git a/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc index ddce00652e..45989542c0 100644 --- a/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc +++ b/doc/modules/ROOT/pages/test_output/test_tools_support_for_logging.adoc @@ -1,5 +1,5 @@ = Tools supports for logging -:page-aliases: boost_test/test_output/test_tools_support_for_logging.adoc +:page-aliases: boost_test/test_output/test_tools_support_for_logging.adoc, boost_test/test_output/test_tools_support_for_logging/test_output_macro_message.adoc, boost_test/test_output/test_tools_support_for_logging/testing_tool_output_disable.adoc [#testing_tool_output_disable] == Logging user defined types diff --git a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc index d914376141..80bf7aa55e 100644 --- a/doc/modules/ROOT/pages/testing_tools/floating_point.adoc +++ b/doc/modules/ROOT/pages/testing_tools/floating_point.adoc @@ -1,5 +1,5 @@ = Floating point comparison -:page-aliases: boost_test/testing_tools/extended_comparison/floating_point.adoc +:page-aliases: boost_test/testing_tools/extended_comparison/floating_point.adoc, boost_test/testing_tools/extended_comparison/floating_point/customizing_for_tolerance.adoc, boost_test/testing_tools/extended_comparison/floating_point/floating_points_comparison_impl.adoc, boost_test/testing_tools/extended_comparison/floating_point/floating_points_comparison_theory.adoc Unless specified otherwise, when a value of floating-point type is compared inside a xref:{boost_test}[`BOOST_TEST`] assertion, operators `==`, `!=` , `<` etc. defined for this type are used. However for floating point type, in most cases what is needed is not an _exact_ diff --git a/doc/modules/ROOT/pages/testing_tools/index.adoc b/doc/modules/ROOT/pages/testing_tools/index.adoc index ab9102fcec..98ac57c5cf 100644 --- a/doc/modules/ROOT/pages/testing_tools/index.adoc +++ b/doc/modules/ROOT/pages/testing_tools/index.adoc @@ -1,5 +1,5 @@ = Writing unit tests -:page-aliases: boost_test/testing_tools.adoc +:page-aliases: boost_test/testing_tools.adoc, boost_test/testing_tools/extended_comparison.adoc Once a test case has been declared, the body of this test should be written. A test case is a sequence of operations in which *assertions* are inserted. Those assertions evaluate _statements_ that implement the expectation being validated, diff --git a/doc/modules/ROOT/pages/tests_organization/decorators.adoc b/doc/modules/ROOT/pages/tests_organization/decorators.adoc index 6eea127474..a78996c2f3 100644 --- a/doc/modules/ROOT/pages/tests_organization/decorators.adoc +++ b/doc/modules/ROOT/pages/tests_organization/decorators.adoc @@ -1,5 +1,5 @@ = Decorators -:page-aliases: boost_test/tests_organization/decorators.adoc +:page-aliases: boost_test/tests_organization/decorators.adoc, boost_test/tests_organization/decorators/explicit_decorator_declaration.adoc, boost_test/tests_organization/decorators/suite_level_decorators.adoc "Decorator" is a uniform mechanism for updating various attributes of the automatically registered test units. These attributes affect how the test tree is processed during the execution of the test module and include test unit diff --git a/doc/modules/ROOT/pages/tests_organization/fixtures.adoc b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc index 58500f5c52..58cfcfa849 100644 --- a/doc/modules/ROOT/pages/tests_organization/fixtures.adoc +++ b/doc/modules/ROOT/pages/tests_organization/fixtures.adoc @@ -1,5 +1,5 @@ = Fixtures -:page-aliases: boost_test/tests_organization/fixtures.adoc +:page-aliases: boost_test/tests_organization/fixtures.adoc, boost_test/tests_organization/fixtures/case.adoc, boost_test/tests_organization/fixtures/global.adoc, boost_test/tests_organization/fixtures/models.adoc, boost_test/tests_organization/fixtures/per_test_suite_fixture.adoc In general terms a test fixture or test context is the collection of one or more of the following items, required to perform the test: diff --git a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc index f19078c0cf..05ad3fd7de 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc @@ -1,5 +1,5 @@ = Data-driven test cases -:page-aliases: boost_test/tests_organization/test_cases/test_case_generation.adoc +:page-aliases: boost_test/tests_organization/test_cases/test_case_generation.adoc, boost_test/tests_organization/test_cases/test_case_generation/datasets.adoc, boost_test/tests_organization/test_cases/test_case_generation/datasets/dataset_creation_and_delayed_creation.adoc, boost_test/tests_organization/test_cases/test_case_generation/datasets/dataset_interface.adoc, boost_test/tests_organization/test_cases/test_case_generation/datasets_auto_registration.adoc, boost_test/tests_organization/test_cases/test_case_generation/generators.adoc, boost_test/tests_organization/test_cases/test_case_generation/operations.adoc, boost_test/tests_organization/test_cases/test_case_generation/operations/grid_cartesian_products.adoc, boost_test/tests_organization/test_cases/test_case_generation/operations/joins.adoc, boost_test/tests_organization/test_cases/test_case_generation/operations/zips.adoc == Why data-driven test cases? diff --git a/doc/modules/ROOT/pages/usage_recommendations/index.adoc b/doc/modules/ROOT/pages/usage_recommendations/index.adoc index bd26fb748d..4f8e145f34 100644 --- a/doc/modules/ROOT/pages/usage_recommendations/index.adoc +++ b/doc/modules/ROOT/pages/usage_recommendations/index.adoc @@ -1,5 +1,5 @@ = Practical usage recommendations -:page-aliases: boost_test/usage_recommendations.adoc +:page-aliases: boost_test/usage_recommendations.adoc, boost_test/usage_recommendations/command_line_usage_recommendations.adoc, boost_test/usage_recommendations/general.adoc, boost_test/usage_recommendations/ide_usage_recommendations.adoc, boost_test/usage_recommendations/tutorials.adoc [#ref_usage_recommendations] Following pages present tips and recommendations on how to use and apply the _Unit Test Framework_ in your real life practice. diff --git a/doc/modules/ROOT/pages/utf_reference/link_references.adoc b/doc/modules/ROOT/pages/utf_reference/link_references.adoc index 6c935b7259..9dc5ae1269 100644 --- a/doc/modules/ROOT/pages/utf_reference/link_references.adoc +++ b/doc/modules/ROOT/pages/utf_reference/link_references.adoc @@ -1,5 +1,5 @@ = Build scenarios and behaviors -:page-aliases: boost_test/utf_reference/link_references.adoc +:page-aliases: boost_test/utf_reference/link_references.adoc, boost_test/utf_reference/link_references/config_disable_alt_stack.adoc, boost_test/utf_reference/link_references/config_no_grid_composition.adoc, boost_test/utf_reference/link_references/config_no_random_dataset.adoc, boost_test/utf_reference/link_references/config_no_zip_composition.adoc, boost_test/utf_reference/link_references/link_boost_test_alternative_init_macro.adoc, boost_test/utf_reference/link_references/link_boost_test_dyn_link.adoc, boost_test/utf_reference/link_references/link_boost_test_global_configuration.adoc, boost_test/utf_reference/link_references/link_boost_test_main_macro.adoc, boost_test/utf_reference/link_references/link_boost_test_module_macro.adoc, boost_test/utf_reference/link_references/link_boost_test_no_lib.adoc, boost_test/utf_reference/link_references/link_boost_test_no_main.adoc [#link_boost_test_main_macro] == `BOOST_TEST_MAIN` diff --git a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc index 1bd6df1702..d0162affe5 100644 --- a/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/rt_param_reference.adoc @@ -1,5 +1,5 @@ = Runtime parameters reference -:page-aliases: boost_test/utf_reference/rt_param_reference.adoc +:page-aliases: boost_test/utf_reference/rt_param_reference.adoc, boost_test/utf_reference/rt_param_reference/auto_dbg.adoc, boost_test/utf_reference/rt_param_reference/build_info.adoc, boost_test/utf_reference/rt_param_reference/catch_system.adoc, boost_test/utf_reference/rt_param_reference/color_output.adoc, boost_test/utf_reference/rt_param_reference/detect_fp_exceptions.adoc, boost_test/utf_reference/rt_param_reference/detect_memory_leaks.adoc, boost_test/utf_reference/rt_param_reference/help.adoc, boost_test/utf_reference/rt_param_reference/list_content.adoc, boost_test/utf_reference/rt_param_reference/list_labels.adoc, boost_test/utf_reference/rt_param_reference/log_format.adoc, boost_test/utf_reference/rt_param_reference/log_level.adoc, boost_test/utf_reference/rt_param_reference/log_sink.adoc, boost_test/utf_reference/rt_param_reference/logger.adoc, boost_test/utf_reference/rt_param_reference/output_format.adoc, boost_test/utf_reference/rt_param_reference/random.adoc, boost_test/utf_reference/rt_param_reference/report_format.adoc, boost_test/utf_reference/rt_param_reference/report_level.adoc, boost_test/utf_reference/rt_param_reference/report_memory_leaks_to.adoc, boost_test/utf_reference/rt_param_reference/report_sink.adoc, boost_test/utf_reference/rt_param_reference/result_code.adoc, boost_test/utf_reference/rt_param_reference/run_test.adoc, boost_test/utf_reference/rt_param_reference/save_pattern.adoc, boost_test/utf_reference/rt_param_reference/show_progress.adoc, boost_test/utf_reference/rt_param_reference/usage.adoc, boost_test/utf_reference/rt_param_reference/use_alt_stack.adoc, boost_test/utf_reference/rt_param_reference/wait_for_debugger.adoc Following sections provide detailed specification for all _Unit Test Framework_ runtime parameters. Each parameter specification includes: diff --git a/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc index 1bd2e12a5d..28f93233ac 100644 --- a/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/test_org_reference.adoc @@ -1,5 +1,5 @@ = Tests declaration and organization -:page-aliases: boost_test/utf_reference/test_org_reference.adoc +:page-aliases: boost_test/utf_reference/test_org_reference.adoc, boost_test/utf_reference/test_org_reference/decorator_depends_on.adoc, boost_test/utf_reference/test_org_reference/decorator_description.adoc, boost_test/utf_reference/test_org_reference/decorator_enable_if.adoc, boost_test/utf_reference/test_org_reference/decorator_enabled.adoc, boost_test/utf_reference/test_org_reference/decorator_fixture.adoc, boost_test/utf_reference/test_org_reference/decorator_label.adoc, boost_test/utf_reference/test_org_reference/decorator_precondition.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_auto_test_case.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_auto_test_suite.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_auto_test_suite_end.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_global_fixture.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case_auto_template.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case_fixture.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case_parameter.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case_template.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_case_template_function.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_dataset.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_dataset_fixture.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_decorator.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_global_fixture.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_suite.adoc, boost_test/utf_reference/test_org_reference/test_org_boost_test_suite_fixture.adoc [#test_org_boost_test_case] == `BOOST_TEST_CASE` and `BOOST_TEST_CASE_NAME` diff --git a/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc index 3d2fc25ed2..3e01885db2 100644 --- a/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc +++ b/doc/modules/ROOT/pages/utf_reference/testing_tool_ref.adoc @@ -1,5 +1,5 @@ = Reference API for writing tests -:page-aliases: boost_test/utf_reference/testing_tool_ref.adoc +:page-aliases: boost_test/utf_reference/testing_tool_ref.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_error.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_fail.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_is_defined.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_bitwise_eq.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_close.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_close_fraction.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_eq.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_eq_collections.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_exception.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_ge.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_gt.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_le.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_lt.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_message.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_ne.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_no_throw.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_predicate.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_small.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_level_throw.adoc, boost_test/utf_reference/testing_tool_ref/assertion_boost_test_universal_macro.adoc, boost_test/utf_reference/testing_tool_ref/assertion_control_under_debuggable.adoc, boost_test/utf_reference/testing_tool_ref/assertion_control_under_debugger.adoc, boost_test/utf_reference/testing_tool_ref/decorator_expected_failures.adoc, boost_test/utf_reference/testing_tool_ref/decorator_timeout.adoc, boost_test/utf_reference/testing_tool_ref/decorator_tolerance.adoc, boost_test/utf_reference/testing_tool_ref/test_org_boost_test_case_expected_failure.adoc [#assertion_boost_test_universal_macro] == `BOOST_TEST` diff --git a/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc index 7103988f73..dce8702ea2 100644 --- a/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc +++ b/doc/modules/ROOT/pages/utf_reference/testout_reference.adoc @@ -1,5 +1,5 @@ = Controlling tests outputs -:page-aliases: boost_test/utf_reference/testout_reference.adoc +:page-aliases: boost_test/utf_reference/testout_reference.adoc, boost_test/utf_reference/testout_reference/test_output_macro_checkpoint.adoc, boost_test/utf_reference/testout_reference/test_output_macro_context.adoc, boost_test/utf_reference/testout_reference/test_output_macro_context_sticky.adoc, boost_test/utf_reference/testout_reference/test_output_macro_disable_type.adoc, boost_test/utf_reference/testout_reference/test_output_macro_info.adoc, boost_test/utf_reference/testout_reference/test_output_macro_message.adoc, boost_test/utf_reference/testout_reference/test_output_macro_passpoint.adoc [#test_output_macro_checkpoint] == `BOOST_TEST_CHECKPOINT` diff --git a/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc b/doc/tools/__pycache__/qbk2adoc.cpython-312.pyc index 60de38a9f76ddde1c9b980946bd592b7555734e0..9c3ebbcbb56654cbcae4b4b8bec558e4d5fca70d 100644 GIT binary patch delta 6768 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 delta 6269 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 - + Automatic redirection failed, please go to -doc/index.html. +doc/html/test/index.html. (aLLM_v0Bj)W9 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 diff --git a/doc/tools/attributes.yml b/doc/tools/attributes.yml deleted file mode 100644 index f317d7bb10..0000000000 --- a/doc/tools/attributes.yml +++ /dev/null @@ -1,79 +0,0 @@ - part_faq: 'section_faq.adoc' - floating_points_testing_tools: 'testing_tools/floating_point.adoc#floating_points_comparison_theory' - master_test_suite: 'tests_organization/master_test_suite.adoc' - runtime_configuration: 'runtime_config/index.adoc' - output_test_stream_tool: 'testing_tools/output_stream_testing.adoc' - boost_test_alternative_init_api: 'utf_reference/link_references.adoc#link_boost_test_alternative_init_macro' - boost_test_main: 'utf_reference/link_references.adoc#link_boost_test_main_macro' - boost_test_dyn_link: 'utf_reference/link_references.adoc#link_boost_test_dyn_link' - boost_test_no_lib: 'utf_reference/link_references.adoc#link_boost_test_no_lib' - boost_test_no_main: 'utf_reference/link_references.adoc#link_boost_test_no_main' - boost_test_module: 'utf_reference/link_references.adoc#link_boost_test_module_macro' - boost_test_global_configuration: 'utf_reference/link_references.adoc#link_boost_test_global_configuration' - boost_test_checkpoint: 'utf_reference/testout_reference.adoc#test_output_macro_checkpoint' - boost_test_passpoint: 'utf_reference/testout_reference.adoc#test_output_macro_passpoint' - boost_test_message: 'utf_reference/testout_reference.adoc#test_output_macro_message' - boost_test_info: 'utf_reference/testout_reference.adoc#test_output_macro_info' - boost_test_context: 'utf_reference/testout_reference.adoc#test_output_macro_context' - boost_test_info_scope: 'utf_reference/testout_reference.adoc#test_output_macro_context_sticky' - boost_test_dont_print_log_value: 'utf_reference/testout_reference.adoc#test_output_macro_disable_type' - boost_test: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' - boost_test_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' - boost_test_require: 'utf_reference/testing_tool_ref.adoc#assertion_boost_test_universal_macro' - boost_level: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level' - boost_level_message: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_message' - boost_level_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq' - boost_level_predicate: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_predicate' - boost_level_equal_collections: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_eq_collections' - boost_level_ne: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ne' - boost_level_ge: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_ge' - boost_level_gt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_gt' - boost_level_le: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_le' - boost_level_lt: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_lt' - boost_level_no_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_no_throw' - boost_level_throw: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw' - boost_level_exception: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_exception' - boost_level_bitwise_equal: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_bitwise_eq' - boost_error: 'utf_reference/testing_tool_ref.adoc#assertion_boost_error' - boost_fail: 'utf_reference/testing_tool_ref.adoc#assertion_boost_fail' - boost_is_defined: 'utf_reference/testing_tool_ref.adoc#assertion_boost_is_defined' - boost_auto_test_case_expected_failures: 'utf_reference/testing_tool_ref.adoc#test_org_boost_test_case_expected_failure' - boost_level_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' - boost_check_small: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_small' - boost_level_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' - boost_check_close: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close' - boost_level_close_fraction: 'utf_reference/testing_tool_ref.adoc#assertion_boost_level_close_fraction' - boost_test_tools_under_debugger: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debugger' - boost_test_tools_debuggable: 'utf_reference/testing_tool_ref.adoc#assertion_control_under_debuggable' - boost_auto_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_case' - boost_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' - boost_test_case_name: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case' - boost_auto_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_auto_template' - boost_test_case_template: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template' - boost_test_case_template_function: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_template_function' - boost_param_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_parameter' - boost_data_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' - boost_data_test_case_f: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset_fixture' - boost_test_dataset_max_arity: 'utf_reference/test_org_reference.adoc#test_org_boost_test_dataset' - boost_auto_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite' - boost_auto_test_suite_end: 'utf_reference/test_org_reference.adoc#test_org_boost_auto_test_suite_end' - boost_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite' - boost_test_decorator: 'utf_reference/test_org_reference.adoc#test_org_boost_test_decorator' - boost_fixture_test_case: 'utf_reference/test_org_reference.adoc#test_org_boost_test_case_fixture' - boost_fixture_test_suite: 'utf_reference/test_org_reference.adoc#test_org_boost_test_suite_fixture' - boost_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_global_fixture' - boost_test_global_fixture: 'utf_reference/test_org_reference.adoc#test_org_boost_test_global_fixture' - boost_test_log_level: 'utf_reference/rt_param_reference.adoc#log_level' - default_run_status: 'runtime_config/test_unit_filtering.adoc#ref_default_run_status' - param_run_test: 'utf_reference/rt_param_reference.adoc#run_test' - decorator_label: 'utf_reference/test_org_reference.adoc#decorator_label' - decorator_enabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' - decorator_disabled: 'utf_reference/test_org_reference.adoc#decorator_enabled' - decorator_enable_if: 'utf_reference/test_org_reference.adoc#decorator_enable_if' - decorator_depends_on: 'utf_reference/test_org_reference.adoc#decorator_depends_on' - decorator_precondition: 'utf_reference/test_org_reference.adoc#decorator_precondition' - decorator_fixture: 'utf_reference/test_org_reference.adoc#decorator_fixture' - decorator_description: 'utf_reference/test_org_reference.adoc#decorator_description' - decorator_expected_failures: 'utf_reference/testing_tool_ref.adoc#decorator_expected_failures' - decorator_timeout: 'utf_reference/testing_tool_ref.adoc#decorator_timeout' - decorator_tolerance: 'utf_reference/testing_tool_ref.adoc#decorator_tolerance' diff --git a/doc/tools/nav.adoc b/doc/tools/nav.adoc deleted file mode 100644 index 10aa61185a..0000000000 --- a/doc/tools/nav.adoc +++ /dev/null @@ -1,76 +0,0 @@ -* xref:index.adoc[] -** xref:intro/design_rationale.adoc[] -** xref:intro/how_to_read.adoc[] -* xref:usage_variants.adoc[] -* xref:tests_organization/index.adoc[] -** xref:tests_organization/test_cases.adoc[] -*** xref:tests_organization/test_organization_nullary.adoc[] -*** xref:tests_organization/test_case_generation.adoc[] -*** xref:tests_organization/test_organization_templates.adoc[] -*** xref:tests_organization/param_test.adoc[] -** xref:tests_organization/test_tree.adoc[] -*** xref:tests_organization/test_suite.adoc[] -*** xref:tests_organization/master_test_suite.adoc[] -*** xref:tests_organization/test_naming.adoc[] -*** xref:tests_organization/test_tree_content.adoc[] -** xref:tests_organization/decorators.adoc[] -** xref:tests_organization/fixtures.adoc[] -** xref:tests_organization/tests_dependencies.adoc[] -** xref:tests_organization/tests_grouping.adoc[] -** xref:tests_organization/enabling.adoc[] -** xref:tests_organization/semantic.adoc[] -** xref:tests_organization/summary.adoc[] -* xref:testing_tools/index.adoc[] -** xref:testing_tools/tools_assertion_severity_level.adoc[] -** xref:testing_tools/boost_test_universal_macro.adoc[] -** xref:testing_tools/reports.adoc[] -** xref:testing_tools/floating_point.adoc[] -** xref:testing_tools/strings.adoc[] -** xref:testing_tools/collections.adoc[] -** xref:testing_tools/bitwise.adoc[] -** xref:testing_tools/exception_correctness.adoc[] -** xref:testing_tools/timeout.adoc[] -** xref:testing_tools/expected_failures.adoc[] -** xref:testing_tools/custom_predicates.adoc[] -** xref:testing_tools/output_stream_testing.adoc[] -** xref:testing_tools/internal_details.adoc[] -** xref:testing_tools/debugging.adoc[] -** xref:testing_tools/summary.adoc[] -* xref:test_output/index.adoc[] -** xref:test_output/test_tools_support_for_logging.adoc[] -*** xref:test_output/checkpoints.adoc[] -*** xref:test_output/contexts.adoc[] -*** xref:test_output/log_floating_points.adoc[] -** xref:test_output/log_formats.adoc[] -** xref:test_output/report_formats.adoc[] -** xref:test_output/logging_api.adoc[] -** xref:test_output/test_output_progress.adoc[] -** xref:test_output/summary.adoc[] -* xref:runtime_config/index.adoc[] -** xref:runtime_config/test_unit_filtering.adoc[] -** xref:runtime_config/runtime_custom.adoc[] -** xref:runtime_config/summary.adoc[] -* xref:adv_scenarios/index.adoc[] -** xref:adv_scenarios/build_utf.adoc[] -** xref:adv_scenarios/entry_point_overview.adoc[] -** xref:adv_scenarios/test_module_init_overview.adoc[] -** xref:adv_scenarios/test_module_runner_overview.adoc[] -** xref:adv_scenarios/single_header_customizations.adoc[] -** xref:adv_scenarios/static_lib_customizations.adoc[] -** xref:adv_scenarios/shared_lib_customizations.adoc[] -** xref:adv_scenarios/external_test_runner.adoc[] -** xref:adv_scenarios/obsolete_init_func.adoc[] -* xref:usage_recommendations/index.adoc[] -** xref:usage_recommendations/bt_and_tdd.adoc[] -** xref:usage_recommendations/hello.adoc[] -** xref:usage_recommendations/web_wisdom.adoc[] -* xref:section_faq.adoc[] -* xref:section_glossary.adoc[] -* xref:change_log.adoc[] -* xref:acknowledgments.adoc[] -* xref:utf_reference/index.adoc[] -** xref:utf_reference/test_org_reference.adoc[] -** xref:utf_reference/testing_tool_ref.adoc[] -** xref:utf_reference/testout_reference.adoc[] -** xref:utf_reference/rt_param_reference.adoc[] -** xref:utf_reference/link_references.adoc[] diff --git a/doc/tools/qbk2adoc.py b/doc/tools/qbk2adoc.py deleted file mode 100644 index 9e2d62aa1d..0000000000 --- a/doc/tools/qbk2adoc.py +++ /dev/null @@ -1,1160 +0,0 @@ -#!/usr/bin/env python3 -"""Convert the Boost.Test QuickBook documentation to Antora AsciiDoc. - -One-shot migration tool: it is run once to produce doc/modules/ROOT/pages and -the [def]-derived attribute block for doc/antora.yml, after which the .qbk -sources and this script are deleted. It is kept in branch history rather than -maintained. - -Usage: - python3 tools/qbk2adoc.py [--out DIR] [--attributes FILE] [--list-pages] - -Two passes: - -1. `Index` walks test.qbk following [include], recording the section tree - (QuickBook id path -> page + anchor), every [#anchor] and [hN:id] target, - and the [def] macros. -2. `Renderer` walks the same tree and emits one .adoc per page, resolving - [link]s against the pass-1 map. - -Anything the converter cannot resolve or does not understand is emitted as a -`// FIXME:` comment in the output and counted on stderr, so nothing is dropped -silently. -""" - -import argparse -import os -import re -import sys -from collections import OrderedDict, Counter - -DOC = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -LIBRARY_ID = "boost_test" - -# --------------------------------------------------------------------------- -# Configuration -# --------------------------------------------------------------------------- - -# Sections whose QuickBook id is absent or unsuitable as a page/anchor slug. -ID_OVERRIDES = { - "Practical usage recommendations": "usage_recommendations", - "Change log": "change_log", - "Acknowledgements": "acknowledgments", - "Report formats": "report_formats", - "Summary of the API for declaring and organizing tests": "summary", - "Custom command line arguments": "runtime_custom", -} - -# Chapter (depth-1 section) id -> directory under pages/. `None` means the -# chapter has no sub-pages and renders as a single top-level page. -CHAPTER_DIRS = { - "intro": "intro", - "usage_variants": None, - "tests_organization": "tests_organization", - "testing_tools": "testing_tools", - "test_output": "test_output", - "runtime_config": "runtime_config", - "adv_scenarios": "adv_scenarios", - "pem": None, - "usage_recommendations": "usage_recommendations", - "section_faq": None, - "section_glossary": None, - "change_log": None, - "acknowledgments": None, - "utf_reference": "utf_reference", -} - -# The introduction is the component's landing page. -PAGE_OVERRIDES = { - "intro": "index.adoc", - "pem": "program_execution_monitor.adoc", -} - -# QuickBook tags naming a C++ entity documented by MrDocs; they all become the -# `cpp:` macro contributed by antora-cpp-tagfiles-extension. -CPP_REF_TAGS = ("classref", "funcref", "memberref", "enumref") - -ADMONITIONS = { - "note": "NOTE", - "tip": "TIP", - "warning": "WARNING", - "caution": "CAUTION", - "important": "IMPORTANT", -} - -# Macros documented only in the hand-written reference pages: MrDocs does not -# emit pages for them, so [macroref] resolves against these anchors instead. -MACROREF_TARGETS = { - "BOOST_TEST_DISABLE_ALT_STACK": "config_disable_alt_stack", - "BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE": "config_no_grid_composition", - "BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE": "config_no_zip_composition", - "BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE": "config_no_random_dataset", -} -MACROREF_PAGE = "utf_reference/link_references.adoc" - -# Link targets naming a chapter that no longer exists and has no successor in -# the narrative. The Execution Monitor lost its chapter long ago; MrDocs now -# documents the class, so that is where the link goes. -STALE_LINK_TARGETS = { - "boost_test.components.execution_monitor": - "xref:reference:boost/execution_monitor.adoc", -} - -# parametric_test_case_generation.qbk gives two different tables the same id. -# The second one lists the random generator's parameters. -DUPLICATE_TABLE_IDS = {"id_range_parameter_table": "id_random_parameter_table"} - - -# --------------------------------------------------------------------------- -# Lexing helpers -# --------------------------------------------------------------------------- - -def scan_code(text, i): - """Scan the backtick-delimited span starting at text[i]. - - QuickBook delimits inline code with a single backtick and code blocks with - a run of two or more; Boost.Test's sources use runs of two *and* three, and - a closing run must match the opening run exactly. Getting this wrong makes - a stray backtick swallow the rest of the file, so it is centralised here. - - Returns (run_length, content_start, content_end, end_of_span); a run_length - of 0 means the backtick is unpaired and should be treated as literal text. - The sources contain two such strays (`parameter`s description` in - runtime_config_reference.qbk and a misplaced backtick in nullary_tests.qbk); - without this guard one of them swallows the rest of the file. - """ - n = len(text) - k = 0 - while i + k < n and text[i + k] == "`": - k += 1 - start = i + k - if k == 1: - # Inline code never crosses a blank line. - limit = text.find("\n\n", start) - limit = n if limit < 0 else limit - j = text.find("`", start, limit) - return (1, start, j, j + 1) if j >= 0 else (0, i, i, i + 1) - j = start - while j < n: - if text[j] != "`": - j += 1 - continue - m = 0 - while j + m < n and text[j + m] == "`": - m += 1 - if m == k: - return (k, start, j, j + m) - j += m - return (k, start, n, n) - - -def match_bracket(text, i): - """Return the index just past the ']' matching the '[' at text[i]. - - Skips code spans/blocks and '''passthrough''', which may legitimately - contain unbalanced brackets. - """ - depth = 0 - n = len(text) - while i < n: - c = text[i] - if c == "[": - depth += 1 - i += 1 - elif c == "]": - depth -= 1 - i += 1 - if depth == 0: - return i - elif text.startswith("'''", i): - j = text.find("'''", i + 3) - i = n if j < 0 else j + 3 - elif c == "`": - i = scan_code(text, i)[3] - else: - i += 1 - return n - - -def strip_comments(text): - """Remove [/ ... ] comments while preserving line numbering.""" - out = [] - i = 0 - n = len(text) - while i < n: - if text.startswith("[/", i): - j = match_bracket(text, i) - out.append("\n" * text.count("\n", i, j)) - i = j - elif text.startswith("'''", i): - j = text.find("'''", i + 3) - j = n if j < 0 else j + 3 - out.append(text[i:j]) - i = j - elif text[i] == "`": - j = scan_code(text, i)[3] - out.append(text[i:j]) - i = j - else: - out.append(text[i]) - i += 1 - return "".join(out) - - -def split_cells(body): - """Split a table/variablelist row body into its bracketed cells.""" - cells = [] - i = 0 - n = len(body) - while i < n: - if body[i] == "[": - j = match_bracket(body, i) - cells.append(body[i + 1:j - 1]) - i = j - else: - i += 1 - return cells - - -def split1(text): - """Split off the first whitespace-delimited token; QuickBook arguments are - routinely separated by a newline rather than a space.""" - parts = re.split(r"\s+", text.strip(), 1) - return parts[0], (parts[1] if len(parts) > 1 else "") - - -def tag_of(inner): - """Return the tag of a bracket body, e.g. 'section' for 'section:id T'.""" - m = re.match(r"([A-Za-z_][\w]*)", inner) - return m.group(1) if m else "" - - -def make_id(title): - """Approximate QuickBook's auto-generated section id.""" - title = re.sub(r"\[[@#$*'_^]?[^\]\s]*\s+([^\]]*)\]", r"\1", title) - title = title.replace("`", "").replace("'", "") - slug = re.sub(r"[^a-z0-9]+", "_", title.lower()).strip("_") - return slug or "section" - - -def attr_name(def_name): - """Map a QuickBook [def] name such as __BOOST_TEST__ to an attribute name.""" - return def_name.strip("_").lower() or "def" - - -# --------------------------------------------------------------------------- -# Pass 1 - document model -# --------------------------------------------------------------------------- - -class Section(object): - def __init__(self, sid, title, depth, src, line, parent): - self.id = sid - self.title = title - self.depth = depth - self.src = src - self.line = line - self.parent = parent - self.children = [] - self.chunks = [] # interleaved ('text', str) | ('section', Section) - self.page = None - self.qid = None - - -class Index(object): - def __init__(self, root_file): - self.defs = OrderedDict() - self.root = Section(LIBRARY_ID, "Boost.Test", 0, root_file, 0, None) - self.by_qid = {} - self.anchors = {} - self.pending_anchor = None - self._load(root_file, self.root) - self._assign_qids(self.root, [LIBRARY_ID]) - self._assign_pages() - self._collect_anchors() - self.link_targets = self.collect_link_targets() - - # -- loading ------------------------------------------------------------ - - def _load(self, path, current): - text = strip_comments(open(path, encoding="utf-8", errors="replace").read()) - rel = os.path.relpath(path, DOC) - i = 0 - n = len(text) - buf = [] - line = 1 - - def flush(): - if buf: - current.chunks.append(("text", "".join(buf))) - del buf[:] - - while i < n: - c = text[i] - if c == "\n": - line += 1 - buf.append(c) - i += 1 - continue - if text.startswith("'''", i) or c == "`": - if c == "`": - j = scan_code(text, i)[3] - else: - j = text.find("'''", i + 3) - j = n if j < 0 else j + 3 - buf.append(text[i:j]) - line += text.count("\n", i, j) - i = j - else: - if c != "[": - buf.append(c) - i += 1 - continue - j = match_bracket(text, i) - inner = text[i + 1:j - 1] - tag = tag_of(inner) - if tag == "include": - flush() - target = inner.split(None, 1)[1].strip() - self._load(os.path.normpath( - os.path.join(os.path.dirname(path), target)), current) - elif tag == "def": - name, value = inner.split(None, 2)[1:] - self.defs[name] = value.strip() - elif tag == "template": - pass # bt_example et al are handled structurally - elif tag == "section": - flush() - # `[#anchor][section ...]` puts the anchor just before the - # section; it names the section, so move it inside. - if current.chunks and current.chunks[-1][0] == "text": - m = re.search(r"(\[#[^\]\s]+\])\s*$", current.chunks[-1][1]) - if m: - self.pending_anchor = m.group(1) - current.chunks[-1] = ( - "text", current.chunks[-1][1][:m.start()]) - sid, title = self._parse_section_head(inner) - child = Section(sid, title, current.depth + 1, rel, line, current) - current.chunks.append(("section", child)) - current.children.append(child) - current = child - if self.pending_anchor: - current.chunks.append(("text", self.pending_anchor + "\n")) - self.pending_anchor = None - elif tag == "endsect": - flush() - if current.parent is not None: - current = current.parent - elif tag in ("library", "quickbook"): - pass - else: - buf.append(text[i:j]) - line += text.count("\n", i, j) - i = j - flush() - - def _parse_section_head(self, inner): - rest = inner[len("section"):] - sid = None - if rest.startswith(":"): - m = re.match(r":(\S+)\s*(.*)", rest, re.S) - sid, rest = m.group(1), m.group(2) - title = rest.strip() - # `[section Report formats][#ref_report_formats]` leaves the anchor in - # the title; peel it off and re-emit it inside the section body. - while True: - m = re.search(r"(\[#[^\]\s]+\])\s*$", title) - if not m: - break - self.pending_anchor = m.group(1) - title = title[:m.start()].rstrip() - if title in ID_OVERRIDES: - sid = ID_OVERRIDES[title] - elif sid is None: - sid = make_id(title) - return sid, title - - # -- ids and pages ------------------------------------------------------ - - def _assign_qids(self, sec, path): - sec.qid = ".".join(path) - self.by_qid[sec.qid] = sec - for child in sec.children: - self._assign_qids(child, path + [child.id]) - - def _assign_pages(self): - for chapter in self.root.children: - directory = CHAPTER_DIRS.get(chapter.id, chapter.id) - override = PAGE_OVERRIDES.get(chapter.id) - if override: - chapter.page = override - elif directory is None: - chapter.page = chapter.id + ".adoc" - else: - chapter.page = directory + "/index.adoc" - self._assign_pages_below(chapter, chapter.src, directory) - - def _assign_pages_below(self, sec, chapter_src, directory): - """A section starts a new page when it opens a .qbk file of its own.""" - for child in sec.children: - if directory is not None and child.src != chapter_src: - child.page = "%s/%s.adoc" % (directory, child.id) - self._assign_pages_below(child, child.src, directory) - else: - self._assign_pages_below(child, chapter_src, directory) - - def owning_page(self, sec): - while sec is not None and sec.page is None: - sec = sec.parent - return sec - - def _collect_anchors(self): - for qid, sec in self.by_qid.items(): - if sec is self.root: - continue - owner = self.owning_page(sec) - self.anchors[qid] = (owner, None if owner is sec else sec.id) - # A section renamed by ID_OVERRIDES is still linked to by the id - # QuickBook derived from its title; keep both resolvable. - for sec in list(self.by_qid.values()): - if sec.parent is None or sec.title not in ID_OVERRIDES: - continue - auto = make_id(sec.title) - if auto != sec.id: - parent_qid = sec.parent.qid - self.anchors["%s.%s" % (parent_qid, auto)] = self.anchors[sec.qid] - for sec in self.by_qid.values(): - owner = self.owning_page(sec) - for kind, chunk in sec.chunks: - if kind != "text": - continue - found = [m.group(1) for m in re.finditer(r"\[#([^\]\s]+)\]", chunk)] - found += [m.group(1) - for m in re.finditer(r"\[h[1-6]:([^\]\s]+)[\s\]]", chunk)] - # QuickBook derives an id from the title of a plain [hN] - # heading, and links do target those. - found += [make_id(m.group(1)) - for m in re.finditer(r"\[h[1-6]\s+([^\]]*)\]", chunk)] - for anchor in found: - self.anchors[anchor] = (owner, anchor) - # links also address these as . - self.anchors.setdefault("%s.%s" % (sec.qid, anchor), - (owner, anchor)) - - def collect_link_targets(self): - targets = set() - for sec in self.by_qid.values(): - for kind, chunk in sec.chunks: - if kind == "text": - for m in re.finditer(r"\[links?\s+(\S+)", chunk): - targets.add(m.group(1)) - return targets - - def resolve(self, target): - """Map a QuickBook link target to (page-section, anchor) or None.""" - if target in self.anchors: - return self.anchors[target] - sec = self.by_qid.get(target) - if sec is not None: - owner = self.owning_page(sec) - return (owner, None if owner is sec else sec.id) - # The chapter tree was reorganised at some point without the links - # being updated: `boost_test.components.section_pem...` still names a - # real section by its last component. Accept that when unambiguous. - tail = target.rsplit(".", 1)[-1] - matches = {s.qid for s in self.by_qid.values() if s.id == tail} - if len(matches) == 1: - sec = self.by_qid[matches.pop()] - owner = self.owning_page(sec) - return (owner, None if owner is sec else sec.id) - return None - - -# --------------------------------------------------------------------------- -# Pass 2 - rendering -# --------------------------------------------------------------------------- - -LIST_RE = re.compile(r"^(\s*)([*#]+)\s+(.*)$") -FENCE_RE = re.compile(r"^\s*``\s*$") - - -class Renderer(object): - def __init__(self, index, outdir): - self.index = index - self.outdir = outdir - self.fixmes = Counter() - self.unresolved = Counter() - self.examples = set() - self.imports = set() - self.snippets = {} # callout id -> example$ resource path - self.table_ids = {} # table anchor -> times seen - self.plain = {} # def name -> plain text, for use inside code - self.def_repl = {} # def name -> the AsciiDoc it expands to in prose - self.attributes = OrderedDict() # antora.yml attribute -> value - for name, value in index.defs.items(): - self.plain[name] = self._plain_text(value) - self.build_def_table(index.root) - - # -- helpers ------------------------------------------------------------ - - @staticmethod - def _plain_text(value): - """Reduce a [def] body to the text a reader sees, for code blocks.""" - m = re.match(r"\[link\s+\S+\s+(.*)\]$", value.strip(), re.S) - if m: - value = m.group(1) - value = re.sub(r"\[[*'_]\s*([^\]]*)\]", r"\1", value) - return value.replace("`", "").replace("/", "").strip() - - # QuickBook's other italic form, /like this/. Excludes C comments (/* ... */) - # and anything spanning a paragraph break; `and/or` is ruled out by the - # word-character check at the call site. - SLASH_ITALIC = re.compile(r"/(?!\*)([^/\n]{1,60}(?:\n[^/\n]{1,60})?)/(?![\w/])") - - # Characters that still take on meaning inside a monospace span. - UNSAFE_IN_CODE = re.compile(r"[{}*#^~`]|__|^_|_$") - - def code_span(self, body): - """Render `code` so AsciiDoc leaves its contents alone.""" - body = self.subst_defs(body.strip(), code=True) - if not self.UNSAFE_IN_CODE.search(body): - return "`%s`" % body - if "+" not in body and "`" not in body: - return "`+%s+`" % body # no substitutions at all - return "`%s`" % body.replace("{", "\\{").replace("`", "'") - - def fixme(self, kind, detail=""): - self.fixmes[kind] += 1 - return "// FIXME(qbk2adoc): %s %s\n" % (kind, detail) - - DEF_RE = re.compile(r"__[A-Za-z0-9_]+?__") - - def subst_defs(self, text, code=False): - """Expand [def] macros to their plain text, for code blocks.""" - def repl(m): - name = m.group(0) - return self.plain[name] if name in self.index.defs else name - return self.DEF_RE.sub(repl, text) if code else text - - def build_def_table(self, page): - r"""Decide, once, what each [def] becomes in prose and in antora.yml. - - Asciidoctor substitutes quotes *before* attributes, and a value coming - from an API attribute -- which is what antora.yml sets -- is inserted - without further substitution. So no formatting inside an attribute - value is ever processed: an attribute holding - `xref:page.adoc#a[\`BOOST_TEST\`]` renders with the backticks visible. - - The ~80 defs that are link aliases therefore put only the link *target* - in the attribute and spell the macro name at each call site. That is - what keeps a reference page renameable in one place, and the label is - formatted normally because it is literal in the page. The three prose - defs carry no target worth naming and are expanded in place. - """ - for name, value in self.index.defs.items(): - attr = attr_name(name) - m = re.match(r"\[link\s+(\S+)\s+(.*)\]$", value.strip(), re.S) - hit = self.index.resolve(m.group(1)) if m else None - if hit and hit[0] is not None and hit[0].page is not None: - owner, anchor = hit - target = owner.page + ("#" + anchor if anchor else "") - self.attributes[attr] = target - label = self.inline(m.group(2).strip(), page) - self.def_repl[name] = "xref:{%s}[%s]" % (attr, label) - else: - rendered = re.sub(r"\s+", " ", self.inline(value, page).strip()) - # QuickBook's /slash italics/ survive only in the [def] bodies. - rendered = re.sub(r"(?*/; AsciiDoc uses markers - # in the listing plus a colist after it. - callouts = [] - - def callout(m): - callouts.append(m.group(1).strip()) - return " <%d>" % len(callouts) - - body = re.sub(r"[ \t]*/\*<(.*?)>\*/", callout, body, flags=re.S) - lines = [ln.rstrip() for ln in body.split("\n")] - while lines and not lines[0].strip(): - lines.pop(0) - while lines and not lines[-1].strip(): - lines.pop() - indent = min((len(ln) - len(ln.lstrip()) for ln in lines if ln.strip()), - default=0) - body = "\n".join(ln[indent:] for ln in lines) - out = "[source,cpp]\n----\n%s\n----\n" % body - for number, text in enumerate(callouts, 1): - out += "<%d> %s\n" % (number, self.inline(text, page).strip()) - return out + "\n" - - def pre_block(self, body, page): - """[pre] is a literal block, except QuickBook still expands markup in - it. Where markup is present, re-enable substitutions on the block.""" - markup = re.search(r"\[[a-z@#$*'_]|__[A-Za-z0-9_]+__", body) - if markup: - body = self.inline(body, page) - else: - body = self.subst_defs(body, code=True) - lines = [ln.rstrip() for ln in body.split("\n")] - while lines and not lines[0].strip(): - lines.pop(0) - while lines and not lines[-1].strip(): - lines.pop() - prefix = '[subs="+macros,+attributes,+quotes"]\n' if markup else "" - return "%s....\n%s\n....\n\n" % (prefix, "\n".join(lines)) - - def bt_example(self, rest, page): - parts = [p.strip() for p in rest.split("..")] - if len(parts) != 3: - return self.fixme("bt_example-arity", rest) - name, descr, rule = parts - self.examples.add((name, rule)) - return ("// tag reference: doc/modules/ROOT/examples/%s.%s.cpp\n" - ":bt-name: %s\n:bt-rule: %s\n:bt-descr: %s\n" - "include::partial$bt_example.adoc[]\n\n" - % (name, rule, name, rule, self.inline(descr, page).strip())) - - # doc/snippet and doc/examples are now both under modules/ROOT/examples, so - # the paths in the QuickBook [import]s have to be remapped. - EXAMPLES_ROOT = os.path.join(DOC, "modules", "ROOT", "examples") - IMPORT_REMAP = (("snippet/", "snippets/"), ("examples/", "")) - - def register_import(self, target): - """Record an [import] and the tag ids the imported file defines.""" - self.imports.add(target) - rel = target.lstrip("./") - for old, new in self.IMPORT_REMAP: - if rel.startswith(old): - rel = new + rel[len(old):] - break - path = os.path.normpath(os.path.join(self.EXAMPLES_ROOT, rel)) - if not os.path.isfile(path): - self.fixmes["import-missing"] += 1 - sys.stderr.write(" missing import: %s\n" % target) - return - for m in re.finditer(r"^\s*(?://|/\*)\s*tag::([\w-]+)\[\]", - open(path, encoding="utf-8", errors="replace").read(), - re.M): - self.snippets[m.group(1)] = rel.replace(os.sep, "/") - - def snippet_include(self, name): - resource = self.snippets[name] - out = ("[source,cpp]\n----\ninclude::example$%s[tag=%s]\n----\n" - % (resource, name)) - # Snippets carrying AsciiDoc callouts keep the colist beside the code, - # in a `-callouts` region of the same file. - if name + "-callouts" in self.snippets: - out += "include::example$%s[tag=%s-callouts]\n" % (resource, name) - return out + "\n" - - def table(self, inner, page): - m = re.match(r"table(?::(\S+))?\s*", inner) - anchor = m.group(1) - rest = inner[m.end():] - first = rest.find("[") - title = rest[:first if first >= 0 else len(rest)].strip() - rows = [split_cells(r) for r in split_cells(rest[first:] if first >= 0 else "")] - rows = [r for r in rows if r] - if not rows: - return self.fixme("empty-table", title) - # The header row fixes the column count. One source table has a row - # with an extra cell; fold the surplus into the first column rather - # than let Asciidoctor drop it. - ncols = len(rows[0]) - for row in rows: - while len(row) > ncols: - row[0:2] = [row[0] + " / " + row[1]] - self.fixmes["table-row-overfull"] += 1 - while len(row) < ncols: - row.append("") - self.fixmes["table-row-short"] += 1 - out = [] - if anchor: - if anchor in self.table_ids: - anchor = DUPLICATE_TABLE_IDS.get( - anchor, "%s-%d" % (anchor, self.table_ids[anchor] + 1)) - self.fixmes["duplicate-table-id"] += 1 - self.table_ids[anchor] = self.table_ids.get(anchor, 0) + 1 - out.append("[#%s]\n" % anchor) - if title: - out.append(".%s\n" % self.inline(title, page).strip()) - out.append('[%%header%%autowidth,cols="%d*"]\n|===\n' % ncols) - for row in rows: - for cell in row: - rendered = self.render_body(cell, page, 6, []).strip() - if "\n" in rendered: - out.append("a|\n%s\n" % rendered) - else: - out.append("|%s\n" % rendered.replace("|", "\\|")) - out.append("\n") - out.append("|===\n\n") - return "".join(out) - - def variablelist(self, rest, page, level): - first = rest.find("[") - title = rest[:first if first >= 0 else len(rest)].strip() - rows = [split_cells(r) for r in split_cells(rest[first:] if first >= 0 else "")] - out = [] - if title: - out.append(".%s\n" % self.inline(title, page).strip()) - out.append("[cols=\"1,3\"]\n|===\n") - for row in rows: - if len(row) != 2: - out.append(self.fixme("variablelist-row", str(row)[:60])) - continue - term = self.render_body(row[0], page, 6, []).strip() - desc = self.render_body(row[1], page, 6, []).strip() - out.append("|%s\na|\n%s\n\n" % (term.replace("|", "\\|"), desc)) - out.append("|===\n\n") - return "".join(out) - - def list_block(self, text, pos, page): - items = [] - n = len(text) - while pos < n: - line_end = text.find("\n", pos) - line_end = n if line_end < 0 else line_end - line = text[pos:line_end] - m = LIST_RE.match(line) - if m: - indent, marker, body = m.group(1), m.group(2), m.group(3) - items.append([len(indent) + len(marker) - 1, marker[-1], [body]]) - pos = line_end + 1 - continue - if not line.strip(): - # a blank line ends the list unless the next line continues it - nxt = text.find("\n", line_end + 1) - nxt = n if nxt < 0 else nxt - peek = text[line_end + 1:nxt] - if items and (LIST_RE.match(peek) or peek.startswith(" ")): - items[-1][2].append("") - pos = line_end + 1 - continue - pos = line_end + 1 - break - if items and line.startswith((" ", "\t")): - items[-1][2].append(line.strip()) - pos = line_end + 1 - continue - break - levels = sorted({item[0] for item in items}) - out = [] - for depth, marker, body in items: - rank = levels.index(depth) + 1 - bullet = ("*" if marker == "*" else ".") * rank - rendered = self.inline("\n".join(body).strip(), page).strip() - rendered = re.sub(r"\n\s*\n", "\n+\n", rendered) - out.append("%s %s\n" % (bullet, rendered)) - out.append("\n") - return "".join(out), pos - - def paragraph(self, text, pos, page): - n = len(text) - depth = 0 - i = pos - while i < n: - c = text[i] - if c == "[": - depth += 1 - elif c == "]": - depth = max(0, depth - 1) - elif c == "`": - i = scan_code(text, i)[3] - continue - elif c == "\n" and depth == 0: - if text.startswith("\n", i + 1): - break - nxt_end = text.find("\n", i + 1) - nxt_end = n if nxt_end < 0 else nxt_end - nxt = text[i + 1:nxt_end] - if LIST_RE.match(nxt) or nxt.startswith("``"): - break - if nxt.strip()[1:-1] in self.snippets and nxt.strip().startswith("["): - break - if nxt.lstrip().startswith("["): - inner_tag = tag_of(nxt.lstrip()[1:]) - if inner_tag in ADMONITIONS or inner_tag in ( - "table", "variablelist", "pre", "bt_example", - "import", "role", "xinclude") or re.match( - r"^h[1-6][\s:]", nxt.lstrip()[1:]): - break - i += 1 - body = text[pos:i].strip() - rendered = self.inline(body, page).strip() - if not rendered: - return "", i + 1 - if rendered[:1] in (".", "+", "=", "-") or rendered.startswith("//"): - rendered = "{empty}" + rendered - return rendered + "\n\n", i + 1 - - # -- page assembly ------------------------------------------------------ - - def heading_ranks(self, sec): - """Distinct [hN] levels used directly in a section, in document order.""" - found = [] - for kind, chunk in sec.chunks: - if kind != "text": - continue - for m in re.finditer(r"\[h([1-6])[\s:]", chunk): - depth = int(m.group(1)) - if depth not in found: - found.append(depth) - return sorted(found) - - def render_section(self, sec, page, level): - out = [] - headings = self.heading_ranks(sec) - for kind, chunk in sec.chunks: - if kind == "text": - out.append(self.render_body(chunk, page, level, headings, sec)) - elif chunk.page is None: - out.append("[#%s]\n%s %s\n\n" % ( - chunk.id, "=" * (level + 1), - self.inline(chunk.title, page).strip())) - out.append(self.render_section(chunk, page, level + 1)) - return "".join(out) - - # QuickBook spells an epigraph's attribution as a *second* epigraph whose - # body starts with `--`; AsciiDoc puts it in the block attribute list. - EPIGRAPH_ATTRIB = re.compile( - r"\[quote\]\n____\n(.*?)\n____\n\n\[quote\]\n____\n--(.+?)\n____\n", - re.S) - - def render_page(self, sec): - body = self.render_section(sec, sec, 1) - body = self.EPIGRAPH_ATTRIB.sub( - lambda m: "[quote, %s]\n____\n%s\n____\n" - % (m.group(2).strip(), m.group(1)), body) - header = "= %s\n" % self.inline(sec.title, sec).strip() - alias = self.page_alias(sec) - if alias: - header += ":page-aliases: %s\n" % alias - return header + "\n" + body.strip() + "\n" - - def page_alias(self, sec): - """The path the BoostBook site used for this section.""" - parts = sec.qid.split(".") - return "%s.adoc" % "/".join(parts) - - def run(self): - pages = OrderedDict() - for sec in self.index.by_qid.values(): - if sec.page: - pages[sec.page] = sec - for page, sec in pages.items(): - path = os.path.join(self.outdir, page) - os.makedirs(os.path.dirname(path), exist_ok=True) - with open(path, "w", encoding="utf-8") as fh: - fh.write(self.render_page(sec)) - return pages - - -def emit_nav(index, renderer, path): - """Draft modules/ROOT/nav.adoc from the section tree, for hand-tuning.""" - lines = [] - - def walk(sec, depth): - for child in sec.children: - if child.page: - lines.append("%s xref:%s[]\n" % ("*" * depth, child.page)) - walk(child, depth + 1) - else: - # a section that is only a heading on its parent page: keep its - # sub-pages, but attach them at the parent's level - walk(child, depth) - - walk(index.root, 1) - with open(path, "w", encoding="utf-8") as fh: - fh.writelines(lines) - - -def emit_attributes(index, renderer, path): - with open(path, "w", encoding="utf-8") as fh: - for name, value in renderer.attributes.items(): - fh.write(" %s: '%s'\n" % (name, value.replace("'", "''"))) - - -def main(): - ap = argparse.ArgumentParser() - ap.add_argument("--out", default=os.path.join(DOC, "modules", "ROOT", "pages")) - ap.add_argument("--attributes", default=os.path.join(DOC, "tools", "attributes.yml")) - ap.add_argument("--nav", default=os.path.join(DOC, "tools", "nav.adoc")) - ap.add_argument("--list-pages", action="store_true") - args = ap.parse_args() - - index = Index(os.path.join(DOC, "test.qbk")) - renderer = Renderer(index, args.out) - if args.list_pages: - for sec in index.by_qid.values(): - if sec.page: - print("%-58s %s" % (sec.page, sec.qid)) - return - pages = renderer.run() - emit_attributes(index, renderer, args.attributes) - emit_nav(index, renderer, args.nav) - - sys.stderr.write("%d sections -> %d pages\n" % (len(index.by_qid), len(pages))) - sys.stderr.write("%d defs -> %s\n" % (len(index.defs), args.attributes)) - if renderer.unresolved: - sys.stderr.write("\nunresolved link targets (%d distinct, %d uses):\n" - % (len(renderer.unresolved), sum(renderer.unresolved.values()))) - for target, count in renderer.unresolved.most_common(): - sys.stderr.write(" %4d %s\n" % (count, target)) - if renderer.fixmes: - sys.stderr.write("\nFIXMEs emitted:\n") - for kind, count in renderer.fixmes.most_common(): - sys.stderr.write(" %4d %s\n" % (count, kind)) - - -if __name__ == "__main__": - main() diff --git a/doc/tutorials/hello_world.qbk b/doc/tutorials/hello_world.qbk deleted file mode 100644 index 9e4be5ebae..0000000000 --- a/doc/tutorials/hello_world.qbk +++ /dev/null @@ -1,77 +0,0 @@ -[/ - / Copyright (c) 2003 Boost.Test contributors - / - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - /] - -[section:hello A testing framework, what for?] -How should a test program report errors? Displaying an error message is an obvious possibility: - -[/snippet9 deleted] -`` -if( something_bad_detected ) - std::cout << "something bad has been detected" << std::endl; -`` - -But that requires inspection of the program's output after each run to determine if an error occurred. Since test -programs are often run as part of a regression test suite, human inspection of output to detect error messages is time -consuming and unreliable. Test frameworks like GNU/expect can do the inspections automatically, but are overly complex -for simple testing. - -A better simple way to report errors is for the test program to return `EXIT_SUCCESS` (normally 0) if the test program -completes satisfactorily, and `EXIT_FAILURE` if an error is detected. This allows a simple regression test script to -automatically and unambiguously detect success or failure. Further appropriate actions such as creating an HTML table or -emailing an alert can be taken by the script, and can be modified as desired without having to change the actual C++ -test programs. - -A testing protocol based on a policy of test programs returning `EXIT_SUCCESS` or `EXIT_FAILURE` does not require any -supporting tools; the C++ language and standard library are sufficient. The programmer must remember, however, to catch -all exceptions and convert them to program exits with non-zero return codes. The programmer must also remember to not -use the standard library `assert()` macro for test code, because on some systems it results in undesirable side effects -like a message requiring manual intervention. - -The Boost Test Library's Unit Test Framework is designed to automate those tasks. The library supplied `main()` relieves -users from messy error detection and reporting duties. Users could use supplied testing tools to perform complex -validation tasks. Let's take a look on the following simple test program: - - -`` -#include - -int main( int, char* [] ) -{ - my_class test_object( "qwerty" ); - return test_object.is_valid() ? EXIT_SUCCESS : EXIT_FAILURE; -} -`` - -There are several issues with above test. - -# You need to convert `is_valid` result in proper result code. -# Would exception happen in test_object construction of method `is_valid` invocation, the program will crash. -# You won't see any output, would you run this test manually. - -The __UTF__ solves all these issues. To integrate with it above program needs to be changed to: - -`` -#include -#define __BOOST_TEST_MODULE__ MyTest -#include - -__BOOST_AUTO_TEST_CASE__( my_test ) -{ - my_class test_object( "qwerty" ); - BOOST_TEST( test_object.is_valid() ); -} -`` - -Now, you not only receive uniform result code, even in case of exception, but also nicely formatted output from -__BOOST_TEST__ tool, would you choose to see it. Is there any other ways to perform checks? The following example test -program shows several different ways to detect and report an error in the `add()` function. - -[import ../snippet/snippet12.cpp] -[snippet12] - - -[endsect] [/section:hello] diff --git a/doc/tutorials/new_year_resolution.qbk b/doc/tutorials/new_year_resolution.qbk deleted file mode 100644 index bf29806ed6..0000000000 --- a/doc/tutorials/new_year_resolution.qbk +++ /dev/null @@ -1,89 +0,0 @@ -[/ - / Copyright (c) 2003 Boost.Test contributors - / - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - /] - -[section:bt_and_tdd Test driven development with Boost.Test] - -Today is a momentous day - first day of new year. Today I am going to start a new life. I am going to stop eating a -greasy food, start attending a fitness club and ... today I am going to test programs I am writing. I can start right -after the last line of a program is completed or, even better, I can write tests while I am coding. And maybe next time -I will write tests before the coding, during the design stage. I have read a lot of literature on how to write the -tests, I have the unit test framework in hand and an idea of new class. So let's get started. - -Let say I want to encapsulate an unchangeable C character buffer with a length into the simple class `const_string`. -Rationale: a string class that does not allocate a memory and provide a convenient read-only access to the pre-allocated -character buffer. I will probably want `const_string` to have an interface similar to the class std::string. What will I -do first? In my new life I will start with writing a test module for future class `const_string`. It will look like -this: - -[import ../snippet/snippet13.cpp] [snippet13] - -Now I can compile it and link with the unit test framework. Done! I have a working test program. It is empty, so when I -run the program it produces following output: - -``*** No errors detected`` - - - -Well, now it could be a good time to start a work on `const_string`. First thing I imagine would be good to have is a -constructors and trivial access methods. So my class initial version looks like this: - -[import ../snippet/snippet14.cpp] [snippet14] - -Now I am able to write a first test case - constructors testing - and add it to a test suite. My test program became to -look like this: - -[import ../snippet/snippet15.cpp] [snippet15] - -The constructors_test test case is intended to check a simple feature of the class `const_string`: an ability to -construct itself properly based on different arguments. To test this feature I am using such characteristics of -constructed object as a data it contains and a length. The specification of the class `const_string` does not contain -any expected failures, so, though the constructor can fail if I would pass a pointer to an invalid memory, error check -control is not performed (can't require what was not promised :-)). But for any valid input it should work. So I am -trying to check a construction for an empty string (1), a NULL string (2) a regular C string(3), an STL string(4), a -copy construction(5) and so on. Well, after fixing all the errors in the implementation (do you write programs without -errors from scratch?) I am able to pass this test case and the unit test framework gives me the following report: - -``Running 1 test case... - -*** No errors detected -`` - -Encouraged I am moving on and adding more access methods: - -[import ../snippet/snippet16.cpp][snippet16] - -I added the new feature - I need a new test case to check it. As a result my test suite became to look like this: - -[import ../snippet/snippet17.cpp] [snippet17] - -In the data_access_test test case I am trying to check the class `const_string` character access correctness. While tests -(1) checks valid access using `const_string::operator[]` and test (2) checks valid access using method -`const_string::at()`, there is one more thing to test. The specification of the method `const_string::at()` contains -validation for the out of bound access. That was test (3) is intended to do: check that the validation is working. A -testing of a validation and error handling code is an important part of a unit testing and should not be left for a -production stage. The data_access_test test case passed and I am ready for the next step. - -[import ../snippet/const_string.hpp] [import ../snippet/const_string_test.cpp] - -Continuing my effort I am able to complete class `const_string` (see [@../snippet/const_string.hpp Listing 1 -=const_string.hpp=]) and testing module for it (see [@../snippet/const_string_test.cpp Listing 2 =const_string_test.cpp=]) -that is checking all features that are presented in the class `const_string` specification. - - - -Well, I am step closer to fulfilling my new year resolution (we should see about this fitness club sometime next ...). -What about you? Your testing habits could be a little different. You could start with a class/library development and -then at some point start writing test cases on feature basis. Or you can, given a detailed specification for the future -product, including expected interfaces, immediately start with writing all test cases (or it could be a different -person, while you working on implementation at the same time). In any case you should not have any problems to use -facilities provided by the Boost.Test unit test framework and, let me hope, be able to write a stable, bulletproof code. -And what is even more important is your confidence in an ability to make changes of any complexity without involving a -lengthy regression testing of your whole product. Your test module and the unit test framework will stay behind your -back to help you with any occasional errors. - - -[endsect] diff --git a/doc/tutorials/web_wisdom.qbk b/doc/tutorials/web_wisdom.qbk deleted file mode 100644 index bd488d611d..0000000000 --- a/doc/tutorials/web_wisdom.qbk +++ /dev/null @@ -1,58 +0,0 @@ -[/ - / Copyright (c) 2015 Boost.Test contributors - / - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - /] - -[section:web_wisdom Web Wisdom] - -If you can't find answer to the question you have on these pages, it is quite possible someone already faced an issue similar to yours -and posted about this online. This page gathers a few of the additional materials you may review. - -[note The following material is provided "as is". The views, implementation or methods expressed are their respective authors and - do not necessarily represent positions of the Boost.Test contributors, and might be outdated.] - -* [@http://stackoverflow.com/search?q=boost+test Stack overflow Boost.Test related questions] -* [@http://www.ibm.com/developerworks/aix/library/au-ctools1_boost/?S_TACT=105AGY20&S_CMP=HP Get to know the Boost unit test framework (from IBM)] -* [@http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/ C++ Unit Testing With Boost.Test] -* [@http://www.beroux.com/english/articles/boost_unit_testing/ C++ Unit Testing Framework: A Boost Test Tutorial] -* [@http://praveen.kumar.in/2010/04/30/introduction-to-test-driven-development-in-c-using-boost-test-library/ - Introduction to Test-Driven Development in C++ using Boost Test Library] -* C++ Unit Tests With Boost.Test: - [@https://legalizeadulthood.wordpress.com/2009/07/04/c-unit-tests-with-boost-test-part-1/ part 1], - [@https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-2/ part 2], - [@https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-3/ part 3], - [@https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-4/ part 4], - [@https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-5/ part 5] -* [@http://alexott.net/en/cpp/CppTestingIntro.html Test-driven development and unit testing with examples in C++] -* [@http://www.hpfsc.de/default.php?url=./boosttest/index.html How to use Boost Test for automated testing] -* [@http://www.abauchu.net/blog/post/2009/12/02/Unit-tests-with-BoostTest Unit tests with Boost.Test] - -* [@http://richarddingwall.name/2008/06/08/boost-how-do-i-write-a-unit-test-for-a-signal/ - Boost: How do I write a unit test for a signal?] -* [@https://chuckaknight.wordpress.com/2013/04/18/testing-using-the-boost-unit-test-framework - Testing Using the Boost Unit Test Framework] -* [@https://sanecpp.wordpress.com/2014/10/08/introduction-to-unit-testing/ Introduction to unit testing] -* [@http://www.alittlemadness.com/2009/12/04/using-boost-test-with-boost-build/ Using Boost.Test with Boost.Build] -* [@http://www.alittlemadness.com/2009/12/10/boost-test-xml-reports-with-boost-build/ Boost.Test XML Reports with Boost.Build] -* [@http://edn.embarcadero.com/article/32703 Boost Unit Testing with C++BuilderX] -* [@http://www.sharprobotica.com/2010/04/including-boost-test-in-your-c-project/ Including Boost.Test in Your C++ Project] -* [@http://bitten.edgewall.org/wiki/BoostTest Using Boost.Test in Bitten] -* [@http://seandenigris.com/blog/?p=187 Automate acceptance/unit testing C++ in Xcode (using Boost.Test)] -* [@http://www.codeproject.com/Articles/368966/Automation-of-running-Boost-Test-with-Visual-Studi - Automation of running Boost.Test with Visual Studio macros] -* [@http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/ Using the Boost Unit Test Framework with Xcode 3] -* [@http://www.lonecpluspluscoder.com/2014/09/some-boost-test-notes/ Some Boost.Test notes] -* [@http://www.devexp.ru/2010/01/boost-test-yunit-testirovanie-i-cmake/ Boost.Test tutorial (in Russian)] -* Boost Test. Setup and usage ([@http://blog.yastrebkov.com/2009/07/boost-test.html Russian], - [@http://blog.yastrebkov.com/2010/07/boost-test-setup-and-usage.html English]) -* [@http://www.ncbi.nlm.nih.gov/toolkit/doc/book/ch_boost/ Using the Boost Unit Test Framework] -* [@http://endl.ch/content/gallio-adapter-boosttest Gallio adapter for Boost.Test] -* [@http://sindicollo.blogspot.com/2008/11/boosttest.html Russian translation of small tutorial to Boost.Test] -* [@http://www.eld.leidenuniv.nl/~moene/Home/projects/testdox/boosttest/ Customizing the output log and report format] -* [@https://github.com/etas/vs-boost-unit-test-adapter Boost Test Adapter] (Boost.Test extension for Microsoft Visual Studio, also - available from [@https://visualstudiogallery.msdn.microsoft.com/5f4ae1bd-b769-410e-8238-fb30beda987f here]). -* [@https://marketplace.visualstudio.com/items?itemName=VisualCPPTeam.TestAdapterforBoostTest Microsoft Boost Test Adapter] - -[endsect] [/section:web_wisdom] diff --git a/doc/usage_recommendations.qbk b/doc/usage_recommendations.qbk deleted file mode 100644 index c35f6264bf..0000000000 --- a/doc/usage_recommendations.qbk +++ /dev/null @@ -1,166 +0,0 @@ -[/ - / Copyright (c) 2003 Boost.Test contributors - / - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - /] - -[#ref_usage_recommendations][section Practical usage recommendations] - -Following pages present tips and recommendations on how to use and apply the __UTF__ in your real life practice. -You don't necessarily need to follow them, but we found them handy. - -Here you will also find some tutorials from Boost.Test authors and world wide. - -[section General] - -[h4 Prefer offline compiled libraries to the inline included components] -If you are just want to write quick simple test in environment where you never used Boost.Test before - yes, -use included components. But if you plan to use Boost.Test on permanent basis, small investment of time needed -to build (if not build yet), install and change you makefiles/project settings will soon return to you in a -form of shorter compilation time. Why do you need to make your compiler do the same work over and over again? - -[h4 If you use only free function based test cases advance to the automatic registration facility] -It's really easy to switch to automatic registration. And you don't need to worry about forgotten test cases. - -[h4 To find location of first error reported by test tool within reused template function, use special hook within framework headers] -In some cases you are reusing the same template based code from within one test case (actually we recommend -better solution in such case - see below). Now if an error gets reported by the test tool within that reused -code you may have difficulty locating were exactly error occurred. To address this issue you could either a add -__BOOST_TEST_MESSAGE__ statements in templated code that log current type id of template parameters or you can use special hook located in -`unit_test_result.hpp` called `first_failed_assertion()`. If you set a breakpoint right on the line where this -function is defined you will be able to unroll the stack and see where error actually occurred. - - -[h4 To test reusable template base component with different template parameter use test case template facility] -If you writing unit test for generic reusable component you may have a need to test it against set of different -template parameter types . Most probably you will end up with a code like this: - -`` -template -void specific_type_test( TestType* = 0 ) -{ - MyComponent c; - // ... here we perform actual testing -} - -void my_component_test() -{ - specific_type_test( (int*)0 ); - specific_type_test( (float*)0 ); - specific_type_test( (UDT*)0 ); - // ... -} -`` - -This is namely the situation where you would use test case template facility. It not only simplifies this kind -of unit testing by automating some of the work, in addition every argument type gets tested separately under -unit test monitor. As a result if one of types produce exception or non-fatal error you may still continue and -get results from testing with other types. - -[endsect][/ General] - -[section IDE usage recommendations] - -This recommendation is shown using Microsoft Visual Studio as an example, but you can apply similar steps in -different IDEs. - -[h4 Use custom build step to automatically start test program after compilation] -I found it most convenient to put test program execution as a post-build step in compilation. To do so use -project property page: - -[$images/post_build_event.jpg] - -Full command you need in "Command Line" field is: - -[pre -"$(TargetDir)\$(TargetName).exe" --[link boost_test.utf_reference.rt_param_reference.result_code `result_code`]=no --[link boost_test.utf_reference.rt_param_reference.report_level `report_level`]=no -] - -Note that both report level and result code are suppressed. This way the only output you may see from this -command are possible runtime errors. But the best part is that you could jump through these errors using usual -keyboard shortcuts/mouse clicks you use for compilation error analysis: - -[$images/post_build_out.jpg] - -[h4 If you got fatal exception somewhere within test case, make debugger break at the point the failure by adding - extra command line argument] - -If you got "memory access violation" message (or any other message indication fatal or system error) when you -run you test, to get more information of error location add - -[pre ---[link boost_test.utf_reference.rt_param_reference.catch_system catch_system_error]=no -] -to the test run command line: - -[$images/run_args.jpg] - -Now run the test again under debugger and it will break at the point of failure. - -[endsect] [/ IDE] - -[section Command line usage recommendations] - -[h4 If you got fatal exception somewhere within test case, make program generate core-dump by adding extra command - line argument] -If you got "memory access violation" message (or any other message indication fatal or system error) when you -run you test, to get more information about the error location add - -[pre ---[link boost_test.utf_reference.rt_param_reference.catch_system catch_system_error]=no -] - -to the test run command line. Now run the test again and it will create a core-dump you could analyze using you preferable -debugger. Or run it under debugger in a first place and it will break at the point of failure. - -[h4 How to use test module build with Boost.Test framework under management of automated regression test facilities?] - -My first recommendation is to make sure that the test framework catches all fatal errors by adding argument - -[pre ---[link boost_test.utf_reference.rt_param_reference.catch_system catch_system_error]=yes -] - -to all test modules invocations. Otherwise test program may produce unwanted dialogs (depends on compiler and OS) that will halt you -regression tests run. The second recommendation is to suppress result report output by adding - -[pre ---[link boost_test.utf_reference.rt_param_reference.report_level report_level]=no -] - -argument and test log output by adding - -[pre ---[link boost_test.utf_reference.rt_param_reference.log_level log_level]=nothing -] - -argument, so that test module won't produce undesirable output no one is going to look at -anyway. We recommend relying only on result code that will be consistent for all test programs. An -alternative to my second recommendation is direct both log and report to separate file you could analyze -later on. Moreover you can make Boost.Test to produce them in XML or JUNIT format using - -[pre ---[link boost_test.utf_reference.rt_param_reference.output_format output_format]=XML -] -or -[pre ---[link boost_test.utf_reference.rt_param_reference.log_format log_format]=JUNIT -] - -and use some automated tool that will format this information as you like. - -[endsect][/command line] - -[section Tutorials] - -[include tutorials/new_year_resolution.qbk] -[include tutorials/hello_world.qbk] - -[endsect] [/ tutorials] - -[include tutorials/web_wisdom.qbk] - -[endsect] [/ recommendations] - -[/EOF] diff --git a/doc/usage_variants.qbk b/doc/usage_variants.qbk deleted file mode 100644 index 1888c0bb5b..0000000000 --- a/doc/usage_variants.qbk +++ /dev/null @@ -1,102 +0,0 @@ -[/ - / Copyright (c) 2003 Boost.Test contributors - / - / Distributed under the Boost Software License, Version 1.0. (See accompanying - / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - /] - -[section:usage_variants Usage variants] - -The __UTF__ supports three different usage variants: - -# [link boost_test.usage_variants.single_header The header-only variant] -# [link boost_test.usage_variants.static_lib The static library variant] -# [link boost_test.usage_variants.shared_lib The shared library variant] - -In most cases you shouldn't have problems deciding which one to use, since there are -clear reasons why would you prefer each one. Following sections should help you with the decision. - -[/ ##################################################################### ] -[h3:single_header Header-only usage variant] - -If you prefer to avoid the compilation of standalone library, you should use the -header-only variant of the __UTF__. This variant only requires you to include -the unique header: `#include ` -and there is no need to link with any library. There are several ways to perform -the initialization, but the simplest way is the following: -`` - #define __BOOST_TEST_MODULE__ test module name - #include /* path is different than the other variants! */ -`` -__BOOST_TEST_MODULE__ macro needs to be defined *before* the include and should indicate -the name of the test module. This name can include spaces and does not need to be wrapped in quotes. - -[link boost_test.adv_scenarios.single_header_customizations This section] -gives additional details on how to customize this usage variant. In particular, -it is possible to have several compilation units with this variant, as explained in the section -[link boost_test.adv_scenarios.single_header_customizations.multiple_translation_units Header-only with multiple translation units]. - -[/ ##################################################################### ] -[h3:static_lib Static library usage variant] -For most users, who has an access to pre-built static library [footnote these files are distributed -with the packaging systems on Linux and OSX for instance] of the __UTF__ or can -[link boost_test.adv_scenarios.build_utf build it] themselves, following usage can be most versatile - and simple approach. This usage variant entails two steps. - -# First, the following line needs to be added to all translation units in the test module: - `` - #include - `` - One and *only one* translation unit should include following lines: - `` - #define __BOOST_TEST_MODULE__ test module name - #include - `` - __BOOST_TEST_MODULE__ macro needs to be defined *before* the include and should indicate the - name of the test module. This name can include spaces and does not need to be wrapped in quotes. -# The second step is to link with the __UTF__ *static* library. - -[note Header `` is an /aggregate/ header: it includes most of the other headers that contains the Unit Test Framework definitions.] - -The flip side of this usage variant is that each test module following this usage variant is going -to be statically linked with __UTF__, which might be something you want to avoid (to save space -for example). For more information about these configuration options check -[link boost_test.adv_scenarios.static_lib_customizations this section]. - -[/ ##################################################################### ] -[h3:shared_lib Shared library usage variant] -In the project with large number of test modules the static library variant of the __UTF__ may -cause you to waste a lot of disk space. The solution is to link test module dynamically with the -__UTF__ built as a shared library. -This usage variant entails two steps. - -# First you need to add following lines to all translation units in a test module: - `` - #define __BOOST_TEST_DYN_LINK__ - #include - `` - and *only one* translation unit should include following lines - `` - #define __BOOST_TEST_MODULE__ test module name - #define __BOOST_TEST_DYN_LINK__ - #include - `` - `BOOST_TEST_MODULE` and `BOOST_TEST_DYN_LINK` macros needs to be defined *before* the include. - `BOOST_TEST_MODULE` should be set to test module name. This name can include spaces and does - not need to be wrapped in quotes. - -# The second step is to link with the __UTF__ *shared* library. - -The flip side of this usage variant is that you will need to make sure the __UTF__ shared library -is accessible at runtime to a test module. - -In addition shared library usage variant facilitates custom test runners. For more information about this -check [link boost_test.adv_scenarios.shared_lib_customizations this section]. - -[caution On Windows, the test module and the __UTF__ shared library should link to the same CRT. Not doing - so (for instance __UTF__ shared library in /release/ mode while the test module is in /debug/) will - lead to crashes.] - -[endsect] [/Usage Variants] - -[/ EOF] From a870fcb38271cae6e049c2a8dbb6ba77ce196c02 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Thu, 30 Jul 2026 15:42:01 -0400 Subject: [PATCH 10/10] doc: restore the header reference The BoostBook reference had a "Header " section per header. MrDocs organises purely by namespace and has no header grouping, so the port dropped it without noticing. utf_reference/ref_headers.adoc puts it back as a curated page: every public header, grouped by area, with what it brings in and a link to its source. That answers "which header do I include for what", which is what the old listing was mostly used for; the reverse direction is already covered, since every generated page names the header its symbol comes from. Writing it surfaced four things that were quietly broken: - boost::math::fpc was not extracted at all, so the three references to close_at_tolerance, small_with_tolerance and the tolerance_based customisation point rendered as plain text. It is Boost.Test's own namespace, and the floating point chapter links straight into it. - Normalising the include path in CMakeLists.txt -- so the "Declared in" links stop going through a GitHub redirect for `doc/../include` -- activated an exclusion of boost/test/detail that had been inert because it never matched. That directory holds global_typedef.hpp, which the Doxygen target listed explicitly and which declares output_format; the exclusion is gone. - One reference named boost::unit_test::data::monomorphic::make_delayed, which is declared in boost::unit_test::data. - Footnotes containing a cross-reference were mangled: the converter escaped `]` in content it had already rendered, which broke the nested macro. Asciidoctor matches balanced brackets inside footnote:[] by itself. Eleven QuickBook code blocks nested inside list items had been flattened into multi-line inline code spans, with blank lines turned into list continuation markers. They are listing blocks again, with the indentation the sources had. All 102 cpp: references now resolve to a reference page, and all 470 fragment links point at an id that exists. Co-Authored-By: Claude Opus 5 (1M context) --- doc/CMakeLists.txt | 3 +- doc/modules/ROOT/nav.adoc | 1 + .../single_header_customizations.adoc | 26 +- doc/modules/ROOT/pages/change_log.adoc | 25 +- .../testing_tools/output_stream_testing.adoc | 2 +- .../tools_assertion_severity_level.adoc | 6 +- .../test_case_generation.adoc | 42 +-- doc/modules/ROOT/pages/usage_variants.adoc | 34 ++- .../ROOT/pages/utf_reference/index.adoc | 1 + .../ROOT/pages/utf_reference/ref_headers.adoc | 249 ++++++++++++++++++ doc/mrdocs.yml | 12 +- 11 files changed, 354 insertions(+), 47 deletions(-) create mode 100644 doc/modules/ROOT/pages/utf_reference/ref_headers.adoc diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index ad8ac2eb96..5a1f930fbf 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -43,7 +43,8 @@ add_library(mrdocs OBJECT mrdocs.cpp) # This worktree's headers must win over whatever the Boost checkout carries, # which matters when BOOST_SRC_DIR is a clone rather than the superproject this # library sits in. -target_include_directories(mrdocs BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include) +get_filename_component(BOOST_TEST_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../include" ABSOLUTE) +target_include_directories(mrdocs BEFORE PRIVATE ${BOOST_TEST_INCLUDE_DIR}) target_link_libraries(mrdocs PRIVATE Boost::unit_test_framework) set_target_properties(mrdocs PROPERTIES CXX_STANDARD 17 diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc index d8c692c9db..669aa3ef3b 100644 --- a/doc/modules/ROOT/nav.adoc +++ b/doc/modules/ROOT/nav.adoc @@ -75,4 +75,5 @@ ** xref:utf_reference/testout_reference.adoc[] ** xref:utf_reference/rt_param_reference.adoc[] ** xref:utf_reference/link_references.adoc[] +** xref:utf_reference/ref_headers.adoc[] ** xref:reference:index.adoc[C++ API reference] diff --git a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc index c5855d5886..4c0bfa43a8 100644 --- a/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc +++ b/doc/modules/ROOT/pages/adv_scenarios/single_header_customizations.adoc @@ -13,22 +13,30 @@ units: An example might be the following: * Translation unit 1, defines xref:{boost_test_module}[`BOOST_TEST_MODULE`] -`+#define BOOST_TEST_MODULE header-only multiunit test -#include + +[source,cpp] +---- +#define BOOST_TEST_MODULE header-only multiunit test +#include + BOOST_AUTO_TEST_CASE( test1 ) { -int i = 1; -BOOST_CHECK( i*i == 1 ); -}+` + int i = 1; + BOOST_CHECK( i*i == 1 ); +} +---- * Translation unit 2, includes `` instead of ``: -`+#include + +[source,cpp] +---- +#include + BOOST_AUTO_TEST_CASE( test2 ) { -int i = 1; -BOOST_CHECK( i*i == 1 ); -}+` + int i = 1; + BOOST_CHECK( i*i == 1 ); +} +---- [#entry_point] == Customizing the module's entry point diff --git a/doc/modules/ROOT/pages/change_log.adoc b/doc/modules/ROOT/pages/change_log.adoc index c30d2b38ca..682cd9bb25 100644 --- a/doc/modules/ROOT/pages/change_log.adoc +++ b/doc/modules/ROOT/pages/change_log.adoc @@ -63,9 +63,12 @@ option was set to `no`. Thanks to https://github.com/thughes[Tom Hughes] for thi * It is now possible to combine tolerance indication, user message and collection comparison modifier in a single `BOOST_TEST` expression + -`+std::vector v1 = f(); +[source,cpp] +---- +std::vector v1 = f(); std::vector v2{1.1, 1.19}; -BOOST_TEST(v1 == v2, boost::test_tools::tolerance( 1e-3 ) << "comparison to ground truth failed" << boost::test_tools::per_element());+` +BOOST_TEST(v1 == v2, boost::test_tools::tolerance( 1e-3 ) << "comparison to ground truth failed" << boost::test_tools::per_element()); +---- === Bugfixes and feature requests @@ -168,19 +171,25 @@ deprecated for a long time already, and will be removed in the near future. Plea switch to eg. the header only variable of Boost.Test. Tests using `minimal.hpp` can readily be converted to the header variant. For instance, the following code: + -`+#include +[source,cpp] +---- +#include int test_main( int, char *[] ) { -... -}+` + ... +} +---- + may be rewritten as: + -`+#include +[source,cpp] +---- +#include BOOST_AUTO_TEST_CASE(test_main) { -... -}+` + ... +} +---- * The floating point comparison behavior change may use this type of comparison while previously using straight relational operator comparison. In particular this may causes _new warnings_. * the member function cpp:boost::unit_test::unit_test_log_formatter::log_build_info[boost::unit_test::unit_test_log_formatter::log_build_info] has slightly changed diff --git a/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc b/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc index fcc92d0dad..0fca0e51e1 100644 --- a/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc +++ b/doc/modules/ROOT/pages/testing_tools/output_stream_testing.adoc @@ -21,7 +21,7 @@ string comparison and error message generation is automated by the tool implemen All `output_test_stream` validation member functions by default flush the stream once the check is performed. If you want to perform several checks with the same output, specify parameter `flush_stream` with value `false` footnote:[This parameter is supported on all comparison methods, see the class -cpp:boost::test_tools::output_test_stream[documentation.\]]. +cpp:boost::test_tools::output_test_stream[documentation].]. In some cases manual generation of expected output is either too time consuming or is impossible at all because of sheer volume. A possible way to address that issue is to split the test in two steps: diff --git a/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc index 873d8b18c1..57c10aa49b 100644 --- a/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc +++ b/doc/modules/ROOT/pages/testing_tools/tools_assertion_severity_level.adoc @@ -16,15 +16,15 @@ to validate aspects less important then correctness: performance, portability, u For example: * xref:utf_reference/testing_tool_ref.adoc#assertion_boost_level_throw[`BOOST_REQUIRE_THROW`], xref:{boost_test_require}[`BOOST_TEST_REQUIRE`] -* `BOOST_CHECK_THROW`, `BOOST_TEST` footnote:[xref:{boost_test}[`BOOST_TEST`\] is equivalent to `BOOST_TEST_CHECK`] +* `BOOST_CHECK_THROW`, `BOOST_TEST` footnote:[xref:{boost_test}[`BOOST_TEST`] is equivalent to `BOOST_TEST_CHECK`] * `BOOST_WARN_THROW`, `BOOST_TEST_WARN` These three levels of assertions are filtered by the framework and reported into the test log and output: . If an assertion designated by the tool passes, confirmation message can be printed in log output -footnote:[to manage what messages appear in the test log stream, set the proper xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`\]]. +footnote:[to manage what messages appear in the test log stream, set the proper xref:utf_reference/rt_param_reference.adoc#log_level[`log_level`]]. . If an assertion designated by the tool fails, the following will happen, depending on the assertion level -footnote:[in some cases log message can be slightly different to reflect failed tool specifics, see xref:testing_tools/reports.adoc[here\]]: +footnote:[in some cases log message can be slightly different to reflect failed tool specifics, see xref:testing_tools/reports.adoc[here]]: [#assertions_severity_levels] .Assertions severity levels diff --git a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc index 05ad3fd7de..b87b2a4e73 100644 --- a/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc +++ b/doc/modules/ROOT/pages/tests_organization/test_case_generation.adoc @@ -53,23 +53,27 @@ to the test. types `T1` and `T2` respectively. Now we would like to test a new functions `func3` that takes as argument a type `T3` containing `T1` and `T2`, and calling `func1` and `func2` through a known algorithm. An example of such a setting would be -`// Returns the log of x ++ +[source,cpp] +---- +// Returns the log of x // Precondition: x strictly positive. double fast_log(double x); -+ + // Returns 1/(x-1) // Precondition: x != 1 double fast_inv(double x); -+ -struct dummy \{ -unsigned int field1; -unsigned int field2; + +struct dummy { + unsigned int field1; + unsigned int field2; }; -+ + double func3(dummy value) -\{ -return 0.5 * (exp(fast_log(value.field1))/value.field1 + value.field2/fast_inv(value.field2)); -}` +{ + return 0.5 * (exp(fast_log(value.field1))/value.field1 + value.field2/fast_inv(value.field2)); +} +---- + In this example, ** `func3` inherits from the preconditions of `fast_log` and `fast_inv`: it is defined in `(0, +infinity)` and in `[-C, +C] - \{1}` for `field1` and `field2` respectively (`C` @@ -128,7 +132,7 @@ The descriptive power of the datasets in _Unit Test Framework_ comes from ==== Only "monomorphic" datasets are supported, which means that all samples within a single dataset have the same type and same arity footnote:[polymorphic datasets will be considered in the future. Their need is mainly driven by the replacement of the - xref:tests_organization/test_organization_templates.adoc[typed parametrized test cases\] by the dataset-like API.] + xref:tests_organization/test_organization_templates.adoc[typed parametrized test cases] by the dataset-like API.] . However, dataset of different sample types may be combined together with zip and cartesian product. ==== @@ -173,7 +177,7 @@ that has been instantiated after the `main` of the test module entry. To overcome this, a *delayed* dataset instantiation interface has been introduced. This effectively wraps the dataset inside another one, which *lazyly* instantiates the dataset. -To instantiate a delayed dataset, the cpp:boost::unit_test::data::monomorphic::make_delayed[boost::unit_test::data::monomorphic::make_delayed] function should be used in the +To instantiate a delayed dataset, the cpp:boost::unit_test::data::make_delayed[boost::unit_test::data::make_delayed] function should be used in the xref:{boost_data_test_case}[`BOOST_DATA_TEST_CASE`] call. The following snippet: [source,cpp] @@ -327,9 +331,12 @@ The following properties hold: * the resulting dataset is of same arity as the operand datasets, * the size of the returned dataset is the sum of the size of the joined datasets, * the operation is associative, and it is possible to combine more than two datasets in one expression. The following joins are equivalent for any datasets `dsa`, `dsb` and `dsc`: -`( dsa + dsb ) + dsc +[source,cpp] +---- +( dsa + dsb ) + dsc == dsa + ( dsb + dsc ) -== dsa + dsb + dsc` +== dsa + dsb + dsc +---- [WARNING] ==== @@ -362,9 +369,12 @@ The following properties hold: * the size of the resulting dataset is equal to the size of the datasets (since they are supposed to be of the same size), exception made for the case the operand datasets size mismatch (see below), * the operation is associative, and it is possible to combine more than two datasets in one expression, -`+( dsa ^ dsb ) ^ dsc +[source,cpp] +---- +( dsa ^ dsb ) ^ dsc == dsa ^ ( dsb ^ dsc ) -== dsa ^ dsb ^ dsc+` +== dsa ^ dsb ^ dsc +---- A particular handling is performed if `dsa` and `dsb` are of different size. The rule is as follow: diff --git a/doc/modules/ROOT/pages/usage_variants.adoc b/doc/modules/ROOT/pages/usage_variants.adoc index e1e32fa062..30686d58d3 100644 --- a/doc/modules/ROOT/pages/usage_variants.adoc +++ b/doc/modules/ROOT/pages/usage_variants.adoc @@ -42,10 +42,20 @@ xref:adv_scenarios/build_utf.adoc[build it] themselves, following usage can be m and simple approach. This usage variant entails two steps. . First, the following line needs to be added to all translation units in the test module: -`+#include +` ++ +[source,cpp] +---- +#include +---- ++ One and *only one* translation unit should include following lines: -`+#define BOOST_TEST_MODULE test module name -#include +` ++ +[source,cpp] +---- +#define BOOST_TEST_MODULE test module name +#include +---- ++ xref:{boost_test_module}[`BOOST_TEST_MODULE`] macro needs to be defined *before* the include and should indicate the name of the test module. This name can include spaces and does not need to be wrapped in quotes. . The second step is to link with the _Unit Test Framework_ *static* library. @@ -66,12 +76,22 @@ _Unit Test Framework_ built as a shared library. This usage variant entails two steps. . First you need to add following lines to all translation units in a test module: -`+#define BOOST_TEST_DYN_LINK -#include +` ++ +[source,cpp] +---- +#define BOOST_TEST_DYN_LINK +#include +---- ++ and *only one* translation unit should include following lines -`+#define BOOST_TEST_MODULE test module name ++ +[source,cpp] +---- +#define BOOST_TEST_MODULE test module name #define BOOST_TEST_DYN_LINK -#include +` +#include +---- ++ `BOOST_TEST_MODULE` and `BOOST_TEST_DYN_LINK` macros needs to be defined *before* the include. `BOOST_TEST_MODULE` should be set to test module name. This name can include spaces and does not need to be wrapped in quotes. diff --git a/doc/modules/ROOT/pages/utf_reference/index.adoc b/doc/modules/ROOT/pages/utf_reference/index.adoc index f6af2cd783..afa8bc6c67 100644 --- a/doc/modules/ROOT/pages/utf_reference/index.adoc +++ b/doc/modules/ROOT/pages/utf_reference/index.adoc @@ -17,6 +17,7 @@ them. parameter, with its command-line syntax and environment variable * xref:utf_reference/link_references.adoc[] -- the macros that select a build variant and the behaviours they switch on +* xref:utf_reference/ref_headers.adoc[] -- which header to include for what The C++ API -- classes, functions and types -- is generated from the headers by https://www.mrdocs.com[MrDocs] and lives in diff --git a/doc/modules/ROOT/pages/utf_reference/ref_headers.adoc b/doc/modules/ROOT/pages/utf_reference/ref_headers.adoc new file mode 100644 index 0000000000..839aff0883 --- /dev/null +++ b/doc/modules/ROOT/pages/utf_reference/ref_headers.adoc @@ -0,0 +1,249 @@ += Headers +:page-aliases: boost_test/utf_reference/headers.adoc + +The public headers of the _Unit Test Framework_, and what each one brings in. +Every page in xref:reference:index.adoc[the generated reference] also names the +header its symbol is declared in, so this page is the way round the other one +does not cover: which header to include for a given facility. + +Most test modules include only `boost/test/unit_test.hpp`, or one of the +xref:usage_variants.adoc[usage variant] headers. The rest matter when +customising the framework or when reaching for a specific component. + +== Core + +`boost/test/unit_test.hpp`:: +The header a test module includes. Pulls in the test tree, the assertion +macros, the logger and the runner. +link:{base-url}/include/boost/test/unit_test.hpp[source] + +`boost/test/framework.hpp`:: +The framework's own interface: initialisation, running the test tree, and +access to the unit under execution -- +cpp:boost::unit_test::framework::run[`run`], +cpp:boost::unit_test::framework::current_test_case[`current_test_case`], +cpp:boost::unit_test::framework::setup_error[`setup_error`]. +link:{base-url}/include/boost/test/framework.hpp[source] + +`boost/test/execution_monitor.hpp`:: +cpp:boost::execution_monitor[`execution_monitor`], which runs a function in a +controlled environment, and cpp:boost::execution_exception[`execution_exception`]. +Also declares xref:utf_reference/link_references.adoc#config_disable_alt_stack[`BOOST_TEST_DISABLE_ALT_STACK`]. +link:{base-url}/include/boost/test/execution_monitor.hpp[source] + +`boost/test/unit_test_parameters.hpp`:: +The xref:utf_reference/rt_param_reference.adoc[runtime parameters] as the +framework sees them, once the command line and the environment have been read. +link:{base-url}/include/boost/test/unit_test_parameters.hpp[source] + +`boost/test/debug.hpp`:: +Debugger detection and attachment: cpp:boost::debug::under_debugger[`under_debugger`], +cpp:boost::debug::attach_debugger[`attach_debugger`], cpp:boost::debug::set_debugger[`set_debugger`]. +`boost/test/debug_config.hpp` is the empty customisation header it includes, +for you to define the debugger configuration macros in. +link:{base-url}/include/boost/test/debug.hpp[source] + +`boost/test/progress_monitor.hpp`:: +cpp:boost::unit_test::progress_monitor_t[`progress_monitor_t`], the observer +behind xref:test_output/test_output_progress.adoc[progress display]. +link:{base-url}/include/boost/test/progress_monitor.hpp[source] + +== Test tree + +`boost/test/tree/test_unit.hpp`:: +cpp:boost::unit_test::test_case[`test_case`], +cpp:boost::unit_test::test_suite[`test_suite`] and the +cpp:boost::unit_test::test_unit[`test_unit`] they share, plus +cpp:boost::unit_test::master_test_suite_t[`master_test_suite_t`]. +link:{base-url}/include/boost/test/tree/test_unit.hpp[source] + +`boost/test/tree/observer.hpp`:: +cpp:boost::unit_test::test_observer[`test_observer`], the interface the logger, +the results collector and the progress monitor all implement. +link:{base-url}/include/boost/test/tree/observer.hpp[source] + +`boost/test/parameterized_test.hpp`:: +`BOOST_PARAM_TEST_CASE`, which builds a test case per element of a sequence. +Superseded by xref:tests_organization/test_case_generation.adoc[data-driven test cases]. +link:{base-url}/include/boost/test/parameterized_test.hpp[source] + +== Assertions + +`boost/test/tools/assertion_result.hpp`:: +cpp:boost::test_tools::assertion_result[`assertion_result`], what a +xref:testing_tools/custom_predicates.adoc[custom predicate] returns when it +wants to explain itself. +link:{base-url}/include/boost/test/tools/assertion_result.hpp[source] + +`boost/test/tools/floating_point_comparison.hpp`:: +The xref:testing_tools/floating_point.adoc[floating point comparison] +machinery: cpp:boost::math::fpc::close_at_tolerance[`close_at_tolerance`], +cpp:boost::math::fpc::small_with_tolerance[`small_with_tolerance`], and the +cpp:boost::math::fpc::tolerance_based[`tolerance_based`] trait to specialise +for a user-defined type. +link:{base-url}/include/boost/test/tools/floating_point_comparison.hpp[source] + +`boost/test/tools/output_test_stream.hpp`:: +cpp:boost::test_tools::output_test_stream[`output_test_stream`], for +xref:testing_tools/output_stream_testing.adoc[comparing output against a pattern]. +link:{base-url}/include/boost/test/tools/output_test_stream.hpp[source] + +`boost/test/tools/detail/tolerance_manip.hpp`:: +The cpp:boost::test_tools::tolerance[`tolerance`] manipulator. +link:{base-url}/include/boost/test/tools/detail/tolerance_manip.hpp[source] + +`boost/test/tools/detail/bitwise_manip.hpp`:: +The cpp:boost::test_tools::bitwise[`bitwise`] manipulator, for +xref:testing_tools/bitwise.adoc[bitwise comparison]. +link:{base-url}/include/boost/test/tools/detail/bitwise_manip.hpp[source] + +`boost/test/tools/detail/per_element_manip.hpp`:: +The cpp:boost::test_tools::per_element[`per_element`] manipulator, for +xref:testing_tools/collections.adoc[element-wise collection comparison]. +link:{base-url}/include/boost/test/tools/detail/per_element_manip.hpp[source] + +`boost/test/tools/detail/lexicographic_manip.hpp`:: +The cpp:boost::test_tools::lexicographic[`lexicographic`] manipulator. +link:{base-url}/include/boost/test/tools/detail/lexicographic_manip.hpp[source] + +== Logs and reports + +`boost/test/unit_test_log.hpp`:: +cpp:boost::unit_test::unit_test_log_t[`unit_test_log_t`], the +xref:test_output/logging_api.adoc[logging API]: where the log goes, how +verbose it is and in which format. +link:{base-url}/include/boost/test/unit_test_log.hpp[source] + +`boost/test/unit_test_log_formatter.hpp`:: +cpp:boost::unit_test::unit_test_log_formatter[`unit_test_log_formatter`], the +interface to implement for a +xref:test_output/logging_api.adoc#custom_log_formatter[custom log format]. +link:{base-url}/include/boost/test/unit_test_log_formatter.hpp[source] + +`boost/test/results_collector.hpp`:: +cpp:boost::unit_test::results_collector_t[`results_collector_t`] and the +cpp:boost::unit_test::test_results[`test_results`] it accumulates per test unit. +link:{base-url}/include/boost/test/results_collector.hpp[source] + +`boost/test/results_reporter.hpp`:: +The xref:test_output/report_formats.adoc[report] side: format selection, +output stream and detail level. +link:{base-url}/include/boost/test/results_reporter.hpp[source] + +`boost/test/output/compiler_log_formatter.hpp`:: +The human readable log format, which imitates compiler diagnostics so an IDE +can jump to the failure. +link:{base-url}/include/boost/test/output/compiler_log_formatter.hpp[source] + +`boost/test/output/xml_log_formatter.hpp`:: +The XML log format. +link:{base-url}/include/boost/test/output/xml_log_formatter.hpp[source] + +`boost/test/output/plain_report_formatter.hpp`:: +The human readable report format. +link:{base-url}/include/boost/test/output/plain_report_formatter.hpp[source] + +`boost/test/output/xml_report_formatter.hpp`:: +The XML report format. +link:{base-url}/include/boost/test/output/xml_report_formatter.hpp[source] + +== Datasets + +`boost/test/data/test_case.hpp`:: +`BOOST_DATA_TEST_CASE` and `BOOST_DATA_TEST_CASE_F`. Including it is what makes +a xref:tests_organization/test_case_generation.adoc[data-driven test case] +available. +link:{base-url}/include/boost/test/data/test_case.hpp[source] + +`boost/test/data/monomorphic/fwd.hpp`:: +cpp:boost::unit_test::data::make[`make`], which turns a value, a collection or +an initializer list into a dataset, and the +cpp:boost::unit_test::data::monomorphic::is_dataset[`is_dataset`] trait. +link:{base-url}/include/boost/test/data/monomorphic/fwd.hpp[source] + +`boost/test/data/config.hpp`:: +Defines `BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE`, +xref:utf_reference/link_references.adoc#config_no_zip_composition[`BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE`] +and +xref:utf_reference/link_references.adoc#config_no_grid_composition[`BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE`] +when the standard library in use cannot support those features. +link:{base-url}/include/boost/test/data/config.hpp[source] + +`boost/test/data/size.hpp`:: +cpp:boost::unit_test::data::size_t[`size_t`], a dataset size that can be +infinite. +link:{base-url}/include/boost/test/data/size.hpp[source] + +`boost/test/data/for_each_sample.hpp`:: +cpp:boost::unit_test::data::for_each_sample[`for_each_sample`], how a dataset +hands its samples to the test body. +link:{base-url}/include/boost/test/data/for_each_sample.hpp[source] + +The dataset kinds each have their own header, all under +`boost/test/data/monomorphic/`: + +[%autowidth,cols="2*"] +|=== +|`singleton.hpp` +|A dataset of exactly one sample + +|`array.hpp` +|A dataset over a C array + +|`collection.hpp` +|A dataset over an STL collection + +|`initializer_list.hpp` +|A dataset over a braced list + +|`generate.hpp` +|A dataset produced by a generator + +|`delayed.hpp` +|A dataset constructed only when the test runs, via + cpp:boost::unit_test::data::make_delayed[`make_delayed`] + +|`join.hpp` +|xref:tests_organization/test_case_generation.adoc#operations[Concatenation] of two datasets + +|`zip.hpp` +|xref:tests_organization/test_case_generation.adoc#operations[Zip] of two datasets + +|`grid.hpp` +|xref:tests_organization/test_case_generation.adoc#operations[Cartesian product] of two datasets +|=== + +`boost/test/data/monomorphic/generators.hpp`:: +Includes the generators below. +link:{base-url}/include/boost/test/data/monomorphic/generators.hpp[source] + +`boost/test/data/monomorphic/generators/xrange.hpp`:: +cpp:boost::unit_test::data::xrange[`xrange`], a dataset of evenly spaced values. +link:{base-url}/include/boost/test/data/monomorphic/generators/xrange.hpp[source] + +`boost/test/data/monomorphic/generators/random.hpp`:: +cpp:boost::unit_test::data::random[`random`], an infinite dataset of random +values, with `seed`, `distribution` and `engine` named parameters. +link:{base-url}/include/boost/test/data/monomorphic/generators/random.hpp[source] + +`boost/test/data/monomorphic/generators/keywords.hpp`:: +The `begin`, `end` and `step` named parameters `xrange` takes. +link:{base-url}/include/boost/test/data/monomorphic/generators/keywords.hpp[source] + +== Utilities + +`boost/test/utils/is_forward_iterable.hpp`:: +cpp:boost::unit_test::is_forward_iterable[`is_forward_iterable`] and +cpp:boost::unit_test::is_container_forward_iterable[`is_container_forward_iterable`], +the traits that decide whether `BOOST_TEST` treats a type as +xref:testing_tools/collections.adoc[a collection]. +link:{base-url}/include/boost/test/utils/is_forward_iterable.hpp[source] + +`boost/test/utils/named_params.hpp`:: +The named parameter mechanism the decorators and the dataset generators use. +link:{base-url}/include/boost/test/utils/named_params.hpp[source] + +`boost/test/utils/algorithm.hpp`:: +The small algorithms the framework needs and the standard library does not +provide, such as `find_first_not_of` over two ranges. +link:{base-url}/include/boost/test/utils/algorithm.hpp[source] diff --git a/doc/mrdocs.yml b/doc/mrdocs.yml index f375abdd6e..f7b83be765 100644 --- a/doc/mrdocs.yml +++ b/doc/mrdocs.yml @@ -17,9 +17,11 @@ exclude: # Definitions, not declarations: pulled in only by the header-only variant. - '../include/boost/test/impl' - '../include/boost/test/included' - # Assembly headers and internal plumbing with no public API of their own. - - '../include/boost/test/detail' - '../include/boost/test/utils/runtime' +# Note: boost/test/detail is deliberately *not* excluded. global_typedef.hpp +# lives there and declares public enums the narrative links to, such as +# output_format; the Doxygen target this replaced listed it explicitly. The +# rest of that directory is plumbing that the symbol filters below drop anyway. compilation-database: ./CMakeLists.txt # Filters @@ -27,11 +29,17 @@ include-symbols: - 'boost::unit_test::**' - 'boost::test_tools::**' - 'boost::debug::**' + # Boost.Test declares its floating point comparison predicates, and the + # tolerance_based customisation point users specialise, in this namespace -- + # it is ours, not Boost.Math's, and the chapter on floating point comparison + # links straight into it. + - 'boost::math::fpc::**' - 'boost::execution_exception' - 'boost::execution_monitor' - 'boost::execution_aborted' - 'boost::system_error' implementation-defined: + - 'boost::math::fpc::fpc_detail' - 'boost::unit_test::ut_detail' - 'boost::unit_test::**::ut_detail' - 'boost::unit_test::**::ds_detail'