interest: drop Selectors from matching functions

matchesData and matchesInterest only consider Name, CanBePrefix,
and MustBeFresh. matchesName is deprecated.

refs #4913

Change-Id: I6f29a98f09f1b6f97e379f4c7d74d9b18da75d0e
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index 38858ca..b14ac15 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -460,22 +460,12 @@
   const Name& dataName = data.getName();
   size_t fullNameLength = dataName.size() + 1;
 
-  // check MinSuffixComponents
-  size_t minSuffixComponents = static_cast<size_t>(std::max(0, getMinSuffixComponents()));
-  if (!(interestNameLength + minSuffixComponents <= fullNameLength))
-    return false;
-
-  // check MaxSuffixComponents
-  bool hasMaxSuffixComponents = getMaxSuffixComponents() >= 0;
-  if (hasMaxSuffixComponents &&
-      !(interestNameLength + getMaxSuffixComponents() >= fullNameLength))
-    return false;
-
-  // check prefix
+  // check Name and CanBePrefix
   if (interestNameLength == fullNameLength) {
     if (m_name.get(-1).isImplicitSha256Digest()) {
-      if (m_name != data.getFullName())
+      if (m_name != data.getFullName()) {
         return false;
+      }
     }
     else {
       // Interest Name is same length as Data full Name, but last component isn't digest
@@ -483,53 +473,13 @@
       return false;
     }
   }
-  else {
-    // Interest Name is a strict prefix of Data full Name
-    if (!m_name.isPrefixOf(dataName))
-      return false;
+  else if (getCanBePrefix() ? !m_name.isPrefixOf(dataName) : (m_name != dataName)) {
+    return false;
   }
 
-  // check Exclude
-  // Exclude won't be violated if Interest Name is same as Data full Name
-  if (!getExclude().empty() && fullNameLength > interestNameLength) {
-    if (interestNameLength == fullNameLength - 1) {
-      // component to exclude is the digest
-      if (getExclude().isExcluded(data.getFullName().get(interestNameLength)))
-        return false;
-      // There's opportunity to inspect the Exclude filter and determine whether
-      // the digest would make a difference.
-      // eg. "<GenericNameComponent>AA</GenericNameComponent><Any/>" doesn't exclude
-      //     any digest - fullName not needed;
-      //     "<Any/><GenericNameComponent>AA</GenericNameComponent>" and
-      //     "<Any/><ImplicitSha256DigestComponent>ffffffffffffffffffffffffffffffff
-      //      </ImplicitSha256DigestComponent>"
-      //     excludes all digests - fullName not needed;
-      //     "<Any/><ImplicitSha256DigestComponent>80000000000000000000000000000000
-      //      </ImplicitSha256DigestComponent>"
-      //     excludes some digests - fullName required
-      // But Interests that contain the exact Data Name before digest and also
-      // contain Exclude filter is too rare to optimize for, so we request
-      // fullName no matter what's in the Exclude filter.
-    }
-    else {
-      // component to exclude is not the digest
-      if (getExclude().isExcluded(dataName.get(interestNameLength)))
-        return false;
-    }
-  }
-
-  // check PublisherPublicKeyLocator
-  const KeyLocator& publisherPublicKeyLocator = getPublisherPublicKeyLocator();
-  if (!publisherPublicKeyLocator.empty()) {
-    const Signature& signature = data.getSignature();
-    const Block& signatureInfo = signature.getInfo();
-    Block::element_const_iterator it = signatureInfo.find(tlv::KeyLocator);
-    if (it == signatureInfo.elements_end()) {
-      return false;
-    }
-    if (publisherPublicKeyLocator.wireEncode() != *it) {
-      return false;
-    }
+  // check MustBeFresh
+  if (getMustBeFresh() && data.getFreshnessPeriod() <= 0_ms) {
+    return false;
   }
 
   return true;
@@ -538,9 +488,9 @@
 bool
 Interest::matchesInterest(const Interest& other) const
 {
-  /// @todo #3162 match ForwardingHint field
-  return this->getName() == other.getName() &&
-         this->getSelectors() == other.getSelectors();
+  return getName() == other.getName() &&
+         getCanBePrefix() == other.getCanBePrefix() &&
+         getMustBeFresh() == other.getMustBeFresh();
 }
 
 // ---- field accessors ----
diff --git a/ndn-cxx/interest.hpp b/ndn-cxx/interest.hpp
index 9f16aff..378954d 100644
--- a/ndn-cxx/interest.hpp
+++ b/ndn-cxx/interest.hpp
@@ -106,25 +106,21 @@
    *  @param name The name to be matched. If this is a Data name, it shall contain the
    *              implicit digest component
    */
+  [[deprecated("use matchesData")]]
   bool
   matchesName(const Name& name) const;
 
   /** @brief Check if Interest can be satisfied by @p data.
    *
-   *  This method considers Name, MinSuffixComponents, MaxSuffixComponents,
-   *  PublisherPublicKeyLocator, and Exclude.
-   *  This method does not consider ChildSelector and MustBeFresh.
+   *  This method considers Name, CanBePrefix, and MustBeFresh. However, MustBeFresh processing
+   *  is limited to rejecting Data with zero/omitted FreshnessPeriod.
    */
   bool
   matchesData(const Data& data) const;
 
-  /** @brief Check if Interest matches @p other interest
+  /** @brief Check if this Interest matches @p other
    *
-   *  Interest matches @p other if both have the same name, selectors, and link.  Other fields
-   *  (e.g., Nonce) may be different.
-   *
-   *  @todo Implement distinguishing Interests by forwarding hint. The current implementation
-   *        checks only name+selectors (Issue #3162).
+   *  Two Interests match if both have the same Name, CanBePrefix, and MustBeFresh.
    */
   bool
   matchesInterest(const Interest& other) const;
diff --git a/tests/unit/ims/in-memory-storage.t.cpp b/tests/unit/ims/in-memory-storage.t.cpp
index 0cb4278..ca1fc35 100644
--- a/tests/unit/ims/in-memory-storage.t.cpp
+++ b/tests/unit/ims/in-memory-storage.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).
  *
@@ -378,256 +378,6 @@
   BOOST_CHECK_EQUAL(ims.size(), 6);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ImplicitDigestSelector, T, InMemoryStorages)
-{
-  T ims;
-
-  Name name("/digest/works");
-  shared_ptr<Data> data = makeData(name);
-  ims.insert(*data);
-
-  shared_ptr<Data> data2 = makeData("/a");
-  ims.insert(*data2);
-
-  shared_ptr<Data> data3 = makeData("/z/z/z");
-  ims.insert(*data3);
-
-  ConstBufferPtr digest1 = util::Sha256::computeDigest(data->wireEncode().wire(), data->wireEncode().size());
-
-  shared_ptr<Interest> interest = makeInterest("");
-  interest->setName(Name(name).appendImplicitSha256Digest(digest1->data(), digest1->size()));
-  interest->setMinSuffixComponents(0);
-  interest->setMaxSuffixComponents(0);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_REQUIRE(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), name);
-
-  shared_ptr<Interest> interest2 = makeInterest("");
-  uint8_t digest2[32] = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
-  interest2->setName(Name(name).appendImplicitSha256Digest(digest2, 32));
-  interest2->setMinSuffixComponents(0);
-  interest2->setMaxSuffixComponents(0);
-
-  shared_ptr<const Data> notfound = ims.find(*interest2);
-  BOOST_CHECK(notfound == nullptr);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ChildSelector, T, InMemoryStorages)
-{
-  T ims;
-
-  shared_ptr<Data> data = makeData("/a");
-  ims.insert(*data);
-
-  shared_ptr<Data> data2 = makeData("/b");
-  ims.insert(*data2);
-
-  shared_ptr<Data> data4 = makeData("/d");
-  ims.insert(*data4);
-
-  shared_ptr<Data> data5 = makeData("/c/c");
-  ims.insert(*data5);
-
-  shared_ptr<Data> data6 = makeData("/c/f");
-  ims.insert(*data6);
-
-  shared_ptr<Data> data7 = makeData("/c/n");
-  ims.insert(*data7);
-
-  shared_ptr<Interest> interest = makeInterest("/c", true);
-  interest->setChildSelector(1);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_REQUIRE(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), "/c/n");
-
-  shared_ptr<Interest> interest2 = makeInterest("/c", true);
-  interest2->setChildSelector(0);
-
-  shared_ptr<const Data> found2 = ims.find(*interest2);
-  BOOST_REQUIRE(found2 != nullptr);
-  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ChildSelector2, T, InMemoryStorages)
-{
-  T ims;
-
-  shared_ptr<Data> data = makeData("/a/b/1");
-  ims.insert(*data);
-
-  shared_ptr<Data> data2 = makeData("/a/b/2");
-  ims.insert(*data2);
-
-  shared_ptr<Data> data3 = makeData("/a/z/1");
-  ims.insert(*data3);
-
-  shared_ptr<Data> data4 = makeData("/a/z/2");
-  ims.insert(*data4);
-
-  shared_ptr<Interest> interest = makeInterest("/a", true);
-  interest->setChildSelector(1);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_REQUIRE(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), "/a/z/1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(PublisherKeySelector, T, InMemoryStorages)
-{
-  T ims;
-
-  Name name("/insert/withkey");
-  shared_ptr<Data> data = makeData(name);
-  ims.insert(*data);
-
-  shared_ptr<Interest> interest = makeInterest(name);
-  Name keyName("/somewhere/key");
-
-  KeyLocator locator(keyName);
-  interest->setPublisherPublicKeyLocator(locator);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_CHECK(found == nullptr);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(PublisherKeySelector2, T, InMemoryStorages)
-{
-  T ims;
-  Name name("/insert/withkey");
-  shared_ptr<Data> data = makeData(name);
-  ims.insert(*data);
-
-  Name name2("/insert/withkey2");
-  shared_ptr<Data> data2 = make_shared<Data>(name2);
-
-  Name keyName("/somewhere/key");
-  const KeyLocator locator(keyName);
-
-  SignatureSha256WithRsa fakeSignature;
-  fakeSignature.setValue(makeEmptyBlock(tlv::SignatureValue));
-  fakeSignature.setKeyLocator(locator);
-  data2->setSignature(fakeSignature);
-  data2->wireEncode();
-
-  ims.insert(*data2);
-
-  shared_ptr<Interest> interest = makeInterest(name2);
-  interest->setPublisherPublicKeyLocator(locator);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_CHECK(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), data2->getName());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(MinMaxComponentsSelector, T, InMemoryStorages)
-{
-  T ims;
-
-  shared_ptr<Data> data = makeData("/a");
-  ims.insert(*data);
-
-  shared_ptr<Data> data2 = makeData("/b");
-  ims.insert(*data2);
-
-  shared_ptr<Data> data4 = makeData("/d");
-  ims.insert(*data4);
-
-  shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
-  ims.insert(*data5);
-
-  shared_ptr<Data> data6 = makeData("/c/c/6/7/8/9");
-  ims.insert(*data6);
-
-  shared_ptr<Data> data7 = makeData("/c/c/1/2/3");
-  ims.insert(*data7);
-
-  shared_ptr<Data> data8 = makeData("/c/c/1");
-  ims.insert(*data8);
-
-  shared_ptr<Interest> interest = makeInterest("/c/c", true);
-  interest->setMinSuffixComponents(3);
-  interest->setChildSelector(0);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_REQUIRE(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), "/c/c/1/2/3");
-
-  shared_ptr<Interest> interest2 = makeInterest("/c/c", true);
-  interest2->setMinSuffixComponents(4);
-  interest2->setChildSelector(1);
-
-  shared_ptr<const Data> found2 = ims.find(*interest2);
-  BOOST_REQUIRE(found2 != nullptr);
-  BOOST_CHECK_EQUAL(found2->getName(), "/c/c/6/7/8/9");
-
-  shared_ptr<Interest> interest3 = makeInterest("/c/c");
-  interest3->setMaxSuffixComponents(2);
-  interest3->setChildSelector(1);
-
-  shared_ptr<const Data> found3 = ims.find(*interest3);
-  BOOST_REQUIRE(found3 != nullptr);
-  BOOST_CHECK_EQUAL(found3->getName(), "/c/c/1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ExcludeSelector, T, InMemoryStorages)
-{
-  T ims;
-
-  shared_ptr<Data> data = makeData("/a");
-  ims.insert(*data);
-
-  shared_ptr<Data> data2 = makeData("/b");
-  ims.insert(*data2);
-
-  shared_ptr<Data> data3 = makeData("/c/a");
-  ims.insert(*data3);
-
-  shared_ptr<Data> data4 = makeData("/d");
-  ims.insert(*data4);
-
-  shared_ptr<Data> data5 = makeData("/c/c");
-  ims.insert(*data5);
-
-  shared_ptr<Data> data6 = makeData("/c/f");
-  ims.insert(*data6);
-
-  shared_ptr<Data> data7 = makeData("/c/n");
-  ims.insert(*data7);
-
-  shared_ptr<Interest> interest = makeInterest("/c", true);
-  interest->setChildSelector(1);
-  Exclude e;
-  e.excludeOne(Name::Component("n"));
-  interest->setExclude(e);
-
-  shared_ptr<const Data> found = ims.find(*interest);
-  BOOST_REQUIRE(found != nullptr);
-  BOOST_CHECK_EQUAL(found->getName(), "/c/f");
-
-  shared_ptr<Interest> interest2 = makeInterest("/c", true);
-  interest2->setChildSelector(0);
-  Exclude e2;
-  e2.excludeOne(Name::Component("a"));
-  interest2->setExclude(e2);
-
-  shared_ptr<const Data> found2 = ims.find(*interest2);
-  BOOST_REQUIRE(found2 != nullptr);
-  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
-
-  shared_ptr<Interest> interest3 = makeInterest("/c", true);
-  interest3->setChildSelector(0);
-  Exclude e3;
-  e3.excludeOne(Name::Component("c"));
-  interest3->setExclude(e3);
-
-  shared_ptr<const Data> found3 = ims.find(*interest3);
-  BOOST_REQUIRE(found3 != nullptr);
-  BOOST_CHECK_EQUAL(found3->getName(), "/c/a");
-}
-
 using InMemoryStoragesLimited = boost::mpl::vector<InMemoryStorageFifo,
                                                    InMemoryStorageLfu,
                                                    InMemoryStorageLru>;
@@ -705,13 +455,17 @@
 
   Name
   insert(uint32_t id, const Name& name,
+         const std::function<void(Data&)>& modifyData = nullptr,
          const time::milliseconds& freshWindow = InMemoryStorage::INFINITE_WINDOW)
   {
-    shared_ptr<Data> data = makeData(name);
-    data->setFreshnessPeriod(99999_ms);
+    auto data = makeData(name);
     data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
-    signData(data);
 
+    if (modifyData != nullptr) {
+      modifyData(*data);
+    }
+
+    data->wireEncode();
     m_ims.insert(*data, freshWindow);
 
     return data->getFullName();
@@ -720,7 +474,7 @@
   Interest&
   startInterest(const Name& name)
   {
-    m_interest = makeInterest(name, true);
+    m_interest = makeInterest(name, false);
     return *m_interest;
   }
 
@@ -747,38 +501,35 @@
 
 BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
 
-BOOST_AUTO_TEST_CASE(EmptyDataName)
-{
-  insert(1, "ndn:/");
-
-  startInterest("ndn:/");
-  BOOST_CHECK_EQUAL(find(), 1);
-}
-
-BOOST_AUTO_TEST_CASE(EmptyInterestName)
-{
-  insert(1, "ndn:/A");
-
-  startInterest("ndn:/");
-  BOOST_CHECK_EQUAL(find(), 1);
-}
-
 BOOST_AUTO_TEST_CASE(ExactName)
 {
-  insert(1, "ndn:/");
-  insert(2, "ndn:/A");
-  insert(3, "ndn:/A/B");
-  insert(4, "ndn:/A/C");
-  insert(5, "ndn:/D");
+  insert(1, "/");
+  insert(2, "/A");
+  insert(3, "/A/B");
+  insert(4, "/A/C");
+  insert(5, "/D");
 
-  startInterest("ndn:/A");
+  startInterest("/A");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(ExactName_CanBePrefix)
+{
+  insert(1, "/");
+  insert(2, "/A");
+  insert(3, "/A/B");
+  insert(4, "/A/C");
+  insert(5, "/D");
+
+  startInterest("/A")
+    .setCanBePrefix(true);
   BOOST_CHECK_EQUAL(find(), 2);
 }
 
 BOOST_AUTO_TEST_CASE(FullName)
 {
-  Name n1 = insert(1, "ndn:/A");
-  Name n2 = insert(2, "ndn:/A");
+  Name n1 = insert(1, "/A");
+  Name n2 = insert(2, "/A");
 
   startInterest(n1);
   BOOST_CHECK_EQUAL(find(), 1);
@@ -787,266 +538,71 @@
   BOOST_CHECK_EQUAL(find(), 2);
 }
 
-BOOST_AUTO_TEST_CASE(Leftmost)
+BOOST_AUTO_TEST_CASE(FullName_EmptyDataName)
 {
-  insert(1, "ndn:/A");
-  insert(2, "ndn:/B/p/1");
-  insert(3, "ndn:/B/p/2");
-  insert(4, "ndn:/B/q/1");
-  insert(5, "ndn:/B/q/2");
-  insert(6, "ndn:/C");
+  Name n1 = insert(1, "/");
+  Name n2 = insert(2, "/");
 
-  startInterest("ndn:/B");
+  startInterest(n1);
+  BOOST_CHECK_EQUAL(find(), 1);
+
+  startInterest(n2);
   BOOST_CHECK_EQUAL(find(), 2);
 }
 
-BOOST_AUTO_TEST_CASE(Rightmost)
+BOOST_AUTO_TEST_CASE(PrefixName)
 {
-  insert(1, "ndn:/A");
-  insert(2, "ndn:/B/p/1");
-  insert(3, "ndn:/B/p/2");
-  insert(4, "ndn:/B/q/1");
-  insert(5, "ndn:/B/q/2");
-  insert(6, "ndn:/C");
+  insert(1, "/A");
+  insert(2, "/B/p/1");
+  insert(3, "/B/p/2");
+  insert(4, "/B/q/1");
+  insert(5, "/B/q/2");
+  insert(6, "/C");
 
-  startInterest("ndn:/B")
-    .setChildSelector(1);
-  BOOST_CHECK_EQUAL(find(), 4);
+  startInterest("/B")
+    .setCanBePrefix(true);
+  BOOST_CHECK_EQUAL(find(), 2);
 }
 
-BOOST_AUTO_TEST_CASE(MinSuffixComponents)
+BOOST_AUTO_TEST_CASE(PrefixName_NoCanBePrefix)
 {
-  insert(1, "ndn:/");
-  insert(2, "ndn:/A");
-  insert(3, "ndn:/B/1");
-  insert(4, "ndn:/C/1/2");
-  insert(5, "ndn:/D/1/2/3");
-  insert(6, "ndn:/E/1/2/3/4");
+  insert(1, "/B/p/1");
 
-  startInterest("ndn:/")
-    .setMinSuffixComponents(0);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(1);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(2);
-  BOOST_CHECK_EQUAL(find(), 2);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(3);
-  BOOST_CHECK_EQUAL(find(), 3);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(4);
-  BOOST_CHECK_EQUAL(find(), 4);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(5);
-  BOOST_CHECK_EQUAL(find(), 5);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(6);
-  BOOST_CHECK_EQUAL(find(), 6);
-
-  startInterest("ndn:/")
-    .setMinSuffixComponents(7);
+  startInterest("/B");
   BOOST_CHECK_EQUAL(find(), 0);
 }
 
-BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
-{
-  insert(1, "ndn:/");
-  insert(2, "ndn:/A");
-  insert(3, "ndn:/B/2");
-  insert(4, "ndn:/C/2/3");
-  insert(5, "ndn:/D/2/3/4");
-  insert(6, "ndn:/E/2/3/4/5");
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(0);
-  BOOST_CHECK_EQUAL(find(), 0);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(1);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(2);
-  BOOST_CHECK_EQUAL(find(), 2);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(3);
-  BOOST_CHECK_EQUAL(find(), 3);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(4);
-  BOOST_CHECK_EQUAL(find(), 4);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(5);
-  BOOST_CHECK_EQUAL(find(), 5);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(6);
-  BOOST_CHECK_EQUAL(find(), 6);
-
-  startInterest("ndn:/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(7);
-  BOOST_CHECK_EQUAL(find(), 6);
-}
-
-BOOST_AUTO_TEST_CASE(DigestOrder)
-{
-  insert(1, "ndn:/A");
-  insert(2, "ndn:/A");
-  // We don't know which comes first, but there must be some order
-
-  startInterest("ndn:/A")
-    .setChildSelector(0);
-  uint32_t leftmost = find();
-
-  startInterest("ndn:/A")
-    .setChildSelector(1);
-  uint32_t rightmost = find();
-
-  BOOST_CHECK_NE(leftmost, rightmost);
-}
-
-BOOST_AUTO_TEST_CASE(DigestExclude)
-{
-  insert(1, "ndn:/A");
-  Name n2 = insert(2, "ndn:/A");
-  insert(3, "ndn:/A/B");
-
-  uint8_t digest00[util::Sha256::DIGEST_SIZE];
-  std::fill_n(digest00, sizeof(digest00), 0x00);
-  uint8_t digestFF[util::Sha256::DIGEST_SIZE];
-  std::fill_n(digestFF, sizeof(digestFF), 0xFF);
-
-  Exclude excludeDigest;
-  excludeDigest.excludeRange(
-    name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
-    name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));
-
-  startInterest("ndn:/A")
-    .setChildSelector(0)
-    .setExclude(excludeDigest);
-  BOOST_CHECK_EQUAL(find(), 3);
-
-  startInterest("ndn:/A")
-    .setChildSelector(1)
-    .setExclude(excludeDigest);
-  BOOST_CHECK_EQUAL(find(), 3);
-
-  Exclude excludeGeneric;
-  excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));
-
-  startInterest("ndn:/A")
-    .setChildSelector(0)
-    .setExclude(excludeGeneric);
-  int found1 = find();
-  BOOST_CHECK(found1 == 1 || found1 == 2);
-
-  startInterest("ndn:/A")
-    .setChildSelector(1)
-    .setExclude(excludeGeneric);
-  int found2 = find();
-  BOOST_CHECK(found2 == 1 || found2 == 2);
-
-  Exclude exclude2 = excludeGeneric;
-  exclude2.excludeOne(n2.get(-1));
-
-  startInterest("ndn:/A")
-    .setChildSelector(0)
-    .setExclude(exclude2);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/A")
-    .setChildSelector(1)
-    .setExclude(exclude2);
-  BOOST_CHECK_EQUAL(find(), 1);
-}
-
 BOOST_AUTO_TEST_CASE(MustBeFresh)
 {
-  Name data1Name = insert(1, "ndn:/A/1", 500_ms);
-  insert(2, "ndn:/A/2", 2500_ms);
-  insert(3, "ndn:/A/3", 3500_ms);
-  insert(4, "ndn:/A/4", 1500_ms);
+  insert(1, "/A/1"); // omitted FreshnessPeriod means FreshnessPeriod = 0 ms
+  insert(2, "/A/2", [] (Data& data) { data.setFreshnessPeriod(0_s); });
+  insert(3, "/A/3", [] (Data& data) { data.setFreshnessPeriod(1_s); }, 1_s);
+  insert(4, "/A/4", [] (Data& data) { data.setFreshnessPeriod(1_h); }, 1_h);
 
-  // @0s, all Data are fresh
-  startInterest("ndn:/A/1")
+  // lookup at exact same moment as insertion is not tested because this won't happen in reality
+
+  advanceClocks(500_ms); // @500ms
+  startInterest("/A")
+    .setCanBePrefix(true)
     .setMustBeFresh(true);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/A/1")
-    .setMustBeFresh(false);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(0);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(1);
-  BOOST_CHECK_EQUAL(find(), 4);
-
-  advanceClocks(1000_ms);
-  // @1s, /A/1 is stale
-  startInterest("ndn:/A/1")
-    .setMustBeFresh(true);
-  BOOST_CHECK_EQUAL(find(), 0);
-  startInterest("ndn:/A/1")
-    .setMustBeFresh(false);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  // MustBeFresh is ignored when full Name is specified
-  startInterest(data1Name)
-    .setMustBeFresh(true);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(0);
-  BOOST_CHECK_EQUAL(find(), 2);
-  startInterest("ndn:/A")
-    .setMustBeFresh(false)
-    .setChildSelector(0);
-  BOOST_CHECK_EQUAL(find(), 1);
-
-  advanceClocks(1000_ms);
-  // @2s, /A/1 and /A/4 are stale
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(1);
   BOOST_CHECK_EQUAL(find(), 3);
-  startInterest("ndn:/A")
-    .setMustBeFresh(false)
-    .setChildSelector(1);
+
+  advanceClocks(1500_ms); // @2s
+  startInterest("/A")
+    .setCanBePrefix(true)
+    .setMustBeFresh(true);
   BOOST_CHECK_EQUAL(find(), 4);
 
-  advanceClocks(2000_ms);
-  // @4s, all Data are stale
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(0);
-  BOOST_CHECK_EQUAL(find(), 0);
-  startInterest("ndn:/A")
-    .setMustBeFresh(true)
-    .setChildSelector(1);
+  advanceClocks(3500_s); // @3502s
+  startInterest("/A")
+    .setCanBePrefix(true)
+    .setMustBeFresh(true);
+  BOOST_CHECK_EQUAL(find(), 4);
+
+  advanceClocks(3500_s); // @7002s
+  startInterest("/A")
+    .setCanBePrefix(true)
+    .setMustBeFresh(true);
   BOOST_CHECK_EQUAL(find(), 0);
 }
 
diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp
index 4523d07..9c4b55d 100644
--- a/tests/unit/interest.t.cpp
+++ b/tests/unit/interest.t.cpp
@@ -25,7 +25,7 @@
 #include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
 
 #include "tests/boost-test.hpp"
-#include "tests/identity-management-fixture.hpp"
+#include "tests/make-interest-data.hpp"
 
 namespace ndn {
 namespace tests {
@@ -357,98 +357,44 @@
 
 BOOST_AUTO_TEST_CASE(MatchesData)
 {
-  Interest interest;
-  interest.setName("ndn:/A")
-          .setMinSuffixComponents(2)
-          .setMaxSuffixComponents(2)
-          .setPublisherPublicKeyLocator(KeyLocator("ndn:/B"))
-          .setExclude(Exclude().excludeAfter(name::Component("J")));
+  auto interest = makeInterest("/A");
 
-  Data data("ndn:/A/D");
-  SignatureSha256WithRsa signature(KeyLocator("ndn:/B"));
-  signature.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
-  data.setSignature(signature);
-  data.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data), true);
+  auto data = makeData("/A");
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), true);
 
-  Data data1 = data;
-  data1.setName("ndn:/A"); // violates MinSuffixComponents
-  data1.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data1), false);
+  data->setName("/A/D");
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), false); // violates CanBePrefix
 
-  Interest interest1 = interest;
-  interest1.setMinSuffixComponents(1);
-  BOOST_CHECK_EQUAL(interest1.matchesData(data1), true);
+  interest->setCanBePrefix(true);
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), true);
 
-  Data data2 = data;
-  data2.setName("ndn:/A/E/F"); // violates MaxSuffixComponents
-  data2.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data2), false);
+  interest->setMustBeFresh(true);
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), false); // violates MustBeFresh
 
-  Interest interest2 = interest;
-  interest2.setMaxSuffixComponents(3);
-  BOOST_CHECK_EQUAL(interest2.matchesData(data2), true);
+  data->setFreshnessPeriod(1_s);
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), true);
 
-  Data data3 = data;
-  SignatureSha256WithRsa signature3(KeyLocator("ndn:/G")); // violates PublisherPublicKeyLocator
-  signature3.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
-  data3.setSignature(signature3);
-  data3.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data3), false);
+  data->setName("/H/I");
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), false); // Name does not match
 
-  Interest interest3 = interest;
-  interest3.setPublisherPublicKeyLocator(KeyLocator("ndn:/G"));
-  BOOST_CHECK_EQUAL(interest3.matchesData(data3), true);
+  data->wireEncode();
+  interest = makeInterest(data->getFullName());
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), true);
 
-  Data data4 = data;
-  DigestSha256 signature4; // violates PublisherPublicKeyLocator
-  signature4.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
-  data4.setSignature(signature4);
-  data4.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data4), false);
-
-  Interest interest4 = interest;
-  interest4.setPublisherPublicKeyLocator(KeyLocator());
-  BOOST_CHECK_EQUAL(interest4.matchesData(data4), true);
-
-  Data data5 = data;
-  data5.setName("ndn:/A/J"); // violates Exclude
-  data5.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data5), false);
-
-  Interest interest5 = interest;
-  interest5.setExclude(Exclude().excludeAfter(name::Component("K")));
-  BOOST_CHECK_EQUAL(interest5.matchesData(data5), true);
-
-  Data data6 = data;
-  data6.setName("ndn:/H/I"); // violates Name
-  data6.wireEncode();
-  BOOST_CHECK_EQUAL(interest.matchesData(data6), false);
-
-  Data data7 = data;
-  data7.setName("ndn:/A/B");
-  data7.wireEncode();
-
-  Interest interest7("/A/B/sha256digest=54008e240a7eea2714a161dfddf0dd6ced223b3856e9da96792151e180f3b128");
-  BOOST_CHECK_EQUAL(interest7.matchesData(data7), true);
-
-  Interest interest7b("/A/B/sha256digest=0000000000000000000000000000000000000000000000000000000000000000");
-  BOOST_CHECK_EQUAL(interest7b.matchesData(data7), false); // violates implicit digest
+  setNameComponent(*interest, -1, Name("/sha256digest=000000000000000000000000"
+                                       "0000000000000000000000000000000000000000").at(0));
+  BOOST_CHECK_EQUAL(interest->matchesData(*data), false); // violates implicit digest
 }
 
 BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(MatchesInterest, 1)
 BOOST_AUTO_TEST_CASE(MatchesInterest)
 {
-  Interest interest;
-  interest
-    .setName("/A")
-    .setMinSuffixComponents(2)
-    .setMaxSuffixComponents(2)
-    .setPublisherPublicKeyLocator(KeyLocator("/B"))
-    .setExclude(Exclude().excludeAfter(name::Component("J")))
-    .setNonce(10)
-    .setInterestLifetime(5_s)
-    .setForwardingHint({{1, "/H"}});
+  Interest interest("/A");
+  interest.setCanBePrefix(true)
+          .setMustBeFresh(true)
+          .setForwardingHint({{1, "/H"}})
+          .setNonce(2228)
+          .setInterestLifetime(5_s);
 
   Interest other;
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), false);
@@ -456,16 +402,19 @@
   other.setName(interest.getName());
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), false);
 
-  other.setSelectors(interest.getSelectors());
+  other.setCanBePrefix(interest.getCanBePrefix());
+  BOOST_CHECK_EQUAL(interest.matchesInterest(other), false);
+
+  other.setMustBeFresh(interest.getMustBeFresh());
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), false); // will match until #3162 implemented
 
-  other.setForwardingHint({{1, "/H"}});
+  other.setForwardingHint(interest.getForwardingHint());
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), true);
 
-  other.setNonce(200);
+  other.setNonce(9336);
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), true);
 
-  other.setInterestLifetime(5_h);
+  other.setInterestLifetime(3_s);
   BOOST_CHECK_EQUAL(interest.matchesInterest(other), true);
 }
 
diff --git a/tests/unit/mgmt/nfd/status-dataset.t.cpp b/tests/unit/mgmt/nfd/status-dataset.t.cpp
index 1af98e9..aac874b 100644
--- a/tests/unit/mgmt/nfd/status-dataset.t.cpp
+++ b/tests/unit/mgmt/nfd/status-dataset.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).
  *
@@ -99,6 +99,7 @@
     }
 
     auto data = make_shared<Data>(name);
+    data->setFreshnessPeriod(1_s);
     data->setFinalBlock(name[-1]);
     return data;
   }
@@ -132,7 +133,9 @@
     datasetFailCallback);
   this->advanceClocks(500_ms);
 
-  face.receive(*makeData("/localhost/nfd/faces/list/%FD%00"));
+  auto data = makeData("/localhost/nfd/faces/list/%FD%00");
+  data->setFreshnessPeriod(1_s);
+  face.receive(*data);
   this->advanceClocks(500_ms);
 
   BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
diff --git a/tests/unit/security/v2/certificate-cache.t.cpp b/tests/unit/security/v2/certificate-cache.t.cpp
index faeb667..8062c18 100644
--- a/tests/unit/security/v2/certificate-cache.t.cpp
+++ b/tests/unit/security/v2/certificate-cache.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).
  *
@@ -81,21 +81,6 @@
 
   advanceClocks(12_s);
   BOOST_CHECK(certCache.find(Interest(cert.getIdentity())) == nullptr);
-
-  Certificate cert3 = addCertificate(identity.getDefaultKey(), "3");
-  Certificate cert4 = addCertificate(identity.getDefaultKey(), "4");
-  Certificate cert5 = addCertificate(identity.getDefaultKey(), "5");
-
-  certCache.insert(cert3);
-  certCache.insert(cert4);
-  certCache.insert(cert5);
-
-  Interest interest4(cert3.getKeyName());
-  interest4.setExclude(Exclude().excludeOne(cert3.getName().at(Certificate::ISSUER_ID_OFFSET)));
-  BOOST_CHECK(certCache.find(interest4) != nullptr);
-  BOOST_CHECK_NE(certCache.find(interest4)->getName(), cert3.getName());
-
-  // TODO cover more cases with different interests
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestCertificateCache
diff --git a/tests/unit/security/v2/trust-anchor-container.t.cpp b/tests/unit/security/v2/trust-anchor-container.t.cpp
index 6430db8..8ed4cec 100644
--- a/tests/unit/security/v2/trust-anchor-container.t.cpp
+++ b/tests/unit/security/v2/trust-anchor-container.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).
  *
@@ -180,12 +180,6 @@
   BOOST_REQUIRE(foundCert != nullptr);
   BOOST_CHECK(interest3.getName().isPrefixOf(foundCert->getName()));
   BOOST_CHECK_EQUAL(foundCert->getName(), cert3.getName());
-
-  interest3.setExclude(Exclude().excludeOne(cert3.getName().at(Certificate::ISSUER_ID_OFFSET)));
-  foundCert = anchorContainer.find(interest3);
-  BOOST_REQUIRE(foundCert != nullptr);
-  BOOST_CHECK(interest3.getName().isPrefixOf(foundCert->getName()));
-  BOOST_CHECK_NE(foundCert->getName(), cert3.getName());
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestTrustAnchorContainer
diff --git a/tests/unit/util/notification-subscriber.t.cpp b/tests/unit/util/notification-subscriber.t.cpp
index 820532d..e3b7aa9 100644
--- a/tests/unit/util/notification-subscriber.t.cpp
+++ b/tests/unit/util/notification-subscriber.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018 Regents of the University of California,
+ * Copyright (c) 2014-2019 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -287,6 +287,7 @@
   Name wrongName = streamPrefix;
   wrongName.append("%07%07");
   Data wrongData(wrongName);
+  wrongData.setFreshnessPeriod(1_s);
   m_keyChain.sign(wrongData);
   subscriberFace.receive(wrongData);
   subscriberFace.sentInterests.clear();
diff --git a/tests/unit/util/segment-fetcher.t.cpp b/tests/unit/util/segment-fetcher.t.cpp
index f870030..9f65f49 100644
--- a/tests/unit/util/segment-fetcher.t.cpp
+++ b/tests/unit/util/segment-fetcher.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).
  *
@@ -52,6 +52,7 @@
     const uint8_t buffer[] = "Hello, world!";
 
     auto data = make_shared<Data>(Name(baseName).appendSegment(segment));
+    data->setFreshnessPeriod(1_s);
     data->setContent(buffer, sizeof(buffer));
     if (isFinal) {
       data->setFinalBlock(data->getName()[-1]);
@@ -525,6 +526,7 @@
 
   const uint8_t buffer[] = "Hello, world!";
   auto data = makeData("/hello/world/version0/no-segment");
+  data->setFreshnessPeriod(1_s);
   data->setContent(buffer, sizeof(buffer));
 
   face.receive(*data);