summaryrefslogtreecommitdiff
path: root/src/qttestrunner/TestRunnerModel.h
blob: ebd3a57d2c1a7f8f9888a03fda567a988d49108d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// //////////////////////////////////////////////////////////////////////////
// Header file TestRunnerModel.h for class TestRunnerModel
// (c)Copyright 2000, Baptiste Lepilleur.
// Created: 2001/09/20
// //////////////////////////////////////////////////////////////////////////
#ifndef TESTRUNNERMODEL_H
#define TESTRUNNERMODEL_H

#include <cppunit/Test.h>
#include <cppunit/TestListener.h>
#include <qptrlist.h>
#include <qobject.h>
#include <qthread.h>
#include "TestFailureInfo.h"
#include "TestRunnerModelThreadInterface.h"
class TestRunnerThread;

/*! \class TestRunnerModel
 * \brief This class represents the model for the TestRunner.
 *
 * Warning: methods that override CppUnit::TestListener are called
 * from the TestRunner thread !
 *
 * Warning: _lock is not recursive. Might want to introduce Doug Lea
 * Thread Interface pattern for methods used while locked (isTestRunning()).
 *
 * Refactoring note: a large part of this object actually duplicate
 * TestResult. 
 */
class TestRunnerModel : public QObject,
                        private CPPUNIT_NS::TestListener,
                        private TestRunnerModelThreadInterface
{
  Q_OBJECT
public:
  /*! Constructs a TestRunnerModel object.
   */
  TestRunnerModel( CPPUNIT_NS::Test *rootTest );

  /*! Destructor.
   */
  virtual ~TestRunnerModel();

  CPPUNIT_NS::Test *rootTest();

  int numberOfTestCase();
  int numberOfTestCaseFailure();
  int numberOfTestCaseRun();

  TestFailureInfo *failureAt( int index );


  bool isTestRunning();

signals:
  void numberOfTestCaseChanged( int numberOfTestCase );
  void numberOfTestCaseRunChanged( int numberOfRun );
  void numberOfTestCaseFailureChanged( int numberOfFailure );
  void failureAdded( TestFailureInfo *failure );
  void failuresCleared();
  void testRunStarted( CPPUNIT_NS::Test *runningTest,
                       CPPUNIT_NS::TestResult *result );
  void testRunFinished();

public slots:
  void resetTestReportCounterFor( CPPUNIT_NS::Test *testToRun );

  /*! Request to run the specified test.
   * Returns immedialty. If a test is already running, then
   * the run request is ignored.
   */
  void runTest( CPPUNIT_NS::Test *testToRun );

  /*! Request to stop running test.
   * This methods returns immediately. testRunFinished() signal
   * should be used to now when the test actually stopped running.
   */
  void stopRunningTest();

private:
  /// Prevents the use of the copy constructor.
  TestRunnerModel( const TestRunnerModel &copy );

  /// Prevents the use of the copy operator.
  void operator =( const TestRunnerModel &copy );

  /// Called from the TestRunnerThread.
  void startTest( CPPUNIT_NS::Test *test );

  /// Called from the TestRunnerThread.
  void addFailure( const CPPUNIT_NS::TestFailure &failure );
  
  /// Called from the TestRunnerThread.
  void endTest( CPPUNIT_NS::Test *test );

  /// Called from the TestRunnerThread.
  void addFailureInfo( TestFailureInfo *failure );

  bool event( QEvent *event );

  /*! Emits new failure signals.
   * Called by the TestRunnerThreadEvent from the GUI thread to
   * emit the following signals:
   * - numberOfTestCaseFailureChanged()
   * - failureAdded()
   */
  void eventNewFailure( TestFailureInfo *failure,
                        int numberOfFailure );

  /*! Emits numberOfTestCaseRunChanged() signal.
   * Called by the TestRunnerThreadEvent from the GUI thread to
   * emit the numberOfTestCaseRunChanged() signal.
   */
  void eventNumberOfTestRunChanged( int numberOfRun );

  void eventTestRunnerThreadFinished();

private:
  class LockGuard
  {
  public:
    LockGuard( QMutex &mutex ) : _mutex( mutex )
    {
      _mutex.lock();
    }

    ~LockGuard()
    {
      _mutex.unlock();
    }

  private:
    QMutex &_mutex;
  };


  QMutex _lock;
  CPPUNIT_NS::Test *_rootTest;
  int _numberOfTestCase;
  int _numberOfTestCaseRun;
  int _numberOfTestCaseFailure;
  QList<TestFailureInfo> _failures;
  TestRunnerThread *_runnerThread;
  CPPUNIT_NS::TestResult *_result;
};



// Inlines methods for TestRunnerModel:
// ------------------------------------



#endif  // TESTRUNNERMODEL_H