forked from pytorch/glow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Testing library with a StrCheck class.
The Testing library holds utility classes that are only used for unit testing. The StrCheck class provides similar functionality to LLVM's FileCheck utility, but in a unit test context.
- Loading branch information
Showing
6 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* Copyright (c) 2018-present, Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef GLOW_TESTING_STRCHECK_H | ||
#define GLOW_TESTING_STRCHECK_H | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
// Forward decls from googletest. | ||
namespace testing { | ||
class AssertionResult; | ||
} | ||
|
||
namespace glow { | ||
|
||
/// Helper class for finding ordered substrings in a larger string. | ||
/// | ||
/// The StrCheck class is intended to be used in googletest unit tests: | ||
/// | ||
/// EXPECT_TRUE(StrCheck(asm).check("foo").no("baz").sameln("arg=7")); | ||
/// | ||
/// A typical use is to search for expected instruction patterns in | ||
/// disassembled code generated for a test case. | ||
class StrCheck { | ||
public: | ||
StrCheck(llvm::StringRef input) : input_(input) {} | ||
|
||
/// Check that `needle` appears in the input at a point after the previous | ||
/// match. | ||
StrCheck &check(llvm::StringRef needle); | ||
|
||
/// Check that `needle` appears on the same line as the previous match. (And | ||
/// following the previous match). | ||
StrCheck &sameln(llvm::StringRef needle); | ||
|
||
/// Check that `needle` appears on the next line after the previous match. | ||
StrCheck &nextln(llvm::StringRef needle); | ||
|
||
/// Check that no instances of `needle` appear before the next positive match. | ||
StrCheck &no(llvm::StringRef needle); | ||
|
||
private: | ||
const std::string input_; | ||
size_t pos_ = 0; | ||
std::string errors_; | ||
std::vector<std::string> nos_; | ||
|
||
size_t findEol(size_t p) const; | ||
size_t findEol() const; | ||
StrCheck &match(size_t pos, size_t size); | ||
StrCheck &fail(const char *msg, llvm::StringRef needle); | ||
|
||
public: | ||
// Allow implicit conversion to allow a StrCheck to be used in EXPECT_TRUE(). | ||
operator testing::AssertionResult(); | ||
operator bool(); | ||
}; | ||
|
||
} // namespace glow | ||
|
||
#endif // GLOW_TESTING_STRCHECK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
add_library(Testing | ||
StrCheck.cpp) | ||
target_link_libraries(Testing | ||
PRIVATE | ||
gtest) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* Copyright (c) 2018-present, Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "glow/Testing/StrCheck.h" | ||
#include "gtest/gtest.h" | ||
|
||
using glow::StrCheck; | ||
|
||
StrCheck &StrCheck::check(llvm::StringRef needle) { | ||
size_t found = input_.find(needle, pos_); | ||
return found != std::string::npos ? match(found, needle.size()) | ||
: fail("not found: check", needle); | ||
} | ||
|
||
StrCheck &StrCheck::sameln(llvm::StringRef needle) { | ||
size_t found = input_.find(needle, pos_); | ||
return found < findEol() ? match(found, needle.size()) | ||
: fail("not found: sameln", needle); | ||
} | ||
|
||
StrCheck &StrCheck::nextln(llvm::StringRef needle) { | ||
size_t eol = findEol(); | ||
size_t found = input_.find(needle, eol); | ||
return found < findEol(eol) ? match(found, needle.size()) | ||
: fail("not found: nextln", needle); | ||
} | ||
|
||
StrCheck &StrCheck::no(llvm::StringRef needle) { | ||
nos_.push_back(needle); | ||
return *this; | ||
} | ||
|
||
StrCheck &StrCheck::match(size_t at, size_t size) { | ||
// We have a positive match. Check if any of the no()'s appeared between | ||
// `pos_` and `at`. | ||
for (const auto &no : nos_) { | ||
if (pos_ + no.size() > at) | ||
continue; | ||
if (input_.find(no, pos_) <= at - no.size()) | ||
fail("matched not", no); | ||
} | ||
nos_.clear(); | ||
|
||
pos_ = at + size; | ||
return *this; | ||
} | ||
|
||
StrCheck &StrCheck::fail(const char *msg, llvm::StringRef needle) { | ||
errors_ += ">>> "; | ||
errors_ += msg; | ||
errors_ += "(\""; | ||
errors_ += needle; | ||
errors_ += "\")\n"; | ||
return *this; | ||
} | ||
|
||
size_t StrCheck::findEol(size_t p) const { | ||
size_t eol = input_.find('\n', p); | ||
return eol == std::string::npos ? input_.size() : eol + 1; | ||
} | ||
|
||
size_t StrCheck::findEol() const { return findEol(pos_); } | ||
|
||
StrCheck::operator testing::AssertionResult() { | ||
if (*this) | ||
return testing::AssertionSuccess(); | ||
else | ||
return testing::AssertionFailure() << "Failed StrCheck in:\n" | ||
<< input_ << '\n' | ||
<< errors_; | ||
} | ||
|
||
StrCheck::operator bool() { | ||
// Match up to the end of the input to make sure we catch any trailing no()'s. | ||
match(input_.size(), 0); | ||
return errors_.empty(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* Copyright (c) 2018-present, Facebook, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "glow/Testing/StrCheck.h" | ||
#include "gtest/gtest.h" | ||
|
||
using glow::StrCheck; | ||
|
||
TEST(StrCheck, check) { | ||
EXPECT_TRUE(StrCheck("foo bar").check("oo").check("bar")); | ||
EXPECT_FALSE(StrCheck("foo bar").check("foo").check("oo")); | ||
} | ||
|
||
TEST(StrCheck, sameln) { | ||
EXPECT_TRUE(StrCheck("foo bar").sameln("foo").sameln("bar")); | ||
EXPECT_FALSE(StrCheck("foo\nbar").sameln("foo").sameln("bar")); | ||
} | ||
|
||
TEST(StrCheck, nextln) { | ||
EXPECT_FALSE(StrCheck("foo bar").check("foo").nextln("bar")); | ||
EXPECT_TRUE(StrCheck("foo\nbar").check("foo").nextln("bar")); | ||
EXPECT_FALSE(StrCheck("foo\n\nbar").check("foo").nextln("bar")); | ||
} | ||
|
||
TEST(StrCheck, no) { | ||
EXPECT_TRUE(StrCheck("foo bar").check("foo").no("baz")); | ||
EXPECT_FALSE(StrCheck("foo bar").check("foo").no("bar")); | ||
EXPECT_TRUE(StrCheck("foo bar").no("baz").check("bar")); | ||
EXPECT_FALSE(StrCheck("foo bar").no("foo").check("bar")); | ||
EXPECT_TRUE(StrCheck("foo bar").check("foo").no("o")); | ||
|
||
EXPECT_FALSE(StrCheck("foo bar\nbaz").check("foo").no("bar").nextln("baz")); | ||
} |