diff --git a/Makefile b/Makefile index b5a8106..7dbcde7 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ clean_examples: make -C examples/3_writing_cpp_tests/custom_stubs clean make -C examples/3_writing_cpp_tests/deriving_a_mocked_interface clean make -C examples/3_writing_cpp_tests/expectation_based_mock_objects clean + make -C examples/3_writing_cpp_tests/injecting_custom_mocks clean make -C examples/6_coverage_enforcement clean make -C examples/7_simple_python_unittest clean @@ -28,4 +29,5 @@ build_examples: make -C examples/3_writing_cpp_tests/custom_stubs make -C examples/3_writing_cpp_tests/deriving_a_mocked_interface make -C examples/3_writing_cpp_tests/expectation_based_mock_objects + make -C examples/3_writing_cpp_tests/injecting_custom_mocks make -C examples/7_simple_python_unittest diff --git a/examples/3_writing_cpp_tests/injecting_custom_mocks/Makefile b/examples/3_writing_cpp_tests/injecting_custom_mocks/Makefile new file mode 100644 index 0000000..18805e1 --- /dev/null +++ b/examples/3_writing_cpp_tests/injecting_custom_mocks/Makefile @@ -0,0 +1,17 @@ +all: test + +ifeq ($(V),1) + Q = +else + Q = @ +endif + +export VOODOO_ROOT_DIR=../../.. +export CXXTEST_FIND_ROOT = cpp +export ENFORCE_COVERAGE_FIND_ROOT_CPP = cpp +export UNITTEST_INCLUDES = -Ibuild_unittest/voodoo/cpp -Icpp -I. +export VOODOO_INCLUDES = --includePath=cpp + +clean: clean_unittest + +include $(VOODOO_ROOT_DIR)/make/integrations/complete.Makefile diff --git a/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/Mocked.h b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/Mocked.h new file mode 100644 index 0000000..383e1d8 --- /dev/null +++ b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/Mocked.h @@ -0,0 +1,15 @@ +#ifndef __MOCKED_H__ +#define __MOCKED_H__ + +#include + +class SomeClass +{ +public: + int generateValue(); +}; + +#endif // __MOCKED_H__ +// FILE_EXEMPT_FROM_CODE_COVERAGE +/*VOODOO_PERFILESETTINGS IGNORE_PARAMETER_PACK.append( 'ClassWithIgnoredParameterPack::someOperation' ) */ +/*VOODOO_PERFILESETTINGS IGNORE_PARAMETER_PACK.append( 'ClassWithIgnoredParameterPack::ClassWithIgnoredParameterPack' ) */ diff --git a/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/UnderTest.h b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/UnderTest.h new file mode 100644 index 0000000..5357c22 --- /dev/null +++ b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/UnderTest.h @@ -0,0 +1,21 @@ +#ifndef __UNDERTEST_H_ +#define __UNDERTEST_H_ + +#include "Example/Mocked.h" +#include + +class ToBeTested +{ +public: + ToBeTested() = default; + + int getValue( ) + { + return _foo.generateValue() * 10; + } +private: + SomeClass _foo; +}; + +#endif // __UNDERTEST_H_ +// FILE_EXEMPT_FROM_CODE_COVERAGE diff --git a/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/tests/Test_UnderTest.h b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/tests/Test_UnderTest.h new file mode 100644 index 0000000..27fef60 --- /dev/null +++ b/examples/3_writing_cpp_tests/injecting_custom_mocks/cpp/Example/tests/Test_UnderTest.h @@ -0,0 +1,71 @@ +#define VOODOO_cpp_Example_Mocked_h +#include + +#include "Example/UnderTest.h" +#include + +//using namespace VoodooCommon::Expect; +//using namespace VoodooCommon::Expect::Parameter; + +class MockSomeClass : public Mock_SomeClass +{ +public: + bool SomeClass_Constructor() + { + return true; + } + + void setValue( int n ) + { + _n = n; + } + + int generateValue() + { + return _n; + } + +private: + int _n; +}; + +class Test_Example: public CxxTest::TestSuite +{ +public: + std::unique_ptr< MockSomeClass > _mockedSomeClass; + + void setUp() + { + _mockedSomeClass.reset( new MockSomeClass ); + } + + void tearDown() + { + } + + void test_ZeroValue() + { + ToBeTested tested; + + _mockedSomeClass->setValue( 0 ); + TS_ASSERT_EQUALS( 0, tested.getValue() ); + } + + void test_PositiveValue() + { + ToBeTested tested; + + _mockedSomeClass->setValue( 1 ); + tested.getValue( ); + TS_ASSERT_EQUALS( 10, tested.getValue() ); + } + + void test_NegativeValue() + { + ToBeTested tested; + + _mockedSomeClass->setValue( -1 ); + TS_ASSERT_EQUALS( -10, tested.getValue() ); + } + +}; diff --git a/voodoo/iterateapi.py b/voodoo/iterateapi.py index 04a318b..833da9f 100644 --- a/voodoo/iterateapi.py +++ b/voodoo/iterateapi.py @@ -183,7 +183,13 @@ def __iterateNode( self, node ): if node.kind == cindex.CursorKind.FUNCTION_TEMPLATE: templatePrefix = self.__templatePrefix( node ) assert returnType.startswith( templatePrefix ), "'%s' '%s'" % ( returnType, templatePrefix ) - returnType = returnType[ len( templatePrefix ) : ].lstrip() + returnTypeList = returnType[ len( templatePrefix ) : ].split() + specialWordsPrefixCount = 0 + for word in returnTypeList: + if word not in _PREFIX_KEYWORDS_TO_FUNCTIONS_TO_DISCARD: + break + specialWordsPrefixCount += 1 + returnType = " ".join( returnTypeList[ specialWordsPrefixCount : ] ) decomposition = functiondecomposition.FunctionDecomposition( name = node.spelling, text = node.spelling, diff --git a/voodoo/voodoomock.py b/voodoo/voodoomock.py index 93b01a2..14d1f9f 100644 --- a/voodoo/voodoomock.py +++ b/voodoo/voodoomock.py @@ -32,12 +32,18 @@ def _isCopyConstructor( self, decomposition ): return decomposition.parametersFullSpec() == \ "const %s & %s" % ( self._identifier, decomposition.parameters[ 0 ][ 'name' ] ) + def _isMoveSemantics( self, decomposition ): + if len( decomposition.parameters ) != 1: + return False + return decomposition.parametersFullSpec() == \ + "%s && %s" % ( self._identifier, decomposition.parameters[ 0 ][ 'name' ] ) + def _mockInherits( self ): return [ i for i in self._inherits if i not in self._perFileSettings.NO_MOCK_DERIVE_AND_USE_DEFAULT_CONSTRUCTOR ] def implementConstructor( self, decomposition ): - if ( self._isCopyConstructor( decomposition ) ): + if ( self._isCopyConstructor( decomposition ) or self._isMoveSemantics( decomposition ) ): return self._constructorCount += 1 inherits = "" @@ -92,6 +98,10 @@ def implementConstructor( self, decomposition ): self._code.lineOut( "" ) def implementMethod( self, decomposition ): + parametersForwardingList = decomposition.parametersForwardingList() + if self._isMoveSemantics( decomposition ): + parametersForwardingList = "std::move( %s )" % parametersForwardingList + const = "" if decomposition.const: const = " const" @@ -107,7 +117,7 @@ def implementMethod( self, decomposition ): const, self._identifier, decomposition.name, - decomposition.parametersForwardingList() ) ) + parametersForwardingList ) ) self._code.lineOut( "\t} else {" ) self._code.lineOut( "\t\t__VoodooGrowingString message;" ) self._code.lineOut( "\t\tmessage.append( \"Method \" " ) @@ -131,7 +141,7 @@ def implementMethod( self, decomposition ): const, self._identifier, decomposition.name, - decomposition.parametersForwardingList() ) ) + parametersForwardingList ) ) self._code.lineOut( "\t}" ) self._code.lineOut( "}" ) self._code.lineOut( "" )