forked from lix-project/lix
add trace test; error formatting refinements
This commit is contained in:
parent
6359d71d6b
commit
9c0e1fd4f1
|
@ -185,6 +185,31 @@ void printCodeLines(std::ostream &out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printAtPos(const string &prefix, const ErrPos &pos, std::ostream &out)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
switch (pos.origin) {
|
||||||
|
case foFile: {
|
||||||
|
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(pos) <<
|
||||||
|
ANSI_BLUE << " in file: " << ANSI_NORMAL << pos.file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case foString: {
|
||||||
|
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(pos) <<
|
||||||
|
ANSI_BLUE << " from command line argument" << ANSI_NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case foStdin: {
|
||||||
|
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(pos) <<
|
||||||
|
ANSI_BLUE << " from stdin" << ANSI_NORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw Error("invalid FileOrigin in errPos");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo)
|
std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo)
|
||||||
{
|
{
|
||||||
auto errwidth = std::max<size_t>(getWindowSize().second, 20);
|
auto errwidth = std::max<size_t>(getWindowSize().second, 20);
|
||||||
|
@ -240,8 +265,12 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length();
|
auto ndl = prefix.length()
|
||||||
auto dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl;
|
+ filterANSIEscapes(levelString, true).length()
|
||||||
|
+ 7
|
||||||
|
+ einfo.name.length()
|
||||||
|
+ einfo.programName.value_or("").length();
|
||||||
|
auto dashwidth = std::max<int>(errwidth - ndl, 3);
|
||||||
|
|
||||||
std::string dashes(dashwidth, '-');
|
std::string dashes(dashwidth, '-');
|
||||||
|
|
||||||
|
@ -262,29 +291,8 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo)
|
||||||
|
|
||||||
bool nl = false; // intersperse newline between sections.
|
bool nl = false; // intersperse newline between sections.
|
||||||
if (einfo.errPos.has_value()) {
|
if (einfo.errPos.has_value()) {
|
||||||
switch (einfo.errPos->origin) {
|
|
||||||
case foFile: {
|
|
||||||
out << prefix << std::endl;
|
out << prefix << std::endl;
|
||||||
auto &pos = *einfo.errPos;
|
printAtPos(prefix, *einfo.errPos, out);
|
||||||
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(pos) <<
|
|
||||||
ANSI_BLUE << " in file: " << ANSI_NORMAL << pos.file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case foString: {
|
|
||||||
out << prefix << std::endl;
|
|
||||||
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(*einfo.errPos) <<
|
|
||||||
ANSI_BLUE << " from command line argument" << ANSI_NORMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case foStdin: {
|
|
||||||
out << prefix << std::endl;
|
|
||||||
out << prefix << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(*einfo.errPos) <<
|
|
||||||
ANSI_BLUE << " from stdin" << ANSI_NORMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw Error("invalid FileOrigin in errPos");
|
|
||||||
}
|
|
||||||
nl = true;
|
nl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,13 +328,33 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo)
|
||||||
for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter)
|
for (auto iter = einfo.traces.rbegin(); iter != einfo.traces.rend(); ++iter)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto pos = *iter->pos;
|
|
||||||
if (nl)
|
if (nl)
|
||||||
out << std::endl << prefix;
|
out << std::endl << prefix;
|
||||||
out << std::endl << prefix;
|
|
||||||
|
const string tracetitle(" show-trace output ");
|
||||||
|
|
||||||
|
int fill = errwidth - tracetitle.length();
|
||||||
|
int lw = 0;
|
||||||
|
int rw = 0;
|
||||||
|
const int min_dashes = 3;
|
||||||
|
if (fill > min_dashes * 2) {
|
||||||
|
if (fill % 2 != 0) {
|
||||||
|
lw = fill / 2;
|
||||||
|
rw = lw + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lw = rw = fill / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lw = rw = min_dashes;
|
||||||
|
|
||||||
|
out << ANSI_BLUE << std::string(lw, '-') << tracetitle << std::string(rw, '-') << std::endl << prefix;
|
||||||
out << iter->hint.str() << std::endl;
|
out << iter->hint.str() << std::endl;
|
||||||
out << ANSI_BLUE << "at: " << ANSI_YELLOW << showErrPos(pos) <<
|
|
||||||
ANSI_BLUE << " in file: " << ANSI_NORMAL << pos.file << std::endl;
|
auto pos = *iter->pos;
|
||||||
|
printAtPos(prefix, pos, out);
|
||||||
nl = true;
|
nl = true;
|
||||||
auto loc = getCodeLines(pos);
|
auto loc = getCodeLines(pos);
|
||||||
if (loc.has_value())
|
if (loc.has_value())
|
||||||
|
|
|
@ -173,6 +173,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseError & addTrace(std::optional<ErrPos> e, hintformat hint);
|
BaseError & addTrace(std::optional<ErrPos> e, hintformat hint);
|
||||||
|
|
||||||
|
bool hasTrace() const { return !err.traces.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MakeError(newClass, superClass) \
|
#define MakeError(newClass, superClass) \
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace nix {
|
||||||
"this is the problem line of code\n"
|
"this is the problem line of code\n"
|
||||||
"next line of code\n";
|
"next line of code\n";
|
||||||
const char *one_liner =
|
const char *one_liner =
|
||||||
"this is the problem line of code";
|
"this is the other problem line of code";
|
||||||
|
|
||||||
TEST(logEI, catpuresBasicProperties) {
|
TEST(logEI, catpuresBasicProperties) {
|
||||||
|
|
||||||
|
@ -245,6 +245,33 @@ namespace nix {
|
||||||
ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from stdin\x1B[0m\n\nwarning description\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
|
ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from stdin\x1B[0m\n\nwarning description\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* traces
|
||||||
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TEST(addTrace, showTracesWithShowTrace) {
|
||||||
|
SymbolTable testTable;
|
||||||
|
auto problem_file = testTable.create(test_file);
|
||||||
|
|
||||||
|
auto oneliner_file = testTable.create(one_liner);
|
||||||
|
|
||||||
|
auto e = AssertionError(ErrorInfo {
|
||||||
|
.name = "wat",
|
||||||
|
.description = "a well-known problem occurred",
|
||||||
|
.hint = hintfmt("it has been %1% days since our last error", "zero"),
|
||||||
|
.errPos = Pos(foString, problem_file, 2, 13),
|
||||||
|
});
|
||||||
|
|
||||||
|
e.addTrace(Pos(foStdin, oneliner_file, 1, 19), "while trying to compute %1%", 42);
|
||||||
|
|
||||||
|
testing::internal::CaptureStderr();
|
||||||
|
|
||||||
|
logError(e.info());
|
||||||
|
|
||||||
|
auto str = testing::internal::GetCapturedStderr();
|
||||||
|
ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- AssertionError --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from command line argument\x1B[0m\n\na well-known problem occurred\n\n 1| previous line of code\n 2| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 3| next line of code\n\nit has been \x1B[33;1mzero\x1B[0m days since our last error\n\x1B[34;1m--- show-trace output ---\nwhile trying to compute \x1B[33;1m42\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(1:19)\x1B[34;1m from stdin\x1B[0m\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* hintfmt
|
* hintfmt
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue