Commit d395b563 authored by Andy Cedilnik's avatar Andy Cedilnik
Browse files

ENH: Improve internal test handling by creating a test class. Command...

ENH: Improve internal test handling by creating a test class. Command cmEnableTesting now only sets CMAKE_TESTING_ENABLED and cmAddTest only adds a test to the list. The actual test files are written by local generator. This way we can at some point in the future replace DartTestfile with some XML file
parent 3a8e7599
......@@ -71,6 +71,8 @@ SET(SRCS
cmSystemTools.h
cmTarget.cxx
cmTarget.h
cmTest.cxx
cmTest.h
cmVariableWatch.cxx
cmVariableWatch.h
cmVersion.cxx
......
......@@ -16,6 +16,9 @@
=========================================================================*/
#include "cmAddTestCommand.h"
#include "cmTest.h"
// cmExecutableCommand
bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args)
{
......@@ -32,67 +35,12 @@ bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args)
// store the arguments for the final pass
// also expand any CMake variables
m_Args = args;
return true;
}
// we append to the file in the final pass because Enable Testing command
// creates the file in the final pass.
void cmAddTestCommand::FinalPass()
{
// Create a full path filename for output Testfile
std::string fname;
fname = m_Makefile->GetStartOutputDirectory();
fname += "/";
if ( m_Makefile->IsSet("CTEST_NEW_FORMAT") )
{
fname += "CTestTestfile.cmake";
}
else
{
fname += "DartTestfile.txt";
}
// If the file doesn't exist, then ENABLE_TESTING hasn't been run
if (cmSystemTools::FileExists(fname.c_str()))
{
// Open the output Testfile
std::ofstream fout(fname.c_str(), std::ios::app);
if (!fout)
{
cmSystemTools::Error("Error Writing ", fname.c_str());
return;
}
std::vector<cmStdString> arguments;
arguments.assign(args.begin() + 2, args.end());
std::vector<std::string>::iterator it;
cmTest* test = m_Makefile->CreateTest(args[0].c_str());
test->SetCommand(args[1].c_str());
test->SetArguments(arguments);
// for each arg in the test
fout << "ADD_TEST(";
it = m_Args.begin();
fout << (*it).c_str();
++it;
for (; it != m_Args.end(); ++it)
{
// Just double-quote all arguments so they are re-parsed
// correctly by the test system.
fout << " \"";
for(std::string::iterator c = it->begin(); c != it->end(); ++c)
{
// Escape quotes within arguments. We should escape
// backslashes too but we cannot because it makes the result
// inconsistent with previous behavior of this command.
if((*c == '"'))
{
fout << '\\';
}
fout << *c;
}
fout << "\"";
}
fout << ")" << std::endl;
fout.close();
}
return;
return true;
}
......@@ -41,12 +41,6 @@ public:
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* This is called at the end after all the information
* specified by the command is accumulated.
*/
virtual void FinalPass();
/**
* The name of the command as specified in CMakeList.txt.
*/
......@@ -79,7 +73,7 @@ public:
cmTypeMacro(cmAddTestCommand, cmCommand);
private:
std::vector<std::string> m_Args;
std::string m_Test;
};
......
......@@ -24,91 +24,3 @@ bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&)
m_Makefile->AddDefinition("CMAKE_TESTING_ENABLED","1");
return true;
}
void cmEnableTestingCommand::FinalPass()
{
// initialize the DartTestfile files for the tree
this->CreateDartTestfileForMakefile(m_Makefile);
}
void cmEnableTestingCommand::CreateDartTestfileForMakefile(cmMakefile *mf)
{
// Create a full path filename for output Testfile
std::string fname;
fname = mf->GetStartOutputDirectory();
fname += "/";
if ( m_Makefile->IsSet("CTEST_NEW_FORMAT") )
{
fname += "CTestTestfile.cmake";
}
else
{
fname += "DartTestfile.txt";
}
cmSystemTools::MakeDirectory(mf->GetStartOutputDirectory());
// Open the output Testfile
std::ofstream fout(fname.c_str());
if (!fout)
{
cmSystemTools::Error("Error Writing ", fname.c_str());
cmSystemTools::ReportLastSystemError("");
return;
}
fout << "# CMake generated Testfile for " << std::endl
<< "#\tSource directory: "
<< mf->GetStartDirectory()
<< std::endl
<< "#\tBuild directory: " << mf->GetStartOutputDirectory()
<< std::endl
<< "# " << std::endl
<< "# This file replicates the SUBDIRS() and ADD_TEST() commands from the source"
<< std::endl
<< "# tree CMakeLists.txt file, skipping any SUBDIRS() or ADD_TEST() commands"
<< std::endl
<< "# that are excluded by CMake control structures, i.e. IF() commands."
<< std::endl
<< "#" << std::endl
<< "# The next line is critical for Dart to work" << std::endl
<< "# Duh :-)" << std::endl << std::endl;
// get our output directory
std::string outDir = mf->GetStartOutputDirectory();
outDir += "/";
// write out the subdirs for the current directory
std::vector<cmLocalGenerator *>& children =
mf->GetLocalGenerator()->GetChildren();
unsigned int i;
if (children.size())
{
fout << "SUBDIRS(";
std::string binP = children[0]->GetMakefile()->GetStartOutputDirectory();
cmSystemTools::ReplaceString(binP, outDir.c_str(), "");
fout << binP.c_str();
for(i = 1; i < children.size(); ++i)
{
binP = children[i]->GetMakefile()->GetStartOutputDirectory();
cmSystemTools::ReplaceString(binP, outDir.c_str(), "");
fout << " " << binP.c_str();
}
fout << ")" << std::endl << std::endl;;
}
fout.close();
// then recurse
if (children.size())
{
for(i = 0; i < children.size(); ++i)
{
this->CreateDartTestfileForMakefile(children[i]->GetMakefile());
}
}
return;
}
......@@ -49,14 +49,6 @@ public:
*/
virtual bool InitialPass(std::vector<std::string> const&);
/**
* This is called at the end after all the information
* specified by the command is accumulated. Most commands do
* not implement this method. At this point, reading and
* writing to the cache can be done.
*/
virtual void FinalPass();
/**
* The name of the command as specified in CMakeList.txt.
*/
......
......@@ -607,6 +607,7 @@ void cmGlobalGenerator::Generate()
{
m_LocalGenerators[i]->Generate();
m_LocalGenerators[i]->GenerateInstallRules();
m_LocalGenerators[i]->GenerateTestFiles();
m_CMakeInstance->UpdateProgress("Generating",
(i+1.0f)/m_LocalGenerators.size());
}
......
......@@ -21,6 +21,7 @@
#include "cmGeneratedFileStream.h"
#include "cmSourceFile.h"
#include "cmOrderLinkDirectories.h"
#include "cmTest.h"
#include <ctype.h> // for isalpha
cmLocalGenerator::cmLocalGenerator()
......@@ -83,15 +84,95 @@ void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
gg->GetCMakeInstance()->GetHomeDirectory());
m_Makefile->SetHomeOutputDirectory(
gg->GetCMakeInstance()->GetHomeOutputDirectory());
}
void cmLocalGenerator::ConfigureFinalPass()
{
m_Makefile->ConfigureFinalPass();
}
void cmLocalGenerator::GenerateTestFiles()
{
if ( !m_Makefile->IsOn("CMAKE_TESTING_ENABLED") )
{
return;
}
std::string file = m_Makefile->GetStartOutputDirectory();
file += "/";
if ( m_Makefile->IsSet("CTEST_NEW_FORMAT") )
{
file += "CTestTestfile.cmake";
}
else
{
file += "DartTestfile.txt";
}
cmGeneratedFileStream fout(file.c_str());
fout.SetCopyIfDifferent(true);
fout << "# CMake generated Testfile for " << std::endl
<< "# Source directory: " << m_Makefile->GetStartDirectory() << std::endl
<< "# Build directory: " << m_Makefile->GetStartOutputDirectory() << std::endl
<< "# " << std::endl
<< "# This file replicates the SUBDIRS() and ADD_TEST() commands from the source" << std::endl
<< "# tree CMakeLists.txt file, skipping any SUBDIRS() or ADD_TEST() commands" << std::endl
<< "# that are excluded by CMake control structures, i.e. IF() commands." << std::endl
<< "#" << std::endl
<< "# The next line is critical for Dart to work" << std::endl
<< "# Duh :-)" << std::endl << std::endl;
const std::vector<cmTest*> *tests = m_Makefile->GetTests();
std::vector<cmTest*>::const_iterator it;
for ( it = tests->begin(); it != tests->end(); ++ it )
{
cmTest* test = *it;
fout << "ADD_TEST(";
fout << test->GetName() << " \"" << test->GetCommand() << "\"";
std::vector<cmStdString>::iterator it;
for (it = test->GetArguments().begin();
it != test->GetArguments().end(); ++it)
{
// Just double-quote all arguments so they are re-parsed
// correctly by the test system.
fout << " \"";
for(std::string::iterator c = it->begin(); c != it->end(); ++c)
{
// Escape quotes within arguments. We should escape
// backslashes too but we cannot because it makes the result
// inconsistent with previous behavior of this command.
if((*c == '"'))
{
fout << '\\';
}
fout << *c;
}
fout << "\"";
}
fout << ")" << std::endl;
}
if ( this->Children.size())
{
fout << "SUBDIRS(";
size_t i;
std::string outDir = m_Makefile->GetStartOutputDirectory();
outDir += "/";
for(i = 0; i < this->Children.size(); ++i)
{
std::string binP = this->Children[i]->GetMakefile()->GetStartOutputDirectory();
cmSystemTools::ReplaceString(binP, outDir.c_str(), "");
if ( i > 0 )
{
fout << " ";
}
fout << binP.c_str();
}
fout << ")" << std::endl << std::endl;;
}
}
void cmLocalGenerator::GenerateInstallRules()
{
const cmTargets &tgts = m_Makefile->GetTargets();
......
......@@ -59,6 +59,12 @@ public:
*/
virtual void GenerateInstallRules();
/**
* Generate the test files for tests.
*/
virtual void GenerateTestFiles();
///! Get the makefile for this generator
cmMakefile *GetMakefile() {
return this->m_Makefile; };
......@@ -188,7 +194,7 @@ protected:
void CreateCustomTargetsAndCommands(std::set<cmStdString> const&);
virtual void AddInstallRule(std::ostream& fout, const char* dest, int type,
const char* files, bool optional = false, const char* properties = 0);
cmMakefile *m_Makefile;
cmGlobalGenerator *m_GlobalGenerator;
// members used for relative path function ConvertToMakefilePath
......
......@@ -24,6 +24,7 @@
#include "cmCacheManager.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
#include "cmTest.h"
#ifdef CMAKE_BUILD_WITH_CMAKE
# include "cmVariableWatch.h"
#endif
......@@ -126,6 +127,11 @@ cmMakefile::~cmMakefile()
{
delete *i;
}
for(std::vector<cmTest*>::iterator i = m_Tests.begin();
i != m_Tests.end(); ++i)
{
delete *i;
}
for(unsigned int i=0; i < m_UsedCommands.size(); i++)
{
delete m_UsedCommands[i];
......@@ -2465,3 +2471,43 @@ cmTarget* cmMakefile::FindTarget(const char* name)
}
return 0;
}
cmTest* cmMakefile::CreateTest(const char* testName)
{
if ( !testName )
{
return 0;
}
cmTest* test = this->GetTest(testName);
if ( test )
{
return test;
}
test = new cmTest;
test->SetName(testName);
m_Tests.push_back(test);
return test;
}
cmTest* cmMakefile::GetTest(const char* testName) const
{
if ( !testName )
{
return 0;
}
std::vector<cmTest*>::const_iterator it;
for ( it = m_Tests.begin(); it != m_Tests.end(); ++ it )
{
if ( strcmp((*it)->GetName(), testName) == 0 )
{
return *it;
}
}
return 0;
}
const std::vector<cmTest*> *cmMakefile::GetTests() const
{
return &m_Tests;
}
......@@ -31,6 +31,7 @@ class cmCommand;
class cmLocalGenerator;
class cmMakeDepend;
class cmSourceFile;
class cmTest;
class cmVariableWatch;
class cmake;
......@@ -642,6 +643,15 @@ public:
*/
void AddMacro(const char* name, const char* signature);
///! Add a new cmTest to the list of tests for this makefile.
cmTest* CreateTest(const char* testName);
/** Get a cmTest pointer for a given test name, if the name is
* not found, then a null pointer is returned.
*/
cmTest* GetTest(const char* testName) const;
const std::vector<cmTest*> *GetTests() const;
/**
* Get a list of macros as a ; separated string
*/
......@@ -686,6 +696,9 @@ protected:
cmTargets m_Targets;
std::vector<cmSourceFile*> m_SourceFiles;
// Tests
std::vector<cmTest*> m_Tests;
// The include and link-library paths. These may have order
// dependency, so they must be vectors (not set).
std::vector<std::string> m_IncludeDirectories;
......
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmTest.h"
#include "cmSystemTools.h"
cmTest::cmTest()
{
}
cmTest::~cmTest()
{
}
void cmTest::SetName(const char* name)
{
if ( !name )
{
name = "";
}
m_Name = name;
}
void cmTest::SetCommand(const char* command)
{
if ( !command )
{
command = "";
}
m_Command = command;
}
void cmTest::SetArguments(const std::vector<cmStdString>& args)
{
m_Args = args;
}
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmTest_h
#define cmTest_h
#include "cmCustomCommand.h"
/** \class cmTest
* \brief Represent a test
*
* cmTest is representation of a test.
*/
class cmTest
{
public:
/**
*/
cmTest();
~cmTest();
///! Set the test name
void SetName(const char* name);
const char* GetName() { return m_Name.c_str(); }
void SetCommand(const char* command);
const char* GetCommand() { return m_Command.c_str(); }
void SetArguments(const std::vector<cmStdString>& args);
std::vector<cmStdString>& GetArguments()
{
return m_Args;
}
/**
* Print the structure to std::cout.
*/
void Print() const;
///! Set/Get a property of this source file
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop) const;
bool GetPropertyAsBool(const char *prop) const;
private:
std::map<cmStdString,cmStdString> m_Properties;
cmStdString m_Name;
cmStdString m_Command;
std::vector<cmStdString> m_Args;
};
#endif
......@@ -53,6 +53,7 @@ CMAKE_CXX_SOURCES="\
cmBootstrapCommands \
cmCommands \
cmTarget \
cmTest \
cmCustomCommand \
cmCacheManager \
cmListFileCache \
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment