test: switch some unit tests to doctest (#5383)

This change moves some tests from the current unit tests that are compiled into the rippled binary to using the doctest framework.
This commit is contained in:
Vlad
2025-06-26 20:35:31 +01:00
committed by GitHub
parent df6daf0d8f
commit e18f27f5f7
25 changed files with 908 additions and 927 deletions

4
src/tests/README.md Normal file
View File

@@ -0,0 +1,4 @@
# Unit tests
This directory contains unit tests for the project. The difference from existing `src/test` folder
is that we switch to 3rd party testing framework (doctest). We intend to gradually move existing tests
from our own framework to doctest and such tests will be moved to this new folder.

View File

@@ -0,0 +1,14 @@
include(xrpl_add_test)
# Test requirements.
find_package(doctest REQUIRED)
# Common library dependencies for the rest of the tests.
add_library(xrpl.imports.test INTERFACE)
target_link_libraries(xrpl.imports.test INTERFACE doctest::doctest xrpl.libxrpl)
# One test for each module.
xrpl_add_test(basics)
target_link_libraries(xrpl.test.basics PRIVATE xrpl.imports.test)
xrpl_add_test(crypto)
target_link_libraries(xrpl.test.crypto PRIVATE xrpl.imports.test)

View File

@@ -0,0 +1,129 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/RangeSet.h>
#include <doctest/doctest.h>
#include <cstdint>
#include <optional>
using namespace ripple;
TEST_SUITE_BEGIN("RangeSet");
TEST_CASE("prevMissing")
{
// Set will include:
// [ 0, 5]
// [10,15]
// [20,25]
// etc...
RangeSet<std::uint32_t> set;
for (std::uint32_t i = 0; i < 10; ++i)
set.insert(range(10 * i, 10 * i + 5));
for (std::uint32_t i = 1; i < 100; ++i)
{
std::optional<std::uint32_t> expected;
// no prev missing in domain for i <= 6
if (i > 6)
{
std::uint32_t const oneBelowRange = (10 * (i / 10)) - 1;
expected = ((i % 10) > 6) ? (i - 1) : oneBelowRange;
}
CHECK(prevMissing(set, i) == expected);
}
}
TEST_CASE("toString")
{
RangeSet<std::uint32_t> set;
CHECK(to_string(set) == "empty");
set.insert(1);
CHECK(to_string(set) == "1");
set.insert(range(4u, 6u));
CHECK(to_string(set) == "1,4-6");
set.insert(2);
CHECK(to_string(set) == "1-2,4-6");
set.erase(range(4u, 5u));
CHECK(to_string(set) == "1-2,6");
}
TEST_CASE("fromString")
{
RangeSet<std::uint32_t> set;
CHECK(!from_string(set, ""));
CHECK(boost::icl::length(set) == 0);
CHECK(!from_string(set, "#"));
CHECK(boost::icl::length(set) == 0);
CHECK(!from_string(set, ","));
CHECK(boost::icl::length(set) == 0);
CHECK(!from_string(set, ",-"));
CHECK(boost::icl::length(set) == 0);
CHECK(!from_string(set, "1,,2"));
CHECK(boost::icl::length(set) == 0);
CHECK(from_string(set, "1"));
CHECK(boost::icl::length(set) == 1);
CHECK(boost::icl::first(set) == 1);
CHECK(from_string(set, "1,1"));
CHECK(boost::icl::length(set) == 1);
CHECK(boost::icl::first(set) == 1);
CHECK(from_string(set, "1-1"));
CHECK(boost::icl::length(set) == 1);
CHECK(boost::icl::first(set) == 1);
CHECK(from_string(set, "1,4-6"));
CHECK(boost::icl::length(set) == 4);
CHECK(boost::icl::first(set) == 1);
CHECK(!boost::icl::contains(set, 2));
CHECK(!boost::icl::contains(set, 3));
CHECK(boost::icl::contains(set, 4));
CHECK(boost::icl::contains(set, 5));
CHECK(boost::icl::last(set) == 6);
CHECK(from_string(set, "1-2,4-6"));
CHECK(boost::icl::length(set) == 5);
CHECK(boost::icl::first(set) == 1);
CHECK(boost::icl::contains(set, 2));
CHECK(boost::icl::contains(set, 4));
CHECK(boost::icl::last(set) == 6);
CHECK(from_string(set, "1-2,6"));
CHECK(boost::icl::length(set) == 3);
CHECK(boost::icl::first(set) == 1);
CHECK(boost::icl::contains(set, 2));
CHECK(boost::icl::last(set) == 6);
}
TEST_SUITE_END();

View File

@@ -0,0 +1,105 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/Slice.h>
#include <doctest/doctest.h>
#include <array>
#include <cstdint>
using namespace ripple;
static std::uint8_t const data[] = {
0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23, 0x71, 0x6d, 0x2a,
0x18, 0xb4, 0x70, 0xcb, 0xf5, 0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c,
0xf0, 0x2c, 0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3};
TEST_SUITE_BEGIN("Slice");
TEST_CASE("equality & inequality")
{
Slice const s0{};
CHECK(s0.size() == 0);
CHECK(s0.data() == nullptr);
CHECK(s0 == s0);
// Test slices of equal and unequal size pointing to same data:
for (std::size_t i = 0; i != sizeof(data); ++i)
{
Slice const s1{data, i};
CHECK(s1.size() == i);
CHECK(s1.data() != nullptr);
if (i == 0)
CHECK(s1 == s0);
else
CHECK(s1 != s0);
for (std::size_t j = 0; j != sizeof(data); ++j)
{
Slice const s2{data, j};
if (i == j)
CHECK(s1 == s2);
else
CHECK(s1 != s2);
}
}
// Test slices of equal size but pointing to different data:
std::array<std::uint8_t, sizeof(data)> a;
std::array<std::uint8_t, sizeof(data)> b;
for (std::size_t i = 0; i != sizeof(data); ++i)
a[i] = b[i] = data[i];
CHECK(makeSlice(a) == makeSlice(b));
b[7]++;
CHECK(makeSlice(a) != makeSlice(b));
a[7]++;
CHECK(makeSlice(a) == makeSlice(b));
}
TEST_CASE("indexing")
{
Slice const s{data, sizeof(data)};
for (std::size_t i = 0; i != sizeof(data); ++i)
CHECK(s[i] == data[i]);
}
TEST_CASE("advancing")
{
for (std::size_t i = 0; i < sizeof(data); ++i)
{
for (std::size_t j = 0; i + j < sizeof(data); ++j)
{
Slice s(data + i, sizeof(data) - i);
s += j;
CHECK(s.data() == data + i + j);
CHECK(s.size() == sizeof(data) - i - j);
}
}
}
TEST_SUITE_END();

View File

@@ -0,0 +1,67 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/base64.h>
#include <doctest/doctest.h>
#include <string>
using namespace ripple;
static void
check(std::string const& in, std::string const& out)
{
auto const encoded = base64_encode(in);
CHECK(encoded == out);
CHECK(base64_decode(encoded) == in);
}
TEST_CASE("base64")
{
check("", "");
check("f", "Zg==");
check("fo", "Zm8=");
check("foo", "Zm9v");
check("foob", "Zm9vYg==");
check("fooba", "Zm9vYmE=");
check("foobar", "Zm9vYmFy");
check(
"Man is distinguished, not only by his reason, but by this "
"singular passion from "
"other animals, which is a lust of the mind, that by a "
"perseverance of delight "
"in the continued and indefatigable generation of knowledge, "
"exceeds the short "
"vehemence of any carnal pleasure.",
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dC"
"BieSB0aGlz"
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
"x1c3Qgb2Yg"
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aG"
"UgY29udGlu"
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleG"
"NlZWRzIHRo"
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
std::string const notBase64 = "not_base64!!";
std::string const truncated = "not";
CHECK(base64_decode(notBase64) == base64_decode(truncated));
}

View File

@@ -0,0 +1,56 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/contract.h>
#include <doctest/doctest.h>
#include <stdexcept>
#include <string>
using namespace ripple;
TEST_CASE("contract")
{
try
{
Throw<std::runtime_error>("Throw test");
}
catch (std::runtime_error const& e1)
{
CHECK(std::string(e1.what()) == "Throw test");
try
{
Rethrow();
}
catch (std::runtime_error const& e2)
{
CHECK(std::string(e2.what()) == "Throw test");
}
catch (...)
{
CHECK(false);
}
}
catch (...)
{
CHECK(false);
}
}

View File

@@ -0,0 +1,2 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>

View File

@@ -0,0 +1,64 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/mulDiv.h>
#include <doctest/doctest.h>
#include <cstdint>
#include <limits>
using namespace ripple;
TEST_CASE("mulDiv")
{
auto const max = std::numeric_limits<std::uint64_t>::max();
std::uint64_t const max32 = std::numeric_limits<std::uint32_t>::max();
auto result = mulDiv(85, 20, 5);
REQUIRE(result);
CHECK(*result == 340);
result = mulDiv(20, 85, 5);
REQUIRE(result);
CHECK(*result == 340);
result = mulDiv(0, max - 1, max - 3);
REQUIRE(result);
CHECK(*result == 0);
result = mulDiv(max - 1, 0, max - 3);
REQUIRE(result);
CHECK(*result == 0);
result = mulDiv(max, 2, max / 2);
REQUIRE(result);
CHECK(*result == 4);
result = mulDiv(max, 1000, max / 1000);
REQUIRE(result);
CHECK(*result == 1000000);
result = mulDiv(max, 1000, max / 1001);
REQUIRE(result);
CHECK(*result == 1001000);
result = mulDiv(max32 + 1, max32 + 1, 5);
REQUIRE(result);
CHECK(*result == 3689348814741910323);
// Overflow
result = mulDiv(max - 1, max - 2, 5);
CHECK(!result);
}

View File

@@ -0,0 +1,174 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2021 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/scope.h>
#include <doctest/doctest.h>
using namespace ripple;
TEST_CASE("scope_exit")
{
// scope_exit always executes the functor on destruction,
// unless release() is called
int i = 0;
{
scope_exit x{[&i]() { i = 1; }};
}
CHECK(i == 1);
{
scope_exit x{[&i]() { i = 2; }};
x.release();
}
CHECK(i == 1);
{
scope_exit x{[&i]() { i += 2; }};
auto x2 = std::move(x);
}
CHECK(i == 3);
{
scope_exit x{[&i]() { i = 4; }};
x.release();
auto x2 = std::move(x);
}
CHECK(i == 3);
{
try
{
scope_exit x{[&i]() { i = 5; }};
throw 1;
}
catch (...)
{
}
}
CHECK(i == 5);
{
try
{
scope_exit x{[&i]() { i = 6; }};
x.release();
throw 1;
}
catch (...)
{
}
}
CHECK(i == 5);
}
TEST_CASE("scope_fail")
{
// scope_fail executes the functor on destruction only
// if an exception is unwinding, unless release() is called
int i = 0;
{
scope_fail x{[&i]() { i = 1; }};
}
CHECK(i == 0);
{
scope_fail x{[&i]() { i = 2; }};
x.release();
}
CHECK(i == 0);
{
scope_fail x{[&i]() { i = 3; }};
auto x2 = std::move(x);
}
CHECK(i == 0);
{
scope_fail x{[&i]() { i = 4; }};
x.release();
auto x2 = std::move(x);
}
CHECK(i == 0);
{
try
{
scope_fail x{[&i]() { i = 5; }};
throw 1;
}
catch (...)
{
}
}
CHECK(i == 5);
{
try
{
scope_fail x{[&i]() { i = 6; }};
x.release();
throw 1;
}
catch (...)
{
}
}
CHECK(i == 5);
}
TEST_CASE("scope_success")
{
// scope_success executes the functor on destruction only
// if an exception is not unwinding, unless release() is called
int i = 0;
{
scope_success x{[&i]() { i = 1; }};
}
CHECK(i == 1);
{
scope_success x{[&i]() { i = 2; }};
x.release();
}
CHECK(i == 1);
{
scope_success x{[&i]() { i += 2; }};
auto x2 = std::move(x);
}
CHECK(i == 3);
{
scope_success x{[&i]() { i = 4; }};
x.release();
auto x2 = std::move(x);
}
CHECK(i == 3);
{
try
{
scope_success x{[&i]() { i = 5; }};
throw 1;
}
catch (...)
{
}
}
CHECK(i == 3);
{
try
{
scope_success x{[&i]() { i = 6; }};
x.release();
throw 1;
}
catch (...)
{
}
}
CHECK(i == 3);
}

View File

@@ -0,0 +1,247 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/basics/tagged_integer.h>
#include <doctest/doctest.h>
#include <type_traits>
using namespace ripple;
struct Tag1
{
};
struct Tag2
{
};
// Static checks that types are not interoperable
using TagUInt1 = tagged_integer<std::uint32_t, Tag1>;
using TagUInt2 = tagged_integer<std::uint32_t, Tag2>;
using TagUInt3 = tagged_integer<std::uint64_t, Tag1>;
// Check construction of tagged_integers
static_assert(
std::is_constructible<TagUInt1, std::uint32_t>::value,
"TagUInt1 should be constructible using a std::uint32_t");
static_assert(
!std::is_constructible<TagUInt1, std::uint64_t>::value,
"TagUInt1 should not be constructible using a std::uint64_t");
static_assert(
std::is_constructible<TagUInt3, std::uint32_t>::value,
"TagUInt3 should be constructible using a std::uint32_t");
static_assert(
std::is_constructible<TagUInt3, std::uint64_t>::value,
"TagUInt3 should be constructible using a std::uint64_t");
// Check assignment of tagged_integers
static_assert(
!std::is_assignable<TagUInt1, std::uint32_t>::value,
"TagUInt1 should not be assignable with a std::uint32_t");
static_assert(
!std::is_assignable<TagUInt1, std::uint64_t>::value,
"TagUInt1 should not be assignable with a std::uint64_t");
static_assert(
!std::is_assignable<TagUInt3, std::uint32_t>::value,
"TagUInt3 should not be assignable with a std::uint32_t");
static_assert(
!std::is_assignable<TagUInt3, std::uint64_t>::value,
"TagUInt3 should not be assignable with a std::uint64_t");
static_assert(
std::is_assignable<TagUInt1, TagUInt1>::value,
"TagUInt1 should be assignable with a TagUInt1");
static_assert(
!std::is_assignable<TagUInt1, TagUInt2>::value,
"TagUInt1 should not be assignable with a TagUInt2");
static_assert(
std::is_assignable<TagUInt3, TagUInt3>::value,
"TagUInt3 should be assignable with a TagUInt1");
static_assert(
!std::is_assignable<TagUInt1, TagUInt3>::value,
"TagUInt1 should not be assignable with a TagUInt3");
static_assert(
!std::is_assignable<TagUInt3, TagUInt1>::value,
"TagUInt3 should not be assignable with a TagUInt1");
// Check convertibility of tagged_integers
static_assert(
!std::is_convertible<std::uint32_t, TagUInt1>::value,
"std::uint32_t should not be convertible to a TagUInt1");
static_assert(
!std::is_convertible<std::uint32_t, TagUInt3>::value,
"std::uint32_t should not be convertible to a TagUInt3");
static_assert(
!std::is_convertible<std::uint64_t, TagUInt3>::value,
"std::uint64_t should not be convertible to a TagUInt3");
static_assert(
!std::is_convertible<std::uint64_t, TagUInt2>::value,
"std::uint64_t should not be convertible to a TagUInt2");
static_assert(
!std::is_convertible<TagUInt1, TagUInt2>::value,
"TagUInt1 should not be convertible to TagUInt2");
static_assert(
!std::is_convertible<TagUInt1, TagUInt3>::value,
"TagUInt1 should not be convertible to TagUInt3");
static_assert(
!std::is_convertible<TagUInt2, TagUInt3>::value,
"TagUInt2 should not be convertible to a TagUInt3");
TEST_SUITE_BEGIN("tagged_integer");
using TagInt = tagged_integer<std::int32_t, Tag1>;
TEST_CASE("comparison operators")
{
TagInt const zero(0);
TagInt const one(1);
CHECK(one == one);
CHECK(!(one == zero));
CHECK(one != zero);
CHECK(!(one != one));
CHECK(zero < one);
CHECK(!(one < zero));
CHECK(one > zero);
CHECK(!(zero > one));
CHECK(one >= one);
CHECK(one >= zero);
CHECK(!(zero >= one));
CHECK(zero <= one);
CHECK(zero <= zero);
CHECK(!(one <= zero));
}
TEST_CASE("increment / decrement operators")
{
TagInt const zero(0);
TagInt const one(1);
TagInt a{0};
++a;
CHECK(a == one);
--a;
CHECK(a == zero);
a++;
CHECK(a == one);
a--;
CHECK(a == zero);
}
TEST_CASE("arithmetic operators")
{
TagInt a{-2};
CHECK(+a == TagInt{-2});
CHECK(-a == TagInt{2});
CHECK(TagInt{-3} + TagInt{4} == TagInt{1});
CHECK(TagInt{-3} - TagInt{4} == TagInt{-7});
CHECK(TagInt{-3} * TagInt{4} == TagInt{-12});
CHECK(TagInt{8} / TagInt{4} == TagInt{2});
CHECK(TagInt{7} % TagInt{4} == TagInt{3});
CHECK(~TagInt{8} == TagInt{~TagInt::value_type{8}});
CHECK((TagInt{6} & TagInt{3}) == TagInt{2});
CHECK((TagInt{6} | TagInt{3}) == TagInt{7});
CHECK((TagInt{6} ^ TagInt{3}) == TagInt{5});
CHECK((TagInt{4} << TagInt{2}) == TagInt{16});
CHECK((TagInt{16} >> TagInt{2}) == TagInt{4});
}
TEST_CASE("assignment operators")
{
TagInt a{-2};
TagInt b{0};
b = a;
CHECK(b == TagInt{-2});
// -3 + 4 == 1
a = TagInt{-3};
a += TagInt{4};
CHECK(a == TagInt{1});
// -3 - 4 == -7
a = TagInt{-3};
a -= TagInt{4};
CHECK(a == TagInt{-7});
// -3 * 4 == -12
a = TagInt{-3};
a *= TagInt{4};
CHECK(a == TagInt{-12});
// 8/4 == 2
a = TagInt{8};
a /= TagInt{4};
CHECK(a == TagInt{2});
// 7 % 4 == 3
a = TagInt{7};
a %= TagInt{4};
CHECK(a == TagInt{3});
// 6 & 3 == 2
a = TagInt{6};
a /= TagInt{3};
CHECK(a == TagInt{2});
// 6 | 3 == 7
a = TagInt{6};
a |= TagInt{3};
CHECK(a == TagInt{7});
// 6 ^ 3 == 5
a = TagInt{6};
a ^= TagInt{3};
CHECK(a == TagInt{5});
// 4 << 2 == 16
a = TagInt{4};
a <<= TagInt{2};
CHECK(a == TagInt{16});
// 16 >> 2 == 4
a = TagInt{16};
a >>= TagInt{2};
CHECK(a == TagInt{4});
}
TEST_SUITE_END();

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2017 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/crypto/csprng.h>
#include <doctest/doctest.h>
using namespace ripple;
TEST_CASE("get values")
{
auto& engine = crypto_prng();
auto rand_val = engine();
CHECK(rand_val >= engine.min());
CHECK(rand_val <= engine.max());
uint16_t twoByte{0};
engine(&twoByte, sizeof(uint16_t));
}

View File

@@ -0,0 +1,2 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>