1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef CXETESTUTILS_H |
|
19 #define CXETESTUTILS_H |
|
20 |
|
21 #include <QSignalSpy> |
|
22 #include "cxutils.h" |
|
23 |
|
24 const int CXE_TEST_POLL_TIME = 10; |
|
25 |
|
26 class CxeTestUtils |
|
27 { |
|
28 public: |
|
29 static bool waitForSignal( |
|
30 QSignalSpy &spy, int ms, int count = 1, bool allowExtraSignals = true); |
|
31 |
|
32 template<typename T> static bool waitForState( |
|
33 T& stateMachine, typename T::State state, int ms); |
|
34 }; |
|
35 |
|
36 |
|
37 /** |
|
38 * Wait for a state machine to transition to a given state. Returns false if |
|
39 * target state is not reached withing the given timeout. |
|
40 * |
|
41 * This function expects the state machine to emit a |
|
42 * "stateChanged(T::State...)" signal. Also, the state machine class needs to |
|
43 * implement an enum called "State". Remember to use the |
|
44 * Q_DECLARE_METATYPE macro for the State enum. |
|
45 * |
|
46 * waitForState() is template based so the implementation needs to be in the |
|
47 * header file. |
|
48 * |
|
49 * @tparam T State machine type |
|
50 * @param stateMachine State machine instance |
|
51 * @param state Target state |
|
52 * @param ms Timeout in milliseconds |
|
53 * @return True if target state was reached, false if timed out |
|
54 */ |
|
55 template<typename T> bool CxeTestUtils::waitForState( |
|
56 T& stateMachine, typename T::State state, int ms) |
|
57 { |
|
58 int waitingTime = 0; |
|
59 bool stateReached = false; |
|
60 |
|
61 // Find stateChanged() signal |
|
62 QByteArray signalSignature; |
|
63 const QMetaObject *meta = stateMachine.metaObject(); |
|
64 for (int i = 0; i < meta->methodCount(); i++) { |
|
65 QMetaMethod method = meta->method(i); |
|
66 if (method.methodType() == QMetaMethod::Signal && |
|
67 QByteArray(method.signature()).startsWith("stateChanged(")) { |
|
68 signalSignature = method.signature(); |
|
69 signalSignature.prepend(QSIGNAL_CODE + '0'); |
|
70 } |
|
71 } |
|
72 |
|
73 // Listen for stateChanged signals using signal spy |
|
74 QSignalSpy spy(&stateMachine, signalSignature.constData()); |
|
75 if (!spy.isValid()) { |
|
76 CX_DEBUG(("waitForState() - unable to set up signal spy - is there a stateChanged() signal?")); |
|
77 return false; |
|
78 } |
|
79 |
|
80 // Loop for waiting for state changes. This terminates when |
|
81 // stateMachine.state() returns the target state, a stateChanged signal |
|
82 // indicates a state change to the target state, or the timeout is expired. |
|
83 while (!stateReached && waitingTime < ms) { |
|
84 QTest::qWait(CXE_TEST_POLL_TIME); |
|
85 waitingTime += CXE_TEST_POLL_TIME; |
|
86 |
|
87 // Check current state |
|
88 if (stateMachine.state() == state) { |
|
89 CX_DEBUG(("waitForState() - current state matches")); |
|
90 stateReached = true; |
|
91 } |
|
92 |
|
93 // Check state history from signal spy in case |
|
94 // there were quick successive state changes |
|
95 for (int i = 0; i < spy.count() && !stateReached; i++) { |
|
96 if (!spy[i].at(0).canConvert<T::State>()) { |
|
97 CX_DEBUG(("waitForState() - can't convert stateChanged params!")); |
|
98 CX_DEBUG(("waitForState() - signature is %s!", signalSignature.constData())); |
|
99 return false; |
|
100 } |
|
101 |
|
102 if (spy[i].at(0).value<T::State>() == state) { |
|
103 CX_DEBUG(("waitForState() - found signal spy state signal match")); |
|
104 stateReached = true; |
|
105 } |
|
106 } |
|
107 } |
|
108 |
|
109 if (stateReached) { |
|
110 CX_DEBUG(("waitForState() - got to state %d successfully", |
|
111 static_cast<int>(state))); |
|
112 } else { |
|
113 CX_DEBUG(("waitForState() - transition to state %d timed out (state is still %d), waitingTime = %d", |
|
114 static_cast<int>(state), static_cast<int>(stateMachine.state()), waitingTime)); |
|
115 } |
|
116 return stateReached; |
|
117 } |
|
118 #endif // CXETESTUTILS_H |
|