camerauis/cameraxui/cxengine/tsrc/unit/utils/cxetestutils.h
branchRCL_3
changeset 24 bac7acad7cb3
parent 23 61bc0f252b2b
child 25 2c87b2808fd7
equal deleted inserted replaced
23:61bc0f252b2b 24:bac7acad7cb3
     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