name-component: encode/decode Convention rev2

Naming Conventions rev2 encode sequence numbers, version
numbers, segment numbers, byte offsets, and timestamps as
typed name components.
Markers as defined in Naming Conventions rev1 are still
supported.

The library by default recognizes both styles, and encodes as
markers. These defaults can be changed via
ndn::name::setConventionDecoding and
ndn::name::setConventionEncoding functions.

"segment offset" is renamed to "byte offset". Functions bearing
"SegmentOffset" in the name are deprecated in favor of their
"ByteOffset" counterparts.

refs #4777

Change-Id: I265d69af474ab27d274ee49619f5cae5fb2c429d
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index beaf62f..5e2a9b3 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -40,6 +40,53 @@
 static_assert(std::is_base_of<tlv::Error, Component::Error>::value,
               "name::Component::Error must inherit from tlv::Error");
 
+static Convention g_conventionEncoding = Convention::MARKER;
+static Convention g_conventionDecoding = Convention::EITHER;
+
+Convention
+getConventionEncoding()
+{
+  return g_conventionEncoding;
+}
+
+void
+setConventionEncoding(Convention convention)
+{
+  switch (convention) {
+    case Convention::MARKER:
+    case Convention::TYPED:
+      g_conventionEncoding = convention;
+      break;
+    default:
+      NDN_THROW(std::invalid_argument("Unknown naming convention"));
+      break;
+  }
+}
+
+Convention
+getConventionDecoding()
+{
+  return g_conventionDecoding;
+}
+
+void
+setConventionDecoding(Convention convention)
+{
+  g_conventionDecoding = convention;
+}
+
+static bool
+canDecodeMarkerConvention()
+{
+  return (static_cast<int>(g_conventionDecoding) & static_cast<int>(Convention::MARKER)) != 0;
+}
+
+static bool
+canDecodeTypedConvention()
+{
+  return (static_cast<int>(g_conventionDecoding) & static_cast<int>(Convention::TYPED)) != 0;
+}
+
 void
 Component::ensureValid() const
 {
@@ -156,31 +203,36 @@
 bool
 Component::isVersion() const
 {
-  return isNumberWithMarker(VERSION_MARKER);
+  return (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent && isNumberWithMarker(VERSION_MARKER)) ||
+         (canDecodeTypedConvention() && type() == tlv::VersionNameComponent && isNumber());
 }
 
 bool
 Component::isSegment() const
 {
-  return isNumberWithMarker(SEGMENT_MARKER);
+  return (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent && isNumberWithMarker(SEGMENT_MARKER)) ||
+         (canDecodeTypedConvention() && type() == tlv::SegmentNameComponent && isNumber());
 }
 
 bool
-Component::isSegmentOffset() const
+Component::isByteOffset() const
 {
-  return isNumberWithMarker(SEGMENT_OFFSET_MARKER);
+  return (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent && isNumberWithMarker(SEGMENT_OFFSET_MARKER)) ||
+         (canDecodeTypedConvention() && type() == tlv::ByteOffsetNameComponent && isNumber());
 }
 
 bool
 Component::isTimestamp() const
 {
-  return isNumberWithMarker(TIMESTAMP_MARKER);
+  return (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent && isNumberWithMarker(TIMESTAMP_MARKER)) ||
+         (canDecodeTypedConvention() && type() == tlv::TimestampNameComponent && isNumber());
 }
 
 bool
 Component::isSequenceNumber() const
 {
-  return isNumberWithMarker(SEQUENCE_NUMBER_MARKER);
+  return (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent && isNumberWithMarker(SEQUENCE_NUMBER_MARKER)) ||
+         (canDecodeTypedConvention() && type() == tlv::SequenceNumNameComponent && isNumber());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -208,40 +260,73 @@
 uint64_t
 Component::toVersion() const
 {
-  return toNumberWithMarker(VERSION_MARKER);
+  if (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent) {
+    return toNumberWithMarker(VERSION_MARKER);
+  }
+  if (canDecodeTypedConvention() && type() == tlv::VersionNameComponent) {
+    return toNumber();
+  }
+  NDN_THROW(Error("Not a Version component"));
 }
 
 uint64_t
 Component::toSegment() const
 {
-  return toNumberWithMarker(SEGMENT_MARKER);
+  if (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent) {
+    return toNumberWithMarker(SEGMENT_MARKER);
+  }
+  if (canDecodeTypedConvention() && type() == tlv::SegmentNameComponent) {
+    return toNumber();
+  }
+  NDN_THROW(Error("Not a Segment component"));
 }
 
 uint64_t
-Component::toSegmentOffset() const
+Component::toByteOffset() const
 {
-  return toNumberWithMarker(SEGMENT_OFFSET_MARKER);
+  if (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent) {
+    return toNumberWithMarker(SEGMENT_OFFSET_MARKER);
+  }
+  if (canDecodeTypedConvention() && type() == tlv::ByteOffsetNameComponent) {
+    return toNumber();
+  }
+  NDN_THROW(Error("Not a ByteOffset component"));
 }
 
 time::system_clock::TimePoint
 Component::toTimestamp() const
 {
-  uint64_t value = toNumberWithMarker(TIMESTAMP_MARKER);
+  uint64_t value = 0;
+  if (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent) {
+    value = toNumberWithMarker(TIMESTAMP_MARKER);
+  }
+  else if (canDecodeTypedConvention() && type() == tlv::TimestampNameComponent) {
+    value = toNumber();
+  }
+  else {
+    NDN_THROW(Error("Not a Timestamp component"));
+  }
   return time::getUnixEpoch() + time::microseconds(value);
 }
 
 uint64_t
 Component::toSequenceNumber() const
 {
-  return toNumberWithMarker(SEQUENCE_NUMBER_MARKER);
+  if (canDecodeMarkerConvention() && type() == tlv::GenericNameComponent) {
+    return toNumberWithMarker(SEQUENCE_NUMBER_MARKER);
+  }
+  if (canDecodeTypedConvention() && type() == tlv::SequenceNumNameComponent) {
+    return toNumber();
+  }
+  NDN_THROW(Error("Not a SequenceNumber component"));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 Component
-Component::fromNumber(uint64_t number)
+Component::fromNumber(uint64_t number, uint32_t type)
 {
-  return makeNonNegativeIntegerBlock(tlv::GenericNameComponent, number);
+  return makeNonNegativeIntegerBlock(type, number);
 }
 
 Component
@@ -267,33 +352,42 @@
 Component
 Component::fromVersion(uint64_t version)
 {
-  return fromNumberWithMarker(VERSION_MARKER, version);
+  return g_conventionEncoding == Convention::MARKER ?
+         fromNumberWithMarker(VERSION_MARKER, version) :
+         fromNumber(version, tlv::VersionNameComponent);
 }
 
 Component
 Component::fromSegment(uint64_t segmentNo)
 {
-  return fromNumberWithMarker(SEGMENT_MARKER, segmentNo);
+  return g_conventionEncoding == Convention::MARKER ?
+         fromNumberWithMarker(SEGMENT_MARKER, segmentNo) :
+         fromNumber(segmentNo, tlv::SegmentNameComponent);
 }
 
 Component
-Component::fromSegmentOffset(uint64_t offset)
+Component::fromByteOffset(uint64_t offset)
 {
-  return fromNumberWithMarker(SEGMENT_OFFSET_MARKER, offset);
+  return g_conventionEncoding == Convention::MARKER ?
+         fromNumberWithMarker(SEGMENT_OFFSET_MARKER, offset) :
+         fromNumber(offset, tlv::ByteOffsetNameComponent);
 }
 
 Component
 Component::fromTimestamp(const time::system_clock::TimePoint& timePoint)
 {
-  using namespace time;
-  uint64_t value = duration_cast<microseconds>(timePoint - getUnixEpoch()).count();
-  return fromNumberWithMarker(TIMESTAMP_MARKER, value);
+  uint64_t value = time::duration_cast<time::microseconds>(timePoint - time::getUnixEpoch()).count();
+  return g_conventionEncoding == Convention::MARKER ?
+         fromNumberWithMarker(TIMESTAMP_MARKER, value) :
+         fromNumber(value, tlv::TimestampNameComponent);
 }
 
 Component
 Component::fromSequenceNumber(uint64_t seqNo)
 {
-  return fromNumberWithMarker(SEQUENCE_NUMBER_MARKER, seqNo);
+  return g_conventionEncoding == Convention::MARKER ?
+         fromNumberWithMarker(SEQUENCE_NUMBER_MARKER, seqNo) :
+         fromNumber(seqNo, tlv::SequenceNumNameComponent);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ndn-cxx/name-component.hpp b/ndn-cxx/name-component.hpp
index 5b1118e..df91ac8 100644
--- a/ndn-cxx/name-component.hpp
+++ b/ndn-cxx/name-component.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,16 +30,50 @@
 namespace ndn {
 namespace name {
 
-/// @brief Segment marker for NDN naming conventions
-static const uint8_t SEGMENT_MARKER = 0x00;
-/// @brief Segment offset marker for NDN naming conventions
-static const uint8_t SEGMENT_OFFSET_MARKER = 0xFB;
-/// @brief Version marker for NDN naming conventions
-static const uint8_t VERSION_MARKER = 0xFD;
-/// @brief Timestamp marker for NDN naming conventions
-static const uint8_t TIMESTAMP_MARKER = 0xFC;
-/// @brief Sequence number marker for NDN naming conventions
-static const uint8_t SEQUENCE_NUMBER_MARKER = 0xFE;
+/** @brief Identify a style of NDN Naming Conventions.
+ */
+enum class Convention {
+  MARKER = 1 << 0, ///< component markers (revision 1)
+  TYPED  = 1 << 1, ///< typed name components (revision 2)
+  EITHER = MARKER | TYPED,
+};
+
+/** @brief Markers in Naming Conventions rev1
+ */
+enum : uint8_t {
+  SEGMENT_MARKER = 0x00,
+  SEGMENT_OFFSET_MARKER = 0xFB,
+  VERSION_MARKER = 0xFD,
+  TIMESTAMP_MARKER = 0xFC,
+  SEQUENCE_NUMBER_MARKER = 0xFE,
+};
+
+/** @brief Return which Naming Conventions style to use while encoding.
+ *
+ *  The current library default is Convention::MARKER, but this will change in the future.
+ */
+Convention
+getConventionEncoding();
+
+/** @brief Set which Naming Conventions style to use while encoding.
+ *  @param convention either Convention::MARKER or Convention::TYPED.
+ */
+void
+setConventionEncoding(Convention convention);
+
+/** @brief Return which Naming Conventions style(s) to accept while decoding.
+ *
+ *  The current library default is Convention::EITHER, but this will change in the future.
+ */
+Convention
+getConventionDecoding();
+
+/** @brief Set which Naming Conventions style(s) to accept while decoding.
+ *  @param convention Convention::MARKER or Convention::TYPED accepts the specified style only;
+ *                    Convention::EITHER accepts either.
+ */
+void
+setConventionDecoding(Convention convention);
 
 /** @brief Represents a name component.
  *
@@ -236,49 +270,56 @@
 
 public: // naming conventions
   /**
-   * @brief Check if the component is nonNegativeInteger
+   * @brief Check if the component is a nonNegativeInteger
    * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
    */
   bool
   isNumber() const;
 
   /**
-   * @brief Check if the component is NameComponentWithMarker per NDN naming conventions
+   * @brief Check if the component is a NameComponentWithMarker per NDN naming conventions rev1
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
   isNumberWithMarker(uint8_t marker) const;
 
   /**
-   * @brief Check if the component is version per NDN naming conventions
+   * @brief Check if the component is a version per NDN naming conventions
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
   isVersion() const;
 
   /**
-   * @brief Check if the component is segment number per NDN naming conventions
+   * @brief Check if the component is a segment number per NDN naming conventions
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
   isSegment() const;
 
   /**
-   * @brief Check if the component is segment offset per NDN naming conventions
+   * @brief Check if the component is a byte offset per NDN naming conventions
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
-  isSegmentOffset() const;
+  isByteOffset() const;
+
+  /// @deprecated use isByteOffset
+  bool
+  isSegmentOffset() const
+  {
+    return isByteOffset();
+  }
 
   /**
-   * @brief Check if the component is timestamp per NDN naming conventions
+   * @brief Check if the component is a timestamp per NDN naming conventions
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
   isTimestamp() const;
 
   /**
-   * @brief Check if the component is sequence number per NDN naming conventions
+   * @brief Check if the component is a sequence number per NDN naming conventions
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   bool
@@ -312,8 +353,7 @@
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    *
-   * @throws Error if name component does not have the specified marker.
-   *         tlv::Error if format does not follow NameComponentWithMarker specification.
+   * @throw tlv::Error not a Version component interpreted by the chosen convention(s).
    */
   uint64_t
   toVersion() const;
@@ -323,30 +363,34 @@
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    *
-   * @throws Error if name component does not have the specified marker.
-   *         tlv::Error if format does not follow NameComponentWithMarker specification.
+   * @throw tlv::Error not a Segment component interpreted by the chosen convention(s).
    */
   uint64_t
   toSegment() const;
 
   /**
-   * @brief Interpret as segment offset component using NDN naming conventions
+   * @brief Interpret as byte offset component using NDN naming conventions
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    *
-   * @throws Error if name component does not have the specified marker.
-   *         tlv::Error if format does not follow NameComponentWithMarker specification.
+   * @throw tlv::Error not a ByteOffset component interpreted by the chosen convention(s).
    */
   uint64_t
-  toSegmentOffset() const;
+  toByteOffset() const;
+
+  /// @deprecated use toByteOffset
+  uint64_t
+  toSegmentOffset() const
+  {
+    return toByteOffset();
+  }
 
   /**
    * @brief Interpret as timestamp component using NDN naming conventions
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    *
-   * @throws Error if name component does not have the specified marker.
-   *         tlv::Error if format does not follow NameComponentWithMarker specification.
+   * @throw tlv::Error not a Timestamp component interpreted by the chosen convention(s).
    */
   time::system_clock::TimePoint
   toTimestamp() const;
@@ -356,8 +400,7 @@
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    *
-   * @throws Error if name component does not have the specified marker.
-   *         tlv::Error if format does not follow NameComponentWithMarker specification.
+   * @throw tlv::Error not a SequenceNumber component interpreted by the chosen convention(s).
    */
   uint64_t
   toSequenceNumber() const;
@@ -368,10 +411,10 @@
    * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
    *
    * @param number The non-negative number
-   * @return The component value.
+   * @param type TLV-TYPE
    */
   static Component
-  fromNumber(uint64_t number);
+  fromNumber(uint64_t number, uint32_t type = tlv::GenericNameComponent);
 
   /**
    * @brief Create a component encoded as NameComponentWithMarker
@@ -392,7 +435,6 @@
    *
    * @param marker 1-byte marker octet
    * @param number The non-negative number
-   * @return The component value.
    */
   static Component
   fromNumberWithMarker(uint8_t marker, uint64_t number);
@@ -414,12 +456,19 @@
   fromSegment(uint64_t segmentNo);
 
   /**
-   * @brief Create segment offset component using NDN naming conventions
+   * @brief Create byte offset component using NDN naming conventions
    *
    * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   static Component
-  fromSegmentOffset(uint64_t offset);
+  fromByteOffset(uint64_t offset);
+
+  /// @deprecated use fromByteOffset
+  static Component
+  fromSegmentOffset(uint64_t offset)
+  {
+    return fromByteOffset(offset);
+  }
 
   /**
    * @brief Create sequence number component using NDN naming conventions
diff --git a/ndn-cxx/name.hpp b/ndn-cxx/name.hpp
index ebd850c..0ce98a4 100644
--- a/ndn-cxx/name.hpp
+++ b/ndn-cxx/name.hpp
@@ -373,14 +373,21 @@
     return append(Component::fromSegment(segmentNo));
   }
 
-  /** @brief Append a segment byte offset component
+  /** @brief Append a byte offset component
    *  @return a reference to this name, to allow chaining
    *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
    */
   Name&
+  appendByteOffset(uint64_t offset)
+  {
+    return append(Component::fromByteOffset(offset));
+  }
+
+  /// @deprecated use appendByteOffset
+  Name&
   appendSegmentOffset(uint64_t offset)
   {
-    return append(Component::fromSegmentOffset(offset));
+    return appendByteOffset(offset);
   }
 
   /** @brief Append a timestamp component
diff --git a/tests/unit/name-component.t.cpp b/tests/unit/name-component.t.cpp
index 78613f1..6f5bffc 100644
--- a/tests/unit/name-component.t.cpp
+++ b/tests/unit/name-component.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -251,9 +251,29 @@
   function<bool(const Component&)> isComponent;
 };
 
+class ConventionMarker
+{
+};
+
+class ConventionTyped
+{
+public:
+  ConventionTyped()
+  {
+    name::setConventionEncoding(name::Convention::TYPED);
+  }
+
+  ~ConventionTyped()
+  {
+    name::setConventionEncoding(name::Convention::MARKER);
+  }
+};
+
 class NumberWithMarker
 {
 public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<uint64_t>
   operator()() const
   {
@@ -266,9 +286,11 @@
   }
 };
 
-class Segment
+class SegmentMarker
 {
 public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<uint64_t>
   operator()() const
   {
@@ -281,9 +303,28 @@
   }
 };
 
-class SegmentOffset
+class SegmentTyped
 {
 public:
+  using ConventionRev = ConventionTyped;
+
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&Component::fromSegment,
+            bind(&Component::toSegment, _1),
+            bind(&Name::appendSegment, _1, _2),
+            Name("/33=%27%10"),
+            10000,
+            bind(&Component::isSegment, _1)};
+  }
+};
+
+class SegmentOffsetMarker
+{
+public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<uint64_t>
   operator()() const
   {
@@ -296,9 +337,28 @@
   }
 };
 
-class Version
+class ByteOffsetTyped
 {
 public:
+  using ConventionRev = ConventionTyped;
+
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&Component::fromByteOffset,
+            bind(&Component::toByteOffset, _1),
+            bind(&Name::appendByteOffset, _1, _2),
+            Name("/34=%00%01%86%A0"),
+            100000,
+            bind(&Component::isByteOffset, _1)};
+  }
+};
+
+class VersionMarker
+{
+public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<uint64_t>
   operator()() const
   {
@@ -311,9 +371,28 @@
   }
 };
 
-class Timestamp
+class VersionTyped
 {
 public:
+  using ConventionRev = ConventionTyped;
+
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&Component::fromVersion,
+            bind(&Component::toVersion, _1),
+            [] (Name& name, uint64_t version) -> Name& { return name.appendVersion(version); },
+            Name("/35=%00%0FB%40"),
+            1000000,
+            bind(&Component::isVersion, _1)};
+  }
+};
+
+class TimestampMarker
+{
+public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<time::system_clock::TimePoint>
   operator()() const
   {
@@ -326,9 +405,28 @@
   }
 };
 
-class SequenceNumber
+class TimestampTyped
 {
 public:
+  using ConventionRev = ConventionTyped;
+
+  ConventionTest<time::system_clock::TimePoint>
+  operator()() const
+  {
+    return {&Component::fromTimestamp,
+            bind(&Component::toTimestamp, _1),
+            [] (Name& name, time::system_clock::TimePoint t) -> Name& { return name.appendTimestamp(t); },
+            Name("/36=%00%04%7BE%E3%1B%00%00"),
+            time::getUnixEpoch() + 14600_days, // 40 years
+            bind(&Component::isTimestamp, _1)};
+  }
+};
+
+class SequenceNumberMarker
+{
+public:
+  using ConventionRev = ConventionMarker;
+
   ConventionTest<uint64_t>
   operator()() const
   {
@@ -341,16 +439,38 @@
   }
 };
 
+class SequenceNumberTyped
+{
+public:
+  using ConventionRev = ConventionTyped;
+
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&Component::fromSequenceNumber,
+            bind(&Component::toSequenceNumber, _1),
+            bind(&Name::appendSequenceNumber, _1, _2),
+            Name("/37=%00%98%96%80"),
+            10000000,
+            bind(&Component::isSequenceNumber, _1)};
+  }
+};
+
 using ConventionTests = boost::mpl::vector<
   NumberWithMarker,
-  Segment,
-  SegmentOffset,
-  Version,
-  Timestamp,
-  SequenceNumber
+  SegmentMarker,
+  SegmentTyped,
+  SegmentOffsetMarker,
+  ByteOffsetTyped,
+  VersionMarker,
+  VersionTyped,
+  TimestampMarker,
+  TimestampTyped,
+  SequenceNumberMarker,
+  SequenceNumberTyped
 >;
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(Convention, T, ConventionTests)
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Convention, T, ConventionTests, T::ConventionRev)
 {
   Component invalidComponent1;
   Component invalidComponent2("1234567890");
@@ -360,8 +480,6 @@
   const Name& expected = test.expected;
   BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
 
-  BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
-
   Component actualComponent = test.makeComponent(test.value);
   BOOST_CHECK_EQUAL(actualComponent, expected[0]);