Uninteresting mock function call - returning default value.
Uninteresting mock function call - returning default value.
Function call: Bar2(0, 1)
Function call: Bar2(0, 1)
Returns: false
Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCall
[ OK ] GMockOutputTest.UninterestingCall
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction
GMOCK WARNING:
GMOCK WARNING:
Uninteresting mock function call - returning directly.
Uninteresting mock function call - returning directly.
Function call: Bar3(0, 1)
Function call: Bar3(0, 1)
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
[ OK ] GMockOutputTest.UninterestingCallToVoidFunction
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
GMOCK WARNING:
GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
Uninteresting mock function call - taking default action specified at:
FILE:#:
FILE:#:
Function call: Bar2(1, 1)
Function call: Bar2(1, 1)
Returns: false
Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details.
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
This guide will explain how to use the Google Testing Framework in your Xcode projects on Mac OS X. This tutorial begins by quickly explaining what to do for experienced users. After the quick start, the guide goes provides additional explanation about each step.
# Quick Start #
Here is the quick guide for using Google Test in your Xcode project.
1. Download the source from the [website](https://github.com/google/googletest) using this command: `svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only`.
1. Open up the `gtest.xcodeproj` in the `googletest-read-only/xcode/` directory and build the gtest.framework.
1. Create a new "Shell Tool" target in your Xcode project called something like "UnitTests".
1. Add the gtest.framework to your project and add it to the "Link Binary with Libraries" build phase of "UnitTests".
1. Add your unit test source code to the "Compile Sources" build phase of "UnitTests".
1. Edit the "UnitTests" executable and add an environment variable named "DYLD\_FRAMEWORK\_PATH" with a value equal to the path to the framework containing the gtest.framework relative to the compiled executable.
1. Build and Go.
The following sections further explain each of the steps listed above in depth, describing in more detail how to complete it including some variations.
# Get the Source #
Currently, the gtest.framework discussed here isn't available in a tagged release of Google Test, it is only available in the trunk. As explained at the Google Test [site](https://github.com/google/googletest), you can get the code from anonymous SVN with this command:
Alternatively, if you are working with Subversion in your own code base, you can add Google Test as an external dependency to your own Subversion repository. By following this approach, everyone that checks out your svn repository will also receive a copy of Google Test (a specific version, if you wish) without having to check it out explicitly. This makes the set up of your project simpler and reduces the copied code in the repository.
To use `svn:externals`, decide where you would like to have the external source reside. You might choose to put the external source inside the trunk, because you want it to be part of the branch when you make a release. However, keeping it outside the trunk in a version-tagged directory called something like `third-party/googletest/1.0.1`, is another option. Once the location is established, use `svn propedit svn:externals _directory_` to set the svn:externals property on a directory in your repository. This directory won't contain the code, but be its versioned parent directory.
The command `svn propedit` will bring up your Subversion editor, making editing the long, (potentially multi-line) property simpler. This same method can be used to check out a tagged branch, by using the appropriate URL (e.g. `https://github.com/google/googletest/releases/tag/release-1.0.1`). Additionally, the svn:externals property allows the specification of a particular revision of the trunk with the `-r_##_` option (e.g. `externals/src/googletest -r60 http://googletest.googlecode.com/svn/trunk`).
Here is an example of using the svn:externals properties on a trunk (read via `svn propget`) of a project. This value checks out a copy of Google Test into the `trunk/externals/src/googletest/` directory.
The next step is to build and add the gtest.framework to your own project. This guide describes two common ways below.
***Option 1** --- The simplest way to add Google Test to your own project, is to open gtest.xcodeproj (found in the xcode/ directory of the Google Test trunk) and build the framework manually. Then, add the built framework into your project using the "Add->Existing Framework..." from the context menu or "Project->Add..." from the main menu. The gtest.framework is relocatable and contains the headers and object code that you'll need to make tests. This method requires rebuilding every time you upgrade Google Test in your project.
***Option 2** --- If you are going to be living off the trunk of Google Test, incorporating its latest features into your unit tests (or are a Google Test developer yourself). You'll want to rebuild the framework every time the source updates. to do this, you'll need to add the gtest.xcodeproj file, not the framework itself, to your own Xcode project. Then, from the build products that are revealed by the project's disclosure triangle, you can find the gtest.framework, which can be added to your targets (discussed below).
# Make a Test Target #
To start writing tests, make a new "Shell Tool" target. This target template is available under BSD, Cocoa, or Carbon. Add your unit test source code to the "Compile Sources" build phase of the target.
Next, you'll want to add gtest.framework in two different ways, depending upon which option you chose above.
***Option 1** --- During compilation, Xcode will need to know that you are linking against the gtest.framework. Add the gtest.framework to the "Link Binary with Libraries" build phase of your test target. This will include the Google Test headers in your header search path, and will tell the linker where to find the library.
***Option 2** --- If your working out of the trunk, you'll also want to add gtest.framework to your "Link Binary with Libraries" build phase of your test target. In addition, you'll want to add the gtest.framework as a dependency to your unit test target. This way, Xcode will make sure that gtest.framework is up to date, every time your build your target. Finally, if you don't share build directories with Google Test, you'll have to copy the gtest.framework into your own build products directory using a "Run Script" build phase.
# Set Up the Executable Run Environment #
Since the unit test executable is a shell tool, it doesn't have a bundle with a `Contents/Frameworks` directory, in which to place gtest.framework. Instead, the dynamic linker must be told at runtime to search for the framework in another location. This can be accomplished by setting the "DYLD\_FRAMEWORK\_PATH" environment variable in the "Edit Active Executable ..." Arguments tab, under "Variables to be set in the environment:". The path for this value is the path (relative or absolute) of the directory containing the gtest.framework.
If you haven't set up the DYLD\_FRAMEWORK\_PATH, correctly, you might get a message like this:
```
[Session started at 2008-08-15 06:23:57 -0600.]
dyld: Library not loaded: @loader_path/../Frameworks/gtest.framework/Versions/A/gtest
To correct this problem, go to to the directory containing the executable named in "Referenced from:" value in the error message above. Then, with the terminal in this location, find the relative path to the directory containing the gtest.framework. That is the value you'll need to set as the DYLD\_FRAMEWORK\_PATH.
# Build and Go #
Now, when you click "Build and Go", the test will be executed. Dumping out something like this:
```
[Session started at 2008-08-06 06:36:13 -0600.]
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from WidgetInitializerTest
[ RUN ] WidgetInitializerTest.TestConstructor
[ OK ] WidgetInitializerTest.TestConstructor
[ RUN ] WidgetInitializerTest.TestConversion
[ OK ] WidgetInitializerTest.TestConversion
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran.
[ PASSED ] 2 tests.
The Debugger has exited with status 0.
```
# Summary #
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment.
| `ASSERT_NEAR(val1, val2, abs_error);` | `EXPECT_NEAR(val1, val2, abs_error);` | the difference between `val1` and `val2` doesn't exceed the given absolute error |
| `ASSERT_NEAR(val1, val2, abs_error);` | `EXPECT_NEAR(val1, val2, abs_error);` | the difference between `val1` and `val2` doesn't exceed the given absolute error |
`ASSERT_DEATH(statement, regex);` | `EXPECT_DEATH(statement, regex);` | `statement` crashes with the given error
`ASSERT_DEATH(statement, matcher);` | `EXPECT_DEATH(statement, matcher);` | `statement` crashes with the given error
`ASSERT_DEATH_IF_SUPPORTED(statement, regex);` | `EXPECT_DEATH_IF_SUPPORTED(statement, regex);` | if death tests are supported, verifies that `statement` crashes with the given error; otherwise verifies nothing
`ASSERT_DEATH_IF_SUPPORTED(statement, matcher);` | `EXPECT_DEATH_IF_SUPPORTED(statement, matcher);` | if death tests are supported, verifies that `statement` crashes with the given error; otherwise verifies nothing
`ASSERT_EXIT(statement, predicate, regex);` | `EXPECT_EXIT(statement, predicate, regex);` | `statement` exits with the given error, and its exit code matches `predicate`
`ASSERT_EXIT(statement, predicate, matcher);` | `EXPECT_EXIT(statement, predicate, matcher);` | `statement` exits with the given error, and its exit code matches `predicate`
where `statement` is a statement that is expected to cause the process to die,
where `statement` is a statement that is expected to cause the process to die,
`predicate` is a function or function object that evaluates an integer exit
`predicate` is a function or function object that evaluates an integer exit
status, and `regex` is a (Perl) regular expression that the stderr output of
status, and `matcher` is either a GMock matcher matching a `const std::string&`
`statement` is expected to match. Note that `statement` can be *any valid
or a (Perl) regular expression - either of which is matched against the stderr
statement* (including *compound statement*) and doesn't have to be an
output of `statement`. For legacy reasons, a bare string (i.e. with no matcher)
expression.
is interpreted as `ContainsRegex(str)`, **not**`Eq(str)`. Note that `statement`
can be *any valid statement* (including *compound statement*) and doesn't have
to be an expression.
As usual, the `ASSERT` variants abort the current test function, while the
As usual, the `ASSERT` variants abort the current test function, while the
`EXPECT` variants do not.
`EXPECT` variants do not.
...
@@ -751,9 +727,9 @@ necessary.
...
@@ -751,9 +727,9 @@ necessary.
### Death Test Naming
### Death Test Naming
IMPORTANT: We strongly recommend you to follow the convention of naming your
IMPORTANT: We strongly recommend you to follow the convention of naming your
**test case** (not test) `*DeathTest` when it contains a death test, as
**test suite** (not test) `*DeathTest` when it contains a death test, as
demonstrated in the above example. The[Death Tests And
## My compiler complains "void value not ignored as it ought to be." What does this mean?
## My compiler complains "void value not ignored as it ought to be." What does this mean?
...
@@ -289,8 +280,8 @@ Please make sure you have read [this](advanced.md#how-it-works).
...
@@ -289,8 +280,8 @@ Please make sure you have read [this](advanced.md#how-it-works).
In particular, death tests don't like having multiple threads in the parent
In particular, death tests don't like having multiple threads in the parent
process. So the first thing you can try is to eliminate creating threads outside
process. So the first thing you can try is to eliminate creating threads outside
of `EXPECT_DEATH()`. For example, you may want to use [mocks](../../googlemock)
of `EXPECT_DEATH()`. For example, you may want to use mocks or fake objects
or fake objects instead of real ones in your tests.
instead of real ones in your tests.
Sometimes this is impossible as some library you must use may be creating
Sometimes this is impossible as some library you must use may be creating
threads before `main()` is even reached. In this case, you can try to minimize
threads before `main()` is even reached. In this case, you can try to minimize
...
@@ -328,12 +319,21 @@ The former is usually preferred, as it has the following benefits:
...
@@ -328,12 +319,21 @@ The former is usually preferred, as it has the following benefits:
forgetting to call the base class' `SetUp()/TearDown()` or call them at the
forgetting to call the base class' `SetUp()/TearDown()` or call them at the
wrong time.
wrong time.
You may still want to use `SetUp()/TearDown()` in the following rare cases:
You may still want to use `SetUp()/TearDown()` in the following cases:
* C++ does not allow virtual function calls in constructors and destructors.
You can call a method declared as virtual, but it will not use dynamic
dispatch, it will use the definition from the class the constructor of which
is currently executing. This is because calling a virtual method before the
derived class constructor has a chance to run is very dangerous - the
virtual method might operate on uninitialized data. Therefore, if you need
to call a method that will be overridden in a derived class, you have to use
`SetUp()/TearDown()`.
* In the body of a constructor (or destructor), it's not possible to use the
* In the body of a constructor (or destructor), it's not possible to use the
`ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal
`ASSERT_xx` macros. Therefore, if the set-up operation could cause a fatal
test failure that should prevent the test from running, it's necessary to
test failure that should prevent the test from running, it's necessary to
use a `CHECK` macro or to use `SetUp()` instead of a constructor.
use `abort`<!-- GOOGLETEST_CM0015 DO NOT DELETE --> and abort the whole test executable,
or to use `SetUp()` instead of a constructor.
* If the tear-down operation could throw an exception, you must use
* If the tear-down operation could throw an exception, you must use
`TearDown()` as opposed to the destructor, as throwing in a destructor leads
`TearDown()` as opposed to the destructor, as throwing in a destructor leads
to undefined behavior and usually will kill your program right away. Note
to undefined behavior and usually will kill your program right away. Note
...
@@ -346,11 +346,6 @@ You may still want to use `SetUp()/TearDown()` in the following rare cases:
...
@@ -346,11 +346,6 @@ You may still want to use `SetUp()/TearDown()` in the following rare cases:
failures from a subroutine to its caller. Therefore, you shouldn't use
failures from a subroutine to its caller. Therefore, you shouldn't use
googletest assertions in a destructor if your code could run on such a
googletest assertions in a destructor if your code could run on such a
platform.
platform.
* In a constructor or destructor, you cannot make a virtual function call on
this object. (You can call a method declared as virtual, but it will be
statically bound.) Therefore, if you need to call a method that will be
overridden in a derived class, you have to use `SetUp()/TearDown()`.
## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it?
...
@@ -421,7 +416,6 @@ parentheses:
...
@@ -421,7 +416,6 @@ parentheses:
ASSERT_PRED2((GreaterThan<int,int>),5,0);
ASSERT_PRED2((GreaterThan<int,int>),5,0);
```
```
## My compiler complains about "ignoring return value" when I call RUN_ALL_TESTS(). Why?
## My compiler complains about "ignoring return value" when I call RUN_ALL_TESTS(). Why?
Some people had been ignoring the return value of `RUN_ALL_TESTS()`. That is,
Some people had been ignoring the return value of `RUN_ALL_TESTS()`. That is,
...
@@ -472,17 +466,11 @@ switch to `EXPECT_*()` if that works. This
...
@@ -472,17 +466,11 @@ switch to `EXPECT_*()` if that works. This
C++ is case-sensitive. Did you spell it as `Setup()`?
C++ is case-sensitive. Did you spell it as `Setup()`?
Similarly, sometimes people spell `SetUpTestCase()` as `SetupTestCase()` and
Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and
wonder why it's never called.
wonder why it's never called.
## How do I jump to the line of a failure in Emacs directly?
googletest's failure message format is understood by Emacs and many other IDEs,
like acme and XCode. If a googletest message is in a compilation buffer in
Emacs, then it's clickable.
## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
## I have several test cases which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious.
You don't have to. Instead of
You don't have to. Instead of
...
@@ -527,7 +515,6 @@ example:
...
@@ -527,7 +515,6 @@ example:
$ ./my_test > gtest_output.txt
$ ./my_test > gtest_output.txt
```
```
## Why should I prefer test fixtures over global variables?
## Why should I prefer test fixtures over global variables?
There are several good reasons:
There are several good reasons:
...
@@ -537,13 +524,12 @@ There are several good reasons:
...
@@ -537,13 +524,12 @@ There are several good reasons:
contaminating others, making debugging difficult. By using fixtures, each
contaminating others, making debugging difficult. By using fixtures, each
test has a fresh set of variables that's different (but with the same
test has a fresh set of variables that's different (but with the same
names). Thus, tests are kept independent of each other.
names). Thus, tests are kept independent of each other.
1. Global variables pollute the global namespace.
2. Global variables pollute the global namespace.
1. Test fixtures can be reused via subclassing, which cannot be done easily
3. Test fixtures can be reused via subclassing, which cannot be done easily
with global variables. This is useful if many test cases have something in
with global variables. This is useful if many test suites have something in
common.
common.
## What can the statement argument in ASSERT_DEATH() be?
## What can the statement argument in ASSERT_DEATH() be?
`ASSERT_DEATH(*statement*, *regex*)` (or any death assertion macro) can be used
`ASSERT_DEATH(*statement*, *regex*)` (or any death assertion macro) can be used
wherever `*statement*` is valid. So basically `*statement*` can be any C++
wherever `*statement*` is valid. So basically `*statement*` can be any C++
...
@@ -621,14 +607,14 @@ The new NPTL thread library doesn't suffer from this problem, as it doesn't
...
@@ -621,14 +607,14 @@ The new NPTL thread library doesn't suffer from this problem, as it doesn't
create a manager thread. However, if you don't control which machine your test
create a manager thread. However, if you don't control which machine your test
runs on, you shouldn't depend on this.
runs on, you shouldn't depend on this.
## Why does googletest require the entire test case, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
## Why does googletest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH?
googletest does not interleave tests from different test cases. That is, it runs
googletest does not interleave tests from different test suites. That is, it
all tests in one test case first, and then runs all tests in the next test case,
runs all tests in one test suite first, and then runs all tests in the next test
and so on. googletest does this because it needs to set up a test case before
suite, and so on. googletest does this because it needs to set up a test suite
the first test in it is run, and tear it down afterwords. Splitting up the test
before the first test in it is run, and tear it down afterwords. Splitting up
case would require multiple set-up and tear-down processes, which is inefficient
the test case would require multiple set-up and tear-down processes, which is
and makes the semantics unclean.
inefficient and makes the semantics unclean.
If we were to determine the order of tests based on test name instead of test
If we were to determine the order of tests based on test name instead of test
case name, then we would have a problem with the following situation:
case name, then we would have a problem with the following situation:
Exercise a particular program path with specific input values and verify the results | [TEST()](#simple-tests) | [Test Case](http://glossary.istqb.org/search/test%20case)
[istqb test case]:http://glossary.istqb.org/en/search/test%20case
A set of several tests related to one component | [TestCase](#basic-concepts) | [TestSuite](http://glossary.istqb.org/search/test%20suite)
[istqb test suite]:http://glossary.istqb.org/en/search/test%20suite
## Basic Concepts
## Basic Concepts
...
@@ -87,15 +88,15 @@ current function; otherwise the program continues normally.
...
@@ -87,15 +88,15 @@ current function; otherwise the program continues normally.
*Tests* use assertions to verify the tested code's behavior. If a test crashes
*Tests* use assertions to verify the tested code's behavior. If a test crashes
or has a failed assertion, then it *fails*; otherwise it *succeeds*.
or has a failed assertion, then it *fails*; otherwise it *succeeds*.
A *test case* contains one or many tests. You should group your tests into test
A *test suite* contains one or many tests. You should group your tests into test
cases that reflect the structure of the tested code. When multiple tests in a
suites that reflect the structure of the tested code. When multiple tests in a
test case need to share common objects and subroutines, you can put them into a
test suite need to share common objects and subroutines, you can put them into a
*test fixture* class.
*test fixture* class.
A *test program* can contain multiple test cases.
A *test program* can contain multiple test suites.
We'll now explain how to write a test program, starting at the individual
We'll now explain how to write a test program, starting at the individual
assertion level and building up to tests and test cases.
assertion level and building up to tests and test suites.
## Assertions
## Assertions
...
@@ -169,7 +170,7 @@ you'll get a compiler error. We used to require the arguments to support the
...
@@ -169,7 +170,7 @@ you'll get a compiler error. We used to require the arguments to support the
`<<` is supported, it will be called to print the arguments when the assertion
`<<` is supported, it will be called to print the arguments when the assertion
fails; otherwise googletest will attempt to print them in the best way it can.
fails; otherwise googletest will attempt to print them in the best way it can.
For more details and how to customize the printing of the arguments, see
For more details and how to customize the printing of the arguments, see
These assertions can work with a user-defined type, but only if you define the
These assertions can work with a user-defined type, but only if you define the
corresponding comparison operator (e.g. `==`, `<`, etc). Since this is
corresponding comparison operator (e.g. `==`, `<`, etc). Since this is
...
@@ -192,14 +193,13 @@ evaluation order.
...
@@ -192,14 +193,13 @@ evaluation order.
tests if they are in the same memory location, not if they have the same value.
tests if they are in the same memory location, not if they have the same value.
Therefore, if you want to compare C strings (e.g. `const char*`) by value, use
Therefore, if you want to compare C strings (e.g. `const char*`) by value, use
`ASSERT_STREQ()`, which will be described later on. In particular, to assert
`ASSERT_STREQ()`, which will be described later on. In particular, to assert
that a C string is `NULL`, use `ASSERT_STREQ(c_string, NULL)`. Consider use
that a C string is `NULL`, use `ASSERT_STREQ(c_string, NULL)`. Consider using
`ASSERT_EQ(c_string, nullptr)` if c++11 is supported. To compare two `string`
`ASSERT_EQ(c_string, nullptr)` if c++11 is supported. To compare two `string`
objects, you should use `ASSERT_EQ`.
objects, you should use `ASSERT_EQ`.
When doing pointer comparisons use `*_EQ(ptr, nullptr)` and `*_NE(ptr, nullptr)`
When doing pointer comparisons use `*_EQ(ptr, nullptr)` and `*_NE(ptr, nullptr)`
instead of `*_EQ(ptr, NULL)` and `*_NE(ptr, NULL)`. This is because `nullptr` is
instead of `*_EQ(ptr, NULL)` and `*_NE(ptr, NULL)`. This is because `nullptr` is
typed while `NULL` is not. See [FAQ](faq.md#why-does-googletest-support-expect_eqnull-ptr-and-assert_eqnull-ptr-but-not-expect_nenull-ptr-and-assert_nenull-ptr)
typed while `NULL` is not. See [FAQ](faq.md) for more details.
for more details.
If you're working with floating point numbers, you may want to use the floating
If you're working with floating point numbers, you may want to use the floating
point variations of some of these macros in order to avoid problems caused by
point variations of some of these macros in order to avoid problems caused by
...
@@ -219,12 +219,16 @@ as `ASSERT_EQ(expected, actual)`, so lots of existing code uses this order. Now
...
@@ -219,12 +219,16 @@ as `ASSERT_EQ(expected, actual)`, so lots of existing code uses this order. Now
The assertions in this group compare two **C strings**. If you want to compare
The assertions in this group compare two **C strings**. If you want to compare
two `string` objects, use `EXPECT_EQ`, `EXPECT_NE`, and etc instead.
two `string` objects, use `EXPECT_EQ`, `EXPECT_NE`, and etc instead.
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
# The Problem #
# The Problem
Template and macro libraries often need to define many classes,
Template and macro libraries often need to define many classes, functions, or
functions, or macros that vary only (or almost only) in the number of
macros that vary only (or almost only) in the number of arguments they take.
arguments they take. It's a lot of repetitive, mechanical, and
It's a lot of repetitive, mechanical, and error-prone work.
error-prone work.
Variadic templates and variadic macros can alleviate the problem.
Variadic templates and variadic macros can alleviate the problem. However, while
However, while both are being considered by the C++ committee, neither
both are being considered by the C++ committee, neither is in the standard yet
is in the standard yet or widely supported by compilers. Thus they
or widely supported by compilers. Thus they are often not a good choice,
are often not a good choice, especially when your code needs to be
especially when your code needs to be portable. And their capabilities are still
portable. And their capabilities are still limited.
limited.
As a result, authors of such libraries often have to write scripts to
As a result, authors of such libraries often have to write scripts to generate
generate their implementation. However, our experience is that it's
their implementation. However, our experience is that it's tedious to write such
tedious to write such scripts, which tend to reflect the structure of
scripts, which tend to reflect the structure of the generated code poorly and
the generated code poorly and are often hard to read and edit. For
are often hard to read and edit. For example, a small change needed in the
example, a small change needed in the generated code may require some
generated code may require some non-intuitive, non-trivial changes in the
non-intuitive, non-trivial changes in the script. This is especially
script. This is especially painful when experimenting with the code.
painful when experimenting with the code.
# Our Solution #
# Our Solution
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
Programming, or Practical Utility for Meta Programming, whichever you
Programming, or Practical Utility for Meta Programming, whichever you prefer) is
prefer) is a simple meta-programming tool for C++. The idea is that a
a simple meta-programming tool for C++. The idea is that a programmer writes a
programmer writes a `foo.pump` file which contains C++ code plus meta
`foo.pump` file which contains C++ code plus meta code that manipulates the C++
code that manipulates the C++ code. The meta code can handle
code. The meta code can handle iterations over a range, nested iterations, local
iterations over a range, nested iterations, local meta variable
meta variable definitions, simple arithmetic, and conditional expressions. You
definitions, simple arithmetic, and conditional expressions. You can
can view it as a small Domain-Specific Language. The meta language is designed
view it as a small Domain-Specific Language. The meta language is
to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
designed to be non-intrusive (s.t. it won't confuse Emacs' C++ mode,
concise, making Pump code intuitive and easy to maintain.
for example) and concise, making Pump code intuitive and easy to
maintain.
## Highlights
## Highlights ##
* The implementation is in a single Python script and thus ultra portable: no
build or installation is needed and it works cross platforms.
* The implementation is in a single Python script and thus ultra portable: no build or installation is needed and it works cross platforms.
* Pump tries to be smart with respect to
* Pump tries to be smart with respect to [Google's style guide](https://github.com/google/styleguide): it breaks long lines (easy to have when they are generated) at acceptable places to fit within 80 columns and indent the continuation lines correctly.
[Google's style guide](https://github.com/google/styleguide): it breaks long
* The format is human-readable and more concise than XML.
lines (easy to have when they are generated) at acceptable places to fit
* The format works relatively well with Emacs' C++ mode.
within 80 columns and indent the continuation lines correctly.
* The format is human-readable and more concise than XML.
## Examples ##
* The format works relatively well with Emacs' C++ mode.
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are meta brackets, and `$$` starts a meta comment that ends with the line):
## Examples
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
meta brackets, and `$$` starts a meta comment that ends with the line):
```
```
$var n = 3 $$ Defines a meta variable n.
$var n = 3 $$ Defines a meta variable n.
...
@@ -71,7 +70,7 @@ $if i == 0 [[
...
@@ -71,7 +70,7 @@ $if i == 0 [[
will be translated by the Pump compiler to:
will be translated by the Pump compiler to:
```cpp
```cpp
// Foo0 does blah for 0-ary predicates.
// Foo0 does blah for 0-ary predicates.
template<size_tN>
template<size_tN>
classFoo0{
classFoo0{
...
@@ -105,9 +104,10 @@ Func($for i + [[a$i]]);
...
@@ -105,9 +104,10 @@ Func($for i + [[a$i]]);
$$ The text between i and [[ is the separator between iterations.
$$ The text between i and [[ is the separator between iterations.
```
```
will generate one of the following lines (without the comments), depending on the value of `n`:
will generate one of the following lines (without the comments), depending on
the value of `n`:
```cpp
```cpp
Func();// If n is 0.
Func();// If n is 0.
Func(a1);// If n is 1.
Func(a1);// If n is 1.
Func(a1+a2);// If n is 2.
Func(a1+a2);// If n is 2.
...
@@ -115,32 +115,38 @@ Func(a1 + a2 + a3); // If n is 3.
...
@@ -115,32 +115,38 @@ Func(a1 + a2 + a3); // If n is 3.
// And so on...
// And so on...
```
```
## Constructs ##
## Constructs
We support the following meta programming constructs:
We support the following meta programming constructs:
| `$var id = exp` | Defines a named constant value. `$id` is valid util the end of the current meta lexical block. |
| `$var id = exp` | Defines a named constant value. `$id` is |
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). It is still
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py).
very unpolished and lacks automated tests, although it has been
It is still very unpolished and lacks automated tests, although it has been
successfully used many times. If you find a chance to use it in your
successfully used many times. If you find a chance to use it in your project,
project, please let us know what you think! We also welcome help on
please let us know what you think! We also welcome help on improving Pump.
improving Pump.
## Real Examples ##
## Real Examples
You can find real-world applications of Pump in [Google Test](https://github.com/google/googletest/tree/master/googletest) and [Google Mock](https://github.com/google/googletest/tree/master/googlemock). The source file `foo.h.pump` generates `foo.h`.
You can find real-world applications of Pump in
[Google Test](https://github.com/google/googletest/tree/master/googletest) and
[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
source file `foo.h.pump` generates `foo.h`.
## Tips ##
## Tips
* If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1.
* If a meta variable is followed by a letter or digit, you can separate them
* To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line.
using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
generate `Foo1Helper` when `j` is 1.
* To avoid extra-long Pump source lines, you can break a line anywhere you
want by inserting `[[]]` followed by a new line. Since any new-line
character next to `[[` or `]]` is ignored, the generated code won't contain