├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── sodiumpp ├── example.cpp ├── include │ ├── bandit │ │ ├── adapters │ │ │ ├── adapter.h │ │ │ ├── adapters.h │ │ │ └── snowhouse.h │ │ ├── assertion_exception.h │ │ ├── assertion_frameworks │ │ │ └── snowhouse │ │ │ │ ├── .gitignore │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── README.md │ │ │ │ ├── example │ │ │ │ └── main.cpp │ │ │ │ └── snowhouse │ │ │ │ ├── assert.h │ │ │ │ ├── assertionexception.h │ │ │ │ ├── assertmacro.h │ │ │ │ ├── constraints │ │ │ │ ├── constraints.h │ │ │ │ ├── containsconstraint.h │ │ │ │ ├── endswithconstraint.h │ │ │ │ ├── equalsconstraint.h │ │ │ │ ├── equalscontainerconstraint.h │ │ │ │ ├── equalswithdeltaconstraint.h │ │ │ │ ├── expressions │ │ │ │ │ ├── andexpression.h │ │ │ │ │ ├── expression.h │ │ │ │ │ ├── expression_fwd.h │ │ │ │ │ ├── notexpression.h │ │ │ │ │ └── orexpression.h │ │ │ │ ├── fulfillsconstraint.h │ │ │ │ ├── haslengthconstraint.h │ │ │ │ ├── isgreaterthanconstraint.h │ │ │ │ ├── islessthanconstraint.h │ │ │ │ └── startswithconstraint.h │ │ │ │ ├── exceptions.h │ │ │ │ ├── fluent │ │ │ │ ├── constraintadapter.h │ │ │ │ ├── constraintlist.h │ │ │ │ ├── expressionbuilder.h │ │ │ │ ├── fluent.h │ │ │ │ └── operators │ │ │ │ │ ├── andoperator.h │ │ │ │ │ ├── collections │ │ │ │ │ ├── alloperator.h │ │ │ │ │ ├── atleastoperator.h │ │ │ │ │ ├── atmostoperator.h │ │ │ │ │ ├── collectionconstraintevaluator.h │ │ │ │ │ ├── collectionoperator.h │ │ │ │ │ ├── exactlyoperator.h │ │ │ │ │ └── noneoperator.h │ │ │ │ │ ├── constraintoperator.h │ │ │ │ │ ├── notoperator.h │ │ │ │ │ └── oroperator.h │ │ │ │ ├── snowhouse.h │ │ │ │ ├── stringize.h │ │ │ │ └── stringizers.h │ │ ├── bandit.h │ │ ├── context.h │ │ ├── external │ │ │ └── optionparser.h │ │ ├── failure_formatters │ │ │ ├── default_failure_formatter.h │ │ │ ├── failure_formatter.h │ │ │ ├── failure_formatters.h │ │ │ └── visual_studio_failure_formatter.h │ │ ├── grammar.h │ │ ├── listener.h │ │ ├── options.h │ │ ├── registration │ │ │ ├── registrar.h │ │ │ ├── registration.h │ │ │ └── spec_registry.h │ │ ├── reporters │ │ │ ├── colorizer.h │ │ │ ├── dots_reporter.h │ │ │ ├── progress_reporter.h │ │ │ ├── reporters.h │ │ │ ├── single_line_reporter.h │ │ │ ├── spec_reporter.h │ │ │ ├── test_run_summary.h │ │ │ └── xunit_reporter.h │ │ ├── run_policies │ │ │ ├── always_run_policy.h │ │ │ ├── bandit_run_policy.h │ │ │ ├── never_run_policy.h │ │ │ ├── run_policies.h │ │ │ └── run_policy.h │ │ ├── runner.h │ │ ├── skip_policies │ │ │ ├── always_include_policy.h │ │ │ ├── always_skip_policy.h │ │ │ ├── name_contains_skip_policy.h │ │ │ ├── skip_policies.h │ │ │ └── skip_policy.h │ │ └── test_run_error.h │ └── sodiumpp │ │ ├── sodiumpp.h │ │ ├── z85.h │ │ └── z85.hpp ├── sodiumpp.cpp ├── test.cpp └── z85 │ ├── z85.c │ └── z85_impl.cpp └── travis ├── Dockerfile └── build.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | # Vim swap files 16 | .*.swp 17 | 18 | # CMake build files 19 | build 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: generic 3 | 4 | services: 5 | - docker 6 | 7 | before_install: 8 | - docker build -t rubendv/sodiumpp travis 9 | 10 | script: 11 | - docker run -it --rm -v $PWD:/opt/sodiumpp rubendv/sodiumpp /opt/sodiumpp/travis/build.sh 12 | - docker run -it --rm -v $PWD:/opt/sodiumpp rubendv/sodiumpp /opt/sodiumpp/build/tests --reporter=spec 13 | - docker run -it --rm -v $PWD:/opt/sodiumpp rubendv/sodiumpp /opt/sodiumpp/build/example 14 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.6) 2 | project (sodiumpp) 3 | 4 | if(APPLE) 5 | set(CMAKE_MACOSX_RPATH ON) 6 | endif() 7 | 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 9 | 10 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -g") 12 | 13 | if(SODIUMPP_MACPORTS) 14 | include_directories("/opt/local/include") 15 | link_directories("/opt/local/lib") 16 | endif() 17 | 18 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sodiumpp/include) 19 | 20 | if(SODIUMPP_STATIC) 21 | add_library(sodiumpp STATIC sodiumpp/sodiumpp.cpp sodiumpp/z85/z85.c sodiumpp/z85/z85_impl.cpp) 22 | find_library(SODIUMLIB libsodium.a) 23 | else() 24 | add_library(sodiumpp SHARED sodiumpp/sodiumpp.cpp sodiumpp/z85/z85.c sodiumpp/z85/z85_impl.cpp) 25 | target_link_libraries(sodiumpp sodium) 26 | find_library(SODIUMLIB sodium) 27 | endif() 28 | 29 | if(SODIUMPP_EXAMPLE) 30 | add_executable(example sodiumpp/example.cpp) 31 | target_link_libraries(example sodiumpp ${SODIUMLIB}) 32 | endif() 33 | 34 | if(SODIUMPP_TEST) 35 | add_executable(tests sodiumpp/test.cpp) 36 | target_link_libraries(tests sodiumpp ${SODIUMLIB}) 37 | endif() 38 | 39 | install(DIRECTORY sodiumpp/include/sodiumpp DESTINATION include) 40 | install_targets(/lib sodiumpp) 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Ruben De Visscher 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sodiumpp 2 | ======== 3 | 4 | [![Build Status](https://travis-ci.org/rubendv/sodiumpp.svg?branch=master)](https://travis-ci.org/rubendv/sodiumpp) 5 | 6 | *This is a very preliminary version, do NOT expect it to be secure or use it for anything important.* 7 | 8 | This library implements the C++ API of NaCl (which is described [here](http://nacl.cr.yp.to/)) with some small improvements on top of libsodium, as well as a high level API that takes care of nonce generation for you. 9 | 10 | Installation 11 | ------------ 12 | 13 | Building and installing is done using cmake: 14 | 15 | ```bash 16 | mkdir build 17 | cd build 18 | cmake .. 19 | make 20 | make install 21 | ``` 22 | 23 | Example 24 | ------- 25 | 26 | Compile this example by supplying the `-DSODIUMPP_EXAMPLE=1` flag to cmake, and run it with `./example`. 27 | 28 | ```c++ 29 | #include 30 | #include 31 | #include 32 | using namespace sodiumpp; 33 | 34 | int main(int argc, const char ** argv) { 35 | box_secret_key sk_client; 36 | box_secret_key sk_server; 37 | 38 | std::cout << "Client key: " << sk_client << std::endl; 39 | std::cout << "Server key: " << sk_server << std::endl; 40 | std::cout << std::endl; 41 | 42 | // Uses predefined nonce type with 64-bit sequential counter 43 | // and constant random bytes for the rest 44 | boxer client_boxer(sk_server.pk, sk_client); 45 | unboxer server_unboxer(sk_client.pk, sk_server, client_boxer.get_nonce_constant()); 46 | 47 | nonce64 used_n; 48 | encoded_bytes boxed = client_boxer.box("Hello, world!\n", used_n); 49 | std::cout << "Nonce (hex): " << used_n.get(encoding::hex).bytes << std::endl; 50 | std::cout << "Boxed message (z85): " << boxed.to(encoding::z85).bytes << std::endl; 51 | // Nonce is passed explicitly here, but will also be increased automatically 52 | // if unboxing happens in the same order as boxing. 53 | // In a real application this nonce would be passed along with the boxed message. 54 | std::string unboxed = server_unboxer.unbox(boxed, used_n); 55 | std::cout << "Unboxed message: " << unboxed; 56 | std::cout << std::endl; 57 | 58 | boxed = client_boxer.box("From sodiumpp!\n", used_n); 59 | unboxed = server_unboxer.unbox(boxed, used_n); 60 | std::cout << "Nonce (hex): " << used_n.get(encoding::hex).bytes << std::endl; 61 | std::cout << "Boxed message (z85): " << boxed.to(encoding::z85).bytes << std::endl; 62 | std::cout << "Unboxed message: " << unboxed; 63 | return 0; 64 | } 65 | ``` 66 | 67 | High-level API Overview 68 | ----------------------- 69 | 70 | The `public_key` and `secret_key` are used to generate and store public and secret keys. Secret keys are locked into memory so they cannot be swapped out to disk, and are securely erased when the key's destructor is called. The template parameter `P` gives the purpose of the key: at the moment this is either `purpose::box` for box/unbox operations and `purpose::sign` for sign/verify operations. Having seperate types for public/secret keys and different purposes helps to avoid mixing them up. 71 | 72 | The `nonce` class provides a nonce that can be incremented and passed to box/unbox functions. It consists of a sequential part that is `sequentialbytes` bytes long, which is preceded by a constant part that takes up the rest of the bytes in the nonce. This constant part can be specified by the user or generated randomly. 73 | The nonce class detects an overflow in the sequential part if it occurs and will throw an exception if you try to access the sequential part after this. This is important for security as a nonce should never be repeated for messages between the same two keypairs. 74 | For convenience, `nonce8`, `nonce16`, `nonce32` and `nonce64` typedefs are defined where the number indicates the number of _bits_ (not bytes!) in the sequential part of the nonce. 75 | 76 | The `boxer` and `unboxer` classes provide respectively box and unbox functionality. They take a template argument `noncetype` which specifies the kind of nonce to use. The boxer will automatically increment the sequential part of the nonce for each message. Generated nonces will be even when the sender's public key is lexicographically smaller than the receiver's public key and uneven otherwise. This ensures that the other side can do the same thing without running the risk of using the same nonce for different messages between the same two keypairs, which would compromise the security of the messages. The unboxer will also automatically increment the nonce in the same manner, but an optional nonce override can be supplied at which point this overriding nonce is used instead of the current automatic nonce, and the current automatic nonce is left as-is. In a real system where ordering of the messages cannot be guaranteed the nonce that was used to box the message would be passed alongside the boxed message, and used as a nonce override at the unboxer side. 77 | 78 | Throughout the API a string wrapper `encoded_bytes` is used, this stores a normal string alongside an encoding such as plain binary, hexadecimal or Z85 encoding to allow easy handling of strings in these encodings. 79 | 80 | For more detailed API documentation, have a look at the comments in sodiumpp/include/sodiumpp/sodiumpp.h. 81 | -------------------------------------------------------------------------------- /sodiumpp/example.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Ruben De Visscher 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // 1. Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // 2. Redistributions in binary form must reproduce the above copyright notice, 10 | // this list of conditions and the following disclaimer in the documentation 11 | // and/or other materials provided with the distribution. 12 | // 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #include 25 | #include 26 | #include 27 | using namespace sodiumpp; 28 | 29 | int main(int argc, const char ** argv) { 30 | box_secret_key sk_client; 31 | box_secret_key sk_server; 32 | 33 | std::cout << "Client key: " << sk_client << std::endl; 34 | std::cout << "Server key: " << sk_server << std::endl; 35 | std::cout << std::endl; 36 | 37 | // Uses predefined nonce type with 64-bit sequential counter 38 | // and constant random bytes for the rest 39 | boxer client_boxer(sk_server.pk, sk_client); 40 | unboxer server_unboxer(sk_client.pk, sk_server, client_boxer.get_nonce_constant()); 41 | 42 | nonce64 used_n; 43 | encoded_bytes boxed = client_boxer.box("Hello, world!\n", used_n); 44 | std::cout << "Nonce (hex): " << used_n.get(encoding::hex).bytes << std::endl; 45 | std::cout << "Boxed message (z85): " << boxed.to(encoding::z85).bytes << std::endl; 46 | // Nonce is passed explicitly here, but will also be increased automatically 47 | // if unboxing happens in the same order as boxing. 48 | // In a real application this nonce would be passed along with the boxed message. 49 | std::string unboxed = server_unboxer.unbox(boxed, used_n); 50 | std::cout << "Unboxed message: " << unboxed; 51 | std::cout << std::endl; 52 | 53 | boxed = client_boxer.box("From sodiumpp!\n", used_n); 54 | unboxed = server_unboxer.unbox(boxed, used_n); 55 | std::cout << "Nonce (hex): " << used_n.get(encoding::hex).bytes << std::endl; 56 | std::cout << "Boxed message (z85): " << boxed.to(encoding::z85).bytes << std::endl; 57 | std::cout << "Unboxed message: " << unboxed; 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/adapters/adapter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ADAPTER_H 2 | #define BANDIT_ADAPTER_H 3 | 4 | namespace bandit { namespace adapters { 5 | 6 | struct assertion_adapter 7 | { 8 | virtual void adapt_exceptions(detail::voidfunc_t) = 0; 9 | }; 10 | }} 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/adapters/adapters.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ADAPTERS_H 2 | #define BANDIT_ADAPTERS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace bandit { namespace detail { 8 | 9 | inline bandit::adapters::assertion_adapter& registered_adapter() 10 | { 11 | static bandit::adapters::snowhouse_adapter adapter; 12 | return adapter; 13 | } 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/adapters/snowhouse.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ADAPTERS_SNOWHOUSE_H 2 | #define BANDIT_ADAPTERS_SNOWHOUSE_H 3 | 4 | namespace bandit { namespace adapters { 5 | 6 | struct snowhouse_adapter : public assertion_adapter 7 | { 8 | void adapt_exceptions(detail::voidfunc_t func) 9 | { 10 | try 11 | { 12 | func(); 13 | } 14 | catch(const snowhouse::AssertionException& ex) 15 | { 16 | throw bandit::detail::assertion_exception(ex.GetMessage(), ex.GetFilename(), ex.GetLineNumber()); 17 | } 18 | } 19 | }; 20 | 21 | }} 22 | #endif 23 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ASSERTION_EXCEPTION_H 2 | #define BANDIT_ASSERTION_EXCEPTION_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct assertion_exception : public std::runtime_error 7 | { 8 | assertion_exception(const std::string& message, 9 | const std::string& file_name, const unsigned int line_number) 10 | : std::runtime_error(message), file_name_(file_name), line_number_(line_number) 11 | {} 12 | 13 | assertion_exception(const std::string& message) 14 | : std::runtime_error(message), line_number_(0) 15 | {} 16 | 17 | // 18 | // To make gcc < 4.7 happy. 19 | // 20 | virtual ~assertion_exception() throw() 21 | {} 22 | 23 | const std::string& file_name() const 24 | { 25 | return file_name_; 26 | } 27 | 28 | unsigned int line_number() const 29 | { 30 | return line_number_; 31 | } 32 | 33 | private: 34 | std::string file_name_; 35 | unsigned int line_number_; 36 | }; 37 | }} 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/.gitignore: -------------------------------------------------------------------------------- 1 | #cmake files 2 | CMakeCache.txt 3 | CMakeFiles/ 4 | Makefile 5 | bin/ 6 | cmake_install.cmake 7 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(snowhouse) 4 | 5 | include_directories("${PROJECT_SOURCE_DIR}") 6 | 7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ./bin) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wfatal-errors -Wall -W -Werror -Wfloat-equal -Wundef -Wendif-labels -Wshadow -pedantic-errors") 10 | 11 | FILE(GLOB SnowhouseSpecSourceFiles example/*.cpp) 12 | add_executable(snowhouse-tests ${SnowhouseSpecSourceFiles}) 13 | 14 | add_custom_command(TARGET snowhouse-tests 15 | POST_BUILD 16 | COMMAND snowhouse-tests 17 | WORKING_DIRECTORY ./bin) 18 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/README.md: -------------------------------------------------------------------------------- 1 | snowhouse 2 | ========= 3 | 4 | An assertion library for C++ 5 | 6 | Snowhouse is a stand alone assertion framework for C++. It was originally 7 | developed as part of [Igloo](http://github.com/joakimkarlsson/igloo) and has 8 | been extracted to be usable in other contexts. 9 | 10 | ## Usage 11 | 12 | ```C++ 13 | #include 14 | using namespace snowhouse; 15 | 16 | int main() 17 | { 18 | std::cout << "Testing that 23 is 23" << std::endl; 19 | AssertThat(23, Is().EqualTo(23)); 20 | 21 | try 22 | { 23 | AssertThat(12, Is().LessThan(11).And().GreaterThan(99)); 24 | } 25 | catch(const AssertionException& ex) 26 | { 27 | std::cout << "Apparently this failed:" << std::endl; 28 | std::cout << ex.GetMessage() << std::endl; 29 | } 30 | 31 | return 0; 32 | } 33 | ``` 34 | 35 | ### Assertions 36 | 37 | Snowhouse uses a constraint based assertion model that is heavily inspired by the 38 | model used in [NUnit](http://nunit.org/). An assertion in Snowhouse is written 39 | using the following format: 40 | 41 | ```cpp 42 | AssertThat(actual_value, ); 43 | ``` 44 | 45 | where <constraint expression> is an expression that actual_value is evaluated against when the test is executed. 46 | 47 | Constraint expressions come in two basic forms: composite and fluent expressions 48 | 49 | #### Composite Expressions 50 | 51 | With composite expressions, you can create compact, powerful expressions that combine a set of predefined constraints with ones that you provide yourself. 52 | 53 | Example: 54 | 55 | ```cpp 56 | AssertThat(length, IsGreaterThan(4) && !Equals(10)); 57 | ``` 58 | 59 | Composite expressions can be any combination of constraints and the standard logical C++ operators. 60 | 61 | You can also add your own constraints to be used within composite expressions. 62 | 63 | ####Fluent Expressions 64 | 65 | With fluent expressions, you can create assertions that better convey the intent of a test without exposing implementation-specific details. Fluent expressions aim to help you create tests that are not just by developers for developers, but rather can be read and understood by domain experts. 66 | 67 | Fluent expressions also has the ability to make assertions on the elements in a conteiner in a way you cannot achieve with composite expressions. 68 | 69 | Example: 70 | 71 | ```cpp 72 | AssertThat(length, Is().GreaterThan(4).And().Not().EqualTo(10)); 73 | ``` 74 | 75 | ### Basic Constraints 76 | 77 | ####Equality Constraint 78 | 79 | Used to verify equality between actual and expected. 80 | 81 | ```cpp 82 | AssertThat(x, Equals(12)); 83 | AssertThat(x, Is().EqualTo(12)); 84 | ``` 85 | 86 | ####EqualityWithDelta Constraint 87 | 88 | Used to verify equality between actual and expected, allowing the two to differ by a delta. 89 | 90 | ```cpp 91 | AssertThat(2.49, EqualsWithDelta(2.5, 0.1)); 92 | AssertThat(2.49, Is().EqualToWithDelta(2.5, 0.1)); 93 | ``` 94 | 95 | ####GreaterThan Constraint 96 | 97 | Used to verify that actual is greater than a value. 98 | 99 | ```cpp 100 | AssertThat(x, IsGreaterThan(4)); 101 | AssertThat(x, Is().GreaterThan(4)); 102 | ``` 103 | 104 | 105 | ####LessThan Constraint 106 | 107 | Used to verify that actual is less than a value. 108 | 109 | ```cpp 110 | AssertThat(x, IsLessThan(3)); 111 | AssertThat(x, Is().LessThan(3)); 112 | ``` 113 | 114 | ### String Constraints 115 | 116 | String assertions in Snowhouse are used to verify the values of STL strings (std::string). 117 | 118 | ####Equality Constraints 119 | 120 | Used to verify that actual is equal to an expected value. 121 | 122 | ```cpp 123 | Assert:That(actual_str, Equals("foo")); 124 | AssertThat(actual_str, Is().EqualTo("foo")); 125 | ``` 126 | 127 | ####Contains Constraint 128 | 129 | Used to verify that a string contains a substring. 130 | 131 | ```cpp 132 | AssertThat(actual_str, Contains("foo")); 133 | AssertThat(actual_str, Is().Containing("foo")); 134 | ``` 135 | 136 | ####EndsWith Constraint 137 | 138 | Used to verify that a string ends with an expected substring. 139 | 140 | ```cpp 141 | AssertThat(actual_str, EndsWith("foo")); 142 | AssertThat(actual_str, Is().EndingWith("foo")); 143 | ``` 144 | 145 | ####StartsWith Constraint 146 | 147 | Used to verify that a string starts with an expected substring. 148 | 149 | ```cpp 150 | AssertThat(actual_str, StartsWith("foo")); 151 | AssertThat(actual_str, Is().StartingWith("foo")); 152 | ``` 153 | 154 | ####HasLength Constraint 155 | 156 | Used to verify that a string is of the expected length. 157 | 158 | ```cpp 159 | AssertThat(actual_str, HasLength(5)); 160 | AssertThat(actual_str, Is().OfLength(5)); 161 | ``` 162 | 163 | ###Constraints on Multi Line Strings 164 | 165 | If you have a string that contains multiple lines, you can use the collection constraints to make assertions on the content of that string. This may be handy if you have a string that, for instance, represents the resulting content of a file or a network transmission. 166 | 167 | Snowhouse can handle both windows (CR+LF) and unix (LF) line endings 168 | 169 | ```cpp 170 | std::string lines = "First line\r\nSecond line\r\nThird line"; 171 | AssertThat(lines, Has().Exactly(1).StartingWith("Second")); 172 | ``` 173 | 174 | ###Container Constraints 175 | 176 | The following constraints can be applied to containers in the standard template library: 177 | 178 | ####Contains Constraint 179 | 180 | Used to verify that a container contains an expected value. 181 | 182 | ```cpp 183 | AssertThat(container, Contains(12)); 184 | AssertThat(container, Is().Containing(12)); 185 | ``` 186 | 187 | ####HasLength Constraint 188 | 189 | Used to verify that a container has the expected length. 190 | 191 | ```cpp 192 | AssertThat(container, HasLength(3)); 193 | AssertThat(container, Is().OfLength(3)); 194 | ``` 195 | 196 | ####IsEmpty Constraint 197 | 198 | Used to verify that a container is empty. 199 | 200 | ```cpp 201 | AssertThat(contatiner, IsEmpty()); 202 | AssertThat(container, Is().Empty()); 203 | ``` 204 | 205 | ####All 206 | 207 | Used to verify that all elements of a STL sequence container matches an expectation. 208 | 209 | ```cpp 210 | AssertThat(container, Has().All().LessThan(5).Or().EqualTo(66)); 211 | ``` 212 | 213 | ####AtLeast 214 | 215 | Used to verify that at least a specified amount of elements in a STL sequence container matches an expectation. 216 | 217 | ```cpp 218 | AssertThat(container, Has().AtLeast(3).StartingWith("foo")); 219 | ``` 220 | 221 | ####AtMost 222 | 223 | Used to verify that at most a specified amount of elements in a STL sequence container matches an expectation. 224 | 225 | ```cpp 226 | Assert:That(container, Has().AtMost(2).Not().Containing("failed")); 227 | ``` 228 | 229 | ####Exactly 230 | 231 | Used to verify that a STL sequence container has exactly a specified amount of elements that matches an expectation. 232 | 233 | ```cpp 234 | AssertThat(container, Has().Exactly(3).GreaterThan(10).And().LessThan(20)); 235 | ``` 236 | 237 | ####EqualsContainer 238 | 239 | Used to verify that two STL sequence containers are equal. 240 | 241 | ```cpp 242 | AssertThat(container1, EqualsContainer(container2)); 243 | AssertThat(container1, Is().EqualToContainer(container2)); 244 | ``` 245 | 246 | #####Predicate functions 247 | 248 | You can supply a predicate function or a functor to EqualsContainer to customize how to compare the elements in the two containers. 249 | 250 | With a predicate function: 251 | 252 | ```cpp 253 | static bool are_my_types_equal(const my_type& lhs, const my_type& rhs) 254 | { 255 | return lhs.my_val_ == rhs.my_val_; 256 | } 257 | 258 | AssertThat(container1, EqualsContainer(container2, are_my_types_equal)); 259 | ``` 260 | 261 | With a functor as predicate: 262 | 263 | ```cpp 264 | struct within_delta 265 | { 266 | within_delta(int delta) : delta_(delta) {} 267 | 268 | bool operator()(const my_type& lhs, const my_type& rhs) const 269 | { 270 | return abs(lhs.my_val_ - rhs.my_val_) <= delta_; 271 | } 272 | 273 | private: 274 | int delta_; 275 | }; 276 | 277 | AssertThat(container1, Is().EqualToContainer(container1, within_delta(1)); 278 | ``` 279 | 280 | ###Exceptions 281 | 282 | Exception constraints can be used to verify that your code throws the correct exceptions. 283 | 284 | ####AssertThrows 285 | 286 | AssertThrows succeeds if the exception thrown by the call is of the supplied type (or one of its subtypes). 287 | 288 | ```cpp 289 | AssertThrows(std::logic_error, myObject.a_method(42)); 290 | ``` 291 | 292 | ####Making Assertions on the Thrown Exceptions 293 | 294 | If AssertThrows succeeds, it will store the thrown exception so that you can make more detailed assertions on it. 295 | 296 | ```cpp 297 | AssertThrows(std::logic_error, myObject.a_method(42)); 298 | AssertThat(LastException().what(), Is().Containing("logic failure")); 299 | ``` 300 | 301 | The LastException<> is available in the scope of the call to AssertThrows. An exception is not available between specs in order to avoid the result of one spec contaminating another. 302 | 303 | ###Custom Constraints 304 | 305 | You can add your own constraints to Snowhouse to create more expressive specifications. 306 | 307 | ####Fulfills Constraints 308 | 309 | By defining the following matcher 310 | 311 | ```cpp 312 | struct IsEvenNumber 313 | { 314 | bool Matches(const int actual) const 315 | { 316 | return (actual % 2) == 0; 317 | } 318 | 319 | friend std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& ); 320 | }; 321 | 322 | std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& ) 323 | { 324 | stm << "An even number"; 325 | return stm; 326 | } 327 | ``` 328 | 329 | You can create the following constraints in Snowhouse: 330 | 331 | ```cpp 332 | AssertThat(42, Fulfills(IsEvenNumber())); 333 | AssertThat(42, Is().Fulfilling(IsEvenNumber())); 334 | ``` 335 | 336 | Your custom matcher should implement a method called Matches() that takes a parameter of the type you expect and returns true if the passed parameter fulfills the constraint. 337 | 338 | To get more expressive failure messages, you should also implement the streaming operator as in the example above. 339 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/example/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace snowhouse; 4 | 5 | int main() 6 | { 7 | std::cout << "Testing that 23 is 23" << std::endl; 8 | Assert::That(23, Is().EqualTo(23)); 9 | 10 | try 11 | { 12 | AssertThat(12, Is().LessThan(11).And().GreaterThan(99)); 13 | } 14 | catch(const AssertionException& ex) 15 | { 16 | std::cout << "Apparently this failed:" << std::endl; 17 | std::cout << ex.GetMessage() << std::endl; 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/assert.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ASSERT_H 8 | #define IGLOO_ASSERT_H 9 | 10 | #include "stringize.h" 11 | #include "stringizers.h" 12 | 13 | namespace snowhouse { 14 | 15 | class Assert 16 | { 17 | public: 18 | 19 | template 20 | static void That(const ActualType& actual, ExpressionBuilder expression) 21 | { 22 | const char* no_file = ""; 23 | int line_number = 0; 24 | 25 | Assert::That(actual, expression, no_file, line_number); 26 | } 27 | 28 | template 29 | static void That(const ActualType& actual, ExpressionBuilder expression, const char* file_name, int line_number) 30 | { 31 | try 32 | { 33 | ResultStack result; 34 | OperatorStack operators; 35 | expression.Evaluate(result, operators, actual); 36 | 37 | while (!operators.empty()) 38 | { 39 | ConstraintOperator* op = operators.top(); 40 | op->PerformOperation(result); 41 | operators.pop(); 42 | } 43 | 44 | if (result.empty()) 45 | { 46 | throw InvalidExpressionException("The expression did not yield any result"); 47 | } 48 | 49 | if (!result.top()) 50 | { 51 | throw AssertionException(CreateErrorText(expression, actual), file_name, line_number); 52 | } 53 | } 54 | catch (const InvalidExpressionException& e) 55 | { 56 | throw AssertionException("Malformed expression: \"" + snowhouse::Stringize(expression) + "\"\n" + e.Message()); 57 | } 58 | } 59 | 60 | template 61 | static void That(const char* actual, ExpressionBuilder expression) 62 | { 63 | return That(std::string(actual), expression); 64 | } 65 | 66 | template 67 | static void That(const ActualType& actual, const ExpressionType& expression) 68 | { 69 | const char* no_file = ""; 70 | int no_line = 0; 71 | That(actual, expression, no_file, no_line); 72 | } 73 | 74 | template 75 | static void That(const ActualType& actual, const ExpressionType& expression, const char* file_name, int line_number) 76 | { 77 | if (!expression(actual)) 78 | { 79 | throw AssertionException(CreateErrorText(expression, actual), file_name, line_number); 80 | } 81 | } 82 | 83 | template 84 | static void That(const char* actual, const ExpressionType& expression) 85 | { 86 | return That(std::string(actual), expression); 87 | } 88 | 89 | static void That(bool actual) 90 | { 91 | if (!actual) 92 | { 93 | throw AssertionException("Expected: true\nActual: false"); 94 | } 95 | } 96 | 97 | static void Failure(const std::string& message) 98 | { 99 | throw AssertionException(message); 100 | } 101 | 102 | private: 103 | template 104 | static std::string CreateErrorText(const ExpectedType& expected, const ActualType& actual) 105 | { 106 | std::ostringstream str; 107 | 108 | str << "Expected: " << snowhouse::Stringize(expected) << std::endl; 109 | str << "Actual: " << snowhouse::Stringize(actual) << std::endl; 110 | 111 | return str.str(); 112 | } 113 | }; 114 | } 115 | 116 | #endif // IGLOO_ASSERT_H 117 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/assertionexception.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ASSERTIONEXCEPTION_H 8 | #define IGLOO_ASSERTIONEXCEPTION_H 9 | 10 | namespace snowhouse { 11 | class AssertionException : public std::exception 12 | { 13 | public: 14 | AssertionException(const std::string& message) 15 | : m_message(message), m_fileName(""), m_line(0) 16 | {} 17 | 18 | AssertionException(const std::string& message, const std::string& fileName, unsigned int line) 19 | : m_message(message), m_fileName(fileName), m_line(line) 20 | {} 21 | 22 | virtual ~AssertionException() throw() 23 | { 24 | } 25 | 26 | std::string GetMessage() const 27 | { 28 | return m_message; 29 | } 30 | 31 | std::string GetFilename() const 32 | { 33 | return m_fileName; 34 | } 35 | 36 | unsigned int GetLineNumber() const 37 | { 38 | return m_line; 39 | } 40 | 41 | private: 42 | std::string m_message; 43 | std::string m_fileName; 44 | unsigned int m_line; 45 | }; 46 | } 47 | 48 | #endif // IGLOO_ASSERTIONEXCEPTION_H 49 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/assertmacro.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ASSERTMACRO_H 8 | #define IGLOO_ASSERTMACRO_H 9 | 10 | #include "assert.h" 11 | 12 | #define AssertThat(p1,p2)\ 13 | Assert::That((p1), (p2), __FILE__, __LINE__);\ 14 | 15 | #endif // IGLOO_ASSERTMACRO_H 16 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/constraints.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_CONSTRAINTS_H 8 | #define IGLOO_CONSTRAINTS_H 9 | 10 | #include "containsconstraint.h" 11 | #include "endswithconstraint.h" 12 | #include "equalsconstraint.h" 13 | #include "haslengthconstraint.h" 14 | #include "isgreaterthanconstraint.h" 15 | #include "islessthanconstraint.h" 16 | #include "startswithconstraint.h" 17 | #include "fulfillsconstraint.h" 18 | #include "equalswithdeltaconstraint.h" 19 | #include "equalscontainerconstraint.h" 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/containsconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_CONTAINSCONSTRAINT_H 8 | #define IGLOO_CONTAINSCONSTRAINT_H 9 | 10 | #include 11 | 12 | #include "./expressions/expression.h" 13 | 14 | namespace snowhouse { 15 | 16 | template 17 | struct find_in_container_traits 18 | { 19 | template 20 | static bool find(const ContainerType& container, const ExpectedType& expected) 21 | { 22 | return std::find(container.begin(), container.end(), expected) != container.end(); 23 | } 24 | }; 25 | 26 | template 27 | struct find_in_container_traits > 28 | { 29 | template 30 | static bool find(const std::map& container, const ExpectedType& expected) 31 | { 32 | return container.find(expected) != container.end(); 33 | } 34 | }; 35 | 36 | template 37 | struct ContainsConstraint : Expression< ContainsConstraint > 38 | { 39 | ContainsConstraint(const ExpectedType& expected) 40 | : m_expected(expected) {} 41 | 42 | template 43 | bool operator()(const ActualType& actual) const 44 | { 45 | return find_in_container_traits::find(actual, m_expected); 46 | } 47 | 48 | bool operator()(const std::string& actual) const 49 | { 50 | return actual.find(m_expected) != actual.npos; 51 | } 52 | 53 | ExpectedType m_expected; 54 | }; 55 | 56 | template< typename ExpectedType > 57 | inline ContainsConstraint Contains(const ExpectedType& expected) 58 | { 59 | return ContainsConstraint(expected); 60 | } 61 | 62 | inline ContainsConstraint Contains(const char* expected) 63 | { 64 | return ContainsConstraint(expected); 65 | } 66 | 67 | template< typename ExpectedType > 68 | struct Stringizer< ContainsConstraint< ExpectedType > > 69 | { 70 | static std::string ToString(const ContainsConstraint& constraint) 71 | { 72 | std::ostringstream builder; 73 | builder << "contains " << snowhouse::Stringize(constraint.m_expected); 74 | 75 | return builder.str(); 76 | } 77 | }; 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/endswithconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ENDSWITHCONSTRAINT_H 8 | #define IGLOO_ENDSWITHCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template 15 | struct EndsWithConstraint : Expression< EndsWithConstraint > 16 | { 17 | EndsWithConstraint(const ExpectedType& expected) 18 | : m_expected(expected) {} 19 | 20 | bool operator()(const std::string& actual) const 21 | { 22 | size_t expectedPos = actual.length() - m_expected.length(); 23 | return actual.find(m_expected) == expectedPos; 24 | } 25 | 26 | ExpectedType m_expected; 27 | }; 28 | 29 | template< typename ExpectedType > 30 | inline EndsWithConstraint EndsWith(const ExpectedType& expected) 31 | { 32 | return EndsWithConstraint(expected); 33 | } 34 | 35 | inline EndsWithConstraint EndsWith(const char* expected) 36 | { 37 | return EndsWithConstraint(expected); 38 | } 39 | 40 | template< typename ExpectedType > 41 | struct Stringizer< EndsWithConstraint< ExpectedType > > 42 | { 43 | static std::string ToString(const EndsWithConstraint& constraint) 44 | { 45 | std::ostringstream builder; 46 | builder << "ends with " << snowhouse::Stringize(constraint.m_expected); 47 | 48 | return builder.str(); 49 | } 50 | }; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalsconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EQUALSCONSTRAINT_H 8 | #define IGLOO_EQUALSCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename ExpectedType > 15 | struct EqualsConstraint : Expression< EqualsConstraint > 16 | { 17 | EqualsConstraint(const ExpectedType& expected) 18 | : m_expected(expected) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return (m_expected == actual); 26 | } 27 | 28 | ExpectedType m_expected; 29 | }; 30 | 31 | template< typename ExpectedType > 32 | inline EqualsConstraint Equals(const ExpectedType& expected) 33 | { 34 | return EqualsConstraint(expected); 35 | } 36 | 37 | inline EqualsConstraint Equals(const char* expected) 38 | { 39 | return EqualsConstraint(expected); 40 | } 41 | 42 | inline EqualsConstraint IsFalse() 43 | { 44 | return EqualsConstraint(false); 45 | } 46 | 47 | inline EqualsConstraint IsTrue() 48 | { 49 | return EqualsConstraint(true); 50 | } 51 | 52 | template <> 53 | struct Stringizer< EqualsConstraint< bool > > 54 | { 55 | static std::string ToString(const EqualsConstraint& constraint) 56 | { 57 | return constraint.m_expected ? "true" : "false"; 58 | } 59 | }; 60 | 61 | template< typename ExpectedType > 62 | struct Stringizer< EqualsConstraint< ExpectedType > > 63 | { 64 | static std::string ToString(const EqualsConstraint& constraint) 65 | { 66 | std::ostringstream builder; 67 | builder << "equal to " << snowhouse::Stringize(constraint.m_expected); 68 | 69 | return builder.str(); 70 | } 71 | }; 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalscontainerconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EQUALSCONTAINERCONSTRAINT_H 8 | #define IGLOO_EQUALSCONTAINERCONSTRAINT_H 9 | 10 | namespace snowhouse { 11 | 12 | namespace constraint_internal { 13 | template 14 | inline bool default_comparer(const T& lhs, const T& rhs) 15 | { 16 | return lhs == rhs; 17 | } 18 | } 19 | 20 | template< typename ExpectedType, typename BinaryPredicate> 21 | struct EqualsContainerConstraint : Expression< EqualsContainerConstraint > 22 | { 23 | EqualsContainerConstraint(const ExpectedType& expected, const BinaryPredicate predicate) 24 | : expected_(expected), predicate_(predicate) 25 | {} 26 | 27 | template 28 | bool operator()(const ActualType& actual) const 29 | { 30 | typename ActualType::const_iterator actual_it; 31 | typename ExpectedType::const_iterator expected_it; 32 | 33 | for(actual_it = actual.begin(), expected_it = expected_.begin(); actual_it != actual.end() && expected_it != expected_.end(); actual_it++, expected_it++) 34 | { 35 | if(!predicate_(*actual_it, *expected_it)) 36 | { 37 | return false; 38 | } 39 | } 40 | 41 | return actual.size() == expected_.size(); 42 | } 43 | 44 | const ExpectedType expected_; 45 | const BinaryPredicate predicate_; 46 | 47 | private: 48 | EqualsContainerConstraint& operator=(const EqualsContainerConstraint&) { return *this; } 49 | }; 50 | 51 | template< typename ExpectedType> 52 | inline EqualsContainerConstraint EqualsContainer(const ExpectedType& expected) 53 | { 54 | return EqualsContainerConstraint(expected, constraint_internal::default_comparer); 55 | } 56 | 57 | template< typename ExpectedType, typename BinaryPredicate > 58 | inline EqualsContainerConstraint EqualsContainer(const ExpectedType& expected, const BinaryPredicate predicate) 59 | { 60 | return EqualsContainerConstraint(expected, predicate); 61 | } 62 | 63 | template< typename ExpectedType, typename BinaryPredicate > 64 | struct Stringizer< EqualsContainerConstraint > 65 | { 66 | static std::string ToString(const EqualsContainerConstraint& constraint) 67 | { 68 | std::ostringstream builder; 69 | builder << snowhouse::Stringize(constraint.expected_); 70 | return builder.str(); 71 | } 72 | }; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalswithdeltaconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EQUALSWITHDELTACONSTRAINT_H 8 | #define IGLOO_EQUALSWITHDELTACONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename ExpectedType, typename DeltaType > 15 | struct EqualsWithDeltaConstraint : Expression< EqualsWithDeltaConstraint > 16 | { 17 | EqualsWithDeltaConstraint(const ExpectedType& expected, const DeltaType& delta) 18 | : m_expected(expected), m_delta(delta) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return ((m_expected <= (actual + m_delta)) && (m_expected >= (actual - m_delta))); 26 | } 27 | 28 | ExpectedType m_expected; 29 | DeltaType m_delta; 30 | }; 31 | 32 | template< typename ExpectedType, typename DeltaType > 33 | inline EqualsWithDeltaConstraint EqualsWithDelta(const ExpectedType& expected, const DeltaType& delta) 34 | { 35 | return EqualsWithDeltaConstraint(expected, delta); 36 | } 37 | 38 | template< typename ExpectedType, typename DeltaType > 39 | struct Stringizer< EqualsWithDeltaConstraint< ExpectedType, DeltaType > > 40 | { 41 | static std::string ToString(const EqualsWithDeltaConstraint& constraint) 42 | { 43 | std::ostringstream builder; 44 | builder << "equal to " << snowhouse::Stringize(constraint.m_expected) << " (+/- " << snowhouse::Stringize(constraint.m_delta) << ")"; 45 | 46 | return builder.str(); 47 | } 48 | }; 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/andexpression.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ANDEXPRESSION_H 8 | #define IGLOO_ANDEXPRESSION_H 9 | 10 | #include "./expression_fwd.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename LeftExpression, typename RightExpression > 15 | struct AndExpression : Expression< AndExpression > 16 | { 17 | AndExpression(const LeftExpression& left, const RightExpression& right) 18 | : m_left(left) 19 | , m_right(right) 20 | { 21 | } 22 | 23 | template< typename ActualType > 24 | bool operator()(const ActualType& actual) const 25 | { 26 | return (m_left(actual) && m_right(actual)); 27 | } 28 | 29 | LeftExpression m_left; 30 | RightExpression m_right; 31 | }; 32 | 33 | template< typename LeftExpression, typename RightExpression > 34 | struct Stringizer< AndExpression > 35 | { 36 | static std::string ToString(const AndExpression& expression) 37 | { 38 | std::ostringstream builder; 39 | builder << Stringize(expression.m_left) << " and " << Stringize(expression.m_right); 40 | 41 | return builder.str(); 42 | } 43 | }; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EXPRESSION_H 8 | #define IGLOO_EXPRESSION_H 9 | 10 | #include "./notexpression.h" 11 | #include "./andexpression.h" 12 | #include "./orexpression.h" 13 | 14 | namespace snowhouse { 15 | 16 | template 17 | struct Expression 18 | { 19 | NotExpression operator!() const 20 | { 21 | return NotExpression(static_cast(*this)); 22 | } 23 | 24 | template< typename Right > 25 | AndExpression operator&&(const Right& right) const 26 | { 27 | return AndExpression(static_cast(*this), right); 28 | } 29 | 30 | template< typename Right > 31 | OrExpression operator||(const Right& right) const 32 | { 33 | return OrExpression(static_cast(*this), right); 34 | } 35 | }; 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression_fwd.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EXPRESSION_FWD_H 8 | #define IGLOO_EXPRESSION_FWD_H 9 | 10 | namespace snowhouse { 11 | template 12 | struct Expression; 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/notexpression.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_NOTEXPRESSION_H 8 | #define IGLOO_NOTEXPRESSION_H 9 | 10 | #include "./expression_fwd.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename ExpressionType > 15 | struct NotExpression : Expression< NotExpression > 16 | { 17 | NotExpression(const ExpressionType& expression) 18 | : m_expression(expression) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return !m_expression(actual); 26 | } 27 | 28 | ExpressionType m_expression; 29 | }; 30 | 31 | template< typename ExpressionType > 32 | struct Stringizer< NotExpression > 33 | { 34 | static std::string ToString(const NotExpression& expression) 35 | { 36 | std::ostringstream builder; 37 | builder << "not " << snowhouse::Stringize(expression.m_expression); 38 | 39 | return builder.str(); 40 | } 41 | }; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/orexpression.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_OREXPRESSION_H 8 | #define IGLOO_OREXPRESSION_H 9 | 10 | #include "./expression_fwd.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename LeftExpression, typename RightExpression > 15 | struct OrExpression : Expression< OrExpression > 16 | { 17 | OrExpression(const LeftExpression& left, const RightExpression& right) 18 | : m_left(left) 19 | , m_right(right) 20 | { 21 | } 22 | 23 | template< typename ActualType > 24 | bool operator()(const ActualType& actual) const 25 | { 26 | return (m_left(actual) || m_right(actual)); 27 | } 28 | 29 | LeftExpression m_left; 30 | RightExpression m_right; 31 | }; 32 | 33 | template< typename LeftExpression, typename RightExpression > 34 | struct Stringizer< OrExpression > 35 | { 36 | static std::string ToString(const OrExpression& expression) 37 | { 38 | std::ostringstream builder; 39 | builder << snowhouse::Stringize(expression.m_left) << " or " << snowhouse::Stringize(expression.m_right); 40 | 41 | return builder.str(); 42 | } 43 | }; 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/fulfillsconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef FULFILLSCONSTRAINT_H 8 | #define FULFILLSCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename MatcherType > 15 | struct FulfillsConstraint : Expression< FulfillsConstraint > 16 | { 17 | FulfillsConstraint(const MatcherType& matcher) 18 | : m_matcher(matcher) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return m_matcher.Matches(actual); 26 | } 27 | 28 | MatcherType m_matcher; 29 | }; 30 | 31 | template< typename MatcherType > 32 | inline FulfillsConstraint Fulfills(const MatcherType& matcher) 33 | { 34 | return FulfillsConstraint(matcher); 35 | } 36 | 37 | template< typename MatcherType > 38 | struct Stringizer< FulfillsConstraint< MatcherType > > 39 | { 40 | static std::string ToString(const FulfillsConstraint& constraint) 41 | { 42 | std::ostringstream builder; 43 | builder << snowhouse::Stringize(constraint.m_matcher); 44 | 45 | return builder.str(); 46 | } 47 | }; 48 | 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/haslengthconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_HASLENGTHCONSTRAINT_H 8 | #define IGLOO_HASLENGTHCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template 15 | struct HasLengthConstraint : Expression< HasLengthConstraint > 16 | { 17 | HasLengthConstraint(const ExpectedType& expected) 18 | : m_expected(expected) {} 19 | 20 | template 21 | bool operator()(const ActualType& actual) const 22 | { 23 | typedef typename ActualType::size_type SizeType; 24 | SizeType expectedSize = static_cast(m_expected); 25 | return (actual.size() == expectedSize); 26 | } 27 | 28 | ExpectedType m_expected; 29 | }; 30 | 31 | template< typename ExpectedType > 32 | inline HasLengthConstraint HasLength(const ExpectedType& expected) 33 | { 34 | return HasLengthConstraint(expected); 35 | } 36 | 37 | inline HasLengthConstraint IsEmpty() 38 | { 39 | return HasLength(0); 40 | } 41 | 42 | inline HasLengthConstraint HasLength(const char* expected) 43 | { 44 | return HasLengthConstraint(expected); 45 | } 46 | 47 | template< typename ExpectedType > 48 | struct Stringizer< HasLengthConstraint< ExpectedType > > 49 | { 50 | static std::string ToString(const HasLengthConstraint& constraint) 51 | { 52 | std::ostringstream builder; 53 | builder << "of length " << snowhouse::Stringize(constraint.m_expected); 54 | 55 | return builder.str(); 56 | } 57 | }; 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ISGREATERTHANCONSTRAINT_H 8 | #define IGLOO_ISGREATERTHANCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename ExpectedType > 15 | struct IsGreaterThanConstraint : Expression< IsGreaterThanConstraint > 16 | { 17 | IsGreaterThanConstraint(const ExpectedType& expected) 18 | : m_expected(expected) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return (actual > m_expected); 26 | } 27 | 28 | ExpectedType m_expected; 29 | }; 30 | 31 | template< typename ExpectedType > 32 | inline IsGreaterThanConstraint IsGreaterThan(const ExpectedType& expected) 33 | { 34 | return IsGreaterThanConstraint(expected); 35 | } 36 | 37 | inline IsGreaterThanConstraint IsGreaterThan(const char* expected) 38 | { 39 | return IsGreaterThanConstraint(expected); 40 | } 41 | 42 | template< typename ExpectedType > 43 | struct Stringizer< IsGreaterThanConstraint< ExpectedType > > 44 | { 45 | static std::string ToString(const IsGreaterThanConstraint& constraint) 46 | { 47 | std::ostringstream builder; 48 | builder << "greater than " << snowhouse::Stringize(constraint.m_expected); 49 | 50 | return builder.str(); 51 | } 52 | }; 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ISLESSTHANCONSTRAINT_H 8 | #define IGLOO_ISLESSTHANCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template< typename ExpectedType > 15 | struct IsLessThanConstraint : Expression< IsLessThanConstraint > 16 | { 17 | IsLessThanConstraint(const ExpectedType& expected) 18 | : m_expected(expected) 19 | { 20 | } 21 | 22 | template 23 | bool operator()(const ActualType& actual) const 24 | { 25 | return (actual < m_expected); 26 | } 27 | 28 | ExpectedType m_expected; 29 | }; 30 | 31 | template< typename ExpectedType > 32 | inline IsLessThanConstraint IsLessThan(const ExpectedType& expected) 33 | { 34 | return IsLessThanConstraint(expected); 35 | } 36 | 37 | inline IsLessThanConstraint IsLessThan(const char* expected) 38 | { 39 | return IsLessThanConstraint(expected); 40 | } 41 | 42 | template< typename ExpectedType > 43 | struct Stringizer< IsLessThanConstraint< ExpectedType > > 44 | { 45 | static std::string ToString(const IsLessThanConstraint& constraint) 46 | { 47 | std::ostringstream builder; 48 | builder << "less than " << snowhouse::Stringize(constraint.m_expected); 49 | 50 | return builder.str(); 51 | } 52 | }; 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/startswithconstraint.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_STARTSWITHCONSTRAINT_H 8 | #define IGLOO_STARTSWITHCONSTRAINT_H 9 | 10 | #include "./expressions/expression.h" 11 | 12 | namespace snowhouse { 13 | 14 | template 15 | struct StartsWithConstraint : Expression< StartsWithConstraint > 16 | { 17 | StartsWithConstraint(const ExpectedType& expected) 18 | : m_expected(expected) {} 19 | 20 | bool operator()(const std::string& actual) const 21 | { 22 | return actual.find(m_expected) == 0; 23 | } 24 | 25 | ExpectedType m_expected; 26 | }; 27 | 28 | template< typename ExpectedType > 29 | inline StartsWithConstraint StartsWith(const ExpectedType& expected) 30 | { 31 | return StartsWithConstraint(expected); 32 | } 33 | 34 | inline StartsWithConstraint StartsWith(const char* expected) 35 | { 36 | return StartsWithConstraint(expected); 37 | } 38 | 39 | template< typename ExpectedType > 40 | struct Stringizer< StartsWithConstraint< ExpectedType > > 41 | { 42 | static std::string ToString(const StartsWithConstraint& constraint) 43 | { 44 | std::ostringstream builder; 45 | builder << "starts with " << snowhouse::Stringize(constraint.m_expected); 46 | 47 | return builder.str(); 48 | } 49 | }; 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/exceptions.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EXCEPTIONS_H 8 | #define IGLOO_EXCEPTIONS_H 9 | 10 | #include "assert.h" 11 | 12 | namespace snowhouse { 13 | 14 | template 15 | class ExceptionStorage 16 | { 17 | public: 18 | static std::auto_ptr& last_exception() 19 | { 20 | static std::auto_ptr last; 21 | return last; 22 | } 23 | 24 | void compiler_thinks_i_am_unused() {} 25 | 26 | ~ExceptionStorage() 27 | { 28 | last_exception().reset(NULL); 29 | } 30 | }; 31 | 32 | template 33 | inline ExceptionType& LastException() 34 | { 35 | if(ExceptionStorage::last_exception().get() == NULL) 36 | { 37 | Assert::Failure("No exception was stored"); 38 | } 39 | 40 | return *(ExceptionStorage::last_exception().get()); 41 | } 42 | } 43 | 44 | #define IGLOO_CONCAT2(a, b) a##b 45 | #define IGLOO_CONCAT(a, b) IGLOO_CONCAT2(a, b) 46 | 47 | #define AssertThrows(EXCEPTION_TYPE, METHOD) \ 48 | ExceptionStorage IGLOO_CONCAT(IGLOO_storage_, __LINE__); IGLOO_CONCAT(IGLOO_storage_, __LINE__).compiler_thinks_i_am_unused(); \ 49 | { \ 50 | bool wrong_exception = false; \ 51 | bool no_exception = false; \ 52 | try \ 53 | { \ 54 | METHOD; \ 55 | no_exception = true; \ 56 | } \ 57 | catch (const EXCEPTION_TYPE& e) \ 58 | { \ 59 | ExceptionStorage::last_exception() = std::auto_ptr(new EXCEPTION_TYPE(e)); \ 60 | } \ 61 | catch(...) \ 62 | { \ 63 | wrong_exception = true; \ 64 | } \ 65 | if(no_exception) \ 66 | { \ 67 | std::ostringstream stm; \ 68 | stm << "Expected " << #EXCEPTION_TYPE << ". No exception was thrown."; \ 69 | Assert::Failure(stm.str()); \ 70 | } \ 71 | if(wrong_exception) \ 72 | { \ 73 | std::ostringstream stm; \ 74 | stm << "Expected " << #EXCEPTION_TYPE << ". Wrong exception was thrown."; \ 75 | Assert::Failure(stm.str()); \ 76 | } \ 77 | } 78 | 79 | #endif 80 | 81 | 82 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintadapter.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_CONSTRAINTADAPTER_H 8 | #define IGLOO_CONSTRAINTADAPTER_H 9 | 10 | namespace snowhouse { 11 | 12 | template 13 | struct ConstraintAdapter 14 | { 15 | ConstraintAdapter(const ConstraintType& constraint) : m_constraint(constraint) 16 | { 17 | } 18 | 19 | template 20 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 21 | { 22 | result.push(m_constraint(actual)); 23 | EvaluateConstraintList(list.m_tail, result, operators, actual); 24 | } 25 | 26 | ConstraintType m_constraint; 27 | }; 28 | 29 | template 30 | struct Stringizer< ConstraintAdapter > 31 | { 32 | static std::string ToString(const ConstraintAdapter& constraintAdapter) 33 | { 34 | return snowhouse::Stringize(constraintAdapter.m_constraint); 35 | } 36 | }; 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintlist.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_CONSTRAINT_H 8 | #define IGLOO_CONSTRAINT_H 9 | 10 | namespace snowhouse { 11 | 12 | struct ConstraintOperator; 13 | typedef std::stack ResultStack; 14 | typedef std::stack OperatorStack; 15 | 16 | template 17 | struct ConstraintList 18 | { 19 | typedef HT HeadType; 20 | typedef TT TailType; 21 | 22 | ConstraintList(const HeadType& head, const TailType& tail) 23 | : m_head(head), m_tail(tail) 24 | { 25 | } 26 | 27 | HeadType m_head; 28 | TailType m_tail; 29 | }; 30 | 31 | struct Nil 32 | { 33 | Nil() {} 34 | Nil(const Nil&) {} 35 | }; 36 | 37 | 38 | // ---- These structs defines the resulting types of list concatenation operations 39 | template 40 | struct type_concat 41 | { 42 | typedef ConstraintList::t> t; 43 | }; 44 | 45 | template struct type_concat { typedef L2 t; }; 46 | 47 | template inline L3 tr_concat(const Nil&, const Nil&) { return Nil(); } 48 | 49 | 50 | // ---- These structs define the concatenation operations. 51 | 52 | template 53 | struct ListConcat 54 | { 55 | static ResultList Concatenate(const LeftList& left, const RightList& right) 56 | { 57 | return ResultList(left.m_head, ListConcat::t>::Concatenate(left.m_tail, right)); 58 | } 59 | }; 60 | 61 | // Concatenating an empty list with a second list yields the second list 62 | template 63 | struct ListConcat 64 | { 65 | static ResultList Concatenate(const Nil&, const RightList& right) 66 | { 67 | return right; 68 | } 69 | 70 | }; 71 | 72 | // Concatenating two empty lists yields an empty list 73 | template 74 | struct ListConcat 75 | { 76 | static ResultList Concatenate(const Nil&, const Nil&) 77 | { 78 | return Nil(); 79 | } 80 | }; 81 | 82 | // ---- The concatenation operation 83 | 84 | template 85 | inline typename type_concat::t Concatenate(const L1& list1, const L2& list2) 86 | { 87 | return ListConcat::t>::Concatenate(list1, list2); 88 | } 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/expressionbuilder.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EXPRESSIONBUILDER_H 8 | #define IGLOO_EXPRESSIONBUILDER_H 9 | 10 | namespace snowhouse { 11 | 12 | // ---- Evaluation of list of constraints 13 | 14 | template 15 | inline void EvaluateConstraintList(ConstraintListType& constraint_list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 16 | { 17 | constraint_list.m_head.Evaluate(constraint_list, result, operators, actual); 18 | } 19 | 20 | template 21 | inline void EvaluateConstraintList(Nil&, ResultStack&, OperatorStack&, const ActualType&) {} 22 | 23 | 24 | template 25 | struct ExpressionBuilder 26 | { 27 | ExpressionBuilder(const ConstraintListType& list) : m_constraint_list(list) 28 | { 29 | } 30 | 31 | template 32 | ExpressionBuilder >, Nil> >::t> 33 | EqualTo(const ExpectedType& expected) 34 | { 35 | typedef ConstraintAdapter > ConstraintAdapterType; 36 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 37 | 38 | ConstraintAdapterType constraint(expected); 39 | ConstraintList node(constraint, Nil()); 40 | 41 | return BuilderType(Concatenate(m_constraint_list, node)); 42 | } 43 | 44 | template 45 | ExpressionBuilder >, Nil> >::t> 46 | EqualToWithDelta(const ExpectedType& expected, const DeltaType& delta) 47 | { 48 | typedef ConstraintAdapter > ConstraintAdapterType; 49 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 50 | 51 | ConstraintAdapterType constraint(EqualsWithDeltaConstraint(expected, delta)); 52 | ConstraintList node(constraint, Nil()); 53 | 54 | return BuilderType(Concatenate(m_constraint_list, node)); 55 | } 56 | 57 | template 58 | ExpressionBuilder >, Nil> >::t> 59 | Fulfilling(const MatcherType& matcher) 60 | { 61 | typedef ConstraintAdapter > ConstraintAdapterType; 62 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 63 | 64 | ConstraintAdapterType constraint(matcher); 65 | ConstraintList node(constraint, Nil()); 66 | 67 | return BuilderType(Concatenate(m_constraint_list, node)); 68 | } 69 | 70 | ExpressionBuilder >, Nil> >::t> 71 | False() 72 | { 73 | return EqualTo(false); 74 | } 75 | 76 | ExpressionBuilder >, Nil> >::t> 77 | True() 78 | { 79 | return EqualTo(true); 80 | } 81 | 82 | ExpressionBuilder >, Nil> >::t> 83 | EqualTo(const char* expected) 84 | { 85 | return EqualTo(std::string(expected)); 86 | } 87 | 88 | template 89 | ExpressionBuilder >, Nil> >::t> 90 | GreaterThan(const ExpectedType& expected) 91 | { 92 | typedef ConstraintAdapter > ConstraintAdapterType; 93 | 94 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 95 | ConstraintAdapterType constraint(expected); 96 | ConstraintList node(constraint, Nil()); 97 | return BuilderType(Concatenate(m_constraint_list, node)); 98 | } 99 | 100 | template 101 | ExpressionBuilder >, Nil> >::t> 102 | LessThan(const ExpectedType& expected) 103 | { 104 | typedef ConstraintAdapter > ConstraintAdapterType; 105 | 106 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 107 | ConstraintAdapterType constraint(expected); 108 | ConstraintList node(constraint, Nil()); 109 | return BuilderType(Concatenate(m_constraint_list, node)); 110 | } 111 | 112 | template 113 | ExpressionBuilder >, Nil> >::t> 114 | Containing(const ExpectedType& expected) 115 | { 116 | typedef ConstraintAdapter > ConstraintAdapterType; 117 | 118 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 119 | ConstraintAdapterType constraint(expected); 120 | ConstraintList node(constraint, Nil()); 121 | return BuilderType(Concatenate(m_constraint_list, node)); 122 | } 123 | 124 | ExpressionBuilder >, Nil> >::t> 125 | Containing(const char* expected) 126 | { 127 | return Containing(std::string(expected)); 128 | } 129 | 130 | template 131 | ExpressionBuilder >, Nil> >::t> 132 | EndingWith(const ExpectedType& expected) 133 | { 134 | typedef ConstraintAdapter > ConstraintAdapterType; 135 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 136 | 137 | ConstraintAdapterType constraint(expected); 138 | ConstraintList node(constraint, Nil()); 139 | return BuilderType(Concatenate(m_constraint_list, node)); 140 | } 141 | 142 | ExpressionBuilder >, Nil> >::t> 143 | EndingWith(const char* expected) 144 | { 145 | return EndingWith(std::string(expected)); 146 | } 147 | 148 | template 149 | ExpressionBuilder >, Nil> >::t> 150 | StartingWith(const ExpectedType& expected) 151 | { 152 | typedef ConstraintAdapter > ConstraintAdapterType; 153 | 154 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 155 | ConstraintAdapterType constraint(expected); 156 | ConstraintList node(constraint, Nil()); 157 | return BuilderType(Concatenate(m_constraint_list, node)); 158 | } 159 | 160 | ExpressionBuilder >, Nil> >::t> 161 | StartingWith(const char* expected) 162 | { 163 | return StartingWith(std::string(expected)); 164 | } 165 | 166 | template 167 | ExpressionBuilder >, Nil> >::t> 168 | OfLength(const ExpectedType& expected) 169 | { 170 | typedef ConstraintAdapter > ConstraintAdapterType; 171 | 172 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 173 | ConstraintAdapterType constraint(expected); 174 | ConstraintList node(constraint, Nil()); 175 | return BuilderType(Concatenate(m_constraint_list, node)); 176 | } 177 | 178 | ExpressionBuilder >, Nil> >::t> 179 | Empty() 180 | { 181 | typedef ConstraintAdapter > ConstraintAdapterType; 182 | 183 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 184 | ConstraintAdapterType constraint(0); 185 | ConstraintList node(constraint, Nil()); 186 | return BuilderType(Concatenate(m_constraint_list, node)); 187 | } 188 | 189 | template 190 | ExpressionBuilder >, Nil> >::t> 191 | EqualToContainer(const ExpectedType& expected) 192 | { 193 | typedef bool (*DefaultBinaryPredivateType)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&); 194 | typedef ConstraintAdapter > ConstraintAdapterType; 195 | 196 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 197 | ConstraintAdapterType constraint(EqualsContainerConstraint(expected, constraint_internal::default_comparer)); 198 | ConstraintList node(constraint, Nil()); 199 | return BuilderType(Concatenate(m_constraint_list, node)); 200 | } 201 | 202 | template 203 | ExpressionBuilder >, Nil> >::t> 204 | EqualToContainer(const ExpectedType& expected, const BinaryPredicate predicate) 205 | { 206 | typedef ConstraintAdapter > ConstraintAdapterType; 207 | 208 | typedef ExpressionBuilder< typename type_concat >::t > BuilderType; 209 | ConstraintAdapterType constraint(EqualsContainerConstraint(expected, predicate)); 210 | ConstraintList node(constraint, Nil()); 211 | return BuilderType(Concatenate(m_constraint_list, node)); 212 | } 213 | 214 | typedef ConstraintList AndOperatorNode; 215 | typedef ConstraintList OrOperatorNode; 216 | typedef ConstraintList NotOperatorNode; 217 | typedef ConstraintList AllOperatorNode; 218 | typedef ConstraintList AtLeastOperatorNode; 219 | typedef ConstraintList ExactlyOperatorNode; 220 | typedef ConstraintList AtMostOperatorNode; 221 | typedef ConstraintList NoneOperatorNode; 222 | 223 | ExpressionBuilder::t> All() 224 | { 225 | typedef ExpressionBuilder::t> BuilderType; 226 | AllOperator op; 227 | AllOperatorNode node(op, Nil()); 228 | return BuilderType(Concatenate(m_constraint_list, node)); 229 | } 230 | 231 | ExpressionBuilder::t> AtLeast(unsigned int expected) 232 | { 233 | typedef ExpressionBuilder::t> BuilderType; 234 | AtLeastOperator op(expected); 235 | AtLeastOperatorNode node(op, Nil()); 236 | return BuilderType(Concatenate(m_constraint_list, node)); 237 | } 238 | 239 | ExpressionBuilder::t> Exactly(unsigned int expected) 240 | { 241 | typedef ExpressionBuilder::t> BuilderType; 242 | ExactlyOperator op(expected); 243 | ExactlyOperatorNode node(op, Nil()); 244 | return BuilderType(Concatenate(m_constraint_list, node)); 245 | } 246 | 247 | ExpressionBuilder::t> AtMost(unsigned int expected) 248 | { 249 | typedef ExpressionBuilder::t> BuilderType; 250 | AtMostOperator op(expected); 251 | AtMostOperatorNode node(op, Nil()); 252 | return BuilderType(Concatenate(m_constraint_list, node)); 253 | } 254 | 255 | ExpressionBuilder::t> None() 256 | { 257 | typedef ExpressionBuilder::t> BuilderType; 258 | NoneOperator op; 259 | NoneOperatorNode node(op, Nil()); 260 | return BuilderType(Concatenate(m_constraint_list, node)); 261 | } 262 | 263 | ExpressionBuilder::t> And() 264 | { 265 | typedef ExpressionBuilder::t> BuilderType; 266 | AndOperator op; 267 | AndOperatorNode node(op, Nil()); 268 | return BuilderType(Concatenate(m_constraint_list, node)); 269 | } 270 | 271 | ExpressionBuilder::t> Or() 272 | { 273 | typedef ExpressionBuilder::t> BuilderType; 274 | OrOperator op; 275 | OrOperatorNode node(op, Nil()); 276 | return BuilderType(Concatenate(m_constraint_list, node)); 277 | } 278 | 279 | ExpressionBuilder::t> Not() 280 | { 281 | typedef ExpressionBuilder::t> BuilderType; 282 | NotOperator op; 283 | NotOperatorNode node(op, Nil()); 284 | return BuilderType(Concatenate(m_constraint_list, node)); 285 | } 286 | 287 | template 288 | void Evaluate(ResultStack& result, OperatorStack& operators, const ActualType& actual) 289 | { 290 | EvaluateConstraintList(m_constraint_list, result, operators, actual); 291 | } 292 | 293 | ConstraintListType m_constraint_list; 294 | }; 295 | 296 | template 297 | inline void StringizeConstraintList(const T& list, std::ostringstream& stm) 298 | { 299 | if (stm.tellp() > 0) 300 | stm << " "; 301 | 302 | stm << snowhouse::Stringize(list.m_head); 303 | StringizeConstraintList(list.m_tail, stm); 304 | } 305 | 306 | inline void StringizeConstraintList(const Nil&, std::ostringstream&) 307 | { 308 | } 309 | 310 | template 311 | struct Stringizer< ExpressionBuilder > 312 | { 313 | static std::string ToString(const ExpressionBuilder& builder) 314 | { 315 | std::ostringstream stm; 316 | StringizeConstraintList(builder.m_constraint_list, stm); 317 | 318 | return stm.str(); 319 | } 320 | }; 321 | } 322 | 323 | #endif 324 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/fluent.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_FLUENT_H 8 | #define IGLOO_FLUENT_H 9 | 10 | #include "constraintlist.h" 11 | #include "constraintadapter.h" 12 | #include "operators/constraintoperator.h" 13 | #include "operators/andoperator.h" 14 | #include "operators/oroperator.h" 15 | #include "operators/collections/collectionconstraintevaluator.h" 16 | #include "operators/collections/alloperator.h" 17 | #include "operators/collections/noneoperator.h" 18 | #include "operators/collections/atleastoperator.h" 19 | #include "operators/collections/exactlyoperator.h" 20 | #include "operators/collections/atmostoperator.h" 21 | #include "operators/notoperator.h" 22 | #include "expressionbuilder.h" 23 | 24 | namespace snowhouse { 25 | 26 | inline ExpressionBuilder Is() 27 | { 28 | return ExpressionBuilder(Nil()); 29 | } 30 | 31 | inline ExpressionBuilder Has() 32 | { 33 | return ExpressionBuilder(Nil()); 34 | } 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/andoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ANDOPERATOR_H 8 | #define IGLOO_ANDOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct AndOperator : public ConstraintOperator 13 | { 14 | template 15 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 16 | { 17 | EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result); 18 | 19 | operators.push(this); 20 | 21 | EvaluateConstraintList(list.m_tail, result, operators, actual); 22 | } 23 | 24 | void PerformOperation(ResultStack& result) 25 | { 26 | if(result.size() < 2) 27 | { 28 | throw InvalidExpressionException("The expression contains an and operator with too few operands"); 29 | } 30 | 31 | bool right = result.top(); 32 | result.pop(); 33 | bool left = result.top(); 34 | result.pop(); 35 | 36 | result.push(left && right); 37 | } 38 | 39 | int Precedence() const 40 | { 41 | return 3; 42 | } 43 | }; 44 | 45 | template<> 46 | struct Stringizer 47 | { 48 | static std::string ToString(const AndOperator&) 49 | { 50 | return "and"; 51 | } 52 | }; 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/alloperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ALLOPERATOR_H 8 | #define IGLOO_ALLOPERATOR_H 9 | 10 | #include "collectionoperator.h" 11 | 12 | namespace snowhouse { 13 | 14 | struct AllOperator : public CollectionOperator 15 | { 16 | template 17 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 18 | { 19 | unsigned int passed_elements = CollectionConstraintEvaluator::Evaluate(*this, list, result, operators, actual); 20 | 21 | result.push(passed_elements == actual.size()); 22 | } 23 | }; 24 | 25 | template<> 26 | struct Stringizer 27 | { 28 | static std::string ToString(const AllOperator&) 29 | { 30 | return "all"; 31 | } 32 | }; 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atleastoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ATLEASTOPERATOR_H 8 | #define IGLOO_ATLEASTOPERATOR_H 9 | 10 | #include "collectionoperator.h" 11 | 12 | namespace snowhouse { 13 | 14 | struct AtLeastOperator : public CollectionOperator 15 | { 16 | AtLeastOperator(unsigned int expected) : m_expected(expected) {} 17 | 18 | template 19 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 20 | { 21 | unsigned int passed_elements = CollectionConstraintEvaluator::Evaluate(*this, list, result, operators, actual); 22 | 23 | result.push(passed_elements >= m_expected); 24 | } 25 | 26 | unsigned int m_expected; 27 | }; 28 | 29 | template<> 30 | struct Stringizer 31 | { 32 | static std::string ToString(const AtLeastOperator& op) 33 | { 34 | std::ostringstream stm; 35 | stm << "at least " << op.m_expected; 36 | return stm.str(); 37 | } 38 | }; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atmostoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_ATMOSTOPERATOR_H 8 | #define IGLOO_ATMOSTOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct AtMostOperator : public CollectionOperator 13 | { 14 | AtMostOperator(unsigned int expected) : m_expected(expected) {} 15 | 16 | template 17 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 18 | { 19 | unsigned int passed_elements = CollectionConstraintEvaluator::Evaluate(*this, list, result, operators, actual); 20 | 21 | result.push(passed_elements <= m_expected); 22 | } 23 | 24 | unsigned int m_expected; 25 | }; 26 | 27 | template<> 28 | struct Stringizer 29 | { 30 | static std::string ToString(const AtMostOperator& op) 31 | { 32 | std::ostringstream stm; 33 | stm << "at most " << op.m_expected; 34 | return stm.str(); 35 | } 36 | }; 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubendv/sodiumpp/e0bb373542fb248c368f4795388d6c12749db1db/sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_COLLECTIONOPERATOR_H 8 | #define IGLOO_COLLECTIONOPERATOR_H 9 | 10 | namespace snowhouse { 11 | struct CollectionOperator : public ConstraintOperator 12 | { 13 | void PerformOperation(ResultStack&) 14 | { 15 | } 16 | 17 | int Precedence() const 18 | { 19 | return 1; 20 | } 21 | }; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/exactlyoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_EXACTLYOPERATOR_H 8 | #define IGLOO_EXACTLYOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct ExactlyOperator : public CollectionOperator 13 | { 14 | ExactlyOperator(unsigned int expected) : m_expected(expected) {} 15 | 16 | template 17 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 18 | { 19 | unsigned int passed_elements = CollectionConstraintEvaluator::Evaluate(*this, list, result, operators, actual); 20 | 21 | result.push(passed_elements == m_expected); 22 | } 23 | 24 | unsigned int m_expected; 25 | }; 26 | 27 | template<> 28 | struct Stringizer< ExactlyOperator > 29 | { 30 | static std::string ToString(const ExactlyOperator& op) 31 | { 32 | std::ostringstream stm; 33 | stm << "exactly " << op.m_expected; 34 | return stm.str(); 35 | } 36 | }; 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/noneoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_NONEOPERATOR_H 8 | #define IGLOO_NONEOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct NoneOperator : public CollectionOperator 13 | { 14 | template 15 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 16 | { 17 | unsigned int passed_elements = CollectionConstraintEvaluator::Evaluate(*this, list, result, operators, actual); 18 | result.push(passed_elements == 0); 19 | } 20 | }; 21 | 22 | template<> 23 | struct Stringizer 24 | { 25 | static std::string ToString(const NoneOperator&) 26 | { 27 | return "none"; 28 | } 29 | }; 30 | 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/constraintoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_CONTRAINTOPERATOR_H 8 | #define IGLOO_CONTRAINTOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct InvalidExpressionException 13 | { 14 | InvalidExpressionException(const std::string& message) : m_message(message) 15 | { 16 | } 17 | 18 | const std::string& Message() const 19 | { 20 | return m_message; 21 | } 22 | 23 | std::string m_message; 24 | }; 25 | 26 | struct ConstraintOperator 27 | { 28 | virtual ~ConstraintOperator() {} 29 | 30 | virtual void PerformOperation(ResultStack& result) = 0; 31 | virtual int Precedence() const = 0; 32 | 33 | template 34 | static bool EvaluateElementAgainstRestOfExpression(ConstraintListType& list, const ActualType& actual) 35 | { 36 | ResultStack innerResult; 37 | OperatorStack innerOperators; 38 | 39 | EvaluateConstraintList(list.m_tail, innerResult, innerOperators, actual); 40 | EvaluateAllOperatorsOnStack(innerOperators, innerResult); 41 | 42 | if(innerResult.empty()) 43 | { 44 | throw InvalidExpressionException("The expression after \"" + snowhouse::Stringize(list.m_head) + "\" operator does not yield any result"); 45 | } 46 | 47 | return innerResult.top(); 48 | } 49 | 50 | static void EvaluateOperatorsWithLessOrEqualPrecedence(const ConstraintOperator& op, OperatorStack& operators, ResultStack& result) 51 | { 52 | while(!operators.empty()) 53 | { 54 | ConstraintOperator* op_from_stack = operators.top(); 55 | 56 | if(op_from_stack->Precedence() > op.Precedence()) 57 | { 58 | break; 59 | } 60 | 61 | op_from_stack->PerformOperation(result); 62 | operators.pop(); 63 | } 64 | } 65 | 66 | static void EvaluateAllOperatorsOnStack(OperatorStack& operators, ResultStack& result) 67 | { 68 | while(!operators.empty()) 69 | { 70 | ConstraintOperator* op = operators.top(); 71 | op->PerformOperation(result); 72 | operators.pop(); 73 | } 74 | } 75 | }; 76 | 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/notoperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_NOTOPERATOR_H 8 | #define IGLOO_NOTOPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct NotOperator : public ConstraintOperator 13 | { 14 | template 15 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 16 | { 17 | EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result); 18 | 19 | operators.push(this); 20 | 21 | EvaluateConstraintList(list.m_tail, result, operators, actual); 22 | } 23 | 24 | void PerformOperation(ResultStack& result) 25 | { 26 | if(result.size() < 1) 27 | { 28 | throw InvalidExpressionException("The expression contains a not operator without any operand"); 29 | } 30 | 31 | bool right = result.top(); 32 | result.pop(); 33 | 34 | result.push(!right); 35 | } 36 | 37 | int Precedence() const 38 | { 39 | return 2; 40 | } 41 | }; 42 | 43 | template<> 44 | struct Stringizer 45 | { 46 | static std::string ToString(const NotOperator&) 47 | { 48 | return "not"; 49 | } 50 | }; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/oroperator.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_OROPERATOR_H 8 | #define IGLOO_OROPERATOR_H 9 | 10 | namespace snowhouse { 11 | 12 | struct OrOperator : public ConstraintOperator 13 | { 14 | template 15 | void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual) 16 | { 17 | EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result); 18 | 19 | operators.push(this); 20 | 21 | EvaluateConstraintList(list.m_tail, result, operators, actual); 22 | } 23 | 24 | void PerformOperation(ResultStack& result) 25 | { 26 | if(result.size() < 2) 27 | { 28 | throw InvalidExpressionException("The expression contains an or operator with too few operands"); 29 | } 30 | 31 | bool right = result.top(); 32 | result.pop(); 33 | bool left = result.top(); 34 | result.pop(); 35 | 36 | result.push(left || right); 37 | } 38 | 39 | int Precedence() const 40 | { 41 | return 4; 42 | } 43 | }; 44 | 45 | template<> 46 | struct Stringizer 47 | { 48 | static std::string ToString(const OrOperator&) 49 | { 50 | return "or"; 51 | } 52 | }; 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h: -------------------------------------------------------------------------------- 1 | #ifndef _SNOWHOUSE_H_JK_2013_06_28 2 | #define _SNOWHOUSE_H_JK_2013_06_28 3 | 4 | #define SNOWHOUSE_VERSION "1.0.2" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "stringize.h" 16 | #include "constraints/constraints.h" 17 | #include "fluent/fluent.h" 18 | #include "assertionexception.h" 19 | #include "assert.h" 20 | #include "assertmacro.h" 21 | #include "exceptions.h" 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/stringize.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_STRINGIZE_H 8 | #define IGLOO_STRINGIZE_H 9 | 10 | namespace snowhouse { 11 | namespace detail { 12 | 13 | // This type soaks up any implicit conversions and makes the following operator<< 14 | // less preferred than any other such operator found via ADL. 15 | struct any 16 | { 17 | // Conversion constructor for any type. 18 | template 19 | any(T const&); 20 | }; 21 | 22 | // A tag type returned by operator<< for the any struct in this namespace 23 | // when T does not support <<. 24 | struct tag {}; 25 | 26 | // Fallback operator<< for types T that don't support <<. 27 | tag operator<<(std::ostream&, any const&); 28 | 29 | // Two overloads to distinguish whether T supports a certain operator expression. 30 | // The first overload returns a reference to a two-element character array and is chosen if 31 | // T does not support the expression, such as <<, whereas the second overload returns a char 32 | // directly and is chosen if T supports the expression. So using sizeof(check()) 33 | // returns 2 for the first overload and 1 for the second overload. 34 | typedef char yes; 35 | typedef char (&no)[2]; 36 | 37 | no check(tag); 38 | 39 | template 40 | yes check(T const&); 41 | 42 | template 43 | struct is_output_streamable 44 | { 45 | static const T& x; 46 | static const bool value = sizeof(check(std::cout << x)) == sizeof(yes); 47 | }; 48 | 49 | template 50 | struct DefaultStringizer 51 | { 52 | static std::string ToString(const T& value) 53 | { 54 | std::ostringstream buf; 55 | buf << value; 56 | return buf.str(); 57 | } 58 | }; 59 | 60 | template 61 | struct DefaultStringizer 62 | { 63 | static std::string ToString(const T&) 64 | { 65 | return "[unsupported type]"; 66 | } 67 | }; 68 | } 69 | 70 | template 71 | struct Stringizer; 72 | 73 | template 74 | std::string Stringize(const T& value) 75 | { 76 | return Stringizer::ToString(value); 77 | } 78 | 79 | // NOTE: Specialize snowhouse::Stringizer to customize assertion messages 80 | template 81 | struct Stringizer 82 | { 83 | static std::string ToString(const T& value) 84 | { 85 | return detail::DefaultStringizer< T, detail::is_output_streamable::value >::ToString(value); 86 | } 87 | }; 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/assertion_frameworks/snowhouse/snowhouse/stringizers.h: -------------------------------------------------------------------------------- 1 | 2 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef IGLOO_STRINGIZERS_H 8 | #define IGLOO_STRINGIZERS_H 9 | 10 | namespace snowhouse 11 | { 12 | 13 | namespace detail 14 | { 15 | 16 | template 17 | struct SequentialContainerStringizer 18 | { 19 | static std::string 20 | ToString(const Container& cont) 21 | { 22 | std::ostringstream stm; 23 | typedef typename Container::const_iterator Iterator; 24 | 25 | stm << "[ "; 26 | for (Iterator it = cont.begin(); it != cont.end();) 27 | { 28 | stm << snowhouse::Stringize(*it); 29 | 30 | if (++it != cont.end()) 31 | { 32 | stm << ", "; 33 | } 34 | } 35 | stm << " ]"; 36 | return stm.str(); 37 | } 38 | }; 39 | } 40 | 41 | template 42 | struct Stringizer > : detail::SequentialContainerStringizer< 43 | std::vector > 44 | { 45 | }; 46 | 47 | template 48 | struct Stringizer > : detail::SequentialContainerStringizer< 49 | std::deque > 50 | { 51 | }; 52 | 53 | template 54 | struct Stringizer > : detail::SequentialContainerStringizer< 55 | std::list > 56 | { 57 | }; 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/bandit.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_BANDIT_H 2 | #define BANDIT_BANDIT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define BANDIT_VERSION "1.1.4" 12 | 13 | namespace bandit { namespace detail { 14 | typedef std::function voidfunc_t; 15 | }} 16 | 17 | #include 18 | using namespace snowhouse; 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/context.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_CONTEXT_H 2 | #define BANDIT_CONTEXT_H 3 | 4 | namespace bandit { 5 | namespace detail { 6 | 7 | class context 8 | { 9 | public: 10 | virtual ~context() {} 11 | virtual const std::string& name() = 0; 12 | virtual void execution_is_starting() = 0; 13 | virtual void register_before_each(voidfunc_t func) = 0; 14 | virtual void register_after_each(voidfunc_t func) = 0; 15 | virtual void run_before_eaches() = 0; 16 | virtual void run_after_eaches() = 0; 17 | virtual bool hard_skip() = 0; 18 | }; 19 | 20 | class bandit_context : public context 21 | { 22 | public: 23 | bandit_context(const char* desc, bool hard_skip) 24 | : desc_(desc), hard_skip_(hard_skip), is_executing_(false) 25 | {} 26 | 27 | const std::string& name() 28 | { 29 | return desc_; 30 | } 31 | 32 | void execution_is_starting() 33 | { 34 | is_executing_ = true; 35 | } 36 | 37 | void register_before_each(voidfunc_t func) 38 | { 39 | if(is_executing_) 40 | { 41 | throw test_run_error("before_each was called after 'describe' or 'it'"); 42 | } 43 | 44 | before_eaches_.push_back(func); 45 | } 46 | 47 | void register_after_each(voidfunc_t func) 48 | { 49 | if(is_executing_) 50 | { 51 | throw test_run_error("after_each was called after 'describe' or 'it'"); 52 | } 53 | 54 | after_eaches_.push_back(func); 55 | } 56 | 57 | void run_before_eaches() 58 | { 59 | run_all(before_eaches_); 60 | } 61 | 62 | void run_after_eaches() 63 | { 64 | run_all(after_eaches_); 65 | } 66 | 67 | bool hard_skip() 68 | { 69 | return hard_skip_; 70 | } 71 | 72 | private: 73 | void run_all(const std::list& funcs) 74 | { 75 | auto call_func = [](voidfunc_t f){ f(); }; 76 | 77 | for_each(funcs.begin(), funcs.end(), call_func); 78 | } 79 | 80 | private: 81 | std::string desc_; 82 | bool hard_skip_; 83 | bool is_executing_; 84 | std::list before_eaches_; 85 | std::list after_eaches_; 86 | }; 87 | typedef std::deque contextstack_t; 88 | 89 | inline contextstack_t& context_stack() 90 | { 91 | static contextstack_t contexts; 92 | return contexts; 93 | } 94 | } 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/failure_formatters/default_failure_formatter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_DEFAULT_FAILURE_FORMATTER_H 2 | #define BANDIT_DEFAULT_FAILURE_FORMATTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct default_failure_formatter : public failure_formatter 7 | { 8 | std::string format(const assertion_exception& err) const 9 | { 10 | std::stringstream ss; 11 | if(err.file_name().size()) 12 | { 13 | ss << err.file_name(); 14 | 15 | if(err.line_number()) 16 | { 17 | ss << ":" << err.line_number(); 18 | } 19 | 20 | ss << ": "; 21 | } 22 | 23 | ss << err.what(); 24 | 25 | return ss.str(); 26 | } 27 | }; 28 | }} 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/failure_formatters/failure_formatter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_FAILURE_FORMATTER_H 2 | #define BANDIT_FAILURE_FORMATTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct failure_formatter 7 | { 8 | virtual std::string format(const assertion_exception&) const = 0; 9 | }; 10 | typedef std::unique_ptr failure_formatter_ptr; 11 | }} 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/failure_formatters/failure_formatters.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_FAILURE_FORMATTERS 2 | #define BANDIT_FAILURE_FORMATTERS 3 | 4 | #include "failure_formatter.h" 5 | #include "default_failure_formatter.h" 6 | #include "visual_studio_failure_formatter.h" 7 | 8 | namespace bandit { namespace detail { 9 | inline failure_formatter& registered_failure_formatter() 10 | { 11 | static default_failure_formatter formatter; 12 | return formatter; 13 | } 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/failure_formatters/visual_studio_failure_formatter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_VISUAL_STUDIO_FAILURE_FORMATTER_H 2 | #define BANDIT_VISUAL_STUDIO_FAILURE_FORMATTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct visual_studio_failure_formatter : public failure_formatter 7 | { 8 | std::string format(const assertion_exception& err) const 9 | { 10 | std::stringstream ss; 11 | if(err.file_name().size()) 12 | { 13 | ss << err.file_name(); 14 | 15 | if(err.line_number()) 16 | { 17 | ss << "(" << err.line_number() << ")"; 18 | } 19 | 20 | ss << ": "; 21 | } 22 | else 23 | { 24 | ss << "bandit: "; 25 | } 26 | 27 | ss << err.what(); 28 | 29 | return ss.str(); 30 | 31 | } 32 | }; 33 | 34 | }} 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/grammar.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_GRAMMAR_H 2 | #define BANDIT_GRAMMAR_H 3 | 4 | namespace bandit { 5 | 6 | inline void describe(const char* desc, detail::voidfunc_t func, 7 | detail::listener& listener, detail::contextstack_t& context_stack, 8 | bool hard_skip = false) 9 | { 10 | listener.context_starting(desc); 11 | 12 | context_stack.back()->execution_is_starting(); 13 | 14 | detail::bandit_context ctxt(desc, hard_skip); 15 | 16 | context_stack.push_back(&ctxt); 17 | try 18 | { 19 | func(); 20 | } 21 | catch(const bandit::detail::test_run_error& error) 22 | { 23 | listener.test_run_error(desc, error); 24 | } 25 | 26 | context_stack.pop_back(); 27 | 28 | listener.context_ended(desc); 29 | } 30 | 31 | inline void describe(const char* desc, detail::voidfunc_t func) 32 | { 33 | describe(desc, func, detail::registered_listener(), detail::context_stack()); 34 | } 35 | 36 | inline void describe_skip(const char* desc, detail::voidfunc_t func, 37 | detail::listener& listener, detail::contextstack_t& context_stack) 38 | { 39 | bool skip = true; 40 | describe(desc, func, listener, context_stack, skip); 41 | } 42 | 43 | inline void describe_skip(const char* desc, detail::voidfunc_t func) 44 | { 45 | describe_skip(desc, func, detail::registered_listener(), 46 | detail::context_stack()); 47 | } 48 | 49 | inline void before_each(detail::voidfunc_t func, 50 | detail::contextstack_t& context_stack) 51 | { 52 | context_stack.back()->register_before_each(func); 53 | } 54 | 55 | inline void before_each(detail::voidfunc_t func) 56 | { 57 | before_each(func, detail::context_stack()); 58 | } 59 | 60 | inline void after_each(detail::voidfunc_t func, 61 | detail::contextstack_t& context_stack) 62 | { 63 | context_stack.back()->register_after_each(func); 64 | } 65 | 66 | inline void after_each(detail::voidfunc_t func) 67 | { 68 | after_each(func, detail::context_stack()); 69 | } 70 | 71 | inline void it_skip(const char* desc, detail::voidfunc_t, detail::listener& listener) 72 | { 73 | listener.it_skip(desc); 74 | } 75 | 76 | inline void it_skip(const char* desc, detail::voidfunc_t func) 77 | { 78 | it_skip(desc, func, detail::registered_listener()); 79 | } 80 | 81 | inline void it(const char* desc, detail::voidfunc_t func, detail::listener& listener, 82 | detail::contextstack_t& context_stack, 83 | bandit::adapters::assertion_adapter& assertion_adapter, 84 | const detail::run_policy& run_policy) 85 | { 86 | if(!run_policy.should_run(desc, context_stack)) 87 | { 88 | it_skip(desc, func, listener); 89 | return; 90 | } 91 | 92 | listener.it_starting(desc); 93 | 94 | context_stack.back()->execution_is_starting(); 95 | 96 | auto run_before_eaches = [&](){ 97 | for_each(context_stack.begin(), context_stack.end(), [](detail::context* ctxt){ 98 | ctxt->run_before_eaches(); 99 | }); 100 | }; 101 | 102 | auto run_after_eaches = [&](){ 103 | for_each(context_stack.begin(), context_stack.end(), [](detail::context* ctxt){ 104 | ctxt->run_after_eaches(); 105 | }); 106 | }; 107 | 108 | try 109 | { 110 | assertion_adapter.adapt_exceptions([&](){ 111 | run_before_eaches(); 112 | 113 | func(); 114 | listener.it_succeeded(desc); 115 | }); 116 | } 117 | catch(const bandit::detail::assertion_exception& ex) 118 | { 119 | listener.it_failed(desc, ex); 120 | } 121 | catch(...) 122 | { 123 | listener.it_unknown_error(desc); 124 | } 125 | 126 | try 127 | { 128 | run_after_eaches(); 129 | } 130 | catch(...) 131 | { 132 | listener.it_unknown_error(desc); 133 | } 134 | } 135 | 136 | inline void it(const char* desc, detail::voidfunc_t func) 137 | { 138 | it(desc, func, detail::registered_listener(), detail::context_stack(), 139 | detail::registered_adapter(), detail::registered_run_policy()); 140 | } 141 | 142 | 143 | } 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/listener.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_LISTENER_H 2 | #define BANDIT_LISTENER_H 3 | 4 | namespace bandit { namespace detail { 5 | struct listener 6 | { 7 | virtual ~listener() {} 8 | 9 | virtual void test_run_starting() = 0; 10 | virtual void test_run_complete() = 0; 11 | 12 | virtual void context_starting(const char* desc) = 0; 13 | virtual void context_ended(const char* desc) = 0; 14 | virtual void test_run_error(const char* desc, const test_run_error& error) = 0; 15 | 16 | virtual void it_starting(const char* desc) = 0; 17 | virtual void it_succeeded(const char* desc) = 0; 18 | virtual void it_failed(const char* desc, const detail::assertion_exception& ex) = 0; 19 | virtual void it_unknown_error(const char* desc) = 0; 20 | virtual void it_skip(const char* desc) = 0; 21 | 22 | virtual bool did_we_pass() const = 0; 23 | }; 24 | typedef std::unique_ptr listener_ptr; 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/options.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_OPTIONS_H 2 | #define BANDIT_OPTIONS_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | // TODO: print any unknown options 7 | // TODO: check for parser errors 8 | struct options 9 | { 10 | 11 | options(int argc, char* argv[]) 12 | { 13 | argc -= (argc>0); argv += (argc>0); // Skip program name (argv[0]) if present 14 | option::Stats stats(usage(), argc, argv); 15 | options_.resize(stats.options_max); 16 | std::vector buffer(stats.buffer_max); 17 | option::Parser parse(usage(), argc, argv, options_.data(), buffer.data()); 18 | parsed_ok_ = !parse.error(); 19 | } 20 | 21 | bool help() const 22 | { 23 | return options_[HELP] != NULL; 24 | } 25 | 26 | void print_usage() const 27 | { 28 | option::printUsage(std::cout, usage()); 29 | } 30 | 31 | bool version() const 32 | { 33 | return options_[VERSION] != NULL; 34 | } 35 | 36 | const char* reporter() const 37 | { 38 | return options_[REPORTER].arg; 39 | } 40 | 41 | bool no_color() const 42 | { 43 | return options_[NO_COLOR] != NULL; 44 | } 45 | 46 | typedef enum 47 | { 48 | FORMATTER_DEFAULT, 49 | FORMATTER_VS, 50 | FORMATTER_UNKNOWN 51 | } formatters; 52 | 53 | formatters formatter() const 54 | { 55 | std::string arg = options_[FORMATTER].arg ? options_[FORMATTER].arg : ""; 56 | if(arg == "vs") 57 | { 58 | return formatters::FORMATTER_VS; 59 | } 60 | 61 | return formatters::FORMATTER_DEFAULT; 62 | } 63 | 64 | const char* skip() const 65 | { 66 | return options_[SKIP].arg ? options_[SKIP].arg : ""; 67 | } 68 | 69 | const char* only() const 70 | { 71 | return options_[ONLY].arg ? options_[ONLY].arg : ""; 72 | } 73 | 74 | private: 75 | enum option_index { UNKNOWN, VERSION, HELP, REPORTER, NO_COLOR, 76 | FORMATTER, SKIP, ONLY }; 77 | 78 | static const option::Descriptor* usage() 79 | { 80 | static const option::Descriptor usage[] = 81 | { 82 | {UNKNOWN, 0, "", "", option::Arg::None, "USAGE: [options]\n\n" 83 | "Options:" }, 84 | {VERSION, 0, "", "version", option::Arg::None, " --version, \tPrint version of bandit"}, 85 | {HELP, 0, "", "help", option::Arg::None, " --help, \tPrint usage and exit."}, 86 | {REPORTER, 0, "", "reporter", option::Arg::Optional, " --reporter=, \tSelect reporter (dots, singleline, xunit, spec)"}, 87 | {NO_COLOR, 0, "", "no-color", option::Arg::None, " --no-color, \tSuppress colors in output"}, 88 | {FORMATTER, 0, "", "formatter", option::Arg::Optional, " --formatter=, \tSelect formatting of errors (default, vs)"}, 89 | {SKIP, 0, "", "skip", option::Arg::Optional, " --skip=, \tskip all 'describe' and 'it' containing substring"}, 90 | {ONLY, 0, "", "only", option::Arg::Optional, " --only=, \tonly run 'describe' and 'it' containing substring"}, 91 | {0, 0, 0, 0, 0, 0} 92 | }; 93 | 94 | return usage; 95 | } 96 | 97 | private: 98 | std::vector options_; 99 | bool parsed_ok_; 100 | 101 | }; 102 | 103 | }} 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/registration/registrar.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REGISTRAR_H 2 | #define BANDIT_REGISTRAR_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct spec_registrar 7 | { 8 | spec_registrar( bandit::detail::voidfunc_t func) 9 | { 10 | bandit::detail::specs().push_back(func); 11 | } 12 | }; 13 | 14 | }} 15 | 16 | #define go_bandit \ 17 | static bandit::detail::spec_registrar bandit_registrar 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/registration/registration.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REGISTRATION_H 2 | #define BANDIT_REGISTRATION_H 3 | 4 | #include 5 | #include 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/registration/spec_registry.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_SPEC_REGISTRY_H 2 | #define BANDIT_SPEC_REGISTRY_H 3 | 4 | namespace bandit { 5 | namespace detail { 6 | typedef std::list spec_registry; 7 | 8 | inline detail::spec_registry& specs() 9 | { 10 | static detail::spec_registry registry; 11 | return registry; 12 | } 13 | } 14 | 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/colorizer.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REPORTERS_COLORIZER_H 2 | #define BANDIT_REPORTERS_COLORIZER_H 3 | 4 | #ifdef _WIN32 5 | #ifndef MINGW32 6 | #define NOMINMAX 7 | #endif 8 | 9 | #define WIN32_LEAN_AND_MEAN 10 | #include 11 | #endif 12 | 13 | namespace bandit { namespace detail { 14 | 15 | #ifdef _WIN32 16 | struct colorizer 17 | { 18 | colorizer(bool colors_enabled = true) 19 | : colors_enabled_(colors_enabled), 20 | stdout_handle_(GetStdHandle(STD_OUTPUT_HANDLE)) 21 | { 22 | original_color_ = get_console_color(); 23 | } 24 | 25 | const char* green() const 26 | { 27 | if(colors_enabled_) 28 | { 29 | set_console_color(FOREGROUND_GREEN); 30 | } 31 | return ""; 32 | } 33 | 34 | const char* red() const 35 | { 36 | if(colors_enabled_) 37 | { 38 | set_console_color(FOREGROUND_RED); 39 | } 40 | return ""; 41 | } 42 | 43 | const char* reset() const 44 | { 45 | if(colors_enabled_) 46 | { 47 | set_console_color(original_color_); 48 | } 49 | return ""; 50 | } 51 | 52 | private: 53 | WORD get_console_color() const 54 | { 55 | CONSOLE_SCREEN_BUFFER_INFO info = {0}; 56 | GetConsoleScreenBufferInfo(stdout_handle_, &info); 57 | return info.wAttributes; 58 | } 59 | 60 | void set_console_color(WORD color) const 61 | { 62 | SetConsoleTextAttribute(stdout_handle_, color); 63 | } 64 | 65 | private: 66 | bool colors_enabled_; 67 | HANDLE stdout_handle_; 68 | WORD original_color_; 69 | }; 70 | 71 | #else 72 | struct colorizer 73 | { 74 | colorizer(bool colors_enabled = true) 75 | : colors_enabled_(colors_enabled) 76 | {} 77 | 78 | const char* green() const 79 | { 80 | return colors_enabled_ ? "\033[1;32m" : ""; 81 | } 82 | 83 | const char* red() const 84 | { 85 | return colors_enabled_ ? "\033[1;31m" : ""; 86 | } 87 | 88 | const char* reset() const 89 | { 90 | return colors_enabled_ ? "\033[0m" : ""; 91 | } 92 | 93 | private: 94 | bool colors_enabled_; 95 | }; 96 | #endif 97 | }} 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/dots_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_DOTS_REPORTER_H 2 | #define BANDIT_DOTS_REPORTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct dots_reporter : public progress_reporter 7 | { 8 | dots_reporter(std::ostream& stm, const failure_formatter& failure_formatter, 9 | const detail::colorizer& colorizer) 10 | : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer) 11 | {} 12 | 13 | dots_reporter(const failure_formatter& failure_formatter, const detail::colorizer& colorizer) 14 | : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer) 15 | {} 16 | 17 | dots_reporter& operator=(const dots_reporter&) { return *this; } 18 | 19 | void test_run_complete() 20 | { 21 | progress_reporter::test_run_complete(); 22 | 23 | stm_ << std::endl; 24 | 25 | test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_, 26 | test_run_errors_, colorizer_); 27 | summary.write(stm_); 28 | stm_.flush(); 29 | } 30 | 31 | void test_run_error(const char* desc, const struct test_run_error& err) 32 | { 33 | progress_reporter::test_run_error(desc, err); 34 | 35 | std::stringstream ss; 36 | ss << std::endl; 37 | ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl; 38 | 39 | test_run_errors_.push_back(ss.str()); 40 | } 41 | 42 | void it_succeeded(const char* desc) 43 | { 44 | progress_reporter::it_succeeded(desc); 45 | stm_ << colorizer_.green() << "." << colorizer_.reset(); 46 | stm_.flush(); 47 | } 48 | 49 | void it_failed(const char* desc, const assertion_exception& ex) 50 | { 51 | progress_reporter::it_failed(desc, ex); 52 | stm_ << colorizer_.red() << "F" << colorizer_.reset(); 53 | stm_.flush(); 54 | } 55 | 56 | void it_unknown_error(const char* desc) 57 | { 58 | progress_reporter::it_unknown_error(desc); 59 | stm_ << colorizer_.red() << "E" << colorizer_.reset(); 60 | stm_.flush(); 61 | } 62 | 63 | private: 64 | std::ostream& stm_; 65 | const detail::colorizer& colorizer_; 66 | }; 67 | }} 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/progress_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_PROGRESS_REPORTER_H 2 | #define BANDIT_PROGRESS_REPORTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct progress_reporter : public listener 7 | { 8 | progress_reporter(const detail::failure_formatter& failure_formatter) 9 | : specs_run_(0), specs_succeeded_(0), specs_failed_(0), specs_skipped_(0), 10 | failure_formatter_(failure_formatter) 11 | {} 12 | 13 | progress_reporter& operator=(const progress_reporter&) { return *this; } 14 | 15 | virtual void test_run_starting() 16 | { 17 | specs_run_ = 0; 18 | specs_succeeded_ = 0; 19 | specs_failed_ = 0; 20 | specs_skipped_ = 0; 21 | failures_.clear(); 22 | contexts_.clear(); 23 | } 24 | 25 | virtual void test_run_complete() 26 | { 27 | } 28 | 29 | virtual void context_starting(const char* desc) 30 | { 31 | contexts_.push_back(std::string(desc)); 32 | } 33 | 34 | virtual void context_ended(const char*) 35 | { 36 | contexts_.pop_back(); 37 | } 38 | 39 | virtual void test_run_error(const char*, const struct test_run_error&) 40 | {} 41 | 42 | void it_starting(const char*) 43 | { 44 | specs_run_++; 45 | } 46 | 47 | void it_succeeded(const char*) 48 | { 49 | specs_succeeded_++; 50 | } 51 | 52 | void it_failed(const char* desc, const assertion_exception& ex) 53 | { 54 | specs_failed_++; 55 | 56 | std::stringstream ss; 57 | ss << std::endl; 58 | ss << current_context_name() << " " << desc << ":" << std::endl; 59 | ss << failure_formatter_.format(ex); 60 | 61 | failures_.push_back(ss.str()); 62 | } 63 | 64 | void it_unknown_error(const char* desc) 65 | { 66 | specs_failed_++; 67 | 68 | std::stringstream ss; 69 | ss << std::endl; 70 | ss << current_context_name() << " " << desc << ":" << std::endl; 71 | ss << "Unknown exception"; 72 | ss << std::endl; 73 | 74 | failures_.push_back(ss.str()); 75 | } 76 | 77 | void it_skip(const char* /* desc */) 78 | { 79 | specs_skipped_++; 80 | } 81 | 82 | bool did_we_pass() const 83 | { 84 | return specs_run_ > 0 && specs_failed_ == 0 && test_run_errors_.size() == 0; 85 | } 86 | 87 | protected: 88 | std::string current_context_name() 89 | { 90 | std::string name; 91 | 92 | std::for_each(contexts_.begin(), contexts_.end(), [&](const std::string context){ 93 | if(name.size() > 0) 94 | { 95 | name += " "; 96 | } 97 | 98 | name += context; 99 | }); 100 | 101 | return name; 102 | } 103 | 104 | protected: 105 | int specs_run_; 106 | int specs_succeeded_; 107 | int specs_failed_; 108 | int specs_skipped_; 109 | const detail::failure_formatter& failure_formatter_; 110 | std::list contexts_; 111 | std::list failures_; 112 | std::list test_run_errors_; 113 | }; 114 | }} 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/reporters.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REPORTERS_H 2 | #define BANDIT_REPORTERS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace bandit { namespace detail { 13 | 14 | inline listener& registered_listener(listener* reporter = NULL) 15 | { 16 | static struct listener* reporter_; 17 | 18 | if(reporter) 19 | { 20 | reporter_ = reporter; 21 | } 22 | 23 | return *reporter_; 24 | } 25 | 26 | }} 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/single_line_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REPORTERS_SINGLE_LINE_REPORTER_H 2 | #define BANDIT_REPORTERS_SINGLE_LINE_REPORTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct single_line_reporter : public progress_reporter 7 | { 8 | single_line_reporter(std::ostream& stm, const failure_formatter& failure_formatter, 9 | const detail::colorizer& colorizer) 10 | : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer) 11 | {} 12 | 13 | single_line_reporter(const failure_formatter& failure_formatter, 14 | const detail::colorizer& colorizer) 15 | : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer) 16 | {} 17 | 18 | single_line_reporter& operator=(const single_line_reporter&) { return *this; } 19 | 20 | void test_run_complete() 21 | { 22 | progress_reporter::test_run_complete(); 23 | 24 | stm_ << std::endl; 25 | 26 | test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_, 27 | test_run_errors_, colorizer_); 28 | summary.write(stm_); 29 | } 30 | 31 | void test_run_error(const char* desc, const struct test_run_error& err) 32 | { 33 | progress_reporter::test_run_error(desc, err); 34 | 35 | std::stringstream ss; 36 | ss << std::endl; 37 | ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl; 38 | 39 | test_run_errors_.push_back(ss.str()); 40 | } 41 | 42 | void it_starting(const char* desc) 43 | { 44 | print_status_line(); 45 | progress_reporter::it_starting(desc); 46 | } 47 | 48 | void it_succeeded(const char* desc) 49 | { 50 | progress_reporter::it_succeeded(desc); 51 | print_status_line(); 52 | } 53 | 54 | void it_failed(const char* desc, const assertion_exception& ex) 55 | { 56 | progress_reporter::it_failed(desc, ex); 57 | print_status_line(); 58 | } 59 | 60 | void it_unknown_error(const char* desc) 61 | { 62 | progress_reporter::it_unknown_error(desc); 63 | print_status_line(); 64 | } 65 | 66 | private: 67 | void print_status_line() 68 | { 69 | stm_ << '\r'; 70 | stm_ << "Executed " << specs_run_ << " tests."; 71 | 72 | if(specs_failed_) 73 | { 74 | stm_ << " " << specs_succeeded_ << " succeeded. " << colorizer_.red() << specs_failed_ << 75 | " failed." << colorizer_.reset(); 76 | } 77 | stm_.flush(); 78 | } 79 | 80 | private: 81 | std::ostream& stm_; 82 | const detail::colorizer& colorizer_; 83 | }; 84 | }} 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/spec_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_SPEC_REPORTER_H 2 | #define BANDIT_SPEC_REPORTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct spec_reporter : public progress_reporter 7 | { 8 | spec_reporter(std::ostream& stm, const failure_formatter& failure_formatter, 9 | const detail::colorizer& colorizer) 10 | : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer), indentation_(0) 11 | {} 12 | 13 | spec_reporter(const failure_formatter& failure_formatter, const detail::colorizer& colorizer) 14 | : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer), indentation_(0) 15 | {} 16 | 17 | spec_reporter& operator=(const spec_reporter&) { return *this; } 18 | 19 | void test_run_complete() 20 | { 21 | progress_reporter::test_run_complete(); 22 | 23 | stm_ << std::endl; 24 | 25 | test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_, 26 | test_run_errors_, colorizer_); 27 | summary.write(stm_); 28 | stm_.flush(); 29 | } 30 | 31 | void test_run_error(const char* desc, const struct test_run_error& err) 32 | { 33 | progress_reporter::test_run_error(desc, err); 34 | 35 | std::stringstream ss; 36 | ss << std::endl; 37 | ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl; 38 | 39 | test_run_errors_.push_back(ss.str()); 40 | } 41 | 42 | virtual void context_starting(const char* desc) 43 | { 44 | progress_reporter::context_starting(desc); 45 | 46 | stm_ << indent(); 47 | stm_ << "describe " << desc << std::endl; 48 | increase_indent(); 49 | stm_.flush(); 50 | 51 | } 52 | 53 | virtual void context_ended(const char* desc) 54 | { 55 | progress_reporter::context_ended(desc); 56 | decrease_indent(); 57 | } 58 | 59 | virtual void it_starting(const char* desc) 60 | { 61 | progress_reporter::it_starting(desc); 62 | stm_ << indent() << "- it " << desc << " ... "; 63 | stm_.flush(); 64 | } 65 | 66 | virtual void it_succeeded(const char* desc) 67 | { 68 | progress_reporter::it_succeeded(desc); 69 | stm_ << colorizer_.green(); 70 | stm_ << "OK"; 71 | stm_ << colorizer_.reset(); 72 | stm_ << std::endl; 73 | stm_.flush(); 74 | } 75 | 76 | virtual void it_failed(const char* desc, const assertion_exception& ex) 77 | { 78 | progress_reporter::it_failed(desc, ex); 79 | stm_ << colorizer_.red(); 80 | stm_ << "FAILED"; 81 | stm_ << colorizer_.reset(); 82 | stm_ << std::endl; 83 | stm_.flush(); 84 | } 85 | 86 | virtual void it_unknown_error(const char* desc) 87 | { 88 | progress_reporter::it_unknown_error(desc); 89 | stm_ << colorizer_.red(); 90 | stm_ << "ERROR"; 91 | stm_ << colorizer_.reset(); 92 | stm_ << std::endl; 93 | stm_.flush(); 94 | } 95 | 96 | virtual void it_skip(const char* desc) 97 | { 98 | progress_reporter::it_skip(desc); 99 | stm_ << indent() << "- it " << desc << " ... SKIPPED" << std::endl; 100 | stm_.flush(); 101 | } 102 | 103 | private: 104 | void increase_indent() 105 | { 106 | indentation_++; 107 | } 108 | 109 | void decrease_indent() 110 | { 111 | indentation_--; 112 | } 113 | 114 | std::string indent() 115 | { 116 | return std::string(indentation_, '\t'); 117 | } 118 | 119 | private: 120 | std::ostream& stm_; 121 | const detail::colorizer& colorizer_; 122 | int indentation_; 123 | }; 124 | }} 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/test_run_summary.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_TEST_RUN_SUMMARY_H 2 | #define BANDIT_TEST_RUN_SUMMARY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct test_run_summary 7 | { 8 | test_run_summary(int specs_run, int specs_failed, int specs_succeeded, int specs_skipped, 9 | const std::list& failures, const std::list& test_run_errors, 10 | const detail::colorizer& colorizer) 11 | : specs_run_(specs_run), specs_succeeded_(specs_succeeded), specs_failed_(specs_failed), 12 | specs_skipped_(specs_skipped), failures_(failures), test_run_errors_(test_run_errors), 13 | colorizer_(colorizer) 14 | {} 15 | 16 | test_run_summary& operator=(const test_run_summary&) { return *this; } 17 | 18 | void write(std::ostream& stm) 19 | { 20 | if(specs_run_ == 0 && test_run_errors_.size() == 0) 21 | { 22 | stm << colorizer_.red(); 23 | stm << "Could not find any tests."; 24 | stm << colorizer_.reset(); 25 | stm << std::endl; 26 | return; 27 | } 28 | 29 | if(specs_failed_ == 0 && test_run_errors_.size() == 0) 30 | { 31 | stm << colorizer_.green(); 32 | stm << "Success!"; 33 | stm << colorizer_.reset(); 34 | stm << std::endl; 35 | } 36 | 37 | if(test_run_errors_.size() > 0) 38 | { 39 | std::for_each(test_run_errors_.begin(), test_run_errors_.end(), 40 | [&](const std::string& error){ 41 | stm << error << std::endl; 42 | }); 43 | } 44 | 45 | 46 | if(specs_failed_ > 0) 47 | { 48 | stm << colorizer_.red(); 49 | stm << "There were failures!"; 50 | stm << colorizer_.reset() << std::endl; 51 | std::for_each(failures_.begin(), failures_.end(), 52 | [&](const std::string& failure) { 53 | stm << failure << std::endl; 54 | }); 55 | stm << std::endl; 56 | } 57 | 58 | stm << "Test run complete. " << specs_run_ << " tests run. " << specs_succeeded_ << 59 | " succeeded."; 60 | 61 | if(specs_skipped_ > 0) 62 | { 63 | stm << " " << specs_skipped_ << " skipped."; 64 | } 65 | 66 | if(specs_failed_ > 0) 67 | { 68 | stm << " " << specs_failed_ << " failed."; 69 | } 70 | 71 | if(test_run_errors_.size() > 0) 72 | { 73 | stm << " " << test_run_errors_.size() << " test run errors."; 74 | } 75 | 76 | stm << std::endl; 77 | } 78 | 79 | private: 80 | int specs_run_; 81 | int specs_succeeded_; 82 | int specs_failed_; 83 | int specs_skipped_; 84 | std::list failures_; 85 | std::list test_run_errors_; 86 | const detail::colorizer& colorizer_; 87 | }; 88 | }} 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/reporters/xunit_reporter.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_REPORTERS_XUNIT_REPORTER_H 2 | #define BANDIT_REPORTERS_XUNIT_REPORTER_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct xunit_reporter : public progress_reporter 7 | { 8 | xunit_reporter(std::ostream& stm, const failure_formatter& formatter) 9 | : progress_reporter(formatter), stm_(stm) 10 | { 11 | } 12 | 13 | xunit_reporter(const failure_formatter& formatter) 14 | : progress_reporter(formatter), stm_(std::cout) 15 | { 16 | } 17 | 18 | void it_starting(const char* desc) 19 | { 20 | progress_reporter::it_starting(desc); 21 | work_stm_ << "\t\n"; 23 | } 24 | 25 | void it_succeeded(const char* desc) 26 | { 27 | progress_reporter::it_succeeded(desc); 28 | work_stm_ << "\t\n"; 29 | } 30 | 31 | void it_failed(const char* desc, const assertion_exception& ex) 32 | { 33 | progress_reporter::it_failed(desc, ex); 34 | work_stm_ << "\t\t\n"; 35 | work_stm_ << "\t\n"; 36 | } 37 | 38 | void it_unknown_error(const char* desc) 39 | { 40 | progress_reporter::it_unknown_error(desc); 41 | work_stm_ << "\t\t\n"; 42 | work_stm_ << "\t\n"; 43 | } 44 | 45 | void it_skip(const char* desc) 46 | { 47 | progress_reporter::it_skip(desc); 48 | work_stm_ << "\t\n"; 50 | work_stm_ << "\t\t\n"; 51 | work_stm_ << "\t\n"; 52 | } 53 | 54 | void test_run_complete() 55 | { 56 | stm_ << "\n"; 57 | stm_ << " 0) 61 | { 62 | stm_ << " skipped=\"" << specs_skipped_ << "\""; 63 | } 64 | 65 | stm_ << ">\n"; 66 | 67 | stm_ << work_stm_.str(); 68 | 69 | stm_ << "\n"; 70 | } 71 | 72 | private: 73 | std::string escape(const std::string& str) 74 | { 75 | std::stringstream stm; 76 | 77 | std::for_each(str.begin(), str.end(), [&](char c){ 78 | switch(c) 79 | { 80 | case '&': 81 | stm << "&"; 82 | break; 83 | case '<': 84 | stm << "<"; 85 | break; 86 | case '>': 87 | stm << ">"; 88 | break; 89 | case '\\': 90 | stm << "'"; 91 | break; 92 | case '\"': 93 | stm << """; 94 | break; 95 | default: 96 | stm << c; 97 | } 98 | }); 99 | 100 | return stm.str(); 101 | } 102 | 103 | private: 104 | std::ostream& stm_; 105 | std::stringstream work_stm_; 106 | }; 107 | }} 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/run_policies/always_run_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ALWAYS_RUN_POLICY_H 2 | #define BANDIT_ALWAYS_RUN_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct always_run_policy : public run_policy 7 | { 8 | bool should_run(const char* /* it_name */, const contextstack_t& /* contexts */) const 9 | { 10 | return true; 11 | } 12 | }; 13 | 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/run_policies/bandit_run_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_BANDIT_RUN_POLICY_H 2 | #define BANDIT_BANDIT_RUN_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct bandit_run_policy : public run_policy 7 | { 8 | bandit_run_policy(const char* skip_pattern, const char* only_pattern) 9 | : skip_pattern_(skip_pattern), only_pattern_(only_pattern) 10 | {} 11 | 12 | bool should_run(const char* it_name, const contextstack_t& contexts) const 13 | { 14 | // 15 | // Never run if a context has been marked as skip 16 | // using 'describe_skip' 17 | // 18 | if(has_context_with_hard_skip(contexts)) 19 | { 20 | return false; 21 | } 22 | 23 | // 24 | // Always run if no patterns have been specifed 25 | // 26 | if(!has_skip_pattern() && !has_only_pattern()) 27 | { 28 | return true; 29 | } 30 | 31 | if(has_only_pattern() && !has_skip_pattern()) 32 | { 33 | return context_matches_only_pattern(contexts) 34 | || matches_only_pattern(it_name); 35 | } 36 | 37 | if(has_skip_pattern() && !has_only_pattern()) 38 | { 39 | bool skip = context_matches_skip_pattern(contexts) || 40 | matches_skip_pattern(it_name); 41 | return !skip; 42 | } 43 | 44 | // 45 | // If we've come this far, both 'skip' and 'only' 46 | // have been specified. 47 | // 48 | // If our contexts match 'only' we're still good 49 | // regardless of whether there's a 'skip' somewhere 50 | // in the context stack as well. 51 | if(context_matches_only_pattern(contexts)) 52 | { 53 | // 54 | // We can still mark the current 'it' as 'skip' 55 | // and ignore it. We check that here. 56 | // 57 | return !matches_skip_pattern(it_name); 58 | } 59 | 60 | // 61 | // If we've gotten this far, the context matches 'skip' 62 | // We can still run this spec if it is specifically marked 63 | // as 'only'. 64 | // 65 | return matches_only_pattern(it_name); 66 | } 67 | 68 | private: 69 | bool has_context_with_hard_skip(const contextstack_t& contexts) const 70 | { 71 | contextstack_t::const_iterator it; 72 | for(it = contexts.begin(); it != contexts.end(); it++) 73 | { 74 | if((*it)->hard_skip()) 75 | { 76 | return true; 77 | } 78 | } 79 | 80 | return false; 81 | } 82 | 83 | bool has_only_pattern() const 84 | { 85 | return only_pattern_.size() > 0; 86 | } 87 | 88 | bool has_skip_pattern() const 89 | { 90 | return skip_pattern_.size() > 0; 91 | } 92 | 93 | bool context_matches_only_pattern(const contextstack_t& contexts) const 94 | { 95 | contextstack_t::const_iterator it; 96 | for(it = contexts.begin(); it != contexts.end(); it++) 97 | { 98 | if(matches_only_pattern((*it)->name())) 99 | { 100 | return true; 101 | } 102 | } 103 | 104 | return false; 105 | } 106 | 107 | bool context_matches_skip_pattern(const contextstack_t& contexts) const 108 | { 109 | contextstack_t::const_iterator it; 110 | for(it = contexts.begin(); it != contexts.end(); it++) 111 | { 112 | if(matches_skip_pattern((*it)->name())) 113 | { 114 | return true; 115 | } 116 | } 117 | 118 | return false; 119 | } 120 | 121 | bool matches_only_pattern(const char* name) const 122 | { 123 | std::string n(name); 124 | return matches_only_pattern(n); 125 | } 126 | 127 | bool matches_only_pattern(const std::string& name) const 128 | { 129 | return matches_pattern(name, only_pattern_); 130 | } 131 | 132 | bool matches_skip_pattern(const char* name) const 133 | { 134 | std::string n(name); 135 | return matches_skip_pattern(n); 136 | } 137 | 138 | bool matches_skip_pattern(const std::string& name) const 139 | { 140 | return matches_pattern(name, skip_pattern_); 141 | } 142 | 143 | bool matches_pattern(const std::string& name, const std::string& pattern) const 144 | { 145 | return name.find(pattern) != std::string::npos; 146 | } 147 | 148 | private: 149 | std::string skip_pattern_; 150 | std::string only_pattern_; 151 | }; 152 | 153 | }} 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/run_policies/never_run_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_NEVER_RUN_POLICY_H 2 | #define BANDIT_NEVER_RUN_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct never_run_policy : public run_policy 7 | { 8 | bool should_run(const char* /* it_name */, const contextstack_t& /* contexts */) const 9 | { 10 | return false; 11 | } 12 | }; 13 | }} 14 | #endif 15 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/run_policies/run_policies.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_RUN_POLICIES_H 2 | #define BANDIT_RUN_POLICIES_H 3 | 4 | #include "run_policy.h" 5 | #include "always_run_policy.h" 6 | #include "never_run_policy.h" 7 | #include "bandit_run_policy.h" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/run_policies/run_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_RUN_POLICY_H 2 | #define BANDIT_RUN_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct run_policy 7 | { 8 | virtual ~run_policy() {} 9 | virtual bool should_run(const char* it_name, const contextstack_t& contexts) const = 0; 10 | }; 11 | typedef std::unique_ptr run_policy_ptr; 12 | 13 | inline run_policy& registered_run_policy(run_policy* policy = NULL) 14 | { 15 | static struct run_policy* policy_; 16 | 17 | if(policy) 18 | { 19 | policy_ = policy; 20 | } 21 | 22 | return *policy_; 23 | } 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/runner.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_RUNNER_H 2 | #define BANDIT_RUNNER_H 3 | 4 | namespace bandit { 5 | 6 | namespace detail { 7 | 8 | inline run_policy_ptr create_run_policy(const options& opt) 9 | { 10 | return run_policy_ptr(new bandit_run_policy(opt.skip(), opt.only())); 11 | } 12 | 13 | inline listener_ptr create_reporter(const options& opt, 14 | const failure_formatter* formatter, const colorizer& colorizer) 15 | { 16 | std::string name(opt.reporter() ? opt.reporter() : ""); 17 | 18 | if(name == "singleline") 19 | { 20 | return std::unique_ptr(new single_line_reporter(*formatter, colorizer)); 21 | } 22 | 23 | if(name == "xunit") 24 | { 25 | return std::unique_ptr(new xunit_reporter(*formatter)); 26 | } 27 | 28 | if(name == "spec") 29 | { 30 | return std::unique_ptr(new spec_reporter(*formatter, colorizer)); 31 | } 32 | 33 | return std::unique_ptr(new dots_reporter(*formatter, colorizer)); 34 | } 35 | 36 | typedef std::function reporter_factory_fn; 37 | typedef std::function register_reporter_fn; 38 | 39 | inline failure_formatter_ptr create_formatter(const options& opt) 40 | { 41 | if(opt.formatter() == options::formatters::FORMATTER_VS) 42 | { 43 | return failure_formatter_ptr(new visual_studio_failure_formatter()); 44 | } 45 | 46 | return failure_formatter_ptr(new default_failure_formatter()); 47 | } 48 | } 49 | 50 | inline int run(const detail::options& opt, const detail::spec_registry& specs, 51 | detail::contextstack_t& context_stack, detail::listener& listener) 52 | { 53 | if(opt.help()) 54 | { 55 | opt.print_usage(); 56 | return 0; 57 | } 58 | 59 | if(opt.version()) 60 | { 61 | std::cout << "bandit version " << BANDIT_VERSION << std::endl; 62 | return 0; 63 | } 64 | 65 | auto call_func = [](const detail::voidfunc_t& func) { 66 | func(); 67 | }; 68 | 69 | listener.test_run_starting(); 70 | 71 | bool hard_skip = false; 72 | detail::bandit_context global_context("", hard_skip); 73 | context_stack.push_back(&global_context); 74 | 75 | for_each(specs.begin(), specs.end(), call_func); 76 | 77 | listener.test_run_complete(); 78 | 79 | return listener.did_we_pass() ? 0 : 1; 80 | } 81 | 82 | inline int run(int argc, char* argv[]) 83 | { 84 | detail::options opt(argc, argv); 85 | detail::failure_formatter_ptr formatter(create_formatter(opt)); 86 | bandit::detail::colorizer colorizer(!opt.no_color()); 87 | detail::listener_ptr reporter(create_reporter(opt, formatter.get(), colorizer)); 88 | 89 | detail::registered_listener(reporter.get()); 90 | 91 | detail::run_policy_ptr run_policy = create_run_policy(opt); 92 | registered_run_policy(run_policy.get()); 93 | 94 | return run(opt, detail::specs(), detail::context_stack(), *reporter); 95 | } 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/skip_policies/always_include_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ALWAYS_INCLUDE_POLICY_H 2 | #define BANDIT_ALWAYS_INCLUDE_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct always_include_policy : public skip_policy 7 | { 8 | bool should_skip(const char*) const 9 | { 10 | return false; 11 | } 12 | }; 13 | 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/skip_policies/always_skip_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_ALWAYS_SKIP_POLICY_H 2 | #define BANDIT_ALWAYS_SKIP_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct always_skip_policy : public skip_policy 7 | { 8 | bool should_skip(const char*) const 9 | { 10 | return true; 11 | } 12 | }; 13 | }} 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/skip_policies/name_contains_skip_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_NAME_CONTAINS_SKIP_POLICY_H 2 | #define BANDIT_NAME_CONTAINS_SKIP_POLICY_H 3 | 4 | namespace bandit { namespace detail { 5 | struct name_contains_skip_policy : public skip_policy 6 | { 7 | name_contains_skip_policy(const char* pattern) 8 | : pattern_(pattern) 9 | {} 10 | 11 | bool should_skip(const char* name) const 12 | { 13 | if(pattern_.size() == 0) 14 | { 15 | return false; 16 | } 17 | 18 | std::string n(name); 19 | bool skip = n.find(pattern_) != std::string::npos; 20 | return skip; 21 | } 22 | 23 | private: 24 | const std::string pattern_; 25 | }; 26 | }} 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/skip_policies/skip_policies.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_SKIP_POLICIES 2 | #define BANDIT_SKIP_POLICIES 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/skip_policies/skip_policy.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_SKIP_POLICY_H 2 | #define BANDIT_SKIP_POLICY_H 3 | 4 | namespace bandit { 5 | 6 | struct skip_policy 7 | { 8 | virtual bool should_skip(const char* name) const = 0; 9 | }; 10 | typedef std::unique_ptr skip_policy_ptr; 11 | 12 | namespace detail { 13 | 14 | inline skip_policy& registered_skip_policy(skip_policy* policy = NULL) 15 | { 16 | static struct skip_policy* policy_; 17 | 18 | if(policy) 19 | { 20 | policy_ = policy; 21 | } 22 | 23 | return *policy_; 24 | } 25 | } 26 | 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /sodiumpp/include/bandit/test_run_error.h: -------------------------------------------------------------------------------- 1 | #ifndef BANDIT_TEST_RUN_ERROR 2 | #define BANDIT_TEST_RUN_ERROR 3 | 4 | namespace bandit { namespace detail { 5 | 6 | struct test_run_error : public std::runtime_error 7 | { 8 | test_run_error(const char* message) : std::runtime_error(message) {} 9 | }; 10 | }} 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /sodiumpp/include/sodiumpp/z85.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Stanislav Artemkin . 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | * 27 | * Implementation of 32/Z85 specification (http://rfc.zeromq.org/spec:32/Z85) 28 | * Source repository: http://github.com/artemkin/z85 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #if defined (__cplusplus) 36 | extern "C" { 37 | #endif 38 | 39 | /******************************************************************************* 40 | * ZeroMQ Base-85 encoding/decoding functions with custom padding * 41 | *******************************************************************************/ 42 | 43 | /** 44 | * @brief Encodes 'inputSize' bytes from 'source' into 'dest'. 45 | * If 'inputSize' is not divisible by 4 with no remainder, 'source' is padded. 46 | * Destination buffer must be already allocated. Use Z85_encode_with_padding_bound() to 47 | * evaluate size of the destination buffer. 48 | * 49 | * @param source in, input buffer (binary string to be encoded) 50 | * @param dest out, destination buffer 51 | * @param inputSize in, number of bytes to be encoded 52 | * @return number of printable symbols written into 'dest' or 0 if something goes wrong 53 | */ 54 | size_t Z85_encode_with_padding(const char* source, char* dest, size_t inputSize); 55 | 56 | /** 57 | * @brief Decodes 'inputSize' printable symbols from 'source' into 'dest', 58 | * encoded with Z85_encode_with_padding(). 59 | * Destination buffer must be already allocated. Use Z85_decode_with_padding_bound() to 60 | * evaluate size of the destination buffer. 61 | * 62 | * @param source in, input buffer (printable string to be decoded) 63 | * @param dest out, destination buffer 64 | * @param inputSize in, number of symbols to be decoded 65 | * @return number of bytes written into 'dest' or 0 if something goes wrong 66 | */ 67 | size_t Z85_decode_with_padding(const char* source, char* dest, size_t inputSize); 68 | 69 | /** 70 | * @brief Evaluates a size of output buffer needed to encode 'size' bytes 71 | * into string of printable symbols using Z85_encode_with_padding(). 72 | * 73 | * @param size in, number of bytes to be encoded 74 | * @return minimal size of output buffer in bytes 75 | */ 76 | size_t Z85_encode_with_padding_bound(size_t size); 77 | 78 | /** 79 | * @brief Evaluates a size of output buffer needed to decode 'size' symbols 80 | * into binary string using Z85_decode_with_padding(). 81 | * 82 | * @param source in, input buffer (first symbol is read from 'source' to evaluate padding) 83 | * @param size in, number of symbols to be decoded 84 | * @return minimal size of output buffer in bytes 85 | */ 86 | size_t Z85_decode_with_padding_bound(const char* source, size_t size); 87 | 88 | 89 | 90 | /******************************************************************************* 91 | * ZeroMQ Base-85 encoding/decoding functions (specification compliant) * 92 | *******************************************************************************/ 93 | 94 | /** 95 | * @brief Encodes 'inputSize' bytes from 'source' into 'dest'. 96 | * If 'inputSize' is not divisible by 4 with no remainder, 0 is retured. 97 | * Destination buffer must be already allocated. Use Z85_encode_bound() to 98 | * evaluate size of the destination buffer. 99 | * 100 | * @param source in, input buffer (binary string to be encoded) 101 | * @param dest out, destination buffer 102 | * @param inputSize in, number of bytes to be encoded 103 | * @return number of printable symbols written into 'dest' or 0 if something goes wrong 104 | */ 105 | size_t Z85_encode(const char* source, char* dest, size_t inputSize); 106 | 107 | /** 108 | * @brief Decodes 'inputSize' printable symbols from 'source' into 'dest'. 109 | * If 'inputSize' is not divisible by 5 with no remainder, 0 is returned. 110 | * Destination buffer must be already allocated. Use Z85_decode_bound() to 111 | * evaluate size of the destination buffer. 112 | * 113 | * @param source in, input buffer (printable string to be decoded) 114 | * @param dest out, destination buffer 115 | * @param inputSize in, number of symbols to be decoded 116 | * @return number of bytes written into 'dest' or 0 if something goes wrong 117 | */ 118 | size_t Z85_decode(const char* source, char* dest, size_t inputSize); 119 | 120 | /** 121 | * @brief Evaluates a size of output buffer needed to encode 'size' bytes 122 | * into string of printable symbols using Z85_encode(). 123 | * 124 | * @param size in, number of bytes to be encoded 125 | * @return minimal size of output buffer in bytes 126 | */ 127 | size_t Z85_encode_bound(size_t size); 128 | 129 | /** 130 | * @brief Evaluates a size of output buffer needed to decode 'size' symbols 131 | * into binary string using Z85_decode(). 132 | * 133 | * @param size in, number of symbols to be decoded 134 | * @return minimal size of output buffer in bytes 135 | */ 136 | size_t Z85_decode_bound(size_t size); 137 | 138 | 139 | 140 | /******************************************************************************* 141 | * ZeroMQ Base-85 unsafe encoding/decoding functions (specification compliant) * 142 | *******************************************************************************/ 143 | 144 | /** 145 | * @brief Encodes bytes from [source;sourceEnd) range into 'dest'. 146 | * It can be used for implementation of your own padding scheme. 147 | * Preconditions: 148 | * - (sourceEnd - source) % 4 == 0 149 | * - destination buffer must be already allocated 150 | * 151 | * @param source in, begin of input buffer 152 | * @param sourceEnd in, end of input buffer (not included) 153 | * @param dest out, output buffer 154 | * @return a pointer immediately after last symbol written into the 'dest' 155 | */ 156 | char* Z85_encode_unsafe(const char* source, const char* sourceEnd, char* dest); 157 | 158 | /** 159 | * @brief Decodes symbols from [source;sourceEnd) range into 'dest'. 160 | * It can be used for implementation of your own padding scheme. 161 | * Preconditions: 162 | * - (sourceEnd - source) % 5 == 0 163 | * - destination buffer must be already allocated 164 | * 165 | * @param source in, begin of input buffer 166 | * @param sourceEnd in, end of input buffer (not included) 167 | * @param dest out, output buffer 168 | * @return a pointer immediately after last byte written into the 'dest' 169 | */ 170 | char* Z85_decode_unsafe(const char* source, const char* sourceEnd, char* dest); 171 | 172 | #if defined (__cplusplus) 173 | } 174 | #endif 175 | 176 | -------------------------------------------------------------------------------- /sodiumpp/include/sodiumpp/z85.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Stanislav Artemkin . 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | * 27 | * Implementation of 32/Z85 specification (http://rfc.zeromq.org/spec:32/Z85) 28 | * Source repository: http://github.com/artemkin/z85 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | 36 | // Used to forbid implicit std::string construction from const char* 37 | #if __cplusplus > 199711L // if C++11 38 | #define Z85_DELETE_FUNCTION_DEFINITION = delete 39 | #else 40 | #define Z85_DELETE_FUNCTION_DEFINITION 41 | #endif 42 | 43 | namespace z85 44 | { 45 | 46 | /******************************************************************************* 47 | * ZeroMQ Base-85 encoding/decoding functions with custom padding * 48 | *******************************************************************************/ 49 | 50 | /** 51 | * @brief Encodes 'inputSize' bytes from 'source'. 52 | * If 'inputSize' is not divisible by 4 with no remainder, 'source' is padded. 53 | * 54 | * @param source in, input buffer (binary string to be encoded) 55 | * @param inputSize in, number of bytes to be encoded 56 | * @return printable string 57 | */ 58 | std::string encode_with_padding(const char* source, size_t inputSize); 59 | std::string encode_with_padding(const std::string& source); 60 | 61 | std::string encode_with_padding(const char*) Z85_DELETE_FUNCTION_DEFINITION; 62 | 63 | /** 64 | * @brief Decodes 'inputSize' printable symbols from 'source', 65 | * encoded with encode_with_padding(). 66 | * 67 | * @param source in, input buffer (printable string to be decoded) 68 | * @param inputSize in, number of symbols to be decoded 69 | * @return decoded string 70 | */ 71 | std::string decode_with_padding(const char* source, size_t inputSize); 72 | std::string decode_with_padding(const std::string& source); 73 | 74 | std::string decode_with_padding(const char*) Z85_DELETE_FUNCTION_DEFINITION; 75 | 76 | 77 | /******************************************************************************* 78 | * ZeroMQ Base-85 encoding/decoding functions (specification compliant) * 79 | *******************************************************************************/ 80 | 81 | /** 82 | * @brief Encodes 'inputSize' bytes from 'source'. 83 | * If 'inputSize' is not divisible by 4 with no remainder, empty string is retured. 84 | * 85 | * @param source in, input buffer (binary string to be encoded) 86 | * @param inputSize in, number of bytes to be encoded 87 | * @return printable string 88 | */ 89 | std::string encode(const char* source, size_t inputSize); 90 | std::string encode(const std::string& source); 91 | 92 | std::string encode(const char*) Z85_DELETE_FUNCTION_DEFINITION; 93 | 94 | /** 95 | * @brief Decodes 'inputSize' printable symbols from 'source'. 96 | * If 'inputSize' is not divisible by 5 with no remainder, empty string is returned. 97 | * 98 | * @param source in, input buffer (printable string to be decoded) 99 | * @param inputSize in, number of symbols to be decoded 100 | * @return decoded string 101 | */ 102 | std::string decode(const char* source, size_t inputSize); 103 | std::string decode(const std::string& source); 104 | 105 | std::string decode(const char*) Z85_DELETE_FUNCTION_DEFINITION; 106 | 107 | } // namespace z85 108 | 109 | #undef Z85_DELETE_FUNCTION_DEFINITION 110 | 111 | -------------------------------------------------------------------------------- /sodiumpp/sodiumpp.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Ruben De Visscher 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // 1. Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // 2. Redistributions in binary form must reproduce the above copyright notice, 10 | // this list of conditions and the following disclaimer in the documentation 11 | // and/or other materials provided with the distribution. 12 | // 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #include 25 | #include 26 | 27 | std::string sodiumpp::crypto_auth(const std::string &m,const std::string &k) 28 | { 29 | if (k.size() != crypto_auth_KEYBYTES) throw std::invalid_argument("incorrect key length"); 30 | unsigned char a[crypto_auth_BYTES]; 31 | ::crypto_auth(a,(const unsigned char *) m.c_str(),m.size(),(const unsigned char *) k.c_str()); 32 | return std::string((char *) a,crypto_auth_BYTES); 33 | } 34 | 35 | void sodiumpp::crypto_auth_verify(const std::string &a,const std::string &m,const std::string &k) 36 | { 37 | if (k.size() != crypto_auth_KEYBYTES) throw std::invalid_argument("incorrect key length"); 38 | if (a.size() != crypto_auth_BYTES) throw std::invalid_argument("incorrect authenticator length"); 39 | if (::crypto_auth_verify( 40 | (const unsigned char *) a.c_str(), 41 | (const unsigned char *) m.c_str(),m.size(), 42 | (const unsigned char *) k.c_str()) == 0) return; 43 | throw sodiumpp::crypto_error("invalid authenticator"); 44 | } 45 | 46 | std::string sodiumpp::crypto_box(const std::string &m,const std::string &n,const std::string &pk,const std::string &sk) 47 | { 48 | if (pk.size() != crypto_box_PUBLICKEYBYTES) throw std::invalid_argument("incorrect public-key length"); 49 | if (sk.size() != crypto_box_SECRETKEYBYTES) throw std::invalid_argument("incorrect secret-key length"); 50 | if (n.size() != crypto_box_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 51 | size_t mlen = m.size() + crypto_box_ZEROBYTES; 52 | unsigned char mpad[mlen]; 53 | for (size_t i = 0;i < crypto_box_ZEROBYTES;++i) mpad[i] = 0; 54 | for (size_t i = crypto_box_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_box_ZEROBYTES]; 55 | unsigned char cpad[mlen]; 56 | ::crypto_box(cpad,mpad,mlen, 57 | (const unsigned char *) n.c_str(), 58 | (const unsigned char *) pk.c_str(), 59 | (const unsigned char *) sk.c_str() 60 | ); 61 | return std::string( 62 | (char *) cpad + crypto_box_BOXZEROBYTES, 63 | mlen - crypto_box_BOXZEROBYTES 64 | ); 65 | } 66 | 67 | std::string sodiumpp::crypto_box_keypair(std::string& sk_string) 68 | { 69 | unsigned char pk[crypto_box_PUBLICKEYBYTES]; 70 | sk_string.resize(crypto_box_SECRETKEYBYTES, 0); 71 | ::crypto_box_keypair(pk,(unsigned char *)&sk_string[0]); 72 | return std::string((char *) pk,sizeof pk); 73 | } 74 | 75 | std::string sodiumpp::crypto_box_beforenm(const std::string &pk, const std::string &sk) { 76 | if (pk.size() != crypto_box_PUBLICKEYBYTES) throw std::invalid_argument("incorrect public-key length"); 77 | if (sk.size() != crypto_box_SECRETKEYBYTES) throw std::invalid_argument("incorrect secret-key length"); 78 | std::string k(crypto_box_BEFORENMBYTES, 0); 79 | ::crypto_box_beforenm((unsigned char *)&k[0], (const unsigned char *)&pk[0], (const unsigned char *)&sk[0]); 80 | return k; 81 | } 82 | 83 | std::string sodiumpp::crypto_box_afternm(const std::string &m,const std::string &n,const std::string &k) { 84 | if (k.size() != crypto_box_BEFORENMBYTES) throw std::invalid_argument("incorrect nm-key length"); 85 | if (n.size() != crypto_box_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 86 | size_t mlen = m.size() + crypto_box_ZEROBYTES; 87 | unsigned char mpad[mlen]; 88 | for (size_t i = 0;i < crypto_box_ZEROBYTES;++i) mpad[i] = 0; 89 | for (size_t i = crypto_box_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_box_ZEROBYTES]; 90 | unsigned char cpad[mlen]; 91 | ::crypto_box_afternm(cpad,mpad,mlen, 92 | (const unsigned char *) n.c_str(), 93 | (const unsigned char *) k.c_str() 94 | ); 95 | return std::string( 96 | (char *) cpad + crypto_box_BOXZEROBYTES, 97 | mlen - crypto_box_BOXZEROBYTES 98 | ); 99 | } 100 | 101 | std::string sodiumpp::crypto_box_open_afternm(const std::string &c,const std::string &n,const std::string &k) 102 | { 103 | if (k.size() != crypto_box_BEFORENMBYTES) throw std::invalid_argument("incorrect nm-key length"); 104 | if (n.size() != crypto_box_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 105 | size_t clen = c.size() + crypto_box_BOXZEROBYTES; 106 | unsigned char cpad[clen]; 107 | for (size_t i = 0;i < crypto_box_BOXZEROBYTES;++i) cpad[i] = 0; 108 | for (size_t i = crypto_box_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES]; 109 | unsigned char mpad[clen]; 110 | if (::crypto_box_open_afternm(mpad,cpad,clen, 111 | (const unsigned char *) n.c_str(), 112 | (const unsigned char *) k.c_str() 113 | ) != 0) 114 | throw sodiumpp::crypto_error("ciphertext fails verification"); 115 | if (clen < crypto_box_ZEROBYTES) 116 | throw sodiumpp::crypto_error("ciphertext too short"); // should have been caught by _open 117 | return std::string( 118 | (char *) mpad + crypto_box_ZEROBYTES, 119 | clen - crypto_box_ZEROBYTES 120 | ); 121 | } 122 | 123 | std::string sodiumpp::crypto_box_open(const std::string &c,const std::string &n,const std::string &pk,const std::string &sk) 124 | { 125 | if (pk.size() != crypto_box_PUBLICKEYBYTES) throw std::invalid_argument("incorrect public-key length"); 126 | if (sk.size() != crypto_box_SECRETKEYBYTES) throw std::invalid_argument("incorrect secret-key length"); 127 | if (n.size() != crypto_box_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 128 | size_t clen = c.size() + crypto_box_BOXZEROBYTES; 129 | unsigned char cpad[clen]; 130 | for (size_t i = 0;i < crypto_box_BOXZEROBYTES;++i) cpad[i] = 0; 131 | for (size_t i = crypto_box_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES]; 132 | unsigned char mpad[clen]; 133 | if (::crypto_box_open(mpad,cpad,clen, 134 | (const unsigned char *) n.c_str(), 135 | (const unsigned char *) pk.c_str(), 136 | (const unsigned char *) sk.c_str() 137 | ) != 0) 138 | throw sodiumpp::crypto_error("ciphertext fails verification"); 139 | if (clen < crypto_box_ZEROBYTES) 140 | throw sodiumpp::crypto_error("ciphertext too short"); // should have been caught by _open 141 | return std::string( 142 | (char *) mpad + crypto_box_ZEROBYTES, 143 | clen - crypto_box_ZEROBYTES 144 | ); 145 | } 146 | 147 | std::string sodiumpp::crypto_hash(const std::string &m) 148 | { 149 | unsigned char h[crypto_hash_BYTES]; 150 | ::crypto_hash(h,(const unsigned char *) m.c_str(),m.size()); 151 | return std::string((char *) h,sizeof h); 152 | } 153 | 154 | std::string sodiumpp::crypto_onetimeauth(const std::string &m,const std::string &k) 155 | { 156 | if (k.size() != crypto_onetimeauth_KEYBYTES) throw std::invalid_argument("incorrect key length"); 157 | unsigned char a[crypto_onetimeauth_BYTES]; 158 | ::crypto_onetimeauth(a,(const unsigned char *) m.c_str(),m.size(),(const unsigned char *) k.c_str()); 159 | return std::string((char *) a,crypto_onetimeauth_BYTES); 160 | } 161 | 162 | void sodiumpp::crypto_onetimeauth_verify(const std::string &a,const std::string &m,const std::string &k) 163 | { 164 | if (k.size() != crypto_onetimeauth_KEYBYTES) throw std::invalid_argument("incorrect key length"); 165 | if (a.size() != crypto_onetimeauth_BYTES) throw std::invalid_argument("incorrect authenticator length"); 166 | if (::crypto_onetimeauth_verify( 167 | (const unsigned char *) a.c_str(), 168 | (const unsigned char *) m.c_str(),m.size(), 169 | (const unsigned char *) k.c_str()) == 0) return; 170 | throw sodiumpp::crypto_error("invalid authenticator"); 171 | } 172 | 173 | std::string sodiumpp::crypto_scalarmult_base(const std::string &n) 174 | { 175 | unsigned char q[crypto_scalarmult_BYTES]; 176 | if (n.size() != crypto_scalarmult_SCALARBYTES) throw std::invalid_argument("incorrect scalar length"); 177 | ::crypto_scalarmult_base(q,(const unsigned char *) n.c_str()); 178 | return std::string((char *) q,sizeof q); 179 | } 180 | 181 | std::string sodiumpp::crypto_scalarmult(const std::string &n,const std::string &p) 182 | { 183 | unsigned char q[crypto_scalarmult_BYTES]; 184 | if (n.size() != crypto_scalarmult_SCALARBYTES) throw std::invalid_argument("incorrect scalar length"); 185 | if (p.size() != crypto_scalarmult_BYTES) throw std::invalid_argument("incorrect element length"); 186 | ::crypto_scalarmult(q,(const unsigned char *) n.c_str(),(const unsigned char *) p.c_str()); 187 | return std::string((char *) q,sizeof q); 188 | } 189 | 190 | std::string sodiumpp::crypto_secretbox(const std::string &m,const std::string &n,const std::string &k) 191 | { 192 | if (k.size() != crypto_secretbox_KEYBYTES) throw std::invalid_argument("incorrect key length"); 193 | if (n.size() != crypto_secretbox_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 194 | size_t mlen = m.size() + crypto_secretbox_ZEROBYTES; 195 | unsigned char mpad[mlen]; 196 | for (size_t i = 0;i < crypto_secretbox_ZEROBYTES;++i) mpad[i] = 0; 197 | for (size_t i = crypto_secretbox_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_secretbox_ZEROBYTES]; 198 | unsigned char cpad[mlen]; 199 | ::crypto_secretbox(cpad,mpad,mlen,(const unsigned char *) n.c_str(),(const unsigned char *) k.c_str()); 200 | return std::string( 201 | (char *) cpad + crypto_secretbox_BOXZEROBYTES, 202 | mlen - crypto_secretbox_BOXZEROBYTES 203 | ); 204 | } 205 | 206 | std::string sodiumpp::crypto_secretbox_open(const std::string &c,const std::string &n,const std::string &k) 207 | { 208 | if (k.size() != crypto_secretbox_KEYBYTES) throw std::invalid_argument("incorrect key length"); 209 | if (n.size() != crypto_secretbox_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 210 | size_t clen = c.size() + crypto_secretbox_BOXZEROBYTES; 211 | unsigned char cpad[clen]; 212 | for (size_t i = 0;i < crypto_secretbox_BOXZEROBYTES;++i) cpad[i] = 0; 213 | for (size_t i = crypto_secretbox_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES]; 214 | unsigned char mpad[clen]; 215 | if (::crypto_secretbox_open(mpad,cpad,clen,(const unsigned char *) n.c_str(),(const unsigned char *) k.c_str()) != 0) 216 | throw sodiumpp::crypto_error("ciphertext fails verification"); 217 | if (clen < crypto_secretbox_ZEROBYTES) 218 | throw sodiumpp::crypto_error("ciphertext too short"); // should have been caught by _open 219 | return std::string( 220 | (char *) mpad + crypto_secretbox_ZEROBYTES, 221 | clen - crypto_secretbox_ZEROBYTES 222 | ); 223 | } 224 | 225 | std::string sodiumpp::crypto_sign_keypair(std::string &sk_string) 226 | { 227 | unsigned char pk[crypto_sign_PUBLICKEYBYTES]; 228 | sk_string.resize(crypto_sign_SECRETKEYBYTES, 0); 229 | ::crypto_sign_keypair(pk,(unsigned char *)&sk_string[0]); 230 | return std::string((char *) pk,sizeof pk); 231 | } 232 | 233 | std::string sodiumpp::crypto_sign_open(const std::string &sm_string, const std::string &pk_string) 234 | { 235 | if (pk_string.size() != crypto_sign_PUBLICKEYBYTES) throw std::invalid_argument("incorrect public-key length"); 236 | size_t smlen = sm_string.size(); 237 | unsigned char m[smlen]; 238 | unsigned long long mlen; 239 | for (size_t i = 0;i < smlen;++i) m[i] = sm_string[i]; 240 | if (::crypto_sign_open( 241 | m, 242 | &mlen, 243 | m, 244 | smlen, 245 | (const unsigned char *) pk_string.c_str() 246 | ) != 0) 247 | throw sodiumpp::crypto_error("ciphertext fails verification"); 248 | return std::string( 249 | (char *) m, 250 | mlen 251 | ); 252 | } 253 | 254 | std::string sodiumpp::crypto_sign(const std::string &m_string, const std::string &sk_string) 255 | { 256 | if (sk_string.size() != crypto_sign_SECRETKEYBYTES) throw std::invalid_argument("incorrect secret-key length"); 257 | size_t mlen = m_string.size(); 258 | unsigned char m[mlen+crypto_sign_BYTES]; 259 | unsigned long long smlen; 260 | for (size_t i = 0;i < mlen;++i) m[i] = m_string[i]; 261 | ::crypto_sign( 262 | m, 263 | &smlen, 264 | m, 265 | mlen, 266 | (const unsigned char *) sk_string.c_str() 267 | ); 268 | return std::string( 269 | (char *) m, 270 | smlen 271 | ); 272 | } 273 | 274 | std::string sodiumpp::crypto_stream(size_t clen,const std::string &n,const std::string &k) 275 | { 276 | if (n.size() != crypto_stream_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 277 | if (k.size() != crypto_stream_KEYBYTES) throw std::invalid_argument("incorrect key length"); 278 | unsigned char c[clen]; 279 | ::crypto_stream(c,clen,(const unsigned char *) n.c_str(),(const unsigned char *) k.c_str()); 280 | return std::string((char *) c,clen); 281 | } 282 | 283 | std::string sodiumpp::crypto_stream_xor(const std::string &m,const std::string &n,const std::string &k) 284 | { 285 | if (n.size() != crypto_stream_NONCEBYTES) throw std::invalid_argument("incorrect nonce length"); 286 | if (k.size() != crypto_stream_KEYBYTES) throw std::invalid_argument("incorrect key length"); 287 | size_t mlen = m.size(); 288 | unsigned char c[mlen]; 289 | ::crypto_stream_xor(c, 290 | (const unsigned char *) m.c_str(),mlen, 291 | (const unsigned char *) n.c_str(), 292 | (const unsigned char *) k.c_str() 293 | ); 294 | return std::string((char *) c,mlen); 295 | } 296 | 297 | std::string sodiumpp::bin2hex(const std::string& bytes) { 298 | std::string hex(bytes.size()*2, 0); 299 | sodium_bin2hex(&hex[0], hex.size()+1, reinterpret_cast(&bytes[0]), bytes.size()); 300 | return hex; 301 | } 302 | 303 | std::string sodiumpp::hex2bin(const std::string& bytes) { 304 | if(bytes.size() % 2 != 0) throw std::invalid_argument("length must be even"); 305 | std::string bin(bytes.size()/2, 0); 306 | size_t binlen; 307 | sodium_hex2bin((unsigned char *)&bin[0], bin.size(), &bytes[0], bytes.size(), nullptr, &binlen, nullptr); 308 | if(binlen != bin.size()) throw std::invalid_argument("string must be all hexadecimal digits"); 309 | return bin; 310 | } 311 | 312 | void sodiumpp::memzero(std::string& bytes) { 313 | sodium_memzero((unsigned char *)&bytes[0], bytes.size()); 314 | } 315 | 316 | void sodiumpp::mlock(std::string& bytes) { 317 | sodium_mlock((unsigned char *)&bytes[0], bytes.size()); 318 | } 319 | 320 | void sodiumpp::munlock(std::string& bytes) { 321 | sodium_munlock((unsigned char *)&bytes[0], bytes.size()); 322 | } 323 | 324 | std::string sodiumpp::crypto_shorthash(const std::string& m, const std::string& k) { 325 | if(k.size() != crypto_shorthash_KEYBYTES) throw std::invalid_argument("incorrect key length"); 326 | std::string out(crypto_shorthash_BYTES, 0); 327 | ::crypto_shorthash((unsigned char *)&out[0], (const unsigned char *)&m[0], m.size(), (const unsigned char *)&k[0]); 328 | return out; 329 | } 330 | 331 | std::string sodiumpp::randombytes(size_t size) { 332 | std::string buf(size, 0); 333 | randombytes_buf(&buf[0], size); 334 | return buf; 335 | } 336 | 337 | std::string sodiumpp::encode_from_binary(const std::string& binary_bytes, sodiumpp::encoding enc) { 338 | switch(enc) { 339 | case encoding::binary: 340 | return binary_bytes; 341 | case encoding::hex: 342 | return bin2hex(binary_bytes); 343 | case encoding::z85: 344 | return z85::encode_with_padding(binary_bytes); 345 | } 346 | } 347 | 348 | std::string sodiumpp::decode_to_binary(const std::string& encoded_bytes, sodiumpp::encoding enc) { 349 | switch(enc) { 350 | case encoding::binary: 351 | return encoded_bytes; 352 | case encoding::hex: 353 | return hex2bin(encoded_bytes); 354 | case encoding::z85: 355 | return z85::decode_with_padding(encoded_bytes); 356 | } 357 | } 358 | -------------------------------------------------------------------------------- /sodiumpp/test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // sodiumpp 4 | // 5 | // Created by Ruben De Visscher on 02/08/14. 6 | // Copyright (c) 2014 Ruben De Visscher. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace sodiumpp; 14 | using namespace bandit; 15 | 16 | go_bandit([](){ 17 | describe("z85", [](){ 18 | box_secret_key box_sk; 19 | sign_secret_key sign_sk; 20 | 21 | it("can encode/decode box sk", [&](){ 22 | encoded_bytes encoded = box_sk.get(encoding::z85); 23 | box_secret_key box_sk_decoded(box_sk.pk, encoded); 24 | AssertThat(box_sk_decoded.get().to_binary(), Equals(box_sk.get().to_binary())); 25 | }); 26 | 27 | it("can encode/decode sign sk", [&](){ 28 | encoded_bytes encoded = sign_sk.get(encoding::z85); 29 | sign_secret_key sign_sk_decoded(sign_sk.pk, encoded); 30 | AssertThat(sign_sk_decoded.get().to_binary(), Equals(sign_sk.get().to_binary())); 31 | }); 32 | }); 33 | 34 | describe("hex", [](){ 35 | box_secret_key box_sk; 36 | sign_secret_key sign_sk; 37 | 38 | it("can encode/decode box sk", [&](){ 39 | encoded_bytes encoded = box_sk.get(encoding::hex); 40 | box_secret_key box_sk_decoded(box_sk.pk, encoded); 41 | AssertThat(box_sk_decoded.get().to_binary(), Equals(box_sk.get().to_binary())); 42 | }); 43 | 44 | it("can encode/decode sign sk", [&](){ 45 | encoded_bytes encoded = sign_sk.get(encoding::hex); 46 | sign_secret_key sign_sk_decoded(sign_sk.pk, encoded); 47 | AssertThat(sign_sk_decoded.get().to_binary(), Equals(sign_sk.get().to_binary())); 48 | }); 49 | }); 50 | 51 | describe("nonce", [](){ 52 | it("can increment basic", [&](){ 53 | nonce64 n = nonce64(encoded_bytes("00000000000000000000000000000000", encoding::hex), encoded_bytes("0000000000000000", encoding::hex)); 54 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "0000000000000000")); 55 | n.increment(); 56 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "0000000000000002")); 57 | }); 58 | it("can increment with carry", [&](){ 59 | nonce64 n = nonce64(encoded_bytes("00000000000000000000000000000000", encoding::hex), encoded_bytes("00fffffffffffffe", encoding::hex)); 60 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "00fffffffffffffe")); 61 | n.increment(); 62 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "0100000000000000")); 63 | 64 | n = nonce64(encoded_bytes("00000000000000000000000000000000", encoding::hex), encoded_bytes("00ffffffffffffff", encoding::hex)); 65 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "00ffffffffffffff")); 66 | n.increment(); 67 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "0100000000000001")); 68 | }); 69 | it("can detect overflow", [&](){ 70 | nonce64 n = nonce64(encoded_bytes("00000000000000000000000000000000", encoding::hex), encoded_bytes("fffffffffffffffe", encoding::hex)); 71 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "fffffffffffffffe")); 72 | n.increment(); 73 | AssertThrows(std::overflow_error, n.get()); 74 | AssertThrows(std::overflow_error, n.next()); 75 | 76 | n = nonce64(encoded_bytes("00000000000000000000000000000000", encoding::hex), encoded_bytes("ffffffffffffffff", encoding::hex)); 77 | AssertThat(n.get(encoding::hex).bytes, Equals("00000000000000000000000000000000" "ffffffffffffffff")); 78 | n.increment(); 79 | AssertThrows(std::overflow_error, n.get()); 80 | AssertThrows(std::overflow_error, n.next()); 81 | }); 82 | }); 83 | }); 84 | 85 | int main(int argc, char ** argv) { 86 | return bandit::run(argc, argv); 87 | } 88 | -------------------------------------------------------------------------------- /sodiumpp/z85/z85.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Stanislav Artemkin . 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | * 27 | * Implementation of 32/Z85 specification (http://rfc.zeromq.org/spec:32/Z85) 28 | * Source repository: http://github.com/artemkin/z85 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | typedef unsigned int uint32_t; 37 | typedef unsigned char byte; 38 | 39 | // make sure uint32_t is 32-bit 40 | typedef char Z85_uint32_t_static_assert[(sizeof(uint32_t) * CHAR_BIT == 32) * 2 - 1]; 41 | 42 | #define DIV85_MAGIC 3233857729ULL 43 | // make sure magic constant is 64-bit 44 | typedef char Z85_div85_magic_static_assert[(sizeof(DIV85_MAGIC) * CHAR_BIT == 64) * 2 - 1]; 45 | 46 | #define DIV85(number) ((uint32_t)((DIV85_MAGIC * number) >> 32) >> 6) 47 | 48 | static const char* base85 = 49 | { 50 | "0123456789" 51 | "abcdefghij" 52 | "klmnopqrst" 53 | "uvwxyzABCD" 54 | "EFGHIJKLMN" 55 | "OPQRSTUVWX" 56 | "YZ.-:+=^!/" 57 | "*?&<>()[]{" 58 | "}@%$#" 59 | }; 60 | 61 | static byte base256[] = 62 | { 63 | 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00, 64 | 0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45, 65 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 66 | 0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47, 67 | 0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 68 | 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 69 | 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 70 | 0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00, 71 | 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 72 | 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 73 | 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 74 | 0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00 75 | }; 76 | 77 | char* Z85_encode_unsafe(const char* source, const char* sourceEnd, char* dest) 78 | { 79 | byte* src = (byte*)source; 80 | byte* end = (byte*)sourceEnd; 81 | byte* dst = (byte*)dest; 82 | uint32_t value; 83 | uint32_t value2; 84 | 85 | for (; src != end; src += 4, dst += 5) 86 | { 87 | // unpack big-endian frame 88 | value = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; 89 | 90 | value2 = DIV85(value); dst[4] = base85[value - value2 * 85]; value = value2; 91 | value2 = DIV85(value); dst[3] = base85[value - value2 * 85]; value = value2; 92 | value2 = DIV85(value); dst[2] = base85[value - value2 * 85]; value = value2; 93 | value2 = DIV85(value); dst[1] = base85[value - value2 * 85]; 94 | dst[0] = base85[value2]; 95 | } 96 | 97 | return (char*)dst; 98 | } 99 | 100 | char* Z85_decode_unsafe(const char* source, const char* sourceEnd, char* dest) 101 | { 102 | byte* src = (byte*)source; 103 | byte* end = (byte*)sourceEnd; 104 | byte* dst = (byte*)dest; 105 | uint32_t value; 106 | 107 | for (; src != end; src += 5, dst += 4) 108 | { 109 | value = base256[(src[0] - 32) & 127]; 110 | value = value * 85 + base256[(src[1] - 32) & 127]; 111 | value = value * 85 + base256[(src[2] - 32) & 127]; 112 | value = value * 85 + base256[(src[3] - 32) & 127]; 113 | value = value * 85 + base256[(src[4] - 32) & 127]; 114 | 115 | // pack big-endian frame 116 | dst[0] = value >> 24; 117 | dst[1] = (byte)(value >> 16); 118 | dst[2] = (byte)(value >> 8); 119 | dst[3] = (byte)(value); 120 | } 121 | 122 | return (char*)dst; 123 | } 124 | 125 | size_t Z85_encode_bound(size_t size) 126 | { 127 | return size * 5 / 4; 128 | } 129 | 130 | size_t Z85_decode_bound(size_t size) 131 | { 132 | return size * 4 / 5; 133 | } 134 | 135 | size_t Z85_encode(const char* source, char* dest, size_t inputSize) 136 | { 137 | if (!source || !dest || inputSize % 4) 138 | { 139 | assert(!"wrong source, destination or input size"); 140 | return 0; 141 | } 142 | 143 | return Z85_encode_unsafe(source, source + inputSize, dest) - dest; 144 | } 145 | 146 | size_t Z85_decode(const char* source, char* dest, size_t inputSize) 147 | { 148 | if (!source || !dest || inputSize % 5) 149 | { 150 | assert(!"wrong source, destination or input size"); 151 | return 0; 152 | } 153 | 154 | return Z85_decode_unsafe(source, source + inputSize, dest) - dest; 155 | } 156 | 157 | size_t Z85_encode_with_padding_bound(size_t size) 158 | { 159 | if (size == 0) return 0; 160 | size = Z85_encode_bound(size); 161 | return size + (5 - size % 5) % 5 + 1; 162 | } 163 | 164 | size_t Z85_decode_with_padding_bound(const char* source, size_t size) 165 | { 166 | if (size == 0 || !source || (byte)(source[0] - '0' - 1) > 3) return 0; 167 | return Z85_decode_bound(size - 1) - 4 + (source[0] - '0'); 168 | } 169 | 170 | size_t Z85_encode_with_padding(const char* source, char* dest, size_t inputSize) 171 | { 172 | size_t tailBytes = inputSize % 4; 173 | char tailBuf[4] = { 0 }; 174 | char* dst = dest; 175 | const char* end = source + inputSize - tailBytes; 176 | 177 | assert(source && dest); 178 | 179 | // zero length string is not padded 180 | if (!source || !dest || inputSize == 0) 181 | { 182 | return 0; 183 | } 184 | 185 | (dst++)[0] = (tailBytes == 0 ? '4' : '0' + (char)tailBytes); // write tail bytes count 186 | dst = Z85_encode_unsafe(source, end, dst); // write body 187 | 188 | // write tail 189 | switch (tailBytes) 190 | { 191 | case 3: 192 | tailBuf[2] = end[2]; 193 | case 2: 194 | tailBuf[1] = end[1]; 195 | case 1: 196 | tailBuf[0] = end[0]; 197 | dst = Z85_encode_unsafe(tailBuf, tailBuf + 4, dst); 198 | } 199 | 200 | return dst - dest; 201 | } 202 | 203 | size_t Z85_decode_with_padding(const char* source, char* dest, size_t inputSize) 204 | { 205 | char* dst = dest; 206 | size_t tailBytes; 207 | char tailBuf[4] = { 0 }; 208 | const char* end = source + inputSize; 209 | 210 | assert(source && dest && (inputSize == 0 || (inputSize - 1) % 5 == 0)); 211 | 212 | // zero length string is not padded 213 | if (!source || !dest || inputSize == 0 || (inputSize - 1) % 5) 214 | { 215 | return 0; 216 | } 217 | 218 | tailBytes = (source++)[0] - '0'; // possible values: 1, 2, 3 or 4 219 | if (tailBytes - 1 > 3) 220 | { 221 | assert(!"wrong tail bytes count"); 222 | return 0; 223 | } 224 | 225 | end -= 5; 226 | if (source != end) 227 | { 228 | // decode body 229 | dst = Z85_decode_unsafe(source, end, dst); 230 | } 231 | 232 | // decode last 5 bytes chunk 233 | Z85_decode_unsafe(end, end + 5, tailBuf); 234 | 235 | switch (tailBytes) 236 | { 237 | case 4: 238 | dst[3] = tailBuf[3]; 239 | case 3: 240 | dst[2] = tailBuf[2]; 241 | case 2: 242 | dst[1] = tailBuf[1]; 243 | case 1: 244 | dst[0] = tailBuf[0]; 245 | } 246 | 247 | return dst - dest + tailBytes; 248 | } 249 | -------------------------------------------------------------------------------- /sodiumpp/z85/z85_impl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Stanislav Artemkin . 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | * 27 | * Implementation of 32/Z85 specification (http://rfc.zeromq.org/spec:32/Z85) 28 | * Source repository: http://github.com/artemkin/z85 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | 37 | 38 | namespace z85 39 | { 40 | 41 | std::string encode_with_padding(const char* source, size_t inputSize) 42 | { 43 | if (!source || inputSize == 0) 44 | { 45 | return std::string(); 46 | } 47 | 48 | std::string buf; 49 | buf.resize(Z85_encode_with_padding_bound(inputSize)); 50 | 51 | const size_t encodedBytes = Z85_encode_with_padding(source, &buf[0], inputSize); 52 | assert(encodedBytes == buf.size()); (void)encodedBytes; 53 | 54 | return buf; 55 | } 56 | 57 | std::string encode_with_padding(const std::string& source) 58 | { 59 | return encode_with_padding(source.c_str(), source.size()); 60 | } 61 | 62 | std::string decode_with_padding(const char* source, size_t inputSize) 63 | { 64 | if (!source || inputSize == 0) 65 | { 66 | return std::string(); 67 | } 68 | 69 | const size_t bufSize = Z85_decode_with_padding_bound(source, inputSize); 70 | if (bufSize == 0) 71 | { 72 | assert(!"wrong padding"); 73 | return std::string(); 74 | } 75 | 76 | std::string buf; 77 | buf.resize(bufSize); 78 | 79 | const size_t decodedBytes = Z85_decode_with_padding(source, &buf[0], inputSize); 80 | assert(decodedBytes == buf.size()); (void)decodedBytes; 81 | 82 | return buf; 83 | } 84 | 85 | std::string decode_with_padding(const std::string& source) 86 | { 87 | return decode_with_padding(source.c_str(), source.size()); 88 | } 89 | 90 | std::string encode(const char* source, size_t inputSize) 91 | { 92 | if (!source || inputSize == 0) 93 | { 94 | return std::string(); 95 | } 96 | 97 | std::string buf; 98 | buf.resize(Z85_encode_bound(inputSize)); 99 | 100 | const size_t encodedBytes = Z85_encode(source, &buf[0], inputSize); 101 | if (encodedBytes == 0) 102 | { 103 | assert(!"wrong input size"); 104 | return std::string(); 105 | } 106 | 107 | return buf; 108 | } 109 | 110 | std::string encode(const std::string& source) 111 | { 112 | return encode(source.c_str(), source.size()); 113 | } 114 | 115 | std::string decode(const char* source, size_t inputSize) 116 | { 117 | if (!source || inputSize == 0) 118 | { 119 | return std::string(); 120 | } 121 | 122 | std::string buf; 123 | buf.resize(Z85_decode_bound(inputSize)); 124 | 125 | const size_t decodedBytes = Z85_decode(source, &buf[0], inputSize); 126 | if (decodedBytes == 0) 127 | { 128 | assert(!"wrong input size"); 129 | return std::string(); 130 | } 131 | 132 | return buf; 133 | } 134 | 135 | std::string decode(const std::string& source) 136 | { 137 | return decode(source.c_str(), source.size()); 138 | } 139 | 140 | } // namespace z85 141 | 142 | -------------------------------------------------------------------------------- /travis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get -y update && apt-get -y upgrade 4 | RUN apt-get -y install g++ clang cmake wget libsodium-dev 5 | RUN mkdir /opt/sodiumpp 6 | WORKDIR /opt/sodiumpp 7 | -------------------------------------------------------------------------------- /travis/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | mkdir -p build 6 | cd build 7 | cmake -DCMAKE_BUILD_TYPE=Release -DSODIUMPP_TEST=1 -DSODIUMPP_EXAMPLE=1 .. 8 | make 9 | --------------------------------------------------------------------------------