[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