Skip to content

Commit

Permalink
Merge pull request #3 from swift-nav/upstream-master
Browse files Browse the repository at this point in the history
Merge upstream master
  • Loading branch information
jbangelo authored Nov 13, 2021
2 parents f79c84f + fec592c commit 1b7d4dd
Show file tree
Hide file tree
Showing 157 changed files with 975 additions and 570 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ GRTAGS
GTAGS
TAGS
ext/gmock
ext/boost
ext/boost
**/Makefile
librapidcheck.a
rapidcheckConfig.cmake
63 changes: 37 additions & 26 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
language: cpp
sudo: false

branches:
only:
- master
cache: ccache

matrix:
include:
# GCC 4.9
- addons: &gcc49
apt:
sources:
- george-edison55-precise-backports
- ubuntu-toolchain-r-test
packages:
- cmake
- cmake-data
- ninja-build
- g++-4.9
- ccache
compiler: gcc
env: COMPILER_VERSION=4.9 BUILD_TYPE=Release

- addons: *gcc49
compiler: gcc
env: COMPILER_VERSION=4.9 BUILD_TYPE=Debug

# Clang 3.5
- addons: &clang35
apt:
Expand All @@ -20,12 +37,13 @@ matrix:
- ninja-build
- g++-4.9
- clang-3.5
- ccache
compiler: clang
env: COMPILER_VERSION=3.5 BUILD_TYPE=Debug
env: COMPILER_VERSION=3.5 BUILD_TYPE=Release

- addons: *clang35
compiler: clang
env: COMPILER_VERSION=3.5 BUILD_TYPE=Release
env: COMPILER_VERSION=3.5 BUILD_TYPE=Debug

# Clang 3.7
- addons: &clang37
Expand All @@ -40,35 +58,28 @@ matrix:
- ninja-build
- g++-4.9
- clang-3.7
- ccache
compiler: clang
env: COMPILER_VERSION=3.7 BUILD_TYPE=Debug
env: COMPILER_VERSION=3.7 BUILD_TYPE=Release

- addons: *clang37
compiler: clang
env: COMPILER_VERSION=3.7 BUILD_TYPE=Release

# GCC 4.9
- addons: &gcc49
apt:
sources:
- george-edison55-precise-backports
- ubuntu-toolchain-r-test
packages:
- cmake
- cmake-data
- ninja-build
- g++-4.9
compiler: gcc
env: COMPILER_VERSION=4.9 BUILD_TYPE=Debug

- addons: *gcc49
compiler: gcc
env: COMPILER_VERSION=4.9 BUILD_TYPE=Release
env: COMPILER_VERSION=3.7 BUILD_TYPE=Debug

script:
- mkdir build && cd build
- export CC="${CC}-${COMPILER_VERSION}"
- export CXX="${CXX}-${COMPILER_VERSION}"
- cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DRC_ENABLE_TESTS=ON -DRC_ENABLE_EXAMPLES=ON -DRC_ENABLE_GTEST=ON -DRC_ENABLE_GMOCK=ON -DRC_ENABLE_BOOST=ON -DRC_ENABLE_BOOST_TEST=ON -G Ninja ..
- ls -l /usr/lib/ccache
# not all compilers get symlinked in ccache's default directory and we don't have sudo access,
# so use home dir to make ccache symlinks.
- mkdir -p ${HOME}/bin
- export PATH="${HOME}/bin:${PATH}"
- ln -sf /usr/bin/ccache ${HOME}/bin/"${CXX}"
- which ${CXX}
- cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DRC_ENABLE_TESTS=ON -DRC_ENABLE_EXAMPLES=ON -DRC_ENABLE_GTEST=ON -DRC_ENABLE_GMOCK=ON -DRC_ENABLE_BOOST=ON -DRC_ENABLE_BOOST_TEST=ON -DRC_ENABLE_RTTI=ON -G Ninja ..
- ccache --show-stats > ccache_before # collect stats
- ninja -j1 # Don't run out of memory, please
- ccache --show-stats > ccache_after
- diff -U100 ccache_before ccache_after || true # display stats, don't care about result
- ctest --output-on-failure
67 changes: 59 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
cmake_minimum_required(VERSION 2.8.12)
project(rapidcheck)
enable_testing()
cmake_minimum_required(VERSION 3.0)
project(rapidcheck CXX)

# Don't warn about symbol visibility for static libraries with CMake 3.3 and later.
if(POLICY CMP0063)
cmake_policy(SET CMP0063 NEW)
endif()

set(CMAKE_CXX_STANDARD 11)

option(RC_ENABLE_TESTS "Build RapidCheck tests" OFF)
option(RC_ENABLE_EXAMPLES "Build RapidCheck examples" OFF)
option(RC_ENABLE_RTTI "Build RapidCheck with RTTI" ON)

if(MSVC)
# /bigobj - some object files become very large so we need this
Expand All @@ -14,9 +21,20 @@ if(MSVC)
string(REGEX REPLACE "/RTC(su|[1su])" ""
CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-missing-braces -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-missing-braces -Wno-unused-command-line-argument")
if(APPLE)
if(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang)")
# Workaround for legacy Apple environment (cf. https://stackoverflow.com/a/19774902/1682144)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()
endif()

# RapidCheck will be built either as a static or a dynamic library depending on the CMake global
# variable BUILD_SHARED_LIBS (https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html).
# If you wish to change the library type of RapidCheck, you can either specify the variable when invoking CMake
# or, if you are including RapidCheck as a subdirectory and wish to control the library type, you can set
# the variable before the call to add_subdirectory and reset it afterwards, if necessary.
add_library(rapidcheck
src/BeforeMinimalTestCase.cpp
src/Check.cpp
Expand Down Expand Up @@ -54,7 +72,7 @@ add_library(rapidcheck
src/gen/detail/ScaleInteger.cpp
)

# Random is used a LOT so it should preferrably be really fast.
# Random is used a LOT so it should preferably be really fast.
if(MSVC)
set_property(SOURCE src/Random.cpp
APPEND_STRING PROPERTY COMPILE_FLAGS " /O2")
Expand All @@ -63,16 +81,49 @@ else()
APPEND_STRING PROPERTY COMPILE_FLAGS " -O3")
endif()

target_include_directories(rapidcheck PUBLIC include)
target_include_directories(rapidcheck PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:include> # <prefix>/include
)

include(GNUInstallDirs)
install(TARGETS rapidcheck EXPORT rapidcheckConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # This is for Windows
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

# On Windows under MinGW, random_device provides no entropy,
# so it will always return the same value.
# Seed using system time instead.
# See: https://stackoverflow.com/questions/18880654/why-do-i-get-the-same-sequence-for-every-run-with-stdrandom-device-with-mingw
if(MINGW)
target_compile_definitions(rapidcheck PRIVATE RC_SEED_SYSTEM_TIME)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "^MSVC$")
# To reflect the language level (cf. https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-160)
target_compile_options(rapidcheck PUBLIC /Zc:__cplusplus)
endif ()

if(NOT RC_ENABLE_RTTI)
target_compile_definitions(rapidcheck PUBLIC RC_DONT_USE_RTTI)
endif()

add_subdirectory(ext)

if (RC_ENABLE_TESTS)
if(RC_ENABLE_TESTS)
enable_testing()
add_subdirectory(test)
endif()

if (RC_ENABLE_EXAMPLES)
if(RC_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()

add_subdirectory(extras)

# Install the export file specifying all the targets for RapidCheck
install(EXPORT rapidcheckConfig DESTINATION share/rapidcheck/cmake)
export(EXPORT rapidcheckConfig FILE rapidcheckConfig.cmake)
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
RapidCheck [![Build Status](https://travis-ci.org/emil-e/rapidcheck.svg?branch=master)](https://travis-ci.org/emil-e/rapidcheck) [![Build status](https://ci.appveyor.com/api/projects/status/8hms56ghn27agpcj/branch/master?svg=true)](https://ci.appveyor.com/project/emil-e/rapidcheck/branch/master)
==========
# RapidCheck [![Build Status](https://travis-ci.org/emil-e/rapidcheck.svg?branch=master)](https://travis-ci.org/emil-e/rapidcheck) [![Build status](https://ci.appveyor.com/api/projects/status/8hms56ghn27agpcj/branch/master?svg=true)](https://ci.appveyor.com/project/emil-e/rapidcheck/branch/master)

RapidCheck is a C++ framework for property based testing inspired by QuickCheck and other similar frameworks. In property based testing, you state facts about your code that given certain precondition should always be true. RapidCheck then generates random test data to try and find a case for which the property doesn't hold. If such a case is found, RapidCheck tries to find the smallest case (for some definition of smallest) for which the property is still false and then displays this as a counterexample. For example, if the input is an integer, RapidCheck tries to find the smallest integer for which the property is false.

Sounds interesting? Why don't you read the **[User Guide](doc/user_guide.md)** to learn more!

## Why RapidCheck? ##
## Why RapidCheck?

There are existing implementations of property based testing but the ones that I have found are either (in my humble opinion) a bit clunky or are missing essential features such as test case shrinking.

Let's throw together a list of features:
Expand All @@ -16,8 +17,9 @@ Let's throw together a list of features:
- Stateful based on commands in the vein of Erlang QuickCheck
- Integration with popular testing frameworks such as Boost Test, Google Test and Google Mock

## Prerequisites and installation ##
RapidCheck makes extensive use of C++11 and thus requires a compliant compiler. RapidCheck continuous integration builds using Clang 3.5, GCC 4.9 and Visual Studio 2015 so any later versions should also work.
## Prerequisites and installation

RapidCheck makes extensive use of C++11 and thus requires a compliant compiler. RapidCheck continuous integration builds using Clang 3.5, GCC 4.9 and Visual Studio 2015 so any later versions should also work.

RapidCheck uses CMake and is built like any other CMake project. If your own project uses CMake you can simply have RapidCheck as a subdirectory and add the following to your `CMakeLists.txt`:

Expand All @@ -26,7 +28,8 @@ RapidCheck uses CMake and is built like any other CMake project. If your own pro

This will give you both linking and include directories.

## Quick introduction ##
## Quick introduction

A common first example is testing a reversal function. For such a function, double reversal should always result in the original list. In this example we will use the standard C++ `std::reverse` function:

```C++
Expand Down Expand Up @@ -54,7 +57,7 @@ The property above also forms part of a specification of the reversal function:

If we were to run this, RapidCheck would (hopefully) output the following:

```
```text
Using configuration: seed=9928307433081493900
- double reversal yields the original value
Expand All @@ -63,7 +66,7 @@ OK, passed 100 tests

Here, RapidCheck tells us that it ran 100 test cases and all of them passed. It also tells us the configuration that was used, in particular the random seed. If there was a bug in the implementation of `std::reverse` we could get the following output instead:

```
```text
Falsifiable after 12 tests and 10 shrinks
std::tuple<std::vector<int>>:
Expand All @@ -80,5 +83,6 @@ Here RapidCheck tells us that it found a case for which the property does not ho

Can you guess what the bug is? The fact that there are exactly 10 items should give a clue. In this case, the bug is that the implementation sets the first element to `0` when `l0.size() >= 10`. This is also the reason for the initial `0`, the problem doesn't manifest when all elements are zero. How did this bug happen? Who knows!

## Thanks ##
## Thanks

Big thanks to my employer, Spotify, for making it possible for me to spend work time improving RapidCheck.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build_script:
- md build
- cd build
- "\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat\" %ARCH%"
- cmake -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DRC_ENABLE_TESTS=ON -DRC_ENABLE_EXAMPLES=ON -DRC_ENABLE_GTEST=ON -DRC_ENABLE_GMOCK=ON -DRC_ENABLE_BOOST=ON -DRC_ENABLE_BOOST_TEST=ON -G "NMake Makefiles" ..
- cmake -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DRC_ENABLE_TESTS=ON -DRC_ENABLE_EXAMPLES=ON -DRC_ENABLE_GTEST=ON -DRC_ENABLE_GMOCK=ON -DRC_ENABLE_BOOST=ON -DRC_ENABLE_BOOST_TEST=ON -DRC_ENABLE_RTTI=ON -G "NMake Makefiles" ..
- nmake

test_script:
Expand Down
4 changes: 2 additions & 2 deletions doc/Gen.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
`Gen<T>`
=======
# `Gen<T>`

_This section is incomplete._
4 changes: 2 additions & 2 deletions doc/Seq.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
`Seq<T>`
=======
# `Seq<T>`

_This section is incomplete._

`Seq<T>` implements a lazy sequence (often called a "stream") of values of type `T`. It has a super simple interface for retrieving these values consisting only of the method `Maybe<T> next()`. As can be seen, it returns a `Maybe<T>` which is similar to `boost::optional`, Haskell's `Maybe` or other similar types that either contain a value or be empty. `next` successively returns the values in the sequence until the sequence is exhausted after which it will return an empty `Maybe` to signal that there are no more values.
Expand Down
4 changes: 2 additions & 2 deletions doc/Shrinkable.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
`Shrinkable<T>`
==============
# `Shrinkable<T>`

_This section is incomplete._

`Shrinkable<T>` is a fundamental template class in RapidCheck. An instance of `Shrinkable<T>` represents some value of type `T` and provides a way to access all the ways in which this value can be shrunk. It has value semantics which means that it can be copied and passed around just like any other value. It has two member functions:
Expand Down
38 changes: 24 additions & 14 deletions doc/assertions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Assertions
==========
# Assertions

There are multiple ways to fail a test case:

- Returning `false`
Expand All @@ -10,7 +10,8 @@ Each is equally valid but using RapidCheck's assertions are a convenient way to

**NOTE:** The assertion macros are implemented using exceptions. The particular exceptions are an implementation detail but you should ensure your properties are exception safe or be prepared to leak resources.

## Capturing ##
## Capturing

In a lot of cases, RapidCheck can capture the expansion of the expression used in the assertion macros in a way inspired by the [Catch.hpp](https://github.com/philsquared/Catch) framework. This means you can write your assertions in a style that is natural to C++:

```C++
Expand All @@ -21,7 +22,7 @@ RC_ASSERT(foo == bar);
If used in a property, RapidCheck might print something similar:
```
```text
main.cpp:24:
foo == bar
Expand All @@ -32,32 +33,41 @@ Expands to:
However, in some cases, this capturing might fail to include the information that you want.

## Reference

The selection of assertion macros is currently rather slim. Suggestions on how to improve this is welcome.

### `RC_ASSERT(expression)` ###
### `RC_ASSERT(expression)`

Fails the test case if `expression` evaluates to `false`.

### `RC_ASSERT_FALSE(expression)` ###
### `RC_ASSERT_FALSE(expression)`

Fails the test case if `expression` evaluates to `true`. Use this instead of `RC_ASSERT(!(...))` since RapidCheck cannot capture the expression in that case.

### `RC_ASSERT_THROWS(expression)` ###
### `RC_ASSERT_THROWS(expression)`

Fails the test case if `expression` does not throw an exception.

### `RC_ASSERT_THROWS_AS(expression, ExceptionType)` ###
### `RC_ASSERT_THROWS_AS(expression, ExceptionType)`

Fails the test case if `expression` does not throw an exception that matches `ExceptionType`.

### `RC_FAIL(msg)` ###
### `RC_FAIL(msg)`

Unconditionally fails the test case with `msg` as message.

### `RC_SUCCEED_IF(expression)` ###
### `RC_SUCCEED_IF(expression)`

Causes the test case to immediately succeed if `expression` evaluates to `true`.

### `RC_SUCCEED(msg)` ###
### `RC_SUCCEED(msg)`

Unconditionally makes the test case succeed with `msg` as the message.

### `RC_PRE(expression)` ###
### `RC_PRE(expression)`

Discards the test case if `expression` evaluates to `false`.

### `RC_DISCARD(msg)` ###
Unconditionally discards the test case with `msg` as the message.
### `RC_DISCARD(msg)`

Unconditionally discards the test case with `msg` as the message.
Loading

0 comments on commit 1b7d4dd

Please sign in to comment.