1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "googletest.h"
27
28 #include <clangfixitoperation.h>
29 #include <fixitcontainer.h>
30
31 #include <utils/changeset.h>
32
33 #include <QFile>
34 #include <QVector>
35
36 using ClangBackEnd::FixItContainer;
37 using ClangCodeModel::Internal::ClangFixItOperation;
38
39 using ::testing::PrintToString;
40
41 namespace {
42
unsavedFileContent(const QString & unsavedFilePath)43 QString unsavedFileContent(const QString &unsavedFilePath)
44 {
45 QFile unsavedFileContentFile(unsavedFilePath);
46 const bool isOpen = unsavedFileContentFile.open(QFile::ReadOnly | QFile::Text);
47 if (!isOpen)
48 ADD_FAILURE() << "File with the unsaved content cannot be opened!";
49
50 return QString::fromUtf8(unsavedFileContentFile.readAll());
51 }
52
53 MATCHER_P(MatchText, expectedText,
54 std::string(negation ? "hasn't" : "has")
55 + " expected text:\n" + PrintToString(expectedText))
56 {
57 const ::ClangFixItOperation &operation = arg;
58 QString resultText = operation.firstRefactoringFileContent_forTestOnly();
59
60 if (resultText != expectedText) {
61 *result_listener << "\n" << resultText.toUtf8().constData();
62 return false;
63 }
64
65 return true;
66 }
67
68 class ClangFixItOperation : public ::testing::Test
69 {
70 protected:
71 Utf8String semicolonFilePath{TESTDATA_DIR"/diagnostic_semicolon_fixit.cpp", -1};
72 Utf8String compareFilePath{TESTDATA_DIR"/diagnostic_comparison_fixit.cpp", -1};
73 Utf8String diagnosticText{Utf8StringLiteral("expected ';' at end of declaration")};
74 FixItContainer semicolonFixItContainer{Utf8StringLiteral(";"),
75 {{semicolonFilePath, 3u, 13u},
76 {semicolonFilePath, 3u, 13u}}};
77 QString semicolonErrorFile{semicolonFilePath.toString()};
78 QString semicolonExpectedFile{QString::fromUtf8(TESTDATA_DIR"/diagnostic_semicolon_fixit_expected.cpp")};
79 QString compareWarningFile{compareFilePath.toString()};
80 QString compareExpected1File{QString::fromUtf8(TESTDATA_DIR"/diagnostic_comparison_fixit_expected1.cpp")};
81 QString compareExpected2File{QString::fromUtf8(TESTDATA_DIR"/diagnostic_comparison_fixit_expected2.cpp")};
82 FixItContainer compareFixItContainer{Utf8StringLiteral("=="),
83 {{compareFilePath, 4u, 11u},
84 {compareFilePath, 4u, 12u}}};
85 FixItContainer assignmentFixItContainerParenLeft{Utf8StringLiteral("("),
86 {{compareFilePath, 4u, 9u},
87 {compareFilePath, 4u, 9u}}};
88 FixItContainer assignmentFixItContainerParenRight{Utf8StringLiteral(")"),
89 {{compareFilePath, 4u, 14u},
90 {compareFilePath, 4u, 14u}}};
91 };
92
TEST_F(ClangFixItOperation,Description)93 TEST_F(ClangFixItOperation, Description)
94 {
95 ::ClangFixItOperation operation(diagnosticText, {semicolonFixItContainer});
96
97 ASSERT_THAT(operation.description(),
98 QStringLiteral("Apply Fix: expected ';' at end of declaration"));
99 }
100
TEST_F(ClangFixItOperation,AppendSemicolon)101 TEST_F(ClangFixItOperation, AppendSemicolon)
102 {
103 ::ClangFixItOperation operation(diagnosticText, {semicolonFixItContainer});
104
105 operation.perform();
106
107 ASSERT_THAT(operation, MatchText(unsavedFileContent(semicolonExpectedFile)));
108 }
109
TEST_F(ClangFixItOperation,ComparisonVersusAssignmentChooseComparison)110 TEST_F(ClangFixItOperation, ComparisonVersusAssignmentChooseComparison)
111 {
112 ::ClangFixItOperation operation(diagnosticText, {compareFixItContainer});
113
114 operation.perform();
115
116 ASSERT_THAT(operation, MatchText(unsavedFileContent(compareExpected1File)));
117 }
118
TEST_F(ClangFixItOperation,ComparisonVersusAssignmentChooseParentheses)119 TEST_F(ClangFixItOperation, ComparisonVersusAssignmentChooseParentheses)
120 {
121 ::ClangFixItOperation operation(diagnosticText,
122 {assignmentFixItContainerParenLeft,
123 assignmentFixItContainerParenRight});
124
125 operation.perform();
126
127 ASSERT_THAT(operation, MatchText(unsavedFileContent(compareExpected2File)));
128 }
129
130 }
131