name: reorganize Name class
* Categorize class methods.
* Make append component methods inline.
* Make comparison operators non-member functions.
* Improve Doxygen.
* Simplify Name::at implementation.
* Reorder test cases.
* Add test coverage for Name::empty() and iterators.
* Make naming convention test case more readable,
and move it to TestNameComponent test suite.
refs #4171
Change-Id: I5f7deff2535f8265ac4942f892879dd7e56f6414
diff --git a/tests/unit-tests/name-component.t.cpp b/tests/unit-tests/name-component.t.cpp
index 8a99b2f..651b160 100644
--- a/tests/unit-tests/name-component.t.cpp
+++ b/tests/unit-tests/name-component.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,6 +20,7 @@
*/
#include "name-component.hpp"
+#include "name.hpp"
#include "boost-test.hpp"
#include <boost/mpl/vector.hpp>
@@ -205,6 +206,149 @@
BOOST_AUTO_TEST_SUITE_END() // CreateFromIterators
+BOOST_AUTO_TEST_SUITE(NamingConvention)
+
+template<typename ArgType>
+struct ConventionTest
+{
+ function<name::Component(ArgType)> makeComponent;
+ function<ArgType(const name::Component&)> getValue;
+ function<Name&(Name&, ArgType)> append;
+ Name expected;
+ ArgType value;
+ function<bool(const name::Component&)> isComponent;
+};
+
+class NumberWithMarker
+{
+public:
+ ConventionTest<uint64_t>
+ operator()() const
+ {
+ return {bind(&name::Component::fromNumberWithMarker, 0xAA, _1),
+ bind(&name::Component::toNumberWithMarker, _1, 0xAA),
+ bind(&Name::appendNumberWithMarker, _1, 0xAA, _2),
+ Name("/%AA%03%E8"),
+ 1000,
+ bind(&name::Component::isNumberWithMarker, _1, 0xAA)};
+ }
+};
+
+class Segment
+{
+public:
+ ConventionTest<uint64_t>
+ operator()() const
+ {
+ return {&name::Component::fromSegment,
+ bind(&name::Component::toSegment, _1),
+ bind(&Name::appendSegment, _1, _2),
+ Name("/%00%27%10"),
+ 10000,
+ bind(&name::Component::isSegment, _1)};
+ }
+};
+
+class SegmentOffset
+{
+public:
+ ConventionTest<uint64_t>
+ operator()() const
+ {
+ return {&name::Component::fromSegmentOffset,
+ bind(&name::Component::toSegmentOffset, _1),
+ bind(&Name::appendSegmentOffset, _1, _2),
+ Name("/%FB%00%01%86%A0"),
+ 100000,
+ bind(&name::Component::isSegmentOffset, _1)};
+ }
+};
+
+class Version
+{
+public:
+ ConventionTest<uint64_t>
+ operator()() const
+ {
+ return {&name::Component::fromVersion,
+ bind(&name::Component::toVersion, _1),
+ [] (Name& name, uint64_t version) -> Name& { return name.appendVersion(version); },
+ Name("/%FD%00%0FB%40"),
+ 1000000,
+ bind(&name::Component::isVersion, _1)};
+ }
+};
+
+class Timestamp
+{
+public:
+ ConventionTest<time::system_clock::TimePoint>
+ operator()() const
+ {
+ return {&name::Component::fromTimestamp,
+ bind(&name::Component::toTimestamp, _1),
+ [] (Name& name, time::system_clock::TimePoint t) -> Name& { return name.appendTimestamp(t); },
+ Name("/%FC%00%04%7BE%E3%1B%00%00"),
+ time::getUnixEpoch() + time::days(14600), // 40 years
+ bind(&name::Component::isTimestamp, _1)};
+ }
+};
+
+class SequenceNumber
+{
+public:
+ ConventionTest<uint64_t>
+ operator()() const
+ {
+ return {&name::Component::fromSequenceNumber,
+ bind(&name::Component::toSequenceNumber, _1),
+ bind(&Name::appendSequenceNumber, _1, _2),
+ Name("/%FE%00%98%96%80"),
+ 10000000,
+ bind(&name::Component::isSequenceNumber, _1)};
+ }
+};
+
+using ConventionTests = boost::mpl::vector<
+ NumberWithMarker,
+ Segment,
+ SegmentOffset,
+ Version,
+ Timestamp,
+ SequenceNumber
+>;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(Convention, T, ConventionTests)
+{
+ name::Component invalidComponent1;
+ name::Component invalidComponent2("1234567890");
+
+ auto test = T()();
+
+ const Name& expected = test.expected;
+ BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
+
+ BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
+
+ name::Component actualComponent = test.makeComponent(test.value);
+ BOOST_CHECK_EQUAL(actualComponent, expected[0]);
+
+ Name actualName;
+ test.append(actualName, test.value);
+ BOOST_CHECK_EQUAL(actualName, expected);
+
+ BOOST_CHECK_EQUAL(test.isComponent(expected[0]), true);
+ BOOST_CHECK_EQUAL(test.getValue(expected[0]), test.value);
+
+ BOOST_CHECK_EQUAL(test.isComponent(invalidComponent1), false);
+ BOOST_CHECK_EQUAL(test.isComponent(invalidComponent2), false);
+
+ BOOST_CHECK_THROW(test.getValue(invalidComponent1), name::Component::Error);
+ BOOST_CHECK_THROW(test.getValue(invalidComponent2), name::Component::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // NamingConvention
+
BOOST_AUTO_TEST_SUITE_END() // TestNameComponent
} // namespace tests
diff --git a/tests/unit-tests/name.t.cpp b/tests/unit-tests/name.t.cpp
index 9840196..dff17e4 100644
--- a/tests/unit-tests/name.t.cpp
+++ b/tests/unit-tests/name.t.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -22,8 +22,6 @@
#include "name.hpp"
#include "boost-test.hpp"
-#include <boost/tuple/tuple.hpp>
-#include <boost/mpl/vector.hpp>
#include <unordered_map>
namespace ndn {
@@ -51,6 +49,8 @@
0x8, 0x3, // NameComponent
0x6e, 0x64, 0x6e};
+// ---- encoding, decoding ----
+
BOOST_AUTO_TEST_CASE(Basic)
{
Name name("/hello/world");
@@ -89,23 +89,6 @@
BOOST_CHECK_EQUAL(name.toUri(), "/local/ndn/prefix");
}
-BOOST_AUTO_TEST_CASE(AppendsAndMultiEncode)
-{
- Name name("/local");
-
- BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
- Name1, Name1 + sizeof(Name1));
-
- name.append("ndn");
-
- BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
- Name2, Name2 + sizeof(Name2));
-
- name.append("prefix");
- BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
- TestName, TestName+sizeof(TestName));
-}
-
BOOST_AUTO_TEST_CASE(ZeroLengthComponent)
{
static const uint8_t compOctets[] {0x08, 0x00};
@@ -130,183 +113,6 @@
BOOST_CHECK(name2Encoded == nameBlock);
}
-BOOST_AUTO_TEST_CASE(AppendNumber)
-{
- Name name;
- for (uint32_t i = 0; i < 10; i++)
- {
- name.appendNumber(i);
- }
-
- BOOST_CHECK_EQUAL(name.size(), 10);
-
- for (uint32_t i = 0; i < 10; i++)
- {
- BOOST_CHECK_EQUAL(name[i].toNumber(), i);
- }
-}
-
-class Numeric
-{
-public:
- typedef std::list<boost::tuple<function<name::Component(uint64_t)>,
- function<uint64_t(const name::Component&)>,
- function<Name&(Name&, uint64_t)>,
- Name/*expected*/,
- uint64_t/*value*/,
- function<bool(const name::Component&)> > > Dataset;
-
- Numeric()
- {
- dataset.push_back(boost::make_tuple(bind(&name::Component::fromNumberWithMarker,
- 0xAA, _1),
- bind(&name::Component::toNumberWithMarker, _1, 0xAA),
- bind(&Name::appendNumberWithMarker, _1, 0xAA, _2),
- Name("/%AA%03%E8"),
- 1000,
- bind(&name::Component::isNumberWithMarker, _1, 0xAA)));
- dataset.push_back(boost::make_tuple(&name::Component::fromSegment,
- bind(&name::Component::toSegment, _1),
- bind(&Name::appendSegment, _1, _2),
- Name("/%00%27%10"),
- 10000,
- bind(&name::Component::isSegment, _1)));
- dataset.push_back(boost::make_tuple(&name::Component::fromSegmentOffset,
- bind(&name::Component::toSegmentOffset, _1),
- bind(&Name::appendSegmentOffset, _1, _2),
- Name("/%FB%00%01%86%A0"),
- 100000,
- bind(&name::Component::isSegmentOffset, _1)));
- dataset.push_back(boost::make_tuple(&name::Component::fromVersion,
- bind(&name::Component::toVersion, _1),
- bind(static_cast<Name&(Name::*)(uint64_t)>(
- &Name::appendVersion), _1, _2),
- Name("/%FD%00%0FB%40"),
- 1000000,
- bind(&name::Component::isVersion, _1)));
- dataset.push_back(boost::make_tuple(&name::Component::fromSequenceNumber,
- bind(&name::Component::toSequenceNumber, _1),
- bind(&Name::appendSequenceNumber, _1, _2),
- Name("/%FE%00%98%96%80"),
- 10000000,
- bind(&name::Component::isSequenceNumber, _1)));
- }
-
- Dataset dataset;
-};
-
-class Timestamp
-{
-public:
- typedef std::list<boost::tuple<function<name::Component(const time::system_clock::TimePoint&)>,
- function<time::system_clock::TimePoint(const name::Component&)>,
- function<Name&(Name&, const time::system_clock::TimePoint&)>,
- Name/*expected*/,
- time::system_clock::TimePoint/*value*/,
- function<bool(const name::Component&)> > > Dataset;
- Timestamp()
- {
- dataset.push_back(boost::make_tuple(&name::Component::fromTimestamp,
- ndn::bind(&name::Component::toTimestamp, _1),
- ndn::bind(&Name::appendTimestamp, _1, _2),
- Name("/%FC%00%04%7BE%E3%1B%00%00"),
- time::getUnixEpoch() + time::days(14600/*40 years*/),
- bind(&name::Component::isTimestamp, _1)));
- }
-
- Dataset dataset;
-};
-
-typedef boost::mpl::vector<Numeric, Timestamp> ConventionsDatasets;
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(NamingConventions, T, ConventionsDatasets, T)
-{
- // // These octets are obtained by the snippet below.
- // // This check is intended to detect unexpected encoding change in the future.
- // for (typename T::Dataset::const_iterator it = this->dataset.begin();
- // it != this->dataset.end(); ++it) {
- // Name name;
- // name.append(it->template get<0>()(it->template get<4>()));
- // std::cout << name << std::endl;
- // }
-
- name::Component invalidComponent1;
- name::Component invalidComponent2("1234567890");
-
- for (typename T::Dataset::const_iterator it = this->dataset.begin();
- it != this->dataset.end(); ++it) {
- const Name& expected = it->template get<3>();
- BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
-
- BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
-
- name::Component actualComponent = it->template get<0>()(it->template get<4>());
- BOOST_CHECK_EQUAL(actualComponent, expected[0]);
-
- Name actualName;
- it->template get<2>()(actualName, it->template get<4>());
- BOOST_CHECK_EQUAL(actualName, expected);
-
- BOOST_CHECK_EQUAL(it->template get<5>()(expected[0]), true);
- BOOST_REQUIRE_NO_THROW(it->template get<1>()(expected[0]));
- BOOST_CHECK_EQUAL(it->template get<1>()(expected[0]), it->template get<4>());
-
- BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent1), false);
- BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent2), false);
-
- BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent1), name::Component::Error);
- BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent2), name::Component::Error);
- }
-}
-
-BOOST_AUTO_TEST_CASE(GetSuccessor)
-{
- BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%02").getSuccessor(), Name("ndn:/%00%01/%01%03"));
- BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%FF").getSuccessor(), Name("ndn:/%00%01/%02%00"));
- BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%FF%FF").getSuccessor(), Name("ndn:/%00%01/%00%00%00"));
- BOOST_CHECK_EQUAL(Name().getSuccessor(), Name("ndn:/%00"));
-}
-
-BOOST_AUTO_TEST_CASE(Markers)
-{
- Name name;
- uint64_t number;
-
- BOOST_REQUIRE_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
- BOOST_CHECK_EQUAL(number, 30923);
-
- BOOST_REQUIRE_NO_THROW(number = name.appendSegmentOffset(589).at(-1).toSegmentOffset());
- BOOST_CHECK_EQUAL(number, 589);
-
- BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
-
- BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
- BOOST_CHECK_EQUAL(number, 25912);
-
- const time::system_clock::TimePoint tp = time::system_clock::now();
- time::system_clock::TimePoint tp2;
- BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
- BOOST_CHECK_LE(std::abs(time::duration_cast<time::microseconds>(tp2 - tp).count()), 1);
-
- BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
- BOOST_CHECK_EQUAL(number, 11676);
-}
-
-BOOST_AUTO_TEST_CASE(UnorderedMap)
-{
- std::unordered_map<Name, int> map;
- Name name1("/1");
- Name name2("/2");
- Name name3("/3");
- map[name1] = 1;
- map[name2] = 2;
- map[name3] = 3;
-
- BOOST_CHECK_EQUAL(map[name1], 1);
- BOOST_CHECK_EQUAL(map[name2], 2);
- BOOST_CHECK_EQUAL(map[name3], 3);
-}
-
BOOST_AUTO_TEST_CASE(ImplicitSha256Digest)
{
Name n;
@@ -361,54 +167,6 @@
BOOST_CHECK(n2.get(1).isGeneric());
}
-BOOST_AUTO_TEST_CASE(Compare)
-{
- BOOST_CHECK_EQUAL(Name("/A") .compare(Name("/A")), 0);
- BOOST_CHECK_EQUAL(Name("/A") .compare(Name("/A")), 0);
- BOOST_CHECK_LT (Name("/A") .compare(Name("/B")), 0);
- BOOST_CHECK_GT (Name("/B") .compare(Name("/A")), 0);
- BOOST_CHECK_LT (Name("/A") .compare(Name("/AA")), 0);
- BOOST_CHECK_GT (Name("/AA") .compare(Name("/A")), 0);
- BOOST_CHECK_LT (Name("/A") .compare(Name("/A/C")), 0);
- BOOST_CHECK_GT (Name("/A/C").compare(Name("/A")), 0);
-
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/A")), 0);
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/B")), 0);
- BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/AA")), 0);
- BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/A/C")), 0);
- BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/A")), 0);
-
- BOOST_CHECK_EQUAL(Name("/Z/A") .compare(1, Name::npos, Name("/A")), 0);
- BOOST_CHECK_EQUAL(Name("/Z/A") .compare(1, Name::npos, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/B")), 0);
- BOOST_CHECK_GT (Name("/Z/B") .compare(1, Name::npos, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/AA")), 0);
- BOOST_CHECK_GT (Name("/Z/AA") .compare(1, Name::npos, Name("/A")), 0);
- BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/A/C")), 0);
- BOOST_CHECK_GT (Name("/Z/A/C").compare(1, Name::npos, Name("/A")), 0);
-
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/B/W"), 1, 1), 0);
- BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/AA/W"), 1, 1), 0);
- BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/A/C/W"), 1, 2), 0);
- BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A/W"), 1, 1), 0);
-
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A"), 1), 0);
- BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A"), 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/B"), 1), 0);
- BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/X/A"), 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/AA"), 1), 0);
- BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A"), 1), 0);
- BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/A/C"), 1), 0);
- BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A"), 1), 0);
-}
-
BOOST_AUTO_TEST_CASE(NameWithSpaces)
{
Name name("/ hello\t/\tworld \r\n");
@@ -417,6 +175,62 @@
BOOST_CHECK_THROW(Name("/hello//world"), name::Component::Error);
}
+BOOST_AUTO_TEST_CASE(DeepCopy)
+{
+ Name n1("/hello/world");
+ Name n2 = n1.deepCopy();
+
+ BOOST_CHECK_EQUAL(n1, n2);
+ BOOST_CHECK_NE(&n1.wireEncode(), &n2.wireEncode());
+
+ EncodingBuffer buffer(1024, 0);
+ n1.wireEncode(buffer);
+ Name n3(buffer.block());
+
+ BOOST_CHECK_EQUAL(n1, n3);
+ BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), 1024);
+ n3 = n3.deepCopy();
+
+ BOOST_CHECK_LT(n3.wireEncode().size(), 1024);
+ BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), n3.wireEncode().size());
+}
+
+// ---- iterators ----
+
+BOOST_AUTO_TEST_CASE(ForwardIterator)
+{
+ name::Component comps[] {
+ name::Component("A"),
+ name::Component("B"),
+ name::Component("C"),
+ name::Component("D")
+ };
+
+ Name n0;
+ BOOST_CHECK_EQUAL_COLLECTIONS(n0.begin(), n0.end(), comps, comps + 0);
+
+ Name n4("/A/B/C/D");
+ BOOST_CHECK_EQUAL_COLLECTIONS(n4.begin(), n4.end(), comps, comps + 4);
+}
+
+BOOST_AUTO_TEST_CASE(ReverseIterator)
+{
+ name::Component comps[] {
+ name::Component("D"),
+ name::Component("C"),
+ name::Component("B"),
+ name::Component("A")
+ };
+
+ Name n0;
+ BOOST_CHECK_EQUAL_COLLECTIONS(n0.rbegin(), n0.rend(), comps, comps + 0);
+
+ Name n4("/A/B/C/D");
+ BOOST_CHECK_EQUAL_COLLECTIONS(n4.rbegin(), n4.rend(), comps, comps + 4);
+}
+
+// ---- modifiers ----
+
BOOST_AUTO_TEST_CASE(Append)
{
PartialName toAppend("/and");
@@ -436,6 +250,126 @@
}
}
+BOOST_AUTO_TEST_CASE(AppendsAndMultiEncode)
+{
+ Name name("/local");
+ BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+ Name1, Name1 + sizeof(Name1));
+
+ name.append("ndn");
+ BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+ Name2, Name2 + sizeof(Name2));
+
+ name.append("prefix");
+ BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+ TestName, TestName+sizeof(TestName));
+}
+
+BOOST_AUTO_TEST_CASE(AppendNumber)
+{
+ Name name;
+ for (uint32_t i = 0; i < 10; i++) {
+ name.appendNumber(i);
+ }
+
+ BOOST_CHECK_EQUAL(name.size(), 10);
+
+ for (uint32_t i = 0; i < 10; i++) {
+ BOOST_CHECK_EQUAL(name[i].toNumber(), i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(Markers)
+{
+ // TestNameComponent/NamingConvention provides additional coverage for these methods,
+ // including verifications of the wire format.
+
+ Name name;
+ uint64_t number;
+
+ BOOST_REQUIRE_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
+ BOOST_CHECK_EQUAL(number, 30923);
+
+ BOOST_REQUIRE_NO_THROW(number = name.appendSegmentOffset(589).at(-1).toSegmentOffset());
+ BOOST_CHECK_EQUAL(number, 589);
+
+ BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
+
+ BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
+ BOOST_CHECK_EQUAL(number, 25912);
+
+ const time::system_clock::TimePoint tp = time::system_clock::now();
+ time::system_clock::TimePoint tp2;
+ BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
+ BOOST_CHECK_LE(std::abs(time::duration_cast<time::microseconds>(tp2 - tp).count()), 1);
+
+ BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
+ BOOST_CHECK_EQUAL(number, 11676);
+}
+
+BOOST_AUTO_TEST_CASE(Clear)
+{
+ Name n("/A");
+ BOOST_CHECK_EQUAL(n.empty(), false);
+
+ n.clear();
+ BOOST_CHECK_EQUAL(n.empty(), true);
+ BOOST_CHECK_EQUAL(n.size(), 0);
+}
+
+// ---- algorithms ----
+
+BOOST_AUTO_TEST_CASE(GetSuccessor)
+{
+ BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%02").getSuccessor(), Name("ndn:/%00%01/%01%03"));
+ BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%FF").getSuccessor(), Name("ndn:/%00%01/%02%00"));
+ BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%FF%FF").getSuccessor(), Name("ndn:/%00%01/%00%00%00"));
+ BOOST_CHECK_EQUAL(Name().getSuccessor(), Name("ndn:/%00"));
+}
+
+BOOST_AUTO_TEST_CASE(Compare)
+{
+ BOOST_CHECK_EQUAL(Name("/A") .compare(Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/A") .compare(Name("/B")), 0);
+ BOOST_CHECK_GT (Name("/B") .compare(Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/A") .compare(Name("/AA")), 0);
+ BOOST_CHECK_GT (Name("/AA") .compare(Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/A") .compare(Name("/A/C")), 0);
+ BOOST_CHECK_GT (Name("/A/C").compare(Name("/A")), 0);
+
+ BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/B")), 0);
+ BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/AA")), 0);
+ BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/A/C")), 0);
+ BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/A")), 0);
+
+ BOOST_CHECK_EQUAL(Name("/Z/A") .compare(1, Name::npos, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/B")), 0);
+ BOOST_CHECK_GT (Name("/Z/B") .compare(1, Name::npos, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/AA")), 0);
+ BOOST_CHECK_GT (Name("/Z/AA") .compare(1, Name::npos, Name("/A")), 0);
+ BOOST_CHECK_LT (Name("/Z/A") .compare(1, Name::npos, Name("/A/C")), 0);
+ BOOST_CHECK_GT (Name("/Z/A/C").compare(1, Name::npos, Name("/A")), 0);
+
+ BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/B/W"), 1, 1), 0);
+ BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/AA/W"), 1, 1), 0);
+ BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A/W"), 1, 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/A/C/W"), 1, 2), 0);
+ BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A/W"), 1, 1), 0);
+
+ BOOST_CHECK_EQUAL(Name("/Z/A/Y") .compare(1, 1, Name("/X/A"), 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/B"), 1), 0);
+ BOOST_CHECK_GT (Name("/Z/B/Y") .compare(1, 1, Name("/X/A"), 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/AA"), 1), 0);
+ BOOST_CHECK_GT (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A"), 1), 0);
+ BOOST_CHECK_LT (Name("/Z/A/Y") .compare(1, 1, Name("/X/A/C"), 1), 0);
+ BOOST_CHECK_GT (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A"), 1), 0);
+}
+
BOOST_AUTO_TEST_CASE(SubName)
{
Name name("/hello/world");
@@ -474,24 +408,19 @@
BOOST_CHECK_EQUAL("/first/second/last", name.getSubName(-10, 10));
}
-BOOST_AUTO_TEST_CASE(DeepCopy)
+BOOST_AUTO_TEST_CASE(UnorderedMap)
{
- Name n1("/hello/world");
- Name n2 = n1.deepCopy();
+ std::unordered_map<Name, int> map;
+ Name name1("/1");
+ Name name2("/2");
+ Name name3("/3");
+ map[name1] = 1;
+ map[name2] = 2;
+ map[name3] = 3;
- BOOST_CHECK_EQUAL(n1, n2);
- BOOST_CHECK_NE(&n1.wireEncode(), &n2.wireEncode());
-
- EncodingBuffer buffer(1024, 0);
- n1.wireEncode(buffer);
- Name n3(buffer.block());
-
- BOOST_CHECK_EQUAL(n1, n3);
- BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), 1024);
- n3 = n3.deepCopy();
-
- BOOST_CHECK_LT(n3.wireEncode().size(), 1024);
- BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), n3.wireEncode().size());
+ BOOST_CHECK_EQUAL(map[name1], 1);
+ BOOST_CHECK_EQUAL(map[name2], 2);
+ BOOST_CHECK_EQUAL(map[name3], 3);
}
BOOST_AUTO_TEST_SUITE_END() // TestName