#if 0 #include "logging.hh" #include "nixexpr.hh" #include "util.hh" #include #include namespace nix { /* ---------------------------------------------------------------------------- * logEI * --------------------------------------------------------------------------*/ const char *test_file = "previous line of code\n" "this is the problem line of code\n" "next line of code\n"; const char *one_liner = "this is the other problem line of code"; TEST(logEI, catpuresBasicProperties) { MakeError(TestError, Error); ErrorInfo::programName = std::optional("error-unit-test"); try { throw TestError("an error for testing purposes"); } catch (Error &e) { testing::internal::CaptureStderr(); logger->logEI(e.info()); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError --- error-unit-test\x1B[0m\nan error for testing purposes\n"); } } TEST(logEI, jsonOutput) { SymbolTable testTable; auto problem_file = testTable.create("random.nix"); testing::internal::CaptureStderr(); makeJSONLogger(*logger)->logEI({ .name = "error name", .msg = HintFmt("this hint has %1% templated %2%!!", "yellow", "values"), .errPos = Pos(foFile, problem_file, 02, 13) }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "@nix {\"action\":\"msg\",\"column\":13,\"file\":\"random.nix\",\"level\":0,\"line\":2,\"msg\":\"\\u001b[31;1merror:\\u001b[0m\\u001b[34;1m --- error name --- error-unit-test\\u001b[0m\\n\\u001b[34;1mat: \\u001b[33;1m(2:13)\\u001b[34;1m in file: \\u001b[0mrandom.nix\\n\\nerror without any code lines.\\n\\nthis hint has \\u001b[33;1myellow\\u001b[0m templated \\u001b[33;1mvalues\\u001b[0m!!\",\"raw_msg\":\"this hint has \\u001b[33;1myellow\\u001b[0m templated \\u001b[33;1mvalues\\u001b[0m!!\"}\n"); } TEST(logEI, appendingHintsToPreviousError) { MakeError(TestError, Error); ErrorInfo::programName = std::optional("error-unit-test"); try { auto e = Error("initial error"); throw TestError(e.info()); } catch (Error &e) { ErrorInfo ei = e.info(); ei.msg = HintFmt("%s; subsequent error message.", Uncolored(e.info().msg.str())); testing::internal::CaptureStderr(); logger->logEI(ei); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError --- error-unit-test\x1B[0m\ninitial error; subsequent error message.\n"); } } TEST(logEI, picksUpSysErrorExitCode) { MakeError(TestError, Error); ErrorInfo::programName = std::optional("error-unit-test"); try { auto x = readFile(-1); } catch (SysError &e) { testing::internal::CaptureStderr(); logError(e.info()); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError --- error-unit-test\x1B[0m\nstatting file: \x1B[33;1mBad file descriptor\x1B[0m\n"); } } TEST(logEI, loggingErrorOnInfoLevel) { testing::internal::CaptureStderr(); logger->logEI({ .level = lvlInfo, .name = "Info name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name --- error-unit-test\x1B[0m\nInfo description\n"); } TEST(logEI, loggingErrorOnTalkativeLevel) { verbosity = lvlTalkative; testing::internal::CaptureStderr(); logger->logEI({ .level = lvlTalkative, .name = "Talkative name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[32;1mtalk:\x1B[0m\x1B[34;1m --- Talkative name --- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnChattyLevel) { verbosity = lvlChatty; testing::internal::CaptureStderr(); logger->logEI({ .level = lvlChatty, .name = "Chatty name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[32;1mchat:\x1B[0m\x1B[34;1m --- Chatty name --- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnDebugLevel) { verbosity = lvlDebug; testing::internal::CaptureStderr(); logger->logEI({ .level = lvlDebug, .name = "Debug name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[33;1mdebug:\x1B[0m\x1B[34;1m --- Debug name --- error-unit-test\x1B[0m\nDebug description\n"); } TEST(logEI, loggingErrorOnVomitLevel) { verbosity = lvlVomit; testing::internal::CaptureStderr(); logger->logEI({ .level = lvlVomit, .name = "Vomit name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[32;1mvomit:\x1B[0m\x1B[34;1m --- Vomit name --- error-unit-test\x1B[0m\nVomit description\n"); } /* ---------------------------------------------------------------------------- * logError * --------------------------------------------------------------------------*/ TEST(logError, logErrorWithoutHintOrCode) { testing::internal::CaptureStderr(); logError({ .name = "name", }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name --- error-unit-test\x1B[0m\nerror description\n"); } TEST(logError, logErrorWithPreviousAndNextLinesOfCode) { SymbolTable testTable; auto problem_file = testTable.create(test_file); testing::internal::CaptureStderr(); logError({ .name = "error name", .msg = HintFmt("this hint has %1% templated %2%!!", "yellow", "values"), .errPos = Pos(foString, problem_file, 02, 13), }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m from string\x1B[0m\n\nerror with code lines\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"); } TEST(logError, logErrorWithInvalidFile) { SymbolTable testTable; auto problem_file = testTable.create("invalid filename"); testing::internal::CaptureStderr(); logError({ .name = "error name", .msg = HintFmt("this hint has %1% templated %2%!!", "yellow", "values"), .errPos = Pos(foFile, problem_file, 02, 13) }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(2:13)\x1B[34;1m in file: \x1B[0minvalid filename\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); } TEST(logError, logErrorWithOnlyHintAndName) { testing::internal::CaptureStderr(); logError({ .name = "error name", .msg = HintFmt("hint %1%", "only"), }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\nhint \x1B[33;1monly\x1B[0m\n"); } /* ---------------------------------------------------------------------------- * logWarning * --------------------------------------------------------------------------*/ TEST(logWarning, logWarningWithNameDescriptionAndHint) { testing::internal::CaptureStderr(); logWarning({ .name = "name", .msg = HintFmt("there was a %1%", "warning"), }); auto str = testing::internal::GetCapturedStderr(); ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --- error-unit-test\x1B[0m\nwarning description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n"); } TEST(logWarning, logWarningWithFileLineNumAndCode) { SymbolTable testTable; auto problem_file = testTable.create(test_file); testing::internal::CaptureStderr(); logWarning({ .name = "warning name", .msg = HintFmt("this hint has %1% templated %2%!!", "yellow", "values"), .errPos = Pos(foStdin, problem_file, 2, 13), }); auto str = testing::internal::GetCapturedStderr(); 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 invalidfilename = testTable.create("invalid filename"); auto e = AssertionError(ErrorInfo { .name = "wat", .msg = 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); e.addTrace(std::nullopt, "while doing something without a %1%", "pos"); e.addTrace(Pos(foFile, invalidfilename, 100, 1), "missing %s", "nix file"); testing::internal::CaptureStderr(); loggerSettings.showTrace.assign(true); 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 string\x1B[0m\n\nshow-traces\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 ----\x1B[0m\n\x1B[34;1mtrace: \x1B[0mwhile 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\n 1| this is the other problem line of code\n | \x1B[31;1m^\x1B[0m\n\n\x1B[34;1mtrace: \x1B[0mwhile doing something without a \x1B[33;1mpos\x1B[0m\n\x1B[34;1mtrace: \x1B[0mmissing \x1B[33;1mnix file\x1B[0m\n\x1B[34;1mat: \x1B[33;1m(100:1)\x1B[34;1m in file: \x1B[0minvalid filename\n"); } TEST(addTrace, hideTracesWithoutShowTrace) { SymbolTable testTable; auto problem_file = testTable.create(test_file); auto oneliner_file = testTable.create(one_liner); auto invalidfilename = testTable.create("invalid filename"); auto e = AssertionError(ErrorInfo { .name = "wat", .msg = 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); e.addTrace(std::nullopt, "while doing something without a %1%", "pos"); e.addTrace(Pos(foFile, invalidfilename, 100, 1), "missing %s", "nix file"); testing::internal::CaptureStderr(); loggerSettings.showTrace.assign(false); 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 string\x1B[0m\n\nhide traces\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"); } /* ---------------------------------------------------------------------------- * HintFmt * --------------------------------------------------------------------------*/ TEST(HintFmt, percentStringWithoutArgs) { const char *teststr = "this is 100%s correct!"; ASSERT_STREQ( HintFmt(teststr).str().c_str(), teststr); } TEST(HintFmt, fmtToHintfmt) { ASSERT_STREQ( HintFmt(fmt("the color of this this text is %1%", "not yellow")).str().c_str(), "the color of this this text is not yellow"); } TEST(HintFmt, tooFewArguments) { ASSERT_STREQ( HintFmt("only one arg %1% %2%", "fulfilled").str().c_str(), "only one arg " ANSI_WARNING "fulfilled" ANSI_NORMAL " "); } TEST(HintFmt, tooManyArguments) { ASSERT_STREQ( HintFmt("what about this %1% %2%", "%3%", "one", "two").str().c_str(), "what about this " ANSI_WARNING "%3%" ANSI_NORMAL " " ANSI_YELLOW "one" ANSI_NORMAL); } /* ---------------------------------------------------------------------------- * ErrPos * --------------------------------------------------------------------------*/ TEST(errpos, invalidPos) { // contains an invalid symbol, which we should not dereference! Pos invalid; // constructing without access violation. ErrPos ep(invalid); // assignment without access violation. ep = invalid; } } #endif