Tuesday, August 31, 2010

Testing Qt slots and signals

Testing slots

Testing slots is very easy, because a slot is just a specially annotated method. You can call slots just like any other method you'd like to test, as shown below:
Example 25. QLabel test code, showing testing of a couple of slots
  1. #include
  2. #include
  3. #include
  4.  
  5. class testLabel: public QObject
  6. {
  7. Q_OBJECT
  8. private slots:
  9. void testChanges();
  10. };
  11.  
  12. void testLabel::testChanges()
  13. {
  14. QLabel label;
  15.  
  16. // setNum() is a QLabel slot, but we can just call it like any
  17. // other method.
  18. label.setNum( 3 );
  19. QCOMPARE( label.text(), QString("3") );
  20.  
  21. // clear() is also a slot.
  22. label.clear();
  23. QVERIFY( label.text().isEmpty() );
  24. }
  25.  
  26. QTEST_MAIN(testLabel)
  27. #include "tutorial5.moc"

Testing signals

Testing of signals is a little more difficult than testing of slots, however Qt offers a very useful class called QSignalSpy that helps a lot.
QSignalSpy is a class provided with Qt that allows you to record the signals that have been emitted from a particular QObject subclass object. You can then check that the right number of signals have been emitted, and that the right kind of signals were emitted. You can find more information on the QSignalSpy class in your Qt documentation.
An example of how you can use QSignalSpy to test a class that has signals is shown below.
Example 26. QCheckBox test code, showing testing of signals
  1. #include
  2. #include
  3. #include
  4.  
  5. class testCheckBox: public QObject
  6. {
  7. Q_OBJECT
  8. private slots:
  9. void testSignals();
  10. };
  11.  
  12. void testCheckBox::testSignals()
  13. {
  14. // You don't need to use an object created with "new" for
  15. // QSignalSpy, I just needed it in this case to test the emission
  16. // of a destroyed() signal.
  17. QCheckBox *xbox = new QCheckBox;
  18.  
  19. // We are going to have two signal monitoring classes in use for
  20. // this test.
  21. // The first monitors the stateChanged() signal.
  22. // Also note that QSignalSpy takes a pointer to the object.
  23. QSignalSpy stateSpy( xbox, SIGNAL( stateChanged(int) ) );
  24.  
  25. // Not strictly necessary, but I like to check that I have set up
  26. // my QSignalSpy correctly.
  27. QVERIFY( stateSpy.isValid() );
  28.  
  29. // Now we check to make sure we don't have any signals already
  30. QCOMPARE( stateSpy.count(), 0 );
  31.  
  32. // Here is a second monitoring class - this one for the
  33. // destroyed() signal.
  34. QSignalSpy destroyedSpy( xbox, SIGNAL( destroyed() ) );
  35. QVERIFY( destroyedSpy.isValid() );
  36.  
  37. // A sanity check to verify the initial state
  38. // This also shows that you can mix normal method checks with
  39. // signal checks.
  40. QCOMPARE( xbox->checkState(), Qt::Unchecked );
  41.  
  42. // Shouldn't already have any signals
  43. QCOMPARE( destroyedSpy.count(), 0 );
  44.  
  45. // If we change the state, we should get a signal.
  46. xbox->setCheckState( Qt::Checked );
  47. QCOMPARE( stateSpy.count(), 1 );
  48.  
  49. xbox->setCheckState( Qt::Unchecked );
  50. QCOMPARE( stateSpy.count(), 2 );
  51.  
  52. xbox->setCheckState( Qt::PartiallyChecked );
  53. QCOMPARE( stateSpy.count(), 3 );
  54.  
  55. // If we destroy the object, the signal should be emitted.
  56. delete xbox;
  57.  
  58. // So the count of objects should increase.
  59. QCOMPARE( destroyedSpy.count(), 1 );
  60.  
  61. // We can also review the signals that we collected
  62. // QSignalSpy is really a QList of QLists, so we take the first
  63. // list, which corresponds to the arguments for the first signal
  64. // we caught.
  65. QList<QVariant> firstSignalArgs = stateSpy.takeFirst();
  66. // stateChanged() only has one argument - an enumerated type (int)
  67. // So we take that argument from the list, and turn it into an integer.
  68. int firstSignalState = firstSignalArgs.at(0).toInt();
  69. // We can then check we got the right kind of signal.
  70. QCOMPARE( firstSignalState, static_cast<int>(Qt::Checked) );
  71.  
  72. // check the next signal - note that takeFirst() removes from the list
  73. QList<QVariant> nextSignalArgs = stateSpy.takeFirst();
  74. // this shows another way of fudging the argument types
  75. Qt::CheckState nextSignalState = (Qt::CheckState)nextSignalArgs.at(0).toInt();
  76. QCOMPARE( nextSignalState, Qt::Unchecked );
  77.  
  78. // and again for the third signal
  79. nextSignalArgs = stateSpy.takeFirst();
  80. nextSignalState = (Qt::CheckState)nextSignalArgs.at(0).toInt();
  81. QCOMPARE( nextSignalState, Qt::PartiallyChecked );
  82. }
  83.  
  84. QTEST_MAIN(testCheckBox)
  85. #include "tutorial5a.moc"
The first 11 lines are essentially unchanged from previous examples that we've seen. Line 15 creates the object that will be tested - as noted in the comments in lines 12-14, the only reason that I'm creating it with new is because I need to delete it in line 45 to cause the destroyed() signal to be emitted.
Line 20 sets up the first of our two QSignalSpy instances. The one in line 20 monitors the stateChanged(int) signal, and the one in line 29 monitors the destroyed() signal. If you get the name or signature of the signal wrong (for example, if you use stateChanged() instead of stateChanged(int)), then this will not be caught at compile time, but will result in a runtime failure. You can test if things were set up correctly using the isValid(), as shown in lines 24 and 30.
As shown in line 34, there is no reason why you cannot test normal methods, signals and slots in the same test.
Line 38 changes the state of the object under test, which is supposed to result in a stateChanged(int) signal being emitted. Line 39 checks that the number of signals increases from zero to one. Lines 40 and 41 repeat the process, and again in lines 42 and 43.
Line 45 deletes the object under test, and line 47 tests that the destroyed() signal has been emitted.
For signals that have arguments (such as our stateChanged(int) signal), you may also wish to check that the arguments were correct. You can do this by looking at the list of signal arguments. Exactly how you do this is fairly flexible, however for simple tests like the one in the example, you can manually work through the list using takeFirst() and check that each argument is correct. This is shown in line 52, 55 and 57 for the first signal. The same approach is shown in lines 59, 61 and 62 for the second signal, and the in lines 64 to 66 for the third signal. For a more complex set of tests, you may wish to apply some data driven techniques.

Dica
noframe
Note: You should be aware that, for some class implementations, you may need to return control to the event loop to have signals emitted. If you need this, try using the QTest::qWait() function.

Thursday, August 19, 2010

General questions

How do I open a .chm file?in Ubuntu or linux??

sudo apt-get install  gnochm

sudo apt-get install kchmviewer

sudo aptitude install chm2pdf

Tuesday, August 17, 2010

MeeGo Dictionary

Maemo - a software platform developed by Nokia forsmartphones and Internet Tablets. It was initially based on theDebian Linux distribution. One of the predecessors of MeeGo, along with Moblin.

Maemo 5 - the default operating system on the Nokia N900, and current latest stable and independent version of Maemo. Based on the GTK toolkit. Aliases: Fremantle


MeeGo - an open source, Linux project which brings together the Moblin project, headed up by Intel, and Maemo, by Nokia, into a single open source activity. Managed by the Linux Foundation. The important thing to note that you end users will mostly be using an edition of MeeGo, MeeGo itself is not a single product (that’s why "will X run/get MeeGo" is a bad question), just like people are using a Linux distributions, not Linux (as in kernel) alone. 


MADDE - Maemo(/MeeGo) Application Development andDebugging Environment,
 offers the following features:

  • Command-line cross-compiling
  • Multi-platform support (Linux (32-bit/64-bit), Windows, Mac OS X)
  • Configurable for different targets & toolchains
  • Client for the device to simplify the development process
  • Will be used as part of future releases of the MeeGo SDK, along with QEMU, to enable cross-OS development.
MeegGo Handheld - MeeGo Core + MeeGo Touch Framework + Reference Handheld UX (not yet released).


MeeGo-Harmattan - the default operating system of the Nokia N9. Successor of Maemo 5, but based of the Qt toolkit. Originally named Maemo 6, but later rebranded as MeeGo-Harmattan (provisional name). It is MeeGo compatible (that is, has a MeeGo API) but is not to be confused with MeeGo 1.0 Handheld (as it is NOT based on MeeGo Core). MeeGo-Harmattan will not be released as a Nokia product for the N900. Aliases: Harmattan, Maemo 6.

MeeGo Touch Framework (MTF) - provides the features needed for developers creating applications for touch-enabled devices. Features include standardized window navigation, list and other widget behavior, and common theming for components.

MeeGo Web RunTime - Web Runtime (WRT) allows web developers to use standard web languages — HTML, CSS, and JavaScript — to create applications for mobile devices. WRT exposes the features of the underlying platform so that applications can interact with device data and combine location-based context with web information

Moblin - short for 'mobile Linux', is an open source operating system and application stack for Mobile Internet Devices (MIDs),netbooksnettops and embedded devices. One of the predecessors of MeeGo, along with Maemo.

QML - a Declarative UI tool, in effect a markup language that defines UI elements and their behavior in a declarative manner, allowing, snappy, whizzy UIs. Present in Qt4.7+

Qt Quick - the Qt User Interface Creation Kit, which consists of QML, a specialized editor in QtCreator and all-around support for the declarative approach. Present in Qt4.7+. Aliases: Qt Declarative, Declarative UI, Bauhaus.


QtMobility - extends Qt with libraries providing additional features for applications targeting mobile platforms. These include the Service Framework and Contact and Bearer Management APIs, Messaging, Sensors, Camera, etc


UI Extensions for Mobile - an extension library for  Qt, which contains more than 50 UI elements tailored for mobile user experience. There is a proposal to use Orbit and Qt together withDirect UI as a replacement for the existing S60 'Avkon' set of UI elements in Symbian^4, but has been demonstrated to work on Maemo, too. It was previous known as Orbit before getting renamed to UI Extensions for Mobile (uiemo) and open sourced. Aliases: Uiemo, Orbit