[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [simon] plugins/Commands: Resuming work on the ATSPI plugin; Adding testing framework
From:       Peter Grasch <grasch () simon-listens ! org>
Date:       2013-02-06 9:15:54
Message-ID: 20130206091554.8FEE5A6091 () git ! kde ! org
[Download RAW message or body]

Git commit 9f5237b638ddabee96cb452ca442b26690a2d3b2 by Peter Grasch.
Committed on 06/02/2013 at 10:15.
Pushed by grasch into branch 'master'.

Resuming work on the ATSPI plugin; Adding testing framework

M  +5    -3    plugins/Commands/ATSPI/CMakeLists.txt
M  +73   -37   plugins/Commands/ATSPI/atspiscanner.cpp
M  +12   -4    plugins/Commands/ATSPI/atspiscanner.h
A  +21   -0    plugins/Commands/ATSPI/test/CMakeLists.txt
A  +112  -0    plugins/Commands/ATSPI/test/accessibleapp.cpp     [License: \
GPL (v2)] A  +49   -0    plugins/Commands/ATSPI/test/accessibleapp.h     \
[License: GPL (v2)] A  +163  -0    \
plugins/Commands/ATSPI/test/atspiscannertest.cpp     [License: GPL (v2)] M  \
+1    -1    plugins/Commands/CMakeLists.txt

http://commits.kde.org/simon/9f5237b638ddabee96cb452ca442b26690a2d3b2

diff --git a/plugins/Commands/ATSPI/CMakeLists.txt \
b/plugins/Commands/ATSPI/CMakeLists.txt index 3d32043..103d5a4 100644
--- a/plugins/Commands/ATSPI/CMakeLists.txt
+++ b/plugins/Commands/ATSPI/CMakeLists.txt
@@ -1,7 +1,7 @@
 include_directories(${QACCESSIBILITYCLIENT_INCLUDE_DIR})
 
-set(simonatspicommandplugin_SRCS 
-  atspicommandmanager.cpp 
+set(simonatspicommandplugin_SRCS
+  atspicommandmanager.cpp
   atspiconfiguration.cpp
   atspiscanner.cpp
 )
@@ -10,8 +10,10 @@ kde4_add_ui_files(simonatspicommandplugin_SRCS  \
atspiconfigurationdlg.ui)  
 kde4_add_plugin(simonatspicommandplugin ${simonatspicommandplugin_SRCS})
 
-target_link_libraries(simonatspicommandplugin ${KDE4_KDEUI_LIBS} \
${QT_QTXML_LIBRARY}  +target_link_libraries(simonatspicommandplugin \
${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY}  ${QACCESSIBILITYCLIENT_LIBRARY} \
simonscenarios simonactions)  
 install(TARGETS simonatspicommandplugin DESTINATION ${PLUGIN_INSTALL_DIR} \
COMPONENT simoncommandatspiplugin)  install(FILES \
simonatspicommandplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR} \
COMPONENT simoncommandatspiplugin) +
+add_subdirectory(test)
\ No newline at end of file
diff --git a/plugins/Commands/ATSPI/atspiscanner.cpp \
b/plugins/Commands/ATSPI/atspiscanner.cpp index 81726d1..557ea60 100644
--- a/plugins/Commands/ATSPI/atspiscanner.cpp
+++ b/plugins/Commands/ATSPI/atspiscanner.cpp
@@ -22,7 +22,7 @@
 #include <QMutexLocker>
 #include <KDebug>
 
-ATSPIScanner::ATSPIScanner() : m_abort(false), 
+ATSPIScanner::ATSPIScanner() : m_abort(false),
   m_thread(new QThread()), m_registry(0), \
m_cleanStringRegExp(QRegExp("[^\\w ]"))  {
   moveToThread(m_thread);
@@ -41,6 +41,10 @@ void ATSPIScanner::initialize()
   connect(m_registry, \
SIGNAL(accessibleNameChanged(QAccessibleClient::AccessibleObject)), this, \
SLOT(nameChanged(QAccessibleClient::AccessibleObject)));  \
connect(m_registry, SIGNAL(accessibleDescriptionChanged(QAccessibleClient::AccessibleObject)), \
this, SLOT(descriptionChanged(QAccessibleClient::AccessibleObject)));  
+  connect(m_registry, \
SIGNAL(childAdded(QAccessibleClient::AccessibleObject, int)), this, \
SLOT(childAdded(QAccessibleClient::AccessibleObject, int))); +  \
connect(m_registry, SIGNAL(childRemoved(QAccessibleClient::AccessibleObject, \
int)), this, SLOT(childRemoved(QAccessibleClient::AccessibleObject, int))); \
+  connect(m_registry, SIGNAL(added(QAccessibleClient::AccessibleObject)), \
this, SLOT(added(QAccessibleClient::AccessibleObject))); +
   m_registry->subscribeEventListeners(QAccessibleClient::Registry::AllEventListeners);
  }
 
@@ -76,6 +80,8 @@ QVector<QSharedPointer<QAction> > \
ATSPIScanner::getActions(const QString& trigge  
 void ATSPIScanner::processTree(const QAccessibleClient::AccessibleObject \
&object, bool added, bool reset)  {
+  kDebug() << "Entering processTree" << object << added << reset;
+  qDebug() << "Entering processTree" << object << "added=" << added << \
"reset=" << reset;  QStringList alreadyParsed;
   QList<QAccessibleClient::AccessibleObject> objectsToParse;
   objectsToParse.append(object);
@@ -83,34 +89,43 @@ void ATSPIScanner::processTree(const \
QAccessibleClient::AccessibleObject &object  // in case this is called from \
a recently hidden object, this objects visibility will be false  // but we \
still want to remove all visible children from the AT model. So force \
re-evaluation  // of the objects children
-  objectsToParse.append(object.children());
-  
+  if (reset || !m_reverseActions.contains(object)) {
+    objectsToParse.append(object.children()); //poll from dbus
+  } else {
+    qDebug() << "Pulling direct children from cache...";
+    objectsToParse.append(m_reverseActions.value(object).second);
+  }
+
   while (!objectsToParse.isEmpty()) {
     const QAccessibleClient::AccessibleObject& o  = \
                objectsToParse.takeFirst();
-    kDebug() << "Object " << o.name() << " is visible: " << o.isVisible() \
<< " id: " << o.id(); +    //kDebug() << "Object " << o.name() << " is \
visible: " << o.isVisible() << " id: " << o.id(); +    qDebug() << "Object \
" << o.name() << " is visible: " << o.isVisible() << " id: " << o.id() << " \
role: " << o.roleName();  
     if (alreadyParsed.contains(o.id()))
       continue;
+    alreadyParsed << o.id();
 
-    QString cleanName = cleanString(o.name());
-    if (!added && !o.isVisible()) {
-      m_modelMutex.lock();
-      removeAction(cleanName, o);
-      m_reverseActions.remove(o);
-      m_modelMutex.unlock();
-    }
-
-    if (!o.isVisible()) {
-      alreadyParsed << o.id();
+    if (added && !o.isVisible())
       continue;
+
+    QList<QAccessibleClient::AccessibleObject> children;
+    if (reset || !m_reverseActions.contains(o)) {
+      children = o.children(); //poll from dbus
+    } else {
+      qDebug() << "Pulling children from cache";
+      children = m_reverseActions.value(o).second;
     }
-    
-    if (!cleanName.isEmpty()) {
-      if (!o.actions().isEmpty()) {
+    qDebug() << children.count() << " children";
+
+    QString cleanName;
+    if (added) {
+      cleanName = cleanString(o.name());
+      if (!cleanName.isEmpty() && !o.actions().isEmpty()) {
         kDebug() << "========== Triggerable: " << cleanName;
 
         m_modelMutex.lock();
         if (m_abort) {
+	  qDebug() << "Aborting";
           m_modelMutex.unlock();
           return;
         }
@@ -118,36 +133,51 @@ void ATSPIScanner::processTree(const \
QAccessibleClient::AccessibleObject &object  if \
(!m_reverseActions.contains(o)) {  kDebug() << "Tracking: " << cleanName << \
o.id();  m_actions.insertMulti(cleanName, o);
-            m_reverseActions.insert(o, cleanName);
+            m_reverseActions.insert(o, qMakePair(cleanName, children));
           }
-        } else {
-          removeAction(cleanName, o);
-          m_reverseActions.remove(o);
         }
         m_modelMutex.unlock();
       }
+    } else {
+      qDebug() << "Removing " << cleanName << o.isValid();
+      m_modelMutex.lock();
+      if (m_reverseActions.contains(o)) {
+	//get cleanName from cache
+        cleanName = m_reverseActions.value(o).first;
+        removeAction(cleanName, o);
+        m_reverseActions.remove(o);
+      }
+      m_modelMutex.unlock();
     }
-    alreadyParsed << o.id();
+
     //add children to the list to parse
-    objectsToParse.append(o.children());
+    objectsToParse.append(children);
   }
 
   QMutexLocker l(&m_modelMutex);
+  qDebug() << "processTree(): Emitting commandsShown()" << \
m_actions.keys();  kDebug() << "Emitting commands shown" << \
m_actions.keys();  emit commandsShown(m_actions.keys(), reset);
 }
 
 void ATSPIScanner::windowActivated(const \
QAccessibleClient::AccessibleObject& object)  {
+  qDebug() << "Window activated: " << object.name() << \
object.childCount();  clearATModel();
   kDebug() << "Window activated: " << object.name() << \
                object.childCount();
-  
+
   // parse all children of this object
   processTree(object, true /* added */, true);
 }
 
+void ATSPIScanner::added(const QAccessibleClient::AccessibleObject \
&object) +{
+  kDebug() << "Object added: " << object.id() << object.roleName();
+}
+
 void ATSPIScanner::stateChanged (const QAccessibleClient::AccessibleObject \
&object, const QString& state, bool active)  {
+  qDebug() << "State changed: " << object.id() << object.roleName() << \
state << active;  kDebug() << "State changed: " << object.id() << state << \
active;  if (state != "showing")
     return;
@@ -156,6 +186,7 @@ void ATSPIScanner::stateChanged (const \
QAccessibleClient::AccessibleObject &obje  m_modelMutex.lock();
     if (!m_reverseActions.contains(object)) {
       kDebug() << "Untracked object changed: " << object.name() << \
object.id(); +      qDebug() << "Untracked object changed: " << \
object.name() << object.id();  m_modelMutex.unlock();
       return;
     }
@@ -186,33 +217,38 @@ void ATSPIScanner::removeAction(const QString& name, \
const QAccessibleClient::Ac  
 void ATSPIScanner::nameChanged(const QAccessibleClient::AccessibleObject& \
object)  {
+  qDebug() << "nameChanged()";
   QMutexLocker l(&m_modelMutex);
   if (!m_reverseActions.contains(object)) {
-    kDebug() << "Untracked object changed its name: " << object.name() << \
object.id(); +    //kDebug() << "Untracked object changed its name: " << \
object.name() << object.id(); +    qDebug() << "Untracked object changed \
its name: " << object.name() << object.id();  return;
   }
 
   QString cleanName = cleanString(object.name());
-  kDebug() << "Name changed: " << cleanName;
-
-  QStringList toAdd;
-  QStringList toRemove;
+  qDebug() << "Name changed: " << cleanName;
+  //kDebug() << "Name changed: " << cleanName;
 
-  QString oldName = m_reverseActions.value(object);
-  m_reverseActions.insert(object, cleanName); // replace
-
-  if (!m_actions.contains(cleanName))
-    toAdd << cleanName;
+  QPair<QString, QList<QAccessibleClient::AccessibleObject> > oldValue = \
m_reverseActions.value(object); +  m_reverseActions.insert(object, \
qMakePair(cleanName, oldValue.second)); // replace  
+  QString oldName = oldValue.first;
   removeAction(oldName, object);
   m_actions.insert(cleanName, object);
-  kDebug() << oldName << m_actions.keys();
-  if (!m_actions.keys().contains(oldName))
-    toRemove << oldName;
 
+  qDebug() << "nameChanged(): " << cleanName << " Emitting \
commandsShown()" << m_actions.keys();  emit commandsShown(m_actions.keys(), \
false);  }
 
+void ATSPIScanner::childAdded(const QAccessibleClient::AccessibleObject \
&parent, int index) +{
+  qDebug() << "Child added to " << parent.name();
+}
+void ATSPIScanner::childRemoved(const QAccessibleClient::AccessibleObject \
&parent, int index) +{
+  qDebug() << "Child removed from " << parent.name();
+}
+
 inline QString ATSPIScanner::cleanString(const QString& input)
 {
   QString out = input;
diff --git a/plugins/Commands/ATSPI/atspiscanner.h \
b/plugins/Commands/ATSPI/atspiscanner.h index 00f9a22..b135d56 100644
--- a/plugins/Commands/ATSPI/atspiscanner.h
+++ b/plugins/Commands/ATSPI/atspiscanner.h
@@ -35,12 +35,12 @@ class ATSPIScanner : public QObject
 Q_OBJECT
 
 signals:
-  void commandsShown(const QStringList& commands, bool reset);
+  void commandsShown(QStringList commands, bool reset);
 
 public:
   ATSPIScanner();
   ~ATSPIScanner();
-  
+
   void clearATModel();
   QVector<QSharedPointer<QAction> > getActions(const QString& \
triggerName);  
@@ -50,6 +50,10 @@ private slots:
   void descriptionChanged (const QAccessibleClient::AccessibleObject \
&object);  void stateChanged (const QAccessibleClient::AccessibleObject \
&object, const QString& state, bool active);  
+  void added(const QAccessibleClient::AccessibleObject &parent);
+  void childAdded(const QAccessibleClient::AccessibleObject &parent, int \
index); +  void childRemoved(const QAccessibleClient::AccessibleObject \
&parent, int index); +
   void initialize();
 
 private:
@@ -58,8 +62,12 @@ private:
   QThread *m_thread;
   QAccessibleClient::Registry *m_registry;
   QRegExp m_cleanStringRegExp;
-  QHash<QString /* name (trigger) */, QAccessibleClient::AccessibleObject \
                /* object id */> m_actions;
-  QHash<QAccessibleClient::AccessibleObject /* object */, QString /* name \
(trigger) */> m_reverseActions; +  QHash<QString /* name (trigger) */, \
QAccessibleClient::AccessibleObject /* object */> m_actions; +  \
QHash<QAccessibleClient::AccessibleObject /* object */, +        \
QPair<QString /* name (trigger) */, \
QList<QAccessibleClient::AccessibleObject> /* children */> > \
m_reverseActions; +
+  //Additionally, store the original object hierarchy to avoid querying it \
on every update +
 
   void processTree(const QAccessibleClient::AccessibleObject &object, bool \
added, bool reset);  void removeAction(const QString& name, const \
                QAccessibleClient::AccessibleObject& o);
diff --git a/plugins/Commands/ATSPI/test/CMakeLists.txt \
b/plugins/Commands/ATSPI/test/CMakeLists.txt new file mode 100644
index 0000000..2645438
--- /dev/null
+++ b/plugins/Commands/ATSPI/test/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(../)
+add_definitions(-DQT_GUI_LIB)
+set (simonatspiscannertest_SRC
+  atspiscannertest.cpp
+  accessibleapp.cpp
+  accessibleapp.h
+
+  #deps
+  ../atspiscanner.cpp
+)
+
+kde4_add_unit_test(simonatspicommandplugin-scanner TESTNAME
+  simonatspicommandplugin-scanner
+  ${simonatspiscannertest_SRC}
+)
+
+
+target_link_libraries( simonatspicommandplugin-scanner
+  ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY}
+  ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY}
+  ${QACCESSIBILITYCLIENT_LIBRARY} simonscenarios simonactions)
diff --git a/plugins/Commands/ATSPI/test/accessibleapp.cpp \
b/plugins/Commands/ATSPI/test/accessibleapp.cpp new file mode 100644
index 0000000..ec00a14
--- /dev/null
+++ b/plugins/Commands/ATSPI/test/accessibleapp.cpp
@@ -0,0 +1,112 @@
+/*
+ *   Copyright (C) 2013 Peter Grasch <peter.grasch@bedahr.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details
+ *
+ *   You should have received a copy of the GNU General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "accessibleapp.h"
+#include <QWidget>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QMenu>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMenuBar>
+#include <QDebug>
+
+AccessibleApp::AccessibleApp() : btn(0), msg(0)
+{
+  show();
+  menuBar();
+}
+
+void AccessibleApp::setUI(QWidget* w)
+{
+  QWidget *central = centralWidget();
+  setCentralWidget(w);
+  delete central;
+}
+
+void AccessibleApp::setupSingleButton()
+{
+  QWidget *newConfiguration(new QWidget(this));
+  QVBoxLayout lay(newConfiguration);
+  btn = new QPushButton("Testbutton", newConfiguration);
+  lay.addWidget(btn);
+
+  setUI(newConfiguration);
+}
+
+void AccessibleApp::clear()
+{
+  setUI(new QWidget(this));
+  menuBar()->clear();
+  delete msg;
+  msg = 0;
+}
+
+
+void AccessibleApp::changeButtonText()
+{
+  btn->setText("Alternate Button");
+}
+void AccessibleApp::hideButton()
+{
+  btn->hide();
+}
+void AccessibleApp::showButton()
+{
+  btn->show();
+}
+
+void AccessibleApp::setupMenu()
+{
+  QMenu *fileMenu = new QMenu("File", this);
+  fileMenu->addAction("Save");
+  fileMenu->addAction("Quit");
+  menuBar()->addMenu(fileMenu);
+  QMenu *settingsMenu = new QMenu("Settings", this);
+  settingsMenu->addAction("Configure Demo...");
+  menuBar()->addMenu(settingsMenu);
+}
+
+void AccessibleApp::setupBuddy()
+{
+  QWidget *newConfiguration(new QWidget(this));
+  QVBoxLayout lay(newConfiguration);
+  QLabel *l = new QLabel("Buddy:", this);
+  QLineEdit *le = new QLineEdit(this);
+  l->setBuddy(le);
+  lay.addWidget(l);
+  lay.addWidget(le);
+
+  setUI(newConfiguration);
+}
+
+void AccessibleApp::setupDialog()
+{
+  msg = new QMessageBox(QMessageBox::NoIcon, "Title", "Text", \
QMessageBox::NoButton, this); +  msg->addButton(new QPushButton("Ok", msg), \
QMessageBox::AcceptRole); +  msg->show();
+}
+
+void AccessibleApp::acceptDialog()
+{
+  msg->accept();
+}
+
+
diff --git a/plugins/Commands/ATSPI/test/accessibleapp.h \
b/plugins/Commands/ATSPI/test/accessibleapp.h new file mode 100644
index 0000000..49e5ad6
--- /dev/null
+++ b/plugins/Commands/ATSPI/test/accessibleapp.h
@@ -0,0 +1,49 @@
+/*
+ *   Copyright (C) 2013 Peter Grasch <peter.grasch@bedahr.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details
+ *
+ *   You should have received a copy of the GNU General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef SIMON_ACCESSIBLEAPP_H_7A7B9100FF5245329569C1B540119C37
+#define SIMON_ACCESSIBLEAPP_H_7A7B9100FF5245329569C1B540119C37
+
+#include <QMainWindow>
+
+class QPushButton;
+class QMessageBox;
+
+class AccessibleApp : public QMainWindow
+{
+  Q_OBJECT
+public:
+  AccessibleApp();
+  void setupSingleButton();
+  void changeButtonText();
+  void showButton();
+  void hideButton();
+  void setupMenu();
+  void setupBuddy();
+  void setupDialog();
+  void acceptDialog();
+  void clear();
+
+private:
+  QPushButton *btn;
+  QMessageBox *msg;
+  void setUI(QWidget *w);
+};
+
+#endif
diff --git a/plugins/Commands/ATSPI/test/atspiscannertest.cpp \
b/plugins/Commands/ATSPI/test/atspiscannertest.cpp new file mode 100644
index 0000000..5854ee8
--- /dev/null
+++ b/plugins/Commands/ATSPI/test/atspiscannertest.cpp
@@ -0,0 +1,163 @@
+/*
+ *   Copyright (C) 2013 Peter Grasch <peter.grasch@bedahr.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details
+ *
+ *   You should have received a copy of the GNU General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QVariant>
+#include <QWidget>
+#include <KApplication>
+#include <KCmdLineArgs>
+#include <QSignalSpy>
+#include <QDebug>
+#include "../atspiscanner.h"
+#include "accessibleapp.h"
+#include <qt4/QtCore/QTimer>
+
+
+class testATSPIScanner: public QObject
+{
+  Q_OBJECT
+private slots:
+  void initTestCase();
+  void testGeneral();
+  void testMenu();
+  void testBuddy();
+  void testDialog();
+  void cleanupTestCase();
+
+private:
+  ATSPIScanner *scanner;
+  AccessibleApp *app;
+  QSignalSpy *spy;
+
+  static const int maxWaitIterations = 1000;
+  static const int waitIterationDuration = 100;
+
+  QStringList currentCommands();
+  void blockingInvoke(void (AccessibleApp::*func)(), int minEvents = 1);
+};
+
+void testATSPIScanner::initTestCase()
+{
+  scanner = new ATSPIScanner;
+  app = new AccessibleApp;
+  spy = new QSignalSpy(scanner, SIGNAL(commandsShown(QStringList, bool)));
+  QVERIFY(spy->isValid());
+
+  QTimer::singleShot(waitIterationDuration, qApp, SLOT(quit()));
+  qApp->exec();
+}
+
+void testATSPIScanner::cleanupTestCase()
+{
+  delete scanner;
+  delete app;
+  delete spy;
+}
+
+QStringList testATSPIScanner::currentCommands()
+{
+  QStringList c;
+  while (!spy->isEmpty()) {
+    QList<QVariant> reply = spy->takeFirst();
+    Q_ASSERT(reply.count() == 2);
+    if (reply.last().toBool() /* reset */)
+      c.clear();
+    foreach (const QString& command, reply.first().toStringList())
+      if (!c.contains(command))
+        c.append(command);
+  }
+  qSort(c);
+  qDebug() << "Current commands: " << c;
+  return c;
+}
+
+void testATSPIScanner::blockingInvoke(void (AccessibleApp::*func)(), int \
minEvents) +{
+  spy->clear();
+  (app->*func)();
+  for (int i = 0; (i < maxWaitIterations) && (spy->count() < minEvents); \
++i) { +    QTimer::singleShot(waitIterationDuration, qApp, SLOT(quit()));
+    qApp->exec();
+  }
+}
+
+void testATSPIScanner::testGeneral()
+{
+  blockingInvoke(&AccessibleApp::setupSingleButton, 1);
+  QCOMPARE(currentCommands(), QStringList() << \
QLatin1String("Testbutton")); +  \
blockingInvoke(&AccessibleApp::changeButtonText, 1); +  \
QCOMPARE(currentCommands(), QStringList() << QLatin1String("Alternate \
Button")); +  blockingInvoke(&AccessibleApp::hideButton, 1);
+  QCOMPARE(currentCommands(), QStringList());
+  blockingInvoke(&AccessibleApp::showButton, 1);
+  QCOMPARE(currentCommands(), QStringList() << QLatin1String("Alternate \
Button")); +
+  blockingInvoke(&AccessibleApp::clear, 1);
+  QCOMPARE(currentCommands(), QStringList());
+}
+
+
+void testATSPIScanner::testMenu()
+{
+  //qDebug() << "========================";
+  blockingInvoke(&AccessibleApp::setupMenu, 1);
+
+  QEXPECT_FAIL("", "Bug # 314464", Continue);
+  QCOMPARE(currentCommands(), QStringList() << QLatin1String("File") << \
QLatin1String("Settings")); +
+  //qDebug() << "========================";
+  blockingInvoke(&AccessibleApp::clear, 1);
+  QCOMPARE(currentCommands(), QStringList());
+
+}
+
+void testATSPIScanner::testBuddy()
+{
+  blockingInvoke(&AccessibleApp::setupBuddy, 1);
+  QCOMPARE(currentCommands(), QStringList() << QLatin1String("Buddy"));
+
+  blockingInvoke(&AccessibleApp::clear, 1);
+  QCOMPARE(currentCommands(), QStringList());
+}
+
+void testATSPIScanner::testDialog()
+{
+  blockingInvoke(&AccessibleApp::setupDialog, 1);
+  QCOMPARE(currentCommands(), QStringList() << QLatin1String("Ok") << \
QLatin1String("Text")); +
+  blockingInvoke(&AccessibleApp::clear, 1);
+  QCOMPARE(currentCommands(), QStringList());
+
+  blockingInvoke(&AccessibleApp::setupSingleButton, 1);
+  QCOMPARE(currentCommands(), QStringList() << \
QLatin1String("Testbutton")); +  \
blockingInvoke(&AccessibleApp::setupDialog, 1); +  \
QCOMPARE(currentCommands(), QStringList() << QLatin1String("Ok") << \
QLatin1String("Text")); +  blockingInvoke(&AccessibleApp::acceptDialog, 1);
+  QCOMPARE(currentCommands(), QStringList() << \
QLatin1String("Testbutton")); +
+  blockingInvoke(&AccessibleApp::clear, 1);
+  QCOMPARE(currentCommands(), QStringList());
+}
+
+QTEST_MAIN(testATSPIScanner)
+
+#include "atspiscannertest.moc"
+
+
diff --git a/plugins/Commands/CMakeLists.txt \
b/plugins/Commands/CMakeLists.txt index a752733..2f5b435 100644
--- a/plugins/Commands/CMakeLists.txt
+++ b/plugins/Commands/CMakeLists.txt
@@ -5,7 +5,7 @@ if (KDEPIMLIBS_FOUND)
 endif (KDEPIMLIBS_FOUND)
 
 if(QAccessibilityClient_FOUND)
-#  add_subdirectory(ATSPI)
+add_subdirectory(ATSPI)
 endif(QAccessibilityClient_FOUND)
 
 add_subdirectory(Calculator)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic