1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329 | /* 1-A: Initialize the plugin on Qt Creator Startup */
bool AutopilotPlugin::initialize(const QStringList &arguments, QString *errorString)
{
// Register objects in the plugin manager's object pool
// Load settings
// Add actions to menus
// Connect to other plugins' signals
// In the initialize function, a plugin can be sure that the plugins it
// depends on have initialized their members.
Q_UNUSED(arguments)
Q_UNUSED(errorString)
createMenu(); // 2-A
connectProjectAdded(); // 3-A
return true;
}
/* 2-A: Create the Menu */
void AutopilotPlugin::createMenu() {
m_menu->menu()->setTitle(QString(QLatin1String("Autopilot")));
Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(m_menu);
return;
}
/* 3-A: onProjectChange->findAutopilotModule | onRefreshClicked->checkForNewTests */
void AutopilotPlugin::connectProjectAdded() {
connect( static_cast <ProjectExplorer::SessionManager *>(ProjectExplorer::SessionManager::instance())
,SIGNAL(projectAdded(ProjectExplorer::Project*))
,this
,SLOT(connectProjectLoaded(ProjectExplorer::Project*))); //4-A
// Todo: Add refresh signal onRefreshClicked->checkForNewTests
return;
}
void AutopilotPlugin::connectProjectLoaded(ProjectExplorer::Project* project) {
qDebug() << "settings loading...";
emit project->settingsLoaded();
return;
}
/* 4-A: Current Project Changed - Search for Autopilot Module */
void AutopilotPlugin::findAutopilotModule()
{
qDebug() << "-----------------------------------====================================================";
qDebug() << "it worked!";
// Todo: Projects > Run > Autopilot Settings > Test List - needs to be cleared
bool m_find = true; // Flag indicates we are still searching for tests
QStringList m_findTestSuiteArgs;
QStringList m_findTestSuiteStout;
QString m_autopilotListModule;
/* Find by project/tests/autopilot Method */
if (m_find && QDir(ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory()
+ tr("/tests/autopilot")).exists()) {
m_findTestSuiteArgs.clear();
m_findTestSuiteStout.clear();
s_workingDirectory = ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory()
+ tr("/tests/autopilot");
/* Get Directory */
QStringList m_findTestSuiteDir = s_workingDirectory.entryList(QDir::Filter::AllDirs);
m_findTestSuiteDir.removeAll(tr(".."));
m_findTestSuiteDir.removeAll(tr("."));
/* Check to see if this method is possible */
if (m_findTestSuiteDir.count() > 1) {
qDebug() << "More than one directory, unable to determine proper module";
}
else {
m_autopilotListModule = m_findTestSuiteDir.first();
m_find = false;
}
}
/* Find by project/app/tests/autopilot Method */
if (m_find && QDir(ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory()
+ tr("/app/tests/autopilot")).exists()) {
m_findTestSuiteArgs.clear();
m_findTestSuiteStout.clear();
s_workingDirectory = ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory()
+ tr("/app/tests/autopilot");
/* Get Directory */
QStringList m_findTestSuiteDir = s_workingDirectory.entryList(QDir::Filter::AllDirs);
m_findTestSuiteDir.removeAll(tr(".."));
m_findTestSuiteDir.removeAll(tr("."));
/* Check to see if this method is possible */
if (m_findTestSuiteDir.count() > 1) {
qDebug() << "More than one directory, unable to determine proper module";
return;
}
else {
m_autopilotListModule = m_findTestSuiteDir.first();
m_find = false;
}
}
/* Find by Folder==Project Name Method */
if (m_find) {
QProcess* m_findTestSuite = new QProcess();
m_findTestSuiteArgs.clear();
/* Directory to search */
m_findTestSuiteArgs.append(ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory());
m_findTestSuiteArgs.append(tr("-type"));// Type of file to find
m_findTestSuiteArgs.append(tr("d")); // Directory
m_findTestSuiteArgs.append(tr("-name"));
m_findTestSuiteArgs.append(ProjectExplorer::ProjectExplorerPlugin::currentProject()->displayName());
m_findTestSuiteArgs.append(tr("-print"));
m_findTestSuite->setArguments(m_findTestSuiteArgs);
m_findTestSuite->start(tr("find"),m_findTestSuite->arguments());
m_findTestSuite->waitForFinished();
m_findTestSuiteStout = QString(QLatin1String(m_findTestSuite->readAllStandardOutput())).split(tr("\n"));
delete m_findTestSuite;
/* Sanitize Results List */
m_findTestSuiteStout.removeAll(tr(""));
m_findTestSuiteStout.removeAll(ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory());
/* Check for empty string, to indicate no Autopilot Suite */
if (m_findTestSuiteStout.isEmpty()) {
}
/* Check for Success */
else if (m_findTestSuiteStout.first().split(tr("/")).at(m_findTestSuiteStout.first().split(tr("/")).count()-2)
== tr("autopilot")) {
s_workingDirectory = QDir(m_findTestSuiteStout.first());
s_workingDirectory.cdUp();
m_autopilotListModule = ProjectExplorer::ProjectExplorerPlugin::currentProject()->displayName();
m_find = false;
}
}
/* Find by __init__.py Method */
if (m_find) {
QProcess* m_findTestSuite = new QProcess();
m_findTestSuiteArgs.clear();
m_findTestSuiteStout.clear();
m_findTestSuiteArgs.append(tr("--recursive")); // Search recursively
m_findTestSuiteArgs.append(tr("--word")); // Match the entire word
m_findTestSuiteArgs.append(tr("--include=__init__.py"));// Search only python files
m_findTestSuiteArgs.append(tr("--files-with-matches")); // Returns the file name
m_findTestSuiteArgs.append(tr("from autopilot")); //
m_findTestSuiteArgs.append(ProjectExplorer::ProjectExplorerPlugin::currentProject()->projectDirectory());
m_findTestSuite->setWorkingDirectory(tr("/")); // Allows to get full paths from grep
m_findTestSuite->setArguments(m_findTestSuiteArgs);
m_findTestSuite->start(tr("grep"),m_findTestSuite->arguments());
m_findTestSuite->waitForFinished();
/* Create List, Sanitize the results */
m_findTestSuiteStout = QString(QLatin1String(m_findTestSuite->readAllStandardOutput())).split(tr("\n"));
m_findTestSuiteStout.removeAll(tr(""));
for (int i=0; i < m_findTestSuiteStout.length(); i++){
if (m_findTestSuiteStout.at(i).split(tr("/")).at(m_findTestSuiteStout.at(i).split(tr("/")).length()-2)
== tr("tests")){
m_findTestSuiteStout.removeAt(i);
i--; // Compensates for the removed item.
}
}
/* Check for any results */
if (!m_findTestSuiteStout.isEmpty()) {
s_workingDirectory = QDir(m_findTestSuiteStout.first().replace(tr("__init__.py"),tr("")));
s_workingDirectory.cdUp();
m_autopilotListModule = m_findTestSuiteStout.first().split(tr("/"))
.at(m_findTestSuiteStout.first().split(tr("/")).count()-2);
m_find = false;
}
delete m_findTestSuite;
}
if (!m_find) {
qDebug() << "Autopilot Suite Found";
findAutopilotTests(m_autopilotListModule);
/* 6-A: Create Test Menu Items */
setMenu();
/* 7-A: A Run Configuration is inserted into the panel above the green play button */
createAutopilotRunConfiguration(m_autopilotListModule);
}
}
/* 5-B: Search for Autopilot Tests, and configure s_autopilotList accordingly */
void AutopilotPlugin::findAutopilotTests(QString module) {
/* Set arguments for "autopilot3 list [module]" QProcess */
QStringList m_autopilotListArgs;
m_autopilotListArgs.append(tr("list"));
m_autopilotListArgs.append(module);
/* Execute "autopilot3 list [module]" Command */
QProcess* m_getAutopilotList = new QProcess();
QString m_autopilotListStout;
m_getAutopilotList->setWorkingDirectory(s_workingDirectory.path());
m_getAutopilotList->setArguments(m_autopilotListArgs);
m_getAutopilotList->start(tr("autopilot3"),m_getAutopilotList->arguments());
m_getAutopilotList->waitForFinished();
m_autopilotListStout = QString(QLatin1String(m_getAutopilotList->readAllStandardOutput()));
delete m_getAutopilotList;
/* Sanitize Stdout String */
s_autoPilotList = m_autopilotListStout
.remove(tr(" ")) // Removes the first 4 spaces, otherwise autopilot won't recognize the module
.remove(QRegularExpression(tr(" \\*[0-9]+ "))) // Some tests are appended with " *3 ".
.split(QString(QLatin1String("\n")));
s_autoPilotList.removeLast();
/* 6-B: Check for autopilot3 test suite error */
if (s_autoPilotList.last() == QString(QLatin1String(" 0 total tests."))
|| s_autoPilotList.at(2).split(tr(":")).first() == tr("Failed to import test module")) {
qDebug() << "Error: Failed to import tests";
qDebug() << m_autopilotListStout;
// Todo: Display Debug in Projects > Run > Autopilot Settings
// Todo: Disable option in run menu
s_autoPilotList.clear();
return;
}
/* Sanitize List of Tests */
s_autoPilotList.removeDuplicates();
s_autoPilotList.removeLast();
s_autoPilotList.removeFirst();
s_autoPilotList.removeFirst();
return;
}
/* 6-A: Create Test Menu Items */
void AutopilotPlugin::setMenu() {
/* Recreate Menu */
for (int i=0; i<s_autoPilotList.length(); i++){
/* Create Menu Item Title */
QAction* m_menuAction = new QAction(QString(s_autoPilotList
.at(i)
.split(tr("."))
.first()
.replace(tr(" "),tr(""))
.replace(tr("_"),tr(" ")) +
tr(" | ") +
s_autoPilotList
.at(i)
.split(tr(".test_"))
.last()
.replace(tr("_"),tr(" ")))
,this);
/* Register the action, feeding it a unique id based on the test. */
m_menuCommand = Core::ActionManager::registerAction(m_menuAction,
s_autoPilotList.at(i).toStdString().c_str(),
Core::Context(Core::Constants::C_GLOBAL));
/* Pass the name of the test */
QSignalMapper* m_menuSignal = new QSignalMapper (this) ;
connect(m_menuAction, SIGNAL(triggered()), m_menuSignal, SLOT(map()));
m_menuSignal->setMapping(m_menuAction,QString(
s_workingDirectory.path() +
tr("😸") + // Its just easier to pass this than a QStringList
s_autoPilotList.at(i)));
connect(m_menuSignal, SIGNAL(mapped(QString)), this, SLOT(runMenuAction(QString))) ;
/* Shuttleworth's Beard */
m_menuAction->setCheckable(true);
m_menu->addAction(m_menuCommand);
}
}
/* 7-A: A Run Configuration is inserted into the panel above the green play button */
void AutopilotPlugin::createAutopilotRunConfiguration(QString module) {
Autopilot::AutopilotRunConfigurationFactory *m_autopilotRunConfigurationFactory
= new Autopilot::AutopilotRunConfigurationFactory();
addAutoReleasedObject(m_autopilotRunConfigurationFactory);
QList<Core::Id> m_autopilotID = m_autopilotRunConfigurationFactory->availableCreationIds(ProjectExplorer::ProjectExplorerPlugin::currentProject()->activeTarget());
m_autopilotRunConfigurationFactory->create(ProjectExplorer::ProjectExplorerPlugin::currentProject()->activeTarget(),m_autopilotID.first());
Autopilot::AutopilotRunConfiguration* m_autopilotRunConfiguration
= new Autopilot::AutopilotRunConfiguration(ProjectExplorer::ProjectExplorerPlugin::currentProject()->activeTarget());
m_autopilotRunConfiguration->setExecutable(tr("/usr/bin/autopilot3"));
//m_autopilotRunConfiguration->setCommandLineArguments(tr("run ") + module);
m_autopilotRunConfiguration->setDisplayName(tr("Autopilot"));
m_autopilotRunConfiguration->setWorkingDirectory(s_workingDirectory.path());
m_autopilotRunConfiguration->setModule(module);
m_autopilotRunConfiguration->setTestList(s_autoPilotList);
m_autopilotRunConfiguration->setDefaultDisplayName(tr("Autopilot"));
m_autopilotRunConfiguration->setObjectName(tr("AutopilotRunConfiguration"));
QWidget *happy = m_autopilotRunConfiguration->createConfigurationWidget();
happy->show();
ProjectExplorer::ProjectExplorerPlugin::instance()->currentProject()->activeTarget()->addRunConfiguration(m_autopilotRunConfiguration);
addAutoReleasedObject(m_autopilotRunConfiguration);
return;
}
/* Running Tests from Menu/HUD */
void AutopilotPlugin::runMenuAction(QString text) {
QProcess* m_menuActionProcess = new QProcess();
QStringList* m_menuActionArguments = new QStringList();
/* Set Arguments */
m_menuActionArguments->append(tr("run"));
m_menuActionArguments->append(text.split(tr("😸")).last());
m_menuActionProcess->setArguments(*m_menuActionArguments);
/* Start */
m_menuActionProcess->setWorkingDirectory(text.split(tr("😸")).first());
m_menuActionProcess->start(tr("autopilot3"), m_menuActionProcess->arguments());
m_menuActionProcess->waitForFinished(60000);
/* Dump Output */
//Todo: Change the dump to the "3 | Application Output"
QMessageBox::information(0, tr("Results"), QString(QLatin1String(m_menuActionProcess->readAllStandardOutput())));
delete m_menuActionProcess;
delete m_menuActionArguments;
return;
}
|