1 /**
2   Copyright: 2017 © LLC CERERIS
3   License: MIT
4   Authors: LLC CERERIS
5 */
6 
7 module checkit.reporter;
8 
9 import checkit.block;
10 import std.conv: to;
11 import std.stdio;
12 import std..string;
13 
14 /// Reporter interface
15 interface ReporterInterface
16 {
17   public:
18     /// Report success test block
19     void success(TestBlock block);
20     /// Report fail test block
21     void fail(TestBlock block);
22     /// Report fail message
23     void fail(string message);
24     /// Print result of testing proccess
25     void printResults(TestBlock[] successBlocks, TestBlock[] failBlocks);
26     /// Set verbose mode - more information
27     void setVerbose(bool verbose);
28 }
29 
30 /// Color reporter for console output
31 class ConsoleReporter: ReporterInterface
32 {
33   public:
34     /// Report success test block
35     void success(TestBlock block)
36     {
37       if(_verbose)
38       {
39         if(auto scenario = cast(ScenarioBlock) block)
40         {
41           writeln();
42           writeln(
43             getColor(ConsoleColor.LIGHT_BLUE) ~
44             to!string(scenario.getTags()) ~
45             getColor(ConsoleColor.INITIAL)
46           );
47           printKeyValue("SCENARIO: ", block.getName(), ConsoleColor.LIGHT_YELLOW, ConsoleColor.LIGHT_GREEN);
48         }
49         else if(auto given = cast(GivenBlock) block)
50         { 
51           printKeyValue("   GIVEN: ", block.getName(), ConsoleColor.LIGHT_YELLOW, ConsoleColor.LIGHT_GREEN);
52         }
53         else if(auto when = cast(WhenBlock) block)
54         {  
55           printKeyValue("    WHEN: ", block.getName(), ConsoleColor.LIGHT_YELLOW, ConsoleColor.LIGHT_GREEN);
56         }
57         else if(auto then = cast(ThenBlock) block)
58         { 
59           printKeyValue("    THEN: ", block.getName(), ConsoleColor.LIGHT_YELLOW, ConsoleColor.LIGHT_GREEN);
60         }
61       }
62       else
63       {
64         printChar('.', ConsoleColor.LIGHT_GREEN);
65       }
66     }
67 
68     /// Report fail test block
69     void fail(TestBlock block)
70     {
71       if(!_verbose)
72       {
73         writeln();
74       }
75 
76       if(auto scenario = cast(ScenarioBlock) block)
77       { 
78         writeln();
79         printKeyValue("SCENARIO: ", block.getName(), ConsoleColor.LIGHT_RED, ConsoleColor.LIGHT_RED);
80       }
81       else if(auto given = cast(GivenBlock) block)
82       { 
83         printKeyValue("   GIVEN: ", block.getName(), ConsoleColor.LIGHT_RED, ConsoleColor.LIGHT_RED);
84       }
85       else if(auto when = cast(WhenBlock) block)
86       { 
87         printKeyValue("    WHEN: ", block.getName(), ConsoleColor.LIGHT_RED, ConsoleColor.LIGHT_RED);
88       }
89       else if(auto then = cast(ThenBlock) block)
90       { 
91         printKeyValue("    THEN: ", block.getName(), ConsoleColor.LIGHT_RED, ConsoleColor.LIGHT_RED);
92       }
93     }
94 
95     /// Report fail message
96     void fail(string message)
97     {
98       writeln(
99           getColor(ConsoleColor.LIGHT_RED) ~
100           "   THROW: " ~
101           message ~
102           getColor(ConsoleColor.INITIAL)
103           );
104     }
105 
106     /** Print result of testing proccess
107 
108       Params:
109         successBlocks = Test that run success.
110         failBlocks = Test that run fail.
111     */
112     void printResults(TestBlock[] successBlocks, TestBlock[] failBlocks)
113     {
114       writeln();
115       writeln("%sTotal %d, success %d, fail %d%s".format(
116             getColor(ConsoleColor.LIGHT_GREEN), 
117             successBlocks.length + failBlocks.length,
118             successBlocks.length,
119             failBlocks.length,
120             getColor(ConsoleColor.INITIAL)));
121     }
122 
123     /** Set verbose mode - more information
124 
125       Params:
126         verbose = Set more information.
127     */
128     void setVerbose(bool verbose)
129     {
130       _verbose = verbose;
131     }
132 
133   private:
134     void printChar(char symbol, ConsoleColor color)
135     {
136       write(getColor(color) ~ symbol ~ getColor(ConsoleColor.INITIAL));
137     }
138 
139     void printKeyValue(string key, string value, ConsoleColor keyColor, ConsoleColor valueColor)
140     {
141       writeln(
142           getColor(keyColor) ~ key ~ 
143           getColor(valueColor) ~ value ~ 
144           getColor(ConsoleColor.INITIAL)
145       );
146     }
147 
148     version(Posix)
149     {
150       enum ConsoleColor: ushort
151       {
152         LIGHT_RED = 95,
153         LIGHT_GREEN = 96,
154         LIGHT_YELLOW = 97,
155         LIGHT_BLUE = 98,
156         BRIGHT = 64,
157         INITIAL = 256
158       }
159 
160       string getColor(ConsoleColor color)
161       {
162         return "\033[%d;%d;%d;%d;%d;%dm".format(
163           color & ConsoleColor.BRIGHT ? 1: 0,
164           color & ~ConsoleColor.BRIGHT,
165           (256 & !ConsoleColor.BRIGHT) + 10,
166           24,
167           29,
168           21
169           );
170       }
171     }
172 
173     /// Is verbose mode
174     bool _verbose;
175 }