2020-06-06 08:22:32 +00:00
# include "logging.hh"
# include "nixexpr.hh"
# include "util.hh"
2020-06-19 20:54:41 +00:00
# include <fstream>
2020-06-06 08:22:32 +00:00
# include <gtest/gtest.h>
namespace nix {
/* ----------------------------------------------------------------------------
* logEI
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2020-06-25 00:31:28 +00:00
const char * test_file =
2020-06-23 21:30:13 +00:00
" previous line of code \n "
" this is the problem line of code \n "
" next line of code \n " ;
2020-06-25 00:31:28 +00:00
const char * one_liner =
" this is the other problem line of code " ;
2020-06-23 21:30:13 +00:00
2020-06-06 08:22:32 +00:00
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 ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- TestError --- error-unit-test \x1B [0m \n an error for testing purposes \n " ) ;
2020-06-06 08:22:32 +00:00
}
}
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 . hint = hintfmt ( " %s; subsequent error message. " , normaltxt ( e . info ( ) . hint ? e . info ( ) . hint - > str ( ) : " " ) ) ;
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( ei ) ;
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-22 17:32:20 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- TestError --- error-unit-test \x1B [0m \n initial error; subsequent error message. \n " ) ;
2020-06-06 08:22:32 +00:00
}
}
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 ( ) ;
2020-06-22 17:32:20 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- SysError --- error-unit-test \x1B [0m \n statting file: \x1B [33;1mBad file descriptor \x1B [0m \n " ) ;
2020-06-06 08:22:32 +00:00
}
}
TEST ( logEI , loggingErrorOnInfoLevel ) {
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( { . level = lvlInfo ,
2020-06-19 21:28:13 +00:00
. name = " Info name " ,
. description = " Info description " ,
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [32;1minfo: \x1B [0m \x1B [34;1m --- Info name --- error-unit-test \x1B [0m \n Info description \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logEI , loggingErrorOnTalkativeLevel ) {
2020-06-07 13:24:49 +00:00
verbosity = lvlTalkative ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( { . level = lvlTalkative ,
. name = " Talkative name " ,
. description = " Talkative description " ,
2020-06-19 21:28:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [32;1mtalk: \x1B [0m \x1B [34;1m --- Talkative name --- error-unit-test \x1B [0m \n Talkative description \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logEI , loggingErrorOnChattyLevel ) {
2020-06-07 13:24:49 +00:00
verbosity = lvlChatty ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( { . level = lvlChatty ,
. name = " Chatty name " ,
. description = " Talkative description " ,
2020-06-19 21:28:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [32;1mchat: \x1B [0m \x1B [34;1m --- Chatty name --- error-unit-test \x1B [0m \n Talkative description \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logEI , loggingErrorOnDebugLevel ) {
2020-06-07 13:24:49 +00:00
verbosity = lvlDebug ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( { . level = lvlDebug ,
. name = " Debug name " ,
. description = " Debug description " ,
2020-06-19 21:28:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [33;1mdebug: \x1B [0m \x1B [34;1m --- Debug name --- error-unit-test \x1B [0m \n Debug description \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logEI , loggingErrorOnVomitLevel ) {
2020-06-07 13:24:49 +00:00
verbosity = lvlVomit ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logger - > logEI ( { . level = lvlVomit ,
. name = " Vomit name " ,
. description = " Vomit description " ,
2020-06-19 21:28:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [32;1mvomit: \x1B [0m \x1B [34;1m --- Vomit name --- error-unit-test \x1B [0m \n Vomit description \n " ) ;
2020-06-06 08:22:32 +00:00
}
/* ----------------------------------------------------------------------------
* logError
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
TEST ( logError , logErrorWithoutHintOrCode ) {
testing : : internal : : CaptureStderr ( ) ;
logError ( {
. name = " name " ,
. description = " error description " ,
2020-06-19 21:28:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-16 07:44:19 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- name --- error-unit-test \x1B [0m \n error description \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logError , logErrorWithPreviousAndNextLinesOfCode ) {
SymbolTable testTable ;
2020-06-23 21:30:13 +00:00
auto problem_file = testTable . create ( test_file ) ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logError ( {
. name = " error name " ,
. description = " error with code lines " ,
. hint = hintfmt ( " this hint has %1% templated %2%!! " ,
2020-06-19 21:28:13 +00:00
" yellow " ,
" values " ) ,
2020-06-23 21:30:13 +00:00
. errPos = Pos ( foString , problem_file , 02 , 13 ) ,
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-07-01 04:05:21 +00:00
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 \n error 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 \n this hint has \x1B [33;1myellow \x1B [0m templated \x1B [33;1mvalues \x1B [0m!! \n " ) ;
2020-06-06 08:22:32 +00:00
}
2020-06-23 21:30:13 +00:00
TEST ( logError , logErrorWithInvalidFile ) {
2020-06-06 08:22:32 +00:00
SymbolTable testTable ;
2020-06-23 21:30:13 +00:00
auto problem_file = testTable . create ( " invalid filename " ) ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logError ( {
. name = " error name " ,
. description = " error without any code lines. " ,
. hint = hintfmt ( " this hint has %1% templated %2%!! " ,
2020-06-19 21:28:13 +00:00
" yellow " ,
" values " ) ,
2020-06-23 21:30:13 +00:00
. errPos = Pos ( foFile , problem_file , 02 , 13 )
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-23 21:30:13 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- SysError --- error-unit-test \x1B [0m \n opening file ' \x1B [33;1minvalid filename \x1B [0m': \x1B [33;1mNo such file or directory \x1B [0m \n \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 \n error without any code lines. \n \n this hint has \x1B [33;1myellow \x1B [0m templated \x1B [33;1mvalues \x1B [0m!! \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logError , logErrorWithOnlyHintAndName ) {
testing : : internal : : CaptureStderr ( ) ;
logError ( {
. name = " error name " ,
. hint = hintfmt ( " hint %1% " , " only " ) ,
2020-06-23 21:30:13 +00:00
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-23 21:30:13 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [31;1merror: \x1B [0m \x1B [34;1m --- error name --- error-unit-test \x1B [0m \n hint \x1B [33;1monly \x1B [0m \n " ) ;
2020-06-06 08:22:32 +00:00
}
/* ----------------------------------------------------------------------------
* logWarning
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
TEST ( logWarning , logWarningWithNameDescriptionAndHint ) {
testing : : internal : : CaptureStderr ( ) ;
logWarning ( {
2020-06-19 21:28:13 +00:00
. name = " name " ,
2020-06-23 21:30:13 +00:00
. description = " warning description " ,
2020-06-19 21:28:13 +00:00
. hint = hintfmt ( " there was a %1% " , " warning " ) ,
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-23 21:30:13 +00:00
ASSERT_STREQ ( str . c_str ( ) , " \x1B [33;1mwarning: \x1B [0m \x1B [34;1m --- name --- error-unit-test \x1B [0m \n warning description \n \n there was a \x1B [33;1mwarning \x1B [0m \n " ) ;
2020-06-06 08:22:32 +00:00
}
TEST ( logWarning , logWarningWithFileLineNumAndCode ) {
SymbolTable testTable ;
2020-06-23 21:30:13 +00:00
auto problem_file = testTable . create ( test_file ) ;
2020-06-06 08:22:32 +00:00
testing : : internal : : CaptureStderr ( ) ;
logWarning ( {
. name = " warning name " ,
. description = " warning description " ,
. hint = hintfmt ( " this hint has %1% templated %2%!! " ,
2020-06-19 21:28:13 +00:00
" yellow " ,
" values " ) ,
2020-06-23 21:30:13 +00:00
. errPos = Pos ( foStdin , problem_file , 2 , 13 ) ,
} ) ;
2020-06-06 08:22:32 +00:00
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-06-23 21:30:13 +00:00
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 \n warning 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 \n this hint has \x1B [33;1myellow \x1B [0m templated \x1B [33;1mvalues \x1B [0m!! \n " ) ;
2020-06-06 08:22:32 +00:00
}
2020-06-19 20:54:41 +00:00
/* ----------------------------------------------------------------------------
2020-06-25 00:31:28 +00:00
* 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 ) ;
2020-07-01 16:37:31 +00:00
e . addTrace ( std : : nullopt , " while doing something without a %1% " , " pos " ) ;
2020-06-25 00:31:28 +00:00
testing : : internal : : CaptureStderr ( ) ;
2020-07-01 04:05:21 +00:00
logger - > setShowTrace ( true ) ;
2020-06-25 00:31:28 +00:00
logError ( e . info ( ) ) ;
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-07-01 16:37:31 +00:00
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 \n a 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 \n it 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 " ) ;
2020-06-25 00:31:28 +00:00
}
2020-06-25 15:23:12 +00:00
TEST ( addTrace , hideTracesWithoutShowTrace ) {
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 ) ;
2020-07-01 16:37:31 +00:00
e . addTrace ( std : : nullopt , " while doing something without a %1% " , " pos " ) ;
2020-06-25 15:23:12 +00:00
testing : : internal : : CaptureStderr ( ) ;
2020-07-01 04:05:21 +00:00
logger - > setShowTrace ( false ) ;
2020-06-25 15:23:12 +00:00
logError ( e . info ( ) ) ;
auto str = testing : : internal : : GetCapturedStderr ( ) ;
2020-07-01 04:05:21 +00:00
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 \n a 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 \n it has been \x1B [33;1mzero \x1B [0m days since our last error \n " ) ;
2020-06-25 15:23:12 +00:00
}
2020-06-25 00:31:28 +00:00
/* ----------------------------------------------------------------------------
2020-06-19 20:54:41 +00:00
* hintfmt
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2020-06-19 21:28:13 +00:00
TEST ( hintfmt , percentStringWithoutArgs ) {
2020-06-19 20:54:41 +00:00
2020-06-19 21:28:13 +00:00
const char * teststr = " this is 100%s correct! " ;
2020-06-19 20:54:41 +00:00
2020-06-19 22:58:12 +00:00
ASSERT_STREQ (
hintfmt ( teststr ) . str ( ) . c_str ( ) ,
teststr ) ;
2020-06-19 20:54:41 +00:00
2020-06-19 21:28:13 +00:00
}
2020-06-19 20:54:41 +00:00
2020-06-19 22:46:49 +00:00
TEST ( hintfmt , fmtToHintfmt ) {
2020-06-19 22:58:12 +00:00
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 " ) ;
2020-06-19 22:46:49 +00:00
}
2020-06-19 21:28:13 +00:00
TEST ( hintfmt , tooFewArguments ) {
2020-06-19 20:54:41 +00:00
2020-06-19 21:28:13 +00:00
ASSERT_STREQ (
hintfmt ( " only one arg %1% %2% " , " fulfilled " ) . str ( ) . c_str ( ) ,
" only one arg " ANSI_YELLOW " fulfilled " ANSI_NORMAL " " ) ;
}
TEST ( hintfmt , tooManyArguments ) {
ASSERT_STREQ (
hintfmt ( " what about this %1% %2% " , " %3% " , " one " , " two " ) . str ( ) . c_str ( ) ,
" what about this " ANSI_YELLOW " %3% " ANSI_NORMAL " " ANSI_YELLOW " one " ANSI_NORMAL ) ;
}
2020-06-30 17:01:46 +00:00
/* ----------------------------------------------------------------------------
* 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 ;
}
2020-06-06 08:22:32 +00:00
}