├── .gitignore ├── BowlingGame ├── BowlingGame.vcxproj ├── BowlingGame.vcxproj.filters ├── Game.cpp ├── Game.h ├── ReadMe.txt ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── BowlingTests.Catch ├── BowlingTests.Catch.cpp ├── BowlingTests.Catch.vcxproj ├── BowlingTests.Catch.vcxproj.filters ├── ReadMe.txt ├── catch.hpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── BowlingTests.GTest ├── BowlingTests.GTest.vcxproj ├── BowlingTests.GTest.vcxproj.filters ├── ReadMe.txt ├── SimpleGameTests.cpp ├── SpareTests.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── BowlingTests.MSTest ├── BowlingTests.MSTest.vcxproj ├── BowlingTests.MSTest.vcxproj.filters ├── SimpleGameTests.cpp ├── SpareTests.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── BowlingTests.Mettle ├── BowlingTests.Mettle.cpp ├── BowlingTests.Mettle.vcxproj ├── BowlingTests.Mettle.vcxproj.filters ├── ReadMe.txt ├── mettle │ ├── basic_suite.hpp │ ├── detail │ │ ├── forward_if.hpp │ │ ├── string_algorithm.hpp │ │ └── tuple_algorithm.hpp │ ├── driver │ │ ├── cmd_line.hpp │ │ ├── detail │ │ │ ├── bencode.hpp │ │ │ ├── export.hpp │ │ │ └── optional.hpp │ │ ├── exit_code.hpp │ │ ├── filters.hpp │ │ ├── filters_core.hpp │ │ ├── header_driver.hpp │ │ ├── lib_driver.hpp │ │ ├── object_factory.hpp │ │ ├── posix │ │ │ ├── scoped_pipe.hpp │ │ │ ├── scoped_signal.hpp │ │ │ └── subprocess.hpp │ │ ├── run_tests.hpp │ │ ├── subprocess_test_runner.hpp │ │ ├── test_name.hpp │ │ └── windows │ │ │ ├── scoped_handle.hpp │ │ │ ├── scoped_pipe.hpp │ │ │ └── subprocess.hpp │ ├── glue.hpp │ ├── header_only.hpp │ ├── matchers.hpp │ ├── matchers │ │ ├── any_capture.hpp │ │ ├── arithmetic.hpp │ │ ├── collection.hpp │ │ ├── combinatoric.hpp │ │ ├── core.hpp │ │ ├── death.hpp │ │ ├── detail │ │ │ ├── source_location.hpp │ │ │ └── source_location_shim.hpp │ │ ├── exception.hpp │ │ ├── expect.hpp │ │ ├── regex.hpp │ │ ├── relational.hpp │ │ └── result.hpp │ ├── output.hpp │ ├── output │ │ ├── string.hpp │ │ ├── to_printable.hpp │ │ ├── traits.hpp │ │ └── type_name.hpp │ ├── suite.hpp │ ├── suite │ │ ├── attributes.hpp │ │ ├── compiled_suite.hpp │ │ ├── detail │ │ │ ├── all_suites.hpp │ │ │ ├── built_in_attrs.hpp │ │ │ └── test_caller.hpp │ │ ├── factory.hpp │ │ ├── global_suite.hpp │ │ └── make_suite.hpp │ └── test_uid.hpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── CppUnitTestingMockComparison.sln ├── CppUnitTestingMockComparison ├── CppUnitTestingMockComparison.cpp ├── CppUnitTestingMockComparison.vcxproj ├── CppUnitTestingMockComparison.vcxproj.filters ├── ReadMe.txt ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── DistibutedCalculator.FakeIt ├── DistibutedCalculator.FakeIt.cpp ├── DistibutedCalculator.FakeIt.vcxproj ├── DistibutedCalculator.FakeIt.vcxproj.filters ├── ReadMe.txt ├── catch.hpp ├── fakeit.hpp ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── DistributedCalculator.HippoMocks ├── DistributedCalculator.HippoMocks.vcxproj ├── DistributedCalculator.HippoMocks.vcxproj.filters ├── DistributedCalculatorTests.cpp ├── hippomocks.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── DistributedCalculator ├── Calculator.cpp ├── Calculator.h ├── DataAccess.h ├── DistributedCalculator.vcxproj ├── DistributedCalculator.vcxproj.filters ├── ReadMe.txt ├── RestApiClient.cpp ├── RestApiClient.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── DistributedCalculatorTests.GMock ├── DistributedCalculatorTests.GMock.cpp ├── DistributedCalculatorTests.GMock.vcxproj ├── DistributedCalculatorTests.GMock.vcxproj.filters ├── FakeDataAccess.h ├── FakeRestApiClient.h ├── ReadMe.txt ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── DistributedCalculatorTests.Trompeloeil ├── DistributedCalculatorTests.Trompeloeil.cpp ├── DistributedCalculatorTests.Trompeloeil.vcxproj ├── DistributedCalculatorTests.Trompeloeil.vcxproj.filters ├── FakeDataAccess.h ├── FakeRestApiClient.h ├── ReadMe.txt ├── catch.hpp ├── stdafx.cpp ├── stdafx.h ├── targetver.h └── trompeloeil.hpp ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /BowlingGame/BowlingGame.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {6D3969ED-98F4-4C00-88E5-12A24A5409DA} 24 | Win32Proj 25 | BowlingGame 26 | 10.0.15063.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Use 77 | Level3 78 | Disabled 79 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 80 | 81 | 82 | Windows 83 | 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | _DEBUG;_LIB;%(PreprocessorDefinitions) 91 | 92 | 93 | Windows 94 | 95 | 96 | 97 | 98 | Level3 99 | Use 100 | MaxSpeed 101 | true 102 | true 103 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 104 | 105 | 106 | Windows 107 | true 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | Use 115 | MaxSpeed 116 | true 117 | true 118 | NDEBUG;_LIB;%(PreprocessorDefinitions) 119 | 120 | 121 | Windows 122 | true 123 | true 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | Create 138 | Create 139 | Create 140 | Create 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /BowlingGame/BowlingGame.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /BowlingGame/Game.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Game.h" 3 | #include 4 | 5 | Game::Game() : _round(0) 6 | { 7 | std::memset(_rolls, 0, sizeof(_rolls)); 8 | } 9 | 10 | 11 | Game::~Game() 12 | { 13 | } 14 | 15 | int Game::Score() const { 16 | int total = 0; 17 | for (int i = 0; i < 21; ++i) { 18 | if (_rolls[i] == 10) 19 | { 20 | if (_round > i + 2) 21 | { 22 | total += 10 + _rolls[i + 2] + _rolls[i + 3]; 23 | } 24 | } 25 | else if (_rolls[i] + _rolls[i + 1] == 10) { 26 | total += 10 + _rolls[i + 2]; 27 | i++; 28 | } 29 | else 30 | { 31 | total += _rolls[i]; 32 | } 33 | } 34 | 35 | return total; 36 | } 37 | 38 | void Game::Roll(int pins) 39 | { 40 | _rolls[_round++] = pins; 41 | 42 | if (pins == 10) 43 | { 44 | _round++; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /BowlingGame/Game.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class Game 3 | { 4 | int _rolls[21]; 5 | int _round; 6 | public: 7 | Game(); 8 | ~Game(); 9 | 10 | int Score() const; 11 | void Roll(int); 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /BowlingGame/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | STATIC LIBRARY : BowlingGame Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this BowlingGame library project for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your BowlingGame application. 9 | 10 | 11 | BowlingGame.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | BowlingGame.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | 25 | ///////////////////////////////////////////////////////////////////////////// 26 | 27 | StdAfx.h, StdAfx.cpp 28 | These files are used to build a precompiled header (PCH) file 29 | named BowlingGame.pch and a precompiled types file named StdAfx.obj. 30 | 31 | ///////////////////////////////////////////////////////////////////////////// 32 | Other notes: 33 | 34 | AppWizard uses "TODO:" comments to indicate parts of the source code you 35 | should add to or customize. 36 | 37 | ///////////////////////////////////////////////////////////////////////////// 38 | -------------------------------------------------------------------------------- /BowlingGame/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BowlingGame.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BowlingGame/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | 12 | 13 | 14 | // TODO: reference additional headers your program requires here 15 | -------------------------------------------------------------------------------- /BowlingGame/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /BowlingTests.Catch/BowlingTests.Catch.cpp: -------------------------------------------------------------------------------- 1 | // BowlingTests.Catch.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file 6 | #include "catch.hpp" 7 | #include "../BowlingGame/Game.h" 8 | 9 | void RollSeveral(Game& game, int rolls, int pins) { 10 | for (int i = 0; i < rolls; i++) { 11 | game.Roll(pins); 12 | } 13 | } 14 | 15 | TEST_CASE("Simple Bowling score -- without score or strike", "[BowlingKata]") 16 | { 17 | Game game; 18 | 19 | SECTION("All rolls are gutter balls --> score == 0") { 20 | RollSeveral(game, 20, 0); 21 | 22 | REQUIRE(game.Score() == 0); 23 | } 24 | 25 | SECTION("All rolls are 1 --> score == 20") { 26 | RollSeveral(game, 20, 1); 27 | 28 | REQUIRE(game.Score() == 20); 29 | } 30 | 31 | SECTION("All rolls are 2 --> score == 40", "[Run me]") { 32 | RollSeveral(game, 20, 2); 33 | 34 | REQUIRE(game.Score() == 40); 35 | } 36 | } 37 | 38 | TEST_CASE("Using spare") 39 | { 40 | Game game; 41 | 42 | SECTION("Spare in the first round --> value equals secod round first roll + 10") 43 | { 44 | game.Roll(7); 45 | game.Roll(3); 46 | game.Roll(4); 47 | RollSeveral(game, 17, 0); 48 | 49 | REQUIRE(game.Score() == 18); 50 | } 51 | } 52 | 53 | SCENARIO("First roll is strike") 54 | { 55 | GIVEN("Bowled strike on first turn") 56 | { 57 | Game game; 58 | game.Roll(10); 59 | 60 | WHEN("All rest rolls are gutter balls") 61 | { 62 | RollSeveral(game, 18, 0); 63 | THEN("Total score is 10") 64 | { 65 | REQUIRE(game.Score() == 10); 66 | } 67 | } 68 | 69 | WHEN("Next two rolls are not spare or strike") 70 | { 71 | game.Roll(3); 72 | game.Roll(4); 73 | RollSeveral(game, 16, 0); 74 | 75 | THEN("Total score is 10 plus twice the sum of these rolls") 76 | { 77 | REQUIRE(game.Score() == 24); 78 | } 79 | } 80 | 81 | WHEN("Next roll is spare then all gutter balls") 82 | { 83 | game.Roll(3); 84 | game.Roll(7); 85 | RollSeveral(game, 16, 0); 86 | 87 | THEN("Total score is 30") 88 | { 89 | REQUIRE(game.Score() == 30); 90 | } 91 | } 92 | 93 | WHEN("Next roll is spare then roll five") 94 | { 95 | game.Roll(3); 96 | game.Roll(7); 97 | game.Roll(5); 98 | RollSeveral(game, 15, 0); 99 | 100 | THEN("Total score is 40") 101 | { 102 | REQUIRE(game.Score() == 40); 103 | } 104 | } 105 | 106 | WHEN("Next two rolls are strike then gutter balls") 107 | { 108 | game.Roll(10); 109 | game.Roll(10); 110 | RollSeveral(game, 16, 0); 111 | 112 | THEN("Total score is 60") 113 | { 114 | REQUIRE(game.Score() == 60); 115 | } 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /BowlingTests.Catch/BowlingTests.Catch.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /BowlingTests.Catch/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : BowlingTests.Catch Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this BowlingTests.Catch application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your BowlingTests.Catch application. 9 | 10 | 11 | BowlingTests.Catch.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | BowlingTests.Catch.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | BowlingTests.Catch.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named BowlingTests.Catch.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /BowlingTests.Catch/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BowlingTests.Catch.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BowlingTests.Catch/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /BowlingTests.Catch/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /BowlingTests.GTest/BowlingTests.GTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /BowlingTests.GTest/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : BowlingTests.GTest Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this BowlingTests.GTest application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your BowlingTests.GTest application. 9 | 10 | 11 | BowlingTests.GTest.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | BowlingTests.GTest.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | BowlingTests.GTest.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named BowlingTests.GTest.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /BowlingTests.GTest/SimpleGameTests.cpp: -------------------------------------------------------------------------------- 1 | // BowlingTests.GTest.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "gtest/gtest.h" 6 | #include "../BowlingGame/Game.h" 7 | 8 | using namespace testing; 9 | 10 | 11 | void RollSeveral(Game& game, int rolls, int pins) { 12 | for (int i = 0; i < rolls; i++) { 13 | game.Roll(pins); 14 | } 15 | } 16 | 17 | TEST(SimpleGameTests, AllRollsAreGutterBalls_ScoreIsZero) 18 | { 19 | Game game; 20 | 21 | RollSeveral(game, 20, 0); 22 | 23 | ASSERT_EQ(0, game.Score()); 24 | } 25 | 26 | TEST(SimpleGameTests, AllRollsAreOne_ScoreIs20) 27 | { 28 | Game game; 29 | 30 | RollSeveral(game, 20, 1); 31 | 32 | ASSERT_EQ(20, game.Score()); 33 | } 34 | 35 | TEST(SimpleGameTests, AllRollsAreTwo_ScoreIs40) 36 | { 37 | Game game; 38 | 39 | RollSeveral(game, 20, 2); 40 | 41 | ASSERT_EQ(40, game.Score()); 42 | } 43 | 44 | 45 | int main(int argc, char** argv) 46 | { 47 | InitGoogleTest(&argc, argv); 48 | 49 | return RUN_ALL_TESTS(); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /BowlingTests.GTest/SpareTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "gtest/gtest.h" 3 | #include "../BowlingGame/Game.h" 4 | 5 | using namespace testing; 6 | 7 | class SpareTests : public Test 8 | { 9 | protected: 10 | Game game; 11 | 12 | 13 | void SetUp() override 14 | { 15 | game.Roll(7); 16 | game.Roll(3); 17 | } 18 | }; 19 | 20 | TEST_F(SpareTests, SecondRoundZero_ScoreIsTen) 21 | { 22 | game.Roll(0); 23 | game.Roll(0); 24 | 25 | ASSERT_EQ(11, game.Score()); 26 | } 27 | 28 | TEST_F(SpareTests, RollSomeValueInSecondRound_ScoreEqualValuePlusTenPlusRound) 29 | { 30 | game.Roll(4); 31 | game.Roll(2); 32 | 33 | ASSERT_EQ(20, game.Score()); 34 | } -------------------------------------------------------------------------------- /BowlingTests.GTest/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BowlingTests.GTest.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BowlingTests.GTest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /BowlingTests.GTest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /BowlingTests.MSTest/BowlingTests.MSTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /BowlingTests.MSTest/SimpleGameTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CppUnitTest.h" 3 | #include "../BowlingGame/Game.h" 4 | 5 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 6 | 7 | namespace BowlingTestsMSTest 8 | { 9 | void RollSeveral(Game& game, int rolls, int pins) { 10 | for (int i = 0; i < rolls; i++) { 11 | game.Roll(pins); 12 | } 13 | } 14 | 15 | TEST_CLASS(SimpleGameTests) 16 | { 17 | Game game; 18 | public: 19 | 20 | TEST_METHOD(AllRollsAreGutterBalls_ScoreIsZero) 21 | { 22 | RollSeveral(game, 20, 0); 23 | 24 | Assert::AreEqual(0, game.Score()); 25 | } 26 | 27 | TEST_METHOD(AllRollsAreOne_ScoreIs20) 28 | { 29 | RollSeveral(game, 20, 1); 30 | 31 | Assert::AreEqual(20, game.Score()); 32 | } 33 | 34 | TEST_METHOD(AllRollsAreTwo_ScoreIs40) 35 | { 36 | RollSeveral(game, 20, 2); 37 | 38 | Assert::AreEqual(40, game.Score()); 39 | } 40 | }; 41 | } -------------------------------------------------------------------------------- /BowlingTests.MSTest/SpareTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CppUnitTest.h" 3 | #include "../BowlingGame/Game.h" 4 | 5 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 6 | 7 | namespace BowlingTestsMSTest 8 | { 9 | TEST_CLASS(SpareTests) 10 | { 11 | Game game; 12 | public: 13 | 14 | TEST_METHOD_INITIALIZE(RollSpareInFirstRound) 15 | { 16 | game.Roll(7); 17 | game.Roll(3); 18 | } 19 | 20 | TEST_METHOD(SecondRoundZero_ScoreIsZero) 21 | { 22 | game.Roll(0); 23 | game.Roll(0); 24 | 25 | Assert::AreEqual(10, game.Score()); 26 | } 27 | 28 | TEST_METHOD(RollSomeValueInSecondRound_ScoreEqualValuePlusTenPlusRound) 29 | { 30 | game.Roll(4); 31 | game.Roll(2); 32 | 33 | Assert::AreEqual(20, game.Score()); 34 | } 35 | }; 36 | } -------------------------------------------------------------------------------- /BowlingTests.MSTest/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BowlingTests.MSTest.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BowlingTests.MSTest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | // Headers for CppUnitTest 11 | #include "CppUnitTest.h" 12 | 13 | // TODO: reference additional headers your program requires here 14 | -------------------------------------------------------------------------------- /BowlingTests.MSTest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/BowlingTests.Mettle.cpp: -------------------------------------------------------------------------------- 1 | // BowlingTests.Mettle.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "mettle/header_only.hpp" 6 | #include "../BowlingGame/Game.h" 7 | 8 | using namespace mettle; 9 | 10 | void RollSeveral(Game& game, int rolls, int pins) { 11 | for (int i = 0; i < rolls; i++) { 12 | game.Roll(pins); 13 | } 14 | } 15 | 16 | suite<> first("simple tests", [](auto &_) { 17 | _.test("When all rolles are gutterballs --> score is 0", []() { 18 | Game game; 19 | 20 | RollSeveral(game, 20, 0); 21 | 22 | expect(game.Score(), equal_to(0)); 23 | }); 24 | 25 | _.test("When all rolles are one --> score is 20", []() { 26 | Game game; 27 | 28 | RollSeveral(game, 20, 1); 29 | 30 | expect(game.Score(), equal_to(20)); 31 | }); 32 | 33 | _.test("When all rolles are two --> score is 40", []() { 34 | Game game; 35 | 36 | RollSeveral(game, 20, 2); 37 | 38 | expect(game.Score(), equal_to(40)); 39 | }); 40 | }); 41 | 42 | struct SpareTests { 43 | Game game; 44 | }; 45 | 46 | suite fix("fixture suite", [](auto &_) { 47 | 48 | _.setup([](SpareTests &f) { 49 | f.game.Roll(7); 50 | f.game.Roll(3); 51 | }); 52 | 53 | _.test("next round is zero --> score is 10", [](SpareTests &f) { 54 | f.game.Roll(0); 55 | f.game.Roll(0); 56 | 57 | expect(f.game.Score(), equal_to(10)); 58 | }); 59 | 60 | _.test("Spare in the first round --> value equals secod round first roll + 10", [](SpareTests &f) { 61 | f.game.Roll(4); 62 | f.game.Roll(0); 63 | 64 | expect(f.game.Score(), equal_to(18)); 65 | }); 66 | }); -------------------------------------------------------------------------------- /BowlingTests.Mettle/BowlingTests.Mettle.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {257C2B29-8CB7-4E17-B236-F9C8C3ACADAD} 24 | Win32Proj 25 | BowlingTestsMettle 26 | 10.0.15063.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | 92 | 93 | Console 94 | $(OutputPath) 95 | bowlinggame.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 96 | 97 | 98 | 99 | 100 | Use 101 | Level3 102 | Disabled 103 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | 105 | 106 | Console 107 | 108 | 109 | 110 | 111 | Level3 112 | Use 113 | MaxSpeed 114 | true 115 | true 116 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 117 | 118 | 119 | Console 120 | true 121 | true 122 | $(OutputPath) 123 | bowlinggame.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 124 | 125 | 126 | 127 | 128 | Level3 129 | Use 130 | MaxSpeed 131 | true 132 | true 133 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 134 | 135 | 136 | Console 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | Create 152 | Create 153 | Create 154 | Create 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/BowlingTests.Mettle.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : BowlingTests.Mettle Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this BowlingTests.Mettle application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your BowlingTests.Mettle application. 9 | 10 | 11 | BowlingTests.Mettle.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | BowlingTests.Mettle.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | BowlingTests.Mettle.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named BowlingTests.Mettle.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/basic_suite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_BASIC_SUITE_HPP 2 | #define INC_METTLE_BASIC_SUITE_HPP 3 | 4 | #include "suite/attributes.hpp" 5 | #include "suite/compiled_suite.hpp" 6 | #include "suite/make_suite.hpp" 7 | #include "suite/global_suite.hpp" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/detail/forward_if.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DETAIL_MOVE_IF_HPP 2 | #define INC_METTLE_DETAIL_MOVE_IF_HPP 3 | 4 | #include 5 | 6 | namespace mettle { 7 | 8 | namespace detail { 9 | template 10 | struct ref_if { 11 | using type = typename std::conditional< 12 | std::is_lvalue_reference::value, 13 | typename std::remove_reference::type &, 14 | typename std::remove_reference::type && 15 | >::type; 16 | }; 17 | 18 | template 19 | inline decltype(auto) 20 | forward_if(Element &&value) { 21 | return static_cast::type>(value); 22 | } 23 | } 24 | 25 | } // namespace mettle 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/detail/string_algorithm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DETAIL_STRING_ALGORITHM_HPP 2 | #define INC_METTLE_DETAIL_STRING_ALGORITHM_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace mettle { 10 | 11 | namespace detail { 12 | 13 | struct identity { 14 | template 15 | constexpr decltype(auto) operator ()(T &&t) const { 16 | return std::forward(t); 17 | } 18 | }; 19 | 20 | template 21 | std::string stringify(const T &t) { 22 | std::ostringstream ss; 23 | ss << t; 24 | return ss.str(); 25 | } 26 | 27 | template 28 | const std::string & stringify(const std::string &s) { 29 | return s; 30 | } 31 | 32 | class ostream_list_append { 33 | public: 34 | ostream_list_append(std::ostream &os, std::string delim = ", ") 35 | : os_(os), delim_(std::move(delim)) {} 36 | 37 | template 38 | void operator ()(T &&t) { 39 | if(first_) 40 | first_ = false; 41 | else 42 | os_ << delim_; 43 | os_ << std::forward(t); 44 | } 45 | private: 46 | std::ostream &os_; 47 | const std::string delim_; 48 | bool first_ = true; 49 | }; 50 | 51 | template 52 | class string_joiner { 53 | public: 54 | string_joiner(Iter begin, Iter end, const Func &func, 55 | const std::string &delim) 56 | : begin_(begin), end_(end), func_(func), delim_(delim) {} 57 | string_joiner(const string_joiner &) = delete; 58 | 59 | friend std::ostream & 60 | operator <<(std::ostream &os, const string_joiner &t) { 61 | ostream_list_append append(os, t.delim_); 62 | for(auto i = t.begin_; i != t.end_; ++i) 63 | append(t.func_(*i)); 64 | return os; 65 | } 66 | private: 67 | const Iter begin_, end_; 68 | const Func &func_; 69 | const std::string &delim_; 70 | }; 71 | 72 | template 73 | inline const string_joiner 74 | iter_joined(Iter begin, Iter end, const Func &func = identity{}, 75 | const std::string &delim = ", ") { 76 | return {begin, end, func, delim}; 77 | } 78 | 79 | template 80 | inline auto joined(const T &t, const Func &func = identity{}, 81 | const std::string &delim = ", ") -> 82 | const string_joiner { 83 | return {std::begin(t), std::end(t), func, delim}; 84 | } 85 | 86 | template 87 | inline auto joined(std::initializer_list t, const Func &func = identity{}, 88 | const std::string &delim = ", ") -> 89 | const string_joiner { 90 | return {std::begin(t), std::end(t), func, delim}; 91 | } 92 | 93 | } 94 | 95 | } // namespace mettle 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/detail/tuple_algorithm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DETAIL_TUPLE_ALGORITHM_HPP 2 | #define INC_METTLE_DETAIL_TUPLE_ALGORITHM_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mettle { 9 | 10 | namespace detail { 11 | 12 | template 13 | struct do_until { 14 | template 15 | do_until(Func &&f) { 16 | if(!f(std::integral_constant{})) 17 | do_until(std::forward(f)); 18 | } 19 | }; 20 | 21 | template 22 | struct do_until { 23 | template 24 | do_until(Func &&) {} 25 | }; 26 | 27 | template 28 | void tuple_for_until(Tuple &&tuple, Func &&f) { 29 | using T = typename std::remove_reference::type; 30 | do_until<0, std::tuple_size::value>([&](auto i) { 31 | return f(std::get(tuple)); 32 | }); 33 | } 34 | 35 | template 36 | class tuple_joiner { 37 | public: 38 | tuple_joiner(const Tuple &tuple, const Func &func, const std::string &delim) 39 | : tuple_(tuple), func_(func), delim_(delim) {} 40 | 41 | friend std::ostream & operator <<(std::ostream &os, const tuple_joiner &t) { 42 | std::size_t i = 0; 43 | tuple_for_until(t.tuple_, [&os, &i, &t](const auto &item) { 44 | if(i++ != 0) 45 | os << t.delim_; 46 | os << t.func_(item); 47 | return false; 48 | }); 49 | return os; 50 | } 51 | private: 52 | const Tuple &tuple_; 53 | const Func &func_; 54 | const std::string &delim_; 55 | }; 56 | 57 | template 58 | inline tuple_joiner 59 | tuple_joined(const Tuple &tuple, const Func &func, 60 | const std::string &delim = ", ") { 61 | return {tuple, func, delim}; 62 | } 63 | } 64 | 65 | } // namespace mettle 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/cmd_line.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_CMD_LINE_HPP 2 | #define INC_METTLE_DRIVER_CMD_LINE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "filters.hpp" 15 | #include "object_factory.hpp" 16 | #include "detail/export.hpp" 17 | #include "detail/optional.hpp" 18 | #include "log/core.hpp" 19 | #include "log/indent.hpp" 20 | 21 | #ifdef _WIN32 22 | # include 23 | #endif 24 | 25 | namespace mettle { 26 | 27 | struct generic_options { 28 | bool show_help = false; 29 | }; 30 | 31 | METTLE_PUBLIC boost::program_options::options_description 32 | make_generic_options(generic_options &opts); 33 | 34 | struct driver_options { 35 | METTLE_OPTIONAL_NS::optional timeout; 36 | filter_set filters; 37 | }; 38 | 39 | METTLE_PUBLIC boost::program_options::options_description 40 | make_driver_options(driver_options &opts); 41 | 42 | enum class color_option { 43 | never, 44 | automatic, 45 | always 46 | }; 47 | 48 | METTLE_PUBLIC bool 49 | color_enabled(color_option opt, int fd = 1 /* STDOUT_FILENO */); 50 | 51 | struct output_options { 52 | std::string output = "brief"; 53 | color_option color = color_option::automatic; 54 | std::size_t runs = 1; 55 | bool show_terminal = false; 56 | bool show_time = false; 57 | }; 58 | 59 | using logger_factory = object_factory< 60 | std::unique_ptr(indenting_ostream &, const output_options &) 61 | >; 62 | METTLE_PUBLIC logger_factory make_logger_factory(); 63 | 64 | METTLE_PUBLIC boost::program_options::options_description 65 | make_output_options(output_options &opts, const logger_factory &factory); 66 | 67 | METTLE_PUBLIC boost::program_options::option_description * 68 | has_option(const boost::program_options::options_description &options, 69 | const boost::program_options::variables_map &args); 70 | 71 | template 72 | std::vector> filter_options( 73 | const boost::program_options::basic_parsed_options &parsed, 74 | const boost::program_options::options_description &desc 75 | ) { 76 | std::vector> filtered; 77 | for(auto &&option : parsed.options) { 78 | if(desc.find_nothrow(option.string_key, false)) { 79 | auto &&tokens = option.original_tokens; 80 | filtered.insert(filtered.end(), tokens.begin(), tokens.end()); 81 | } 82 | } 83 | return filtered; 84 | } 85 | 86 | METTLE_PUBLIC attr_filter parse_attr(const std::string &value); 87 | 88 | METTLE_PUBLIC void 89 | validate(boost::any &v, const std::vector &values, 90 | color_option*, int); 91 | 92 | METTLE_PUBLIC void 93 | validate(boost::any &v, const std::vector &values, 94 | attr_filter_set*, int); 95 | 96 | METTLE_PUBLIC void 97 | validate(boost::any &v, const std::vector &values, 98 | name_filter_set*, int); 99 | 100 | } // namespace mettle 101 | 102 | // Put these in the boost namespace so that ADL picks them up (via the 103 | // boost::any parameter). 104 | namespace boost { 105 | 106 | METTLE_PUBLIC void 107 | validate(boost::any &v, const std::vector &values, 108 | std::chrono::milliseconds*, int); 109 | 110 | #ifdef _WIN32 111 | METTLE_PUBLIC void 112 | validate(boost::any &v, const std::vector &values, HANDLE*, int); 113 | #endif 114 | 115 | template 116 | void validate(boost::any &v, const std::vector &values, 117 | METTLE_OPTIONAL_NS::optional*, int) { 118 | using namespace boost::program_options; 119 | using optional_t = METTLE_OPTIONAL_NS::optional; 120 | 121 | if(v.empty()) 122 | v = optional_t(); 123 | auto *val = boost::any_cast(&v); 124 | assert(val); 125 | 126 | boost::any a; 127 | validate(a, values, static_cast(nullptr), 0); 128 | *val = boost::any_cast(a); 129 | } 130 | 131 | } // namespace boost 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/detail/bencode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_DETAIL_BENCODE_HPP 2 | #define INC_METTLE_DRIVER_DETAIL_BENCODE_HPP 3 | 4 | #ifdef METTLE_USE_STDLIB_EXTS 5 | # define BENCODE_USE_STDLIB_EXTS 6 | #endif 7 | 8 | #ifdef METTLE_NO_STDLIB_EXTS 9 | # define BENCODE_NO_STDLIB_EXTS 10 | #endif 11 | 12 | #include 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/detail/export.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_DETAIL_EXPORT_HPP 2 | #define INC_METTLE_DRIVER_DETAIL_EXPORT_HPP 3 | 4 | #if defined(_WIN32) && !defined(METTLE_STATIC) 5 | # ifdef LIBMETTLE_EXPORTS 6 | # define METTLE_PUBLIC __declspec(dllexport) 7 | # else 8 | # define METTLE_PUBLIC __declspec(dllimport) 9 | # endif 10 | #else 11 | # define METTLE_PUBLIC 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/detail/optional.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_DETAIL_OPTIONAL_HPP 2 | #define INC_METTLE_DRIVER_DETAIL_OPTIONAL_HPP 3 | 4 | // Get _LIBCPP_VERSION to detect libc++. 5 | #include 6 | 7 | // Try to use N4480's optional class, or fall back to Boost's. 8 | #if defined(METTLE_USE_STDLIB_EXTS) 9 | # include 10 | # define METTLE_OPTIONAL_NS std::experimental 11 | #elif !defined(METTLE_NO_STDLIB_EXTS) && defined(__has_include) 12 | // XXX: clang doesn't support SFINAE in variadic templates, which libstdc++'s 13 | // `optional` relies on. See . 14 | # if !(defined(__clang__) && !defined(_LIBCPP_VERSION) && \ 15 | defined(__GLIBCXX__)) && __has_include() 16 | # include 17 | # define METTLE_OPTIONAL_NS std::experimental 18 | # else 19 | # include 20 | # include 21 | # define METTLE_OPTIONAL_NS boost 22 | # endif 23 | #else 24 | # include 25 | # include 26 | # define METTLE_OPTIONAL_NS boost 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/exit_code.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_EXIT_CODE_HPP 2 | #define INC_METTLE_DRIVER_EXIT_CODE_HPP 3 | 4 | namespace mettle { 5 | 6 | namespace exit_code { 7 | // Exit codes >= 64 are designed to match sysexits.h values. 8 | constexpr const int success = 0; 9 | constexpr const int failure = 1; 10 | constexpr const int timeout = 32; 11 | constexpr const int bad_args = 64; 12 | constexpr const int no_inputs = 66; 13 | constexpr const int unknown_error = 70; 14 | constexpr const int fatal = 71; 15 | } 16 | 17 | } // namespace mettle 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/filters.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_FILTERS_HPP 2 | #define INC_METTLE_DRIVER_FILTERS_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "filters_core.hpp" 11 | #include "detail/export.hpp" 12 | 13 | namespace mettle { 14 | 15 | class name_filter_set { 16 | public: 17 | using value_type = std::regex; 18 | using container_type = std::vector; 19 | using iterator = container_type::const_iterator; 20 | 21 | name_filter_set() = default; 22 | name_filter_set(std::initializer_list i) : filters_(i) {} 23 | 24 | METTLE_PUBLIC filter_result 25 | operator ()(const test_name &name, const attributes &) const; 26 | 27 | void insert(const value_type &item) { 28 | filters_.push_back(item); 29 | } 30 | 31 | void insert(value_type &&item) { 32 | filters_.push_back(std::move(item)); 33 | } 34 | 35 | bool empty() const { 36 | return filters_.empty(); 37 | } 38 | 39 | std::size_t size() const { 40 | return filters_.size(); 41 | } 42 | 43 | iterator begin() const { 44 | return filters_.begin(); 45 | } 46 | 47 | iterator end() const { 48 | return filters_.end(); 49 | } 50 | private: 51 | container_type filters_; 52 | }; 53 | 54 | struct attr_filter_item { 55 | std::string attribute; 56 | std::function func; 57 | }; 58 | 59 | inline attr_filter_item 60 | has_attr(std::string name) { 61 | return {std::move(name), [](const attr_instance *attr) -> bool { 62 | return attr != nullptr; 63 | }}; 64 | } 65 | 66 | inline attr_filter_item 67 | has_attr(std::string name, std::string value) { 68 | auto f = [value = std::move(value)](const attr_instance *attr) -> bool { 69 | return attr && attr->value.count(value); 70 | }; 71 | return {std::move(name), std::move(f)}; 72 | } 73 | 74 | inline attr_filter_item 75 | operator !(attr_filter_item filter) { 76 | auto f = [func = std::move(filter.func)](const attr_instance *attr) -> bool { 77 | return !func(attr); 78 | }; 79 | return {std::move(filter.attribute), std::move(f)}; 80 | } 81 | 82 | class attr_filter { 83 | public: 84 | using value_type = attr_filter_item; 85 | using container_type = std::vector; 86 | using iterator = container_type::const_iterator; 87 | 88 | attr_filter() = default; 89 | attr_filter(std::initializer_list i) : filters_(i) {} 90 | 91 | METTLE_PUBLIC filter_result 92 | operator ()(const test_name &, const attributes &attrs) const; 93 | 94 | void insert(const value_type &item) { 95 | filters_.push_back(item); 96 | } 97 | 98 | void insert(value_type &&item) { 99 | filters_.push_back(std::move(item)); 100 | } 101 | 102 | bool empty() const { 103 | return filters_.empty(); 104 | } 105 | 106 | std::size_t size() const { 107 | return filters_.size(); 108 | } 109 | 110 | iterator begin() const { 111 | return filters_.begin(); 112 | } 113 | 114 | iterator end() const { 115 | return filters_.end(); 116 | } 117 | private: 118 | container_type filters_; 119 | }; 120 | 121 | class attr_filter_set { 122 | public: 123 | using value_type = attr_filter; 124 | using container_type = std::vector; 125 | using iterator = container_type::const_iterator; 126 | 127 | attr_filter_set() = default; 128 | attr_filter_set(std::initializer_list i) : filters_(i) {} 129 | 130 | METTLE_PUBLIC filter_result 131 | operator ()(const test_name &, const attributes &attrs) const; 132 | 133 | void insert(const value_type &item) { 134 | filters_.push_back(item); 135 | } 136 | 137 | void insert(value_type &&item) { 138 | filters_.push_back(std::move(item)); 139 | } 140 | 141 | bool empty() const { 142 | return filters_.empty(); 143 | } 144 | 145 | std::size_t size() const { 146 | return filters_.size(); 147 | } 148 | 149 | iterator begin() const { 150 | return filters_.begin(); 151 | } 152 | 153 | iterator end() const { 154 | return filters_.end(); 155 | } 156 | private: 157 | container_type filters_; 158 | }; 159 | 160 | struct filter_set { 161 | name_filter_set by_name; 162 | attr_filter_set by_attr; 163 | 164 | filter_result 165 | operator ()(const test_name &name, const attributes &attrs) const { 166 | auto first = by_name(name, attrs); 167 | if(first.action == test_action::hide) 168 | return first; 169 | 170 | auto second = by_attr(name, attrs); 171 | if(second.action == test_action::indeterminate) 172 | return first; 173 | return second; 174 | } 175 | }; 176 | 177 | } // namespace mettle 178 | 179 | #endif 180 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/filters_core.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_FILTERS_CORE_HPP 2 | #define INC_METTLE_DRIVER_FILTERS_CORE_HPP 3 | 4 | #include "../suite/attributes.hpp" 5 | #include "../detail/string_algorithm.hpp" 6 | #include "test_name.hpp" 7 | 8 | namespace mettle { 9 | 10 | struct filter_result { 11 | filter_result() = default; 12 | filter_result(test_action action, std::string message = "") 13 | : action(action), message(std::move(message)) {} 14 | 15 | test_action action; 16 | std::string message; 17 | }; 18 | 19 | struct default_filter { 20 | filter_result operator ()(const test_name &, const attributes &) const { 21 | return test_action::indeterminate; 22 | } 23 | }; 24 | 25 | inline filter_result filter_by_attr(const attributes &attrs) { 26 | using namespace detail; 27 | for(const auto &attr : attrs) { 28 | if(attr.attribute.action() == test_action::skip) 29 | return {test_action::skip, stringify(joined(attr.value))}; 30 | } 31 | return test_action::run; 32 | } 33 | 34 | } // namespace mettle 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/header_driver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_HEADER_DRIVER_HPP 2 | #define INC_METTLE_DRIVER_HEADER_DRIVER_HPP 3 | 4 | #include 5 | 6 | #define METTLE_STATIC 7 | 8 | #include "run_tests.hpp" 9 | #include "log/indent.hpp" 10 | #include "log/simple_summary.hpp" 11 | #include "../suite/detail/all_suites.hpp" 12 | #include "../suite/detail/built_in_attrs.hpp" 13 | 14 | int main() { 15 | using namespace mettle; 16 | 17 | indenting_ostream out(std::cout); 18 | 19 | log::simple_summary logger(out); 20 | run_tests(detail::all_suites(), logger, inline_test_runner); 21 | logger.summarize(); 22 | return !logger.good(); 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/lib_driver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_LIB_DRIVER_HPP 2 | #define INC_METTLE_DRIVER_LIB_DRIVER_HPP 3 | 4 | #include "detail/export.hpp" 5 | #include "../suite/detail/all_suites.hpp" 6 | #include "../suite/detail/built_in_attrs.hpp" 7 | 8 | namespace mettle { 9 | 10 | namespace detail { 11 | METTLE_PUBLIC int 12 | drive_tests(int argc, const char *argv[], const suites_list &suites); 13 | } 14 | 15 | } // namespace mettle 16 | 17 | int main(int argc, const char *argv[]) { 18 | return mettle::detail::drive_tests(argc, argv, mettle::detail::all_suites()); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/object_factory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_OBJECT_FACTORY_HPP 2 | #define INC_METTLE_DRIVER_OBJECT_FACTORY_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mettle { 11 | 12 | template 13 | class object_factory; 14 | 15 | template 16 | class object_factory { 17 | public: 18 | using result_type = Result; 19 | using function_type = std::function; 20 | using container_type = std::map; 21 | using iterator = typename container_type::const_iterator; 22 | 23 | void add(std::string name, function_type f) { 24 | registry_.emplace(std::move(name), std::move(f)); 25 | } 26 | 27 | template 28 | result_type make(const std::string &name, CallArgs &&...args) { 29 | return registry_.at(name)(std::forward(args)...); 30 | } 31 | 32 | iterator begin() const { 33 | return registry_.begin(); 34 | } 35 | 36 | iterator end() const { 37 | return registry_.end(); 38 | } 39 | private: 40 | container_type registry_; 41 | }; 42 | 43 | } // namespace mettle 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/posix/scoped_pipe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_POSIX_SCOPED_PIPE_HPP 2 | #define INC_METTLE_DRIVER_POSIX_SCOPED_PIPE_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace mettle { 10 | 11 | namespace posix { 12 | 13 | class scoped_pipe { 14 | public: 15 | scoped_pipe() = default; 16 | scoped_pipe(const scoped_pipe &) = delete; 17 | 18 | ~scoped_pipe() { 19 | close_read(); 20 | close_write(); 21 | } 22 | 23 | int open(int flags = 0) { 24 | assert(read_fd == -1 && write_fd == -1); 25 | #ifdef _GNU_SOURCE 26 | return pipe2(&read_fd, flags); 27 | #else 28 | if(pipe(&read_fd) == -1) 29 | return -1; 30 | 31 | if(flags & O_CLOEXEC) { 32 | if(fcntl(read_fd, F_SETFD, FD_CLOEXEC) == -1 || 33 | fcntl(write_fd, F_SETFD, FD_CLOEXEC) == -1) { 34 | read_fd = write_fd = -1; 35 | return -1; 36 | } 37 | } 38 | return 0; 39 | #endif 40 | } 41 | 42 | int close_read() { 43 | return do_close(read_fd); 44 | } 45 | 46 | int close_write() { 47 | return do_close(write_fd); 48 | } 49 | 50 | int move_read(int new_fd) { 51 | return do_move(read_fd, new_fd); 52 | } 53 | 54 | int move_write(int new_fd) { 55 | return do_move(write_fd, new_fd); 56 | } 57 | 58 | int read_fd = -1, write_fd = -1; 59 | private: 60 | int do_close(int &fd) { 61 | if(fd == -1) { 62 | errno = EBADF; 63 | return -1; 64 | } 65 | 66 | int err = ::close(fd); 67 | if(err == 0) 68 | fd = -1; 69 | return err; 70 | } 71 | 72 | int do_move(int &old_fd, int new_fd) { 73 | if(old_fd == -1) { 74 | errno = EBADF; 75 | return -1; 76 | } 77 | if(old_fd == new_fd) 78 | return 0; 79 | 80 | int err; 81 | if((err = dup2(old_fd, new_fd)) < 0) 82 | return err; 83 | return do_close(old_fd); 84 | } 85 | }; 86 | 87 | } 88 | 89 | } // namespace mettle 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/posix/scoped_signal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_POSIX_SCOPED_SIGNAL_HPP 2 | #define INC_METTLE_DRIVER_POSIX_SCOPED_SIGNAL_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mettle { 11 | 12 | namespace posix { 13 | 14 | class scoped_sigprocmask { 15 | public: 16 | scoped_sigprocmask() = default; 17 | scoped_sigprocmask(const scoped_sigprocmask &) = delete; 18 | 19 | ~scoped_sigprocmask() { 20 | clear(); 21 | } 22 | 23 | template 24 | int push(int how, const T &t) { 25 | return do_push(how, t); 26 | } 27 | 28 | int push(int how, std::initializer_list t) { 29 | return do_push(how, t); 30 | } 31 | 32 | int push(int how, int signum) { 33 | return push(how, {signum}); 34 | } 35 | 36 | int pop() { 37 | assert(!old_masks_.empty()); 38 | int err; 39 | if((err = sigprocmask(SIG_SETMASK, &old_masks_.back(), nullptr)) < 0) 40 | return err; 41 | 42 | old_masks_.pop_back(); 43 | return 0; 44 | } 45 | 46 | int clear() { 47 | if(!old_masks_.empty()) { 48 | int err; 49 | if((err = sigprocmask(SIG_SETMASK, &old_masks_.front(), nullptr)) < 0) 50 | return err; 51 | } 52 | 53 | old_masks_.clear(); 54 | return 0; 55 | } 56 | private: 57 | template 58 | int do_push(int how, const T &t) { 59 | int err; 60 | sigset_t mask; 61 | sigemptyset(&mask); 62 | for(auto &&signum : t) { 63 | if((err = sigaddset(&mask, signum)) < 0) 64 | return err; 65 | } 66 | 67 | try { 68 | old_masks_.emplace_back(); 69 | } 70 | catch(...) { 71 | errno = ENOMEM; 72 | return -1; 73 | } 74 | 75 | if((err = sigprocmask(how, &mask, &old_masks_.back())) < 0) 76 | old_masks_.pop_back(); 77 | return err; 78 | } 79 | 80 | std::vector old_masks_; 81 | }; 82 | 83 | class scoped_sigaction { 84 | public: 85 | using function_type = void (*)(int); 86 | 87 | scoped_sigaction() = default; 88 | scoped_sigaction(const scoped_sigaction &) = delete; 89 | 90 | ~scoped_sigaction() { 91 | close(); 92 | } 93 | 94 | int open(int sig, function_type handler) { 95 | assert(signum == 0); 96 | signum = sig; 97 | sigemptyset(&act.sa_mask); 98 | act.sa_flags = 0; 99 | act.sa_handler = handler; 100 | return sigaction(signum, &act, &old_act); 101 | } 102 | 103 | int close() { 104 | if(signum == 0) { 105 | errno = EINVAL; 106 | return -1; 107 | } 108 | 109 | int err; 110 | err = sigaction(signum, &old_act, nullptr); 111 | signum = 0; 112 | return err; 113 | } 114 | private: 115 | int signum = 0; 116 | struct sigaction act, old_act; 117 | }; 118 | 119 | } 120 | 121 | } // namespace mettle 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/posix/subprocess.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_POSIX_SUBPROCESS_HPP 2 | #define INC_METTLE_DRIVER_POSIX_SUBPROCESS_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mettle { 11 | 12 | namespace posix { 13 | struct readfd { 14 | int fd; 15 | std::string *dest; 16 | }; 17 | 18 | void make_timeout_monitor(std::chrono::milliseconds timeout); 19 | 20 | int read_into(std::vector &dests, const timespec *timeout, 21 | const sigset_t *sigmask); 22 | 23 | int send_pgid(int fd, int pgid); 24 | int recv_pgid(int fd, int *pgid); 25 | } 26 | 27 | } // namespace mettle 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/run_tests.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_RUN_TESTS_HPP 2 | #define INC_METTLE_DRIVER_RUN_TESTS_HPP 3 | 4 | #include "../suite/compiled_suite.hpp" 5 | #include "filters_core.hpp" 6 | #include "log/core.hpp" 7 | 8 | namespace mettle { 9 | 10 | using test_runner = std::function< 11 | test_result(const test_info &, log::test_output &) 12 | >; 13 | 14 | namespace detail { 15 | class suite_stack { 16 | public: 17 | using value_type = std::vector; 18 | 19 | template 20 | void push(T &&t) { 21 | queued_.push_back(std::forward(t)); 22 | } 23 | 24 | void pop() { 25 | if(!queued_.empty()) 26 | queued_.pop_back(); 27 | else 28 | committed_.pop_back(); 29 | } 30 | 31 | template 32 | void commit(T &&callback) { 33 | if(!queued_.empty()) { 34 | for(auto &&i : queued_) { 35 | committed_.push_back(std::move(i)); 36 | callback(committed_); 37 | } 38 | queued_.clear(); 39 | } 40 | } 41 | 42 | const value_type committed() const { 43 | return committed_; 44 | } 45 | 46 | value_type all() const { 47 | value_type all = committed_; 48 | all.insert(all.end(), queued_.begin(), queued_.end()); 49 | return all; 50 | } 51 | 52 | bool has_queued() const { 53 | return !queued_.empty(); 54 | } 55 | private: 56 | value_type committed_, queued_; 57 | }; 58 | 59 | template 60 | void run_tests_impl( 61 | const Suites &suites, log::test_logger &logger, const test_runner &runner, 62 | const Filter &filter, suite_stack &parents 63 | ) { 64 | for(const auto &suite : suites) { 65 | parents.push(suite.name()); 66 | 67 | for(const auto &test : suite.tests()) { 68 | const test_name name = {parents.all(), test.name, test.id}; 69 | auto action = filter(name, test.attrs); 70 | if(action.action == test_action::indeterminate) 71 | action = filter_by_attr(test.attrs); 72 | 73 | if(action.action == test_action::hide) 74 | continue; 75 | parents.commit([&logger](const auto &committed) { 76 | logger.started_suite(committed); 77 | }); 78 | 79 | logger.started_test(name); 80 | 81 | if(action.action == test_action::skip) { 82 | logger.skipped_test(name, action.message); 83 | continue; 84 | } 85 | 86 | log::test_output output; 87 | 88 | using namespace std::chrono; 89 | auto then = steady_clock::now(); 90 | auto result = runner(test, output); 91 | auto now = steady_clock::now(); 92 | auto duration = duration_cast(now - then); 93 | 94 | if(result.passed) 95 | logger.passed_test(name, output, duration); 96 | else 97 | logger.failed_test(name, result.message, output, duration); 98 | } 99 | 100 | run_tests_impl(suite.subsuites(), logger, runner, filter, parents); 101 | 102 | if(!parents.has_queued()) 103 | logger.ended_suite(parents.committed()); 104 | parents.pop(); 105 | } 106 | } 107 | } 108 | 109 | inline test_result 110 | inline_test_runner(const test_info &test, log::test_output &) { 111 | return test.function(); 112 | } 113 | 114 | template 115 | void run_tests(const Suites &suites, log::test_logger &logger, 116 | const test_runner &runner, const Filter &filter) { 117 | detail::suite_stack parents; 118 | logger.started_run(); 119 | detail::run_tests_impl(suites, logger, runner, filter, parents); 120 | logger.ended_run(); 121 | } 122 | 123 | template 124 | inline void run_tests(const Suites &suites, log::test_logger &&logger, 125 | const test_runner &runner, const Filter &filter) { 126 | run_tests(suites, logger, runner, filter); 127 | } 128 | 129 | template 130 | inline void run_tests(const Suites &suites, log::test_logger &logger, 131 | const test_runner &runner) { 132 | run_tests(suites, logger, runner, default_filter()); 133 | } 134 | 135 | template 136 | inline void run_tests(const Suites &suites, log::test_logger &&logger, 137 | const test_runner &runner) { 138 | run_tests(suites, logger, runner, default_filter()); 139 | } 140 | 141 | } // namespace mettle 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/subprocess_test_runner.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_SUBPROCESS_TEST_RUNNER_HPP 2 | #define INC_METTLE_DRIVER_SUBPROCESS_TEST_RUNNER_HPP 3 | 4 | #include 5 | 6 | #ifdef _WIN32 7 | # include 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace mettle { 16 | 17 | class METTLE_PUBLIC subprocess_test_runner { 18 | public: 19 | using timeout_t = METTLE_OPTIONAL_NS::optional; 20 | 21 | subprocess_test_runner(timeout_t timeout = {}) : timeout_(timeout) {} 22 | 23 | template 24 | subprocess_test_runner(std::chrono::duration timeout) 25 | : timeout_(timeout) {} 26 | 27 | test_result 28 | operator ()(const test_info &test, log::test_output &output) const; 29 | private: 30 | timeout_t timeout_; 31 | }; 32 | 33 | #ifndef _WIN32 34 | 35 | int make_fd_private(int fd); 36 | 37 | #else 38 | 39 | METTLE_PUBLIC int make_fd_private(HANDLE handle); 40 | 41 | METTLE_PUBLIC const test_info * 42 | find_test(const suites_list &suites, test_uid id); 43 | 44 | METTLE_PUBLIC bool run_single_test(const test_info &test, HANDLE log_pipe); 45 | 46 | #endif 47 | 48 | } // namespace mettle 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/test_name.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_TEST_NAME_HPP 2 | #define INC_METTLE_DRIVER_TEST_NAME_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../test_uid.hpp" 9 | 10 | namespace mettle { 11 | 12 | struct test_name { 13 | std::vector suites; 14 | std::string test; 15 | test_uid id; 16 | 17 | std::string full_name() const { 18 | std::ostringstream ss; 19 | for(const auto &i : suites) 20 | ss << i << " > "; 21 | ss << test; 22 | return ss.str(); 23 | } 24 | }; 25 | 26 | inline bool operator ==(const test_name &lhs, const test_name &rhs) { 27 | return lhs.id == rhs.id; 28 | } 29 | inline bool operator !=(const test_name &lhs, const test_name &rhs) { 30 | return lhs.id != rhs.id; 31 | } 32 | inline bool operator <(const test_name &lhs, const test_name &rhs) { 33 | return lhs.id < rhs.id; 34 | } 35 | inline bool operator <=(const test_name &lhs, const test_name &rhs) { 36 | return lhs.id <= rhs.id; 37 | } 38 | inline bool operator >(const test_name &lhs, const test_name &rhs) { 39 | return lhs.id > rhs.id; 40 | } 41 | inline bool operator >=(const test_name &lhs, const test_name &rhs) { 42 | return lhs.id >= rhs.id; 43 | } 44 | 45 | } // namespace mettle 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/windows/scoped_handle.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_WINDOWS_SCOPED_HANDLE_HPP 2 | #define INC_METTLE_DRIVER_WINDOWS_SCOPED_HANDLE_HPP 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "../detail/export.hpp" 9 | 10 | namespace mettle { 11 | 12 | namespace windows { 13 | 14 | class METTLE_PUBLIC scoped_handle { 15 | public: 16 | scoped_handle(HANDLE handle = nullptr) : handle_(handle) {} 17 | scoped_handle(const scoped_handle &) = delete; 18 | 19 | ~scoped_handle() { 20 | close(); 21 | } 22 | 23 | scoped_handle & operator =(HANDLE handle) { 24 | assert(handle_ == nullptr); 25 | handle_ = handle; 26 | return *this; 27 | } 28 | 29 | bool close(); 30 | 31 | const HANDLE & handle() const { 32 | return handle_; 33 | } 34 | 35 | HANDLE & handle() { 36 | return handle_; 37 | } 38 | 39 | operator const HANDLE &() const { 40 | return handle_; 41 | } 42 | 43 | operator HANDLE &() { 44 | return handle_; 45 | } 46 | 47 | explicit operator bool() const { 48 | return handle_ != nullptr; 49 | } 50 | private: 51 | HANDLE handle_; 52 | }; 53 | 54 | } 55 | 56 | } // namespace mettle 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/windows/scoped_pipe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_WINDOWS_SCOPED_PIPE_HPP 2 | #define INC_METTLE_DRIVER_WINDOWS_SCOPED_PIPE_HPP 3 | 4 | #include 5 | 6 | #include "scoped_handle.hpp" 7 | #include "../detail/export.hpp" 8 | 9 | namespace mettle { 10 | 11 | namespace windows { 12 | 13 | class METTLE_PUBLIC scoped_pipe { 14 | public: 15 | scoped_pipe() = default; 16 | scoped_pipe(const scoped_pipe &) = delete; 17 | 18 | bool open(bool overlapped_read, bool overlapped_write); 19 | 20 | bool open() { 21 | return open(false, false); 22 | } 23 | 24 | bool set_read_inherit(bool inherit) { 25 | return do_set_inherit(read_handle, inherit); 26 | } 27 | 28 | bool set_write_inherit(bool inherit) { 29 | return do_set_inherit(write_handle, inherit); 30 | } 31 | 32 | bool close_read() { 33 | return read_handle.close(); 34 | } 35 | 36 | bool close_write() { 37 | return write_handle.close(); 38 | } 39 | 40 | scoped_handle read_handle, write_handle; 41 | private: 42 | bool do_set_inherit(HANDLE &handle, bool inherit); 43 | }; 44 | 45 | } 46 | 47 | } // namespace mettle 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/driver/windows/subprocess.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_DRIVER_WINDOWS_SUBPROCESS_HPP 2 | #define INC_METTLE_DRIVER_WINDOWS_SUBPROCESS_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "../detail/export.hpp" 10 | 11 | namespace mettle { 12 | 13 | namespace windows { 14 | struct readhandle { 15 | HANDLE handle; 16 | std::string *dest; 17 | }; 18 | 19 | METTLE_PUBLIC HANDLE 20 | read_into(std::vector &dests, DWORD timeout, 21 | const std::vector &interrupts); 22 | } 23 | 24 | } // namespace mettle 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/glue.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_GLUE_HPP 2 | #define INC_METTLE_GLUE_HPP 3 | 4 | #include 5 | 6 | #include "suite/make_suite.hpp" 7 | #include "suite/global_suite.hpp" 8 | #include "matchers/expect.hpp" 9 | 10 | namespace mettle { 11 | 12 | template 13 | inline runnable_suite 14 | make_suite(const std::string &name, const attributes &attrs, 15 | Factory &&factory, F &&f) { 16 | return make_basic_suite( 17 | name, attrs, std::forward(factory), std::forward(f) 18 | ); 19 | } 20 | 21 | template 22 | inline runnable_suite 23 | make_suite(const std::string &name, Factory &&factory, F &&f) { 24 | return make_basic_suite( 25 | name, std::forward(factory), std::forward(f) 26 | ); 27 | } 28 | 29 | template 30 | inline runnable_suite 31 | make_suite(const std::string &name, const attributes &attrs, F &&f) { 32 | return make_suite(name, attrs, auto_factory, std::forward(f)); 33 | } 34 | 35 | template 36 | inline runnable_suite 37 | make_suite(const std::string &name, F &&f) { 38 | return make_suite(name, auto_factory, std::forward(f)); 39 | } 40 | 41 | template 42 | inline std::array 43 | make_suites(const std::string &name, const attributes &attrs, 44 | Factory &&factory, F &&f) { 45 | return make_basic_suites( 46 | name, attrs, std::forward(factory), std::forward(f) 47 | ); 48 | } 49 | 50 | template 51 | inline std::array 52 | make_suites(const std::string &name, Factory &&factory, F &&f) { 53 | return make_basic_suites( 54 | name, std::forward(factory), std::forward(f) 55 | ); 56 | } 57 | 58 | template 59 | inline std::array 60 | make_suites(const std::string &name, const attributes &attrs, F &&f) { 61 | return make_suites(name, attrs, auto_factory, std::forward(f)); 62 | } 63 | 64 | template 65 | inline std::array 66 | make_suites(const std::string &name, F &&f) { 67 | return make_suites(name, auto_factory, std::forward(f)); 68 | } 69 | 70 | template 71 | using suite = basic_suite; 72 | 73 | } // namespace mettle 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/header_only.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_HEADER_ONLY_HPP 2 | #define INC_METTLE_HEADER_ONLY_HPP 3 | 4 | #include "suite.hpp" 5 | #include "matchers.hpp" 6 | #include "driver/header_driver.hpp" 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_HPP 2 | #define INC_METTLE_MATCHERS_HPP 3 | 4 | #include "matchers/core.hpp" 5 | #include "matchers/expect.hpp" 6 | #include "matchers/relational.hpp" 7 | #include "matchers/arithmetic.hpp" 8 | #include "matchers/regex.hpp" 9 | #include "matchers/combinatoric.hpp" 10 | #include "matchers/collection.hpp" 11 | #include "matchers/exception.hpp" 12 | #include "matchers/death.hpp" 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/any_capture.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_ANY_CAPTURE_HPP 2 | #define INC_METTLE_MATCHERS_ANY_CAPTURE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mettle { 8 | 9 | template 10 | class any_capture { 11 | public: 12 | using type = T; 13 | 14 | constexpr any_capture(const T &t) : value(t) {} 15 | constexpr any_capture(T &&t) : value(std::move(t)) {} 16 | 17 | T value; 18 | }; 19 | 20 | template 21 | class any_capture { 22 | public: 23 | using type = T[N]; 24 | 25 | constexpr any_capture(const T (&t)[N]) 26 | : any_capture(t, std::make_index_sequence()) {} 27 | constexpr any_capture(T (&&t)[N]) 28 | : any_capture(std::move(t), std::make_index_sequence()) {} 29 | 30 | T value[N]; 31 | private: 32 | template 33 | constexpr any_capture(const T (&t)[N], std::index_sequence) 34 | : value{t[I]...} {} 35 | 36 | template 37 | constexpr any_capture(T (&&t)[N], std::index_sequence) 38 | : value{std::move(t[I])...} {} 39 | }; 40 | 41 | template 42 | class any_capture : public any_capture { 43 | using any_capture::any_capture; 44 | }; 45 | 46 | template 47 | class any_capture { 48 | static_assert(std::is_same::value, 49 | "any_capture can't be used by incomplete array types"); 50 | }; 51 | 52 | } // namespace mettle 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/arithmetic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_ARITHMETIC_HPP 2 | #define INC_METTLE_MATCHERS_ARITHMETIC_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "core.hpp" 10 | 11 | namespace mettle { 12 | 13 | template 14 | auto near_to(T &&expected, U &&epsilon) { 15 | return make_matcher( 16 | std::forward(expected), 17 | [epsilon = std::forward(epsilon)]( 18 | const auto &actual, const auto &expected 19 | ) -> bool { 20 | // If one of expected or actual is NaN, mag is undefined, but that's ok 21 | // because we'll always return false in that case, just like we should. 22 | auto mag = std::max(std::abs(expected), std::abs(actual)); 23 | return std::abs(actual - expected) <= mag * epsilon; 24 | }, "~= " 25 | ); 26 | } 27 | 28 | template 29 | inline auto near_to(T &&expected) { 30 | using ValueType = std::remove_cv_t>; 31 | static_assert(!std::numeric_limits::is_integer, 32 | "near_to(x) not defined for integral types"); 33 | 34 | return near_to(std::forward(expected), 35 | std::numeric_limits::epsilon() * 10); 36 | } 37 | 38 | template 39 | auto near_to_abs(T &&expected, U &&tolerance) { 40 | return make_matcher( 41 | std::forward(expected), 42 | [tolerance = std::forward(tolerance)]( 43 | const auto &actual, const auto &expected 44 | ) -> bool { 45 | return std::abs(actual - expected) <= tolerance; 46 | }, "~= " 47 | ); 48 | } 49 | 50 | } // namespace mettle 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/combinatoric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_COMBINATORIC_HPP 2 | #define INC_METTLE_MATCHERS_COMBINATORIC_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "core.hpp" 8 | #include "../detail/tuple_algorithm.hpp" 9 | 10 | namespace mettle { 11 | 12 | namespace detail { 13 | template 14 | class reduce_impl : public matcher_tag { 15 | public: 16 | reduce_impl(std::string desc, bool initial, Reducer reducer, T ...matchers) 17 | : desc_(std::move(desc)), initial_(initial), reducer_(std::move(reducer)), 18 | matchers_(std::move(matchers)...) {} 19 | 20 | template 21 | match_result operator ()(const U &value) const { 22 | match_result result = initial_; 23 | tuple_for_until(matchers_, [&, this](const auto &matcher) { 24 | auto m = matcher(value); 25 | bool done = reducer_(initial_, m) != initial_; 26 | if(done) 27 | result = std::move(m); 28 | return done; 29 | }); 30 | return result; 31 | } 32 | 33 | std::string desc() const { 34 | std::ostringstream ss; 35 | ss << desc_ << "(" << tuple_joined(matchers_, [](auto &&matcher) { 36 | return matcher.desc(); 37 | }) << ")"; 38 | return ss.str(); 39 | } 40 | private: 41 | const std::string desc_; 42 | const bool initial_; 43 | Reducer reducer_; 44 | std::tuple matchers_; 45 | }; 46 | } 47 | 48 | // We'd call these any_of, all_of, and none_of like the std:: functions, but 49 | // doing so would introduce an ambiguity where the std:: versions could be 50 | // preferred via ADL if we pass in three arguments. 51 | 52 | template 53 | inline auto any(T &&...things) { 54 | return detail::reduce_impl, ensure_matcher_t...>( 55 | "any of", false, std::logical_or(), 56 | ensure_matcher(std::forward(things))... 57 | ); 58 | } 59 | 60 | template 61 | inline auto all(T &&...things) { 62 | return detail::reduce_impl, ensure_matcher_t...>( 63 | "all of", true, std::logical_and(), 64 | ensure_matcher(std::forward(things))... 65 | ); 66 | } 67 | 68 | template 69 | inline auto none(T &&...things) { 70 | auto reducer = [](bool a, bool b) { return a && !b; }; 71 | return detail::reduce_impl...>( 72 | "none of", true, std::move(reducer), 73 | ensure_matcher(std::forward(things))... 74 | ); 75 | } 76 | 77 | } // namespace mettle 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/core.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_CORE_HPP 2 | #define INC_METTLE_MATCHERS_CORE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../output.hpp" 10 | #include "any_capture.hpp" 11 | #include "result.hpp" 12 | 13 | namespace mettle { 14 | 15 | struct matcher_tag {}; 16 | 17 | template 18 | struct is_matcher : public std::is_base_of< 19 | matcher_tag, typename std::remove_reference::type 20 | > {}; 21 | 22 | template 23 | constexpr bool is_matcher_v = is_matcher::value; 24 | 25 | namespace detail { 26 | template 27 | inline auto matcher_desc(T &&matcher) -> std::enable_if_t< 28 | is_matcher_v, decltype( std::forward(matcher).desc() ) 29 | > { 30 | return std::forward(matcher).desc(); 31 | } 32 | 33 | template 34 | inline auto matcher_desc(T &&expected) -> std::enable_if_t< 35 | !is_matcher_v, decltype( to_printable(std::forward(expected)) ) 36 | > { 37 | return to_printable(std::forward(expected)); 38 | } 39 | } 40 | 41 | template 42 | class basic_matcher : public matcher_tag { 43 | public: 44 | basic_matcher(any_capture thing, F f, std::string prefix) 45 | : thing_(std::move(thing)), f_(std::move(f)), prefix_(std::move(prefix)) {} 46 | basic_matcher(any_capture thing, F f, 47 | std::pair format) 48 | : thing_(std::move(thing)), f_(std::move(f)), 49 | prefix_(std::move(format.first)), suffix_(std::move(format.second)) {} 50 | 51 | template 52 | decltype(auto) operator ()(U &&actual) const { 53 | return f_(std::forward(actual), thing_.value); 54 | } 55 | 56 | std::string desc() const { 57 | std::ostringstream ss; 58 | ss << prefix_ << detail::matcher_desc(thing_.value) << suffix_; 59 | return ss.str(); 60 | } 61 | private: 62 | any_capture thing_; 63 | F f_; 64 | std::string prefix_, suffix_; 65 | }; 66 | 67 | template 68 | class basic_matcher : public matcher_tag { 69 | public: 70 | template 71 | basic_matcher(F2 &&f, std::string desc) 72 | : f_(std::forward(f)), desc_(std::move(desc)) {} 73 | 74 | template 75 | decltype(auto) operator ()(U &&actual) const { 76 | return f_(std::forward(actual)); 77 | } 78 | 79 | const std::string & desc() const { 80 | return desc_; 81 | } 82 | private: 83 | F f_; 84 | std::string desc_; 85 | }; 86 | 87 | template 88 | inline auto make_matcher(T &&thing, F &&f, String &&prefix) { 89 | return basic_matcher< 90 | std::remove_reference_t, std::remove_reference_t 91 | >(std::forward(thing), std::forward(f), std::forward(prefix)); 92 | } 93 | 94 | template 95 | inline auto 96 | make_matcher(T &&thing, F &&f, std::pair format) { 97 | return basic_matcher< 98 | std::remove_reference_t, std::remove_reference_t 99 | >(std::forward(thing), std::forward(f), std::move(format)); 100 | } 101 | 102 | template 103 | inline auto make_matcher(F &&f, String &&desc) { 104 | return basic_matcher< 105 | void, std::remove_reference_t 106 | >(std::forward(f), std::forward(desc)); 107 | } 108 | 109 | template 110 | auto equal_to(T &&expected) { 111 | return make_matcher(std::forward(expected), std::equal_to<>(), ""); 112 | } 113 | 114 | inline auto anything() { 115 | return make_matcher([](const auto &) -> bool { 116 | return true; 117 | }, "anything"); 118 | } 119 | 120 | template 121 | inline auto ensure_matcher(T &&matcher) -> std::enable_if_t< 122 | is_matcher_v, decltype( std::forward(matcher) ) 123 | > { 124 | return std::forward(matcher); 125 | } 126 | 127 | template 128 | inline auto ensure_matcher(T &&expected) -> std::enable_if_t< 129 | !is_matcher_v, decltype( equal_to(std::forward(expected)) ) 130 | > { 131 | return equal_to(std::forward(expected)); 132 | } 133 | 134 | template 135 | struct ensure_matcher_type : public std::remove_reference< 136 | decltype(ensure_matcher(std::declval())) 137 | > {}; 138 | 139 | template 140 | using ensure_matcher_t = typename ensure_matcher_type::type; 141 | 142 | template 143 | inline auto is_not(T &&thing) { 144 | return make_matcher( 145 | ensure_matcher(std::forward(thing)), 146 | [](const auto &value, auto &&matcher) { 147 | return !matcher(value); 148 | }, "not " 149 | ); 150 | } 151 | 152 | template 153 | inline auto describe(T &&matcher, const std::string &desc) { 154 | return make_matcher(std::forward(matcher), desc); 155 | } 156 | 157 | template 158 | auto filter(Filter &&f, Matcher &&matcher, const std::string &desc = "") { 159 | return make_matcher( 160 | std::forward(matcher), 161 | [f = std::forward(f), desc](const auto &actual, auto &&matcher) { 162 | auto filtered = f(actual); 163 | auto result = matcher(filtered); 164 | std::ostringstream ss; 165 | ss << desc << matcher_message(result, filtered); 166 | return match_result(result, ss.str()); 167 | }, desc 168 | ); 169 | } 170 | 171 | } // namespace mettle 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/death.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_DEATH_HPP 2 | #define INC_METTLE_MATCHERS_DEATH_HPP 3 | 4 | #ifndef _WIN32 5 | 6 | #include "core.hpp" 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace mettle { 15 | 16 | namespace detail { 17 | template 18 | int get_status(T &&func, U &&terminate) { 19 | pid_t pid; 20 | if((pid = fork()) < 0) 21 | throw std::system_error(errno, std::system_category()); 22 | if(pid == 0) { 23 | try { 24 | func(); 25 | } 26 | catch(...) {} 27 | terminate(); 28 | assert(false && "should never get here"); 29 | } 30 | else { 31 | int status; 32 | if(waitpid(pid, &status, 0) < 0) 33 | throw std::system_error(errno, std::system_category()); 34 | return status; 35 | } 36 | } 37 | 38 | template 39 | class killed_impl : public matcher_tag { 40 | public: 41 | template 42 | killed_impl(T &&t, bool verbose = true) 43 | : matcher_(std::forward(t)), verbose_(verbose) {} 44 | 45 | template 46 | match_result operator ()(U &&value) const { 47 | int status = get_status(std::forward(value), terminate); 48 | if(WIFSIGNALED(status)) { 49 | std::ostringstream ss; 50 | ss << "killed with signal " << WTERMSIG(status); 51 | return { matcher_(WTERMSIG(status)), ss.str() }; 52 | } 53 | return { false, "wasn't killed" }; 54 | } 55 | 56 | std::string desc() const { 57 | std::ostringstream ss; 58 | ss << "killed"; 59 | if(verbose_) 60 | ss << " with signal " << matcher_.desc(); 61 | return ss.str(); 62 | } 63 | private: 64 | [[noreturn]] static void terminate() { 65 | _exit(0); 66 | } 67 | 68 | Matcher matcher_; 69 | bool verbose_; 70 | }; 71 | 72 | template 73 | class exited_impl : public matcher_tag { 74 | public: 75 | template 76 | exited_impl(T &&t, bool verbose = true) 77 | : matcher_(std::forward(t)), verbose_(verbose) {} 78 | 79 | template 80 | match_result operator ()(U &&value) const { 81 | int status = get_status(std::forward(value), terminate); 82 | if(WIFEXITED(status)) { 83 | std::ostringstream ss; 84 | ss << "exited with status " << WEXITSTATUS(status); 85 | return { matcher_(WEXITSTATUS(status)), ss.str() }; 86 | } 87 | return { false, "didn't exit" }; 88 | } 89 | 90 | std::string desc() const { 91 | std::ostringstream ss; 92 | ss << "exited"; 93 | if(verbose_) 94 | ss << " with status " << matcher_.desc(); 95 | return ss.str(); 96 | } 97 | private: 98 | [[noreturn]] static void terminate() { 99 | abort(); 100 | } 101 | 102 | Matcher matcher_; 103 | bool verbose_; 104 | }; 105 | } 106 | 107 | inline auto killed() { 108 | return detail::killed_impl(anything(), false); 109 | } 110 | 111 | template 112 | inline auto killed(T &&thing) { 113 | auto matcher = ensure_matcher(std::forward(thing)); 114 | return detail::killed_impl(std::move(matcher)); 115 | } 116 | 117 | inline auto exited() { 118 | return detail::exited_impl(anything(), false); 119 | } 120 | 121 | template 122 | inline auto exited(T &&thing) { 123 | auto matcher = ensure_matcher(std::forward(thing)); 124 | return detail::exited_impl(std::move(matcher)); 125 | } 126 | 127 | } // namespace mettle 128 | 129 | #endif 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/detail/source_location.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_DETAIL_SOURCE_LOCATION_HPP 2 | #define INC_METTLE_MATCHERS_DETAIL_SOURCE_LOCATION_HPP 3 | 4 | // Get _LIBCPP_VERSION to detect libc++. 5 | #include 6 | 7 | #if defined(METTLE_USE_STDLIB_EXTS) 8 | # include 9 | # define METTLE_SOURCE_LOCATION std::experimental::source_location 10 | #elif !defined(METTLE_NO_STDLIB_EXTS) && defined(__has_include) 11 | // XXX: clang probably won't support libstdc++'s source_location, since it 12 | // lacks the required compiler magic. Just disable it for now. See 13 | // . 14 | # if !(defined(__clang__) && !defined(_LIBCPP_VERSION) && \ 15 | defined(__GLIBCXX__)) && __has_include() 16 | # include 17 | # define METTLE_SOURCE_LOCATION std::experimental::source_location 18 | # else 19 | # include "source_location_shim.hpp" 20 | # define METTLE_SOURCE_LOCATION mettle::detail::source_location 21 | # endif 22 | #else 23 | # include "source_location_shim.hpp" 24 | # define METTLE_SOURCE_LOCATION mettle::detail::source_location 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/detail/source_location_shim.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_DETAIL_SOURCE_LOCATION_SHIM_HPP 2 | #define INC_METTLE_MATCHERS_DETAIL_SOURCE_LOCATION_SHIM_HPP 3 | 4 | #include 5 | 6 | // Only GCC has the intrinsics necessary to support this shim. 7 | #if !defined(__GNUG__) || defined(__clang__) 8 | # define METTLE_NO_SOURCE_LOCATION 9 | #endif 10 | 11 | namespace mettle { 12 | 13 | namespace detail { 14 | 15 | class source_location { 16 | public: 17 | constexpr source_location() noexcept : 18 | file_("unknown"), func_("unknown"), line_(0), col_(0) {} 19 | 20 | static source_location current( 21 | #ifdef METTLE_NO_SOURCE_LOCATION 22 | const char *file = "unknown", 23 | const char *func = "unknown", 24 | std::uint_least32_t line = 0, 25 | std::uint_least32_t col = 0 26 | #else 27 | const char *file = __builtin_FILE(), 28 | const char *func = __builtin_FUNCTION(), 29 | std::uint_least32_t line = __builtin_LINE(), 30 | std::uint_least32_t col = 0 31 | #endif 32 | ) { 33 | source_location loc; 34 | loc.file_ = file; 35 | loc.func_ = func; 36 | loc.line_ = line; 37 | loc.col_ = col; 38 | return loc; 39 | } 40 | 41 | constexpr const char* file_name() const { 42 | return file_; 43 | } 44 | 45 | constexpr const char* function_name() const { 46 | return func_; 47 | } 48 | 49 | constexpr std::uint_least32_t line() const { 50 | return line_; 51 | } 52 | 53 | constexpr std::uint_least32_t column() const { 54 | return col_; 55 | } 56 | private: 57 | const char *file_, *func_; 58 | std::uint_least32_t line_, col_; 59 | }; 60 | 61 | } 62 | 63 | } // namespace mettle 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/exception.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_EXCEPTION_HPP 2 | #define INC_METTLE_MATCHERS_EXCEPTION_HPP 3 | 4 | #include "core.hpp" 5 | 6 | namespace mettle { 7 | 8 | namespace detail { 9 | template 10 | class thrown_impl_base : public matcher_tag { 11 | public: 12 | template 13 | thrown_impl_base(T &&t) : matcher(std::forward(t)) {} 14 | 15 | std::string desc() const { 16 | std::ostringstream ss; 17 | ss << "threw " << type_name() << "(" << matcher.desc() << ")"; 18 | return ss.str(); 19 | } 20 | protected: 21 | match_result match(const Exception &e) const { 22 | match_result m = matcher(e); 23 | std::ostringstream ss; 24 | ss << "threw "; 25 | if(m.message.empty()) 26 | ss << to_printable(e); 27 | else 28 | ss << type_name(e) << "(" << m.message << ")"; 29 | return {m.matched, ss.str()}; 30 | } 31 | private: 32 | Matcher matcher; 33 | }; 34 | 35 | 36 | template 37 | struct thrown_impl : thrown_impl_base { 38 | using base = thrown_impl_base; 39 | 40 | using base::base; 41 | 42 | template 43 | match_result operator ()(U &&value) const { 44 | try { 45 | value(); 46 | return {false, "threw nothing"}; 47 | } 48 | catch(const Exception &e) { 49 | return base::match(e); 50 | } 51 | catch(const std::exception &e) { 52 | std::ostringstream ss; 53 | ss << "threw " << to_printable(e); 54 | return {false, ss.str()}; 55 | } 56 | catch(...) { 57 | return {false, "threw unknown exception"}; 58 | } 59 | } 60 | }; 61 | 62 | template 63 | struct thrown_impl 64 | : thrown_impl_base { 65 | using base = thrown_impl_base; 66 | 67 | using base::base; 68 | 69 | template 70 | match_result operator ()(U &&value) const { 71 | try { 72 | value(); 73 | return {false, "threw nothing"}; 74 | } 75 | catch(const std::exception &e) { 76 | return base::match(e); 77 | } 78 | catch(...) { 79 | return {false, "threw unknown exception"}; 80 | } 81 | } 82 | }; 83 | 84 | } 85 | 86 | template 87 | auto thrown_raw(T &&thing) { 88 | auto matcher = ensure_matcher(std::forward(thing)); 89 | return detail::thrown_impl(std::move(matcher)); 90 | } 91 | 92 | template 93 | auto thrown(T &&thing) { 94 | return thrown_raw(filter( 95 | [](auto &&e) { return std::string(e.what()); }, 96 | ensure_matcher(std::forward(thing)), 97 | "what: " 98 | )); 99 | } 100 | 101 | template 102 | auto thrown() { 103 | return thrown_raw(anything()); 104 | } 105 | 106 | inline auto thrown() { 107 | return make_matcher([](auto &&value) -> match_result { 108 | try { 109 | value(); 110 | return {false, "threw nothing"}; 111 | } 112 | catch(const std::exception &e) { 113 | std::ostringstream ss; 114 | ss << "threw " << to_printable(e); 115 | return {true, ss.str()}; 116 | } 117 | catch(...) { 118 | return {true, "threw unknown exception"}; 119 | } 120 | }, "threw exception"); 121 | } 122 | 123 | } // namespace mettle 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/expect.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_EXPECT_HPP 2 | #define INC_METTLE_MATCHERS_EXPECT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "core.hpp" 9 | #include "result.hpp" 10 | #include "detail/source_location.hpp" 11 | 12 | #ifndef METTLE_NO_MACROS 13 | # ifdef METTLE_NO_SOURCE_LOCATION 14 | # define METTLE_EXPECT(...) ::mettle::expect( \ 15 | __VA_ARGS__, \ 16 | METTLE_SOURCE_LOCATION::current(__FILE__, __func__, __LINE__) \ 17 | ) 18 | # else 19 | # define METTLE_EXPECT(...) ::mettle::expect(__VA_ARGS__) 20 | # endif 21 | #endif 22 | 23 | namespace mettle { 24 | 25 | class expectation_error : public std::runtime_error { 26 | using std::runtime_error::runtime_error; 27 | }; 28 | 29 | template >> 31 | void expect(const T &value, const Matcher &matcher, 32 | METTLE_SOURCE_LOCATION loc = METTLE_SOURCE_LOCATION::current()) { 33 | auto m = matcher(value); 34 | if(m == false) { 35 | std::ostringstream ss; 36 | if(loc.line()) 37 | ss << loc.file_name() << ":" << loc.line() << std::endl; 38 | ss << "expected: " << matcher.desc() << std::endl 39 | << "actual: " << matcher_message(m, value); 40 | throw expectation_error(ss.str()); 41 | } 42 | } 43 | 44 | template >> 46 | void expect(const std::string &desc, const T &value, const Matcher &matcher, 47 | METTLE_SOURCE_LOCATION loc = METTLE_SOURCE_LOCATION::current()) { 48 | auto m = matcher(value); 49 | if(m == false) { 50 | std::ostringstream ss; 51 | ss << desc; 52 | if(loc.line()) 53 | ss << " (" << loc.file_name() << ":" << loc.line() << ")"; 54 | ss << std::endl << "expected: " << matcher.desc() << std::endl 55 | << "actual: " << matcher_message(m, value); 56 | throw expectation_error(ss.str()); 57 | } 58 | } 59 | 60 | } // namespace mettle 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/regex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_REGEX_HPP 2 | #define INC_METTLE_MATCHERS_REGEX_HPP 3 | 4 | #include 5 | 6 | #include "core.hpp" 7 | 8 | namespace mettle { 9 | 10 | template 11 | auto regex_match(const std::basic_string &ex, 12 | std::regex_constants::syntax_option_type syntax = 13 | std::regex_constants::ECMAScript, 14 | std::regex_constants::match_flag_type match = {}) { 15 | std::ostringstream ss; 16 | ss << "matched " << escape_string(string_convert(ex), '/'); 17 | if(syntax & std::regex_constants::icase) 18 | ss << "i"; 19 | 20 | return make_matcher( 21 | [ex = std::basic_regex(ex, syntax), match](const auto &actual) { 22 | return std::regex_match(actual, ex, match); 23 | }, ss.str() 24 | ); 25 | } 26 | 27 | template 28 | auto regex_match(const Char *ex, 29 | std::regex_constants::syntax_option_type syntax = 30 | std::regex_constants::ECMAScript, 31 | std::regex_constants::match_flag_type match = {}) { 32 | return regex_match(std::basic_string(ex), syntax, match); 33 | } 34 | 35 | template 36 | auto regex_search(const std::basic_string &ex, 37 | std::regex_constants::syntax_option_type syntax = 38 | std::regex_constants::ECMAScript, 39 | std::regex_constants::match_flag_type match = {}) { 40 | std::ostringstream ss; 41 | ss << "searched " << escape_string(string_convert(ex), '/'); 42 | if(syntax & std::regex_constants::icase) 43 | ss << "i"; 44 | 45 | return make_matcher( 46 | [ex = std::basic_regex(ex, syntax), match](const auto &actual) { 47 | return std::regex_search(actual, ex, match); 48 | }, ss.str() 49 | ); 50 | } 51 | 52 | template 53 | auto regex_search(const Char *ex, 54 | std::regex_constants::syntax_option_type syntax = 55 | std::regex_constants::ECMAScript, 56 | std::regex_constants::match_flag_type match = {}) { 57 | return regex_search(std::basic_string(ex), syntax, match); 58 | } 59 | 60 | } // namespace mettle 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/relational.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_RELATIONAL_HPP 2 | #define INC_METTLE_MATCHERS_RELATIONAL_HPP 3 | 4 | #include "core.hpp" 5 | 6 | namespace mettle { 7 | 8 | // Note: equal_to is declared in core.hpp, since it's pretty important! 9 | 10 | template 11 | inline auto not_equal_to(T &&expected) { 12 | return make_matcher(std::forward(expected), std::not_equal_to<>(), "not "); 13 | } 14 | 15 | template 16 | inline auto greater(T &&expected) { 17 | return make_matcher(std::forward(expected), std::greater<>(), "> "); 18 | } 19 | 20 | template 21 | inline auto greater_equal(T &&expected) { 22 | return make_matcher(std::forward(expected), std::greater_equal<>(), ">= "); 23 | } 24 | 25 | template 26 | inline auto less(T &&expected) { 27 | return make_matcher(std::forward(expected), std::less<>(), "< "); 28 | } 29 | 30 | template 31 | inline auto less_equal(T &&expected) { 32 | return make_matcher(std::forward(expected), std::less_equal<>(), "<= "); 33 | } 34 | 35 | } // namespace mettle 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/matchers/result.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_MATCHERS_RESULT_HPP 2 | #define INC_METTLE_MATCHERS_RESULT_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "../output/to_printable.hpp" 8 | 9 | namespace mettle { 10 | 11 | struct match_result { 12 | match_result(bool matched, std::string message = "") 13 | : matched(matched), message(std::move(message)) {} 14 | 15 | bool matched; 16 | std::string message; 17 | 18 | operator bool() const { 19 | return matched; 20 | } 21 | }; 22 | 23 | inline match_result operator !(const match_result &m) { 24 | return {!m.matched, m.message}; 25 | } 26 | 27 | inline match_result operator !(match_result &&m) { 28 | return {!m.matched, std::move(m.message)}; 29 | } 30 | 31 | namespace detail { 32 | template 33 | class message_impl { 34 | public: 35 | message_impl(const match_result &result, const T &fallback) 36 | : result(result), fallback(fallback) {} 37 | message_impl(const message_impl &) = delete; 38 | 39 | friend std::ostream & 40 | operator <<(std::ostream &os, const message_impl &m) { 41 | if(!m.result.message.empty()) 42 | return os << m.result.message; 43 | else 44 | return os << to_printable(m.fallback); 45 | } 46 | private: 47 | const match_result &result; 48 | const T &fallback; 49 | }; 50 | } 51 | 52 | template 53 | inline const detail::message_impl 54 | matcher_message(const match_result &result, const T &fallback) { 55 | return {result, fallback}; 56 | } 57 | 58 | template 59 | inline decltype(auto) 60 | matcher_message(bool, const T &fallback) { 61 | return to_printable(fallback); 62 | } 63 | 64 | } // namespace mettle 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/output.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_OUTPUT_HPP 2 | #define INC_METTLE_OUTPUT_HPP 3 | 4 | #include "output/type_name.hpp" 5 | #include "output/to_printable.hpp" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/output/string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_OUTPUT_STRING_HPP 2 | #define INC_METTLE_OUTPUT_STRING_HPP 3 | 4 | // Try to use N4480's string_view class, or fall back to Boost's. 5 | #if defined(METTLE_USE_STDLIB_EXTS) 6 | # include 7 | # define METTLE_STRING_VIEW boost::basic_string_ref 8 | #elif !defined(METTLE_NO_STDLIB_EXTS) && defined(__has_include) 9 | # if __has_include() 10 | # include 11 | # define METTLE_STRING_VIEW std::experimental::basic_string_view 12 | # else 13 | # include 14 | # define METTLE_STRING_VIEW boost::basic_string_ref 15 | # endif 16 | #else 17 | # include 18 | # define METTLE_STRING_VIEW boost::basic_string_ref 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace mettle { 26 | 27 | namespace detail { 28 | template 29 | void escape_char(std::basic_ostream &os, Char c, Char delim) { 30 | const char escape = '\\'; 31 | if(c < 32 || c == 0x7f) { 32 | os << escape; 33 | switch(c) { 34 | case '\0': os << os.widen('0'); break; 35 | case '\a': os << os.widen('a'); break; 36 | case '\b': os << os.widen('b'); break; 37 | case '\f': os << os.widen('f'); break; 38 | case '\n': os << os.widen('n'); break; 39 | case '\r': os << os.widen('r'); break; 40 | case '\t': os << os.widen('t'); break; 41 | case '\v': os << os.widen('v'); break; 42 | default: os << os.widen('x') << static_cast(c); 43 | } 44 | } 45 | else if(c == delim || c == escape) { 46 | os << escape << c; 47 | } 48 | else { 49 | os << c; 50 | } 51 | } 52 | 53 | template, 54 | typename Alloc = std::allocator> 55 | std::basic_string 56 | null_str() { 57 | std::basic_ostringstream ss; 58 | ss << static_cast(nullptr); 59 | return ss.str(); 60 | } 61 | } 62 | 63 | template> 64 | std::basic_string 65 | escape_string(const METTLE_STRING_VIEW &s, Char delim = '"') { 66 | std::basic_ostringstream ss; 67 | ss << std::hex << delim; 68 | for(const auto &c : s) 69 | detail::escape_char(ss, c, delim); 70 | ss << delim; 71 | return ss.str(); 72 | } 73 | 74 | template 75 | std::basic_string 76 | escape_string(const std::basic_string &s, 77 | Char delim = '"') { 78 | return escape_string( 79 | METTLE_STRING_VIEW(s), delim 80 | ); 81 | } 82 | 83 | template, 84 | typename Alloc = std::allocator> 85 | std::basic_string 86 | escape_string(const Char *s, Char delim = '"') { 87 | return escape_string(METTLE_STRING_VIEW(s), delim); 88 | } 89 | 90 | inline METTLE_STRING_VIEW 91 | string_convert(const METTLE_STRING_VIEW &s) { 92 | return s; 93 | } 94 | 95 | inline std::string 96 | string_convert(const METTLE_STRING_VIEW &s) { 97 | std::wstring_convert, wchar_t> conv; 98 | return conv.to_bytes(s.data(), s.data() + s.size()); 99 | } 100 | 101 | inline std::string 102 | string_convert(const METTLE_STRING_VIEW &s) { 103 | #if defined(_MSC_VER) && !defined(__clang__) 104 | // MSVC 2015's codecvt expects uint16_t instead of char16_t because char16_t 105 | // used to just be a typedef of uint16_t. 106 | std::wstring_convert, 107 | std::uint16_t> conv; 108 | return conv.to_bytes( 109 | reinterpret_cast(s.data()), 110 | reinterpret_cast(s.data() + s.size()) 111 | ); 112 | #else 113 | std::wstring_convert, char16_t> conv; 114 | return conv.to_bytes(s.data(), s.data() + s.size()); 115 | #endif 116 | } 117 | 118 | inline std::string 119 | string_convert(const METTLE_STRING_VIEW &s) { 120 | #if defined(_MSC_VER) && !defined(__clang__) 121 | // MSVC 2015's codecvt expects uint32_t instead of char32_t because char32_t 122 | // used to just be a typedef of uint32_t. 123 | std::wstring_convert, std::uint32_t> conv; 124 | return conv.to_bytes( 125 | reinterpret_cast(s.data()), 126 | reinterpret_cast(s.data() + s.size()) 127 | ); 128 | #else 129 | std::wstring_convert, char32_t> conv; 130 | return conv.to_bytes(s.data(), s.data() + s.size()); 131 | #endif 132 | } 133 | 134 | } // namespace mettle 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/output/to_printable.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_OUTPUT_TO_PRINTABLE_HPP 2 | #define INC_METTLE_OUTPUT_TO_PRINTABLE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "string.hpp" 11 | #include "traits.hpp" 12 | #include "type_name.hpp" 13 | #include "../detail/string_algorithm.hpp" 14 | #include "../detail/tuple_algorithm.hpp" 15 | 16 | namespace mettle { 17 | 18 | // The to_printable overloads below are rather complicated, to say the least; we 19 | // need to be extra-careful to ensure that things which are convertible to bool 20 | // don't erroneously get printed out *as* bools. As such, if a type is 21 | // "bool-ish" (convertible to bool, but not a non-bool arithmetic type), we 22 | // delegate to to_printable_boolish. Here's the basic structure: 23 | // 24 | // to_printable: 25 | // if is_printable 26 | // if is_boolish -> to_printable_boolish 27 | // else -> pass-through 28 | // else 29 | // if is_enum -> enum (class) 30 | // else if is_exception -> exception 31 | // else if is_iterable -> iterable 32 | // else -> fallback 33 | // 34 | // to_printable_boolish: 35 | // if is_bool -> bool 36 | // if is_enum -> enum 37 | // if is_pointer 38 | // if is_any_char -> c string 39 | // else if is_function -> function pointer 40 | // else -> pointer 41 | // if !is_scalar -> fallback 42 | // 43 | // We also have an overload for array types, which is selected if it's *not* an 44 | // array of char (arrays of char ultimately get selected by a const char * 45 | // overload). Finally, we have a few non-generic overloads for nullptrs, 46 | // std::strings, and std::pairs/std::tuples. 47 | 48 | // Non-generic overloads 49 | 50 | inline std::string to_printable(std::nullptr_t) { 51 | return "nullptr"; 52 | } 53 | 54 | template 55 | inline std::string 56 | to_printable(const std::basic_string &s) { 57 | return escape_string(string_convert(s)); 58 | } 59 | 60 | template 61 | inline std::string 62 | to_printable(const METTLE_STRING_VIEW &s) { 63 | return escape_string(string_convert(s)); 64 | } 65 | 66 | inline std::string to_printable(char c) { 67 | return escape_string(std::string(1, c), '\''); 68 | } 69 | 70 | inline std::string to_printable(unsigned char c) { 71 | return escape_string(std::string(1, c), '\''); 72 | } 73 | 74 | inline std::string to_printable(signed char c) { 75 | return escape_string(std::string(1, c), '\''); 76 | } 77 | 78 | inline std::string to_printable(wchar_t c) { 79 | return escape_string(string_convert(std::wstring(1, c)), '\''); 80 | } 81 | 82 | inline std::string to_printable(char16_t c) { 83 | return escape_string(string_convert(std::u16string(1, c)), '\''); 84 | } 85 | 86 | inline std::string to_printable(char32_t c) { 87 | return escape_string(string_convert(std::u32string(1, c)), '\''); 88 | } 89 | 90 | // Helper for bool-ish types 91 | 92 | template 93 | inline auto to_printable_boolish(T b) -> typename std::enable_if< 94 | std::is_same::type, bool>::value, std::string 95 | >::type { 96 | return b ? "true" : "false"; 97 | } 98 | 99 | template 100 | auto to_printable_boolish(T t) -> typename std::enable_if< 101 | std::is_enum::value, std::string 102 | >::type { 103 | return type_name() + "(" + std::to_string( 104 | static_cast::type>(t) 105 | ) + ")"; 106 | } 107 | 108 | template 109 | constexpr inline auto to_printable_boolish(const T *t) -> 110 | typename std::enable_if::value, const T *>::type { 111 | return t; 112 | } 113 | 114 | template 115 | inline auto to_printable_boolish(Ret (*)(Args...)) { 116 | return type_name(); 117 | } 118 | 119 | // XXX: These don't work for volatile strings. 120 | 121 | inline std::string to_printable_boolish(const char *s) { 122 | if(!s) return detail::null_str(); 123 | return escape_string(s); 124 | } 125 | 126 | inline std::string to_printable_boolish(const unsigned char *s) { 127 | if(!s) return detail::null_str(); 128 | return escape_string(reinterpret_cast(s)); 129 | } 130 | 131 | inline std::string to_printable_boolish(const signed char *s) { 132 | if(!s) return detail::null_str(); 133 | return escape_string(reinterpret_cast(s)); 134 | } 135 | 136 | inline std::string to_printable_boolish(const wchar_t *s) { 137 | if(!s) return detail::null_str(); 138 | return escape_string(string_convert(s)); 139 | } 140 | 141 | inline std::string to_printable_boolish(const char16_t *s) { 142 | if(!s) return detail::null_str(); 143 | return escape_string(string_convert(s)); 144 | } 145 | 146 | inline std::string to_printable_boolish(const char32_t *s) { 147 | if(!s) return detail::null_str(); 148 | return escape_string(string_convert(s)); 149 | } 150 | 151 | template 152 | auto to_printable_boolish(const T &t) -> typename std::enable_if< 153 | !std::is_scalar::type>::value, std::string 154 | >::type { 155 | return type_name(t); 156 | } 157 | 158 | // Pass-through 159 | 160 | template 161 | constexpr auto to_printable(const T &t) -> typename std::enable_if< 162 | is_printable::value && !is_boolish::value, const T & 163 | >::type { 164 | return t; 165 | } 166 | 167 | // Bool-ish types 168 | 169 | template 170 | constexpr inline auto to_printable(const T &t) -> typename std::enable_if< 171 | is_printable::value && is_boolish::value, 172 | decltype(to_printable_boolish(t)) 173 | >::type { 174 | return to_printable_boolish(t); 175 | } 176 | 177 | // Fallback 178 | 179 | template 180 | auto to_printable(const T &t) -> typename std::enable_if< 181 | !is_printable::value && !std::is_enum::value && 182 | !is_exception::value && !is_iterable::value, 183 | std::string 184 | >::type { 185 | return type_name(t); 186 | } 187 | 188 | // Enum classes 189 | 190 | template 191 | constexpr inline auto to_printable(T t) -> typename std::enable_if< 192 | !is_printable::value && std::is_enum::value, std::string 193 | >::type { 194 | return to_printable_boolish(t); 195 | } 196 | 197 | // Exceptions 198 | 199 | template 200 | inline auto to_printable(const T &e) -> typename std::enable_if< 201 | !is_printable::value && is_exception::value, std::string 202 | >::type { 203 | std::ostringstream ss; 204 | ss << type_name(e) << "(" << to_printable(e.what()) << ")"; 205 | return ss.str(); 206 | } 207 | 208 | // Iterables 209 | 210 | template 211 | std::string to_printable(T begin, T end); 212 | 213 | template 214 | auto to_printable(const T &v) -> typename std::enable_if< 215 | !is_printable::value && !is_exception::value && is_iterable::value, 216 | std::string 217 | >::type { 218 | return to_printable(std::begin(v), std::end(v)); 219 | } 220 | 221 | template 222 | auto to_printable(const T (&v)[N]) -> typename std::enable_if< 223 | !is_any_char::value, std::string 224 | >::type { 225 | return to_printable(std::begin(v), std::end(v)); 226 | } 227 | 228 | // Pairs/Tuples 229 | 230 | namespace detail { 231 | template 232 | std::string stringify_tuple(const T &tuple); 233 | } 234 | 235 | template 236 | std::string to_printable(const std::pair &pair) { 237 | return detail::stringify_tuple(pair); 238 | } 239 | 240 | template 241 | std::string to_printable(const std::tuple &tuple) { 242 | return detail::stringify_tuple(tuple); 243 | } 244 | 245 | template 246 | std::string to_printable(T begin, T end) { 247 | std::ostringstream ss; 248 | ss << "[" << detail::iter_joined(begin, end, [](auto &&item) { 249 | return to_printable(item); 250 | }) << "]"; 251 | return ss.str(); 252 | } 253 | 254 | namespace detail { 255 | template 256 | std::string stringify_tuple(const T &tuple) { 257 | std::ostringstream ss; 258 | ss << "[" << tuple_joined(tuple, [](auto &&item) { 259 | return to_printable(item); 260 | }) << "]"; 261 | return ss.str(); 262 | } 263 | } 264 | 265 | } // namespace mettle 266 | 267 | #endif 268 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/output/traits.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_OUTPUT_TRAITS_HPP 2 | #define INC_METTLE_OUTPUT_TRAITS_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mettle { 8 | 9 | namespace detail { 10 | template 11 | auto check_printable(...) -> std::false_type; 12 | 13 | template 14 | auto check_printable(int) -> decltype( 15 | std::declval() << std::declval(), std::true_type() 16 | ); 17 | } 18 | 19 | template 20 | struct is_printable : decltype(detail::check_printable(0)) {}; 21 | 22 | template 23 | struct is_boolish : std::integral_constant::type, bool>::value || 25 | (std::is_convertible::value && !std::is_arithmetic::value) 26 | > {}; 27 | 28 | template 29 | struct is_boolish : is_boolish {}; 30 | 31 | template 32 | struct is_boolish : is_boolish {}; 33 | 34 | template 35 | struct is_any_char_helper : std::false_type {}; 36 | 37 | template<> struct is_any_char_helper : std::true_type {}; 38 | template<> struct is_any_char_helper : std::true_type {}; 39 | template<> struct is_any_char_helper : std::true_type {}; 40 | 41 | template<> struct is_any_char_helper : std::true_type {}; 42 | template<> struct is_any_char_helper : std::true_type {}; 43 | template<> struct is_any_char_helper : std::true_type {}; 44 | 45 | template 46 | struct is_any_char : is_any_char_helper::type> {}; 47 | 48 | template 49 | using is_exception = std::is_base_of; 50 | 51 | namespace detail { 52 | template 53 | auto check_iterable(...) -> std::false_type; 54 | 55 | template 56 | auto check_iterable(int) -> decltype( 57 | std::begin(std::declval()), std::end(std::declval()), std::true_type() 58 | ); 59 | } 60 | 61 | template 62 | struct is_iterable : decltype(detail::check_iterable(0)) {}; 63 | 64 | template 65 | struct is_iterable : std::true_type {}; 66 | 67 | } // namespace mettle 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/output/type_name.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_OUTPUT_TYPE_NAME_HPP 2 | #define INC_METTLE_OUTPUT_TYPE_NAME_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mettle { 9 | 10 | #if defined(__clang__) 11 | 12 | template 13 | std::string type_name() { 14 | const auto begin = sizeof("std::string mettle::type_name() [T = ") - 1; 15 | const auto end = sizeof(__PRETTY_FUNCTION__) - sizeof("]"); 16 | return std::string(__PRETTY_FUNCTION__ + begin, __PRETTY_FUNCTION__ + end); 17 | } 18 | 19 | #elif defined(__GNUG__) 20 | 21 | template 22 | std::basic_string type_name() { 23 | const auto begin = sizeof( 24 | #if defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI == 1 25 | "std::__cxx11::basic_string mettle::type_name() [with T = " 26 | #else 27 | "std::basic_string mettle::type_name() [with T = " 28 | #endif 29 | ) - 1; 30 | const auto end = sizeof(__PRETTY_FUNCTION__) - sizeof("]"); 31 | return std::string(__PRETTY_FUNCTION__ + begin, __PRETTY_FUNCTION__ + end); 32 | } 33 | 34 | #elif defined(_MSC_VER) 35 | 36 | template 37 | std::string type_name() { 38 | const char sig[] = __FUNCSIG__; 39 | const auto begin = sizeof( 40 | "class std::basic_string," 41 | "class std::allocator > __cdecl mettle::type_name<" 42 | ) - 1; 43 | const auto end = sizeof(sig) - sizeof(">(void)"); 44 | return std::string(sig + begin, sig + end); 45 | } 46 | 47 | #else 48 | 49 | template 50 | std::string type_name() { 51 | return typeid(T).name(); 52 | } 53 | 54 | #endif 55 | 56 | template 57 | std::string type_name(const T &t); 58 | 59 | } // namespace mettle 60 | 61 | #if defined(__clang__) || defined(__GNUG__) 62 | 63 | #include 64 | 65 | template 66 | std::string mettle::type_name(const T &t) { 67 | int status; 68 | const char *mangled = typeid(t).name(); 69 | std::unique_ptr demangled( 70 | abi::__cxa_demangle(mangled, nullptr, nullptr, &status), 71 | std::free 72 | ); 73 | return status ? mangled : demangled.get(); 74 | } 75 | 76 | #else 77 | 78 | template 79 | std::string mettle::type_name(const T &t) { 80 | return typeid(t).name(); 81 | } 82 | 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_HPP 2 | #define INC_METTLE_SUITE_HPP 3 | 4 | #include "basic_suite.hpp" 5 | #include "glue.hpp" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/attributes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_ATTRIBUTES_HPP 2 | #define INC_METTLE_SUITE_ATTRIBUTES_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mettle { 13 | 14 | enum class test_action { 15 | run, 16 | skip, 17 | hide, 18 | indeterminate 19 | }; 20 | 21 | class attr_base; 22 | 23 | struct attr_instance { 24 | using value_type = std::set; 25 | 26 | const attr_base &attribute; 27 | const value_type value; 28 | }; 29 | 30 | class attr_base { 31 | protected: 32 | attr_base(std::string name, test_action action = test_action::run) 33 | : name_(std::move(name)), action_(action) { 34 | assert(action == test_action::run || action == test_action::skip); 35 | } 36 | public: 37 | virtual ~attr_base() = default; 38 | 39 | const std::string & name() const { 40 | return name_; 41 | } 42 | 43 | test_action action() const { 44 | return action_; 45 | } 46 | 47 | virtual const attr_instance 48 | compose(const attr_instance &lhs, const attr_instance &rhs) const { 49 | assert(&lhs.attribute == this && &rhs.attribute == this); 50 | (void)rhs; 51 | return lhs; 52 | } 53 | private: 54 | std::string name_; 55 | test_action action_; 56 | }; 57 | 58 | namespace detail { 59 | struct attr_less { 60 | using is_transparent = void; 61 | 62 | bool operator ()(const attr_instance &lhs, const attr_instance &rhs) const { 63 | return lhs.attribute.name() < rhs.attribute.name(); 64 | } 65 | 66 | bool operator ()(const attr_instance &lhs, const std::string &rhs) const { 67 | return lhs.attribute.name() < rhs; 68 | } 69 | 70 | bool operator ()(const std::string &lhs, const attr_instance &rhs) const { 71 | return lhs < rhs.attribute.name(); 72 | } 73 | }; 74 | } 75 | 76 | class bool_attr : public attr_base { 77 | public: 78 | bool_attr(std::string name, test_action action = test_action::run) 79 | : attr_base(std::move(name), action) {} 80 | 81 | operator attr_instance() const { 82 | return attr_instance{*this, {}}; 83 | } 84 | 85 | template 86 | attr_instance operator ()(T &&comment) const { 87 | return attr_instance{*this, {std::forward(comment)}}; 88 | } 89 | }; 90 | 91 | class string_attr : public attr_base { 92 | public: 93 | string_attr(std::string name) 94 | : attr_base(std::move(name)) {} 95 | 96 | template 97 | attr_instance operator ()(T &&value) const { 98 | return attr_instance{*this, {std::forward(value)}}; 99 | } 100 | }; 101 | 102 | class list_attr : public attr_base { 103 | public: 104 | list_attr(std::string name) 105 | : attr_base(std::move(name)) {} 106 | 107 | template 108 | attr_instance operator ()(T &&...args) const { 109 | return attr_instance{*this, {std::forward(args)...}}; 110 | } 111 | 112 | const attr_instance 113 | compose(const attr_instance &lhs, const attr_instance &rhs) const override { 114 | assert(&lhs.attribute == this && &rhs.attribute == this); 115 | attr_instance::value_type merged; 116 | std::set_union( 117 | lhs.value.begin(), lhs.value.end(), 118 | rhs.value.begin(), rhs.value.end(), 119 | std::inserter(merged, merged.begin()) 120 | ); 121 | return attr_instance{*this, std::move(merged)}; 122 | } 123 | }; 124 | 125 | using attributes = std::set; 126 | 127 | namespace detail { 128 | template 130 | Output merge_union(Input1 first1, Input1 last1, Input2 first2, Input2 last2, 131 | Output result, Compare comp, Merge merge) { 132 | for(; first1 != last1; ++result) { 133 | if(first2 == last2) 134 | return std::copy(first1, last1, result); 135 | 136 | if(comp(*first1, *first2)) 137 | *result = *first1++; 138 | else if(comp(*first2, *first1)) 139 | *result = *first2++; 140 | else 141 | *result = merge(*first1++, *first2++); 142 | } 143 | return std::copy(first2, last2, result); 144 | } 145 | } 146 | 147 | inline attr_instance unite(const attr_instance &lhs, const attr_instance &rhs) { 148 | if(&lhs.attribute != &rhs.attribute) 149 | throw std::invalid_argument("mismatched attributes"); 150 | return lhs.attribute.compose(lhs, rhs); 151 | } 152 | 153 | inline attributes unite(const attributes &lhs, const attributes &rhs) { 154 | attributes all_attrs; 155 | detail::merge_union( 156 | lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), 157 | std::inserter(all_attrs, all_attrs.begin()), detail::attr_less(), 158 | [](const attr_instance &lhs, const attr_instance &rhs) { 159 | return unite(lhs, rhs); 160 | } 161 | ); 162 | return all_attrs; 163 | } 164 | 165 | extern bool_attr skip; 166 | 167 | } // namespace mettle 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/compiled_suite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_COMPILED_SUITE_HPP 2 | #define INC_METTLE_SUITE_COMPILED_SUITE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "attributes.hpp" 9 | #include "../test_uid.hpp" 10 | #include "../detail/forward_if.hpp" 11 | 12 | namespace mettle { 13 | 14 | struct test_result { 15 | bool passed; 16 | std::string message; 17 | }; 18 | 19 | template 20 | struct basic_test_info { 21 | using function_type = std::function; 22 | 23 | basic_test_info(std::string name, function_type function, attributes attrs) 24 | : name(std::move(name)), function(std::move(function)), 25 | attrs(std::move(attrs)), id(detail::make_test_uid()) {} 26 | 27 | std::string name; 28 | function_type function; 29 | attributes attrs; 30 | test_uid id; 31 | }; 32 | 33 | template 34 | class compiled_suite { 35 | template 36 | friend class compiled_suite; 37 | public: 38 | using test_info = basic_test_info; 39 | using iterator = typename std::vector::const_iterator; 40 | 41 | template 43 | compiled_suite( 44 | String &&name, Tests &&tests, Subsuites &&subsuites, 45 | const attributes &attrs, Compile &&compile 46 | ) : name_(std::forward(name)) { 47 | using detail::forward_if; 48 | 49 | for(auto &&test : tests) { 50 | tests_.emplace_back( 51 | forward_if(test.name), 52 | compile(forward_if(test.function)), 53 | unite(forward_if(test.attrs), attrs) 54 | ); 55 | } 56 | for(auto &&ss : subsuites) 57 | subsuites_.emplace_back(forward_if(ss), attrs, compile); 58 | } 59 | 60 | template 61 | compiled_suite(const compiled_suite &suite, 62 | const attributes &attrs, Compile &&compile) 63 | : compiled_suite(suite.name_, suite.tests_, suite.subsuites_, attrs, 64 | std::forward(compile)) {} 65 | 66 | template 67 | compiled_suite(compiled_suite &&suite, 68 | const attributes &attrs, Compile &&compile) 69 | : compiled_suite(std::move(suite.name_), std::move(suite.tests_), 70 | std::move(suite.subsuites_), attrs, 71 | std::forward(compile)) {} 72 | 73 | const std::string & name() const { 74 | return name_; 75 | } 76 | 77 | const std::vector & tests() const { 78 | return tests_; 79 | } 80 | 81 | const std::vector & subsuites() const { 82 | return subsuites_; 83 | } 84 | private: 85 | std::string name_; 86 | std::vector tests_; 87 | std::vector subsuites_; 88 | }; 89 | 90 | using runnable_suite = compiled_suite; 91 | using suites_list = std::vector; 92 | using test_info = runnable_suite::test_info; 93 | 94 | } // namespace mettle 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/detail/all_suites.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_DETAIL_ALL_SUITES_HPP 2 | #define INC_METTLE_SUITE_DETAIL_ALL_SUITES_HPP 3 | 4 | #include "../compiled_suite.hpp" 5 | 6 | namespace mettle { 7 | 8 | namespace detail { 9 | inline suites_list & all_suites() { 10 | static suites_list all; 11 | return all; 12 | } 13 | } 14 | 15 | } // namespace mettle 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/detail/built_in_attrs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_DETAIL_BUILT_IN_ATTRS_HPP 2 | #define INC_METTLE_SUITE_DETAIL_BUILT_IN_ATTRS_HPP 3 | 4 | #include "../attributes.hpp" 5 | 6 | namespace mettle { 7 | 8 | bool_attr skip("skip", test_action::skip); 9 | 10 | } // namespace mettle 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/detail/test_caller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_DETAIL_TEST_CALLER_HPP 2 | #define INC_METTLE_SUITE_DETAIL_TEST_CALLER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mettle { 9 | 10 | namespace detail { 11 | template 12 | struct first; 13 | 14 | template 15 | struct first { 16 | using type = First; 17 | }; 18 | 19 | template<> 20 | struct first<> { 21 | using type = void; 22 | }; 23 | 24 | template 25 | using first_t = typename first::type; 26 | 27 | template 28 | struct transform_fixture; 29 | 30 | template 31 | struct transform_fixture { 32 | using type = void; 33 | }; 34 | 35 | template 36 | struct transform_fixture { 37 | using type = decltype(std::declval().template make()); 38 | }; 39 | 40 | template 41 | using transform_fixture_t = typename transform_fixture< 42 | Factory, Child... 43 | >::type; 44 | 45 | template 46 | struct test_caller_base { 47 | using function_type = std::function; 48 | 49 | void call_test(Args &...args) { 50 | if(setup) 51 | setup(args...); 52 | 53 | try { 54 | test(args...); 55 | } 56 | catch(...) { 57 | if(teardown) { 58 | try { teardown(args...); } catch(...) {} 59 | } 60 | throw; 61 | } 62 | 63 | if(teardown) 64 | teardown(args...); 65 | } 66 | 67 | function_type setup, teardown, test; 68 | }; 69 | 70 | template 72 | class test_caller_impl; 73 | 74 | template 76 | class test_caller_impl, InChild, OutChild> 77 | : private test_caller_base { 78 | private: 79 | using base = test_caller_base; 80 | public: 81 | template 82 | test_caller_impl(Factory f, T &&...t) 83 | : base{std::forward(t)...}, factory(f) {} 84 | 85 | inline void operator ()(Parent &...args) { 86 | auto &&child = factory.template make(); 87 | base::call_test(args..., child); 88 | } 89 | 90 | Factory factory; 91 | }; 92 | 93 | template 94 | class test_caller_impl, InChild, void> 95 | : private test_caller_base { 96 | private: 97 | using base = test_caller_base; 98 | public: 99 | template 100 | test_caller_impl(const Factory &, T &&...t) 101 | : base{std::forward(t)...} {} 102 | public: 103 | inline void operator ()(Parent &...args) { 104 | base::call_test(args...); 105 | } 106 | }; 107 | 108 | template 109 | using test_caller = test_caller_impl< 110 | Factory, Parent, first_t, transform_fixture_t 111 | >; 112 | 113 | } 114 | 115 | } // namespace mettle 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/factory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_FACTORY_HPP 2 | #define INC_METTLE_SUITE_FACTORY_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mettle { 9 | 10 | namespace detail { 11 | 12 | struct auto_factory_t { 13 | constexpr auto_factory_t() {} 14 | 15 | template 16 | T make() const { 17 | return {}; 18 | } 19 | }; 20 | 21 | struct type_only_factory_t { 22 | constexpr type_only_factory_t() {} 23 | 24 | template 25 | void make() const {} 26 | }; 27 | 28 | template 29 | class bind_factory_t { 30 | using tuple_type = std::tuple; 31 | public: 32 | template::value 34 | >> explicit bind_factory_t(CallArgs &&...args) : args_(args...) {} 35 | 36 | template 37 | T make() const { 38 | using Indices = std::make_index_sequence< 39 | std::tuple_size::value 40 | >; 41 | return make_impl(Indices()); 42 | } 43 | private: 44 | template 45 | T make_impl(std::index_sequence) const { 46 | return T(std::get(args_)...); 47 | } 48 | 49 | tuple_type args_; 50 | }; 51 | 52 | } 53 | 54 | constexpr detail::auto_factory_t auto_factory; 55 | constexpr detail::type_only_factory_t type_only; 56 | 57 | // XXX: Work around GCC bug 65308 and don't return auto here. 58 | template 59 | detail::bind_factory_t::type...> 60 | bind_factory(Args &&...args) { 61 | return detail::bind_factory_t::type...>( 62 | std::forward(args)... 63 | ); 64 | } 65 | 66 | } // namespace mettle 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/suite/global_suite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_SUITE_GLOBAL_SUITE_HPP 2 | #define INC_METTLE_SUITE_GLOBAL_SUITE_HPP 3 | 4 | #include "detail/all_suites.hpp" 5 | #include "make_suite.hpp" 6 | 7 | namespace mettle { 8 | 9 | template 10 | struct basic_suite { 11 | template 12 | basic_suite(suites_list &list, const std::string &name, 13 | const attributes &attrs, Args &&...args) { 14 | auto &&suites = make_basic_suites( 15 | name, attrs, std::forward(args)... 16 | ); 17 | for(auto &&i : suites) 18 | list.push_back(std::move(i)); 19 | } 20 | 21 | template 22 | basic_suite(suites_list &list, const std::string &name, Args &&...args) 23 | : basic_suite(list, name, {}, std::forward(args)...) {} 24 | 25 | template 26 | basic_suite(const std::string &name, const attributes &attrs, Args &&...args) 27 | : basic_suite(detail::all_suites(), name, attrs, 28 | std::forward(args)...) {} 29 | 30 | template 31 | basic_suite(const std::string &name, Args &&...args) 32 | : basic_suite(name, {}, std::forward(args)...) {} 33 | }; 34 | 35 | } // namespace mettle 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/mettle/test_uid.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INC_METTLE_TEST_UID_HPP 2 | #define INC_METTLE_TEST_UID_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace mettle { 8 | 9 | using test_uid = std::uint64_t; 10 | 11 | namespace detail { 12 | inline test_uid make_test_uid() { 13 | static std::atomic id_(0); 14 | return id_++; 15 | } 16 | } 17 | 18 | } // namespace mettle 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BowlingTests.Mettle.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /BowlingTests.Mettle/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/CppUnitTestingMockComparison.cpp: -------------------------------------------------------------------------------- 1 | // CppUnitTestingMockComparison.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | int main() 8 | { 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/CppUnitTestingMockComparison.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {C97EFE44-B0E5-4ABC-A76E-18903D0B861A} 24 | Win32Proj 25 | CppUnitTestingMockComparison 26 | 10.0.15063.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | 92 | 93 | Console 94 | 95 | 96 | 97 | 98 | Use 99 | Level3 100 | Disabled 101 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 102 | 103 | 104 | Console 105 | 106 | 107 | 108 | 109 | Level3 110 | Use 111 | MaxSpeed 112 | true 113 | true 114 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 115 | 116 | 117 | Console 118 | true 119 | true 120 | 121 | 122 | 123 | 124 | Level3 125 | Use 126 | MaxSpeed 127 | true 128 | true 129 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | 131 | 132 | Console 133 | true 134 | true 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | Create 148 | Create 149 | Create 150 | Create 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/CppUnitTestingMockComparison.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : CppUnitTestingMockComparison Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this CppUnitTestingMockComparison application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your CppUnitTestingMockComparison application. 9 | 10 | 11 | CppUnitTestingMockComparison.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | CppUnitTestingMockComparison.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | CppUnitTestingMockComparison.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named CppUnitTestingMockComparison.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // CppUnitTestingMockComparison.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /CppUnitTestingMockComparison/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/DistibutedCalculator.FakeIt.cpp: -------------------------------------------------------------------------------- 1 | // DistibutedCalculator.FakeIt.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #define CATCH_CONFIG_MAIN 6 | #include "catch.hpp" 7 | #include "fakeit.hpp" 8 | #include "../DistributedCalculator/Calculator.h" 9 | 10 | using namespace fakeit; 11 | 12 | bool has_suffix(const std::string &str, const std::string &suffix) 13 | { 14 | return str.size() >= suffix.size() && 15 | str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; 16 | } 17 | 18 | TEST_CASE("Calculate with two valid numbers --> server called") 19 | { 20 | Mock fakeDataAccess; 21 | 22 | auto data = std::make_pair(1, 2); 23 | When(Method(fakeDataAccess, GetData)).Return(data); 24 | 25 | std::string dummy = "http://base"; 26 | Mock fakeClient; 27 | 28 | When(Method(fakeClient, HttpGet)).Return("3"); 29 | 30 | Calculator calculator(fakeDataAccess.get(), fakeClient.get()); 31 | 32 | calculator.CalculateNextData(); 33 | 34 | Verify(Method(fakeClient, HttpGet)).AtLeastOnce(); 35 | } -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/DistibutedCalculator.FakeIt.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : DistibutedCalculator.FakeIt Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this DistibutedCalculator.FakeIt application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your DistibutedCalculator.FakeIt application. 9 | 10 | 11 | DistibutedCalculator.FakeIt.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | DistibutedCalculator.FakeIt.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | DistibutedCalculator.FakeIt.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named DistibutedCalculator.FakeIt.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DistibutedCalculator.FakeIt.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /DistibutedCalculator.FakeIt/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DistributedCalculator.HippoMocks/DistributedCalculator.HippoMocks.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /DistributedCalculator.HippoMocks/DistributedCalculatorTests.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CppUnitTest.h" 3 | #include "hippomocks.h" 4 | #include "../DistributedCalculator/DataAccess.h" 5 | #include "../DistributedCalculator/RestApiClient.h" 6 | #include "../DistributedCalculator/Calculator.h" 7 | 8 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 9 | 10 | namespace DistributedCalculatorHippoMocks 11 | { 12 | TEST_CLASS(DistributedCalculatorTests) 13 | { 14 | public: 15 | 16 | TEST_METHOD(Calculate_ReturnTwoValidNumbers_ServerCalled) 17 | { 18 | MockRepository mocks; 19 | 20 | DataAccess* fakeDataAccess = mocks.Mock(); 21 | auto data = std::make_pair(1, 2); 22 | mocks.OnCall(fakeDataAccess, DataAccess::GetData).Return(data); 23 | 24 | RestApiClient* fakeClient = mocks.Mock(); 25 | auto called = 0; 26 | mocks.ExpectCall(fakeClient, RestApiClient::HttpGet) 27 | .Do([&](std::string& arg) 28 | { 29 | if (arg.find("/Add?1&2") != std::string::npos) 30 | called++; 31 | 32 | return "3"; 33 | }); 34 | 35 | Calculator calculator(*fakeDataAccess, *fakeClient); 36 | 37 | calculator.CalculateNextData(); 38 | } 39 | 40 | }; 41 | } -------------------------------------------------------------------------------- /DistributedCalculator.HippoMocks/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DistributedCalculator.HippoMocks.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /DistributedCalculator.HippoMocks/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | // Headers for CppUnitTest 11 | #include "CppUnitTest.h" 12 | 13 | // TODO: reference additional headers your program requires here 14 | -------------------------------------------------------------------------------- /DistributedCalculator.HippoMocks/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DistributedCalculator/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Calculator.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | Calculator::Calculator(DataAccess& dataAccess, RestApiClient& restClient) : _dataAccess(dataAccess), _client(restClient) 8 | { 9 | } 10 | 11 | 12 | Calculator::~Calculator() 13 | { 14 | } 15 | 16 | int Calculator::CalculateNextData() const 17 | { 18 | auto data = _dataAccess.GetData(); 19 | 20 | ostringstream oss; 21 | oss << "/Add?" << data.first << "&" << data.second; 22 | auto result = _client.HttpGet(oss.str()); 23 | 24 | return stoi(result); 25 | } 26 | -------------------------------------------------------------------------------- /DistributedCalculator/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "DataAccess.h" 3 | #include "RestApiClient.h" 4 | 5 | class Calculator 6 | { 7 | DataAccess& _dataAccess; 8 | RestApiClient& _client; 9 | public: 10 | Calculator(DataAccess& dataAccess, RestApiClient& restClient); 11 | ~Calculator(); 12 | 13 | int CalculateNextData() const; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /DistributedCalculator/DataAccess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef std::pair Inputnumbers; 5 | class DataAccess 6 | { 7 | public: 8 | virtual ~DataAccess() = default; 9 | virtual Inputnumbers GetData() const = 0; 10 | }; 11 | -------------------------------------------------------------------------------- /DistributedCalculator/DistributedCalculator.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {2887CED3-72F9-4E1D-9089-39E2B0338992} 24 | Win32Proj 25 | DistributedCalculator 26 | 10.0.15063.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Use 77 | Level3 78 | Disabled 79 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 80 | 81 | 82 | Windows 83 | 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | _DEBUG;_LIB;%(PreprocessorDefinitions) 91 | 92 | 93 | Windows 94 | 95 | 96 | 97 | 98 | Level3 99 | Use 100 | MaxSpeed 101 | true 102 | true 103 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 104 | 105 | 106 | Windows 107 | true 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | Use 115 | MaxSpeed 116 | true 117 | true 118 | NDEBUG;_LIB;%(PreprocessorDefinitions) 119 | 120 | 121 | Windows 122 | true 123 | true 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | Create 141 | Create 142 | Create 143 | Create 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /DistributedCalculator/DistributedCalculator.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /DistributedCalculator/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | STATIC LIBRARY : DistributedCalculator Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this DistributedCalculator library project for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your DistributedCalculator application. 9 | 10 | 11 | DistributedCalculator.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | DistributedCalculator.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | 25 | ///////////////////////////////////////////////////////////////////////////// 26 | 27 | StdAfx.h, StdAfx.cpp 28 | These files are used to build a precompiled header (PCH) file 29 | named DistributedCalculator.pch and a precompiled types file named StdAfx.obj. 30 | 31 | ///////////////////////////////////////////////////////////////////////////// 32 | Other notes: 33 | 34 | AppWizard uses "TODO:" comments to indicate parts of the source code you 35 | should add to or customize. 36 | 37 | ///////////////////////////////////////////////////////////////////////////// 38 | -------------------------------------------------------------------------------- /DistributedCalculator/RestApiClient.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "RestApiClient.h" 3 | #include "curl/curl.h" 4 | 5 | using namespace std; 6 | 7 | RestApiClient::RestApiClient(const string& baseUrl): _baseUrl(baseUrl) { 8 | } 9 | 10 | 11 | RestApiClient::~RestApiClient() 12 | { 13 | } 14 | 15 | string buffer; 16 | size_t curl_write(void *ptr, size_t size, size_t nmemb, void *stream) 17 | { 18 | buffer.append(static_cast(ptr), size*nmemb); 19 | return size*nmemb; 20 | } 21 | 22 | string RestApiClient::HttpGet(string& url) 23 | { 24 | CURL *curl = curl_easy_init(); 25 | if (!curl) 26 | { 27 | // TODO: handle error 28 | curl_easy_cleanup(curl); 29 | return ""; 30 | } 31 | 32 | buffer.clear(); 33 | curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); 34 | 35 | curl_easy_setopt(curl, CURLOPT_URL, _baseUrl + url.c_str()); 36 | 37 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write); 38 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{}"); 39 | CURLcode res = curl_easy_perform(curl); 40 | curl_easy_cleanup(curl); 41 | 42 | if (res != CURLE_OK) 43 | { 44 | // TODO: handle error 45 | 46 | return ""; 47 | } 48 | 49 | return buffer; 50 | } -------------------------------------------------------------------------------- /DistributedCalculator/RestApiClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class RestApiClient 5 | { 6 | const std::string& _baseUrl; 7 | 8 | public: 9 | RestApiClient(const std::string& baseUrl); 10 | ~RestApiClient(); 11 | 12 | virtual std::string HttpGet(std::string& url); 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /DistributedCalculator/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DistributedCalculator.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /DistributedCalculator/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | 12 | 13 | 14 | // TODO: reference additional headers your program requires here 15 | -------------------------------------------------------------------------------- /DistributedCalculator/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/DistributedCalculatorTests.GMock.cpp: -------------------------------------------------------------------------------- 1 | // DistributedCalculatorTests.GMock.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | #include "gmock/gmock.h" 7 | #include "FakeDataAccess.h" 8 | #include "FakeRestApiClient.h" 9 | #include "../DistributedCalculator/Calculator.h" 10 | 11 | using namespace testing; 12 | 13 | TEST(DistributedCalculatorTests, Calculate_ReturnTwoValidNumbers_ServerCalled) 14 | { 15 | FakeDataAccess fakeDataAccess; 16 | auto data = std::make_pair(1,2); 17 | EXPECT_CALL(fakeDataAccess, GetData()).WillRepeatedly(Return(data)); 18 | 19 | std::string dummy = "http://base"; 20 | FakeRestApiClient fakeClient(dummy); 21 | 22 | EXPECT_CALL(fakeClient, HttpGet(StrEq("/Add?1&2"))) 23 | .Times(AtLeast(1)) 24 | .WillOnce(Return("3")); 25 | 26 | Calculator calculator(fakeDataAccess, fakeClient); 27 | 28 | calculator.CalculateNextData(); 29 | } 30 | 31 | int main(int argc, char** argv) 32 | { 33 | InitGoogleMock(&argc, argv); 34 | 35 | return RUN_ALL_TESTS(); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/DistributedCalculatorTests.GMock.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/FakeDataAccess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gmock/gmock.h" 3 | #include "../DistributedCalculator/DataAccess.h" 4 | #include "gmock/gmock-generated-function-mockers.h" 5 | 6 | class FakeDataAccess : public DataAccess 7 | { 8 | public: 9 | MOCK_CONST_METHOD0(GetData, std::pair()); 10 | }; 11 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/FakeRestApiClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../DistributedCalculator/RestApiClient.h" 3 | #include "gmock/gmock.h" 4 | 5 | class FakeRestApiClient : public RestApiClient 6 | { 7 | public: 8 | 9 | FakeRestApiClient(const std::string& baseUrl) 10 | : RestApiClient(baseUrl) 11 | { 12 | } 13 | 14 | MOCK_METHOD1(HttpGet, std::string(std::string&)); 15 | }; 16 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : DistributedCalculatorTests.GMock Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this DistributedCalculatorTests.GMock application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your DistributedCalculatorTests.GMock application. 9 | 10 | 11 | DistributedCalculatorTests.GMock.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | DistributedCalculatorTests.GMock.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | DistributedCalculatorTests.GMock.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named DistributedCalculatorTests.GMock.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DistributedCalculatorTests.GMock.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.GMock/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/DistributedCalculatorTests.Trompeloeil.cpp: -------------------------------------------------------------------------------- 1 | // DistributedCalculatorTests.Trompeloeil.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #define CATCH_CONFIG_MAIN 6 | #include "catch.hpp" 7 | #include "trompeloeil.hpp" 8 | #include "FakeDataAccess.h" 9 | #include "FakeRestApiClient.h" 10 | #include "../DistributedCalculator/Calculator.h" 11 | 12 | namespace trompeloeil 13 | { 14 | template <> 15 | void reporter::send(severity s, const char* file, unsigned long line, const char* msg) 16 | { 17 | std::ostringstream os; 18 | if (line) os << file << ':' << line << '\n'; 19 | os << msg; 20 | auto failure = os.str(); 21 | if (s == severity::fatal) 22 | { 23 | FAIL(failure); 24 | } 25 | else 26 | { 27 | CAPTURE(failure); 28 | CHECK(failure.empty()); 29 | } 30 | } 31 | } 32 | 33 | using namespace trompeloeil; 34 | 35 | TEST_CASE("Calculate with two valid numbers --> server called") 36 | { 37 | FakeDataAccess fakeDataAccess; 38 | auto data = std::make_pair(1, 2); 39 | ALLOW_CALL(fakeDataAccess, GetData()).RETURN(data); 40 | 41 | std::string dummy = "http://base"; 42 | FakeRestApiClient fakeClient(dummy); 43 | 44 | REQUIRE_CALL(fakeClient, HttpGet(eq("/Add?1&2"))).RETURN("3").TIMES(1); 45 | 46 | Calculator calculator(fakeDataAccess, fakeClient); 47 | 48 | calculator.CalculateNextData(); 49 | } -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/DistributedCalculatorTests.Trompeloeil.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/FakeDataAccess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../DistributedCalculator/DataAccess.h" 3 | #include "trompeloeil.hpp" 4 | 5 | 6 | class FakeDataAccess : public DataAccess 7 | { 8 | public: 9 | MAKE_CONST_MOCK0(GetData, Inputnumbers()); 10 | }; 11 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/FakeRestApiClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../DistributedCalculator/RestApiClient.h" 3 | #include "trompeloeil.hpp" 4 | 5 | class FakeRestApiClient : public RestApiClient 6 | { 7 | public: 8 | 9 | FakeRestApiClient(const std::string& baseUrl) 10 | : RestApiClient(baseUrl) 11 | { 12 | } 13 | 14 | MAKE_MOCK1(HttpGet, std::string(std::string&), override); 15 | }; 16 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : DistributedCalculatorTests.Trompeloeil Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this DistributedCalculatorTests.Trompeloeil application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your DistributedCalculatorTests.Trompeloeil application. 9 | 10 | 11 | DistributedCalculatorTests.Trompeloeil.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | DistributedCalculatorTests.Trompeloeil.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | DistributedCalculatorTests.Trompeloeil.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named DistributedCalculatorTests.Trompeloeil.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DistributedCalculatorTests.Trompeloeil.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /DistributedCalculatorTests.Trompeloeil/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Dror Helper 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppUnitTestingAndMockingComparison --------------------------------------------------------------------------------