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 dextool.plugin.mutate.backend.test_mutant.test_case_analyze : GatherTestCase;
19 import dextool.plugin.mutate.backend.type : TestCase;
20 import dextool.type : AbsolutePath;
21 
22 /** Parse input for ctest test cases.
23  *
24  * Params:
25  *  r = range that is chunked by line
26  *  report = where the results are put.
27  */
28 struct CtestParser {
29     import std.regex : regex, matchFirst;
30 
31     private {
32         // example: Start 35: gtest_repeat_test
33         enum re_start_tc = regex(`^\s*Start\s*\d*:\s*(?P<tc>.*)`);
34         // example:  2/3  Test  #2: gmock-cardinalities_test ................***Failed    0.00 sec
35         enum re_fail_tc = regex(`.*?Test.*:\s*(?P<tc>.*?)\s*\.*\*\*\*.*`);
36 
37         StateData data;
38     }
39 
40     void process(T)(T line, ref GatherTestCase report) {
41         auto start_tc_match = matchFirst(line, re_start_tc);
42         auto fail_tc_match = matchFirst(line, re_fail_tc);
43 
44         data.hasStartTc = !start_tc_match.empty;
45         data.hasFailTc = !fail_tc_match.empty;
46 
47         if (data.hasStartTc)
48             report.reportFound(TestCase(start_tc_match["tc"].idup));
49 
50         if (data.hasFailTc)
51             report.reportFailed(TestCase(fail_tc_match["tc"].idup));
52     }
53 }
54 
55 private:
56 
57 struct StateData {
58     bool hasStartTc;
59     bool hasFailTc;
60 }
61 
62 version (unittest) {
63     import std.algorithm : each, sort;
64     import std.array : array;
65     import unit_threaded : shouldEqual, shouldBeIn;
66 }
67 
68 @("shall report the failed test cases")
69 unittest {
70     GatherTestCase app;
71     CtestParser parser;
72     testData2.each!(a => parser.process(a, app));
73 
74     // dfmt off
75     shouldEqual(app.failedAsArray.sort,
76                 [TestCase("gmock-cardinalities_test")]
77                 );
78     // dfmt on
79 }
80 
81 @("shall report the found test cases")
82 unittest {
83     GatherTestCase app;
84     CtestParser parser;
85     testData1.each!(a => parser.process(a, app));
86 
87     // dfmt off
88     shouldEqual(app.foundAsArray.sort, [
89                 TestCase("gmock-actions_test"),
90                 TestCase("gmock-cardinalities_test"),
91                 TestCase("gmock_ex_test")
92                 ]);
93     // dfmt on
94 }
95 
96 version (unittest) {
97     string[] testData1() {
98         // dfmt off
99         return [
100 "Test project /home/joker/src/cpp/googletest/build",
101 "      Start  1: gmock-actions_test",
102 " 1/3  Test  #1: gmock-actions_test ......................   Passed    1.61 sec",
103 "      Start  2: gmock-cardinalities_test",
104 " 2/3  Test  #2: gmock-cardinalities_test ................   Passed    0.00 sec",
105 "      Start  3: gmock_ex_test",
106 " 3/3  Test  #3: gmock_ex_test ...........................   Passed    0.01 sec",
107 "",
108 "100% tests passed, 0 tests failed out of 3",
109 "",
110 "Total Test time (real) =   7.10 sec",
111         ];
112         // dfmt on
113     }
114 
115     string[] testData2() {
116         // dfmt off
117         return [
118 "Test project /home/joker/src/cpp/googletest/build",
119 "      Start  1: gmock-actions_test",
120 " 1/3  Test  #1: gmock-actions_test ......................   Passed    1.61 sec",
121 "      Start  2: gmock-cardinalities_test",
122 " 2/3  Test  #2: gmock-cardinalities_test ................***Failed    0.00 sec",
123 "      Start  3: gmock_ex_test",
124 " 3/3  Test  #3: gmock_ex_test ...........................   Passed    0.01 sec",
125 "",
126 "100% tests passed, 0 tests failed out of 3",
127 "",
128 "Total Test time (real) =   7.10 sec",
129 "",
130 "The following tests FAILED:",
131 "         15 - gmock-cardinalities_test (Failed)",
132         ];
133         // dfmt on
134     }
135 }