klayout/src/tl/unit_tests/tlDeferredExecutionTests.cc

230 lines
4.0 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2024 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tlDeferredExecution.h"
#include "tlUnitTest.h"
#if defined(HAVE_QT)
# include <QCoreApplication>
#endif
int g_na = 0;
int g_nb = 0;
class X
{
public:
X () : da (this, &X::a), db (this, &X::b, false), na (0), nb (0) { }
void a () { ++na; ++g_na; }
void b () { ++nb; ++g_nb; }
tl::DeferredMethod<X> da, db;
int na, nb;
};
void trigger_execution ()
{
#if defined(HAVE_QT)
if (QCoreApplication::instance ()) {
QCoreApplication::instance ()->processEvents ();
return;
}
#endif
// explicit execute if timer does not do it
tl::DeferredMethodScheduler::execute ();
}
TEST(1)
{
g_na = g_nb = 0;
trigger_execution ();
X *x = new X ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 0);
EXPECT_EQ (g_nb, 0);
trigger_execution ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 0);
EXPECT_EQ (g_nb, 0);
x->da ();
x->da ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 0);
EXPECT_EQ (g_nb, 0);
tl::DeferredMethodScheduler::enable (false);
tl::DeferredMethodScheduler::enable (false);
trigger_execution ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 0);
EXPECT_EQ (g_nb, 0);
tl::DeferredMethodScheduler::enable (true);
x->db ();
x->db ();
trigger_execution ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 0);
EXPECT_EQ (g_nb, 0);
tl::DeferredMethodScheduler::enable (true);
trigger_execution ();
EXPECT_EQ (x->na, 1);
EXPECT_EQ (x->nb, 2);
EXPECT_EQ (g_na, 1);
EXPECT_EQ (g_nb, 2);
trigger_execution ();
EXPECT_EQ (x->na, 1);
EXPECT_EQ (x->nb, 2);
EXPECT_EQ (g_na, 1);
EXPECT_EQ (g_nb, 2);
x->da ();
x->da ();
x->db ();
x->db ();
EXPECT_EQ (x->na, 1);
EXPECT_EQ (x->nb, 2);
EXPECT_EQ (g_na, 1);
EXPECT_EQ (g_nb, 2);
trigger_execution ();
EXPECT_EQ (x->na, 2);
EXPECT_EQ (x->nb, 4);
EXPECT_EQ (g_na, 2);
EXPECT_EQ (g_nb, 4);
trigger_execution ();
EXPECT_EQ (x->na, 2);
EXPECT_EQ (x->nb, 4);
EXPECT_EQ (g_na, 2);
EXPECT_EQ (g_nb, 4);
delete x;
trigger_execution ();
x = new X ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 2);
EXPECT_EQ (g_nb, 4);
trigger_execution ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 2);
EXPECT_EQ (g_nb, 4);
x->da ();
x->db ();
x->da ();
x->db ();
EXPECT_EQ (x->na, 0);
EXPECT_EQ (x->nb, 0);
EXPECT_EQ (g_na, 2);
EXPECT_EQ (g_nb, 4);
trigger_execution ();
EXPECT_EQ (x->na, 1);
EXPECT_EQ (x->nb, 2);
EXPECT_EQ (g_na, 3);
EXPECT_EQ (g_nb, 6);
trigger_execution ();
EXPECT_EQ (x->na, 1);
EXPECT_EQ (x->nb, 2);
EXPECT_EQ (g_na, 3);
EXPECT_EQ (g_nb, 6);
x->da ();
x->da ();
x->db ();
x->db ();
delete x;
trigger_execution ();
EXPECT_EQ (g_na, 3);
EXPECT_EQ (g_nb, 6);
}
static int y_inst = 0;
class Y
{
public:
Y () : da (this, &Y::a), db (this, &Y::b) { ++y_inst; }
~Y () { --y_inst; }
void a () { delete this; }
void b () { tl_assert(false); }
tl::DeferredMethod<Y> da, db;
};
TEST(2)
{
// execution of a deletes db which must not be executed
y_inst = 0;
Y *y = new Y ();
y->da ();
y->db ();
trigger_execution ();
EXPECT_EQ (y_inst, 0);
}