summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/quickbook/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/tools/quickbook/test/unit')
-rw-r--r--src/boost/tools/quickbook/test/unit/Jamfile.v231
-rw-r--r--src/boost/tools/quickbook/test/unit/cleanup_test.cpp80
-rw-r--r--src/boost/tools/quickbook/test/unit/glob_test.cpp163
-rw-r--r--src/boost/tools/quickbook/test/unit/path_test.cpp189
-rw-r--r--src/boost/tools/quickbook/test/unit/post_process_test.cpp27
-rw-r--r--src/boost/tools/quickbook/test/unit/source_map_test.cpp444
-rw-r--r--src/boost/tools/quickbook/test/unit/symbols_find_null.cpp36
-rw-r--r--src/boost/tools/quickbook/test/unit/symbols_tests.cpp374
-rw-r--r--src/boost/tools/quickbook/test/unit/utils_test.cpp67
-rw-r--r--src/boost/tools/quickbook/test/unit/values_test.cpp128
10 files changed, 1539 insertions, 0 deletions
diff --git a/src/boost/tools/quickbook/test/unit/Jamfile.v2 b/src/boost/tools/quickbook/test/unit/Jamfile.v2
new file mode 100644
index 000000000..43271b48c
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/Jamfile.v2
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2011 Daniel James
+#
+# 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)
+#
+
+import testing ;
+
+project quickbook/test/unit-tests
+ : requirements
+ <include>../../src
+ <warnings>all
+ <library>/boost//filesystem
+ <toolset>gcc:<cflags>-g0
+ <toolset>darwin:<cflags>-g0
+ <toolset>msvc:<cflags>/wd4709
+ ;
+
+run values_test.cpp ../../src/values.cpp ../../src/files.cpp ;
+run post_process_test.cpp ../../src/post_process.cpp ;
+run source_map_test.cpp ../../src/files.cpp ;
+run glob_test.cpp ../../src/glob.cpp ;
+run utils_test.cpp ../../src/id_xml.cpp ../../src/utils.cpp ;
+run cleanup_test.cpp ;
+run path_test.cpp ../../src/path.cpp ../../src/native_text.cpp ../../src/utils.cpp ;
+
+# Copied from spirit
+run symbols_tests.cpp ;
+run symbols_find_null.cpp ;
diff --git a/src/boost/tools/quickbook/test/unit/cleanup_test.cpp b/src/boost/tools/quickbook/test/unit/cleanup_test.cpp
new file mode 100644
index 000000000..4952c991a
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/cleanup_test.cpp
@@ -0,0 +1,80 @@
+
+/*=============================================================================
+ Copyright (c) 2017 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <vector>
+#include <boost/core/lightweight_test.hpp>
+#include "cleanup.hpp"
+
+struct counted
+{
+ static int count;
+ static std::vector<int> destroyed;
+ static void reset()
+ {
+ count = 0;
+ destroyed.clear();
+ }
+
+ int value;
+
+ counted(int v) : value(v)
+ {
+ BOOST_TEST(value != -1);
+ ++count;
+ }
+
+ counted(counted const& x) : value(x.value)
+ {
+ BOOST_TEST(value != -1);
+ ++count;
+ }
+
+ ~counted()
+ {
+ BOOST_TEST(value != -1);
+ destroyed.push_back(value);
+ value = -1;
+ BOOST_TEST(count > 0);
+ --count;
+ }
+};
+
+int counted::count = 0;
+std::vector<int> counted::destroyed;
+
+int main()
+{
+ counted::reset();
+ {
+ quickbook::cleanup c;
+ }
+ BOOST_TEST(counted::count == 0);
+
+ counted::reset();
+ {
+ quickbook::cleanup c;
+ counted& v1 = c.add(new counted(1));
+ counted& v2 = c.add(new counted(2));
+ BOOST_TEST(v1.value == 1);
+ BOOST_TEST(v2.value == 2);
+ }
+ BOOST_TEST(counted::count == 0);
+ BOOST_TEST(counted::destroyed.size() == 2);
+ BOOST_TEST(counted::destroyed[0] == 2);
+ BOOST_TEST(counted::destroyed[1] == 1);
+
+ counted::reset();
+ {
+ quickbook::cleanup c;
+ int& x = c.add(new int(10));
+ BOOST_TEST(x == 10);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/glob_test.cpp b/src/boost/tools/quickbook/test/unit/glob_test.cpp
new file mode 100644
index 000000000..27d2611b3
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/glob_test.cpp
@@ -0,0 +1,163 @@
+/*=============================================================================
+ Copyright (c) 2013 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include "glob.hpp"
+
+void glob_tests()
+{
+ BOOST_TEST(quickbook::glob("", ""));
+
+ BOOST_TEST(!quickbook::glob("*", ""));
+ BOOST_TEST(quickbook::glob("*", "a"));
+ BOOST_TEST(quickbook::glob("*b", "b"));
+ BOOST_TEST(quickbook::glob("*b", "ab"));
+ BOOST_TEST(quickbook::glob("*b", "bab"));
+ BOOST_TEST(quickbook::glob("*b*", "b"));
+ BOOST_TEST(quickbook::glob("*b*", "ab"));
+ BOOST_TEST(quickbook::glob("*b*", "bc"));
+ BOOST_TEST(quickbook::glob("*b*", "abc"));
+ BOOST_TEST(!quickbook::glob("*b*", ""));
+ BOOST_TEST(!quickbook::glob("*b*", "a"));
+ BOOST_TEST(!quickbook::glob("*b*", "ac"));
+
+ BOOST_TEST(quickbook::glob("hello.txt", "hello.txt"));
+ BOOST_TEST(!quickbook::glob("world.txt", "helloworld.txt"));
+ BOOST_TEST(quickbook::glob("*world.txt", "helloworld.txt"));
+ BOOST_TEST(!quickbook::glob("world.txt*", "helloworld.txt"));
+ BOOST_TEST(!quickbook::glob("hello", "helloworld.txt"));
+ BOOST_TEST(!quickbook::glob("*hello", "helloworld.txt"));
+ BOOST_TEST(quickbook::glob("hello*", "helloworld.txt"));
+ BOOST_TEST(quickbook::glob("*world*", "helloworld.txt"));
+
+ BOOST_TEST(quickbook::glob("?", "a"));
+ BOOST_TEST(!quickbook::glob("?", ""));
+ BOOST_TEST(!quickbook::glob("?", "ab"));
+ BOOST_TEST(quickbook::glob("a?", "ab"));
+ BOOST_TEST(quickbook::glob("?b", "ab"));
+ BOOST_TEST(quickbook::glob("?bc", "abc"));
+ BOOST_TEST(quickbook::glob("a?c", "abc"));
+ BOOST_TEST(quickbook::glob("ab?", "abc"));
+ BOOST_TEST(!quickbook::glob("?bc", "aac"));
+ BOOST_TEST(!quickbook::glob("a?c", "bbc"));
+ BOOST_TEST(!quickbook::glob("ab?", "abcd"));
+
+ BOOST_TEST(quickbook::glob("[a]", "a"));
+ BOOST_TEST(!quickbook::glob("[^a]", "a"));
+ BOOST_TEST(!quickbook::glob("[b]", "a"));
+ BOOST_TEST(quickbook::glob("[^b]", "a"));
+ BOOST_TEST(quickbook::glob("[a-z]", "a"));
+ BOOST_TEST(!quickbook::glob("[^a-z]", "a"));
+ BOOST_TEST(!quickbook::glob("[b-z]", "a"));
+ BOOST_TEST(quickbook::glob("[^b-z]", "a"));
+ BOOST_TEST(quickbook::glob("[-a]", "a"));
+ BOOST_TEST(quickbook::glob("[-a]", "-"));
+ BOOST_TEST(!quickbook::glob("[-a]", "b"));
+ BOOST_TEST(!quickbook::glob("[^-a]", "a"));
+ BOOST_TEST(!quickbook::glob("[^-a]", "-"));
+ BOOST_TEST(quickbook::glob("[^-a]", "b"));
+ BOOST_TEST(quickbook::glob("[a-]", "a"));
+ BOOST_TEST(quickbook::glob("[a-]", "-"));
+ BOOST_TEST(!quickbook::glob("[a-]", "b"));
+ BOOST_TEST(!quickbook::glob("[^a-]", "a"));
+ BOOST_TEST(!quickbook::glob("[^a-]", "-"));
+ BOOST_TEST(quickbook::glob("[^a-]", "b"));
+ BOOST_TEST(quickbook::glob("[a-ce-f]", "a"));
+ BOOST_TEST(!quickbook::glob("[a-ce-f]", "d"));
+ BOOST_TEST(quickbook::glob("[a-ce-f]", "f"));
+ BOOST_TEST(!quickbook::glob("[a-ce-f]", "g"));
+ BOOST_TEST(!quickbook::glob("[^a-ce-f]", "a"));
+ BOOST_TEST(quickbook::glob("[^a-ce-f]", "d"));
+ BOOST_TEST(!quickbook::glob("[^a-ce-f]", "f"));
+ BOOST_TEST(quickbook::glob("[^a-ce-f]", "g"));
+ BOOST_TEST(!quickbook::glob("[b]", "a"));
+ BOOST_TEST(quickbook::glob("[a]bc", "abc"));
+ BOOST_TEST(quickbook::glob("a[b]c", "abc"));
+ BOOST_TEST(quickbook::glob("ab[c]", "abc"));
+ BOOST_TEST(quickbook::glob("a[a-c]c", "abc"));
+ BOOST_TEST(quickbook::glob("*[b]*", "abc"));
+ BOOST_TEST(quickbook::glob("[\\]]", "]"));
+ BOOST_TEST(!quickbook::glob("[^\\]]", "]"));
+
+ BOOST_TEST(quickbook::glob("b*ana", "banana"));
+ BOOST_TEST(quickbook::glob("1234*1234*1234", "123412341234"));
+ BOOST_TEST(!quickbook::glob("1234*1234*1234", "1234123341234"));
+ BOOST_TEST(quickbook::glob("1234*1234*1234", "123412312312341231231234"));
+ BOOST_TEST(!quickbook::glob("1234*1234*1234", "12341231231234123123123"));
+}
+
+void invalid_glob_tests()
+{
+ // Note that glob only throws an exception when the pattern matches up to
+ // the point where the error occurs.
+ BOOST_TEST_THROWS(quickbook::glob("[", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[^", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[xyz", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[xyz\\", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[x\\y", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[a-", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[a-z", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[a-\\", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[a-\\a", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("xyx[", "xyxa"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("abc]", "abcd"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("]def", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[[]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[]]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("**", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[/]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[\\/]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[ -/]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("[ -\\/]", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("\\", "a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::glob("\\\\", "a"), quickbook::glob_error);
+}
+
+void check_glob_tests()
+{
+ BOOST_TEST(!quickbook::check_glob(""));
+ BOOST_TEST(!quickbook::check_glob("file"));
+ BOOST_TEST(!quickbook::check_glob("file\\[\\]"));
+ BOOST_TEST(quickbook::check_glob("[x]"));
+ BOOST_TEST(quickbook::check_glob("abc[x]"));
+ BOOST_TEST(quickbook::check_glob("[x]abd"));
+ BOOST_TEST_THROWS(quickbook::check_glob("["), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[^"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[xyz"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[xyz\\"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[x\\y"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[a-"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[a-z"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[a-\\"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[a-\\a"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("xyx["), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("abc]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("]def"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[[]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[]]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("**"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[/]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[\\/]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[ -/]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("[ -\\/]"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("\\"), quickbook::glob_error);
+ BOOST_TEST_THROWS(quickbook::check_glob("\\\\"), quickbook::glob_error);
+}
+
+int main()
+{
+ glob_tests();
+ invalid_glob_tests();
+ check_glob_tests();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/path_test.cpp b/src/boost/tools/quickbook/test/unit/path_test.cpp
new file mode 100644
index 000000000..734769ef6
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/path_test.cpp
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2015 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/predef.h>
+#include "path.hpp"
+
+void file_path_to_url_tests()
+{
+ using boost::filesystem::path;
+ using quickbook::file_path_to_url;
+
+ BOOST_TEST_EQ(std::string(), file_path_to_url(path()));
+ BOOST_TEST_EQ(std::string("."), file_path_to_url(path(".")));
+ BOOST_TEST_EQ(std::string("./"), file_path_to_url(path("./")));
+ BOOST_TEST_EQ(std::string("a/b"), file_path_to_url(path("a/b")));
+ BOOST_TEST_EQ(std::string("a/b/"), file_path_to_url(path("a/b/")));
+ BOOST_TEST_EQ(std::string("./a/b"), file_path_to_url(path("./a/./././b")));
+ BOOST_TEST_EQ(std::string("../a/b"), file_path_to_url(path("../a/b")));
+ BOOST_TEST_EQ(
+ std::string("A%20B%2bC%2520"), file_path_to_url(path("A B+C%20")));
+ BOOST_TEST_EQ(std::string("file:///"), file_path_to_url(path("/")));
+ BOOST_TEST_EQ(std::string("file:///a/b"), file_path_to_url(path("/a/b")));
+ BOOST_TEST_EQ(std::string("file:///a/b/"), file_path_to_url(path("/a/b/")));
+ BOOST_TEST_EQ(
+ std::string("file://hello/a/b"), file_path_to_url(path("//hello/a/b")));
+
+#if BOOST_OS_WINDOWS || BOOST_OS_CYGWIN
+ // Should this be file:///c:/x ?
+ BOOST_TEST_EQ(
+ std::string("file://?/a:/x"), file_path_to_url(path("\\\\?\\a:\\x")));
+ BOOST_TEST_EQ(std::string("file:///a"), file_path_to_url(path("\\a")));
+ BOOST_TEST_EQ(std::string("file:///c:/"), file_path_to_url(path("c:\\")));
+ BOOST_TEST_EQ(
+ std::string("file:///c:/foo/bar"),
+ file_path_to_url(path("c:\\foo\\bar")));
+ BOOST_TEST_EQ(
+ std::string("file://localhost/c:/foo/bar"),
+ file_path_to_url(path("\\\\localhost\\c:\\foo\\bar")));
+
+ // Really not sure what to do with these examples.
+ // Maybe an error?
+ BOOST_TEST_EQ(std::string("file:///c:"), file_path_to_url(path("c:")));
+ BOOST_TEST_EQ(
+ std::string("file:///c:foo/bar"), file_path_to_url(path("c:foo\\bar")));
+#endif
+}
+
+void dir_path_to_url_tests()
+{
+ using boost::filesystem::path;
+ using quickbook::dir_path_to_url;
+
+ BOOST_TEST_EQ(std::string("./"), dir_path_to_url(path()));
+ BOOST_TEST_EQ(std::string("./"), dir_path_to_url(path(".")));
+ BOOST_TEST_EQ(std::string("./"), dir_path_to_url(path("./")));
+ BOOST_TEST_EQ(std::string("a/b/"), dir_path_to_url(path("a/b")));
+ BOOST_TEST_EQ(std::string("a/b/"), dir_path_to_url(path("a/b/")));
+ BOOST_TEST_EQ(std::string("./a/b/"), dir_path_to_url(path("./a/./././b")));
+ BOOST_TEST_EQ(std::string("../a/b/"), dir_path_to_url(path("../a/b")));
+ BOOST_TEST_EQ(
+ std::string("A%20B%2bC%2520/"), dir_path_to_url(path("A B+C%20")));
+ BOOST_TEST_EQ(std::string("file:///"), dir_path_to_url(path("/")));
+ BOOST_TEST_EQ(std::string("file:///a/b/"), dir_path_to_url(path("/a/b")));
+ BOOST_TEST_EQ(std::string("file:///a/b/"), dir_path_to_url(path("/a/b/")));
+ BOOST_TEST_EQ(
+ std::string("file://hello/a/b/"), dir_path_to_url(path("//hello/a/b")));
+
+#if BOOST_OS_WINDOWS || BOOST_OS_CYGWIN
+ // Should this be file:///c:/x/ ?
+ BOOST_TEST_EQ(
+ std::string("file://?/a:/x/"), dir_path_to_url(path("\\\\?\\a:\\x")));
+ BOOST_TEST_EQ(std::string("file:///a/"), dir_path_to_url(path("\\a")));
+ BOOST_TEST_EQ(std::string("file:///c:/"), dir_path_to_url(path("c:\\")));
+ BOOST_TEST_EQ(
+ std::string("file:///c:/foo/bar/"),
+ dir_path_to_url(path("c:\\foo\\bar")));
+ BOOST_TEST_EQ(
+ std::string("file://localhost/c:/foo/bar/"),
+ dir_path_to_url(path("\\\\localhost\\c:\\foo\\bar")));
+
+ // Really not sure what to do with these examples.
+ // Maybe an error?
+ BOOST_TEST_EQ(std::string("file:///c:"), dir_path_to_url(path("c:")));
+ BOOST_TEST_EQ(
+ std::string("file:///c:foo/bar/"), dir_path_to_url(path("c:foo\\bar")));
+#endif
+}
+
+void path_difference_tests()
+{
+ using boost::filesystem::current_path;
+ using boost::filesystem::path;
+ using quickbook::path_difference;
+
+ BOOST_TEST(path(".") == path_difference(path(""), path("")));
+ BOOST_TEST(path(".") == path_difference(path("a"), path("a")));
+ BOOST_TEST(path(".") == path_difference(path("a/../b"), path("b")));
+ BOOST_TEST(path(".") == path_difference(current_path(), current_path()));
+ BOOST_TEST(path("..") == path_difference(path("a"), path("")));
+ BOOST_TEST(
+ path("..") == path_difference(current_path() / "a", current_path()));
+ BOOST_TEST(path("a") == path_difference(path(""), path("a")));
+ BOOST_TEST(
+ path("a") == path_difference(current_path(), current_path() / "a"));
+ BOOST_TEST(path("b") == path_difference(path("a"), path("a/b")));
+ BOOST_TEST(
+ path("b") ==
+ path_difference(current_path() / "a", current_path() / "a" / "b"));
+ BOOST_TEST(path("../a/b") == path_difference(path("c"), path("a/b")));
+ BOOST_TEST(
+ path("../a/b") ==
+ path_difference(current_path() / "c", current_path() / "a" / "b"));
+ BOOST_TEST(path("..") == path_difference(path(""), path("..")));
+ BOOST_TEST(
+ path("..") ==
+ path_difference(current_path(), current_path().parent_path()));
+ BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b")));
+ BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("a/b")));
+ BOOST_TEST(
+ path("b") ==
+ path_difference(path("b/c/../../a"), path("d/f/../../a/b")));
+ BOOST_TEST(
+ path("../../x/a/b") ==
+ path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b")));
+
+ // path_difference to a file, try to include the filename in the result,
+ // although not always possible. Maybe nonsense calls should be an error?
+ //
+ // Commented out cases are wrong because path_difference resolves the paths
+ // to the current working directory. In use this doesn't matter as it's
+ // always called with the full path, but it'd be nice to get this right.
+ // Or maybe just add the pre-condition to path_difference?
+ std::cout << path_difference(path(""), path(""), true) << std::endl;
+ // BOOST_TEST(path(".") == path_difference(path(""), path(""), true));
+ BOOST_TEST(path("../a") == path_difference(path("a"), path("a"), true));
+ BOOST_TEST(
+ path("../../a") == path_difference(path("a/b"), path("a"), true));
+ BOOST_TEST(
+ path("../b") == path_difference(path("a/../b"), path("b"), true));
+ BOOST_TEST(
+ ".." / current_path().filename() ==
+ path_difference(current_path(), current_path(), true));
+ // BOOST_TEST(path("..") == path_difference(path("a"), path(""), true));
+ BOOST_TEST(
+ "../.." / current_path().filename() ==
+ path_difference(current_path() / "a", current_path(), true));
+ BOOST_TEST(path("a") == path_difference(path(""), path("a"), true));
+ BOOST_TEST(
+ path("a") ==
+ path_difference(current_path(), current_path() / "a", true));
+ BOOST_TEST(path("b") == path_difference(path("a"), path("a/b"), true));
+ BOOST_TEST(
+ path("b") ==
+ path_difference(
+ current_path() / "a", current_path() / "a" / "b", true));
+ BOOST_TEST(path("../a/b") == path_difference(path("c"), path("a/b"), true));
+ BOOST_TEST(
+ path("../a/b") ==
+ path_difference(
+ current_path() / "c", current_path() / "a" / "b", true));
+ // BOOST_TEST(path("..") == path_difference(path(""), path(".."), true));
+ BOOST_TEST(
+ "../.." / current_path().parent_path().filename() ==
+ path_difference(current_path(), current_path().parent_path(), true));
+ BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b"), true));
+ BOOST_TEST(
+ path("b") == path_difference(path("b/c/../../a"), path("a/b"), true));
+ BOOST_TEST(
+ path("b") ==
+ path_difference(path("b/c/../../a"), path("d/f/../../a/b"), true));
+ BOOST_TEST(
+ path("../../x/a/b") ==
+ path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"), true));
+}
+
+int main()
+{
+ file_path_to_url_tests();
+ dir_path_to_url_tests();
+ path_difference_tests();
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/post_process_test.cpp b/src/boost/tools/quickbook/test/unit/post_process_test.cpp
new file mode 100644
index 000000000..e7681c72d
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/post_process_test.cpp
@@ -0,0 +1,27 @@
+/*=============================================================================
+ Copyright (c) 2011 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include "post_process.hpp"
+
+#define EXPECT_EXCEPTION(test, msg) \
+ try { \
+ test; \
+ BOOST_ERROR(msg); \
+ } catch (quickbook::post_process_failure&) { \
+ }
+
+int main()
+{
+ EXPECT_EXCEPTION(
+ quickbook::post_process("</thing>"), "Succeeded with unbalanced tag");
+ EXPECT_EXCEPTION(
+ quickbook::post_process("<"), "Succeeded with badly formed tag");
+
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/source_map_test.cpp b/src/boost/tools/quickbook/test/unit/source_map_test.cpp
new file mode 100644
index 000000000..6248ac1f6
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/source_map_test.cpp
@@ -0,0 +1,444 @@
+/*=============================================================================
+ Copyright (c) 2012 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/range/algorithm/find.hpp>
+#include "files.hpp"
+#include "fwd.hpp"
+#include "string_view.hpp"
+
+void simple_map_tests()
+{
+ quickbook::string_view source("First Line\nSecond Line");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+
+ quickbook::string_iterator line1 = fake_file->source().begin();
+ quickbook::string_iterator line1_end =
+ boost::find(fake_file->source(), '\n');
+ quickbook::string_iterator line2 = line1_end + 1;
+ quickbook::string_iterator line2_end = fake_file->source().end();
+
+ quickbook::mapped_file_builder builder;
+
+ { // Empty test
+ builder.start(fake_file);
+ BOOST_TEST(builder.empty());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST(f1->source().empty());
+ }
+
+ { // Add full text
+ builder.start(fake_file);
+ builder.add(quickbook::string_view(line1, line2_end - line1));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), source);
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(1, 3));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line1_end - line1)),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2 - line1)),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ fake_file->position_of(fake_file->source().end()));
+ }
+
+ { // Add first line
+ builder.start(fake_file);
+ builder.add(quickbook::string_view(line1, line1_end - line1));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(),
+ quickbook::string_view(source.begin(), line1_end - line1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(1, 3));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ }
+
+ { // Add second line
+ builder.start(fake_file);
+ builder.add(quickbook::string_view(line2, line2_end - line2));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), quickbook::string_view("Second Line"));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(2, 3));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(2, line2_end - line2 + 1));
+ }
+
+ { // Out of order
+ builder.start(fake_file);
+ builder.add(quickbook::string_view(line2, line2_end - line2));
+ builder.add(quickbook::string_view(line1_end, 1));
+ builder.add(quickbook::string_view(line1, line1_end - line1));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Second Line\nFirst Line"));
+
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(2, 3));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2 - 1)),
+ quickbook::file_position(2, line2_end - line2));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2)),
+ quickbook::file_position(1, (line1_end - line1 + 1)));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2 + 1)),
+ quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ }
+
+ { // Repeated text
+ builder.start(fake_file);
+ builder.add(quickbook::string_view(line2, line2_end - line2));
+ builder.add(quickbook::string_view(line1_end, 1));
+ builder.add(quickbook::string_view(line2, line2_end - line2));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Second Line\nSecond Line"));
+
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(2, 3));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2 - 1)),
+ quickbook::file_position(2, line2_end - line2));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2)),
+ quickbook::file_position(1, (line1_end - line1 + 1)));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + (line2_end - line2 + 1)),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(2, line2_end - line2 + 1));
+ }
+
+ { // Generated text
+ builder.start(fake_file);
+ builder.add_at_pos("------\n", line1);
+ builder.add(quickbook::string_view(line1, line1_end - line1));
+ builder.add_at_pos("\n------\n", line1_end);
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(),
+ quickbook::string_view("------\nFirst Line\n------\n"));
+
+ quickbook::string_iterator newline = boost::find(f1->source(), '\n');
+
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 2),
+ quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(f1->position_of(newline), quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(newline + 1), quickbook::file_position(1, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(newline + 2), quickbook::file_position(1, 2));
+ BOOST_TEST_EQ(
+ f1->position_of(newline + (line1_end - line1)),
+ quickbook::file_position(1, line1_end - line1));
+ BOOST_TEST_EQ(
+ f1->position_of(newline + (line1_end - line1 + 1)),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ BOOST_TEST_EQ(
+ f1->position_of(newline + (line1_end - line1 + 2)),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(1, line1_end - line1 + 1));
+ }
+}
+
+void indented_map_tests()
+{
+ quickbook::string_view source(" Code line1\n"
+ " Code line2\n");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+
+ quickbook::mapped_file_builder builder;
+
+ {
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line1\nCode line2\n"));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 1),
+ quickbook::file_position(1, 5));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 5),
+ quickbook::file_position(1, 9));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 10),
+ quickbook::file_position(1, 14));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 11),
+ quickbook::file_position(2, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(3, 1));
+ }
+
+ {
+ builder.start(fake_file);
+ {
+ quickbook::mapped_file_builder builder2;
+ builder2.start(fake_file);
+ builder2.unindent_and_add(fake_file->source());
+ builder.add(builder2);
+ }
+ quickbook::file_ptr f1 = builder.release();
+
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line1\nCode line2\n"));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 1),
+ quickbook::file_position(1, 5));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 5),
+ quickbook::file_position(1, 9));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 10),
+ quickbook::file_position(1, 14));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 11),
+ quickbook::file_position(2, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(3, 1));
+ }
+
+ {
+ builder.start(fake_file);
+ builder.unindent_and_add(quickbook::string_view(
+ fake_file->source().begin() + 3,
+ fake_file->source().end() - (fake_file->source().begin() + 3)));
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(),
+ quickbook::string_view("Code line1\n Code line2\n"));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 1),
+ quickbook::file_position(1, 5));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 5),
+ quickbook::file_position(1, 9));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 10),
+ quickbook::file_position(1, 14));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 11),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().end()),
+ quickbook::file_position(3, 1));
+ }
+}
+
+void indented_map_tests2()
+{
+ quickbook::string_view source(" Code line1\n"
+ "\n"
+ " Code line2\n");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+
+ quickbook::mapped_file_builder builder;
+
+ {
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line1\n\nCode line2\n"));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin()),
+ quickbook::file_position(1, 4));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 1),
+ quickbook::file_position(1, 5));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 5),
+ quickbook::file_position(1, 9));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 10),
+ quickbook::file_position(1, 14));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 11),
+ quickbook::file_position(2, 1));
+ BOOST_TEST_EQ(
+ f1->position_of(f1->source().begin() + 12),
+ quickbook::file_position(3, 4));
+ }
+}
+
+void indented_map_leading_blanks_test()
+{
+ quickbook::mapped_file_builder builder;
+
+ {
+ quickbook::string_view source("\n\n Code line1\n");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n"));
+ }
+
+ {
+ quickbook::string_view source(" \n \n Code line1\n");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n"));
+ }
+
+ {
+ quickbook::string_view source(" Code line1\n \n Code line2");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line1\n\nCode line2"));
+ }
+}
+
+void indented_map_trailing_blanks_test()
+{
+ quickbook::mapped_file_builder builder;
+
+ {
+ quickbook::string_view source("\n\n Code line1\n ");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n"));
+ }
+
+ {
+ quickbook::string_view source(" \n \n Code line1\n ");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n "));
+ }
+
+ {
+ quickbook::string_view source(" Code line1\n \n Code line2\n ");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line1\n\nCode line2\n"));
+ }
+}
+
+void indented_map_mixed_test()
+{
+ quickbook::mapped_file_builder builder;
+
+ {
+ quickbook::string_view source("\tCode line 1\n Code line 2\n\t "
+ "Code line 3\n \tCode line 4");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(),
+ quickbook::string_view(
+ "Code line 1\nCode line 2\n Code line 3\n Code line 4"));
+ }
+
+ {
+ quickbook::string_view source(" Code line 1\n\tCode line 2");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line 1\n Code line 2"));
+ }
+
+ {
+ quickbook::string_view source(" Code line 1\n \tCode line 2");
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ builder.start(fake_file);
+ builder.unindent_and_add(fake_file->source());
+ quickbook::file_ptr f1 = builder.release();
+ BOOST_TEST_EQ(
+ f1->source(), quickbook::string_view("Code line 1\n\tCode line 2"));
+ }
+}
+
+int main()
+{
+ simple_map_tests();
+ indented_map_tests();
+ indented_map_tests2();
+ indented_map_leading_blanks_test();
+ indented_map_trailing_blanks_test();
+ indented_map_mixed_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/symbols_find_null.cpp b/src/boost/tools/quickbook/test/unit/symbols_find_null.cpp
new file mode 100644
index 000000000..0be8ab1e5
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/symbols_find_null.cpp
@@ -0,0 +1,36 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_scanner.hpp>
+#include <boost/utility/addressof.hpp>
+#include "symbols.hpp"
+
+typedef char char_type;
+typedef char const* iterator;
+
+char_type data_[] = "whatever";
+
+iterator begin = data_;
+iterator end =
+ data_ +
+ sizeof(data_) / sizeof(char_type); // Yes, this is an intentional bug ;)
+
+int main()
+{
+ typedef BOOST_SPIRIT_CLASSIC_NS::scanner<> scanner;
+ typedef quickbook::tst<void*, char_type> symbols;
+
+ symbols symbols_;
+
+ symbols_.add(begin, end - 1, (void*)boost::addressof(symbols_));
+
+ // The symbol table parser should not choke on input containing the null
+ // character.
+ symbols_.find(scanner(begin, end));
+}
diff --git a/src/boost/tools/quickbook/test/unit/symbols_tests.cpp b/src/boost/tools/quickbook/test/unit/symbols_tests.cpp
new file mode 100644
index 000000000..41f37b5e7
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/symbols_tests.cpp
@@ -0,0 +1,374 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <boost/swap.hpp>
+#include "symbols.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename IteratorT> bool equal(IteratorT p, IteratorT q)
+{
+ while (*p && *p == *q) {
+ ++p;
+ ++q;
+ }
+ return *p == *q;
+}
+
+template <class SymbolsT, typename CharT>
+void docheck(
+ SymbolsT const& sym,
+ CharT const* candidate,
+ bool hit,
+ CharT const* result,
+ int length)
+{
+ parse_info<CharT const*> info = parse(candidate, sym);
+
+#define correctly_matched hit == info.hit
+#define correct_match_length unsigned(length) == info.length
+#define correct_tail equal(candidate + (hit ? 1 : 0) * length, result)
+
+ BOOST_TEST(correctly_matched);
+
+ if (hit) {
+ BOOST_TEST(correct_match_length);
+ BOOST_TEST(correct_tail);
+ }
+ else {
+ BOOST_TEST(correct_tail);
+ }
+}
+
+template <typename T> struct store_action
+{
+ store_action(T const& v) : value(v) {}
+ void operator()(T& v) const { v = value; }
+
+ private:
+ T const value;
+};
+
+template <typename T> store_action<T> store(T const& v) { return v; }
+
+template <typename T> struct check_action
+{
+ check_action(T const& v) : value(v) {}
+
+#define correct_value_stored (v == value)
+ void operator()(T const& v) const { BOOST_TEST(correct_value_stored); }
+
+ private:
+ T const value;
+};
+
+template <typename T> check_action<T> docheck(T const& v) { return v; }
+
+static void default_constructible()
+{ // this actually a compile time test
+ symbols<int, char, quickbook::tst<int, char> > ns1;
+ symbols<int, wchar_t, quickbook::tst<int, wchar_t> > ws1;
+ symbols<std::string, char, quickbook::tst<std::string, char> > ns2;
+ symbols<std::string, wchar_t, quickbook::tst<std::string, wchar_t> > ws2;
+
+ (void)ns1;
+ (void)ws1;
+ (void)ns2;
+ (void)ws2;
+}
+
+typedef symbols<int, char, quickbook::tst<int, char> > nsymbols;
+typedef symbols<int, wchar_t, quickbook::tst<int, wchar_t> > wsymbols;
+
+static void narrow_match_tests()
+{
+ nsymbols sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ docheck(sym, "pineapple", true, "", 9);
+ docheck(sym, "orange", true, "", 6);
+ docheck(sym, "banana", true, "", 6);
+ docheck(sym, "apple", true, "", 5);
+ docheck(sym, "pizza", false, "pizza", -1);
+ docheck(sym, "steak", false, "steak", -1);
+ docheck(sym, "applepie", true, "", 8);
+ docheck(sym, "bananarama", true, "rama", 6);
+ docheck(sym, "applet", true, "t", 5);
+ docheck(sym, "applepi", true, "pi", 5);
+ docheck(sym, "appl", false, "appl", -1);
+
+ docheck(sym, "pineapplez", true, "z", 9);
+ docheck(sym, "orangez", true, "z", 6);
+ docheck(sym, "bananaz", true, "z", 6);
+ docheck(sym, "applez", true, "z", 5);
+ docheck(sym, "pizzaz", false, "pizzaz", -1);
+ docheck(sym, "steakz", false, "steakz", -1);
+ docheck(sym, "applepiez", true, "z", 8);
+ docheck(sym, "bananaramaz", true, "ramaz", 6);
+ docheck(sym, "appletz", true, "tz", 5);
+ docheck(sym, "applepix", true, "pix", 5);
+}
+
+static void narrow_copy_ctor_tests()
+{
+ nsymbols sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ nsymbols sym2(sym);
+ docheck(sym2, "pineapple", true, "", 9);
+ docheck(sym2, "pizza", false, "pizza", -1);
+ docheck(sym2, "bananarama", true, "rama", 6);
+}
+
+static void narrow_assigment_operator_tests()
+{
+ nsymbols sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ nsymbols sym2;
+ sym2 = sym;
+
+ docheck(sym2, "pineapple", true, "", 9);
+ docheck(sym2, "pizza", false, "pizza", -1);
+ docheck(sym2, "bananarama", true, "rama", 6);
+}
+
+static void narrow_swap_tests()
+{
+ nsymbols sym, sym2;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+ sym2 = "potato", "cucumber", "cauliflower", "carrot";
+
+ boost::swap(sym, sym2);
+
+ docheck(sym2, "pineapple", true, "", 9);
+ docheck(sym2, "pizza", false, "pizza", -1);
+ docheck(sym2, "bananarama", true, "rama", 6);
+ docheck(sym, "potatoe", true, "e", 6);
+ docheck(sym, "cauliflour", false, "cauliflour", -1);
+}
+
+static void narrow_value_tests()
+{ // also tests the add member functions
+ nsymbols sym;
+
+ sym = "orange", "banana";
+ sym.add("pineapple", 1234);
+ sym.add("lemon");
+
+ parse("orange", sym[store(12345)]);
+ parse("orange", sym[docheck(12345)]);
+ parse("pineapple", sym[docheck(1234)]);
+ parse("banana", sym[docheck(int())]);
+ parse("lemon", sym[docheck(int())]);
+}
+
+static void narrow_free_functions_tests()
+{
+ nsymbols sym;
+
+#define add_returned_non_null_value (res != 0)
+#define add_returned_null (res == 0)
+#define find_returned_non_null_value (res != 0)
+#define find_returned_null (res == 0)
+
+ int* res = add(sym, "pineapple");
+ BOOST_TEST(add_returned_non_null_value);
+ res = add(sym, "pineapple");
+ BOOST_TEST(add_returned_null);
+
+ res = find(sym, "pineapple");
+ BOOST_TEST(find_returned_non_null_value);
+ res = find(sym, "banana");
+ BOOST_TEST(find_returned_null);
+}
+
+static void wide_match_tests()
+{
+ wsymbols sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ docheck(sym, L"pineapple", true, L"", 9);
+ docheck(sym, L"orange", true, L"", 6);
+ docheck(sym, L"banana", true, L"", 6);
+ docheck(sym, L"apple", true, L"", 5);
+ docheck(sym, L"pizza", false, L"pizza", -1);
+ docheck(sym, L"steak", false, L"steak", -1);
+ docheck(sym, L"applepie", true, L"", 8);
+ docheck(sym, L"bananarama", true, L"rama", 6);
+ docheck(sym, L"applet", true, L"t", 5);
+ docheck(sym, L"applepi", true, L"pi", 5);
+ docheck(sym, L"appl", false, L"appl", -1);
+
+ docheck(sym, L"pineapplez", true, L"z", 9);
+ docheck(sym, L"orangez", true, L"z", 6);
+ docheck(sym, L"bananaz", true, L"z", 6);
+ docheck(sym, L"applez", true, L"z", 5);
+ docheck(sym, L"pizzaz", false, L"pizzaz", -1);
+ docheck(sym, L"steakz", false, L"steakz", -1);
+ docheck(sym, L"applepiez", true, L"z", 8);
+ docheck(sym, L"bananaramaz", true, L"ramaz", 6);
+ docheck(sym, L"appletz", true, L"tz", 5);
+ docheck(sym, L"applepix", true, L"pix", 5);
+}
+
+static void wide_copy_ctor_tests()
+{
+ wsymbols sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ wsymbols sym2(sym);
+ docheck(sym2, L"pineapple", true, L"", 9);
+ docheck(sym2, L"pizza", false, L"pizza", -1);
+ docheck(sym2, L"bananarama", true, L"rama", 6);
+}
+
+static void wide_assigment_operator_tests()
+{
+ wsymbols sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ wsymbols sym2;
+ sym2 = sym;
+
+ docheck(sym2, L"pineapple", true, L"", 9);
+ docheck(sym2, L"pizza", false, L"pizza", -1);
+ docheck(sym2, L"bananarama", true, L"rama", 6);
+}
+
+static void wide_swap_tests()
+{
+ wsymbols sym, sym2;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+ sym2 = L"potato", L"cucumber", L"cauliflower", L"carrot";
+
+ boost::swap(sym, sym2);
+
+ docheck(sym2, L"pineapple", true, L"", 9);
+ docheck(sym2, L"pizza", false, L"pizza", -1);
+ docheck(sym2, L"bananarama", true, L"rama", 6);
+ docheck(sym, L"potatoe", true, L"e", 6);
+ docheck(sym, L"cauliflour", false, L"cauliflour", -1);
+}
+
+static void wide_value_tests()
+{ // also tests the add member functions
+ wsymbols sym;
+
+ sym = L"orange", L"banana";
+ sym.add(L"pineapple", 1234);
+ sym.add(L"lemon");
+
+ parse(L"orange", sym[store(12345)]);
+ parse(L"orange", sym[docheck(12345)]);
+ parse(L"pineapple", sym[docheck(1234)]);
+ parse(L"banana", sym[docheck(int())]);
+ parse(L"lemon", sym[docheck(int())]);
+}
+
+static void wide_free_functions_tests()
+{
+ wsymbols sym;
+
+ int* res = add(sym, L"pineapple");
+ BOOST_TEST(add_returned_non_null_value);
+ res = add(sym, L"pineapple");
+ BOOST_TEST(add_returned_null);
+
+ res = find(sym, L"pineapple");
+ BOOST_TEST(find_returned_non_null_value);
+ res = find(sym, L"banana");
+ BOOST_TEST(find_returned_null);
+}
+
+static void free_add_find_functions_tests()
+{
+ nsymbols sym;
+ BOOST_TEST(*add(sym, "a", 0) == 0);
+ BOOST_TEST(*add(sym, "a2", 1) == 1);
+ BOOST_TEST(add(sym, "a2", 2) == 0);
+ BOOST_TEST(find(sym, "a2"));
+ BOOST_TEST(find(sym, "a"));
+}
+
+// The original teneray search tree implementation contained a bug when
+// inserting duplicate values. I want this implementation to be as
+// close as possible to the original (so they can be easily switched)
+// so check that the bug remains the same.
+
+struct check_parse_value
+{
+ explicit check_parse_value(int value) : value_(value) {}
+
+ void operator()(int value) const { BOOST_TEST(value == value_); }
+
+ int value_;
+};
+
+// My version is different to the original, if there's an existing value
+// it replaces it with the new one.
+
+static void duplicate_add_tests()
+{
+ char const* foo1 = "foo";
+ char const* foo2 = foo1 + 3;
+
+ nsymbols sym;
+ sym.add(foo1, foo2, 1);
+ nsymbols sym2 = sym;
+ sym.add(foo1, foo2, 2);
+ sym2.add(foo1, foo2, 3);
+
+ BOOST_TEST(find(sym, "foo") && *find(sym, "foo") == 2);
+ BOOST_TEST(find(sym2, "foo") && *find(sym2, "foo") == 3);
+
+ parse_info<char const*> info;
+
+ info = parse("foo ", sym[check_parse_value(2)]);
+ BOOST_TEST(info.hit && info.length == 3);
+
+ info = parse("foo", sym[check_parse_value(2)]);
+ BOOST_TEST(info.hit && info.length == 3);
+
+ info = parse("foo ", sym2[check_parse_value(3)]);
+ BOOST_TEST(info.hit && info.length == 3);
+
+ info = parse("foo", sym2[check_parse_value(3)]);
+ BOOST_TEST(info.hit && info.length == 3);
+}
+
+int main()
+{
+ default_constructible();
+ narrow_match_tests();
+ narrow_copy_ctor_tests();
+ narrow_assigment_operator_tests();
+ narrow_swap_tests();
+ narrow_value_tests();
+ narrow_free_functions_tests();
+ wide_match_tests();
+ wide_copy_ctor_tests();
+ wide_assigment_operator_tests();
+ wide_swap_tests();
+ wide_value_tests();
+ wide_free_functions_tests();
+ free_add_find_functions_tests();
+ duplicate_add_tests();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/utils_test.cpp b/src/boost/tools/quickbook/test/unit/utils_test.cpp
new file mode 100644
index 000000000..6a54dccfe
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/utils_test.cpp
@@ -0,0 +1,67 @@
+
+/*=============================================================================
+ Copyright (c) 2017 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include "utils.hpp"
+
+#include <iostream>
+
+void linkify_test()
+{
+ using quickbook::detail::linkify;
+
+ BOOST_TEST(linkify("abc", "link") == "<link linkend=\"link\">abc</link>");
+ BOOST_TEST(
+ linkify("<link linkend=\"something\">abc</link>", "link") ==
+ "<link linkend=\"something\">abc</link>");
+ BOOST_TEST(
+ linkify("abc <link linkend=\"something\">def</link>", "link") ==
+ "abc <link linkend=\"something\">def</link>");
+ BOOST_TEST(
+ linkify("<link linkend=\"something\">abc</link> def", "link") ==
+ "<link linkend=\"something\">abc</link> def");
+}
+
+void decode_string_test()
+{
+ using quickbook::detail::decode_string;
+ BOOST_TEST_EQ(std::string("<A&B>"), decode_string("&lt;A&amp;B&gt;"));
+ BOOST_TEST_EQ(std::string("<A&B>"), decode_string("&lt;A&B&gt;"));
+ BOOST_TEST_EQ(std::string("a"), decode_string("&#97;"));
+ BOOST_TEST_EQ(std::string("OO"), decode_string("&#x4f;&#x4F;"));
+ // Unicode examples taken from wikipedia.
+ // https://en.wikipedia.org/wiki/UTF-8#Examples
+ BOOST_TEST_EQ(
+ std::string("\x24\xc2\xa2\xe2\x82\xAC\xF0\x90\x8D\x88"),
+ decode_string("&#x24;&#xA2;&#x20AC;&#x10348;"));
+}
+
+void encode_string_test()
+{
+ using quickbook::detail::encode_string;
+ BOOST_TEST_EQ(std::string("&lt;A&amp;B&gt;"), encode_string("<A&B>"));
+}
+
+void escape_uri_test()
+{
+ using quickbook::detail::escape_uri;
+ using quickbook::detail::partially_escape_uri;
+
+ BOOST_TEST_EQ(std::string("%2520%2525%25"), escape_uri("%20%25%"));
+ BOOST_TEST_EQ(std::string("%20%25%25"), partially_escape_uri("%20%25%"));
+}
+
+int main()
+{
+ linkify_test();
+ decode_string_test();
+ encode_string_test();
+ escape_uri_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/tools/quickbook/test/unit/values_test.cpp b/src/boost/tools/quickbook/test/unit/values_test.cpp
new file mode 100644
index 000000000..d0036d428
--- /dev/null
+++ b/src/boost/tools/quickbook/test/unit/values_test.cpp
@@ -0,0 +1,128 @@
+/*=============================================================================
+ Copyright (c) 2010-2011 Daniel James
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// Some very light testing for quickbook::value and friends.
+// Just for a few issues that came up during development.
+
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include "files.hpp"
+#include "values.hpp"
+
+void empty_tests()
+{
+ quickbook::value q;
+ BOOST_TEST(q.empty());
+ BOOST_TEST(!q.is_list());
+ BOOST_TEST(!q.is_encoded());
+}
+
+void qbk_tests()
+{
+ std::string source = "Source";
+ quickbook::value q;
+ {
+ quickbook::file_ptr fake_file =
+ new quickbook::file("(fake file)", source, 105u);
+ q = quickbook::qbk_value(
+ fake_file, fake_file->source().begin(), fake_file->source().end());
+ }
+ BOOST_TEST_EQ(q.get_quickbook(), quickbook::string_view(source));
+}
+
+void sort_test()
+{
+ quickbook::value_builder b;
+ b.insert(quickbook::encoded_value("a", 10));
+ b.insert(quickbook::encoded_value("b", 2));
+ b.insert(quickbook::encoded_value("c", 5));
+ b.insert(quickbook::encoded_value("d", 8));
+ b.sort_list();
+
+ quickbook::value_consumer c = b.release();
+ BOOST_TEST(c.check(2));
+ BOOST_TEST_EQ(c.consume(2).get_encoded(), "b");
+ BOOST_TEST(c.check(5));
+ c.consume(5);
+ BOOST_TEST(c.check(8));
+ c.consume(8);
+ BOOST_TEST(c.check(10));
+ c.consume(10);
+ BOOST_TEST(!c.check());
+}
+
+void multiple_list_test()
+{
+ quickbook::value_builder list1;
+ quickbook::value_builder list2;
+
+ list1.insert(quickbook::encoded_value("b", 10));
+
+ {
+ quickbook::value p1 = quickbook::encoded_value("a", 5);
+ list1.insert(p1);
+ list2.insert(p1);
+ }
+
+ list2.insert(quickbook::encoded_value("c", 3));
+
+ quickbook::value_consumer l1 = list1.release();
+ quickbook::value_consumer l2 = list2.release();
+
+ BOOST_TEST(l1.check(10));
+ BOOST_TEST_EQ(l1.consume(10).get_encoded(), "b");
+ BOOST_TEST(l1.check(5));
+ BOOST_TEST_EQ(l1.consume(5).get_encoded(), "a");
+ BOOST_TEST(!l1.check());
+
+ BOOST_TEST(l2.check(5));
+ BOOST_TEST_EQ(l2.consume(5).get_encoded(), "a");
+ BOOST_TEST(l2.check(3));
+ BOOST_TEST_EQ(l2.consume(3).get_encoded(), "c");
+ BOOST_TEST(!l2.check());
+}
+
+void equality_tests()
+{
+ std::vector<quickbook::value> distinct_values;
+
+ quickbook::value_builder builder;
+ quickbook::value nil;
+
+ // 0: nil
+ distinct_values.push_back(nil);
+
+ // 1: []
+ distinct_values.push_back(builder.release());
+
+ // 2: [nil]
+ builder.insert(nil);
+ distinct_values.push_back(builder.release());
+
+ for (std::size_t i = 0; i < distinct_values.size(); ++i) {
+ for (std::size_t j = 0; j < distinct_values.size(); ++j) {
+ if ((i == j) != (distinct_values[i] == distinct_values[j])) {
+ BOOST_ERROR("Value mismatch.");
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\tat " << i << ", " << j
+ << std::endl;
+ }
+ }
+ }
+}
+
+int main()
+{
+ empty_tests();
+ qbk_tests();
+ sort_test();
+ multiple_list_test();
+ equality_tests();
+
+ return boost::report_errors();
+}