├── .gitignore ├── runtests.sh ├── examples ├── SpecTest.cpp ├── CMakeLists.txt ├── cmake_install.cmake ├── InterfaceSpec.h ├── RegExSpec.h ├── ContainmentSpec.h ├── StackSpec.h └── Makefile ├── test ├── TimerStub.h ├── VoidSpecification.cpp ├── main.cpp ├── DummyReporter.h ├── StubRunnable.h ├── SpecificationRegistryTest.cpp ├── TypeHasStreamingOperatorTest.cpp ├── DummyReporter.cpp ├── OutputStreamStub.h ├── BoostTimerTest.cpp ├── CMakeLists.txt ├── ExpectationTest.cpp ├── MatcherTest.cpp ├── SpecDoxReporterTest.cpp ├── JUnitReporterTest.cpp ├── InvokingTypeTest.cpp ├── InvocationTest.cpp ├── SpecificationTest.cpp ├── SpecRunnerTest.cpp └── ExceptionThrowingSpecificationTest.cpp ├── src ├── Timer.cpp ├── Util.cpp ├── ConsoleOutputStream.cpp ├── BoostTimer.cpp ├── FileOutputStream.cpp ├── SpecificationRegistry.cpp ├── Matcher.cpp ├── CMakeLists.txt ├── SpecDoxReporter.cpp ├── SpecResult.cpp ├── JUnitReporter.cpp └── SpecRunner.cpp ├── include ├── Functor.h ├── CppSpecConfig.h ├── Timer.h ├── ContextHolder.h ├── Reporter.h ├── OutputStream.h ├── SpecRunner.h ├── BoostTimer.h ├── ConsoleOutputStream.h ├── CppSpec.h ├── SpecifyFailedException.h ├── Matcher.h ├── Runnable.h ├── BeType.h ├── SpecDoxReporter.h ├── FileOutputStream.h ├── InvocationResult.h ├── Behavior.h ├── TypeHasStreamingOperator.h ├── SpecificationRegistry.h ├── InvokingType.h ├── TypeNameResolver.h ├── JUnitReporter.h ├── SpecResult.h ├── Expectation.h ├── ShouldType.h ├── ThreadPool.h ├── Specification.h ├── Invocation.h └── SpecificationBase.h ├── CMakeLists.txt ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Builds CppSpec and runs test measuring coverage 3 | pushd build 4 | make -j3 5 | lcov -d test/ -z 6 | ./bin/CppSpecTest 7 | lcov -d test/ -c -o coverage/CppSpecTest.info 8 | pushd coverage 9 | genhtml CppSpecTest.info 10 | popd 11 | popd 12 | -------------------------------------------------------------------------------- /examples/SpecTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "CppSpec.h" 18 | #include "StackSpec.h" 19 | #include "InterfaceSpec.h" 20 | #include "ContainmentSpec.h" 21 | #include "RegExSpec.h" 22 | 23 | CPPSPEC_MAIN 24 | -------------------------------------------------------------------------------- /test/TimerStub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "Timer.h" 20 | 21 | class TimerStub : public CppSpec::Timer { 22 | void start() {} 23 | std::string stop() {return "00.010000";} 24 | }; 25 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2007 Timo Puronen 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include_directories("${CMAKE_HOME_DIRECTORY}/include" ${Boost_INCLUDE_DIRS}) 18 | 19 | set(EXECUTABLE_OUTPUT_PATH ../bin) 20 | add_executable(SpecTest SpecTest.cpp) 21 | target_link_libraries(SpecTest CppSpec) 22 | -------------------------------------------------------------------------------- /src/Timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Timer.h" 18 | #include "BoostTimer.h" 19 | 20 | namespace CppSpec { 21 | 22 | boost::shared_ptr Timer::create() { 23 | return boost::shared_ptr(new BoostTimer()); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /include/Functor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FUNCTOR_H_ 18 | #define FUNCTOR_H_ 19 | 20 | #include 21 | 22 | namespace CppSpec { 23 | 24 | class Functor { 25 | public: 26 | virtual void operator()() = 0; 27 | virtual const std::string& getName() const = 0; 28 | }; 29 | 30 | } 31 | 32 | #endif /* FUNCTOR_H_ */ 33 | -------------------------------------------------------------------------------- /test/VoidSpecification.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "CppSpec.h" 18 | 19 | class VoidSpecification : public CppSpec::Specification { 20 | public: 21 | VoidSpecification() { 22 | } 23 | 24 | void specifies() { 25 | specify(true); 26 | specify(1, should.equal(1)); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /include/CppSpecConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008, 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CPPSPEC_CONFIG__ 18 | #define CPPSPEC_CONFIG__ 19 | 20 | #ifdef _WINDLL 21 | #ifdef CppSpec_EXPORTS 22 | #define CppSpec_EXPORT __declspec( dllexport ) 23 | #else 24 | #define CppSpec_EXPORT __declspec( dllimport ) 25 | #endif 26 | #else 27 | #define CppSpec_EXPORT 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "TimerStub.h" 19 | 20 | int main(int argc, char* argv[]) { 21 | ::testing::InitGoogleTest(&argc, argv); 22 | return RUN_ALL_TESTS(); 23 | } 24 | 25 | namespace CppSpec { 26 | boost::shared_ptr Timer::create() { 27 | return boost::shared_ptr(new TimerStub()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | bool operator==(const std::exception& lhs, const std::exception& rhs) { 22 | return ::strcmp(lhs.what(), rhs.what()) == 0; 23 | } 24 | 25 | std::ostream& operator<<(std::ostream& out, const std::exception& e) { 26 | out << std::string(e.what()); 27 | return out; 28 | } 29 | -------------------------------------------------------------------------------- /include/Timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef TIMER_H_ 18 | #define TIMER_H_ 19 | 20 | #include 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | class Timer { 26 | public: 27 | static boost::shared_ptr create(); 28 | virtual ~Timer() {} 29 | virtual void start() = 0; 30 | virtual std::string stop() = 0; 31 | }; 32 | 33 | } 34 | 35 | #endif /* TIMER_H_ */ 36 | -------------------------------------------------------------------------------- /include/ContextHolder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CONTEXTCREATOR_H_ 18 | #define CONTEXTCREATOR_H_ 19 | 20 | template 21 | class ContextHolder { 22 | public: 23 | /** 24 | * Get current context. 25 | */ 26 | virtual Context& context() = 0; 27 | }; 28 | 29 | template<> 30 | class ContextHolder { 31 | public: 32 | virtual void context() {} 33 | }; 34 | 35 | #endif /*CONTEXTCREATOR_H_*/ 36 | -------------------------------------------------------------------------------- /include/Reporter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef REPORTER_H_ 18 | #define REPORTER_H_ 19 | 20 | #include 21 | 22 | namespace CppSpec { 23 | 24 | class SpecResult; 25 | 26 | class Reporter { 27 | public: 28 | virtual ~Reporter() {} 29 | 30 | public: 31 | virtual void addSpecification(const SpecResult& results) = 0; 32 | virtual bool anyBehaviorFailed() const = 0; 33 | }; 34 | 35 | } 36 | 37 | #endif /*REPORTER_H_*/ 38 | -------------------------------------------------------------------------------- /include/OutputStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef OUTPUTSTREAM_H_ 18 | #define OUTPUTSTREAM_H_ 19 | 20 | #include 21 | 22 | namespace CppSpec { 23 | 24 | class OutputStream { 25 | public: 26 | virtual ~OutputStream() {}; 27 | public: 28 | virtual OutputStream& operator<<(const std::string& output) = 0; 29 | virtual OutputStream& operator<<(long output) = 0; 30 | }; 31 | 32 | } 33 | 34 | #endif /* OUTPUTSTREAM_H_ */ 35 | -------------------------------------------------------------------------------- /include/SpecRunner.h: -------------------------------------------------------------------------------- 1 | #ifndef SPECRUNNER_H_ 2 | #define SPECRUNNER_H_ 3 | 4 | #include "CppSpecConfig.h" 5 | #include 6 | #include 7 | 8 | namespace boost { 9 | namespace program_options { 10 | class variables_map; 11 | } 12 | } 13 | 14 | namespace CppSpec { 15 | 16 | class OutputStream; 17 | class Reporter; 18 | 19 | class CppSpec_EXPORT SpecRunner { 20 | public: 21 | SpecRunner(int argc, const char* argv[]); 22 | virtual ~SpecRunner(); 23 | 24 | public: 25 | int runSpecifications(); 26 | friend class SpecRunnerTestAccessor; 27 | 28 | protected: 29 | virtual OutputStream* createOutputStream(); 30 | 31 | private: 32 | Reporter* createReporter(OutputStream& outputStream); 33 | bool runSpecs(const std::vector& specifications); 34 | 35 | private: 36 | boost::program_options::variables_map* arguments; 37 | std::vector specificationsToRun; 38 | 39 | private: 40 | SpecRunner(const SpecRunner&); 41 | SpecRunner& operator=(const SpecRunner&); 42 | }; 43 | 44 | } 45 | 46 | #endif /*SPECRUNNER_H_*/ 47 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2007-2008 Timo Puronen 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | cmake_minimum_required(VERSION 2.6 FATAL_ERROR) 18 | 19 | project(CppSpec) 20 | set(VERSION 0.5.0) 21 | 22 | if(WIN32) 23 | set(Boost_USE_STATIC_LIBS ON) 24 | endif(WIN32) 25 | find_package(Boost COMPONENTS regex program_options filesystem date_time chrono thread system REQUIRED) 26 | add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) 27 | 28 | add_subdirectory(src) 29 | add_subdirectory(examples) 30 | add_subdirectory(test) 31 | -------------------------------------------------------------------------------- /test/DummyReporter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DUMMYREPORTER_H_ 18 | #define DUMMYREPORTER_H_ 19 | 20 | #include "Reporter.h" 21 | 22 | class DummyReporter : public CppSpec::Reporter { 23 | public: 24 | DummyReporter(); 25 | ~DummyReporter(); 26 | 27 | public: // from Reporter 28 | void addSpecification(const CppSpec::SpecResult& results); 29 | bool anyBehaviorFailed() const; 30 | 31 | public: 32 | int success; 33 | int failed; 34 | }; 35 | 36 | #endif /*DUMMYREPORTER_H_*/ 37 | -------------------------------------------------------------------------------- /test/StubRunnable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef STUBRUNNABLE_H_ 18 | #define STUBRUNNABLE_H_ 19 | 20 | #include "Runnable.h" 21 | 22 | static std::string stubName = "TestSpec"; 23 | 24 | class StubRunnable : public CppSpec::Runnable { 25 | public: 26 | CppSpec::SpecResult operator()() {CppSpec::SpecResult result("stub"); return result;} 27 | const std::string& getName() const {return stubName;} 28 | unsigned int getBehaviorCount() const {return 1;} 29 | }; 30 | 31 | 32 | #endif /* STUBRUNNABLE_H_ */ 33 | -------------------------------------------------------------------------------- /src/ConsoleOutputStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ConsoleOutputStream.h" 18 | #include 19 | 20 | namespace CppSpec { 21 | 22 | ConsoleOutputStream::ConsoleOutputStream() { 23 | } 24 | 25 | ConsoleOutputStream::~ConsoleOutputStream() { 26 | } 27 | 28 | OutputStream& ConsoleOutputStream::operator<<(const std::string& output) { 29 | std::cout << output; 30 | return *this; 31 | } 32 | 33 | OutputStream& ConsoleOutputStream::operator<<(long output) { 34 | std::cout << output; 35 | return *this; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /test/SpecificationRegistryTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "SpecificationRegistry.h" 19 | #include "StubRunnable.h" 20 | 21 | using namespace CppSpec; 22 | 23 | TEST(SpecificationRegistryTest, canAddSpecification) 24 | { 25 | SpecificationRegistry& registry = SpecificationRegistry::instance(); 26 | StubRunnable runnable; 27 | const size_t initialSpecificationCount(registry.getSpecifications().size()); 28 | registry.addSpecification(&runnable); 29 | EXPECT_EQ(initialSpecificationCount + 1, registry.getSpecifications().size()); 30 | } 31 | -------------------------------------------------------------------------------- /test/TypeHasStreamingOperatorTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "TypeHasStreamingOperator.h" 19 | 20 | class Foo { 21 | }; 22 | 23 | TEST(TypeHasStreamingOperatorTest, TypeHasStreamingOperator) { 24 | EXPECT_TRUE(CppSpec::TypeHasStreamingOperator::result); 25 | } 26 | 27 | TEST(TypeHasStreamingOperatorTest, TypeDoesNotHavenStreamingOperator) { 28 | EXPECT_FALSE(CppSpec::TypeHasStreamingOperator::result); 29 | } 30 | 31 | TEST(TypeHasStreamingOperatorTest, StreamingReference) { 32 | EXPECT_TRUE(CppSpec::TypeHasStreamingOperator::result); 33 | } 34 | -------------------------------------------------------------------------------- /src/BoostTimer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "BoostTimer.h" 18 | #include 19 | #include 20 | 21 | namespace CppSpec { 22 | 23 | BoostTimer::BoostTimer() {} 24 | 25 | BoostTimer::~BoostTimer() { 26 | } 27 | 28 | void BoostTimer::start() { 29 | startTime = boost::chrono::system_clock::now(); 30 | } 31 | 32 | std::string BoostTimer::stop() { 33 | boost::chrono::duration secs = boost::chrono::system_clock::now() - startTime; 34 | std::stringstream stream; 35 | stream << std::fixed << std::setprecision(6) << secs.count(); 36 | return stream.str(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /include/BoostTimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BOOSTTIMER_H_ 18 | #define BOOSTTIMER_H_ 19 | 20 | #include "Timer.h" 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | class BoostTimer : public Timer { 26 | public: 27 | explicit BoostTimer(); 28 | virtual ~BoostTimer(); 29 | 30 | public: // from Timer 31 | void start(); 32 | std::string stop(); 33 | 34 | private: 35 | BoostTimer(const BoostTimer&); 36 | BoostTimer& operator=(const BoostTimer&); 37 | 38 | private: 39 | boost::chrono::system_clock::time_point startTime; 40 | }; 41 | 42 | } 43 | 44 | #endif /* BOOSTTIMER_H_ */ 45 | -------------------------------------------------------------------------------- /test/DummyReporter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "DummyReporter.h" 18 | #include "SpecResult.h" 19 | #include 20 | 21 | DummyReporter::DummyReporter() : success(0), failed(0) { 22 | } 23 | 24 | DummyReporter::~DummyReporter() { 25 | } 26 | 27 | void DummyReporter::addSpecification(const CppSpec::SpecResult& results) { 28 | for (BOOST_AUTO(it, results.firstBehavior()); it != results.lastBehavior(); ++it) { 29 | it->passed ? ++success : ++failed; 30 | } 31 | } 32 | 33 | bool DummyReporter::anyBehaviorFailed() const { 34 | return failed != 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/OutputStreamStub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef OUTPUTSTREAMSTUB_H_ 18 | #define OUTPUTSTREAMSTUB_H_ 19 | 20 | #include "OutputStream.h" 21 | #include 22 | 23 | class OutputStreamStub : public CppSpec::OutputStream { 24 | public: 25 | OutputStreamStub() : writtenData() {} 26 | OutputStream& operator<<(const std::string& output) {writtenData << output; return *this;} 27 | OutputStream& operator<<(long output) {writtenData << output; return *this;} 28 | 29 | const std::string written() {return writtenData.str();} 30 | private: 31 | std::stringstream writtenData; 32 | }; 33 | 34 | #endif /* OUTPUTSTREAMSTUB_H_ */ 35 | -------------------------------------------------------------------------------- /include/ConsoleOutputStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CONSOLEOUTPUTSTREAM_H_ 18 | #define CONSOLEOUTPUTSTREAM_H_ 19 | 20 | #include "OutputStream.h" 21 | 22 | namespace CppSpec { 23 | 24 | class ConsoleOutputStream : public OutputStream { 25 | public: 26 | ConsoleOutputStream(); 27 | ~ConsoleOutputStream(); 28 | 29 | public: // from OutputStream 30 | OutputStream& operator<<(const std::string& output); 31 | OutputStream& operator<<(long output); 32 | 33 | private: 34 | ConsoleOutputStream(const ConsoleOutputStream&); 35 | ConsoleOutputStream& operator=(const ConsoleOutputStream&); 36 | }; 37 | 38 | } 39 | 40 | #endif /* CONSOLEOUTPUTSTREAM_H_ */ 41 | -------------------------------------------------------------------------------- /examples/cmake_install.cmake: -------------------------------------------------------------------------------- 1 | # Install script for directory: /home/tpuronen/src/cppspec/trunk/examples 2 | 3 | # Set the install prefix 4 | IF(NOT DEFINED CMAKE_INSTALL_PREFIX) 5 | SET(CMAKE_INSTALL_PREFIX "/usr/local") 6 | ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) 7 | STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") 8 | 9 | # Set the install configuration name. 10 | IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) 11 | IF(BUILD_TYPE) 12 | STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" 13 | CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") 14 | ELSE(BUILD_TYPE) 15 | SET(CMAKE_INSTALL_CONFIG_NAME "") 16 | ENDIF(BUILD_TYPE) 17 | MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") 18 | ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) 19 | 20 | # Set the component getting installed. 21 | IF(NOT CMAKE_INSTALL_COMPONENT) 22 | IF(COMPONENT) 23 | MESSAGE(STATUS "Install component: \"${COMPONENT}\"") 24 | SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") 25 | ELSE(COMPONENT) 26 | SET(CMAKE_INSTALL_COMPONENT) 27 | ENDIF(COMPONENT) 28 | ENDIF(NOT CMAKE_INSTALL_COMPONENT) 29 | 30 | # Install shared libraries without execute permission? 31 | IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) 32 | SET(CMAKE_INSTALL_SO_NO_EXE "1") 33 | ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) 34 | 35 | -------------------------------------------------------------------------------- /src/FileOutputStream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "FileOutputStream.h" 18 | 19 | namespace CppSpec { 20 | 21 | FileOutputStream::FileOutputStream(const std::string& directory, const std::string& specification) { 22 | boost::filesystem::path reportPath(directory); 23 | reportPath /= (specification + ".xml"); 24 | file.open(reportPath); 25 | } 26 | 27 | FileOutputStream::~FileOutputStream() { 28 | file.close(); 29 | } 30 | 31 | OutputStream& FileOutputStream::operator<<(const std::string& output) { 32 | file << output; 33 | return *this; 34 | } 35 | 36 | OutputStream& FileOutputStream::operator<<(long output) { 37 | file << output; 38 | return *this; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /include/CppSpec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CPPSPEC_H_ 18 | #define CPPSPEC_H_ 19 | 20 | #include "Specification.h" 21 | #include "Behavior.h" 22 | #include "SpecRunner.h" 23 | 24 | #define REGISTER_BEHAVIOUR(Specification, BehaviorName) \ 25 | static CppSpec::Behavior BehaviorName##Instance(this, &Specification::BehaviorName, #BehaviorName); \ 26 | behaviors.push_back(&BehaviorName##Instance); 27 | 28 | #define specify(...) \ 29 | specifyImpl(__FILE__, __LINE__, __VA_ARGS__) 30 | 31 | #define CPPSPEC_MAIN \ 32 | int main(int argc, const char* argv[]) { \ 33 | CppSpec::SpecRunner runner(argc, argv); \ 34 | return runner.runSpecifications(); \ 35 | } 36 | 37 | 38 | #endif /*CPPSPEC_H_*/ 39 | -------------------------------------------------------------------------------- /include/SpecifyFailedException.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SPECIFYFAILEDEXCEPTION_H_ 18 | #define SPECIFYFAILEDEXCEPTION_H_ 19 | 20 | namespace CppSpec { 21 | 22 | class SpecifyFailedException { 23 | public: 24 | SpecifyFailedException(const std::string& file, int line, const std::string& message) : file(file), line(line), message(message) {} 25 | SpecifyFailedException(const SpecifyFailedException& that) : file(that.file), line(that.line), message(that.message) {} 26 | 27 | private: 28 | SpecifyFailedException& operator=(const SpecifyFailedException&); 29 | 30 | public: 31 | std::string file; 32 | int line; 33 | std::string message; 34 | }; 35 | 36 | } 37 | 38 | #endif /* SPECIFYFAILEDEXCEPTION_H_ */ 39 | -------------------------------------------------------------------------------- /include/Matcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MATCHER_H_ 18 | #define MATCHER_H_ 19 | 20 | #include "CppSpecConfig.h" 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | class CppSpec_EXPORT Matcher { 26 | public: 27 | enum Mode {Search, Match}; 28 | explicit Matcher(const std::string& expression, Mode mode); 29 | Matcher(const Matcher& that); 30 | 31 | public: 32 | bool operator()(const std::string& text) const; 33 | Matcher& operator !(); 34 | Mode getMode() const; 35 | const std::string& getExpression() const; 36 | 37 | private: 38 | Matcher& operator=(const Matcher&); 39 | 40 | private: 41 | const std::string expression; 42 | Mode mode; 43 | bool reversed; 44 | }; 45 | 46 | } 47 | 48 | #endif /*MATCHER_H_*/ 49 | -------------------------------------------------------------------------------- /src/SpecificationRegistry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "SpecificationRegistry.h" 18 | #include 19 | 20 | namespace CppSpec { 21 | 22 | SpecificationRegistry::SpecificationRegistry() : specifications() { 23 | } 24 | 25 | SpecificationRegistry& SpecificationRegistry::instance() { 26 | static SpecificationRegistry registry; 27 | return registry; 28 | } 29 | 30 | void SpecificationRegistry::addSpecification(Runnable* specification) { 31 | specifications.push_back(specification); 32 | } 33 | 34 | const SpecificationRegistry::SpecificationList& SpecificationRegistry::getSpecifications() const { 35 | return specifications; 36 | } 37 | 38 | void SpecificationRegistry::clear() { 39 | specifications.clear(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /include/Runnable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RUNNABLE_H_ 18 | #define RUNNABLE_H_ 19 | 20 | #include "Reporter.h" 21 | #include "SpecResult.h" 22 | #include 23 | 24 | namespace CppSpec { 25 | 26 | class Reporter; 27 | 28 | /** 29 | * Interface of a runnable specification object 30 | */ 31 | class Runnable { 32 | public: 33 | virtual ~Runnable() {} 34 | 35 | /** 36 | * Execute behaviors of a specification 37 | */ 38 | virtual SpecResult operator()() = 0; 39 | 40 | /** 41 | * Get the name of the specification. 42 | */ 43 | virtual const std::string& getName() const = 0; 44 | 45 | /** 46 | * Get count of behaviors 47 | */ 48 | virtual unsigned int getBehaviorCount() const = 0; 49 | }; 50 | 51 | } 52 | 53 | #endif /*RUNNABLE_H_*/ 54 | -------------------------------------------------------------------------------- /include/BeType.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BETYPE_H_ 18 | #define BETYPE_H_ 19 | 20 | #include "ContextHolder.h" 21 | 22 | namespace CppSpec { 23 | 24 | template 25 | class BeType 26 | { 27 | public: 28 | explicit BeType(ContextHolder& creator) : contextHolder(creator) {} 29 | virtual ~BeType() {}; 30 | 31 | Context& operator()() { 32 | return contextHolder.context(); 33 | } 34 | 35 | private: 36 | BeType(const BeType&); 37 | BeType& operator=(const BeType&); 38 | 39 | private: 40 | ContextHolder& contextHolder; 41 | }; 42 | 43 | template<> 44 | class BeType { 45 | public: 46 | void operator()() { 47 | } 48 | 49 | private: 50 | BeType(const BeType&); 51 | BeType& operator=(const BeType&); 52 | }; 53 | 54 | } 55 | 56 | #endif /*BESTATEMENT_H_*/ 57 | -------------------------------------------------------------------------------- /examples/InterfaceSpec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef INTERFACESPEC_H_ 18 | #define INTERFACESPEC_H_ 19 | 20 | #include "CppSpec.h" 21 | 22 | class Interface { 23 | public: 24 | virtual ~Interface() {} 25 | virtual void Foo() = 0; 26 | }; 27 | 28 | class Implementation : public Interface { 29 | public: 30 | explicit Implementation() {} 31 | virtual ~Implementation() {} 32 | 33 | void Foo() {} 34 | }; 35 | 36 | class ImplementationSpec : public CppSpec::Specification { 37 | public: 38 | ImplementationSpec() { 39 | REGISTER_BEHAVIOUR(ImplementationSpec, implementsInterface); 40 | } 41 | 42 | void implementsInterface() { 43 | specify(should.implement()); 44 | } 45 | } interfaceSpec; 46 | 47 | #endif /*INTERFACESPEC_H_*/ 48 | -------------------------------------------------------------------------------- /include/SpecDoxReporter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef CONSOLEREPORTER_H_ 18 | #define CONSOLEREPORTER_H_ 19 | 20 | #include "Reporter.h" 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | class OutputStream; 26 | 27 | class SpecDoxReporter : public Reporter { 28 | public: 29 | explicit SpecDoxReporter(OutputStream& outputStream); 30 | ~SpecDoxReporter(); 31 | 32 | void addSpecification(const SpecResult& results); 33 | bool anyBehaviorFailed() const; 34 | 35 | private: 36 | std::string formatCamelCasedWordsAndUnderlines(const std::string& text); 37 | 38 | private: 39 | SpecDoxReporter(const SpecDoxReporter&); 40 | SpecDoxReporter& operator=(const SpecDoxReporter&); 41 | 42 | private: 43 | OutputStream& outputStream; 44 | bool anyFailed; 45 | }; 46 | 47 | } 48 | 49 | #endif /*CONSOLEREPORTER_H_*/ 50 | -------------------------------------------------------------------------------- /include/FileOutputStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FILEOUTPUTSTREAM_H_ 18 | #define FILEOUTPUTSTREAM_H_ 19 | 20 | #include "OutputStream.h" 21 | #include 22 | #include 23 | 24 | namespace CppSpec { 25 | 26 | class FileOutputStream : public OutputStream { 27 | public: 28 | explicit FileOutputStream(const std::string& directory, const std::string& specification); 29 | virtual ~FileOutputStream(); 30 | 31 | public: // from OutputStream 32 | OutputStream& operator<<(const std::string& output); 33 | OutputStream& operator<<(long output); 34 | 35 | private: 36 | FileOutputStream(const FileOutputStream&); 37 | FileOutputStream& operator=(const FileOutputStream&); 38 | 39 | private: 40 | boost::filesystem::ofstream file; 41 | }; 42 | 43 | } 44 | 45 | #endif /* FILEOUTPUTSTREAM_H_ */ 46 | -------------------------------------------------------------------------------- /include/InvocationResult.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef INVOCATIONRESULT_H_ 18 | #define INVOCATIONRESULT_H_ 19 | 20 | #include 21 | 22 | namespace CppSpec { 23 | 24 | class InvocationResult { 25 | public: 26 | explicit InvocationResult() : result(false) {} 27 | InvocationResult(const InvocationResult& that) : result(that.result), description(that.description) {} 28 | 29 | void setSuccess() {result = true;} 30 | void setFailure(const std::string& description) {this->description = description;} 31 | 32 | bool wasSuccess() const {return result;} 33 | const std::string& getDescription() const {return description;} 34 | 35 | private: 36 | InvocationResult& operator=(const InvocationResult&); 37 | 38 | private: 39 | bool result; 40 | std::string description; 41 | }; 42 | 43 | } 44 | 45 | #endif /* INVOCATIONRESULT_H_ */ 46 | -------------------------------------------------------------------------------- /test/BoostTimerTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "BoostTimer.h" 19 | #include 20 | #include 21 | 22 | using CppSpec::BoostTimer; 23 | 24 | class BoostTimerTest : public ::testing::Test { 25 | public: 26 | BoostTimerTest() : regexp("\\d{1}.\\d{6}") {timer = new BoostTimer;} 27 | ~BoostTimerTest() {delete timer;} 28 | 29 | BoostTimer* timer; 30 | boost::regex regexp; 31 | }; 32 | 33 | TEST_F(BoostTimerTest, specificationDurationFormatIsExpected) { 34 | timer->start(); 35 | std::string duration(timer->stop()); 36 | ASSERT_TRUE(boost::regex_match(duration, regexp)); 37 | } 38 | 39 | TEST_F(BoostTimerTest, behaviorDurationFormatIsExpected) { 40 | timer->start(); 41 | std::string duration(timer->stop()); 42 | ASSERT_TRUE(boost::regex_match(duration, regexp)); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /include/Behavior.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef BEHAVIOR_H_ 19 | #define BEHAVIOR_H_ 20 | 21 | #include "Functor.h" 22 | #include 23 | 24 | namespace CppSpec { 25 | 26 | template 27 | class Behavior : public Functor { 28 | public: 29 | explicit Behavior(SpecificationClass* specification, void(SpecificationClass::*method)(), std::string name) : specification(specification), method(method), name(name) { 30 | } 31 | 32 | void operator()() { 33 | (specification->*method)(); 34 | } 35 | 36 | const std::string& getName() const { 37 | return name; 38 | } 39 | 40 | private: 41 | SpecificationClass* specification; 42 | void (SpecificationClass::*method)(); 43 | std::string name; 44 | 45 | private: 46 | Behavior(const Behavior&); 47 | Behavior& operator=(const Behavior&); 48 | }; 49 | 50 | } 51 | 52 | #endif /* BEHAVIOR_H_ */ 53 | -------------------------------------------------------------------------------- /include/TypeHasStreamingOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef TYPEHASSTREAMINGOPERATOR_H_ 18 | #define TYPEHASSTREAMINGOPERATOR_H_ 19 | 20 | #include 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | typedef char yes; 26 | typedef char (&no)[2]; 27 | 28 | struct tag{}; 29 | 30 | struct any { 31 | template any(const T&); 32 | }; 33 | 34 | tag operator << (const any&, const any&); 35 | 36 | no test(tag); 37 | 38 | template 39 | yes test(const T&); 40 | 41 | template 42 | struct TypeHasStreamingOperator { 43 | static typename boost::remove_cv::type>::type const& x; 44 | static const bool result = sizeof(test(std::cout << x)) == sizeof(yes); 45 | }; 46 | 47 | template 48 | struct CheckIf { 49 | enum { value = v }; 50 | }; 51 | 52 | } 53 | 54 | #endif /* TYPEHASSTREAMINGOPERATOR_H_ */ 55 | -------------------------------------------------------------------------------- /src/Matcher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Matcher.h" 18 | #include 19 | 20 | namespace CppSpec { 21 | 22 | Matcher::Matcher(const std::string& expression, Mode mode) : expression(expression), mode(mode), reversed(false) { 23 | } 24 | 25 | Matcher::Matcher(const Matcher& that) : expression(that.expression), mode(that.mode), reversed(that.reversed) { 26 | } 27 | 28 | Matcher& Matcher::operator !() { 29 | reversed = !reversed; 30 | return *this; 31 | } 32 | 33 | bool Matcher::operator()(const std::string& text) const { 34 | boost::regex exp(expression); 35 | bool result = (mode == Search) ? boost::regex_search(text, exp) : boost::regex_match(text, exp); 36 | return reversed ? !result : result; 37 | } 38 | 39 | Matcher::Mode Matcher::getMode() const { 40 | return mode; 41 | } 42 | 43 | const std::string& Matcher::getExpression() const { 44 | return expression; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /include/SpecificationRegistry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SPECIFICATIONREGISTRY_H_ 18 | #define SPECIFICATIONREGISTRY_H_ 19 | 20 | #include "Runnable.h" 21 | #include "CppSpecConfig.h" 22 | #include 23 | 24 | namespace CppSpec { 25 | 26 | class CppSpec_EXPORT SpecificationRegistry { 27 | public: 28 | typedef std::vector SpecificationList; 29 | 30 | public: 31 | static SpecificationRegistry& instance(); 32 | void addSpecification(Runnable* specification); 33 | 34 | const SpecificationList& getSpecifications() const; 35 | 36 | void clear(); 37 | 38 | private: 39 | explicit SpecificationRegistry(); 40 | SpecificationRegistry(const SpecificationRegistry&); 41 | SpecificationRegistry& operator=(const SpecificationRegistry&); 42 | 43 | private: 44 | SpecificationList specifications; 45 | }; 46 | 47 | } 48 | 49 | #endif /*SPECIFICATIONREGISTRY_H_*/ 50 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2007 Timo Puronen 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | find_package(GTest REQUIRED) 18 | include_directories(../include ${GTEST_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) 19 | 20 | set(CPPSPEC_SRCS ../src/SpecDoxReporter.cpp ../src/Matcher.cpp ../src/SpecificationRegistry.cpp ../src/SpecRunner.cpp ../src/BoostTimer.cpp 21 | ../src/JUnitReporter.cpp ../src/FileOutputStream.cpp ../src/ConsoleOutputStream.cpp ../src/Util.cpp ../src/SpecResult.cpp) 22 | 23 | set(CPPSPEC_TEST_SRCS main.cpp JUnitReporterTest.cpp SpecDoxReporterTest.cpp BoostTimerTest.cpp SpecificationRegistryTest.cpp 24 | InvokingTypeTest.cpp TypeHasStreamingOperatorTest.cpp VoidSpecification.cpp MatcherTest.cpp 25 | ExpectationTest.cpp InvocationTest.cpp ExceptionThrowingSpecificationTest.cpp SpecificationTest.cpp 26 | DummyReporter.cpp SpecRunnerTest.cpp) 27 | 28 | add_executable(CppSpecGTest ${CPPSPEC_SRCS} ${CPPSPEC_TEST_SRCS}) 29 | link_directories(${BOOST_LIBRARY_DIRS}) 30 | target_link_libraries(CppSpecGTest ${GTEST_BOTH_LIBRARIES} ${Boost_LIBRARIES}) 31 | 32 | add_test(CppSpecTests CppSpecGTest) 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppSpec 2 | 3 | CppSpec is a behavior driven development (BDD) framework for C++. BDD is a refinement of TDD which turns the focus from writing the tests to the process of defining the behavior of the software using tests. You can read more about BDD from www.behaviour-driven.org. 4 | 5 | CppSpec is licensed under Apache License, version 2.0.

6 | 7 | ## Using CppSpec 8 | 9 | To define behavior of your class you need to create a specifications for different states of your class. Specification is created by deriving from CppSpec::Specification class. Expectations for the behavior are written using specify method. 10 | 11 | ### Basic validation 12 | 13 | specify(should.be.empty()); 14 | specify(not should.be.empty()); 15 | specify(context().count(), should.equal(1)); 16 | 17 | ### Exception handling 18 | 19 | Exceptions are tested by calling a method which should throw an exception and verifying the result. For example: 20 | 21 | specify(invoking(&Stack::pop).should.raise.exception()); 22 | 23 | ### Containers 24 | 25 | If the context implements iterator interface, you can specify that context should contain either unique items or sequences using contain keyword. 26 | 27 | specify(should.contain("key")); 28 | specify(should.contain(sequence.begin(), sequence.end())); 29 | 30 | ### Regular expressions 31 | 32 | specify(context().asString(), should.match(pattern)); 33 | 34 | ## Building 35 | 36 | Building CppSpec requires CMake and Boost. See CMake documentation for more information about building using CMake. -------------------------------------------------------------------------------- /include/InvokingType.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef INVOKINGTYPE_H_ 18 | #define INVOKINGTYPE_H_ 19 | 20 | #include 21 | #include "Invocation.h" 22 | 23 | namespace CppSpec { 24 | 25 | class InvokingType { 26 | public: 27 | template 28 | explicit InvokingType(Invocation invocation) : should(*this), raise(*this), invocation(invocation) { 29 | } 30 | 31 | virtual ~InvokingType() { 32 | } 33 | 34 | InvokingType(const InvokingType& that) : should(*this), raise(*this), invocation(that.invocation) { 35 | } 36 | 37 | template 38 | InvocationResult exception() { 39 | return Invocation(invocation).invoke(); 40 | } 41 | 42 | template 43 | InvocationResult exception(T expected) { 44 | return Invocation(invocation).invoke(expected); 45 | } 46 | 47 | public: 48 | InvokingType& should; 49 | InvokingType& raise; 50 | 51 | private: 52 | boost::function invocation; 53 | 54 | private: 55 | InvokingType& operator=(const InvokingType&); 56 | }; 57 | 58 | } 59 | 60 | #endif /* INVOKINGTYPE_H_ */ 61 | -------------------------------------------------------------------------------- /include/TypeNameResolver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #ifdef __GNUC__ 20 | #include 21 | #endif 22 | 23 | #ifndef TYPENAMERESOLVER_H_ 24 | #define TYPENAMERESOLVER_H_ 25 | 26 | namespace CppSpec { 27 | 28 | class TypeNameResolver { 29 | public: 30 | template 31 | std::string getTypename() const { 32 | #if __GNUC__ 33 | int status; 34 | char* demangledName = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, &status); 35 | std::string demangled(demangledName); 36 | ::free(demangledName); 37 | return demangled; 38 | #else 39 | return typeid(T).name(); 40 | #endif 41 | } 42 | 43 | template 44 | std::string getTypename(T& t) { 45 | #if __GNUC__ 46 | int status; 47 | char* demangledName = abi::__cxa_demangle(typeid(t).name(), NULL, NULL, &status); 48 | std::string demangled(demangledName); 49 | ::free(demangledName); 50 | return demangled; 51 | #else 52 | return typeid(t).name(); 53 | #endif 54 | } 55 | }; 56 | 57 | } 58 | 59 | #endif /* TYPENAMERESOLVER_H_ */ 60 | -------------------------------------------------------------------------------- /examples/RegExSpec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef REGEXSPEC_H_ 18 | #define REGEXSPEC_H_ 19 | 20 | #include "CppSpec.h" 21 | #include 22 | 23 | class RegExSpec : public CppSpec::Specification { 24 | public: 25 | explicit RegExSpec() { 26 | REGISTER_BEHAVIOUR(RegExSpec, shouldContainPattern); 27 | REGISTER_BEHAVIOUR(RegExSpec, shouldNotContainPattern); 28 | REGISTER_BEHAVIOUR(RegExSpec, shouldMatchPattern); 29 | } 30 | 31 | std::string* createContext() { 32 | std::string* context = new std::string("abc.def@ghi.jkl"); 33 | return context; 34 | } 35 | 36 | void shouldContainPattern() { 37 | std::string pattern("def@"); 38 | specify(context(), should.contain(pattern)); 39 | } 40 | 41 | void shouldNotContainPattern() { 42 | std::string pattern("defa"); 43 | specify(context(), not should.contain(pattern)); 44 | } 45 | 46 | void shouldMatchPattern() { 47 | const std::string regexp("^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$"); 48 | specify(context(), should.match(regexp)); 49 | } 50 | } regExSpec; 51 | 52 | #endif /*REGEXSPEC_H_*/ 53 | -------------------------------------------------------------------------------- /test/ExpectationTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "Expectation.h" 19 | 20 | using CppSpec::Expectation; 21 | using CppSpec::FloatExpectation; 22 | 23 | TEST(ExpectationTest, sameTypesEqual) { 24 | std::string result("expected"); 25 | Expectation expected(result); 26 | EXPECT_TRUE(expected.equals(std::string("expected"))); 27 | EXPECT_TRUE((!expected).equals("something else")); 28 | } 29 | 30 | TEST(ExpectationTest, convertibleTypesEqual) { 31 | std::string result("expected"); 32 | Expectation expected(result); 33 | EXPECT_TRUE(expected.equals("expected")); 34 | } 35 | 36 | TEST(ExpectationTest, intTypesEqual) { 37 | const int result = 24; 38 | Expectation expected(result); 39 | EXPECT_TRUE(expected.equals(24)); 40 | EXPECT_TRUE((!expected).equals(25)); 41 | } 42 | 43 | TEST(FloatExpectationTest, floatTypesEqual) { 44 | const float result = 2.4f; 45 | const float tolerance = 0.05f; 46 | FloatExpectation expected(result, tolerance); 47 | EXPECT_TRUE(expected.almostEquals(2.41f)); 48 | EXPECT_TRUE((!expected).almostEquals(2.5f)); 49 | } 50 | -------------------------------------------------------------------------------- /test/MatcherTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "Matcher.h" 19 | 20 | using CppSpec::Matcher; 21 | 22 | TEST(MatcherTest, findsSubstring) { 23 | Matcher matcher("violence", Matcher::Search); 24 | EXPECT_TRUE(matcher("Words like violence break the silence.")); 25 | } 26 | 27 | TEST(MatcherTest, substringNotFound) { 28 | Matcher matcher("enjoy", Matcher::Search); 29 | EXPECT_FALSE(matcher("Words like violence break the silence.")); 30 | } 31 | 32 | TEST(MatcherTest, stringsMatch) { 33 | Matcher matcher(".*violence.*silence.*", Matcher::Match); 34 | EXPECT_TRUE(matcher("Words like violence break the silence.")); 35 | } 36 | 37 | TEST(MatcherTest, stringsDoNotMatch) { 38 | Matcher matcher(".*silence.*violence.*", Matcher::Match); 39 | !matcher; 40 | EXPECT_TRUE(matcher("Words like violence break the silence.")); 41 | } 42 | 43 | TEST(MatcherTest, copy) { 44 | Matcher matcher(".*silence.*violence.*", Matcher::Match); 45 | Matcher that(matcher); 46 | EXPECT_EQ(that.getMode(), Matcher::Match); 47 | EXPECT_EQ(that.getExpression(), ".*silence.*violence.*"); 48 | } 49 | -------------------------------------------------------------------------------- /examples/ContainmentSpec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "CppSpec.h" 18 | 19 | #include 20 | 21 | class VectorSpec : public CppSpec::Specification, VectorSpec> { 22 | public: 23 | VectorSpec() { 24 | REGISTER_BEHAVIOUR(VectorSpec, shouldContainOne); 25 | REGISTER_BEHAVIOUR(VectorSpec, shouldNotContainThree); 26 | REGISTER_BEHAVIOUR(VectorSpec, shouldContainSequence); 27 | REGISTER_BEHAVIOUR(VectorSpec, shouldNotContainSeq123); 28 | } 29 | 30 | std::vector* createContext() { 31 | std::vector* context = new std::vector(); 32 | context->push_back(6); 33 | context->push_back(1); 34 | context->push_back(7); 35 | context->push_back(8); 36 | context->push_back(2); 37 | return context; 38 | } 39 | 40 | void shouldContainOne() { 41 | specify(should.have.element(1)); 42 | } 43 | 44 | void shouldNotContainThree() { 45 | specify(not should.have.element(3)); 46 | } 47 | 48 | void shouldContainSequence() { 49 | std::vector vector; 50 | vector.push_back(7); 51 | vector.push_back(8); 52 | specify(should.have.elements(vector.begin(), vector.end())); 53 | } 54 | 55 | void shouldNotContainSeq123() { 56 | std::vector vector; 57 | vector.push_back(1); 58 | vector.push_back(2); 59 | vector.push_back(3); 60 | specify(not should.have.elements(vector.begin(), vector.end())); 61 | } 62 | } vectorSpec; 63 | 64 | -------------------------------------------------------------------------------- /include/JUnitReporter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef JUNITREPORTER_H_ 18 | #define JUNITREPORTER_H_ 19 | 20 | #include "Reporter.h" 21 | #include "Timer.h" 22 | #include 23 | #include 24 | 25 | namespace CppSpec { 26 | 27 | class OutputStream; 28 | 29 | class JUnitReporter : public Reporter { 30 | public: 31 | JUnitReporter(); 32 | JUnitReporter(const std::string& reportDirectory); 33 | 34 | ~JUnitReporter(); 35 | 36 | public: // from Reporter 37 | void addSpecification(const SpecResult& results); 38 | bool anyBehaviorFailed() const; 39 | 40 | public: 41 | struct Result { 42 | Result(const std::string& behaviorName, const std::string& reason, bool pass, const std::string& duration, const std::string& file, int line) 43 | : behaviorName(behaviorName), reason(reason), pass(pass), duration(duration), file(file), line(line) { 44 | } 45 | 46 | std::string behaviorName; 47 | std::string reason; 48 | bool pass; 49 | std::string duration; 50 | std::string file; 51 | int line; 52 | }; 53 | 54 | private: 55 | OutputStream* createOutputStream(const std::string& reportDirectory); 56 | std::string currentTime(); 57 | 58 | private: 59 | JUnitReporter(const JUnitReporter& rhs); 60 | JUnitReporter& operator= (const JUnitReporter& rhs); 61 | 62 | private: 63 | bool createLogFiles; 64 | std::string reportDirectory; 65 | bool failOccured; 66 | }; 67 | 68 | } 69 | 70 | #endif /*JUNITREPORTER_H_*/ 71 | -------------------------------------------------------------------------------- /test/SpecDoxReporterTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "OutputStreamStub.h" 19 | #include "SpecDoxReporter.h" 20 | #include "SpecResult.h" 21 | 22 | class SpecDoxReporterTest : public ::testing::Test { 23 | protected: 24 | SpecDoxReporterTest() : outputStream(new OutputStreamStub), reporter(new CppSpec::SpecDoxReporter(*outputStream)) { 25 | } 26 | 27 | ~SpecDoxReporterTest() { 28 | delete reporter; 29 | reporter = NULL; 30 | delete outputStream; 31 | outputStream = NULL; 32 | } 33 | 34 | OutputStreamStub* outputStream; 35 | CppSpec::SpecDoxReporter* reporter; 36 | }; 37 | 38 | TEST_F(SpecDoxReporterTest, specificationRun) { 39 | CppSpec::SpecResult results("TestSpec"); 40 | reporter->addSpecification(results); 41 | EXPECT_EQ("TestSpec:\nTestSpec executed, 0 of 0 behaviors passed and 0 failed.\n\n", outputStream->written()); 42 | } 43 | 44 | TEST_F(SpecDoxReporterTest, specificationWithPassingBehavior) { 45 | CppSpec::SpecResult results("TestSpec"); 46 | results.addPass("thisShouldPass", "00.010000"); 47 | reporter->addSpecification(results); 48 | EXPECT_EQ("TestSpec:\n this should pass\nTestSpec executed, 1 of 1 behaviors passed and 0 failed.\n\n", outputStream->written()); 49 | } 50 | 51 | TEST_F(SpecDoxReporterTest, specificationWithFailingBehavior) { 52 | CppSpec::SpecResult results("TestSpec"); 53 | results.addFail("thisShouldPass", "00.010000", "file.cpp", 10, "an exception occured"); 54 | reporter->addSpecification(results); 55 | EXPECT_EQ("TestSpec:\n this should pass, an exception occured in file.cpp:10\nTestSpec executed, 0 of 1 behaviors passed and 1 failed.\n\n", outputStream->written()); 56 | } 57 | -------------------------------------------------------------------------------- /test/JUnitReporterTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "JUnitReporter.h" 19 | #include "SpecResult.h" 20 | 21 | class JUnitReporterTest : public ::testing::Test { 22 | protected: 23 | virtual void SetUp() { 24 | stream = new std::stringstream(); 25 | coutBuf = std::cout.rdbuf(); 26 | std::cout.rdbuf(stream->rdbuf()); 27 | 28 | reporter = new CppSpec::JUnitReporter(); 29 | } 30 | 31 | virtual void TearDown() { 32 | delete reporter; 33 | std::cout.rdbuf(coutBuf); 34 | delete stream; 35 | } 36 | 37 | CppSpec::JUnitReporter* reporter; 38 | std::stringstream* stream; 39 | std::streambuf* coutBuf; 40 | }; 41 | 42 | TEST_F(JUnitReporterTest, oneSuiteWithOnePass) { 43 | CppSpec::SpecResult result("TestSpec"); 44 | result.addPass("Behavior", "00.010000"); 45 | result.setDuration("00.010000"); 46 | reporter->addSpecification(result); 47 | const std::string& log(stream->str()); 48 | 49 | EXPECT_NE(std::string::npos, log.find("tests=\"1\"")); 50 | EXPECT_NE(std::string::npos, log.find("anyBehaviorFailed()); 53 | } 54 | 55 | TEST_F(JUnitReporterTest, oneFail) { 56 | CppSpec::SpecResult result("TestSpec"); 57 | result.addFail("Behavior", "00.010000", "Foo.cpp", 10, "An exception occured"); 58 | reporter->addSpecification(result); 59 | const std::string& log(stream->str()); 60 | 61 | EXPECT_NE(std::string::npos, log.find("failures=\"1\"")); 62 | EXPECT_TRUE(reporter->anyBehaviorFailed()); 63 | } 64 | -------------------------------------------------------------------------------- /include/SpecResult.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __SPEC_RESULT__ 18 | #define __SPEC_RESULT__ 19 | 20 | #include "CppSpecConfig.h" 21 | #include 22 | #include 23 | 24 | namespace CppSpec { 25 | 26 | class SpecResult { 27 | public: 28 | struct BehaviorResult { 29 | BehaviorResult() {} 30 | BehaviorResult(const BehaviorResult& that); 31 | std::string name; 32 | std::string duration; 33 | bool passed; 34 | std::string file; 35 | std::string message; 36 | int line; 37 | }; 38 | 39 | public: 40 | SpecResult(const std::string& name); 41 | SpecResult(const SpecResult& that); 42 | SpecResult& operator=(const SpecResult& that); 43 | 44 | void addPass(const std::string& name, const std::string& duration); 45 | void addFail(const std::string& name, const std::string& duration, const std::string& message); 46 | void addFail(const std::string& name, const std::string& duration, const std::string& file, int line, const std::string& message); 47 | 48 | const std::string& getSpecificationName() const {return specificationName;} 49 | 50 | void setDuration(const std::string& specDuration) {duration = specDuration;} 51 | const std::string& getDuration() const {return duration;} 52 | 53 | std::vector::const_iterator firstBehavior() const {return behaviorResults.begin();} 54 | std::vector::const_iterator lastBehavior() const {return behaviorResults.end();} 55 | size_t passCount() const; 56 | size_t failCount() const; 57 | 58 | private: 59 | std::string specificationName; 60 | std::string duration; 61 | std::vector behaviorResults; 62 | }; 63 | 64 | } 65 | 66 | #endif // __SPEC_RESULT__ -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2007 - 2009 Timo Puronen 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../lib) 18 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../bin) 19 | set(CPPSPEC_SRCS SpecDoxReporter.cpp SpecificationRegistry.cpp SpecRunner.cpp Util.cpp SpecResult.cpp 20 | Timer.cpp Matcher.cpp JUnitReporter.cpp BoostTimer.cpp FileOutputStream.cpp ConsoleOutputStream.cpp) 21 | file(GLOB CPPSPEC_INCLUDES ../include/*.h) 22 | 23 | include_directories("${CMAKE_HOME_DIRECTORY}/include" ${Boost_INCLUDE_DIRS}) 24 | link_directories(${Boost_LIBRARY_DIRS}) 25 | add_library(CppSpec SHARED ${CPPSPEC_SRCS}) 26 | target_link_libraries(CppSpec ${Boost_LIBRARIES}) 27 | 28 | if(MSVC_IDE) 29 | file(GLOB CPPSPEC_HEADERS "${CMAKE_HOME_DIRECTORY}/include/*.h") 30 | source_group("Header Files" FILES ${CPPSPEC_HEADERS}) 31 | 32 | list(APPEND CPPSPEC_SRCS ${CPPSPEC_HEADERS}) 33 | endif(MSVC_IDE) 34 | 35 | if(UNIX) 36 | set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} " -Wall -Wextra") 37 | endif(UNIX) 38 | 39 | if(MSVC) 40 | set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} " /EHsc") 41 | endif(MSVC) 42 | 43 | 44 | install(TARGETS CppSpec 45 | RUNTIME DESTINATION bin 46 | LIBRARY DESTINATION lib 47 | ARCHIVE DESTINATION lib) 48 | 49 | install(FILES ${CPPSPEC_INCLUDES} DESTINATION include/CppSpec) 50 | 51 | set(CPACK_PACKAGE_NAME "cppspec") 52 | set(CPACK_PACKAGE_VERSION_MAJOR 0) 53 | set(CPACK_PACKAGE_VERSION_MINOR 5) 54 | set(CPACK_PACKAGE_VERSION_PATCH 0) 55 | set(CPACK_PACKAGE_CONTACT timo.puronen@reaktor.fi) 56 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Behavior-driven development framework for C++") 57 | #set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_HOME_DIRECTORY}/README") 58 | #set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_HOME_DIRECTORY}/LICENSE") 59 | set(CPACK_NSIS_MODIFY_PATH ON) 60 | 61 | include(CPack) 62 | include(InstallRequiredSystemLibraries) 63 | -------------------------------------------------------------------------------- /src/SpecDoxReporter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "SpecDoxReporter.h" 18 | #include "Runnable.h" 19 | #include "ConsoleOutputStream.h" 20 | #include "SpecResult.h" 21 | #include 22 | 23 | namespace CppSpec { 24 | 25 | SpecDoxReporter::SpecDoxReporter(OutputStream& outputStream) : outputStream(outputStream), anyFailed(false) { 26 | } 27 | 28 | SpecDoxReporter::~SpecDoxReporter() { 29 | } 30 | 31 | void SpecDoxReporter::addSpecification(const SpecResult &results) { 32 | int pass(0); 33 | int fail(0); 34 | outputStream << results.getSpecificationName() << ":" << "\n"; 35 | for (std::vector::const_iterator it = results.firstBehavior(); it != results.lastBehavior(); it++) { 36 | outputStream << " " << formatCamelCasedWordsAndUnderlines(it->name); 37 | if (it->passed) { 38 | outputStream << "\n"; 39 | ++pass; 40 | } else { 41 | outputStream << ", " << it->message << " in " << it->file << ":" << it->line << "\n"; 42 | ++fail; 43 | } 44 | } 45 | anyFailed = anyFailed || (fail != 0); 46 | outputStream << results.getSpecificationName() << " executed, " << pass << " of " << pass + fail << " behaviors passed and " << fail << " failed." << "\n" << "\n"; 47 | } 48 | 49 | bool SpecDoxReporter::anyBehaviorFailed() const { 50 | return anyFailed; 51 | } 52 | 53 | std::string SpecDoxReporter::formatCamelCasedWordsAndUnderlines(const std::string& text) { 54 | std::string result; 55 | std::string::iterator it = (const_cast(text)).begin(); 56 | while(it != text.end()) { 57 | if(::isupper(*it)) { 58 | result.append(" "); 59 | } 60 | if('_' == *it) { 61 | result.append(" "); 62 | } else { 63 | result += ::tolower(*it); 64 | } 65 | ++it; 66 | } 67 | return result; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /test/InvokingTypeTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include "InvokingType.h" 20 | #include 21 | 22 | using namespace CppSpec; 23 | 24 | class Context { 25 | public: 26 | explicit Context() : methodCalled(false) {} 27 | 28 | void voidMethodWithNoArgs() {methodCalled = true;} 29 | void voidMethodWithOneArg(int a) {methodCalled = true;} 30 | void voidMethodWithTwoArgs(int a, int b) {methodCalled = true;} 31 | void voidMethodWithThreeArgs(int a, int b, int c) {methodCalled = true;} 32 | void voidMethodWithFourArgs(int a, int b, int c, int d) {methodCalled = true;} 33 | void voidMethodWithFiveArgs(int a, int b, int c, int d, int e) {methodCalled = true;} 34 | 35 | public: 36 | bool methodCalled; 37 | }; 38 | 39 | class InvokingTypeTest : public ::testing::Test { 40 | protected: 41 | InvokingTypeTest() { 42 | context = new Context; 43 | } 44 | 45 | ~InvokingTypeTest() { 46 | delete context; 47 | context = NULL; 48 | } 49 | 50 | Context* context; 51 | }; 52 | 53 | TEST_F(InvokingTypeTest, callMethodWithNoArgs) { 54 | InvokingType functor(boost::bind(&Context::voidMethodWithNoArgs, context)); 55 | functor.exception(); 56 | ASSERT_TRUE(context->methodCalled); 57 | } 58 | 59 | TEST_F(InvokingTypeTest, callMethodWithOneArg) { 60 | InvokingType functor(boost::bind(&Context::voidMethodWithOneArg, context, 1)); 61 | functor.exception(); 62 | ASSERT_TRUE(context->methodCalled); 63 | } 64 | 65 | TEST_F(InvokingTypeTest, callMethodWithTwoArgs) { 66 | InvokingType functor(boost::bind(&Context::voidMethodWithTwoArgs, context, 1, 2)); 67 | functor.exception(); 68 | ASSERT_TRUE(context->methodCalled); 69 | } 70 | 71 | TEST_F(InvokingTypeTest, callMethodWithThreeArgs) { 72 | InvokingType functor(boost::bind(&Context::voidMethodWithThreeArgs, context, 1, 2, 3)); 73 | functor.exception(); 74 | ASSERT_TRUE(context->methodCalled); 75 | } 76 | 77 | TEST_F(InvokingTypeTest, callMethodWithFourArgs) { 78 | InvokingType functor(boost::bind(&Context::voidMethodWithFourArgs, context, 1, 2, 3, 4)); 79 | functor.exception(); 80 | ASSERT_TRUE(context->methodCalled); 81 | } 82 | -------------------------------------------------------------------------------- /include/Expectation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef EXPECTATION_H_ 18 | #define EXPECTATION_H_ 19 | 20 | #include 21 | 22 | namespace CppSpec { 23 | 24 | template 25 | class Expectation { 26 | public: 27 | explicit Expectation(const T& expected) : expected(expected), reversed(false) { 28 | } 29 | 30 | Expectation(const Expectation& rhs) : expected(rhs.expected), reversed(rhs.reversed) { 31 | } 32 | 33 | template 34 | bool equals(const U& actual) const { 35 | bool result = (expected == actual); 36 | return result ^ reversed; 37 | } 38 | 39 | Expectation& operator !() { 40 | reversed = !reversed; 41 | return *this; 42 | } 43 | 44 | const T& operator()() const { 45 | return expected; 46 | } 47 | 48 | private: 49 | Expectation& operator =(const Expectation&); 50 | 51 | private: 52 | const T& expected; 53 | bool reversed; 54 | }; 55 | 56 | template 57 | class FloatExpectation { 58 | public: 59 | explicit FloatExpectation(const T& expected, const T& tolerance) : 60 | expected(expected), 61 | tolerance(tolerance), 62 | reversed(false) 63 | { 64 | } 65 | 66 | FloatExpectation(const FloatExpectation& rhs) : 67 | expected(rhs.expected), 68 | tolerance(rhs.tolerance), 69 | reversed(rhs.reversed) { 70 | } 71 | 72 | template 73 | bool almostEquals(const U& actual) const { 74 | bool result = (upper() > actual) && (lower() < actual); 75 | return result ^ reversed; 76 | } 77 | 78 | FloatExpectation& operator !() { 79 | reversed = !reversed; 80 | return *this; 81 | } 82 | 83 | const T& operator()() const { 84 | return expected; 85 | } 86 | 87 | const T upper() const { 88 | return expected + tolerance; 89 | } 90 | const T lower() const { 91 | return expected - tolerance; 92 | } 93 | 94 | private: 95 | FloatExpectation& operator =(const FloatExpectation&); 96 | 97 | private: 98 | const T& expected; 99 | const T& tolerance; 100 | bool reversed; 101 | 102 | }; 103 | 104 | 105 | } 106 | 107 | #endif /* EXPECTATION_H_ */ 108 | -------------------------------------------------------------------------------- /src/SpecResult.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "SpecResult.h" 18 | #include 19 | #include 20 | 21 | namespace CppSpec { 22 | 23 | SpecResult::BehaviorResult::BehaviorResult(const SpecResult::BehaviorResult& that) 24 | : name(that.name), duration(that.duration), passed(that.passed), file(that.file), message(that.message), line(that.line) 25 | { 26 | } 27 | 28 | SpecResult::SpecResult(const std::string& name) : specificationName(name) { 29 | } 30 | 31 | SpecResult::SpecResult(const SpecResult& that) : specificationName(that.specificationName), duration(that.duration) { 32 | behaviorResults.resize(that.behaviorResults.size()); 33 | std::copy(that.firstBehavior(), that.lastBehavior(), behaviorResults.begin()); 34 | } 35 | 36 | SpecResult& SpecResult::operator=(const SpecResult& that) { 37 | specificationName = that.specificationName; 38 | duration = that.duration; 39 | behaviorResults.resize(that.behaviorResults.size()); 40 | std::copy(that.firstBehavior(), that.lastBehavior(), behaviorResults.begin()); 41 | return *this; 42 | } 43 | 44 | void SpecResult::addPass(const std::string& name, const std::string& duration) { 45 | BehaviorResult result; 46 | result.name = name; 47 | result.duration = duration; 48 | result.passed = true; 49 | behaviorResults.push_back(result); 50 | } 51 | 52 | void SpecResult::addFail(const std::string& name, const std::string& duration, const std::string& message) { 53 | addFail(name, duration, "", 0, message); 54 | } 55 | 56 | void SpecResult::addFail(const std::string& name, const std::string& duration, 57 | const std::string& file, int line, const std::string& message) { 58 | BehaviorResult result; 59 | result.name = name; 60 | result.duration = duration; 61 | result.passed = false; 62 | result.file = file; 63 | result.line = line; 64 | result.message = message; 65 | behaviorResults.push_back(result); 66 | } 67 | 68 | size_t SpecResult::passCount() const { 69 | return std::count_if(behaviorResults.begin(), behaviorResults.end(), 70 | boost::lambda::bind(&BehaviorResult::passed, boost::lambda::_1) == true); 71 | } 72 | 73 | size_t SpecResult::failCount() const { 74 | return std::count_if(behaviorResults.begin(), behaviorResults.end(), 75 | boost::lambda::bind(&BehaviorResult::passed, boost::lambda::_1) == false); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/JUnitReporter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "JUnitReporter.h" 18 | #include "Runnable.h" 19 | #include "FileOutputStream.h" 20 | #include "ConsoleOutputStream.h" 21 | #include "SpecResult.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace CppSpec { 28 | 29 | JUnitReporter::JUnitReporter() 30 | : createLogFiles(false), reportDirectory(), failOccured(false) { 31 | } 32 | 33 | JUnitReporter::JUnitReporter(const std::string& reportDirectory) 34 | : createLogFiles(true), reportDirectory(reportDirectory), failOccured(false) { 35 | } 36 | 37 | JUnitReporter::~JUnitReporter() { 38 | } 39 | 40 | void JUnitReporter::addSpecification(const SpecResult& results) { 41 | const int fails(results.failCount()); 42 | const int pass(results.passCount()); 43 | failOccured = (fails != 0) || failOccured; 44 | OutputStream* output = createOutputStream(results.getSpecificationName()); 45 | (*output) << "" << "\n"; 46 | (*output) << "" << "\n"; 48 | 49 | for (BOOST_AUTO(it, results.firstBehavior()); it != results.lastBehavior(); ++it) { 50 | (*output) << "name 54 | << "\" time=\"" 55 | << it->duration << "\""; 56 | if (it->passed) { 57 | (*output) << " />" << "\n"; 58 | } else { 59 | (*output) << ">" << "\n"; 60 | (*output) << "message << " at " << it->file << ":" << it->line << "\" />" << "\n"; 61 | (*output) << "" << "\n"; 62 | } 63 | } 64 | 65 | (*output) << "" << "\n"; 66 | delete output; 67 | } 68 | 69 | bool JUnitReporter::anyBehaviorFailed() const { 70 | return failOccured; 71 | } 72 | 73 | OutputStream* JUnitReporter::createOutputStream(const std::string& specificationName) { 74 | if(createLogFiles) { 75 | return new FileOutputStream(reportDirectory, specificationName); 76 | } 77 | 78 | return new ConsoleOutputStream; 79 | } 80 | 81 | std::string JUnitReporter::currentTime() { 82 | using namespace boost::posix_time; 83 | return to_simple_string(second_clock::local_time()); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /test/InvocationTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "Invocation.h" 19 | #include "Specification.h" 20 | 21 | using CppSpec::Invocation; 22 | using CppSpec::InvocationResult; 23 | 24 | void methodThrowingInt() { 25 | throw 5; 26 | } 27 | 28 | void methodThrowingStdException() { 29 | class stdexception : public std::exception { 30 | public: 31 | const char* what() const throw() {return "std::exception";} 32 | }; 33 | throw stdexception(); 34 | } 35 | 36 | void nonThrowingMethod() {} 37 | 38 | 39 | TEST(InvocationTest, methodThrowsExpectedException) { 40 | Invocation invocation(&methodThrowingInt); 41 | InvocationResult result = invocation.invoke(); 42 | EXPECT_TRUE(result.wasSuccess()); 43 | } 44 | 45 | TEST(InvocationTest, methodThrowsDifferentExceptionType) { 46 | Invocation invocation(&methodThrowingInt); 47 | InvocationResult result = invocation.invoke(); 48 | EXPECT_FALSE(result.wasSuccess()); 49 | EXPECT_EQ("Expected std::string but unknown type was thrown", result.getDescription()); 50 | } 51 | 52 | TEST(InvocationTest, methodThrowsExpectedValue) { 53 | Invocation invocation(&methodThrowingInt); 54 | InvocationResult result = invocation.invoke(5); 55 | EXPECT_TRUE(result.wasSuccess()); 56 | } 57 | 58 | TEST(InvocationTest, methodThrowsOtherValue) { 59 | Invocation invocation(&methodThrowingInt); 60 | InvocationResult result = invocation.invoke(1); 61 | EXPECT_EQ("Expected int[1] but int[5] was thrown", result.getDescription()); 62 | EXPECT_FALSE(result.wasSuccess()); 63 | } 64 | 65 | TEST(InvocationTest, methodThrowsStdExceptionWhenIntExpected) { 66 | Invocation invocation(&methodThrowingStdException); 67 | InvocationResult result = invocation.invoke(1); 68 | EXPECT_EQ("Expected int but methodThrowingStdException()::stdexception[std::exception] was thrown", result.getDescription()); 69 | EXPECT_FALSE(result.wasSuccess()); 70 | } 71 | 72 | TEST(InvocationTest, methodThrowsDifferentTypeWhenValueExpected) { 73 | Invocation invocation(&methodThrowingInt); 74 | InvocationResult result = invocation.invoke(std::string("Exception")); 75 | EXPECT_EQ("Expected std::string but unknown type was thrown", result.getDescription()); 76 | EXPECT_FALSE(result.wasSuccess()); 77 | } 78 | 79 | TEST(InvocationTest, methodDoesNotThrowException) { 80 | Invocation invocation(&nonThrowingMethod); 81 | InvocationResult result = invocation.invoke(std::string("Exception")); 82 | EXPECT_EQ("Expected std::string but no exception was thrown", result.getDescription()); 83 | EXPECT_FALSE(result.wasSuccess()); 84 | } 85 | -------------------------------------------------------------------------------- /test/SpecificationTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "CppSpec.h" 19 | #include "DummyReporter.h" 20 | #include "TimerStub.h" 21 | 22 | using CppSpec::Specification; 23 | 24 | class EmptyTestSpec : public Specification { 25 | }; 26 | 27 | class SpecWithBehaviours : public Specification { 28 | public: 29 | SpecWithBehaviours() { 30 | REGISTER_BEHAVIOUR(SpecWithBehaviours, passingBehaviour); 31 | REGISTER_BEHAVIOUR(SpecWithBehaviours, failingBehaviour); 32 | REGISTER_BEHAVIOUR(SpecWithBehaviours, intsShouldEqual); 33 | REGISTER_BEHAVIOUR(SpecWithBehaviours, intsAreInequal); 34 | REGISTER_BEHAVIOUR(SpecWithBehaviours, findsSubstring); 35 | REGISTER_BEHAVIOUR(SpecWithBehaviours, substringIsNotFound); 36 | REGISTER_BEHAVIOUR(SpecWithBehaviours, stringsDoNotMatch); 37 | } 38 | 39 | void passingBehaviour() { 40 | specify(true); 41 | } 42 | 43 | void failingBehaviour() { 44 | specify(false); 45 | } 46 | 47 | void intsShouldEqual() { 48 | specify(2, should.equal(2)); 49 | } 50 | 51 | void intsAreInequal() { 52 | specify(1, should.equal(2)); 53 | } 54 | 55 | void findsSubstring() { 56 | specify("silence", should.contain("si")); 57 | } 58 | 59 | void substringIsNotFound() { 60 | specify("silence", should.contain("is")); 61 | } 62 | 63 | void stringsDoNotMatch() { 64 | specify("silence", should.match("noise")); 65 | } 66 | }; 67 | 68 | TEST(EmptySpecificationTest, HasName) { 69 | EmptyTestSpec spec; 70 | EXPECT_EQ(std::string("EmptyTestSpec"), spec.getName()); 71 | } 72 | 73 | TEST(EmptySpecificationTest, HasCountOfZero) { 74 | EmptyTestSpec spec; 75 | EXPECT_EQ((size_t)0, spec.getBehaviorCount()); 76 | } 77 | 78 | class SpecWithBehavioursTest : public ::testing::Test { 79 | protected: 80 | void SetUp() { 81 | spec = new SpecWithBehaviours(); 82 | } 83 | 84 | void TearDown() { 85 | delete spec; 86 | spec = NULL; 87 | } 88 | 89 | SpecWithBehaviours* spec; 90 | }; 91 | 92 | TEST_F(SpecWithBehavioursTest, HasCount) { 93 | EXPECT_EQ((size_t)7, spec->getBehaviorCount()); 94 | } 95 | 96 | TEST_F(SpecWithBehavioursTest, CanCallContextForVoid) { 97 | spec->context(); 98 | } 99 | 100 | bool hasBehaviorPassed(const CppSpec::SpecResult::BehaviorResult& r) { 101 | return r.passed; 102 | } 103 | 104 | TEST_F(SpecWithBehavioursTest, BehaviorsAreExecuted) { 105 | CppSpec::SpecResult result = (*spec)(); 106 | EXPECT_EQ((size_t)3, result.passCount()); 107 | EXPECT_EQ((size_t)4, result.failCount()); 108 | } 109 | -------------------------------------------------------------------------------- /include/ShouldType.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SHOULDTYPE_H_ 18 | #define SHOULDTYPE_H_ 19 | 20 | #include "BeType.h" 21 | #include "Expectation.h" 22 | #include "Matcher.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace CppSpec { 28 | 29 | template 30 | class ShouldType { 31 | public: 32 | explicit ShouldType(ContextHolder& creator) 33 | : be(creator), have(*this), contextHolder(creator) { 34 | } 35 | 36 | public: // Interface 37 | /** 38 | * Specify that context must implement the given interface. 39 | */ 40 | template 41 | bool implement() { 42 | Base* base = dynamic_cast(&(contextHolder.context())); 43 | return base != NULL; 44 | } 45 | 46 | template 47 | bool element(const T& t) { 48 | return std::find(contextHolder.context().begin(), contextHolder.context().end(), t) != contextHolder.context().end(); 49 | } 50 | 51 | template 52 | bool elements(Iterator begin, Iterator end) { 53 | return std::search(contextHolder.context().begin(), contextHolder.context().end(), begin, end) != contextHolder.context().end(); 54 | } 55 | 56 | template 57 | Expectation equal(const T& t) { 58 | return Expectation(t); 59 | } 60 | 61 | template 62 | FloatExpectation almostEqual(const T& t, const T& r) { 63 | return FloatExpectation(t, r); 64 | } 65 | 66 | Matcher contain(const std::string& regex) { 67 | return Matcher(regex, Matcher::Search); 68 | } 69 | 70 | Matcher match(const std::string& regex) { 71 | return Matcher(regex, Matcher::Match); 72 | } 73 | 74 | private: 75 | ShouldType(const ShouldType&); 76 | ShouldType& operator=(const ShouldType&); 77 | 78 | public: // Members 79 | BeType be; 80 | ShouldType& have; 81 | 82 | private: 83 | ContextHolder& contextHolder; 84 | }; 85 | 86 | template<> 87 | class ShouldType { 88 | public: 89 | ShouldType() : have(*this) { 90 | } 91 | 92 | template 93 | Expectation equal(const T& t) { 94 | return Expectation(t); 95 | } 96 | 97 | template 98 | FloatExpectation almostEqual(const T& t, const T& r) { 99 | return FloatExpectation(t, r); 100 | } 101 | 102 | Matcher contain(const std::string& regex) { 103 | return Matcher(regex, Matcher::Search); 104 | } 105 | 106 | Matcher match(const std::string& regex) { 107 | return Matcher(regex, Matcher::Match); 108 | } 109 | 110 | public: 111 | ShouldType& have; 112 | 113 | private: 114 | ShouldType(const ShouldType&); 115 | ShouldType& operator=(const ShouldType&); 116 | }; 117 | 118 | } 119 | 120 | #endif /*SHOULDTYPE_H_*/ 121 | -------------------------------------------------------------------------------- /include/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_POOL__ 2 | #define __THREAD_POOL__ 3 | 4 | #include "Runnable.h" 5 | #include 6 | 7 | namespace CppSpec { 8 | 9 | class ThreadPool { 10 | private: 11 | class Consumer { 12 | public: 13 | template 14 | Consumer(Iterator begin, Iterator end) : specs(begin, end), threads(0) {} 15 | 16 | Runnable* getSpec() { 17 | boost::lock_guard lock(specsLock); 18 | if (specs.empty()) { 19 | return NULL; 20 | } 21 | Runnable* spec = specs.back(); 22 | specs.pop_back(); 23 | return spec; 24 | } 25 | 26 | void addResult(const SpecResult& result) { 27 | boost::lock_guard lock(resultLock); 28 | results.push_back(result); 29 | cond.notify_one(); 30 | } 31 | 32 | void operator()() { 33 | incrementThreadCount(); 34 | Runnable* spec = getSpec(); 35 | while (spec != NULL) { 36 | SpecResult result = (*spec)(); 37 | addResult(result); 38 | spec = getSpec(); 39 | } 40 | decrementThreadCount(); 41 | cond.notify_all(); 42 | } 43 | 44 | bool isReady() const { 45 | return threads == 0 && results.empty(); 46 | } 47 | 48 | private: 49 | void incrementThreadCount() { 50 | boost::lock_guard lock(threadCountLock); 51 | ++threads; 52 | } 53 | 54 | void decrementThreadCount() { 55 | boost::lock_guard lock(threadCountLock); 56 | --threads; 57 | } 58 | 59 | public: 60 | std::vector results; 61 | boost::mutex resultLock; 62 | boost::condition_variable cond; 63 | 64 | private: 65 | std::vector specs; 66 | boost::mutex specsLock; 67 | int threads; 68 | boost::mutex threadCountLock; 69 | }; 70 | 71 | public: 72 | ThreadPool(int threadCount) : threadCount(threadCount) {} 73 | 74 | template 75 | void start(InputIterator begin, InputIterator end, Reporter& reporter) { 76 | if (std::distance(begin, end) == 0) { 77 | return; 78 | } 79 | 80 | Consumer consumer(begin, end); 81 | for (int i = 0; i < threadCount; ++i) { 82 | threads.push_back(new boost::thread(boost::ref(consumer))); 83 | } 84 | 85 | while (true) { 86 | boost::unique_lock lock(consumer.resultLock); 87 | while(consumer.results.empty()) { 88 | consumer.cond.wait(lock); 89 | if (consumer.isReady()) { 90 | break; 91 | } 92 | } 93 | if (!consumer.results.empty()) { 94 | SpecResult res = consumer.results.back(); 95 | consumer.results.pop_back(); 96 | lock.unlock(); 97 | reporter.addSpecification(res); 98 | } 99 | if (consumer.isReady()) { 100 | break; 101 | } 102 | } 103 | for (std::vector::const_iterator it = threads.begin(); it != threads.end(); ++it) { 104 | (*it)->join(); 105 | delete *it; 106 | } 107 | } 108 | 109 | private: 110 | std::vector threads; 111 | int threadCount; 112 | }; 113 | 114 | } 115 | 116 | #endif // __THREAD_POOL__ -------------------------------------------------------------------------------- /examples/StackSpec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "CppSpec.h" 18 | 19 | #include 20 | 21 | template 22 | class Stack { 23 | public: 24 | explicit Stack() : elements() {} 25 | 26 | void push(ElementType element) {elements.push_back(element);} 27 | 28 | void pop() { 29 | if(elements.empty()) { 30 | throw std::exception(); 31 | } 32 | 33 | elements.pop_back(); 34 | } 35 | 36 | ElementType& top() { 37 | if(elements.empty()) { 38 | throw std::exception(); 39 | } 40 | 41 | return elements.back(); 42 | } 43 | 44 | int count() const {return elements.size();} 45 | bool empty() const {return elements.empty();} 46 | 47 | bool operator==(const Stack& rhs) const { 48 | return elements == rhs.elements; 49 | } 50 | 51 | private: 52 | Stack(const Stack& rhs); 53 | Stack& operator =(const Stack& rhs); 54 | 55 | private: 56 | std::vector elements; 57 | }; 58 | 59 | class EmptyStackSpec : public CppSpec::Specification, EmptyStackSpec> { 60 | public: 61 | EmptyStackSpec() { 62 | REGISTER_BEHAVIOUR(EmptyStackSpec, poppingShouldRaiseException); 63 | REGISTER_BEHAVIOUR(EmptyStackSpec, backShouldRaiseException); 64 | REGISTER_BEHAVIOUR(EmptyStackSpec, stackIsEmpty); 65 | REGISTER_BEHAVIOUR(EmptyStackSpec, stackEqualsWithEmpty); 66 | REGISTER_BEHAVIOUR(EmptyStackSpec, countShouldBeZero); 67 | } 68 | 69 | void poppingShouldRaiseException() { 70 | specify(invoking(&Stack::pop).should.raise.exception()); 71 | } 72 | 73 | void backShouldRaiseException() { 74 | specify(invoking(&Stack::top).should.raise.exception()); 75 | } 76 | 77 | void stackIsEmpty() { 78 | specify(should.be().empty()); 79 | } 80 | 81 | void stackEqualsWithEmpty() { 82 | Stack anotherStack; 83 | specify(context(), should.equal(anotherStack)); 84 | } 85 | 86 | void countShouldBeZero() { 87 | specify(context().count(), should.equal(0)); 88 | } 89 | } emptyStackSpec; 90 | 91 | class StackWithElementsSpec : public CppSpec::Specification, StackWithElementsSpec > { 92 | public: 93 | StackWithElementsSpec() { 94 | REGISTER_BEHAVIOUR(StackWithElementsSpec, stackIsNotEmpty); 95 | REGISTER_BEHAVIOUR(StackWithElementsSpec, stackShouldReturnPushedObject); 96 | REGISTER_BEHAVIOUR(StackWithElementsSpec, stackShouldBeEmptyAfterPop); 97 | REGISTER_BEHAVIOUR(StackWithElementsSpec, stackShouldEqualWithItself); 98 | REGISTER_BEHAVIOUR(StackWithElementsSpec, countShouldBeOne); 99 | } 100 | 101 | Stack* createContext() { 102 | Stack* stack = new Stack(); 103 | stack->push(1); 104 | return stack; 105 | } 106 | 107 | void stackIsNotEmpty() { 108 | specify(not should.be().empty()); 109 | } 110 | 111 | void stackShouldReturnPushedObject() { 112 | specify(context().top(), should.equal(1)); 113 | } 114 | 115 | void stackShouldBeEmptyAfterPop() { 116 | context().pop(); 117 | specify(should.be().empty()); 118 | } 119 | 120 | void stackShouldEqualWithItself() { 121 | specify(context(), should.equal(context())); 122 | } 123 | 124 | void countShouldBeOne() { 125 | specify(context().count(), should.equal(1)); 126 | } 127 | } stackWithElementsSpec; 128 | -------------------------------------------------------------------------------- /src/SpecRunner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "SpecRunner.h" 18 | #include "SpecificationRegistry.h" 19 | #include "Reporter.h" 20 | #include "SpecDoxReporter.h" 21 | #include "JUnitReporter.h" 22 | #include "BoostTimer.h" 23 | #include "ConsoleOutputStream.h" 24 | #include "ThreadPool.h" 25 | #include 26 | 27 | namespace CppSpec { 28 | 29 | class RemoveIfNotToBeRun { 30 | public: 31 | RemoveIfNotToBeRun(const std::vector& specificationsToRun) : specificationsToRun(specificationsToRun) {} 32 | 33 | bool operator()(Runnable* runnable) { 34 | return std::find(specificationsToRun.begin(), specificationsToRun.end(), runnable->getName()) == specificationsToRun.end(); 35 | } 36 | 37 | private: 38 | const std::vector& specificationsToRun; 39 | }; 40 | 41 | SpecRunner::SpecRunner(int argc, const char* argv[]) { 42 | boost::program_options::options_description options("Options"); 43 | options.add_options() 44 | ("output,o", boost::program_options::value(), "define output format. Allowed values: junit console") 45 | ("no-logs", "do not create log files when using JUnitReporter. No effect on other reporters") 46 | ("report-dir", boost::program_options::value(), "directory where JUnit reports are created") 47 | ("specification,s", boost::program_options::value >(&specificationsToRun),"specification to be run, if multiple specifications will be run, the option can be repeated") 48 | ("multithreaded,m", "run tests using multiple threads to shorten execution time") 49 | ("help,h", "show help"); 50 | arguments = new boost::program_options::variables_map(); 51 | boost::program_options::store(boost::program_options::parse_command_line(argc, argv, options), *arguments); 52 | boost::program_options::notify(*arguments); 53 | if (arguments->count("help")) { 54 | std::cout << options << std::endl; 55 | exit(0); 56 | } 57 | } 58 | 59 | SpecRunner::~SpecRunner() { 60 | delete arguments; 61 | } 62 | 63 | int SpecRunner::runSpecifications() { 64 | return runSpecs(specificationsToRun); 65 | } 66 | 67 | OutputStream* SpecRunner::createOutputStream() { 68 | return new ConsoleOutputStream(); 69 | } 70 | 71 | Reporter* SpecRunner::createReporter(OutputStream& outputStream) { 72 | if (arguments->count("output")) { 73 | const std::string& selectedReporter((*arguments)["output"].as()); 74 | if (selectedReporter == "junit") { 75 | if (arguments->count("no-logs")) { 76 | return new JUnitReporter(); 77 | } else { 78 | std::string reportPath("."); 79 | if (arguments->count("report-dir")) { 80 | reportPath = (*arguments)["report-dir"].as(); 81 | } 82 | return new JUnitReporter(reportPath); 83 | } 84 | } 85 | } 86 | return new SpecDoxReporter(outputStream); 87 | } 88 | 89 | bool SpecRunner::runSpecs(const std::vector& specificationsToRun) { 90 | OutputStream* output = createOutputStream(); 91 | Reporter* reporter = createReporter(*output); 92 | std::vector specs = SpecificationRegistry::instance().getSpecifications(); 93 | std::vector::iterator last = specs.end(); 94 | if (!specificationsToRun.empty()) { 95 | RemoveIfNotToBeRun removeIfNotToBeRun(specificationsToRun); 96 | last = std::remove_if(specs.begin(), specs.end(), removeIfNotToBeRun); 97 | } 98 | int threads(1); 99 | if (arguments->count("multithreaded")) { 100 | threads = std::max((unsigned int)1, boost::thread::hardware_concurrency()); 101 | } 102 | ThreadPool pool(threads); 103 | pool.start(specs.begin(), last, *reporter); 104 | 105 | bool failures = reporter->anyBehaviorFailed(); 106 | delete reporter; 107 | delete output; 108 | return failures; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /include/Specification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007, 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SPECIFICATION_H_ 18 | #define SPECIFICATION_H_ 19 | 20 | #include "SpecificationBase.h" 21 | #include "Reporter.h" 22 | #include "ShouldType.h" 23 | #include "ContextHolder.h" 24 | #include "SpecResult.h" 25 | #include "BoostTimer.h" 26 | #include 27 | 28 | /** 29 | * MSVC++ does not support not keyword. 30 | */ 31 | #ifdef _WIN32 32 | #define not ! 33 | #endif 34 | 35 | namespace CppSpec { 36 | 37 | /** 38 | * Specification base class. 39 | * @param Context the class under test. 40 | * @param Derived the concrete specification class as in curiously recurring template pattern. 41 | */ 42 | template 43 | class Specification : public SpecificationBase, public ContextHolder { 44 | public: 45 | explicit Specification() : should(*this), contextPtr(NULL) { 46 | } 47 | 48 | virtual ~Specification() { 49 | static_cast(this)->destroyContext(); 50 | } 51 | 52 | /** 53 | * Create the context object. Can be overridden in derived specification class. 54 | */ 55 | Context* createContext() { 56 | return new Context; 57 | } 58 | 59 | /** 60 | * Destroy the context object. Can be overridden in derived specification class. 61 | */ 62 | void destroyContext() { 63 | delete contextPtr; 64 | contextPtr = NULL; 65 | } 66 | 67 | public: // Expectations, these are used through specify-macro 68 | template 69 | InvokingType invoking(F f) { 70 | InvokingType invocation(boost::bind(f, &context())); 71 | return invocation; 72 | } 73 | 74 | template 75 | InvokingType invoking(F f, Arg1 arg1) { 76 | InvokingType invocation(boost::bind(f, &context(), arg1)); 77 | return invocation; 78 | } 79 | 80 | template 81 | InvokingType invoking(F f, Arg1 arg1, Arg2 arg2) { 82 | InvokingType invocation(boost::bind(f, &context(), arg1, arg2)); 83 | return invocation; 84 | } 85 | 86 | template 87 | InvokingType invoking(F f, Arg1 arg1, Arg2 arg2, Arg3 arg3) { 88 | InvokingType invocation(boost::bind(f, &context(), arg1, arg2, arg3)); 89 | return invocation; 90 | } 91 | 92 | template 93 | InvokingType invoking(F f, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { 94 | InvokingType invocation(boost::bind(f, &context(), arg1, arg2, arg3, arg4)); 95 | return invocation; 96 | } 97 | 98 | template 99 | InvokingType invoking(F f, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { 100 | InvokingType invocation(boost::bind(f, &context(), arg1, arg2, arg3, arg4, arg5)); 101 | return invocation; 102 | } 103 | 104 | public: // from Runnable 105 | SpecResult operator()() { 106 | SpecResult results(SpecificationBase::getName()); 107 | const int count(SpecificationBase::behaviors.size()); 108 | boost::shared_ptr timer = Timer::create(); 109 | timer->start(); 110 | for(int i = 0; i < count; ++i) { 111 | contextPtr = static_cast(this)->createContext(); 112 | Functor& behavior = *(SpecificationBase::behaviors[i]); 113 | SpecificationBase::executeBehavior(behavior, results); 114 | static_cast(this)->destroyContext(); 115 | } 116 | results.setDuration(timer->stop()); 117 | return results; 118 | } 119 | 120 | public: // Vocabulary 121 | Context& context() { 122 | return *contextPtr; 123 | } 124 | 125 | ShouldType should; 126 | 127 | protected: 128 | Context* contextPtr; 129 | 130 | private: 131 | Specification(const Specification&); 132 | Specification& operator=(const Specification&); 133 | }; 134 | 135 | template 136 | class Specification : public SpecificationBase, public ContextHolder { 137 | public: 138 | Specification() { 139 | } 140 | 141 | ~Specification() { 142 | } 143 | 144 | public: // from Runnable 145 | SpecResult operator()() { 146 | SpecResult results(SpecificationBase::getName()); 147 | const int count(SpecificationBase::behaviors.size()); 148 | for(int i = 0; i < count; ++i) { 149 | Functor& behavior = *(SpecificationBase::behaviors[i]); 150 | SpecificationBase::executeBehavior(behavior, results); 151 | } 152 | return results; 153 | } 154 | 155 | public: 156 | ShouldType should; 157 | 158 | private: 159 | Specification(const Specification&); 160 | Specification& operator=(const Specification&); 161 | }; 162 | 163 | } 164 | #endif /*SPECIFICATION_H_*/ 165 | -------------------------------------------------------------------------------- /test/SpecRunnerTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "SpecRunner.h" 19 | #include "OutputStreamStub.h" 20 | #include "SpecificationRegistry.h" 21 | #include "SpecDoxReporter.h" 22 | #include "JUnitReporter.h" 23 | #include "Runnable.h" 24 | #include "TimerStub.h" 25 | #include "SpecResult.h" 26 | #include "DummyReporter.h" 27 | #include "ThreadPool.h" 28 | #include 29 | 30 | using CppSpec::SpecRunner; 31 | using CppSpec::SpecificationRegistry; 32 | using CppSpec::SpecDoxReporter; 33 | using CppSpec::JUnitReporter; 34 | using CppSpec::Runnable; 35 | using CppSpec::Reporter; 36 | using CppSpec::SpecResult; 37 | using CppSpec::ThreadPool; 38 | 39 | namespace CppSpec { 40 | class SpecRunnerTestAccessor { 41 | public: 42 | template 43 | void checkThatGivenReporterIsCreated(SpecRunner& specRunner) { 44 | OutputStreamStub output; 45 | Reporter* reporter = specRunner.createReporter(output); 46 | ExpectedReporterType* expectedReporterType = dynamic_cast(reporter); 47 | EXPECT_TRUE(expectedReporterType != NULL); 48 | delete reporter; 49 | } 50 | }; 51 | } 52 | using CppSpec::SpecRunnerTestAccessor; 53 | 54 | class SpecRunnerStub : public CppSpec::SpecRunner { 55 | public: 56 | SpecRunnerStub(int argc, const char* argv[]) : CppSpec::SpecRunner(argc, argv) {} 57 | protected: 58 | CppSpec::OutputStream* createOutputStream() {return new OutputStreamStub();} 59 | }; 60 | 61 | SpecRunner* createSpecRunner() { 62 | const char* args[] = {"test"}; 63 | SpecificationRegistry::instance().clear(); 64 | return new SpecRunnerStub(1, args); 65 | } 66 | 67 | TEST(SpecRunnerTest, SpecDoxReporterIsReturnedByDefault) { 68 | SpecRunner* specRunner = createSpecRunner(); 69 | SpecRunnerTestAccessor().checkThatGivenReporterIsCreated(*specRunner); 70 | delete specRunner; 71 | } 72 | 73 | TEST(SpecRunnerTest, CreateReporterReturnsJUnitReporterIfGivenInArguments) { 74 | const char* args[] = {"test", "-o", "junit", "--report-dir", "foo"}; 75 | SpecRunner specRunner(5, args); 76 | SpecRunnerTestAccessor().checkThatGivenReporterIsCreated(specRunner); 77 | } 78 | 79 | TEST(SpecRunnerTest, CreateReporterReturnsJUnitReporterWithoutLogFilesIfGivenInArguments) { 80 | const char* args[] = {"test", "-o", "junit", "--no-logs"}; 81 | SpecRunner specRunner(4, args); 82 | SpecRunnerTestAccessor().checkThatGivenReporterIsCreated(specRunner); 83 | } 84 | 85 | TEST(SpecRunnerTest, ReturnZeroIfNoTestsExecuted) { 86 | SpecRunner* specRunner = createSpecRunner(); 87 | EXPECT_EQ(0, specRunner->runSpecifications()); 88 | delete specRunner; 89 | } 90 | 91 | struct DummyRunnable : public Runnable { 92 | DummyRunnable() : name("dummy"), pass(false) {} 93 | DummyRunnable(const std::string& id, bool pass) : name(id), pass(pass) {} 94 | SpecResult operator()() { 95 | SpecResult result("dummy"); 96 | if (pass) { 97 | result.addPass("pass", "00.01000"); 98 | } else { 99 | result.addFail("fail", "00.01000", "dummy failed"); 100 | } 101 | return result; 102 | } 103 | const std::string& getName() const {return name;} 104 | unsigned int getBehaviorCount() const {return 1;} 105 | const std::string name; 106 | bool pass; 107 | }; 108 | 109 | TEST(SpecRunnerTest, ReturnOneIfATestFails) { 110 | SpecRunner* specRunner = createSpecRunner(); 111 | DummyRunnable runnable; 112 | SpecificationRegistry::instance().addSpecification(&runnable); 113 | EXPECT_EQ(1, specRunner->runSpecifications()); 114 | delete specRunner; 115 | } 116 | 117 | void runTestsInPool(ThreadPool& pool) { 118 | DummyReporter reporter; 119 | std::vector specs; 120 | for (int i=0; i < 10; i++) { 121 | specs.push_back(new DummyRunnable("" + i, false)); 122 | } 123 | pool.start(specs.begin(), specs.end(), reporter); 124 | EXPECT_EQ(0, reporter.success); 125 | EXPECT_EQ(10, reporter.failed); 126 | for (std::vector::iterator it = specs.begin(); it != specs.end(); it++) { 127 | delete *it; 128 | } 129 | } 130 | 131 | TEST(SpecRunnerTest, RunTestUsingOneThread) { 132 | ThreadPool pool(1); 133 | runTestsInPool(pool); 134 | } 135 | 136 | TEST(SpecRunnerTest, RunTestsUsingThreeThreads) { 137 | ThreadPool pool(3); 138 | runTestsInPool(pool); 139 | } 140 | 141 | TEST(SpecRunnerTest, RunSelectedTest) { 142 | SpecificationRegistry::instance().clear(); 143 | const char* args[] = {"test", "-s", "runme"}; 144 | SpecRunner* specRunner = new SpecRunnerStub(3, args); 145 | 146 | DummyRunnable dontRun; 147 | DummyRunnable runThis("runme", true); 148 | SpecificationRegistry::instance().addSpecification(&dontRun); 149 | SpecificationRegistry::instance().addSpecification(&runThis); 150 | EXPECT_EQ(0, specRunner->runSpecifications()); 151 | delete specRunner; 152 | } 153 | -------------------------------------------------------------------------------- /include/Invocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef INVOCATION_H_ 18 | #define INVOCATION_H_ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "TypeHasStreamingOperator.h" 29 | #include "TypeNameResolver.h" 30 | #include "InvocationResult.h" 31 | 32 | namespace CppSpec { 33 | 34 | template 35 | class Invocation { 36 | private: 37 | class NonOccuringException { 38 | }; 39 | 40 | typedef typename boost::mpl::if_c::value, 41 | NonOccuringException, 42 | std::exception>::type StandardOrNonThrownExceptionType; 43 | 44 | public: 45 | explicit Invocation(boost::function invocation) : invocation(invocation) {} 46 | 47 | InvocationResult invoke() { 48 | return internalInvoke(boost::lambda::constant(true), 0); 49 | } 50 | 51 | InvocationResult invoke(Expected expected) { 52 | return internalInvoke(boost::lambda::_1 == expected, expected); 53 | } 54 | 55 | private: 56 | template 57 | InvocationResult internalInvoke(T expectedEquals, E expected) { 58 | InvocationResult result; 59 | try { 60 | invocation(); 61 | } 62 | catch(typename boost::call_traits::reference occured) { 63 | if(expectedEquals(occured)) { 64 | result.setSuccess(); 65 | return result; 66 | } 67 | result.setFailure(exceptionValuesNotMatchedMessage(expected, occured)); 68 | return result; 69 | } catch(typename boost::add_reference::type occured) { 70 | result.setFailure(standardExceptionThrown(occured)); 71 | return result; 72 | } catch(...) { 73 | result.setFailure(wrongExceptionThrownMessage()); 74 | return result; 75 | } 76 | result.setFailure(noExceptionThrownMessage()); 77 | return result; 78 | } 79 | 80 | std::string noExceptionThrownMessage() const { 81 | std::string description("Expected "); 82 | description += TypeNameResolver().getTypename(); 83 | description += " but no exception was thrown"; 84 | return description; 85 | } 86 | 87 | std::string wrongExceptionThrownMessage() const { 88 | std::string description("Expected "); 89 | description += TypeNameResolver().getTypename(); 90 | description += " but unknown type was thrown"; 91 | return description; 92 | } 93 | 94 | std::string standardExceptionThrown(std::exception& occured) { 95 | std::string description("Expected "); 96 | description += TypeNameResolver().getTypename(); 97 | description += " but "; 98 | description += TypeNameResolver().getTypename(occured); 99 | description += "["; 100 | description += occured.what(); 101 | description += "] was thrown"; 102 | return description; 103 | } 104 | 105 | std::string standardExceptionThrown(NonOccuringException&) { 106 | throw std::logic_error("standardExceptionThrown(NonOccuringException&) called"); 107 | } 108 | 109 | template 110 | std::string exceptionValuesNotMatchedMessage(T expected, U occured) const { 111 | std::string description("Expected "); 112 | const std::string exceptionTypeName(TypeNameResolver().getTypename()); 113 | description += exceptionTypeName; 114 | description += "["; 115 | description += toString(expected); 116 | description += "] but "; 117 | description += exceptionTypeName; 118 | description += "["; 119 | description += toString(occured); 120 | description += "] was thrown"; 121 | return description; 122 | } 123 | 124 | template 125 | std::string toString(T t) const { 126 | return toStringImpl(t, CheckIf::result>()); 127 | } 128 | 129 | template 130 | std::string toStringImpl(T t, CheckIf) const { 131 | try { 132 | return boost::lexical_cast(t); 133 | } catch(boost::bad_lexical_cast&) { 134 | return "** unstreamable class **"; 135 | } 136 | } 137 | 138 | template 139 | std::string toStringImpl(T t, CheckIf) const { 140 | return "** unstreamable class **"; 141 | } 142 | 143 | private: 144 | Invocation(const Invocation&); 145 | Invocation& operator=(const Invocation&); 146 | 147 | private: 148 | boost::function invocation; 149 | }; 150 | 151 | } 152 | 153 | bool operator==(const std::exception& lhs, const std::exception& rhs); 154 | std::ostream& operator<<(std::ostream& out, const std::exception& e); 155 | 156 | #endif /* INVOCATION_H_ */ 157 | -------------------------------------------------------------------------------- /include/SpecificationBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SPECIFICATIONBASE_H_ 18 | #define SPECIFICATIONBASE_H_ 19 | 20 | #include "Runnable.h" 21 | #include "TypeNameResolver.h" 22 | #include "Expectation.h" 23 | #include "SpecifyFailedException.h" 24 | #include "SpecificationRegistry.h" 25 | #include "Functor.h" 26 | #include "TypeHasStreamingOperator.h" 27 | #include "Matcher.h" 28 | #include "InvokingType.h" 29 | #include "SpecResult.h" 30 | #include "Timer.h" 31 | #include 32 | #include 33 | 34 | namespace CppSpec { 35 | 36 | template 37 | class SpecificationBase : public Runnable { 38 | public: 39 | SpecificationBase() : behaviors(), name(TypeNameResolver().getTypename()) { 40 | SpecificationRegistry::instance().addSpecification(this); 41 | } 42 | 43 | public: 44 | /** 45 | * Specify that condition must be fullfilled. 46 | */ 47 | void specifyImpl(const std::string& file, int line, bool condition) { 48 | if(!condition) { 49 | throw SpecifyFailedException(file, line, "Expected true, but was false"); 50 | } 51 | } 52 | 53 | /** 54 | * Specify that actual and expected must equal. 55 | */ 56 | template 57 | void specifyImpl(const std::string& file, int line, const T& actual, const Expectation& expected) { 58 | if(!expected.equals(actual)) { 59 | std::stringstream message; 60 | writeInequalMessageToStream(message, actual, expected, CheckIf::result && TypeHasStreamingOperator::result>()); 61 | throw SpecifyFailedException(file, line, message.str()); 62 | } 63 | } 64 | 65 | /** 66 | * Specify that actual and expected must almost equal (for floating point values). 67 | */ 68 | template 69 | void specifyImpl(const std::string& file, int line, const T& actual, const FloatExpectation& expected) { 70 | if(!expected.almostEquals(actual)) { 71 | std::stringstream message; 72 | writeInequalMessageToStream(message, actual, expected, CheckIf::result && TypeHasStreamingOperator::result>()); 73 | throw SpecifyFailedException(file, line, message.str()); 74 | } 75 | } 76 | 77 | void specifyImpl(const std::string& file, int line, const std::string& text, const Matcher& matcher) { 78 | if(!matcher(text)) { 79 | std::stringstream message; 80 | if(matcher.getMode() == Matcher::Search) { 81 | message << matcher.getExpression() << " was not found in " << text; 82 | } else { 83 | message << matcher.getExpression() << " did not match " << text; 84 | } 85 | throw SpecifyFailedException(file, line, message.str()); 86 | } 87 | } 88 | 89 | void specifyImpl(const std::string& file, int line, const InvocationResult& invocation) { 90 | if(!invocation.wasSuccess()) { 91 | throw SpecifyFailedException(file, line, invocation.getDescription()); 92 | } 93 | } 94 | 95 | public: // from Runnable 96 | const std::string& getName() const { 97 | return name; 98 | } 99 | 100 | unsigned int getBehaviorCount() const { 101 | return behaviors.size(); 102 | } 103 | 104 | protected: 105 | void executeBehavior(Functor& behavior, SpecResult& results) { 106 | boost::shared_ptr timer = Timer::create(); 107 | try { 108 | timer->start(); 109 | behavior(); 110 | results.addPass(behavior.getName(), timer->stop()); 111 | } 112 | catch (SpecifyFailedException& e) { 113 | results.addFail(behavior.getName(), timer->stop(), e.file, e.line, e.message); 114 | } 115 | catch (std::exception& e) { 116 | std::stringstream msg; 117 | msg << TypeNameResolver().getTypename(e) << "[" << e.what() << "] occured in " << behavior.getName(); 118 | results.addFail(behavior.getName(), timer->stop(), msg.str()); 119 | } 120 | catch (...) { 121 | std::stringstream msg; 122 | msg << "An exception occured in " << behavior.getName(); 123 | results.addFail(behavior.getName(), timer->stop(), msg.str()); 124 | } 125 | } 126 | 127 | private: 128 | template 129 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const Expectation& expected, CheckIf) { 130 | stream << std::boolalpha << "expected " << expected() << ", but was " << actual; 131 | } 132 | 133 | template 134 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const Expectation& expected, CheckIf) { 135 | stream << std::boolalpha << "expected " << expected() << ", but was " << actual; 136 | } 137 | 138 | template 139 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const Expectation& expected, CheckIf) { 140 | stream << "actual was not expected"; 141 | } 142 | 143 | template 144 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const FloatExpectation& expected, CheckIf) { 145 | stream << std::boolalpha << "expected [" << expected.lower() << ", " << expected.upper() << "] but was " << actual; 146 | } 147 | 148 | template 149 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const FloatExpectation& expected, CheckIf) { 150 | stream << std::boolalpha << "expected [" << expected.lower() << ", " << expected.upper() << "] but was " << actual; 151 | } 152 | 153 | template 154 | void writeInequalMessageToStream(std::ostream& stream, const T& actual, const FloatExpectation& expected, CheckIf) { 155 | stream << "actual was not expected"; 156 | } 157 | 158 | protected: 159 | typedef std::vector BehaviorList; 160 | BehaviorList behaviors; 161 | 162 | private: 163 | SpecificationBase(const SpecificationBase&); 164 | SpecificationBase& operator=(const SpecificationBase&); 165 | 166 | private: 167 | const std::string name; 168 | }; 169 | 170 | } 171 | 172 | #endif /* SPECIFICATIONBASE_H_ */ 173 | -------------------------------------------------------------------------------- /test/ExceptionThrowingSpecificationTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Timo Puronen 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | #include "CppSpec.h" 20 | 21 | using CppSpec::InvocationResult; 22 | using CppSpec::Specification; 23 | 24 | class TestClass { 25 | public: 26 | class MyException : public std::exception { 27 | public: 28 | const char* what() const throw() {return "MyException";} 29 | }; 30 | 31 | class RuntimeException : public std::runtime_error { 32 | public: 33 | explicit RuntimeException(const std::string& message) : std::runtime_error(message) {} 34 | }; 35 | 36 | class NonStreamable { 37 | public: 38 | bool operator==(const NonStreamable&) { 39 | return false; 40 | } 41 | }; 42 | 43 | void throwStdException() { 44 | throw std::exception(); 45 | } 46 | 47 | void throwInt() { 48 | throw 1; 49 | } 50 | 51 | void throwDerived() { 52 | throw MyException(); 53 | } 54 | 55 | void throwRuntimeException() { 56 | throw RuntimeException("Something terrible happened"); 57 | } 58 | 59 | void throwString() { 60 | throw std::string("Exception occured"); 61 | } 62 | 63 | void functionWithArgument(int arg) { 64 | if(arg > 10) { 65 | throw std::exception(); 66 | } 67 | } 68 | 69 | void constFunctionThrowingException() const { 70 | throw std::exception(); 71 | } 72 | 73 | void functionWithTwoArguments(int arg, int arg2) { 74 | throw std::exception(); 75 | } 76 | 77 | void functionWithThreeArguments(int arg, int arg2, int arg3) { 78 | throw std::exception(); 79 | } 80 | 81 | void throwNonStreamable() { 82 | throw NonStreamable(); 83 | } 84 | }; 85 | 86 | class TestSpec : public Specification { 87 | }; 88 | 89 | class ExceptionThrowingSpecificationTest : public ::testing::Test { 90 | protected: 91 | ExceptionThrowingSpecificationTest() { 92 | spec = new TestSpec(); 93 | } 94 | 95 | ~ExceptionThrowingSpecificationTest() { 96 | delete spec; 97 | spec = NULL; 98 | } 99 | 100 | TestSpec* spec; 101 | }; 102 | 103 | TEST_F(ExceptionThrowingSpecificationTest, StdException) { 104 | InvocationResult result = spec->invoking(&TestClass::throwStdException).should.raise.exception(); 105 | EXPECT_TRUE(result.wasSuccess()); 106 | } 107 | 108 | TEST_F(ExceptionThrowingSpecificationTest, ThrowInt) { 109 | InvocationResult result = spec->invoking(&TestClass::throwInt).should.raise.exception(); 110 | EXPECT_TRUE(result.wasSuccess()); 111 | } 112 | 113 | TEST_F(ExceptionThrowingSpecificationTest, ThrowIntValue) { 114 | InvocationResult result = spec->invoking(&TestClass::throwInt).should.raise.exception(1); 115 | EXPECT_TRUE(result.wasSuccess()); 116 | } 117 | 118 | TEST_F(ExceptionThrowingSpecificationTest, ThrowStringValue) { 119 | InvocationResult result = spec->invoking(&TestClass::throwString).should.raise.exception(std::string("Exception occured")); 120 | EXPECT_TRUE(result.wasSuccess()); 121 | } 122 | 123 | TEST_F(ExceptionThrowingSpecificationTest, DifferentStringValueThrown) { 124 | try { 125 | spec->specify(spec->invoking(&TestClass::throwString).should.raise.exception(std::string("Another exception occured"))); 126 | } catch (CppSpec::SpecifyFailedException& e) { 127 | EXPECT_EQ("Expected std::string[Another exception occured] but std::string[Exception occured] was thrown", e.message); 128 | return; 129 | } 130 | FAIL(); 131 | } 132 | 133 | TEST_F(ExceptionThrowingSpecificationTest, ThrowWrongIntValue) { 134 | try { 135 | spec->specify(spec->invoking(&TestClass::throwInt).should.raise.exception(2)); 136 | } catch (CppSpec::SpecifyFailedException& e) { 137 | EXPECT_EQ("Expected int[2] but int[1] was thrown", e.message); 138 | return; 139 | } 140 | FAIL(); 141 | } 142 | 143 | TEST_F(ExceptionThrowingSpecificationTest, DerivedException) { 144 | InvocationResult result = spec->invoking(&TestClass::throwDerived).should.raise.exception(); 145 | EXPECT_TRUE(result.wasSuccess()); 146 | } 147 | 148 | TEST_F(ExceptionThrowingSpecificationTest, ThrowWrongException) { 149 | try { 150 | spec->specify(spec->invoking(&TestClass::throwDerived).should.raise.exception()); 151 | } catch (CppSpec::SpecifyFailedException& e) { 152 | EXPECT_EQ("Expected std::string but TestClass::MyException[MyException] was thrown", e.message); 153 | return; 154 | } 155 | FAIL(); 156 | } 157 | 158 | TEST_F(ExceptionThrowingSpecificationTest, ConstFunctionThrowing) { 159 | InvocationResult result = spec->invoking(&TestClass::constFunctionThrowingException).should.raise.exception(); 160 | EXPECT_TRUE(result.wasSuccess()); 161 | } 162 | 163 | TEST_F(ExceptionThrowingSpecificationTest, FunctionWithArgument) { 164 | InvocationResult result = spec->invoking(&TestClass::functionWithArgument, 20).should.raise.exception(); 165 | EXPECT_TRUE(result.wasSuccess()); 166 | } 167 | 168 | TEST_F(ExceptionThrowingSpecificationTest, FunctionWithTwoArguments) { 169 | InvocationResult result = spec->invoking(&TestClass::functionWithTwoArguments, 1, 2).should.raise.exception(); 170 | EXPECT_TRUE(result.wasSuccess()); 171 | } 172 | 173 | TEST_F(ExceptionThrowingSpecificationTest, FunctionWithThreeArguments) { 174 | InvocationResult result = spec->invoking(&TestClass::functionWithThreeArguments, 1, 2, 3).should.raise.exception(); 175 | EXPECT_TRUE(result.wasSuccess()); 176 | } 177 | 178 | TEST_F(ExceptionThrowingSpecificationTest, FunctionWithArgumentNoThrow) { 179 | try { 180 | spec->specify(spec->invoking(&TestClass::functionWithArgument, 0).should.raise.exception()); 181 | } catch (CppSpec::SpecifyFailedException& e) { 182 | EXPECT_EQ("Expected std::string but no exception was thrown", e.message); 183 | return; 184 | } 185 | FAIL(); 186 | } 187 | 188 | TEST_F(ExceptionThrowingSpecificationTest, ThrowNonStreamable) { 189 | try { 190 | spec->specify(spec->invoking(&TestClass::throwNonStreamable).should.raise.exception()); 191 | } catch (CppSpec::SpecifyFailedException& e) { 192 | EXPECT_EQ("Expected int but unknown type was thrown", e.message); 193 | return; 194 | } 195 | FAIL(); 196 | } 197 | 198 | TEST_F(ExceptionThrowingSpecificationTest, AssertStdExceptionTypeAndMessage) { 199 | InvocationResult result = spec->invoking(&TestClass::throwDerived).should.raise.exception(TestClass::MyException()); 200 | EXPECT_TRUE(result.wasSuccess()); 201 | } 202 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 2.6 3 | 4 | # Default target executed when no arguments are given to make. 5 | default_target: all 6 | .PHONY : default_target 7 | 8 | #============================================================================= 9 | # Special targets provided by cmake. 10 | 11 | # Disable implicit rules so canoncical targets will work. 12 | .SUFFIXES: 13 | 14 | # Remove some rules from gmake that .SUFFIXES does not remove. 15 | SUFFIXES = 16 | 17 | .SUFFIXES: .hpux_make_needs_suffix_list 18 | 19 | # Produce verbose output by default. 20 | VERBOSE = 1 21 | 22 | # Suppress display of executed commands. 23 | $(VERBOSE).SILENT: 24 | 25 | # A target that is always out of date. 26 | cmake_force: 27 | .PHONY : cmake_force 28 | 29 | #============================================================================= 30 | # Set environment variables for the build. 31 | 32 | # The shell in which to execute make rules. 33 | SHELL = /bin/sh 34 | 35 | # The CMake executable. 36 | CMAKE_COMMAND = /usr/local/bin/cmake 37 | 38 | # The command to remove a file. 39 | RM = /usr/local/bin/cmake -E remove -f 40 | 41 | # The program to use to edit the cache. 42 | CMAKE_EDIT_COMMAND = /usr/local/bin/ccmake 43 | 44 | # The top-level source directory on which CMake was run. 45 | CMAKE_SOURCE_DIR = /home/tpuronen/src/cppspec/trunk 46 | 47 | # The top-level build directory on which CMake was run. 48 | CMAKE_BINARY_DIR = /home/tpuronen/src/cppspec/trunk 49 | 50 | #============================================================================= 51 | # Targets provided globally by CMake. 52 | 53 | # Special rule for the target edit_cache 54 | edit_cache: 55 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." 56 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 57 | .PHONY : edit_cache 58 | 59 | # Special rule for the target edit_cache 60 | edit_cache/fast: edit_cache 61 | .PHONY : edit_cache/fast 62 | 63 | # Special rule for the target install 64 | install: preinstall 65 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." 66 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cmake -P cmake_install.cmake 67 | .PHONY : install 68 | 69 | # Special rule for the target install 70 | install/fast: preinstall/fast 71 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." 72 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cmake -P cmake_install.cmake 73 | .PHONY : install/fast 74 | 75 | # Special rule for the target install/local 76 | install/local: preinstall 77 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." 78 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake 79 | .PHONY : install/local 80 | 81 | # Special rule for the target install/local 82 | install/local/fast: install/local 83 | .PHONY : install/local/fast 84 | 85 | # Special rule for the target install/strip 86 | install/strip: preinstall 87 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." 88 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake 89 | .PHONY : install/strip 90 | 91 | # Special rule for the target install/strip 92 | install/strip/fast: install/strip 93 | .PHONY : install/strip/fast 94 | 95 | # Special rule for the target list_install_components 96 | list_install_components: 97 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" 98 | .PHONY : list_install_components 99 | 100 | # Special rule for the target list_install_components 101 | list_install_components/fast: list_install_components 102 | .PHONY : list_install_components/fast 103 | 104 | # Special rule for the target package 105 | package: preinstall 106 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool..." 107 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cpack --config /home/tpuronen/src/cppspec/trunk/CPackConfig.cmake 108 | .PHONY : package 109 | 110 | # Special rule for the target package 111 | package/fast: package 112 | .PHONY : package/fast 113 | 114 | # Special rule for the target package_source 115 | package_source: 116 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool for source..." 117 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cpack --config /home/tpuronen/src/cppspec/trunk/CPackSourceConfig.cmake 118 | .PHONY : package_source 119 | 120 | # Special rule for the target package_source 121 | package_source/fast: package_source 122 | .PHONY : package_source/fast 123 | 124 | # Special rule for the target rebuild_cache 125 | rebuild_cache: 126 | @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." 127 | cd /home/tpuronen/src/cppspec/trunk/examples && /usr/local/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) 128 | .PHONY : rebuild_cache 129 | 130 | # Special rule for the target rebuild_cache 131 | rebuild_cache/fast: rebuild_cache 132 | .PHONY : rebuild_cache/fast 133 | 134 | # The main all target 135 | all: cmake_check_build_system 136 | cd /home/tpuronen/src/cppspec/trunk && $(CMAKE_COMMAND) -E cmake_progress_start /home/tpuronen/src/cppspec/trunk/CMakeFiles /home/tpuronen/src/cppspec/trunk/examples/CMakeFiles/progress.make 137 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f CMakeFiles/Makefile2 examples/all 138 | $(CMAKE_COMMAND) -E cmake_progress_start /home/tpuronen/src/cppspec/trunk/CMakeFiles 0 139 | .PHONY : all 140 | 141 | # The main clean target 142 | clean: 143 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f CMakeFiles/Makefile2 examples/clean 144 | .PHONY : clean 145 | 146 | # The main clean target 147 | clean/fast: clean 148 | .PHONY : clean/fast 149 | 150 | # Prepare targets for installation. 151 | preinstall: all 152 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f CMakeFiles/Makefile2 examples/preinstall 153 | .PHONY : preinstall 154 | 155 | # Prepare targets for installation. 156 | preinstall/fast: 157 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f CMakeFiles/Makefile2 examples/preinstall 158 | .PHONY : preinstall/fast 159 | 160 | # clear depends 161 | depend: 162 | cd /home/tpuronen/src/cppspec/trunk && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 163 | .PHONY : depend 164 | 165 | # Convenience name for target. 166 | examples/CMakeFiles/SpecTest.dir/rule: 167 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f CMakeFiles/Makefile2 examples/CMakeFiles/SpecTest.dir/rule 168 | .PHONY : examples/CMakeFiles/SpecTest.dir/rule 169 | 170 | # Convenience name for target. 171 | SpecTest: examples/CMakeFiles/SpecTest.dir/rule 172 | .PHONY : SpecTest 173 | 174 | # fast build rule for target. 175 | SpecTest/fast: 176 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f examples/CMakeFiles/SpecTest.dir/build.make examples/CMakeFiles/SpecTest.dir/build 177 | .PHONY : SpecTest/fast 178 | 179 | SpecTest.o: SpecTest.cpp.o 180 | .PHONY : SpecTest.o 181 | 182 | # target to build an object file 183 | SpecTest.cpp.o: 184 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f examples/CMakeFiles/SpecTest.dir/build.make examples/CMakeFiles/SpecTest.dir/SpecTest.cpp.o 185 | .PHONY : SpecTest.cpp.o 186 | 187 | SpecTest.i: SpecTest.cpp.i 188 | .PHONY : SpecTest.i 189 | 190 | # target to preprocess a source file 191 | SpecTest.cpp.i: 192 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f examples/CMakeFiles/SpecTest.dir/build.make examples/CMakeFiles/SpecTest.dir/SpecTest.cpp.i 193 | .PHONY : SpecTest.cpp.i 194 | 195 | SpecTest.s: SpecTest.cpp.s 196 | .PHONY : SpecTest.s 197 | 198 | # target to generate assembly for a file 199 | SpecTest.cpp.s: 200 | cd /home/tpuronen/src/cppspec/trunk && $(MAKE) -f examples/CMakeFiles/SpecTest.dir/build.make examples/CMakeFiles/SpecTest.dir/SpecTest.cpp.s 201 | .PHONY : SpecTest.cpp.s 202 | 203 | # Help Target 204 | help: 205 | @echo "The following are some of the valid targets for this Makefile:" 206 | @echo "... all (the default if no target is provided)" 207 | @echo "... clean" 208 | @echo "... depend" 209 | @echo "... SpecTest" 210 | @echo "... edit_cache" 211 | @echo "... install" 212 | @echo "... install/local" 213 | @echo "... install/strip" 214 | @echo "... list_install_components" 215 | @echo "... package" 216 | @echo "... package_source" 217 | @echo "... rebuild_cache" 218 | @echo "... SpecTest.o" 219 | @echo "... SpecTest.i" 220 | @echo "... SpecTest.s" 221 | .PHONY : help 222 | 223 | 224 | 225 | #============================================================================= 226 | # Special targets to cleanup operation of make. 227 | 228 | # Special rule to run CMake to check the build system integrity. 229 | # No rule that depends on this can have commands that come from listfiles 230 | # because they might be regenerated. 231 | cmake_check_build_system: 232 | cd /home/tpuronen/src/cppspec/trunk && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 233 | .PHONY : cmake_check_build_system 234 | 235 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------