JD2022-TU1/main/extern/FastBuild/Code/Tools/FBuild/FBuildTest/Tests/TestIncludeParser.cpp

176 lines
5.6 KiB
C++

// TestIncludeParser.cpp
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "TestFramework/UnitTest.h"
#include "Tools/FBuild/FBuildCore/FBuild.h"
#include "Tools/FBuild/FBuildCore/Helpers/CIncludeParser.h"
// Core
#include "Core/Containers/AutoPtr.h"
#include "Core/FileIO/FileStream.h"
#include "Core/Strings/AStackString.h"
#include "Core/Time/Timer.h"
#include "Core/Tracing/Tracing.h"
// TestIncludeParser
//------------------------------------------------------------------------------
class TestIncludeParser : public UnitTest
{
private:
DECLARE_TESTS
void TestMSVCPreprocessedOutput() const;
void TestMSVCShowIncludesOutput() const;
void TestGCCPreprocessedOutput() const;
void TestEdgeCases() const;
};
// Register Tests
//------------------------------------------------------------------------------
REGISTER_TESTS_BEGIN( TestIncludeParser )
REGISTER_TEST( TestMSVCPreprocessedOutput );
REGISTER_TEST( TestMSVCShowIncludesOutput );
REGISTER_TEST( TestGCCPreprocessedOutput );
REGISTER_TEST( TestEdgeCases );
REGISTER_TESTS_END
// TestMSVCPreprocessedOutput
//------------------------------------------------------------------------------
void TestIncludeParser::TestMSVCPreprocessedOutput() const
{
FileStream f;
TEST_ASSERT( f.Open( "Data\\TestIncludeParser\\MSVCPreProcessor.cpp", FileStream::READ_ONLY) )
const size_t fileSize = (size_t)f.GetFileSize();
AutoPtr< char > mem( (char *)ALLOC( fileSize + 1 ) );
TEST_ASSERT( f.Read( mem.Get(), fileSize ) == fileSize );
mem.Get()[ fileSize ] = 0;
Timer t;
const size_t repeatCount( 100 );
for ( size_t i=0; i<repeatCount; ++i )
{
CIncludeParser parser;
TEST_ASSERT( parser.ParseMSCL_Preprocessed( mem.Get(), fileSize ) );
// check number of includes found to prevent future regressions
const Array< AString > & includes = parser.GetIncludes();
TEST_ASSERT( includes.GetSize() == 29 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 520 );
#endif
}
float time = t.GetElapsed();
OUTPUT( "Parse MSVC Preprocessor: %2.3fs (%2.1f MiB/sec)\n", time, ( (float)( fileSize * repeatCount / ( 1024.0f * 1024.0f ) ) / time ) );
}
// TestMSVCShowIncludesOutput
//------------------------------------------------------------------------------
void TestIncludeParser::TestMSVCShowIncludesOutput() const
{
FileStream f;
TEST_ASSERT( f.Open( "Data\\TestIncludeParser\\MSVCShowIncludes.dat", FileStream::READ_ONLY) )
const size_t fileSize = (size_t)f.GetFileSize();
AutoPtr< char > mem( (char *)Alloc( fileSize + 1 ) );
TEST_ASSERT( f.Read( mem.Get(), fileSize ) == fileSize );
mem.Get()[ fileSize ] = 0;
Timer t;
const size_t repeatCount( 100 );
for ( size_t i=0; i<repeatCount; ++i )
{
CIncludeParser parser;
TEST_ASSERT( parser.ParseMSCL_Output( mem.Get(), fileSize ) );
// check number of includes found to prevent future regressions
const Array< AString > & includes = parser.GetIncludes();
TEST_ASSERT( includes.GetSize() == 237 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 273 );
#endif
}
float time = t.GetElapsed();
OUTPUT( "Parse MSVC /showincludes: %2.3fs (%2.1f MiB/sec)\n", time, ( (float)( fileSize * repeatCount / ( 1024.0f * 1024.0f ) ) / time ) );
}
// TestGCCPreprocessedOutput
//------------------------------------------------------------------------------
void TestIncludeParser::TestGCCPreprocessedOutput() const
{
FBuild fBuild; // needed fer CleanPath for relative dirs
FileStream f;
TEST_ASSERT( f.Open( "Data\\TestIncludeParser\\GCCPreProcessor.cpp", FileStream::READ_ONLY) )
const size_t fileSize = (size_t)f.GetFileSize();
AutoPtr< char > mem( (char *)ALLOC( fileSize + 1 ) );
TEST_ASSERT( f.Read( mem.Get(), fileSize ) == fileSize );
mem.Get()[ fileSize ] = 0;
Timer t;
const size_t repeatCount( 100 );
for ( size_t i=0; i<repeatCount; ++i )
{
CIncludeParser parser;
TEST_ASSERT( parser.ParseGCC_Preprocessed( mem.Get(), fileSize ) );
// check number of includes found to prevent future regressions
const Array< AString > & includes = parser.GetIncludes();
TEST_ASSERT( includes.GetSize() == 7 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 462 );
#endif
}
float time = t.GetElapsed();
OUTPUT( "Parse GCC Preprocessor: %2.3fs (%2.1f MiB/sec)\n", time, ( (float)( fileSize * repeatCount / ( 1024.0f * 1024.0f ) ) / time ) );
}
//
//------------------------------------------------------------------------------
void TestIncludeParser::TestEdgeCases() const
{
FBuild fBuild; // needed fer CleanPath for relative dirs
// include on last line
{
AStackString<> data( "#line \"hello\"" );
CIncludeParser parser;
TEST_ASSERT( parser.ParseMSCL_Preprocessed( data.Get(), data.GetLength() ) );
TEST_ASSERT( parser.GetIncludes().GetSize() == 1 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 1 );
#endif
}
// empty
{
AStackString<> data( "" );
CIncludeParser parser;
TEST_ASSERT( parser.ParseMSCL_Preprocessed( data.Get(), data.GetLength() ) );
TEST_ASSERT( parser.GetIncludes().GetSize() == 0 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 0 );
#endif
}
// #pragma or # pragma should be ignored
{
AStackString<> data( "#pragma message\"hello\"\n# pragma message\"hello\"\n" );
uint32_t dataLen = data.GetLength();
CIncludeParser parser;
TEST_ASSERT( parser.ParseGCC_Preprocessed( data.Get(), dataLen ) );
TEST_ASSERT( parser.GetIncludes().GetSize() == 0 );
#ifdef DEBUG
TEST_ASSERT( parser.GetNonUniqueCount() == 0 );
#endif
}
}
//------------------------------------------------------------------------------