1 /++
2   When you run complex tests, or tests that take a lot of time, it helps
3   to mark certain areas as steps, to ease the debug or to improve the report.
4 
5   A good usage is for running BDD tests where a step can be steps from the
6   `Gherkin Syntax` or UI Automation tests.
7 
8   Copyright: © 2017 Szabo Bogdan
9   License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
10   Authors: Szabo Bogdan
11 +/
12 module trial.step;
13 
14 import trial.runner;
15 import trial.interfaces;
16 import std.datetime;
17 import std.stdio;
18 
19 /** A step structure. Creating a Step will automatically be added to the current step as a child
20   * The steps can be nested to allow you to group steps as with meanigful names.
21   *
22   * The steps ends when the Struct is destroyed. In order to have a step that represents a method
23   * assign it to a local variable
24   *
25   * Examples:
26   * ------------------------
27   * void TestSetup() @system
28   * {
29   *   auto aStep = Step("Given some precondition");
30   *
31   *   Step("Some setup");
32   *   performSomeSetup();
33   *
34   *   Step("Other setup");
35   *   performOtherSetup();
36   * }
37   * // will create this tree:
38   * // Test
39   * //  |
40   * //  +- Given some precondition
41   * //        |
42   * //        +- Some setup
43   * //        +- Other setup
44   * ------------------------
45   */
46 struct Step
47 {
48   static {
49     /// The current suite name. Do not alter this global variable
50     string suite;
51     /// The current test name. Do not alter this global variable
52     string test;
53   }
54 
55   @disable
56   this();
57 
58   private {
59     StepResult step;
60   }
61 
62   /// Create and attach a step
63   this(string name) {
64     step = new StepResult;
65     step.name = name;
66     step.begin = Clock.currTime;
67     step.end = Clock.currTime;
68 
69     if(LifeCycleListeners.instance is null) {
70       writeln("Warning! Can not set steps if the LifeCycleListeners.instance is not set.");
71       return;
72     }
73 
74     LifeCycleListeners.instance.begin(suite, test, step);
75   }
76 
77   /// Mark the test as finished
78   ~this() {
79     if(LifeCycleListeners.instance is null) {
80       writeln("Warning! Can not set steps if the LifeCycleListeners.instance is not set.");
81       return;
82     }
83 
84     step.end = Clock.currTime;
85     LifeCycleListeners.instance.end(suite, test, step);
86   }
87 }