name: add isKeyword and appendKeyword convenience methods

Also, deprecate Component::fromImplicitSha256Digest() and
Component::fromParametersSha256Digest() that do not provide
any advantages over the Component constructors.

Change-Id: I4890bb1ecab3dfcd96854f5f3aa4927a2328e5cf
diff --git a/tests/unit/name-component.t.cpp b/tests/unit/name-component.t.cpp
index 4dc0370..2743514 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-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -91,6 +91,7 @@
   BOOST_CHECK_THROW(Component::fromEscapedString(""), Component::Error);
   BOOST_CHECK_THROW(Component::fromEscapedString("."), Component::Error);
   BOOST_CHECK_THROW(Component::fromEscapedString(".."), Component::Error);
+  BOOST_CHECK_THROW(Component::fromEscapedString("8="), Component::Error);
 }
 
 static void
@@ -104,7 +105,7 @@
   }
   const std::string hexPctCanonical = "%28%BA%D4%B5%27%5B%D3%92%DB%B6p%C7%5C%F0%B6o%13%F7%94%2B%21%E8%0FU%C0%E8k7GS%A5H";
 
-  Component comp(Block(type, fromHex(hexLower)));
+  Component comp(type, fromHex(hexLower));
 
   BOOST_CHECK_EQUAL(comp.type(), type);
   BOOST_CHECK_EQUAL(comp.toUri(), uriPrefix + hexLower);
@@ -152,7 +153,7 @@
   BOOST_CHECK_EQUAL(comp, Component::fromEscapedString(to_string(type) + "=%2A"));
   BOOST_CHECK_EQUAL(comp, Component::fromNumber(42, type));
 
-  const Component comp2(Block(type, fromHex("010203"))); // TLV-VALUE is *not* a NonNegativeInteger
+  const Component comp2(type, fromHex("010203")); // TLV-VALUE is *not* a NonNegativeInteger
   BOOST_CHECK_EQUAL(comp2.type(), type);
   BOOST_CHECK_EQUAL(comp2.isNumber(), false);
   const auto comp2Uri = to_string(type) + "=%01%02%03";
@@ -196,6 +197,29 @@
   testDecimalComponent(tlv::SequenceNumNameComponent, "seq=");
 }
 
+BOOST_AUTO_TEST_CASE(Keyword)
+{
+  Component comp("2007 6E646E2D637878"_block);
+  BOOST_CHECK_EQUAL(comp.type(), tlv::KeywordNameComponent);
+  BOOST_CHECK_EQUAL(comp.isKeyword(), true);
+  BOOST_CHECK_EQUAL(comp.toUri(), "32=ndn-cxx");
+  BOOST_CHECK_EQUAL(comp.toUri(UriFormat::CANONICAL), "32=ndn-cxx");
+  BOOST_CHECK_EQUAL(comp.toUri(UriFormat::ALTERNATE), "32=ndn-cxx");
+  BOOST_CHECK_EQUAL(comp.toUri(UriFormat::ENV_OR_CANONICAL), "32=ndn-cxx");
+  BOOST_CHECK_EQUAL(comp.toUri(UriFormat::ENV_OR_ALTERNATE), "32=ndn-cxx");
+  BOOST_CHECK_EQUAL(Component::fromEscapedString("32=ndn-cxx"), comp);
+
+  comp.wireDecode("2000"_block);
+  BOOST_CHECK_EQUAL(comp.type(), tlv::KeywordNameComponent);
+  BOOST_CHECK_EQUAL(comp.isKeyword(), true);
+  BOOST_CHECK_EQUAL(comp.toUri(), "32=...");
+  BOOST_CHECK_EQUAL(Component::fromEscapedString("32=..."), comp);
+
+  BOOST_CHECK_THROW(Component::fromEscapedString("32="), Component::Error);
+  BOOST_CHECK_THROW(Component::fromEscapedString("32=."), Component::Error);
+  BOOST_CHECK_THROW(Component::fromEscapedString("32=.."), Component::Error);
+}
+
 BOOST_AUTO_TEST_CASE(OtherType)
 {
   Component comp("0907 6E646E2D637878"_block);
diff --git a/tests/unit/name.t.cpp b/tests/unit/name.t.cpp
index 165c3fc..9195e15 100644
--- a/tests/unit/name.t.cpp
+++ b/tests/unit/name.t.cpp
@@ -312,29 +312,42 @@
                     "0725 080150 0220E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"_block);
 }
 
-BOOST_AUTO_TEST_CASE(Markers)
+BOOST_AUTO_TEST_CASE(AppendTypedComponent)
 {
   // TestNameComponent/NamingConvention provides additional coverage for these methods,
-  // including verifications of the wire format.
+  // including verification 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_CHECK_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
+  BOOST_TEST(number == 30923);
 
-  BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
+  BOOST_CHECK_NO_THROW(number = name.appendByteOffset(41880).at(-1).toByteOffset());
+  BOOST_TEST(number == 41880);
 
-  BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
-  BOOST_CHECK_EQUAL(number, 25912);
+  auto before = time::toUnixTimestamp(time::system_clock::now());
+  BOOST_CHECK_NO_THROW(number = name.appendVersion().at(-1).toVersion());
+  auto after = time::toUnixTimestamp(time::system_clock::now());
+  BOOST_TEST(number >= before.count());
+  BOOST_TEST(number <= after.count());
+
+  BOOST_CHECK_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
+  BOOST_TEST(number == 25912);
 
   const auto tp = time::system_clock::now();
   time::system_clock::TimePoint tp2;
-  BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
-  BOOST_CHECK_LE(time::abs(tp2 - tp), 1_us);
+  BOOST_CHECK_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
+  BOOST_TEST(time::abs(tp2 - tp) <= 1_us);
 
-  BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
-  BOOST_CHECK_EQUAL(number, 11676);
+  BOOST_CHECK_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
+  BOOST_TEST(number == 11676);
+
+  name.appendKeyword({0xab, 0xcd, 0xef});
+  BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=%AB%CD%EF"));
+
+  name.appendKeyword("test-keyword");
+  BOOST_TEST(name.at(-1) == Component::fromEscapedString("32=test-keyword"));
 }
 
 BOOST_AUTO_TEST_CASE(EraseComponent)
@@ -343,15 +356,20 @@
   BOOST_CHECK_EQUAL(name.wireEncode(), "0709 080141 080142 080143"_block);
   BOOST_CHECK_EQUAL(name.hasWire(), true);
 
-  name.erase(1);
+  name.erase(-2);
   BOOST_CHECK_EQUAL(name.size(), 2);
   BOOST_CHECK_EQUAL(name.hasWire(), false);
   BOOST_CHECK_EQUAL(name.wireEncode(), "0706 080141 080143"_block);
 
-  name.erase(-1);
+  name.erase(1);
   BOOST_CHECK_EQUAL(name.size(), 1);
   BOOST_CHECK_EQUAL(name.hasWire(), false);
   BOOST_CHECK_EQUAL(name.wireEncode(), "0703 080141"_block);
+
+  name.erase(0);
+  BOOST_CHECK_EQUAL(name.size(), 0);
+  BOOST_CHECK_EQUAL(name.hasWire(), false);
+  BOOST_CHECK_EQUAL(name.wireEncode(), "0700"_block);
 }
 
 BOOST_AUTO_TEST_CASE(Clear)