1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 
10 #SPC-track_ctest
11 */
12 module dextool.plugin.mutate.backend.test_mutant.ctest_post_analyze;
13 
14 import std.exception : collectException;
15 import std.range : isInputRange, isOutputRange;
16 import logger = std.experimental.logger;
17 
18 import my.set;
19 
20 import dextool.plugin.mutate.backend.test_mutant.test_case_analyze : GatherTestCase;
21 import dextool.plugin.mutate.backend.type : TestCase;
22 import dextool.type : AbsolutePath;
23 
24 /** Parse input for ctest test cases.
25  *
26  * Params:
27  *  r = range that is chunked by line
28  *  report = where the results are put.
29  */
30 struct CtestParser {
31     import std.regex : regex, matchFirst;
32 
33     private {
34         // example: Start 35: gtest_repeat_test
35         enum re_start_tc = regex(`^\s*Start\s*\d*:\s*(?P<tc>.*)`);
36         // example:  2/3  Test  #2: gmock-cardinalities_test ................***Failed    0.00 sec
37         enum re_fail_tc = regex(`.*?Test.*:\s*(?P<tc>.*?)\s*\.*\*\*\*.*`);
38 
39         StateData data;
40     }
41 
42     void process(T)(T line, ref GatherTestCase report) {
43         auto start_tc_match = matchFirst(line, re_start_tc);
44         auto fail_tc_match = matchFirst(line, re_fail_tc);
45 
46         data.hasStartTc = !start_tc_match.empty;
47         data.hasFailTc = !fail_tc_match.empty;
48 
49         if (data.hasStartTc)
50             report.reportFound(TestCase(start_tc_match["tc"].idup));
51 
52         if (data.hasFailTc)
53             report.reportFailed(TestCase(fail_tc_match["tc"].idup));
54     }
55 }
56 
57 private:
58 
59 struct StateData {
60     bool hasStartTc;
61     bool hasFailTc;
62 }
63 
64 version (unittest) {
65     import std.algorithm : each, sort;
66     import std.array : array;
67     import unit_threaded : shouldEqual, shouldBeIn;
68 }
69 
70 @("shall report the failed test cases")
71 unittest {
72     GatherTestCase app;
73     CtestParser parser;
74     testData2.each!(a => parser.process(a, app));
75 
76     // dfmt off
77     shouldEqual(app.failed.toArray.sort,
78                 [TestCase("gmock-cardinalities_test")]
79                 );
80     // dfmt on
81 }
82 
83 @("shall report the found test cases")
84 unittest {
85     GatherTestCase app;
86     CtestParser parser;
87     testData1.each!(a => parser.process(a, app));
88 
89     // dfmt off
90     shouldEqual(app.found.toArray.sort, [
91                 TestCase("gmock-actions_test"),
92                 TestCase("gmock-cardinalities_test"),
93                 TestCase("gmock_ex_test")
94                 ]);
95     // dfmt on
96 }
97 
98 version (unittest) {
99     string[] testData1() {
100         // dfmt off
101         return [
102 "Test project /home/joker/src/cpp/googletest/build",
103 "      Start  1: gmock-actions_test",
104 " 1/3  Test  #1: gmock-actions_test ......................   Passed    1.61 sec",
105 "      Start  2: gmock-cardinalities_test",
106 " 2/3  Test  #2: gmock-cardinalities_test ................   Passed    0.00 sec",
107 "      Start  3: gmock_ex_test",
108 " 3/3  Test  #3: gmock_ex_test ...........................   Passed    0.01 sec",
109 "",
110 "100% tests passed, 0 tests failed out of 3",
111 "",
112 "Total Test time (real) =   7.10 sec",
113         ];
114         // dfmt on
115     }
116 
117     string[] testData2() {
118         // dfmt off
119         return [
120 "Test project /home/joker/src/cpp/googletest/build",
121 "      Start  1: gmock-actions_test",
122 " 1/3  Test  #1: gmock-actions_test ......................   Passed    1.61 sec",
123 "      Start  2: gmock-cardinalities_test",
124 " 2/3  Test  #2: gmock-cardinalities_test ................***Failed    0.00 sec",
125 "      Start  3: gmock_ex_test",
126 " 3/3  Test  #3: gmock_ex_test ...........................   Passed    0.01 sec",
127 "",
128 "100% tests passed, 0 tests failed out of 3",
129 "",
130 "Total Test time (real) =   7.10 sec",
131 "",
132 "The following tests FAILED:",
133 "         15 - gmock-cardinalities_test (Failed)",
134         ];
135         // dfmt on
136     }
137 }