├── .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 |
--------------------------------------------------------------------------------