1 /** 2 Copyright: 2017 © LLC CERERIS 3 License: MIT 4 Authors: LLC CERERIS 5 */ 6 7 module checkit.runner; 8 9 import checkit.block; 10 import checkit.blockmanager; 11 import checkit.reporter; 12 import std.conv; 13 import std.getopt; 14 import std.stdio; 15 16 /// Interface for running test 17 interface RunnerInterface 18 { 19 public: 20 /// Run tests and return code 21 int run(); 22 } 23 24 /** Provide run BDD tests 25 26 Params: 27 T = BlockManagerInterface 28 */ 29 class BDDTestRunner(T): RunnerInterface 30 { 31 public: 32 /** Constructor 33 34 Params: 35 reporter = Provide reporting test. 36 37 Examples: 38 --- 39 auto reporter = new ConsoleReporter(); 40 auto runner = new BDDTestRunner!(reporter); 41 --- 42 */ 43 this(ReporterInterface reporter) 44 { 45 _reporter = reporter; 46 } 47 48 /** Run tests and return code 49 50 Returns: 51 Return code $(D int) for main function 52 53 Examples: 54 --- 55 auto reporter = new ConsoleReporter(); 56 auto runner = new BDDTestRunner!(reporter); 57 runner.run(); 58 --- 59 */ 60 int run() 61 { 62 _returnCode = 0; 63 _failBlocks = []; 64 _successBlocks = []; 65 checkNoBlock!GivenBlock(); 66 checkNoBlock!WhenBlock(); 67 checkNoBlock!ThenBlock(); 68 69 foreach(scenario; T.getByType!ScenarioBlock()) 70 { 71 runBlock(scenario); 72 } 73 74 _reporter.printResults(_successBlocks, _failBlocks); 75 76 return _returnCode; 77 } 78 79 private: 80 81 void checkNoBlock(U)() 82 { 83 U[] blocks = T.getByType!U(); 84 if(blocks.length) 85 { 86 _returnCode = -1; 87 88 foreach(block; blocks) 89 { 90 T.removeBlockByUUID(block.getUUID()); 91 } 92 } 93 } 94 95 void runBlock(ScenarioBlock block) 96 { 97 checkNoBlock!WhenBlock(); 98 checkNoBlock!ThenBlock(); 99 100 executeBlock(block); 101 foreach(given; T.getByType!GivenBlock()) 102 { 103 runBlock(given); 104 } 105 } 106 107 void runBlock(GivenBlock block) 108 { 109 checkNoBlock!ThenBlock(); 110 111 executeBlock(block); 112 foreach(when; T.getByType!WhenBlock()) 113 { 114 runBlock(when); 115 } 116 } 117 118 void runBlock(WhenBlock block) 119 { 120 executeBlock(block); 121 foreach(then; T.getByType!ThenBlock()) 122 { 123 executeBlock(then); 124 } 125 } 126 127 void executeBlock(U)(U block) 128 { 129 try 130 { 131 block.getCallback()(); 132 _reporter.success(block); 133 _successBlocks ~= block; 134 } 135 catch(Exception e) 136 { 137 _returnCode = -1; 138 _failBlocks ~= block; 139 _reporter.fail(block); 140 _reporter.fail(typeid(e).toString() ~ "@" ~ e.file ~ "(" ~ to!string(e.line) ~ "): " ~ e.msg); 141 } 142 143 T.removeBlockByUUID(block.getUUID()); 144 } 145 146 ReporterInterface _reporter; 147 int _returnCode; 148 TestBlock[] _successBlocks; 149 TestBlock[] _failBlocks; 150 } 151 152 int runTests(string[] args) 153 { 154 bool verbose = false; 155 156 getopt( 157 args, 158 "verbose|v", &verbose 159 ); 160 161 auto reporter = new ConsoleReporter; 162 reporter.setVerbose(verbose); 163 auto runner = new BDDTestRunner!BlockManager(reporter); 164 return runner.run(); 165 }