You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2018/12/28 09:33:29 UTC
svn commit: r1849831 - in /subversion/trunk/subversion/bindings/cxx:
include/svnxx/revision.hpp src/private.hpp src/private/revision-private.hpp
src/revision.cpp tests/test_revision.cpp
Author: brane
Date: Fri Dec 28 09:33:29 2018
New Revision: 1849831
URL: http://svn.apache.org/viewvc?rev=1849831&view=rev
Log:
Add SVN++ encapsulation of svn_revnum_t and svn_opt_revision_t.
[in subversion/bindings/cxx]
* include/svnxx/revision.hpp: New.
* src/private/revision-private.hpp: New.
* src/private.hpp: Include revision-private.hpp.
* src/revision.cpp: New.
* tests/test_revision.cpp: New.
Added:
subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp (with props)
subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp (with props)
subversion/trunk/subversion/bindings/cxx/src/revision.cpp (with props)
subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp (with props)
Modified:
subversion/trunk/subversion/bindings/cxx/src/private.hpp
Added: subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp?rev=1849831&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp (added)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp Fri Dec 28 09:33:29 2018
@@ -0,0 +1,369 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef SVNXX_REVISION_HPP
+#define SVNXX_REVISION_HPP
+
+#include <chrono>
+#include <cstdint>
+
+#include "tristate.hpp"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+
+/**
+ * @brief A revision, see @ref svn_opt_revision_t.
+ *
+ * The @c revision can represent a revision number, a point in time
+ * in the repository or a property of the working copy or repository
+ * node (see revision::kind).
+ */
+class revision
+{
+public:
+ /**
+ * @brief Revisiion number type.
+ */
+ enum class number : long
+ {
+ invalid = -1, //< Invalid revision number.
+ };
+
+ /**
+ * @brief Revision by date/time uses the system clock.
+ */
+ template<typename Duration>
+ using time = std::chrono::time_point<std::chrono::system_clock, Duration>;
+
+ /**
+ * @brief The resolution of the stored date/time.
+ */
+ using usec = std::chrono::microseconds;
+
+ /**
+ * @brief Revision kind discriminator (see @ref svn_opt_revision_kind).
+ */
+ // NOTE: Keep these values identical to those in svn_opt_revision_kind!
+ enum class kind : std::int8_t
+ {
+ unspecified,
+ number,
+ date,
+ committed,
+ previous,
+ base,
+ working,
+ head,
+ };
+
+ /**
+ * @brief Default constructor.
+ * @post get_kind() == kind::unspecified.
+ */
+ revision() noexcept
+ : tag(kind::unspecified)
+ {}
+
+ /**
+ * @brief Construct a revision of the given kind.
+ * @pre The @a revkind argument may be any @c kind value @b except
+ * kind::number or kind::date, which require additional
+ * parameters and therefore have their own constructors.
+ * @post get_kind() == @a revkind.
+ * @throw std::invalid_argument if the @a revkind value
+ * precondition is not met.
+ */
+ explicit revision(kind revkind)
+ : tag(revkind)
+ {
+ if (revkind == kind::number || revkind == kind::date)
+ throw std::invalid_argument("invalid svn::revision::kind");
+ }
+
+ /**
+ * @brief Construct a numbered revision.
+ * @post get_kind() == kind::number.
+ */
+ explicit revision(number revnum_) noexcept
+ : tag(kind::number),
+ revnum(revnum_)
+ {}
+
+ /**
+ * @brief Construct a dated revision from a system clock time point.
+ * @post get_kind() == kind::date.
+ */
+ template<typename D>
+ explicit revision(time<D> time_) noexcept
+ : tag(kind::date),
+ date(std::chrono::time_point_cast<usec>(time_))
+ {}
+
+ /**
+ * @brief Return the revision kind.
+ */
+ kind get_kind() const noexcept
+ {
+ return tag;
+ }
+
+ /**
+ * @brief Return the revision number.
+ * @pre get_kind() == kind::number.
+ * @throw std::logic_error if the precondition is not met.
+ */
+ number get_number() const
+ {
+ if (tag != kind::number)
+ throw std::logic_error("svn::revision kind != number");
+ return revnum;
+ }
+
+ /**
+ * @brief Return the revision date/time as a system clock time point.
+ * @pre get_kind() == kind::date.
+ * @throw std::logic_error if the precondition is not met.
+ */
+ template<typename D>
+ time<D> get_date() const
+ {
+ if (tag != kind::date)
+ throw std::logic_error("svn::revision kind != date");
+ return std::chrono::time_point_cast<D>(date);
+ }
+
+private:
+ // Even if we were using C++17, we wouldn't use std::variant because we
+ // already maintain an explicit discriminator tag for the union.
+ kind tag; // Union discriminator
+ union {
+ number revnum; // (tag == kind::number): revision number.
+ time<usec> date; // (tag == kind::date): microseconds from epoch.
+ };
+};
+
+/**
+ * @related revision
+ * @brief revision::number alias for convenience.
+ */
+using revnum = revision::number;
+
+/**
+ * @related revision
+ * @brief Equality comparison.
+ */
+inline bool operator==(const revision& a, const revision& b)
+{
+ const auto kind = a.get_kind();
+ if (kind != b.get_kind())
+ return false;
+ else if (kind == revision::kind::number)
+ return a.get_number() == b.get_number();
+ else if (kind == revision::kind::date)
+ return a.get_date<revision::usec>() == b.get_date<revision::usec>();
+ else
+ return true;
+}
+
+/**
+ * @related revision
+ * @brief Inequality comparison.
+ */
+inline bool operator!=(const revision& a, const revision& b)
+{
+ return !(a == b);
+}
+
+/**
+ * @related revision
+ * @brief Ordering: less-than (<tt>operator @<</tt>).
+ * @returns a @c tristate result of comparing two @c revision values,
+ * according to the following table:
+ * <table border=1>
+ * <tr>
+ * <th><center><code>@<</code></center></th>
+ * <th><center><tt>number</tt></center></th>
+ * <th><center><tt>date</tt></center></th>
+ * <th><center><em>other</em></center></th>
+ * </tr>
+ * <tr>
+ * <th><center><tt>number</tt></center></th>
+ * <td><center><tt>a.get_number() < b.get_number()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><tt>date</tt></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><tt>a.get_date() < b.get_date()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><em>other</em></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * </table>
+ */
+inline tristate operator<(const revision& a, const revision& b)
+{
+ const auto kind = a.get_kind();
+ if (kind != b.get_kind())
+ return tristate::unknown();
+ else if (kind == revision::kind::number)
+ return a.get_number() < b.get_number();
+ else if (kind == revision::kind::date)
+ return a.get_date<revision::usec>() < b.get_date<revision::usec>();
+ else
+ return tristate::unknown();
+}
+
+/**
+ * @related revision
+ * @brief Ordering: greater-than (<tt>operator @></tt>).
+ * @returns a @c tristate result of comparing two @c revision values,
+ * according to the following table:
+ * <table border=1>
+ * <tr>
+ * <th><center><code>@></code></center></th>
+ * <th><center><tt>number</tt></center></th>
+ * <th><center><tt>date</tt></center></th>
+ * <th><center><em>other</em></center></th>
+ * </tr>
+ * <tr>
+ * <th><center><tt>number</tt></center></th>
+ * <td><center><tt>a.get_number() > b.get_number()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><tt>date</tt></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><tt>a.get_date() > b.get_date()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><em>other</em></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * </table>
+ */
+inline tristate operator>(const revision& a, const revision& b)
+{
+ const auto kind = a.get_kind();
+ if (kind != b.get_kind())
+ return tristate::unknown();
+ else if (kind == revision::kind::number)
+ return a.get_number() > b.get_number();
+ else if (kind == revision::kind::date)
+ return a.get_date<revision::usec>() > b.get_date<revision::usec>();
+ else
+ return tristate::unknown();
+}
+
+/**
+ * @related revision
+ * @brief Ordering: less-or-equal (<tt>operator @<=</tt>).
+ * @returns a @c tristate result of comparing two @c revision values,
+ * according to the following table:
+ * <table border=1>
+ * <tr>
+ * <th><center><code>@<=</code></center></th>
+ * <th><center><tt>number</tt></center></th>
+ * <th><center><tt>date</tt></center></th>
+ * <th><center><em>other</em></center></th>
+ * </tr>
+ * <tr>
+ * <th><center><tt>number</tt></center></th>
+ * <td><center><tt>a.get_number() <= b.get_number()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><tt>date</tt></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><tt>a.get_date() <= b.get_date()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><em>other</em></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>true</em>† or <em>unknown</em></center></td>
+ * </tr>
+ * </table>
+ * † <em>true</em> when <tt>a.get_kind() == b.get_kind()</tt>.
+ */
+inline tristate operator<=(const revision& a, const revision& b)
+{
+ return (a == b || !(a > b));
+}
+
+/**
+ * @related revision
+ * @brief Ordering: greater-or-equal (<tt>operator @>=</tt>).
+ * @returns a @c tristate result of comparing two @c revision values,
+ * according to the following table:
+ * <table border=1>
+ * <tr>
+ * <th><center><code>@>=</code></center></th>
+ * <th><center><tt>number</tt></center></th>
+ * <th><center><tt>date</tt></center></th>
+ * <th><center><em>other</em></center></th>
+ * </tr>
+ * <tr>
+ * <th><center><tt>number</tt></center></th>
+ * <td><center><tt>a.get_number() >= b.get_number()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><tt>date</tt></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><tt>a.get_date() >= b.get_date()</tt></td>
+ * <td><center><em>unknown</em></center></td>
+ * </tr>
+ * <tr>
+ * <th><center><em>other</em></center></th>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>unknown</em></center></td>
+ * <td><center><em>true</em>† or <em>unknown</em></center></td>
+ * </tr>
+ * </table>
+ * † <em>true</em> when <tt>a.get_kind() == b.get_kind()</tt>.
+ */
+inline tristate operator>=(const revision& a, const revision& b)
+{
+ return (a == b || !(a < b));
+}
+
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_REVISION_HPP
Propchange: subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/trunk/subversion/bindings/cxx/src/private.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private.hpp?rev=1849831&r1=1849830&r2=1849831&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/src/private.hpp Fri Dec 28 09:33:29 2018
@@ -26,6 +26,7 @@
#include "private/depth-private.hpp"
#include "private/exception-private.hpp"
+#include "private/revision-private.hpp"
#include "private/strings-private.hpp"
#include "private/tristate-private.hpp"
Added: subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp?rev=1849831&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp (added)
+++ subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp Fri Dec 28 09:33:29 2018
@@ -0,0 +1,62 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef SVNXX_PRIVATE_REVISION_HPP
+#define SVNXX_PRIVATE_REVISION_HPP
+
+#include "svnxx/revision.hpp"
+
+#include "svn_types.h"
+#include "svn_opt.h"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+
+/**
+ * Convert @a kind to an svn_opt_revision_kind.
+ */
+svn_opt_revision_kind convert(revision::kind kind);
+
+/**
+ * Convert @a kind to an svn::revision::kind.
+ */
+revision::kind convert(svn_opt_revision_kind kind);
+
+/**
+ * Convert @a rev to an svn_opt_revision_t.
+ */
+svn_opt_revision_t convert(const revision& rev);
+
+/**
+ * Convert @a rev to an svn::revision.
+ */
+revision convert(const svn_opt_revision_t& rev);
+
+} // namespace detail
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_PRIVATE_REVISION_HPP
Propchange: subversion/trunk/subversion/bindings/cxx/src/private/revision-private.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: subversion/trunk/subversion/bindings/cxx/src/revision.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/revision.cpp?rev=1849831&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/revision.cpp (added)
+++ subversion/trunk/subversion/bindings/cxx/src/revision.cpp Fri Dec 28 09:33:29 2018
@@ -0,0 +1,165 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#include <stdexcept>
+
+#include "private/revision-private.hpp"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+
+svn_opt_revision_kind convert(revision::kind kind)
+{
+#ifdef SVN_DEBUG
+ switch (kind)
+ {
+ case revision::kind::unspecified:
+ if (kind != svn_opt_revision_unspecified)
+ throw std::range_error("convert svn::revision::kind::unspecified");
+ break;
+
+ case revision::kind::number:
+ if (kind != svn_opt_revision_number)
+ throw std::range_error("convert svn::revision::kind::number");
+ break;
+
+ case revision::kind::date:
+ if (kind != svn_opt_revision_date)
+ throw std::range_error("convert svn::revision::kind::date");
+ break;
+
+ case revision::kind::committed:
+ if (kind != svn_opt_revision_committed)
+ throw std::range_error("convert svn::revision::kind::committed");
+ break;
+
+ case revision::kind::base:
+ if (kind != svn_opt_revision_base)
+ throw std::range_error("convert svn::revision::kind::base");
+ break;
+
+ case revision::kind::working:
+ if (kind != svn_opt_revision_working)
+ throw std::range_error("convert svn::revision::kind::working");
+ break;
+
+ case revision::kind::head:
+ if (kind != svn_opt_revision_head)
+ throw std::range_error("convert svn::revision::kind::head");
+ break;
+
+ default:
+ throw std::range_error("unknown svn::revision::kind");
+ }
+#endif
+ return svn_opt_revision_kind(kind);
+}
+
+revision::kind convert(svn_opt_revision_kind kind)
+{
+#ifdef SVN_DEBUG
+ switch (kind)
+ {
+ case svn_opt_revision_unspecified:
+ if (kind != revision::kind::unspecified)
+ throw std::range_error("convert svn_opt_revision_unspecified");
+ break;
+
+ case svn_opt_revision_number:
+ if (kind != revision::kind::number)
+ throw std::range_error("convert svn_opt_revision_number");
+ break;
+
+ case svn_opt_revision_date:
+ if (kind != revision::kind::date)
+ throw std::range_error("convert svn_opt_revision_date");
+ break;
+
+ case svn_opt_revision_committed:
+ if (kind != revision::kind::committed)
+ throw std::range_error("convert svn_opt_revision_committed");
+ break;
+
+ case svn_opt_revision_base:
+ if (kind != revision::kind::base)
+ throw std::range_error("convert svn_opt_revision_base");
+ break;
+
+ case svn_opt_revision_working:
+ if (kind != revision::kind::working)
+ throw std::range_error("convert svn_opt_revision_working");
+ break;
+
+ case svn_opt_revision_head:
+ if (kind != revision::kind::head)
+ throw std::range_error("convert svn_opt_revision_head");
+ break;
+
+ default:
+ throw std::range_error("unknown svn_opt_revision_kind");
+ }
+#endif
+ return revision::kind(kind);
+}
+
+svn_opt_revision_t convert(const revision& rev)
+{
+ svn_opt_revision_t result;
+ result.kind = convert(rev.get_kind());
+ if (result.kind == svn_opt_revision_number)
+ result.value.number = svn_revnum_t(rev.get_number());
+ else if (result.kind == svn_opt_revision_date)
+ {
+ // NOTE: We're assuming that the APR and C++ system_clock epochs
+ // are the same. This will be standardized in C++20.
+ using usec = revision::usec;
+ const auto usecs = (rev.get_date<usec>() - revision::time<usec>());
+ result.value.date = usecs.count();
+ }
+ return result;
+}
+
+revision convert(const svn_opt_revision_t& rev)
+{
+ switch (rev.kind)
+ {
+ case svn_opt_revision_number:
+ return revision(revision::number(rev.value.number));
+ case svn_opt_revision_date:
+ {
+ // NOTE: We're assuming that the APR and C++ system_clock epochs
+ // are the same. This will be standardized in C++20.
+ using usec = revision::usec;
+ return revision(revision::time<usec>(usec{rev.value.date}));
+ }
+ default:
+ return revision(convert(rev.kind));
+ }
+}
+
+} // namespace detail
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
Propchange: subversion/trunk/subversion/bindings/cxx/src/revision.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp?rev=1849831&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp (added)
+++ subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp Fri Dec 28 09:33:29 2018
@@ -0,0 +1,137 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include <boost/test/unit_test.hpp>
+
+#include <array>
+
+#include "../src/private/revision-private.hpp"
+
+namespace svn = ::apache::subversion::svnxx;
+namespace detail = ::apache::subversion::svnxx::detail;
+
+BOOST_AUTO_TEST_SUITE(revision);
+
+BOOST_AUTO_TEST_CASE(convert_to_kind)
+{
+ using kind = svn::revision::kind;
+ BOOST_TEST((detail::convert(kind::unspecified) == svn_opt_revision_unspecified));
+ BOOST_TEST((detail::convert(kind::number) == svn_opt_revision_number));
+ BOOST_TEST((detail::convert(kind::date) == svn_opt_revision_date));
+ BOOST_TEST((detail::convert(kind::committed) == svn_opt_revision_committed));
+ BOOST_TEST((detail::convert(kind::previous) == svn_opt_revision_previous));
+ BOOST_TEST((detail::convert(kind::base) == svn_opt_revision_base));
+ BOOST_TEST((detail::convert(kind::working) == svn_opt_revision_working));
+ BOOST_TEST((detail::convert(kind::head) == svn_opt_revision_head));
+}
+
+BOOST_AUTO_TEST_CASE(convert_from_kind)
+{
+ using kind = svn::revision::kind;
+ BOOST_TEST((detail::convert(svn_opt_revision_unspecified) == kind::unspecified));
+ BOOST_TEST((detail::convert(svn_opt_revision_number) == kind::number));
+ BOOST_TEST((detail::convert(svn_opt_revision_date) == kind::date));
+ BOOST_TEST((detail::convert(svn_opt_revision_committed) == kind::committed));
+ BOOST_TEST((detail::convert(svn_opt_revision_previous) == kind::previous));
+ BOOST_TEST((detail::convert(svn_opt_revision_base) == kind::base));
+ BOOST_TEST((detail::convert(svn_opt_revision_working) == kind::working));
+ BOOST_TEST((detail::convert(svn_opt_revision_head) == kind::head));
+}
+
+BOOST_AUTO_TEST_CASE(roundtrip_conversions)
+{
+ using kind = svn::revision::kind;
+ using usec = svn::revision::usec;
+
+ std::array<svn::revision, 11> data = {
+ svn::revision(),
+ svn::revision(kind::unspecified),
+ svn::revision(kind::committed),
+ svn::revision(kind::previous),
+ svn::revision(kind::base),
+ svn::revision(kind::working),
+ svn::revision(kind::head),
+ svn::revision(svn::revnum::invalid),
+ svn::revision(svn::revnum(7)),
+ svn::revision(svn::revision::time<usec>()),
+ svn::revision(svn::revision::time<usec>(usec{11})),
+ };
+
+ for (const auto& r : data)
+ BOOST_TEST((detail::convert(detail::convert(r)) == r));
+}
+
+BOOST_AUTO_TEST_CASE(preconditions)
+{
+ using kind = svn::revision::kind;
+ BOOST_CHECK_THROW(auto r = svn::revision(kind::number), std::invalid_argument);
+ BOOST_CHECK_THROW(auto r = svn::revision(kind::date), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE(postconditions_kind)
+{
+ using kind = svn::revision::kind;
+ using usec = svn::revision::usec;
+
+ BOOST_TEST((svn::revision(kind::unspecified).get_kind() == kind::unspecified));
+ BOOST_TEST((svn::revision(kind::committed) .get_kind() == kind::committed));
+ BOOST_TEST((svn::revision(kind::previous) .get_kind() == kind::previous));
+ BOOST_TEST((svn::revision(kind::base) .get_kind() == kind::base));
+ BOOST_TEST((svn::revision(kind::working) .get_kind() == kind::working));
+ BOOST_TEST((svn::revision(kind::head) .get_kind() == kind::head));
+}
+
+BOOST_AUTO_TEST_CASE(postconditions_default)
+{
+ using kind = svn::revision::kind;
+ using usec = svn::revision::usec;
+
+ const auto r = svn::revision();
+ BOOST_TEST((r.get_kind() == kind::unspecified));
+ BOOST_CHECK_THROW(r.get_number(), std::logic_error);
+ BOOST_CHECK_THROW(r.get_date<usec>(), std::logic_error);
+}
+
+BOOST_AUTO_TEST_CASE(postconditions_number)
+{
+ using kind = svn::revision::kind;
+ using usec = svn::revision::usec;
+
+ const auto r = svn::revision(svn::revnum::invalid);
+ BOOST_TEST((r.get_kind() == kind::number));
+ BOOST_TEST((r.get_number() == svn::revnum::invalid));
+ BOOST_CHECK_THROW(r.get_date<usec>(), std::logic_error);
+}
+
+BOOST_AUTO_TEST_CASE(postconditions_date)
+{
+ using kind = svn::revision::kind;
+ using usec = svn::revision::usec;
+
+ const auto r = svn::revision(svn::revision::time<usec>());
+ BOOST_TEST((r.get_kind() == kind::date));
+ BOOST_TEST((r.get_date<usec>() == svn::revision::time<usec>()));
+ BOOST_CHECK_THROW(r.get_number(), std::logic_error);
+}
+
+// TODO: Add tests for !=, <, >, <= and >=
+
+BOOST_AUTO_TEST_SUITE_END();
Propchange: subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp
------------------------------------------------------------------------------
svn:eol-style = native