mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Initial import
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@2 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
8081e7006f
commit
8e18676b92
31 changed files with 4062 additions and 0 deletions
1
build/build.properties
Normal file
1
build/build.properties
Normal file
|
|
@ -0,0 +1 @@
|
|||
platform = vc80
|
||||
32
build/build.xml
Normal file
32
build/build.xml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<project name="turtle" default="all">
|
||||
|
||||
<property environment="env"/>
|
||||
<import file="${env.PONEY_HOME}/poney.xml"/>
|
||||
|
||||
<target name="turtle_test" description="build and run unit tests">
|
||||
<build-test name="turtle" mode="all">
|
||||
<compilerarg value="-Wno-uninitialized" location="mid" if="is-cygwin"/>
|
||||
</build-test>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="clean intermediate build artifacts">
|
||||
<delete dir="${out.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="configure" description="update external libraries">
|
||||
<update name="boost"/>
|
||||
</target>
|
||||
|
||||
<target name="test" depends="turtle_test" description="run unit tests"/>
|
||||
|
||||
<target name="export" description="export the distribution">
|
||||
<deploy>
|
||||
<module name="turtle">
|
||||
<include name="**/*.hpp"/>
|
||||
</module>
|
||||
</deploy>
|
||||
</target>
|
||||
|
||||
<target name="all" depends="configure,test,export" description="build, run tests and package application"/>
|
||||
|
||||
</project>
|
||||
25
build/vc80/turtle.sln
Normal file
25
build/vc80/turtle.sln
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "turtle", "turtle.vcproj", "{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "turtle_test", "turtle_test.vcproj", "{74810A2A-33D8-47D6-9A50-71261F1683F5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug|Win32 = debug|Win32
|
||||
release|Win32 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}.debug|Win32.ActiveCfg = debug|Win32
|
||||
{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}.debug|Win32.Build.0 = debug|Win32
|
||||
{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}.release|Win32.ActiveCfg = release|Win32
|
||||
{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}.release|Win32.Build.0 = release|Win32
|
||||
{74810A2A-33D8-47D6-9A50-71261F1683F5}.debug|Win32.ActiveCfg = debug|Win32
|
||||
{74810A2A-33D8-47D6-9A50-71261F1683F5}.debug|Win32.Build.0 = debug|Win32
|
||||
{74810A2A-33D8-47D6-9A50-71261F1683F5}.release|Win32.ActiveCfg = release|Win32
|
||||
{74810A2A-33D8-47D6-9A50-71261F1683F5}.release|Win32.Build.0 = release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
227
build/vc80/turtle.vcproj
Normal file
227
build/vc80/turtle.vcproj
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="turtle"
|
||||
ProjectGUID="{831F2DEE-1E35-4533-A3B2-12C01BA8DA1D}"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug|Win32"
|
||||
OutputDirectory="../../out/vc80/$(ConfigurationName)/libraries/$(ProjectName)"
|
||||
IntermediateDirectory="../../out/vc80/$(ConfigurationName)/libraries/$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm179"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(IntDir)", ../../include, ../../src/libraries, ../../src/libraries/$(ProjectName)"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="$(ProjectName)_pch.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/$(ProjectName).pch"
|
||||
ProgramDataBaseFileName="$(IntDir)/$(ProjectName).pdb"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/lib$(ProjectName)-vc80-mt-gd.lib"
|
||||
AdditionalLibraryDirectories="$(OutDir) , ../../lib/vc80"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release|Win32"
|
||||
OutputDirectory="../../out/vc80/$(ConfigurationName)/libraries/$(ProjectName)"
|
||||
IntermediateDirectory="../../out/vc80/$(ConfigurationName)/libraries/$(ProjectName)"
|
||||
ConfigurationType="4"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm176"
|
||||
AdditionalIncludeDirectories=""$(IntDir)", ../../include, ../../src/libraries, ../../src/libraries/$(ProjectName)"
|
||||
PreprocessorDefinitions="WIN32, NDEBUG,_WINDOWS"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="$(ProjectName)_pch.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/$(ProjectName).pch"
|
||||
ProgramDataBaseFileName="$(IntDir)\$(ProjectName).pdb"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/lib$(ProjectName)-vc80-mt.lib"
|
||||
AdditionalLibraryDirectories="$(OutDir) , ../../lib/vc80"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\check.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\config.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\constraint.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\error.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\expectation.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\format.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\functional.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\invocation.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\matcher.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\node.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\object.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\placeholder.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\result.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\root.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\sequence.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\tools.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\libraries\turtle\verifiable.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
239
build/vc80/turtle_test.vcproj
Normal file
239
build/vc80/turtle_test.vcproj
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="turtle_test"
|
||||
ProjectGUID="{74810A2A-33D8-47D6-9A50-71261F1683F5}"
|
||||
RootNamespace="turtle_test"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="debug|Win32"
|
||||
OutputDirectory="../../out/vc80/$(ConfigurationName)/tests/$(ProjectName)"
|
||||
IntermediateDirectory="../../out/vc80/$(ConfigurationName)/tests/$(ProjectName)"
|
||||
ConfigurationType="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm172"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../src/libraries, ../../include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="$(ProjectName)_pch.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/$(ProjectName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/$(ProjectName).pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
AdditionalLibraryDirectories="../../lib/vc80"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="cd ../../run/vc80
"$(TargetDir)$(TargetName).exe" --result_code=no --report_level=no --log_level=messages --data_directory=../../data/tests/$(ProjectName)
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release|Win32"
|
||||
OutputDirectory="../../out/vc80/$(ConfigurationName)/tests/$(ProjectName)"
|
||||
IntermediateDirectory="../../out/vc80/$(ConfigurationName)/tests/$(ProjectName)"
|
||||
ConfigurationType="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/Zm162"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="../../src/libraries, ../../include"
|
||||
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
|
||||
BasicRuntimeChecks="0"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="$(ProjectName)_pch.h"
|
||||
PrecompiledHeaderFile="$(IntDir)/$(ProjectName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/$(ProjectName).pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
OutputFile="$(OutDir)/$(ProjectName).exe"
|
||||
AdditionalLibraryDirectories="../../lib/vc80"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="cd ../../run/vc80
"$(TargetDir)$(TargetName).exe" --result_code=no --report_level=no --log_level=messages --data_directory=../../data/tests/$(ProjectName)
"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx;h;hpp;hxx;hm;inl;inc;xsd"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\constraint_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\error_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\expectation_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\format_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\invocation_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\object_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\samples_test.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\sequence_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\tests\turtle_test\tools_test.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
66
src/libraries/turtle/check.hpp
Normal file
66
src/libraries/turtle/check.hpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_CHECK_HPP_INCLUDED
|
||||
#define MOCK_CHECK_HPP_INCLUDED
|
||||
|
||||
#include "placeholder.hpp"
|
||||
#include "constraint.hpp"
|
||||
#include "format.hpp"
|
||||
#include <boost/function.hpp>
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Arg >
|
||||
class check
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< bool( Arg ) > functor_type;
|
||||
|
||||
public:
|
||||
template< typename T >
|
||||
explicit check( const T& t )
|
||||
: functor_( equal( t ).functor_ )
|
||||
, desc_ ( detail::format( t ) )
|
||||
{
|
||||
if( !functor_ )
|
||||
std::invalid_argument( "invalid functor" );
|
||||
}
|
||||
|
||||
template< typename Constraint >
|
||||
explicit check( const placeholder< Constraint >& c )
|
||||
: functor_( c.functor_ )
|
||||
, desc_ ( c.desc_ )
|
||||
{
|
||||
if( !functor_ )
|
||||
std::invalid_argument( "invalid functor" );
|
||||
}
|
||||
|
||||
template< typename Y >
|
||||
bool operator()( Y& y ) const
|
||||
{
|
||||
return functor_( y );
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const check& c )
|
||||
{
|
||||
return s << c.desc_;
|
||||
}
|
||||
|
||||
private:
|
||||
functor_type functor_;
|
||||
std::string desc_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_CHECK_HPP_INCLUDED
|
||||
26
src/libraries/turtle/config.hpp
Normal file
26
src/libraries/turtle/config.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2009
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_CONFIG_HPP_INCLUDED
|
||||
#define MOCK_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <boost/preprocessor/comparison/less_equal.hpp>
|
||||
#include <boost/preprocessor/debug/assert.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#ifndef MOCK_MAX_ARGS
|
||||
# define MOCK_MAX_ARGS 10
|
||||
#endif // MOCK_MAX_ARGS
|
||||
|
||||
BOOST_PP_ASSERT( BOOST_PP_LESS_EQUAL(MOCK_MAX_ARGS, BOOST_FUNCTION_MAX_ARGS) )
|
||||
|
||||
#ifdef BOOST_TEST_DECL
|
||||
# define MOCK_USE_BOOST_TEST
|
||||
#endif
|
||||
|
||||
#endif // #ifndef MOCK_CONFIG_HPP_INCLUDED
|
||||
132
src/libraries/turtle/constraint.hpp
Normal file
132
src/libraries/turtle/constraint.hpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
#define MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
|
||||
#include "placeholder.hpp"
|
||||
#include "functional.hpp"
|
||||
#include "format.hpp"
|
||||
#include <sstream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
template< typename Functor, typename Description >
|
||||
const detail::placeholder< Functor > constraint( const Functor& f,
|
||||
const Description& desc )
|
||||
{
|
||||
std::stringstream s;
|
||||
s << std::boolalpha << desc;
|
||||
return detail::placeholder< Functor >( f, s.str() );
|
||||
}
|
||||
template< typename Functor >
|
||||
const detail::placeholder< Functor > constraint( const Functor& f )
|
||||
{
|
||||
return detail::placeholder< Functor >( f, "?" );
|
||||
}
|
||||
template< typename Functor, typename T >
|
||||
const detail::placeholder< Functor > constraint( const Functor& f,
|
||||
const std::string& name,
|
||||
const T& t )
|
||||
{
|
||||
return detail::placeholder< Functor >( f,
|
||||
name + "( " + detail::format( t ) + " )" );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<>
|
||||
struct placeholder< nothing >
|
||||
{
|
||||
placeholder()
|
||||
: desc_( "any" )
|
||||
{}
|
||||
nothing functor_;
|
||||
std::string desc_;
|
||||
};
|
||||
template<>
|
||||
struct placeholder< negation >
|
||||
{
|
||||
placeholder()
|
||||
: desc_( "negate" )
|
||||
{}
|
||||
negation functor_;
|
||||
std::string desc_;
|
||||
};
|
||||
template<>
|
||||
struct placeholder< evaluation >
|
||||
{
|
||||
placeholder()
|
||||
: desc_( "evaluate" )
|
||||
{}
|
||||
evaluation functor_;
|
||||
std::string desc_;
|
||||
};
|
||||
}
|
||||
const detail::placeholder< detail::nothing > any;
|
||||
const detail::placeholder< detail::negation > negate;
|
||||
const detail::placeholder< detail::evaluation > evaluate;
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::equality< T > > equal( T t )
|
||||
{
|
||||
return constraint( detail::equality< T >( t ), "equal", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::identity< T > > same( T& t )
|
||||
{
|
||||
return constraint( detail::identity< T >( boost::ref( t ) ),
|
||||
"same", &t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::inferiority< T > > less( T t )
|
||||
{
|
||||
return constraint( detail::inferiority< T >( t ), "less", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::superiority< T > > greater( T t )
|
||||
{
|
||||
return constraint( detail::superiority< T >( t ), "greater", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder<
|
||||
detail::or_< detail::inferiority< T >, detail::equality< T > > >
|
||||
less_equal( T t )
|
||||
{
|
||||
return constraint( (less( t ) || equal( t )).functor_,
|
||||
"less_equal", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder<
|
||||
detail::or_< detail::superiority< T >, detail::equality< T > > >
|
||||
greater_equal( T t )
|
||||
{
|
||||
return constraint( (greater( t ) || equal( t )).functor_,
|
||||
"greater_equal", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::assignment< T > > assign( T t )
|
||||
{
|
||||
return constraint( detail::assignment< T >( t ), "assign", t );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
detail::placeholder< detail::retrieval< T > > retrieve( T& t )
|
||||
{
|
||||
return constraint( detail::retrieval< T >( boost::ref( t ) ),
|
||||
"retrieve", t );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
98
src/libraries/turtle/error.hpp
Normal file
98
src/libraries/turtle/error.hpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_ERROR_HPP_INCLUDED
|
||||
#define MOCK_ERROR_HPP_INCLUDED
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class errors_t : public boost::unit_test::singleton< errors_t >
|
||||
{
|
||||
public:
|
||||
long count_;
|
||||
private:
|
||||
friend class boost::unit_test::singleton< errors_t >;
|
||||
errors_t()
|
||||
: count_( 0 )
|
||||
{}
|
||||
};
|
||||
BOOST_TEST_SINGLETON_INST( errors )
|
||||
}
|
||||
|
||||
class exception : public boost::execution_exception
|
||||
{
|
||||
public:
|
||||
explicit exception( const std::string& s )
|
||||
: boost::execution_exception( boost::execution_exception::user_error, s )
|
||||
{}
|
||||
};
|
||||
|
||||
template< typename Result >
|
||||
struct boost_test_error_policy
|
||||
{
|
||||
static void missing_result_specification()
|
||||
{
|
||||
++detail::errors.count_;
|
||||
static std::string m;
|
||||
m = "mock error : missing result specification";
|
||||
throw mock::exception( m );
|
||||
}
|
||||
|
||||
static Result no_match( const std::string& context )
|
||||
{
|
||||
++detail::errors.count_;
|
||||
static std::string m;
|
||||
m = "mock error : unexpected call : " + context;
|
||||
throw mock::exception( m );
|
||||
}
|
||||
|
||||
static void sequence_failed( const std::string& context,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{
|
||||
++detail::errors.count_;
|
||||
static std::string m;
|
||||
m = "mock error : unexpected call : " + context;
|
||||
throw mock::exception( m );
|
||||
}
|
||||
|
||||
static void verification_failed( const std::string& context,
|
||||
const std::string& file, int line )
|
||||
{
|
||||
notify( "verification failed : " + context, file, line );
|
||||
}
|
||||
|
||||
static void untriggered_expectation( const std::string& context,
|
||||
const std::string& file, int line )
|
||||
{
|
||||
if( detail::errors.count_ == 0 )
|
||||
notify( "untriggered expectation : " + context, file, line );
|
||||
}
|
||||
|
||||
static void notify( const std::string& message,
|
||||
const std::string& file, int line )
|
||||
{
|
||||
boost::test_tools::tt_detail::check_impl(
|
||||
false,
|
||||
boost::unit_test::lazy_ostream::instance() << message,
|
||||
file, (std::size_t)line,
|
||||
boost::test_tools::tt_detail::CHECK,
|
||||
boost::test_tools::tt_detail::CHECK_MSG,
|
||||
0 );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_ERROR_HPP_INCLUDED
|
||||
202
src/libraries/turtle/expectation.hpp
Normal file
202
src/libraries/turtle/expectation.hpp
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_EXPECTATION_HPP_INCLUDED
|
||||
#define MOCK_EXPECTATION_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "error.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include "matcher.hpp"
|
||||
#include "node.hpp"
|
||||
#include "root.hpp"
|
||||
#include "format.hpp"
|
||||
#include "invocation.hpp"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <ostream>
|
||||
#include <list>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
template< typename Signature,
|
||||
typename ErrorPolicy = boost_test_error_policy<
|
||||
BOOST_DEDUCED_TYPENAME boost::function<
|
||||
Signature >::result_type > > // $$$$ MAT : concept check Signature is actually a signature
|
||||
class expectation : private verifiable
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature >::result_type result_type;
|
||||
typedef detail::matcher< result_type,
|
||||
Signature,
|
||||
ErrorPolicy,
|
||||
boost::function< Signature >::arity >
|
||||
matcher_type;
|
||||
|
||||
expectation( node& parent = root, const std::string& name = "?" )
|
||||
: name_( name )
|
||||
, parent_( &parent )
|
||||
, valid_( true )
|
||||
{
|
||||
parent_->add( *this );
|
||||
}
|
||||
expectation( const std::string& name )
|
||||
: name_( name )
|
||||
, parent_( &root )
|
||||
, valid_( true )
|
||||
{
|
||||
parent_->add( *this );
|
||||
}
|
||||
virtual ~expectation()
|
||||
{
|
||||
parent_->remove( *this );
|
||||
for( matchers_cit it = matchers_.begin();
|
||||
it != matchers_.end(); ++it )
|
||||
if( valid_ && ! it->verify() )
|
||||
ErrorPolicy::untriggered_expectation(
|
||||
context(), it->file(), it->line() );
|
||||
}
|
||||
|
||||
expectation& set_name( const std::string& name )
|
||||
{
|
||||
name_ = name;
|
||||
return *this;
|
||||
}
|
||||
expectation& set_parent( node& parent )
|
||||
{
|
||||
parent_->remove( *this );
|
||||
parent.add( *this );
|
||||
parent_ = &parent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual bool verify()
|
||||
{
|
||||
for( matchers_cit it = matchers_.begin();
|
||||
it != matchers_.end(); ++it )
|
||||
if( !it->verify() )
|
||||
{
|
||||
valid_ = false;
|
||||
ErrorPolicy::verification_failed( context(),
|
||||
it->file(), it->line() );
|
||||
}
|
||||
return valid_;
|
||||
}
|
||||
virtual void reset()
|
||||
{
|
||||
valid_ = true;
|
||||
matchers_.clear();
|
||||
}
|
||||
|
||||
matcher_type& expect( const std::string& file, int line )
|
||||
{
|
||||
matchers_.push_back( matcher_type() );
|
||||
matchers_.back().set_location( file, line );
|
||||
valid_ = true;
|
||||
return matchers_.back();
|
||||
}
|
||||
matcher_type& expect()
|
||||
{
|
||||
matchers_.push_back( matcher_type() );
|
||||
valid_ = true;
|
||||
return matchers_.back();
|
||||
}
|
||||
|
||||
result_type operator()() const
|
||||
{
|
||||
for( matchers_cit it = matchers_.begin();
|
||||
it != matchers_.end(); ++it )
|
||||
if( it->is_valid() )
|
||||
{
|
||||
if( !it->invoke() )
|
||||
{
|
||||
valid_ = false;
|
||||
ErrorPolicy::sequence_failed( context( "" ),
|
||||
it->file(), it->line() );
|
||||
}
|
||||
return it->functor()();
|
||||
}
|
||||
valid_ = false;
|
||||
return ErrorPolicy::no_match( context( "" ) );
|
||||
}
|
||||
|
||||
#define MOCK_EXPECTATION_PARAMETER(z, n, d) BOOST_PP_COMMA_IF(n) const_cast< A##n & >( a##n )
|
||||
#define MOCK_EXPECTATION_DETAIL(z, n, d) + ", " + detail::format( a##n )
|
||||
#define MOCK_EXPECTATION_PARAMETERS(n) \
|
||||
detail::format( a0 ) BOOST_PP_REPEAT_FROM_TO(1, n, MOCK_EXPECTATION_DETAIL, BOOST_PP_EMPTY)
|
||||
#define MOCK_EXPECTATION_OPERATOR(z, n, d) \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename A) > \
|
||||
result_type operator()( BOOST_PP_ENUM_BINARY_PARAMS(n, const A, & a) ) const \
|
||||
{ \
|
||||
for( matchers_cit it = matchers_.begin(); it != matchers_.end(); ++it ) \
|
||||
if( it->is_valid( BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_EXPECTATION_PARAMETER, BOOST_PP_EMPTY) ) ) \
|
||||
{ \
|
||||
if( !it->invoke() ) \
|
||||
{ \
|
||||
valid_ = false; \
|
||||
ErrorPolicy::sequence_failed( context( MOCK_EXPECTATION_PARAMETERS(n) ), it->file(), it->line() ); \
|
||||
} \
|
||||
return it->functor()( BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_EXPECTATION_PARAMETER, BOOST_PP_EMPTY) ); \
|
||||
} \
|
||||
valid_ = false; \
|
||||
return ErrorPolicy::no_match( context( MOCK_EXPECTATION_PARAMETERS(n) ) ); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, MOCK_MAX_ARGS, MOCK_EXPECTATION_OPERATOR, BOOST_PP_EMPTY)
|
||||
#undef MOCK_EXPECTATION_PARAMETER
|
||||
#undef MOCK_EXPECTATION_PARAMETERS
|
||||
#undef MOCK_EXPECTATION_DETAIL
|
||||
#undef MOCK_EXPECTATION_OPERATOR
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const expectation& e )
|
||||
{
|
||||
return s << e.context();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::list< matcher_type > matchers_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
matchers_type::const_iterator matchers_cit;
|
||||
|
||||
void serialize( std::ostream& s ) const
|
||||
{
|
||||
for( matchers_cit it = matchers_.begin();
|
||||
it != matchers_.end(); ++it )
|
||||
s << std::endl << *it;
|
||||
}
|
||||
|
||||
std::string context() const
|
||||
{
|
||||
std::stringstream s;
|
||||
s << *parent_ << name_;
|
||||
serialize( s );
|
||||
return s.str();
|
||||
}
|
||||
std::string context( const std::string& parameters ) const
|
||||
{
|
||||
std::stringstream s;
|
||||
s << *parent_ << name_;
|
||||
if( parameters.empty() )
|
||||
s << "()";
|
||||
else
|
||||
s << "( " << parameters << " )";
|
||||
serialize( s );
|
||||
return s.str();
|
||||
}
|
||||
|
||||
std::string name_;
|
||||
node* parent_;
|
||||
mutable bool valid_;
|
||||
matchers_type matchers_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_EXPECTATION_HPP_INCLUDED
|
||||
78
src/libraries/turtle/format.hpp
Normal file
78
src/libraries/turtle/format.hpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_FORMAT_HPP_INCLUDED
|
||||
#define MOCK_FORMAT_HPP_INCLUDED
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct eater
|
||||
{
|
||||
template< typename T >
|
||||
eater( const T& ) {}
|
||||
};
|
||||
|
||||
struct eaten
|
||||
{};
|
||||
|
||||
template< typename S >
|
||||
eaten operator<<( S& s, const eater& );
|
||||
|
||||
template< int I >
|
||||
struct selector
|
||||
{
|
||||
};
|
||||
template<>
|
||||
struct selector< sizeof( std::ostream& ) >
|
||||
{
|
||||
typedef boost::true_type type;
|
||||
};
|
||||
template<>
|
||||
struct selector< sizeof( eaten ) >
|
||||
{
|
||||
typedef boost::false_type type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct is_serializable
|
||||
{
|
||||
static std::ostream& s();
|
||||
static const T& t();
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
selector< sizeof( s() << t() ) >::type type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
std::string format( const T& t,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if<
|
||||
BOOST_DEDUCED_TYPENAME detail::is_serializable< T >::type >::type* = 0 )
|
||||
{
|
||||
std::stringstream s;
|
||||
static_cast< std::ostream& >( s ) << std::boolalpha << t;
|
||||
return s.str();
|
||||
}
|
||||
template< typename T >
|
||||
std::string format( const T&,
|
||||
BOOST_DEDUCED_TYPENAME boost::disable_if<
|
||||
BOOST_DEDUCED_TYPENAME detail::is_serializable< T >::type >::type* = 0 )
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_FORMAT_HPP_INCLUDED
|
||||
160
src/libraries/turtle/functional.hpp
Normal file
160
src/libraries/turtle/functional.hpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_FUNCTIONAL_HPP_INCLUDED
|
||||
#define MOCK_FUNCTIONAL_HPP_INCLUDED
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class nothing
|
||||
{
|
||||
public:
|
||||
template< typename Y >
|
||||
bool operator()( const Y& ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class negation
|
||||
{
|
||||
public:
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return ! y;
|
||||
}
|
||||
};
|
||||
|
||||
class evaluation
|
||||
{
|
||||
public:
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return y();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class equality
|
||||
{
|
||||
public:
|
||||
explicit equality( const T& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return y == t_;
|
||||
}
|
||||
private:
|
||||
T t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class identity
|
||||
{
|
||||
public:
|
||||
explicit identity( const boost::reference_wrapper< T >& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return &y == t_.get_pointer();
|
||||
}
|
||||
private:
|
||||
boost::reference_wrapper< T > t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class inferiority
|
||||
{
|
||||
public:
|
||||
explicit inferiority( const T& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return y < t_;
|
||||
}
|
||||
private:
|
||||
T t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class superiority
|
||||
{
|
||||
public:
|
||||
explicit superiority( const T& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return y > t_;
|
||||
}
|
||||
private:
|
||||
T t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class assignment
|
||||
{
|
||||
public:
|
||||
explicit assignment( const T& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( Y& y ) const
|
||||
{
|
||||
y = t_;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
T t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class retrieval
|
||||
{
|
||||
public:
|
||||
explicit retrieval( const boost::reference_wrapper< T >& t )
|
||||
: t_( t )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y,
|
||||
BOOST_DEDUCED_TYPENAME boost::disable_if<
|
||||
boost::is_convertible< Y*, T >, Y >::type* = 0 ) const
|
||||
{
|
||||
t_.get() = y;
|
||||
return true;
|
||||
}
|
||||
template< typename Y >
|
||||
bool operator()( Y& y,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if<
|
||||
boost::is_convertible< Y*, T >, Y >::type* = 0 ) const
|
||||
{
|
||||
t_.get() = &y;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
boost::reference_wrapper< T > t_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_FUNCTIONAL_HPP_INCLUDED
|
||||
176
src/libraries/turtle/invocation.hpp
Normal file
176
src/libraries/turtle/invocation.hpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_INVOCATION_HPP_INCLUDED
|
||||
#define MOCK_INVOCATION_HPP_INCLUDED
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class invocation : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
invocation() {}
|
||||
|
||||
virtual ~invocation() {}
|
||||
|
||||
// Trigger invocation
|
||||
// returns false if the invocation has failed
|
||||
virtual bool invoke() = 0;
|
||||
|
||||
// Test whether the invocation is exhausted or not
|
||||
// returns false if the invocation is exhausted
|
||||
virtual bool is_valid() const = 0;
|
||||
|
||||
// Verify invocation
|
||||
virtual bool verify() const = 0;
|
||||
|
||||
friend inline std::ostream& operator<<( std::ostream& s, const invocation& i )
|
||||
{
|
||||
return i.serialize( s );
|
||||
}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const = 0;
|
||||
};
|
||||
|
||||
class between : public invocation
|
||||
{
|
||||
public:
|
||||
between( std::size_t min, std::size_t max )
|
||||
: min_ ( min )
|
||||
, max_ ( max )
|
||||
, count_( 0 )
|
||||
{
|
||||
if( min > max )
|
||||
throw std::invalid_argument( "'min' > 'max'" );
|
||||
}
|
||||
|
||||
virtual bool invoke()
|
||||
{
|
||||
if( count_ == max_ )
|
||||
return false;
|
||||
++count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool is_valid() const
|
||||
{
|
||||
return count_ < max_;
|
||||
}
|
||||
|
||||
virtual bool verify() const
|
||||
{
|
||||
return min_ <= count_ && count_ <= max_;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::size_t min_, max_;
|
||||
std::size_t count_;
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "between( " << count_ << "/[" << min_ << ',' << max_ << "] )";
|
||||
}
|
||||
};
|
||||
|
||||
class exactly : public between
|
||||
{
|
||||
public:
|
||||
explicit exactly( std::size_t count )
|
||||
: between( count, count )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "exactly( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class never : public exactly
|
||||
{
|
||||
public:
|
||||
never()
|
||||
: exactly( 0 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "never()";
|
||||
}
|
||||
};
|
||||
|
||||
class once : public exactly
|
||||
{
|
||||
public:
|
||||
once()
|
||||
: exactly( 1 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "once()";
|
||||
}
|
||||
};
|
||||
|
||||
class at_least : public between
|
||||
{
|
||||
public:
|
||||
explicit at_least( std::size_t min )
|
||||
: between( min, std::numeric_limits< std::size_t >::max() )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "at_least( " << count_ << '/' << min_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class at_most : public between
|
||||
{
|
||||
public:
|
||||
explicit at_most( std::size_t max )
|
||||
: between( 0, max )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "at_most( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class unlimited : public at_least
|
||||
{
|
||||
public:
|
||||
unlimited()
|
||||
: at_least( 0 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "unlimited()";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_INVOCATION_HPP_INCLUDED
|
||||
222
src/libraries/turtle/matcher.hpp
Normal file
222
src/libraries/turtle/matcher.hpp
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_MATCHER_HPP_INCLUDED
|
||||
#define MOCK_MATCHER_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "invocation.hpp"
|
||||
#include "result.hpp"
|
||||
#include "sequence.hpp"
|
||||
#include "check.hpp"
|
||||
#include "constraint.hpp"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class matcher_base : private orderable
|
||||
{
|
||||
public:
|
||||
matcher_base()
|
||||
: i_( new detail::unlimited() )
|
||||
, file_( "unknown location" )
|
||||
, line_( 0 )
|
||||
{}
|
||||
virtual ~matcher_base()
|
||||
{
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
(*it)->remove( *this );
|
||||
}
|
||||
|
||||
void set_location( const std::string& file, int line )
|
||||
{
|
||||
file_ = file;
|
||||
line_ = line;
|
||||
}
|
||||
|
||||
bool verify() const
|
||||
{
|
||||
return i_->verify();
|
||||
}
|
||||
|
||||
bool invoke() const
|
||||
{
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
if( ! (*it)->is_valid( *this ) )
|
||||
return false;
|
||||
bool result = i_->invoke();
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
(*it)->call( *this );
|
||||
return result;
|
||||
}
|
||||
|
||||
matcher_base& in( sequence& s )
|
||||
{
|
||||
s.add( *this );
|
||||
sequences_.push_back( &s );
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string& file() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
int line() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::shared_ptr< detail::invocation > i_;
|
||||
|
||||
void expect( detail::invocation* i )
|
||||
{
|
||||
i_.reset( i );
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void remove( sequence& s )
|
||||
{
|
||||
sequences_.erase( std::remove( sequences_.begin(),
|
||||
sequences_.end(), &s ), sequences_.end() );
|
||||
}
|
||||
|
||||
typedef std::vector< sequence* > sequences_type;
|
||||
typedef sequences_type::const_iterator sequences_cit;
|
||||
|
||||
sequences_type sequences_;
|
||||
std::string file_;
|
||||
int line_;
|
||||
};
|
||||
|
||||
template< typename Result, typename Signature, typename ErrorPolicy, int >
|
||||
class matcher
|
||||
{
|
||||
};
|
||||
|
||||
#define MOCK_INVOCATIONS \
|
||||
matcher& once() \
|
||||
{ \
|
||||
expect( new detail::once() ); \
|
||||
return *this; \
|
||||
} \
|
||||
matcher& never() \
|
||||
{ \
|
||||
expect( new detail::never() ); \
|
||||
return *this; \
|
||||
} \
|
||||
matcher& exactly( std::size_t count ) \
|
||||
{ \
|
||||
expect( new detail::exactly( count ) ); \
|
||||
return *this; \
|
||||
} \
|
||||
matcher& at_least( std::size_t min ) \
|
||||
{ \
|
||||
expect( new detail::at_least( min ) ); \
|
||||
return *this; \
|
||||
} \
|
||||
matcher& at_most( std::size_t max ) \
|
||||
{ \
|
||||
expect( new detail::at_most( max ) ); \
|
||||
return *this; \
|
||||
} \
|
||||
matcher& between( std::size_t min, std::size_t max ) \
|
||||
{ \
|
||||
expect( new detail::at_most( min, max ) ); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
template< typename Result, typename Signature, typename ErrorPolicy >
|
||||
class matcher< Result, Signature, ErrorPolicy, 0 >
|
||||
: public matcher_base, public result< Result, Signature, ErrorPolicy >
|
||||
{
|
||||
public:
|
||||
bool is_valid() const
|
||||
{
|
||||
return i_->is_valid();
|
||||
}
|
||||
|
||||
MOCK_INVOCATIONS
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
|
||||
{
|
||||
return s << (m.i_->is_valid() ? '.' : 'v')
|
||||
<< " expect( " << *m.i_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
#define MOCK_MATCHER_TYPEDEF(z, n, d) \
|
||||
typedef BOOST_DEDUCED_TYPENAME \
|
||||
boost::function< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) arg##n##_type; \
|
||||
typedef detail::check< arg##n##_type > constraint##n##_type;
|
||||
#define MOCK_MATCHER_CONSTRUCTOR(z, n, d) BOOST_PP_COMMA_IF(n) c##n##_ ( any )
|
||||
#define MOCK_MATCHER_WITH(z, n, d) c##n##_ = constraint##n##_type( c##n );
|
||||
#define MOCK_MATCHER_MEMBER(z, n, d) constraint##n##_type c##n##_;
|
||||
#define MOCK_MATCHER_IS_VALID_PARAMS(z, n, d) BOOST_PP_COMMA_IF(n) arg##n##_type a##n
|
||||
#define MOCK_MATCHER_IS_VALID(z, n, d) && c##n##_( a##n )
|
||||
#define MOCK_MATCHER_SERIALIZE(z, n, d) << ", " << m.c##n##_
|
||||
#define MOCK_MATCHER(z, n, d) \
|
||||
template< typename Result, typename Signature, typename ErrorPolicy > \
|
||||
class matcher< Result, Signature, ErrorPolicy, n > \
|
||||
: public matcher_base, public result< Result, Signature, ErrorPolicy > \
|
||||
{ \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_TYPEDEF, BOOST_PP_EMPTY) \
|
||||
public: \
|
||||
matcher() \
|
||||
: BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_CONSTRUCTOR, BOOST_PP_EMPTY) \
|
||||
{} \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename C) > \
|
||||
matcher& with( BOOST_PP_ENUM_BINARY_PARAMS(n, const C, & c) ) \
|
||||
{ \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_WITH, BOOST_PP_EMPTY) \
|
||||
return *this; \
|
||||
} \
|
||||
bool is_valid( BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_IS_VALID_PARAMS, BOOST_PP_EMPTY) ) const \
|
||||
{ \
|
||||
return i_->is_valid() \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_IS_VALID, BOOST_PP_EMPTY); \
|
||||
} \
|
||||
MOCK_INVOCATIONS \
|
||||
friend std::ostream& operator<<( std::ostream& s, const matcher& m ) \
|
||||
{ \
|
||||
return s << (m.i_->is_valid() ? '.' : 'v') \
|
||||
<< " expect( " << *m.i_ << " ).with( " \
|
||||
<< m.c0_ \
|
||||
BOOST_PP_REPEAT_FROM_TO(1, n, MOCK_MATCHER_SERIALIZE, BOOST_PP_EMPTY) \
|
||||
<< " )"; \
|
||||
} \
|
||||
private: \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_MEMBER, BOOST_PP_EMPTY) \
|
||||
};
|
||||
BOOST_PP_REPEAT_FROM_TO(1, MOCK_MAX_ARGS, MOCK_MATCHER, BOOST_PP_EMPTY)
|
||||
|
||||
#undef MOCK_INVOCATIONS
|
||||
#undef MOCK_MATCHER_TYPEDEF
|
||||
#undef MOCK_MATCHER_CONSTRUCTOR
|
||||
#undef MOCK_MATCHER_WITH
|
||||
#undef MOCK_MATCHER_MEMBER
|
||||
#undef MOCK_MATCHER_IS_VALID_PARAMS
|
||||
#undef MOCK_MATCHER_IS_VALID
|
||||
#undef MOCK_MATCHER_SERIALIZE
|
||||
#undef MOCK_MATCHER
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_MATCHER_HPP_INCLUDED
|
||||
91
src/libraries/turtle/node.hpp
Normal file
91
src/libraries/turtle/node.hpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_NODE_HPP_INCLUDED
|
||||
#define MOCK_NODE_HPP_INCLUDED
|
||||
|
||||
#include "verifiable.hpp"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class node : private verifiable
|
||||
{
|
||||
public:
|
||||
node()
|
||||
: parent_( 0 )
|
||||
{}
|
||||
explicit node( node& parent )
|
||||
: verifiable()
|
||||
, parent_( &parent )
|
||||
{
|
||||
if( parent_ )
|
||||
parent_->add( *this );
|
||||
}
|
||||
virtual ~node()
|
||||
{
|
||||
if( parent_ )
|
||||
parent_->remove( *this );
|
||||
}
|
||||
|
||||
void set_parent( node& parent )
|
||||
{
|
||||
if( parent_ )
|
||||
parent_->remove( *this );
|
||||
parent_ = &parent;
|
||||
parent_->add( *this );
|
||||
}
|
||||
|
||||
void add( verifiable& e )
|
||||
{
|
||||
v_.push_back( &e );
|
||||
}
|
||||
void remove( verifiable& e )
|
||||
{
|
||||
v_.erase( std::remove( v_.begin(), v_.end(), &e ), v_.end() );
|
||||
}
|
||||
|
||||
virtual bool verify()
|
||||
{
|
||||
bool valid = true;
|
||||
for( verifiables_cit it = v_.begin(); it != v_.end(); ++it )
|
||||
if( ! (*it)->verify() )
|
||||
valid = false;
|
||||
return valid;
|
||||
}
|
||||
virtual void reset()
|
||||
{
|
||||
std::for_each( v_.begin(), v_.end(),
|
||||
std::mem_fun( &verifiable::reset ) );
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, node& n )
|
||||
{
|
||||
if( n.parent_ )
|
||||
s << *n.parent_;
|
||||
n.serialize( s );
|
||||
return s;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void serialize( std::ostream& s ) const = 0;
|
||||
|
||||
private:
|
||||
typedef std::vector< verifiable* > verifiables_type;
|
||||
typedef verifiables_type::const_iterator verifiables_cit;
|
||||
|
||||
node* parent_;
|
||||
std::vector< verifiable* > v_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_NODE_HPP_INCLUDED
|
||||
47
src/libraries/turtle/object.hpp
Normal file
47
src/libraries/turtle/object.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_OBJECT_HPP_INCLUDED
|
||||
#define MOCK_OBJECT_HPP_INCLUDED
|
||||
|
||||
#include "node.hpp"
|
||||
#include "root.hpp"
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class object : public node
|
||||
{
|
||||
public:
|
||||
explicit object( node& parent = root, const std::string& name = "" )
|
||||
: node( parent )
|
||||
, name_( name )
|
||||
{}
|
||||
explicit object( const std::string& name )
|
||||
: node( root )
|
||||
, name_( name )
|
||||
{}
|
||||
|
||||
void set_name( const std::string& name )
|
||||
{
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
{
|
||||
s << (name_.empty() ? "?" : name_) << "::";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_OBJECT_HPP_INCLUDED
|
||||
111
src/libraries/turtle/placeholder.hpp
Normal file
111
src/libraries/turtle/placeholder.hpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_PLACEHOLDER_HPP_INCLUDED
|
||||
#define MOCK_PLACEHOLDER_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Functor >
|
||||
struct placeholder
|
||||
{
|
||||
placeholder( const Functor& f, const std::string& desc )
|
||||
: functor_( f )
|
||||
, desc_ ( desc )
|
||||
{}
|
||||
Functor functor_;
|
||||
std::string desc_;
|
||||
};
|
||||
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
class and_
|
||||
{
|
||||
public:
|
||||
and_( const Constraint1& c1, const Constraint2& c2 )
|
||||
: c1_( c1 )
|
||||
, c2_( c2 )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return c1_( y ) && c2_( y );
|
||||
}
|
||||
private:
|
||||
Constraint1 c1_;
|
||||
Constraint2 c2_;
|
||||
};
|
||||
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
class or_
|
||||
{
|
||||
public:
|
||||
or_( const Constraint1& c1, const Constraint2& c2 )
|
||||
: c1_( c1 )
|
||||
, c2_( c2 )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return c1_( y ) || c2_( y );
|
||||
}
|
||||
private:
|
||||
Constraint1 c1_;
|
||||
Constraint2 c2_;
|
||||
};
|
||||
|
||||
template< typename Constraint >
|
||||
class not_
|
||||
{
|
||||
public:
|
||||
explicit not_( const Constraint& c )
|
||||
: c_( c )
|
||||
{}
|
||||
template< typename Y >
|
||||
bool operator()( const Y& y ) const
|
||||
{
|
||||
return ! c_( y );
|
||||
}
|
||||
private:
|
||||
Constraint c_;
|
||||
};
|
||||
|
||||
template< typename F1, typename F2 >
|
||||
const placeholder< or_< F1, F2 > >
|
||||
operator||( const placeholder< F1 >& lhs,
|
||||
const placeholder< F2 >& rhs )
|
||||
{
|
||||
return placeholder< or_< F1, F2 > >(
|
||||
or_< F1, F2 >( lhs.functor_, rhs.functor_ ),
|
||||
"(" + lhs.desc_ + " || " + rhs.desc_ + ")" );
|
||||
}
|
||||
|
||||
template< typename F1, typename F2 >
|
||||
const placeholder< and_< F1, F2 > >
|
||||
operator&&( const placeholder< F1 >& lhs,
|
||||
const placeholder< F2 >& rhs )
|
||||
{
|
||||
return placeholder< and_< F1, F2 > >(
|
||||
and_< F1, F2 >( lhs.functor_, rhs.functor_ ),
|
||||
"(" + lhs.desc_ + " && " + rhs.desc_ + ")" );
|
||||
}
|
||||
|
||||
template< typename F >
|
||||
const placeholder< not_< F > >
|
||||
operator!( const placeholder< F >& ph )
|
||||
{
|
||||
return placeholder< not_< F > >(
|
||||
not_< F >( ph.functor_ ), "! " + ph.desc_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_PLACEHOLDER_HPP_INCLUDED
|
||||
254
src/libraries/turtle/result.hpp
Normal file
254
src/libraries/turtle/result.hpp
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_RESULT_HPP_INCLUDED
|
||||
#define MOCK_RESULT_HPP_INCLUDED
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename T, typename Signature, typename ErrorPolicy >
|
||||
class result
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
public:
|
||||
template< typename Value >
|
||||
void returns( Value v )
|
||||
{
|
||||
set( v );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = boost::bind( &throw_exception< Exception >, e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
if( !f_ )
|
||||
ErrorPolicy::missing_result_specification();
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
void set( T t )
|
||||
{
|
||||
f_ = boost::bind( &return_value, t );
|
||||
}
|
||||
template< typename Y >
|
||||
void set( const boost::reference_wrapper< Y >& t )
|
||||
{
|
||||
f_ = boost::bind( &return_value, t );
|
||||
}
|
||||
|
||||
static T return_value( T t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
static T throw_exception( const Exception& e )
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename T, typename Signature, typename ErrorPolicy >
|
||||
class result< T*, Signature, ErrorPolicy >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
public:
|
||||
void returns( T* t )
|
||||
{
|
||||
f_ = boost::bind( &return_value, t );
|
||||
}
|
||||
template< typename Y >
|
||||
void returns( const boost::reference_wrapper< Y >& t )
|
||||
{
|
||||
f_ = boost::bind( &return_value, t );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = boost::bind( &throw_exception< Exception >, e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
if( !f_ )
|
||||
ErrorPolicy::missing_result_specification();
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
static T* return_value( T* t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
static T* throw_exception( const Exception& e )
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename Signature, typename ErrorPolicy >
|
||||
class result< void, Signature, ErrorPolicy >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
public:
|
||||
result()
|
||||
: f_( boost::bind( ¬hing ) )
|
||||
{}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = boost::bind( &throw_exception< Exception >, e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
static void nothing()
|
||||
{}
|
||||
|
||||
template< typename Exception >
|
||||
static void throw_exception( const Exception& e )
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename T, typename Signature, typename ErrorPolicy >
|
||||
class result< std::auto_ptr< T >, Signature, ErrorPolicy >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
public:
|
||||
result()
|
||||
: t_()
|
||||
, f_()
|
||||
{}
|
||||
result( const result& rhs )
|
||||
: t_( const_cast< result& >( rhs ).t_.release() )
|
||||
, f_( t_.get() ? boost::bind( &return_value, boost::ref( t_ ) ) : rhs.f_ )
|
||||
{}
|
||||
|
||||
template< typename Value >
|
||||
void returns( Value v )
|
||||
{
|
||||
set( v );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = boost::bind( &throw_exception< Exception >, e );
|
||||
t_.reset();
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
if( !f_ )
|
||||
ErrorPolicy::missing_result_specification();
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename Y >
|
||||
void set( std::auto_ptr< Y > t )
|
||||
{
|
||||
t_ = t;
|
||||
f_ = boost::bind( &return_value, boost::ref( t_ ) );
|
||||
}
|
||||
template< typename Y >
|
||||
void set( const boost::reference_wrapper< Y >& t )
|
||||
{
|
||||
f_ = boost::bind( &return_value, t );
|
||||
t_.reset();
|
||||
}
|
||||
template< typename Y >
|
||||
void set( Y* t )
|
||||
{
|
||||
t_.reset( t );
|
||||
f_ = boost::bind( &return_value, boost::ref( t_ ) );
|
||||
}
|
||||
|
||||
static std::auto_ptr< T > return_value( std::auto_ptr< T > t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
static std::auto_ptr< T > throw_exception( const Exception& e )
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
mutable std::auto_ptr< T > t_;
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_RESULT_HPP_INCLUDED
|
||||
36
src/libraries/turtle/root.hpp
Normal file
36
src/libraries/turtle/root.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_ROOT_HPP_INCLUDED
|
||||
#define MOCK_ROOT_HPP_INCLUDED
|
||||
|
||||
#include "node.hpp"
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class root_t : public boost::unit_test::singleton< root_t >, public node
|
||||
{
|
||||
private:
|
||||
virtual void serialize( std::ostream& /*s*/ ) const
|
||||
{}
|
||||
BOOST_TEST_SINGLETON_CONS( root_t );
|
||||
};
|
||||
BOOST_TEST_SINGLETON_INST( root )
|
||||
|
||||
inline bool verify()
|
||||
{
|
||||
return root.verify();
|
||||
}
|
||||
inline void reset()
|
||||
{
|
||||
root.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_ROOT_HPP_INCLUDED
|
||||
83
src/libraries/turtle/sequence.hpp
Normal file
83
src/libraries/turtle/sequence.hpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_SEQUENCE_HPP_INCLUDED
|
||||
#define MOCK_SEQUENCE_HPP_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class sequence;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class orderable
|
||||
{
|
||||
public:
|
||||
orderable() {}
|
||||
virtual ~orderable() {}
|
||||
|
||||
virtual void remove( sequence& s ) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
class sequence
|
||||
{
|
||||
public:
|
||||
~sequence()
|
||||
{
|
||||
for( elements_it it = elements_.begin();
|
||||
it != elements_.end(); ++it )
|
||||
(*it)->remove( *this );
|
||||
for( elements_it it = called_.begin();
|
||||
it != called_.end(); ++it )
|
||||
(*it)->remove( *this );
|
||||
}
|
||||
|
||||
void add( detail::orderable& e )
|
||||
{
|
||||
elements_.push_back( &e );
|
||||
}
|
||||
void remove( detail::orderable& e )
|
||||
{
|
||||
elements_.erase( std::remove( elements_.begin(),
|
||||
elements_.end(), &e ), elements_.end() );
|
||||
called_.erase( std::remove( called_.begin(),
|
||||
called_.end(), &e ), called_.end() );
|
||||
}
|
||||
|
||||
bool is_valid( const detail::orderable& e ) const
|
||||
{
|
||||
return std::find( called_.begin(), called_.end(), &e )
|
||||
== called_.end();
|
||||
}
|
||||
|
||||
void call( const detail::orderable& e )
|
||||
{
|
||||
elements_it it =
|
||||
std::find( elements_.begin(), elements_.end(), &e );
|
||||
if( it != elements_.end() )
|
||||
{
|
||||
std::copy( elements_.begin(), it,
|
||||
std::back_inserter( called_ ) );
|
||||
elements_.erase( elements_.begin(), it );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector< detail::orderable* > elements_type;
|
||||
typedef elements_type::iterator elements_it;
|
||||
|
||||
elements_type elements_;
|
||||
elements_type called_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_SEQUENCE_HPP_INCLUDED
|
||||
156
src/libraries/turtle/tools.hpp
Normal file
156
src/libraries/turtle/tools.hpp
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_TOOLS_HPP_INCLUDED
|
||||
#define MOCK_TOOLS_HPP_INCLUDED
|
||||
|
||||
#include "error.hpp"
|
||||
#include "object.hpp"
|
||||
#include "expectation.hpp"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/seq/push_back.hpp>
|
||||
#include <boost/preprocessor/seq/pop_back.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/function_type.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/erase.hpp>
|
||||
#include <boost/mpl/insert_range.hpp>
|
||||
#include <boost/mpl/back_inserter.hpp>
|
||||
#define BOOST_TYPEOF_SILENT
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename T >
|
||||
T& ref( T& t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
template< typename T >
|
||||
T& ref( T* t )
|
||||
{
|
||||
if( ! t )
|
||||
throw std::invalid_argument( "derefencing null pointer" );
|
||||
return *t;
|
||||
}
|
||||
template< typename T >
|
||||
T& ref( std::auto_ptr< T >& t )
|
||||
{
|
||||
if( ! t.get() )
|
||||
throw std::invalid_argument( "derefencing null pointer" );
|
||||
return *t;
|
||||
}
|
||||
template< typename T >
|
||||
T& ref( boost::shared_ptr< T >& t )
|
||||
{
|
||||
if( ! t.get() )
|
||||
throw std::invalid_argument( "derefencing null pointer" );
|
||||
return *t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MOCK_MIXIN(T) \
|
||||
template< typename U > struct T##_mock_mixin : U \
|
||||
{ \
|
||||
explicit T##_mock_mixin( const std::string& tag = "" ) \
|
||||
{ \
|
||||
mock::object::set_name( BOOST_PP_STRINGIZE(T) + tag ); \
|
||||
} \
|
||||
explicit T##_mock_mixin( mock::node& parent, const std::string& tag = "" ) \
|
||||
{ \
|
||||
mock::object::set_name( BOOST_PP_STRINGIZE(T) + tag ); \
|
||||
mock::node::set_parent( parent ); \
|
||||
} \
|
||||
}; \
|
||||
struct T##_super_class; \
|
||||
typedef T##_mock_mixin< T##_super_class > T;
|
||||
#define MOCK_INTERFACE(T, I) \
|
||||
MOCK_MIXIN(T) \
|
||||
struct T##_typedef { typedef I interface_type; }; \
|
||||
struct T##_super_class : I, mock::object, private T##_typedef
|
||||
#define MOCK_CLASS(T) \
|
||||
MOCK_MIXIN(T) \
|
||||
struct T##_super_class : mock::object
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename M >
|
||||
struct signature
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function_types::result_type< M >::type result;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function_types::parameter_types< M >::type parameters;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function_types::function_type<
|
||||
BOOST_DEDUCED_TYPENAME boost::mpl::push_front<
|
||||
BOOST_DEDUCED_TYPENAME boost::mpl::pop_front<
|
||||
BOOST_DEDUCED_TYPENAME boost::mpl::copy<
|
||||
parameters,
|
||||
boost::mpl::back_inserter<
|
||||
boost::mpl::vector<>
|
||||
>
|
||||
>::type
|
||||
>::type,
|
||||
result
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#define MOCK_METHOD_ARG(z, n, S) BOOST_PP_COMMA_IF(n) \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(boost::function< S >::arg, BOOST_PP_INC(n)),_type) \
|
||||
BOOST_PP_CAT(a, BOOST_PP_INC(n))
|
||||
#define MOCK_METHOD_ARGS(n, S) \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_METHOD_ARG, S)
|
||||
#define MOCK_MOCKER_ARG(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(a, BOOST_PP_INC(n))
|
||||
#define MOCK_MOCKER_ARGS(n, M) \
|
||||
BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MOCKER_ARG, BOOST_PP_EMPTY)
|
||||
#define MOCK_METHOD_STUB(M, n, S, t, c) \
|
||||
boost::function< S >::result_type M( MOCK_METHOD_ARGS(n, S) ) c \
|
||||
{ \
|
||||
return MOCK_MOCKER(*this, t)( MOCK_MOCKER_ARGS(n, M) ); \
|
||||
}
|
||||
#define MOCK_METHOD_EXPECTATION(S, t) \
|
||||
mutable mock::expectation< S > t##_exp;
|
||||
#define MOCK_METHOD_EXT(M, n, S, t) \
|
||||
MOCK_METHOD_STUB(M, n, S, t,) \
|
||||
MOCK_METHOD_STUB(M, n, S, t, const) \
|
||||
MOCK_METHOD_EXPECTATION(S, t)
|
||||
#define MOCK_CONST_METHOD_EXT(M, n, S, t) \
|
||||
MOCK_METHOD_STUB(M, n, S, t, const) \
|
||||
MOCK_METHOD_EXPECTATION(S, t)
|
||||
#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) \
|
||||
MOCK_METHOD_STUB(M, n, S, t,) \
|
||||
MOCK_METHOD_EXPECTATION(S, t)
|
||||
#define MOCK_METHOD(M, n) \
|
||||
MOCK_METHOD_EXT(M, n, MOCK_SIGNATURE(&interface_type::M), M)
|
||||
#define MOCK_SIGNATURE(pM) \
|
||||
mock::detail::signature< BOOST_TYPEOF(pM) >::type
|
||||
#define MOCK_MOCKER(m, t) \
|
||||
mock::detail::ref( m ).t##_exp.set_name( BOOST_PP_STRINGIZE(t) ).set_parent( \
|
||||
const_cast< mock::object& >( dynamic_cast< const mock::object& >( mock::detail::ref( m ) ) ) )
|
||||
|
||||
#define MOCK_EXPECT(m,t) MOCK_MOCKER(m,t).expect( __FILE__, __LINE__ )
|
||||
#define MOCK_RESET(m,t) MOCK_MOCKER(m,t).reset()
|
||||
#define MOCK_VERIFY(m,t) MOCK_MOCKER(m,t).verify()
|
||||
|
||||
#endif // #ifndef MOCK_TOOLS_HPP_INCLUDED
|
||||
30
src/libraries/turtle/verifiable.hpp
Normal file
30
src/libraries/turtle/verifiable.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef MOCK_VERIFIABLE_HPP_INCLUDED
|
||||
#define MOCK_VERIFIABLE_HPP_INCLUDED
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class verifiable : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
verifiable() {}
|
||||
virtual ~verifiable() {}
|
||||
|
||||
// return false if verification fails
|
||||
virtual bool verify() = 0;
|
||||
|
||||
// return to the initial state where calling verify won't throw
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef MOCK_VERIFIABLE_HPP_INCLUDED
|
||||
164
src/tests/turtle_test/constraint_test.cpp
Normal file
164
src/tests/turtle_test/constraint_test.cpp
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/constraint.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( all_comparison_constraints_can_be_instanciated )
|
||||
{
|
||||
mock::any;
|
||||
mock::negate;
|
||||
mock::evaluate;
|
||||
mock::equal( 0 );
|
||||
mock::less( 0 );
|
||||
mock::greater( 0 );
|
||||
mock::less_equal( 0 );
|
||||
mock::greater_equal( 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( constraints_can_be_negated_using_the_not_operator )
|
||||
{
|
||||
! mock::any;
|
||||
! mock::negate;
|
||||
! mock::evaluate;
|
||||
! mock::equal( 0 );
|
||||
! mock::less( 0 );
|
||||
! mock::greater( 0 );
|
||||
! mock::less_equal( 0 );
|
||||
! mock::greater_equal( 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( constraints_can_be_combined_using_the_or_operator )
|
||||
{
|
||||
mock::less( 0 ) || mock::greater( 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( constraints_can_be_combined_using_the_and_operator )
|
||||
{
|
||||
mock::less( 0 ) && mock::greater( 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( same )
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
BOOST_CHECK_EQUAL( i, j );
|
||||
BOOST_CHECK( ! mock::same( i ).functor_( j ) );
|
||||
BOOST_CHECK( mock::same( i ).functor_( i ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( assign )
|
||||
{
|
||||
{
|
||||
int i = 0;
|
||||
BOOST_CHECK( mock::assign( 3 ).functor_( i ) );
|
||||
BOOST_CHECK_EQUAL( 3, i );
|
||||
}
|
||||
{
|
||||
const int* i = 0;
|
||||
const int j = 1;
|
||||
BOOST_CHECK( mock::assign( &j ).functor_( i ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( retrieve )
|
||||
{
|
||||
{
|
||||
int i = 0;
|
||||
const int j = 1;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, j );
|
||||
}
|
||||
{
|
||||
int* i = 0;
|
||||
int j = 1;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( &j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
{
|
||||
const int* i = 0;
|
||||
const int j = 1;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
{
|
||||
int* i = 0;
|
||||
int j = 1;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
{
|
||||
const int* i = 0;
|
||||
const int j = 1;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
{
|
||||
int** i = 0;
|
||||
int* j = 0;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
{
|
||||
const int** i = 0;
|
||||
const int* j = 0;
|
||||
BOOST_CHECK( mock::retrieve( i ).functor_( j ) );
|
||||
BOOST_CHECK_EQUAL( i, &j );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A
|
||||
{
|
||||
};
|
||||
struct B
|
||||
{
|
||||
B& operator=( const A& )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( retrieve_uses_assignment_operator )
|
||||
{
|
||||
B b;
|
||||
const A a = A();
|
||||
mock::retrieve( b ).functor_( a );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negate )
|
||||
{
|
||||
int* i = 0;
|
||||
int j;
|
||||
BOOST_CHECK( mock::negate.functor_( i ) );
|
||||
BOOST_CHECK( ! mock::negate.functor_( &j ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool return_true()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool return_false()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( evaluate )
|
||||
{
|
||||
BOOST_CHECK( mock::evaluate.functor_( &return_true ) );
|
||||
BOOST_CHECK( ! mock::evaluate.functor_( &return_false ) );
|
||||
}
|
||||
27
src/tests/turtle_test/error_test.cpp
Normal file
27
src/tests/turtle_test/error_test.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/error.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( a_mock_exception_is_not_an_std_exception_to_not_mess_with_user_exceptions )
|
||||
{
|
||||
try
|
||||
{
|
||||
throw mock::exception( "" );
|
||||
}
|
||||
catch( std::exception& )
|
||||
{
|
||||
BOOST_FAIL( "mock::exception must not be an std::exception" );
|
||||
}
|
||||
catch( mock::exception& )
|
||||
{}
|
||||
}
|
||||
762
src/tests/turtle_test/expectation_test.cpp
Normal file
762
src/tests/turtle_test/expectation_test.cpp
Normal file
|
|
@ -0,0 +1,762 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#define BOOST_AUTO_TEST_MAIN
|
||||
#include <turtle/expectation.hpp>
|
||||
#include <turtle/constraint.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool check_exception_contains( const mock::exception& e, const std::string& str )
|
||||
{
|
||||
return e.what().find( str ) != std::string::npos;
|
||||
}
|
||||
}
|
||||
#define BOOST_CHECK_EXCEPTION_CONTAINS( S, C ) \
|
||||
BOOST_CHECK_EXCEPTION( S, mock::exception, boost::bind( &check_exception_contains, _1, C ) );
|
||||
|
||||
// functor
|
||||
|
||||
BOOST_AUTO_TEST_CASE( an_expectation_can_be_passed_as_functor_using_boost_bind_and_boost_ref )
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
boost::function< void() > f = boost::bind( boost::ref( e ) );
|
||||
}
|
||||
|
||||
// invocations
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_empty_expectation_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_a_never_expectation_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect().never();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect().never();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_unlimited_expectation_never_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect();
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int, const std::string& ) > e;
|
||||
e.expect();
|
||||
BOOST_CHECK_NO_THROW( e( 1, "s" ) );
|
||||
BOOST_CHECK_NO_THROW( e( 1, "s" ) );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_a_once_expectation_throws_after_one_call )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect().once();
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int, const std::string& ) > e;
|
||||
e.expect().once();
|
||||
BOOST_CHECK_NO_THROW( e( 1, "s" ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_expectation_operator_call_as_pointers )
|
||||
{
|
||||
mock::expectation< void( int* ) > e;
|
||||
e( 0 );
|
||||
}
|
||||
*/
|
||||
|
||||
// verify
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_an_empty_expectation_succeeds )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_an_unlimited_expectation_succeeds )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect();
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect();
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_a_once_expectation_after_one_call_succeeds )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect().once();
|
||||
e();
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int, const std::string& ) > e;
|
||||
e.expect().once();
|
||||
e( 1, "s" );
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template< typename Result >
|
||||
struct silent_error
|
||||
{
|
||||
static Result no_match( const std::string& context )
|
||||
{
|
||||
throw std::runtime_error( __FUNCTION__ );
|
||||
}
|
||||
static void sequence_failed( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{}
|
||||
static void verification_failed( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{}
|
||||
static void untriggered_expectation( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_a_once_expectation_before_the_call_fails )
|
||||
{
|
||||
{
|
||||
mock::expectation< void(), silent_error< void > > e;
|
||||
e.expect().once();
|
||||
BOOST_CHECK( ! e.verify() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ), silent_error< int > > e;
|
||||
e.expect().once();
|
||||
BOOST_CHECK( ! e.verify() );
|
||||
}
|
||||
}
|
||||
|
||||
// reset
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_a_reset_expectation_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect();
|
||||
e.reset();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect();
|
||||
e.reset();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_a_reset_expectation_succeeds )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect();
|
||||
e.reset();
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect();
|
||||
e.reset();
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
}
|
||||
|
||||
// constraints
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_constraint_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( 42 );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect().with( 42, "expected" );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( passing_raw_parameter_as_constraint_falls_back_to_using_the_equal_constraint )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( 42 );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect().with( 42, "expected" );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_or_less_constraint_throws )
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( mock::equal( 42 ) || mock::less( 42 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 41 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 42 ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_and_not_less_constraint_throws )
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( mock::equal( 42 ) && ! mock::less( 41 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 42 ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class my_interface : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~my_interface() {}
|
||||
private:
|
||||
virtual void my_method() = 0;
|
||||
};
|
||||
class my_implementation : public my_interface
|
||||
{
|
||||
virtual void my_method() {}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( passing_call_values_by_reference_is_transparent )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( my_interface& ) > e;
|
||||
my_implementation imp;
|
||||
e.expect().with( mock::same( imp ) );
|
||||
e( imp );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( const my_interface& ) > e;
|
||||
my_implementation imp;
|
||||
e.expect().with( mock::same( imp ) );
|
||||
e( imp );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool custom_constraint( int )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_failing_custom_constraint_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( mock::constraint( &custom_constraint ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 42 ), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int( int, const std::string& ) > e;
|
||||
e.expect().with( mock::constraint( &custom_constraint ), "actual" );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_custom_constraint_throws )
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( mock::constraint( &custom_constraint, "custom constraint" ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 42 ), "custom constraint" );
|
||||
}
|
||||
/*
|
||||
BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_place_of_null_pointers_in_constraints )
|
||||
{
|
||||
mock::expectation< void( int* ) > e;
|
||||
e.expect().with( 0 );
|
||||
e.reset();
|
||||
}
|
||||
*/
|
||||
|
||||
// result handling
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_no_return_set_throws )
|
||||
{
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
e.expect();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
e.expect();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" );
|
||||
}
|
||||
{
|
||||
mock::expectation< const std::string&() > e;
|
||||
e.expect();
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_returns_the_set_value )
|
||||
{
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
e.expect().returns( 42 );
|
||||
BOOST_CHECK_EQUAL( 42, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
const int i = 42;
|
||||
e.expect().returns( i );
|
||||
BOOST_CHECK_EQUAL( i, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
int i = 42;
|
||||
e.expect().returns( boost::ref( i ) );
|
||||
i = 43;
|
||||
BOOST_CHECK_EQUAL( 43, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
e.expect().returns( 42 );
|
||||
BOOST_CHECK_EQUAL( 42, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
const int result = 42;
|
||||
e.expect().returns( result );
|
||||
BOOST_CHECK_EQUAL( result, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
int i = 42;
|
||||
e.expect().returns( i );
|
||||
i = 43;
|
||||
BOOST_CHECK_EQUAL( 42, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
int i = 42;
|
||||
e.expect().returns( boost::ref( i ) );
|
||||
i = 43;
|
||||
BOOST_CHECK_EQUAL( 43, e() );
|
||||
BOOST_CHECK_EQUAL( 12, e() = 12 );
|
||||
BOOST_CHECK_EQUAL( 12, i );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::string() > e;
|
||||
e.expect().returns( "result" );
|
||||
BOOST_CHECK_EQUAL( "result", e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< const std::string&() > e;
|
||||
e.expect().returns( "result" );
|
||||
BOOST_CHECK_EQUAL( "result", e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int*() > e;
|
||||
e.expect().returns( 0 );
|
||||
BOOST_CHECK( ! e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
e.expect().returns( 0 );
|
||||
BOOST_CHECK_EQUAL( 0, e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< int&() > e;
|
||||
e.expect().returns( 0 );
|
||||
BOOST_CHECK_EQUAL( 0, e() );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A {};
|
||||
struct B : A {};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_returns_the_set_auto_ptr_value )
|
||||
{
|
||||
{
|
||||
mock::expectation< std::auto_ptr< int >() > e;
|
||||
std::auto_ptr< int > ptr( new int( 3 ) );
|
||||
e.expect().returns( boost::ref( ptr ) );
|
||||
BOOST_CHECK_EQUAL( 3, *ptr );
|
||||
BOOST_CHECK_EQUAL( 3, *e() );
|
||||
BOOST_CHECK( ! ptr.get() );
|
||||
BOOST_CHECK( ! e().get() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< int >() > e;
|
||||
std::auto_ptr< int > ptr( new int( 3 ) );
|
||||
e.expect().returns( ptr );
|
||||
BOOST_CHECK( ! ptr.get() );
|
||||
BOOST_CHECK_EQUAL( 3, *e() );
|
||||
BOOST_CHECK( ! e().get() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< int >() > e;
|
||||
e.expect().returns( new int( 3 ) );
|
||||
BOOST_CHECK_EQUAL( 3, *e() );
|
||||
BOOST_CHECK( ! e().get() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< int >() > e;
|
||||
e.expect().returns( std::auto_ptr< int >( new int( 3 ) ) );
|
||||
BOOST_CHECK_EQUAL( 3, *e() );
|
||||
BOOST_CHECK( ! e().get() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< A >() > e;
|
||||
e.expect().returns( new B );
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< A >() > e;
|
||||
e.expect().returns( std::auto_ptr< A >( new B ) );
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
}
|
||||
{
|
||||
mock::expectation< std::auto_ptr< A >() > e;
|
||||
e.expect().returns( std::auto_ptr< B >( new B ) );
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
int custom_result()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor )
|
||||
{
|
||||
mock::expectation< int() > e;
|
||||
e.expect().calls( &custom_result );
|
||||
BOOST_CHECK_EQUAL( 42, e() );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
int custom_result_with_parameter( int i )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_with_parameters )
|
||||
{
|
||||
mock::expectation< int( int ) > e;
|
||||
e.expect().calls( &custom_result_with_parameter );
|
||||
BOOST_CHECK_EQUAL( 42, e( 42 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_without_parameters_thanks_to_boost_bind )
|
||||
{
|
||||
mock::expectation< int( int ) > e;
|
||||
e.expect().calls( boost::bind( &custom_result ) );
|
||||
BOOST_CHECK_EQUAL( 42, e( 17 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( triggering_an_expectation_throws_the_set_exception )
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect().throws( std::runtime_error( "some exception" ) );
|
||||
try
|
||||
{
|
||||
e();
|
||||
}
|
||||
catch( std::runtime_error& e )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "some exception", e.what() );
|
||||
return;
|
||||
}
|
||||
BOOST_FAIL( "should have thrown" );
|
||||
}
|
||||
|
||||
// multiple matchers
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expecting_twice_a_single_expectation_makes_it_callable_twice )
|
||||
{
|
||||
{
|
||||
mock::expectation< void() > e;
|
||||
e.expect().once();
|
||||
e.expect().once();
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
BOOST_CHECK_NO_THROW( e() );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( const std::string& ) > e;
|
||||
e.expect().once().with( "first" );
|
||||
e.expect().once().with( "second" );
|
||||
BOOST_CHECK_NO_THROW( e( "first" ) );
|
||||
BOOST_CHECK_NO_THROW( e( "second" ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( "third" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( best_matcher_is_selected_first )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().once().with( 1 );
|
||||
e.expect().once().with( 2 );
|
||||
BOOST_CHECK_NO_THROW( e( 2 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 1 ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( 3 ), "unexpected call" );
|
||||
}
|
||||
{
|
||||
mock::expectation< void( const std::string& ) > e;
|
||||
e.expect().once().with( "first" );
|
||||
e.expect().once().with( "second" );
|
||||
BOOST_CHECK_NO_THROW( e( "second" ) );
|
||||
BOOST_CHECK_NO_THROW( e( "first" ) );
|
||||
BOOST_CHECK_EXCEPTION_CONTAINS( e( "third" ), "unexpected call" );
|
||||
}
|
||||
}
|
||||
|
||||
// error report
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expectation_can_be_serialized_to_be_human_readable )
|
||||
{
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once().with( 1 );
|
||||
e.expect().once().with( 2 );
|
||||
BOOST_CHECK_NO_THROW( e( 2 ) );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( 1 )\n"
|
||||
"v expect( once() ).with( 2 )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().never().with( 1 );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
"v expect( never() ).with( 1 )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( const std::string& ) > e;
|
||||
e.expect().never().with( mock::less( "first" ) );
|
||||
e.expect().exactly( 2 ).with( "second" );
|
||||
BOOST_CHECK_NO_THROW( e( "second" ) );
|
||||
{
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "?\n"
|
||||
"v expect( never() ).with( less( first ) )\n"
|
||||
". expect( exactly( 1/2 ) ).with( second )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
}
|
||||
BOOST_CHECK_NO_THROW( e( "second" ) );
|
||||
{
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "?\n"
|
||||
"v expect( never() ).with( less( first ) )\n"
|
||||
"v expect( exactly( 2/2 ) ).with( second )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
}
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once();
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( any )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once().with( mock::any );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( any )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once();
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( any )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once().with( mock::constraint( &custom_constraint ) );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( ? )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once().with( mock::constraint( &custom_constraint, "custom constraint" ) );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( custom constraint )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
{
|
||||
mock::expectation< void( int ) > e( "my expectation" );
|
||||
e.expect().once().with( mock::constraint( &custom_constraint, true ) );
|
||||
std::stringstream s;
|
||||
s << e;
|
||||
const std::string expected = "my expectation\n"
|
||||
". expect( once() ).with( true )";
|
||||
BOOST_CHECK_EQUAL( expected, s.str() );
|
||||
e.reset();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
mock::expectation< void() > no_match_exp( "no_match" );
|
||||
mock::expectation< void() > sequence_failed_exp( "sequence_failed" );
|
||||
mock::expectation< void() > verification_failed_exp( "verification_failed" );
|
||||
mock::expectation< void() > untriggered_expectation_exp( "untriggered_expectation" );
|
||||
|
||||
struct mock_error
|
||||
{
|
||||
static void no_match( const std::string& /*context*/ )
|
||||
{
|
||||
no_match_exp();
|
||||
}
|
||||
static void sequence_failed( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{
|
||||
sequence_failed_exp();
|
||||
}
|
||||
static void verification_failed( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{
|
||||
verification_failed_exp();
|
||||
}
|
||||
static void untriggered_expectation( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{
|
||||
untriggered_expectation_exp();
|
||||
}
|
||||
};
|
||||
struct error_guard
|
||||
{
|
||||
~error_guard()
|
||||
{
|
||||
no_match_exp.verify();
|
||||
no_match_exp.reset();
|
||||
sequence_failed_exp.verify();
|
||||
sequence_failed_exp.reset();
|
||||
verification_failed_exp.verify();
|
||||
verification_failed_exp.reset();
|
||||
untriggered_expectation_exp.verify();
|
||||
untriggered_expectation_exp.reset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( expectation_with_remaining_untriggered_matches_notifies_an_error_upon_destructions, error_guard )
|
||||
{
|
||||
mock::expectation< void(), mock_error > e;
|
||||
e.expect().once();
|
||||
untriggered_expectation_exp.expect().once();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( verifying_expectation_with_remaining_matches_disables_the_automatic_verification_upon_destruction, error_guard )
|
||||
{
|
||||
mock::expectation< void(), mock_error > e;
|
||||
e.expect().once();
|
||||
verification_failed_exp.expect();
|
||||
e.verify();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( triggering_no_match_call_disables_the_automatic_verification_upon_destruction, error_guard )
|
||||
{
|
||||
mock::expectation< void(), mock_error > e;
|
||||
no_match_exp.expect();
|
||||
e();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( adding_a_matcher_reactivates_the_verification_upon_destruction, error_guard )
|
||||
{
|
||||
mock::expectation< void(), mock_error > e;
|
||||
no_match_exp.expect();
|
||||
e();
|
||||
e.expect().once();
|
||||
untriggered_expectation_exp.expect().once();
|
||||
}
|
||||
79
src/tests/turtle_test/format_test.cpp
Normal file
79
src/tests/turtle_test/format_test.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/format.hpp>
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct non_serializable_type {};
|
||||
|
||||
struct serializable_type {};
|
||||
std::ostream& operator<<( std::ostream& s, const serializable_type& )
|
||||
{
|
||||
return s << "serializable_type";
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( type_not_serializable_in_standard_stream_yields_an_interrogation_mark_when_serialized )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "?", mock::detail::format( non_serializable_type() ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( base_type_serializable_in_standard_stream_yields_its_value_when_serialized )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "42", mock::detail::format( 42 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( custom_type_serializable_in_standard_stream_yields_its_value_when_serialized )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "serializable_type", mock::detail::format( serializable_type() ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct convertible_to_int
|
||||
{
|
||||
operator int() const { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( custom_type_convertible_to_base_type_yields_its_value_when_serialized )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "0", mock::detail::format( convertible_to_int() ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct serializable
|
||||
{
|
||||
friend std::ostream& operator<<( std::ostream& s, const serializable& )
|
||||
{
|
||||
return s << "serializable";
|
||||
}
|
||||
};
|
||||
struct convertible_to_serializable
|
||||
{
|
||||
operator serializable() const { return serializable(); }
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( custom_type_convertible_to_another_type_serializable_in_standard_stream_yields_its_value_when_serialized )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "serializable", mock::detail::format( convertible_to_serializable() ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( booleans_are_serialized_as_booleans )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "true", mock::detail::format( true ) );
|
||||
BOOST_CHECK_EQUAL( "false", mock::detail::format( false ) );
|
||||
}
|
||||
79
src/tests/turtle_test/invocation_test.cpp
Normal file
79
src/tests/turtle_test/invocation_test.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/invocation.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( unlimited )
|
||||
{
|
||||
mock::detail::unlimited invocation;
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( once )
|
||||
{
|
||||
mock::detail::once invocation;
|
||||
BOOST_CHECK( ! invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( ! invocation.is_valid() );
|
||||
BOOST_CHECK( ! invocation.invoke() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( never )
|
||||
{
|
||||
mock::detail::never invocation;
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( ! invocation.is_valid() );
|
||||
BOOST_CHECK( ! invocation.invoke() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( at_most )
|
||||
{
|
||||
mock::detail::at_most invocation( 1 );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( ! invocation.is_valid() );
|
||||
BOOST_CHECK( ! invocation.invoke() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( at_least )
|
||||
{
|
||||
mock::detail::at_least invocation( 1 );
|
||||
BOOST_CHECK( ! invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( between )
|
||||
{
|
||||
mock::detail::between invocation( 1, 2 );
|
||||
BOOST_CHECK( ! invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( invocation.is_valid() );
|
||||
BOOST_CHECK( invocation.invoke() );
|
||||
BOOST_CHECK( invocation.verify() );
|
||||
BOOST_CHECK( ! invocation.is_valid() );
|
||||
BOOST_CHECK( ! invocation.invoke() );
|
||||
}
|
||||
72
src/tests/turtle_test/object_test.cpp
Normal file
72
src/tests/turtle_test/object_test.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/object.hpp>
|
||||
#include <turtle/expectation.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_an_empty_object_succeeds )
|
||||
{
|
||||
mock::object o;
|
||||
BOOST_CHECK( o.verify() );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct silent_error
|
||||
{
|
||||
static void verification_failed( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{}
|
||||
static void untriggered_expectation( const std::string& /*context*/,
|
||||
const std::string& /*file*/, int /*line*/ )
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails )
|
||||
{
|
||||
mock::object o;
|
||||
mock::expectation< void(), silent_error > e( o );
|
||||
e.expect().once();
|
||||
BOOST_CHECK( ! o.verify() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( resetting_an_object_containing_a_failing_expectation_and_verifying_it_succeeds )
|
||||
{
|
||||
mock::object o;
|
||||
mock::expectation< void() > e( o );
|
||||
e.expect().once();
|
||||
o.reset();
|
||||
BOOST_CHECK( o.verify() );
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( verifying_an_object_containing_another_object_with_a_failing_expectation_fails )
|
||||
{
|
||||
mock::object o1;
|
||||
mock::object o2( o1 );
|
||||
mock::expectation< void(), silent_error > e( o2 );
|
||||
e.expect().once();
|
||||
BOOST_CHECK( ! o1.verify() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( resetting_an_object_containing_another_object_with_a_failing_expectation_and_verifying_it_succeeds )
|
||||
{
|
||||
mock::object o1;
|
||||
mock::object o2( o1 );
|
||||
mock::expectation< void() > e( o2 );
|
||||
e.expect().once();
|
||||
o1.reset();
|
||||
BOOST_CHECK( o1.verify() );
|
||||
BOOST_CHECK( o2.verify() );
|
||||
BOOST_CHECK( e.verify() );
|
||||
}
|
||||
166
src/tests/turtle_test/samples_test.cpp
Normal file
166
src/tests/turtle_test/samples_test.cpp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/object.hpp>
|
||||
#include <turtle/expectation.hpp>
|
||||
#include <turtle/constraint.hpp>
|
||||
#include <turtle/tools.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4355 4505 )
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
MOCK_CLASS( my_mock )
|
||||
{
|
||||
MOCK_METHOD_EXT( my_method, 1, int( int ), my_method )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_mock_object_usage )
|
||||
{
|
||||
my_mock m;
|
||||
MOCK_EXPECT( m, my_method ).once().returns( 0 );
|
||||
BOOST_CHECK_EQUAL( 0, m.my_method( 13 ) );
|
||||
mock::verify();
|
||||
mock::reset(); // $$$$ MAT : shouldn't reset implicitly call verify ?
|
||||
MOCK_EXPECT( m, my_method ).once().with( 42 ).returns( 7 );
|
||||
BOOST_CHECK_EQUAL( 7, m.my_method( 42 ) );
|
||||
mock::verify();
|
||||
mock::reset();
|
||||
MOCK_EXPECT( m, my_method ).once().returns( 51 );
|
||||
BOOST_CHECK_EQUAL( 51, m.my_method( 27 ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class my_observer : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~my_observer() {}
|
||||
|
||||
virtual void notify( int value ) = 0;
|
||||
};
|
||||
|
||||
class my_manager : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~my_manager() {}
|
||||
|
||||
virtual my_observer& get_observer() const = 0;
|
||||
};
|
||||
|
||||
class my_subject : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit my_subject( my_manager& f )
|
||||
: o_( f.get_observer() )
|
||||
, value_( 0 )
|
||||
{}
|
||||
void increment()
|
||||
{
|
||||
o_.notify( ++value_ );
|
||||
}
|
||||
private:
|
||||
my_observer& o_;
|
||||
int value_;
|
||||
};
|
||||
|
||||
MOCK_INTERFACE( my_mock_observer, my_observer )
|
||||
{
|
||||
MOCK_METHOD( notify, 1 )
|
||||
};
|
||||
|
||||
MOCK_INTERFACE( my_mock_manager, my_manager )
|
||||
{
|
||||
MOCK_METHOD( get_observer, 0 )
|
||||
};
|
||||
|
||||
class fixture
|
||||
{
|
||||
public:
|
||||
fixture()
|
||||
: manager( "(the only one)" )
|
||||
{}
|
||||
my_mock_manager manager;
|
||||
my_mock_observer observer;
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( basic_mock_object_collaboration_usage, fixture )
|
||||
{
|
||||
MOCK_EXPECT( manager, get_observer ).returns( boost::ref( observer ) );
|
||||
my_subject subject( manager );
|
||||
MOCK_EXPECT( observer, notify ).once().with( 1 );
|
||||
subject.increment();
|
||||
MOCK_EXPECT( observer, notify ).once().with( 2 );
|
||||
subject.increment();
|
||||
MOCK_EXPECT( observer, notify ).once().with( 3 );
|
||||
subject.increment();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class my_ambiguited_interface : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~my_ambiguited_interface() {}
|
||||
|
||||
virtual void my_method() = 0;
|
||||
virtual void my_method( int ) = 0;
|
||||
};
|
||||
|
||||
MOCK_INTERFACE( my_ambiguited_mock, my_ambiguited_interface )
|
||||
{
|
||||
MOCK_METHOD_EXT( my_method, 0, void(), tag1 )
|
||||
MOCK_METHOD_EXT( my_method, 1, void( int ), tag2 )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_object_method_disambiguation )
|
||||
{
|
||||
my_ambiguited_mock mock;
|
||||
MOCK_EXPECT( mock, tag1 );
|
||||
BOOST_CHECK_NO_THROW( mock.my_method() );
|
||||
BOOST_CHECK_THROW( mock.my_method( 12 ), mock::exception );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class my_const_ambiguited_interface : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~my_const_ambiguited_interface() {}
|
||||
|
||||
virtual void my_method() = 0;
|
||||
virtual void my_method() const = 0;
|
||||
};
|
||||
|
||||
MOCK_INTERFACE( my_const_ambiguited_mock, my_const_ambiguited_interface )
|
||||
{
|
||||
MOCK_NON_CONST_METHOD_EXT( my_method, 0, void(), tag1 )
|
||||
MOCK_CONST_METHOD_EXT( my_method, 0, void(), tag2 )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_object_method_const_disambiguation )
|
||||
{
|
||||
my_const_ambiguited_mock mock;
|
||||
MOCK_EXPECT( mock, tag1 );
|
||||
BOOST_CHECK_NO_THROW( mock.my_method() );
|
||||
const my_const_ambiguited_mock const_mock;
|
||||
BOOST_CHECK_THROW( const_mock.my_method(), mock::exception );
|
||||
}
|
||||
78
src/tests/turtle_test/sequence_test.cpp
Normal file
78
src/tests/turtle_test/sequence_test.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/sequence.hpp>
|
||||
#include <turtle/expectation.hpp>
|
||||
#include <turtle/constraint.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_throws )
|
||||
{
|
||||
mock::sequence s;
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().once().with( 1 ).in( s );
|
||||
e.expect().once().with( 2 ).in( s );
|
||||
BOOST_CHECK_NO_THROW( e( 2 ) );
|
||||
BOOST_CHECK_THROW( e( 1 ), mock::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_multiple_invocations_throws )
|
||||
{
|
||||
mock::sequence s;
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().with( 1 ).in( s );
|
||||
e.expect().once().with( 2 ).in( s );
|
||||
BOOST_CHECK_NO_THROW( e( 1 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 2 ) );
|
||||
BOOST_CHECK_THROW( e( 1 ), mock::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_in_order_is_valid )
|
||||
{
|
||||
mock::sequence s;
|
||||
mock::expectation< void( int ) > e;
|
||||
e.expect().once().with( 1 ).in( s );
|
||||
e.expect().once().with( 2 ).in( s );
|
||||
BOOST_CHECK_NO_THROW( e( 1 ) );
|
||||
BOOST_CHECK_NO_THROW( e( 2 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( registering_to_a_sequence_enforces_call_order_verification_between_two_different_expectations )
|
||||
{
|
||||
mock::sequence s;
|
||||
mock::expectation< void() > e1, e2;
|
||||
e1.expect().once().in( s );
|
||||
e2.expect().once().in( s );
|
||||
BOOST_CHECK_NO_THROW( e2() );
|
||||
BOOST_CHECK_THROW( e1(), mock::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( destroying_a_sequence_removes_order_call_enforcement )
|
||||
{
|
||||
mock::expectation< void() > e1, e2;
|
||||
{
|
||||
mock::sequence s;
|
||||
e1.expect().once().in( s );
|
||||
e2.expect().once().in( s );
|
||||
}
|
||||
BOOST_CHECK_NO_THROW( e2() );
|
||||
BOOST_CHECK_NO_THROW( e1() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( resetting_an_expectation_removes_it_from_order_call_enforcement )
|
||||
{
|
||||
mock::sequence s;
|
||||
mock::expectation< void() > e1, e2;
|
||||
e1.expect().once().in( s );
|
||||
e2.expect().once().in( s );
|
||||
e1.reset();
|
||||
BOOST_CHECK_NO_THROW( e2() );
|
||||
}
|
||||
143
src/tests/turtle_test/tools_test.cpp
Normal file
143
src/tests/turtle_test/tools_test.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
// Copyright Mathieu Champlon 2009
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <turtle/tools.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/equal.hpp>
|
||||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#define BOOST_LIB_NAME boost_unit_test_framework
|
||||
#include <boost/config/auto_link.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4355 )
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
void f1();
|
||||
int f2( float );
|
||||
|
||||
BOOST_STATIC_ASSERT( (boost::mpl::equal< mock::expectation< void() >,
|
||||
mock::expectation< BOOST_TYPEOF( f1 ) >
|
||||
>::value) );
|
||||
BOOST_STATIC_ASSERT( (boost::mpl::equal< mock::expectation< int( float ) >,
|
||||
mock::expectation< BOOST_TYPEOF( f2 ) >
|
||||
>::value) );
|
||||
|
||||
struct example
|
||||
{
|
||||
void method1();
|
||||
float method2( int );
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::mpl::equal<
|
||||
mock::expectation< void() >,
|
||||
mock::expectation<
|
||||
mock::detail::signature<
|
||||
BOOST_TYPEOF( &example::method1 )
|
||||
>::type
|
||||
>
|
||||
>::value) );
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::mpl::equal<
|
||||
mock::expectation< float( int ) >,
|
||||
mock::expectation<
|
||||
mock::detail::signature<
|
||||
BOOST_TYPEOF( &example::method2 )
|
||||
>::type
|
||||
>
|
||||
>::value) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ptr_uniformizes_reference_and_pointer )
|
||||
{
|
||||
int i = 0;
|
||||
BOOST_CHECK_EQUAL( mock::detail::ref( i ), mock::detail::ref( &i ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ptr_accesses_inner_pointer_from_auto_ptr )
|
||||
{
|
||||
std::auto_ptr< int > i( new int( 0 ) );
|
||||
BOOST_CHECK_EQUAL( *i, mock::detail::ref( i ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ptr_accesses_inner_pointer_from_shared_ptr )
|
||||
{
|
||||
boost::shared_ptr< int > i( new int( 0 ) );
|
||||
BOOST_CHECK_EQUAL( *i, mock::detail::ref( i ) );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template< typename T >
|
||||
void my_function( T& t )
|
||||
{
|
||||
t.my_method( "some parameter" );
|
||||
}
|
||||
MOCK_CLASS( mock_class )
|
||||
{
|
||||
MOCK_METHOD_EXT( my_method, 1, void( const std::string& ), my_method )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_object_for_static_polymorphism )
|
||||
{
|
||||
const mock_class mock;
|
||||
MOCK_EXPECT( mock, my_method ).once().with( "some parameter" );
|
||||
my_function( mock );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
MOCK_CLASS( mock_class_with_operator )
|
||||
{
|
||||
MOCK_CONST_METHOD_EXT( operator+=, 1, mock_class_with_operator&( int ), addition )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_addition_operator )
|
||||
{
|
||||
mock_class_with_operator mock;
|
||||
MOCK_EXPECT( mock, addition ).once().returns( boost::ref( mock ) );
|
||||
mock += 1;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
MOCK_CLASS( my_mock )
|
||||
{
|
||||
MOCK_METHOD_EXT( my_method, 1, void( int ), my_method )
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( MOCK_METHOD_EXT_macro_defines_a_bindable_method )
|
||||
{
|
||||
my_mock m;
|
||||
boost::bind( &my_mock::my_method, &m, 42 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( MOCK_VERIFY_macro )
|
||||
{
|
||||
my_mock m;
|
||||
MOCK_VERIFY( m, my_method );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( MOCK_RESET_macro )
|
||||
{
|
||||
my_mock m;
|
||||
MOCK_RESET( m, my_method );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( MOCK_EXPECT_macro )
|
||||
{
|
||||
my_mock m;
|
||||
MOCK_EXPECT( m, my_method ).once().with( 42 );
|
||||
m.my_method( 42 );
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue