1///////////////////////////////////////////////////////////////////////////////
2// Name:        tests/scopeguard/scopeguardtest.cpp
3// Purpose:     Test wxScopeGuard and related macros
4// Author:      Vadim Zeitlin
5// RCS-ID:      $Id: scopeguardtest.cpp 34684 2005-06-16 23:47:30Z VZ $
6// Copyright:   (c) 2005 Vadim Zeitlin
7// Licence:     wxWidgets licence
8///////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18#include "testprec.h"
19
20#ifdef __BORLANDC__
21    #pragma hdrstop
22#endif
23
24#include "wx/scopeguard.h"
25
26// ----------------------------------------------------------------------------
27// helper stuff: something to do on scope exit
28// ----------------------------------------------------------------------------
29
30static int gs_count = 0;
31
32static void IncGlobal() { gs_count++; }
33static void Inc(int *n) { (*n)++; }
34static void IncBy(int *n, int m) { (*n) += m; }
35
36class Counter
37{
38public:
39    Counter(int n) : m_count(n) { }
40
41    void Zero() { m_count = 0; }
42    void Set(int n) { m_count = n; }
43    void Sum(int n, int m) { m_count = n + m; }
44
45    int GetCount() const { return m_count; }
46
47private:
48    int m_count;
49};
50
51// ----------------------------------------------------------------------------
52// test class
53// ----------------------------------------------------------------------------
54
55class ScopeGuardTestCase : public CppUnit::TestCase
56{
57public:
58    CPPUNIT_TEST_SUITE(ScopeGuardTestCase);
59        CPPUNIT_TEST(Normal);
60        CPPUNIT_TEST(Dismiss);
61        CPPUNIT_TEST(BlockExit);
62        CPPUNIT_TEST(BlockExitObj);
63    CPPUNIT_TEST_SUITE_END();
64
65    void Normal();
66    void Dismiss();
67    void BlockExit();
68    void BlockExitObj();
69};
70
71// register in the unnamed registry so that these tests are run by default
72CPPUNIT_TEST_SUITE_REGISTRATION(ScopeGuardTestCase);
73
74// also include in it's own registry so that these tests can be run alone
75CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ScopeGuardTestCase,
76                                      "ScopeGuardTestCase");
77
78// ============================================================================
79// ScopeGuardTestCase implementation
80// ============================================================================
81
82void ScopeGuardTestCase::Normal()
83{
84    int n = 1,
85        m = 2;
86
87    {
88        gs_count = 1;
89        wxScopeGuard incGlobal = wxMakeGuard(IncGlobal),
90                     incN = wxMakeGuard(Inc, &n),
91                     incMby15 = wxMakeGuard(IncBy, &m, 15);
92
93        wxUnusedVar(incGlobal);
94        wxUnusedVar(incN);
95        wxUnusedVar(incMby15);
96
97        CPPUNIT_ASSERT_EQUAL( 1, gs_count );
98        CPPUNIT_ASSERT_EQUAL( 1, n );
99        CPPUNIT_ASSERT_EQUAL( 2, m );
100    }
101
102    CPPUNIT_ASSERT_EQUAL( 2, gs_count );
103    CPPUNIT_ASSERT_EQUAL( 2, n );
104    CPPUNIT_ASSERT_EQUAL( 17, m );
105}
106
107void ScopeGuardTestCase::Dismiss()
108{
109    int n = 1,
110        m = 2;
111
112    {
113        gs_count = 1;
114        wxScopeGuard incGlobal = wxMakeGuard(IncGlobal),
115                     incN = wxMakeGuard(Inc, &n),
116                     incMby15 = wxMakeGuard(IncBy, &m, 15);
117
118        incGlobal.Dismiss();
119        incN.Dismiss();
120        incMby15.Dismiss();
121
122        CPPUNIT_ASSERT_EQUAL( 1, gs_count );
123        CPPUNIT_ASSERT_EQUAL( 1, n );
124        CPPUNIT_ASSERT_EQUAL( 2, m );
125    }
126
127    CPPUNIT_ASSERT_EQUAL( 1, gs_count );
128    CPPUNIT_ASSERT_EQUAL( 1, n );
129    CPPUNIT_ASSERT_EQUAL( 2, m );
130}
131
132void ScopeGuardTestCase::BlockExit()
133{
134    int n = 1,
135        m = 2;
136
137    {
138        gs_count = 1;
139
140        wxON_BLOCK_EXIT0(IncGlobal);
141        wxON_BLOCK_EXIT1(Inc, &n);
142        wxON_BLOCK_EXIT2(IncBy, &m, 15);
143
144        CPPUNIT_ASSERT_EQUAL( 1, gs_count );
145        CPPUNIT_ASSERT_EQUAL( 1, n );
146        CPPUNIT_ASSERT_EQUAL( 2, m );
147    }
148
149    CPPUNIT_ASSERT_EQUAL( 2, gs_count );
150    CPPUNIT_ASSERT_EQUAL( 2, n );
151    CPPUNIT_ASSERT_EQUAL( 17, m );
152}
153
154void ScopeGuardTestCase::BlockExitObj()
155{
156    Counter count0(1),
157            count1(2),
158            count2(3);
159
160    {
161        wxON_BLOCK_EXIT_OBJ0(count0, Counter::Zero);
162        wxON_BLOCK_EXIT_OBJ1(count1, Counter::Set, 17);
163        wxON_BLOCK_EXIT_OBJ2(count2, Counter::Sum, 2, 3);
164
165        CPPUNIT_ASSERT_EQUAL( 1, count0.GetCount() );
166        CPPUNIT_ASSERT_EQUAL( 2, count1.GetCount() );
167        CPPUNIT_ASSERT_EQUAL( 3, count2.GetCount() );
168    }
169
170    CPPUNIT_ASSERT_EQUAL( 0, count0.GetCount() );
171    CPPUNIT_ASSERT_EQUAL( 17, count1.GetCount() );
172    CPPUNIT_ASSERT_EQUAL( 5, count2.GetCount() );
173}
174
175