diff --git a/src/tests/kits/app/Jamfile b/src/tests/kits/app/Jamfile index daf9effa01..0e4e9f77f3 100644 --- a/src/tests/kits/app/Jamfile +++ b/src/tests/kits/app/Jamfile @@ -12,6 +12,8 @@ CommonTestLib libapptest.so # BApplication ApplicationTest.cpp + AppQuitRequestedTester.cpp + AppQuitTester.cpp AppRunner.cpp AppRunTester.cpp BApplicationTester.cpp diff --git a/src/tests/kits/app/bapplication/AppQuitRequestedTester.cpp b/src/tests/kits/app/bapplication/AppQuitRequestedTester.cpp new file mode 100644 index 0000000000..de5eb1280f --- /dev/null +++ b/src/tests/kits/app/bapplication/AppQuitRequestedTester.cpp @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +// AppQuitRequestedTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// Local Includes -------------------------------------------------------------- +#include "AppRunner.h" +#include "AppQuitRequestedTester.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ + +// check_output +static +void +check_output(AppRunner &runner, const char *expectedOutput) +{ + BString buffer; + CHK(runner.GetOutput(&buffer) == B_OK); +if (buffer != expectedOutput) +printf("result is `%s', but should be `%s'\n", buffer.String(), +expectedOutput); + CHK(buffer == expectedOutput); +} + +/* + bool QuitRequested() + @case 1 return false the first time, true the second time it is + invoked + @results Should not quit after the first time, but after the + second one. +*/ +void AppQuitRequestedTester::QuitRequestedTest1() +{ + BApplication app("application/x-vnd.obos-app-quit-requested-test"); + const char *output = + "error: 0\n" + "InitCheck(): 0\n" + "BApplication::ReadyToRun()\n" + "BApplication::QuitRequested()\n" + "BApplication::QuitRequested()\n" + "BApplication::Run() done: 1\n" + "BApplication::~BApplication()\n"; + // run the app + AppRunner runner; + CHK(runner.Run("AppQuitRequestedTestApp1") == B_OK); + runner.WaitFor(false); + // get the output and compare the result + check_output(runner, output); +} + + +Test* AppQuitRequestedTester::Suite() +{ + TestSuite* SuiteOfTests = new TestSuite; + + ADD_TEST4(BApplication, SuiteOfTests, AppQuitRequestedTester, + QuitRequestedTest1); + + return SuiteOfTests; +} + + + diff --git a/src/tests/kits/app/bapplication/AppQuitRequestedTester.h b/src/tests/kits/app/bapplication/AppQuitRequestedTester.h new file mode 100644 index 0000000000..1f770fe340 --- /dev/null +++ b/src/tests/kits/app/bapplication/AppQuitRequestedTester.h @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// AppQuitRequestedTester.h +// +//------------------------------------------------------------------------------ + +#ifndef APP_QUIT_REQUESTED_TESTER_H +#define APP_QUIT_REQUESTED_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class AppQuitRequestedTester : public TestCase +{ + public: + AppQuitRequestedTester() {;} + AppQuitRequestedTester(std::string name) : TestCase(name) {;} + + void QuitRequestedTest1(); + + static Test* Suite(); +}; + +#endif // APP_QUIT_REQUESTED_TESTER_H + diff --git a/src/tests/kits/app/bapplication/AppQuitTester.cpp b/src/tests/kits/app/bapplication/AppQuitTester.cpp new file mode 100644 index 0000000000..b1d44d7e7f --- /dev/null +++ b/src/tests/kits/app/bapplication/AppQuitTester.cpp @@ -0,0 +1,166 @@ +//------------------------------------------------------------------------------ +// AppQuitTester.cpp +// +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include + +// System Includes ------------------------------------------------------------- +#include +#include + +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ +#include +#include +#include + +// Local Includes -------------------------------------------------------------- +#include "AppRunner.h" +#include "AppQuitTester.h" +#include "PipedAppRunner.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ + +// check_output +template +static +void +check_output(AppRunnerC &runner, const char *expectedOutput) +{ + BString buffer; + CHK(runner.GetOutput(&buffer) == B_OK); +if (buffer != expectedOutput) +printf("result is `%s', but should be `%s'\n", buffer.String(), +expectedOutput); + CHK(buffer == expectedOutput); +} + +/* + void Quit() + @case 1 not running application + @results Should delete the application object. +*/ +void AppQuitTester::QuitTest1() +{ + BApplication app("application/x-vnd.obos-app-quit-test"); + const char *output = + "error: 0\n" + "InitCheck(): 0\n" + "BApplication::~BApplication()\n"; + // run the apps + AppRunner runner; + CHK(runner.Run("AppQuitTestApp1") == B_OK); + runner.WaitFor(false); + // get the output and compare the result + check_output(runner, output); +} + +/* + void Quit() + @case 2 running application, call from looper thread + @results Run() should return. Should not delete the application + object. +*/ +void AppQuitTester::QuitTest2() +{ + BApplication app("application/x-vnd.obos-app-quit-test"); + const char *output = + "error: 0\n" + "InitCheck(): 0\n" + "BApplication::ReadyToRun()\n" + "BApplication::Run() done: 1\n" + "BApplication::~BApplication()\n"; + // run the apps + AppRunner runner; + CHK(runner.Run("AppQuitTestApp2") == B_OK); + runner.WaitFor(false); + // get the output and compare the result + check_output(runner, output); +} + +/* + void Quit() + @case 3 running application, call from other thread + @results Run() should return. Should not delete the application + object. +*/ +void AppQuitTester::QuitTest3() +{ + BApplication app("application/x-vnd.obos-app-quit-test"); + const char *output = + "error: 0\n" + "InitCheck(): 0\n" + "BApplication::ReadyToRun()\n" + "BApplication::Run() done: 1\n" + "BApplication::~BApplication()\n"; + // run the apps + AppRunner runner; + CHK(runner.Run("AppQuitTestApp3") == B_OK); + runner.WaitFor(false); + // get the output and compare the result + check_output(runner, output); +} + +/* + void Quit() + @case 4 running application, call from other thread, but don't + lock before + @results Should print error message, but proceed anyway. + Run() should return. + Should not delete the application object. +*/ +void AppQuitTester::QuitTest4() +{ + BApplication app("application/x-vnd.obos-app-quit-test"); + const char *output = + "error: 0\n" + "InitCheck(): 0\n" + "BApplication::ReadyToRun()\n" + "BApplication::Run() done: 1\n" + "BApplication::~BApplication()\n"; + // run the apps + PipedAppRunner runner; + CHK(runner.Run("AppQuitTestApp4") == B_OK); + runner.WaitFor(); + // get the output and compare the result + BString buffer; + CHK(runner.GetOutput(&buffer) == B_OK); + // Remove the error message, as it contains the team ID, which we don't + // know. + int32 errorIndex = buffer.FindFirst( + "ERROR - you must Lock the application object before calling Quit()"); + CHK(errorIndex >= 0); + int32 errorEnd = buffer.FindFirst('\n', errorIndex); + CHK(errorEnd >= 0); + buffer.Remove(errorIndex, errorEnd - errorIndex + 1); +if (buffer != output) +printf("result is `%s', but should be `%s'\n", buffer.String(), +output); + CHK(buffer == output); +} + + +Test* AppQuitTester::Suite() +{ + TestSuite* SuiteOfTests = new TestSuite; + + ADD_TEST4(BApplication, SuiteOfTests, AppQuitTester, QuitTest1); + ADD_TEST4(BApplication, SuiteOfTests, AppQuitTester, QuitTest2); + ADD_TEST4(BApplication, SuiteOfTests, AppQuitTester, QuitTest3); + ADD_TEST4(BApplication, SuiteOfTests, AppQuitTester, QuitTest4); + + return SuiteOfTests; +} + + + diff --git a/src/tests/kits/app/bapplication/AppQuitTester.h b/src/tests/kits/app/bapplication/AppQuitTester.h new file mode 100644 index 0000000000..bd79655499 --- /dev/null +++ b/src/tests/kits/app/bapplication/AppQuitTester.h @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +// AppQuitTester.h +// +//------------------------------------------------------------------------------ + +#ifndef APP_QUIT_TESTER_H +#define APP_QUIT_TESTER_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- +#include "../common.h" + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +class AppQuitTester : public TestCase +{ + public: + AppQuitTester() {;} + AppQuitTester(std::string name) : TestCase(name) {;} + + void QuitTest1(); + void QuitTest2(); + void QuitTest3(); + void QuitTest4(); + + static Test* Suite(); +}; + +#endif // APP_QUIT_TESTER_H + diff --git a/src/tests/kits/app/bapplication/AppRunTester.cpp b/src/tests/kits/app/bapplication/AppRunTester.cpp index b88c6c9b2b..7f10cb3901 100644 --- a/src/tests/kits/app/bapplication/AppRunTester.cpp +++ b/src/tests/kits/app/bapplication/AppRunTester.cpp @@ -64,7 +64,6 @@ void AppRunTester::RunTest1() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp1") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp1") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -103,7 +102,6 @@ void AppRunTester::RunTest2() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp1", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp1", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -132,7 +130,6 @@ void AppRunTester::RunTest3() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp2") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp2") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -170,7 +167,6 @@ void AppRunTester::RunTest4() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp2", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp2", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -201,7 +197,6 @@ void AppRunTester::RunTest5() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp3") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp3") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -234,7 +229,6 @@ void AppRunTester::RunTest6() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp3", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp3", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -265,7 +259,6 @@ void AppRunTester::RunTest7() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp4") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp4") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -301,7 +294,6 @@ void AppRunTester::RunTest8() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp4", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp4", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -331,7 +323,6 @@ void AppRunTester::RunTest9() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp3") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp3a") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -370,7 +361,6 @@ void AppRunTester::RunTest10() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp3", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp3a", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -400,7 +390,6 @@ void AppRunTester::RunTest11() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp4") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp4a") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -439,7 +428,6 @@ void AppRunTester::RunTest12() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp4", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp4a", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -470,7 +458,6 @@ void AppRunTester::RunTest13() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp5") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp5") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -503,7 +490,6 @@ void AppRunTester::RunTest14() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp5", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -534,7 +520,6 @@ void AppRunTester::RunTest15() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp6") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp6") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -570,7 +555,6 @@ void AppRunTester::RunTest16() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp6", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -602,7 +586,6 @@ void AppRunTester::RunTest17() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp5") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp5a") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -636,7 +619,6 @@ void AppRunTester::RunTest18() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp5a", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -667,7 +649,6 @@ void AppRunTester::RunTest19() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp6") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp6a") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -703,7 +684,6 @@ void AppRunTester::RunTest20() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp6a", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -740,7 +720,6 @@ void AppRunTester::RunTest21() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp6", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp5", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); @@ -775,7 +754,6 @@ void AppRunTester::RunTest22() // run the apps AppRunner runner1, runner2; CHK(runner1.Run("AppRunTestApp5", "a b") == B_OK); - runner1.Team(); CHK(runner2.Run("AppRunTestApp6", "c d e") == B_OK); runner1.WaitFor(true); runner2.WaitFor(true); diff --git a/src/tests/kits/app/bapplication/ApplicationTest.cpp b/src/tests/kits/app/bapplication/ApplicationTest.cpp index c31bc1663a..a74b875211 100644 --- a/src/tests/kits/app/bapplication/ApplicationTest.cpp +++ b/src/tests/kits/app/bapplication/ApplicationTest.cpp @@ -1,4 +1,6 @@ #include "../common.h" +#include "AppQuitRequestedTester.h" +#include "AppQuitTester.h" #include "AppRunTester.h" #include "BApplicationTester.h" @@ -6,6 +8,8 @@ CppUnit::Test* ApplicationTestSuite() { CppUnit::TestSuite *testSuite = new CppUnit::TestSuite(); + testSuite->addTest(AppQuitRequestedTester::Suite()); + testSuite->addTest(AppQuitTester::Suite()); testSuite->addTest(AppRunTester::Suite()); testSuite->addTest(TBApplicationTester::Suite()); diff --git a/src/tests/kits/app/bapplication/BApplicationCases b/src/tests/kits/app/bapplication/BApplicationCases index 01233d6374..ffcf8e0091 100644 --- a/src/tests/kits/app/bapplication/BApplicationCases +++ b/src/tests/kits/app/bapplication/BApplicationCases @@ -121,10 +121,18 @@ case 22:launch the app two times: first: B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY, first app: ArgvReceived(), ReadyToRun(), QuitRequested() second app: quits - void Quit() -TODO +case 1: not running application => + Should delete the application object. +case 2: running application, call from looper thread => + Run() should return. Should not delete the application object. +case 3: running application, call from other thread => + Run() should return. Should not delete the application object. +case 4: running application, call from other thread, but don't lock before => + Should print error message, but proceed anyway. Run() should return. + Should not delete the application object. bool QuitRequested() -TODO +case 1: return false the first time, true the second time it is invoked => + Should not quit after the first time, but after the second one. diff --git a/src/tests/kits/app/bapplication/testapps/AppQuitRequestedTestApp1.cpp b/src/tests/kits/app/bapplication/testapps/AppQuitRequestedTestApp1.cpp new file mode 100644 index 0000000000..a16cdf7731 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppQuitRequestedTestApp1.cpp @@ -0,0 +1,33 @@ +// AppQuitRequestedTestApp1.cpp + +#include + +#include + +#include "CommonTestApp.h" + +int +main() +{ +// R5: doesn't set the error variable in case of success +#ifdef TEST_R5 + status_t error = B_OK; +#else + status_t error = B_ERROR; +#endif + CommonTestApp *app = new CommonTestApp( + "application/x-vnd.obos-app-quit-testapp1", &error); + init_connection(); + report("error: %lx\n", error); + report("InitCheck(): %lx\n", app->InitCheck()); + app->SetReportDestruction(true); + if (error == B_OK) { + app->SetQuittingPolicy(true); + app->PostMessage(B_QUIT_REQUESTED, app); + app->PostMessage(B_QUIT_REQUESTED, app); + app->Run(); + } + delete app; + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/AppQuitTestApp1.cpp b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp1.cpp new file mode 100644 index 0000000000..0bf99d829a --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp1.cpp @@ -0,0 +1,27 @@ +// AppQuitTestApp1.cpp + +#include + +#include + +#include "CommonTestApp.h" + +int +main() +{ +// R5: doesn't set the error variable in case of success +#ifdef TEST_R5 + status_t error = B_OK; +#else + status_t error = B_ERROR; +#endif + CommonTestApp *app = new CommonTestApp( + "application/x-vnd.obos-app-quit-testapp1", &error); + init_connection(); + report("error: %lx\n", error); + report("InitCheck(): %lx\n", app->InitCheck()); + app->SetReportDestruction(true); + app->Quit(); + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/AppQuitTestApp2.cpp b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp2.cpp new file mode 100644 index 0000000000..968d77e004 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp2.cpp @@ -0,0 +1,45 @@ +// AppQuitTestApp2.cpp + +#include + +#include + +#include "CommonTestApp.h" + +enum { + MSG_QUIT = 'quit', +}; + +class Quitter : public BHandler { +public: + virtual void MessageReceived(BMessage *message) + { + if (message->what == MSG_QUIT) + be_app->Quit(); + } +}; + +int +main() +{ +// R5: doesn't set the error variable in case of success +#ifdef TEST_R5 + status_t error = B_OK; +#else + status_t error = B_ERROR; +#endif + CommonTestApp *app = new CommonTestApp( + "application/x-vnd.obos-app-quit-testapp1", &error); + init_connection(); + report("error: %lx\n", error); + report("InitCheck(): %lx\n", app->InitCheck()); + app->SetReportDestruction(true); + if (error == B_OK) { + app->SetMessageHandler(new Quitter); + app->PostMessage(MSG_QUIT, app); + app->Run(); + } + delete app; + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/AppQuitTestApp3.cpp b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp3.cpp new file mode 100644 index 0000000000..a01a26f128 --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp3.cpp @@ -0,0 +1,41 @@ +// AppQuitTestApp3.cpp + +#include + +#include + +#include "CommonTestApp.h" + +class Quitter : public EventHandler { +public: + virtual void HandleEvent(CommonTestApp *app) + { + app->Lock(); + app->Quit(); + app->Unlock(); + } +}; + +int +main() +{ +// R5: doesn't set the error variable in case of success +#ifdef TEST_R5 + status_t error = B_OK; +#else + status_t error = B_ERROR; +#endif + CommonTestApp *app = new CommonTestApp( + "application/x-vnd.obos-app-quit-testapp1", &error); + init_connection(); + report("error: %lx\n", error); + report("InitCheck(): %lx\n", app->InitCheck()); + app->SetReportDestruction(true); + if (error == B_OK) { + app->RunEventThread(10000, 1, new Quitter); + app->Run(); + } + delete app; + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/AppQuitTestApp4.cpp b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp4.cpp new file mode 100644 index 0000000000..86ec1143db --- /dev/null +++ b/src/tests/kits/app/bapplication/testapps/AppQuitTestApp4.cpp @@ -0,0 +1,41 @@ +// AppQuitTestApp4.cpp + +#include + +#include + +#include "CommonTestApp.h" + +class Quitter : public EventHandler { +public: + virtual void HandleEvent(CommonTestApp *app) + { + app->Quit(); + if (app->IsLocked()) + report("ERROR: BApplication is locked!\n"); + } +}; + +int +main() +{ +// R5: doesn't set the error variable in case of success +#ifdef TEST_R5 + status_t error = B_OK; +#else + status_t error = B_ERROR; +#endif + CommonTestApp *app = new CommonTestApp( + "application/x-vnd.obos-app-quit-testapp1", &error); +// init_connection(); + report("error: %lx\n", error); + report("InitCheck(): %lx\n", app->InitCheck()); + app->SetReportDestruction(true); + if (error == B_OK) { + app->RunEventThread(10000, 1, new Quitter); + app->Run(); + } + delete app; + return 0; +} + diff --git a/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp b/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp index 4ad2dfc233..09690701bd 100644 --- a/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp +++ b/src/tests/kits/app/bapplication/testapps/CommonTestApp.cpp @@ -10,9 +10,12 @@ CommonTestApp::CommonTestApp(const char *signature) : BApplication(signature), fQuitOnSecondTry(false), - fQuitter(-1), - fQuittingDelay(0), - fQuittingTries(1) + fEventThread(-1), + fEventDelay(0), + fEventCount(0), + fEventHandler(NULL), + fMessageHandler(NULL), + fReportDestruction(false) { } @@ -25,10 +28,14 @@ CommonTestApp::CommonTestApp(const char *signature, status_t *result) // destructor CommonTestApp::~CommonTestApp() { - if (fQuitter >= 0) { + if (fEventThread >= 0) { int32 result; - wait_for_thread(fQuitter, &result); + wait_for_thread(fEventThread, &result); } + if (fReportDestruction) + report("BApplication::~BApplication()\n"); + delete fEventHandler; + delete fMessageHandler; } // ArgvReceived @@ -44,6 +51,15 @@ CommonTestApp::ArgvReceived(int32 argc, char **argv) } } +// MessageReceived +void +CommonTestApp::MessageReceived(BMessage *message) +{ + if (fMessageHandler) + fMessageHandler->MessageReceived(message); + BApplication::MessageReceived(message); +} + // QuitRequested bool CommonTestApp::QuitRequested() @@ -80,51 +96,69 @@ CommonTestApp::SetQuittingPolicy(bool onSecondTry) fQuitOnSecondTry = onSecondTry; } -// RunQuitterThread +// SetReportDestruction +void +CommonTestApp::SetReportDestruction(bool reportDestruction) +{ + fReportDestruction = reportDestruction; +} + +// RunEventThread status_t -CommonTestApp::RunQuitterThread(bigtime_t delay, int32 tries) +CommonTestApp::RunEventThread(bigtime_t delay, int32 count, + EventHandler *handler) { status_t error = B_OK; - fQuittingDelay = delay; - fQuittingTries = tries; + fEventDelay = delay; + fEventCount = count; + fEventHandler = handler; // spawn the thread - fQuitter = spawn_thread(&_QuitterEntry, "quitter thread", - B_NORMAL_PRIORITY, this); - if (fQuitter < 0) - error = fQuitter; + fEventThread = spawn_thread(&_EventThreadEntry, "event thread", + B_NORMAL_PRIORITY, this); + if (fEventThread < 0) + error = fEventThread; if (error == B_OK) - error = resume_thread(fQuitter); + error = resume_thread(fEventThread); // cleanup on error - if (error != B_OK && fQuitter >= 0) { - kill_thread(fQuitter); - fQuitter = -1; + if (error != B_OK && fEventThread >= 0) { + kill_thread(fEventThread); + fEventThread = -1; } return error; } -// _QuitterEntry +// SetMessageHandler +void +CommonTestApp::SetMessageHandler(BHandler *handler) +{ + delete fMessageHandler; + fMessageHandler = handler; +} + +// _EventThreadEntry int32 -CommonTestApp::_QuitterEntry(void *data) +CommonTestApp::_EventThreadEntry(void *data) { int32 result = 0; if (CommonTestApp *app = (CommonTestApp*)data) - result = app->_QuitterLoop(); + result = app->_EventLoop(); return result; } -// _QuitterLoop +// _EventLoop int32 -CommonTestApp::_QuitterLoop() +CommonTestApp::_EventLoop() { - for (; fQuittingTries > 0; fQuittingTries--) { - snooze(fQuittingDelay); - PostMessage(B_QUIT_REQUESTED, this); + for (; fEventCount > 0; fEventCount--) { + snooze(fEventDelay); + if (fEventHandler) + fEventHandler->HandleEvent(this); } return 0; } static const char *kAppRunnerTeamPort = "app runner team port"; - +static bool connectionEstablished = false; static port_id outputPort = -1; // init_connection @@ -150,6 +184,7 @@ init_connection() if (written < 0) error = written; } + connectionEstablished = (error == B_OK); return error; } @@ -159,7 +194,10 @@ report(const char *format,...) { va_list args; va_start(args, format); - vreport(format, args); + if (connectionEstablished) + vreport(format, args); + else + vprintf(format, args); va_end(args); } diff --git a/src/tests/kits/app/bapplication/testapps/CommonTestApp.h b/src/tests/kits/app/bapplication/testapps/CommonTestApp.h index a53971d665..8e216cbd9c 100644 --- a/src/tests/kits/app/bapplication/testapps/CommonTestApp.h +++ b/src/tests/kits/app/bapplication/testapps/CommonTestApp.h @@ -7,6 +7,16 @@ #include +class CommonTestApp; + +class EventHandler { +public: + EventHandler() {} + virtual ~EventHandler() {} + + virtual void HandleEvent(CommonTestApp *app) = 0; +}; + class CommonTestApp : public BApplication { public: CommonTestApp(const char *signature); @@ -14,23 +24,31 @@ public: virtual ~CommonTestApp(); virtual void ArgvReceived(int32 argc, char **argv); + virtual void MessageReceived(BMessage *message); virtual bool QuitRequested(); virtual void ReadyToRun(); thread_id Run(); void SetQuittingPolicy(bool onSecondTry); + void SetReportDestruction(bool reportDestruction); - status_t RunQuitterThread(bigtime_t delay, int32 tries); + status_t RunEventThread(bigtime_t delay, int32 count, + EventHandler *handler); + + void SetMessageHandler(BHandler *handler); private: - static int32 _QuitterEntry(void *data); - int32 _QuitterLoop(); + static int32 _EventThreadEntry(void *data); + int32 _EventLoop(); private: - bool fQuitOnSecondTry; - thread_id fQuitter; - bigtime_t fQuittingDelay; - int32 fQuittingTries; + bool fQuitOnSecondTry; + thread_id fEventThread; + bigtime_t fEventDelay; + int32 fEventCount; + EventHandler *fEventHandler; + BHandler *fMessageHandler; + bool fReportDestruction; }; status_t init_connection(); diff --git a/src/tests/kits/app/bapplication/testapps/Jamfile b/src/tests/kits/app/bapplication/testapps/Jamfile index 53fc915d9e..35a0ba0498 100644 --- a/src/tests/kits/app/bapplication/testapps/Jamfile +++ b/src/tests/kits/app/bapplication/testapps/Jamfile @@ -49,6 +49,9 @@ rule CopyBAppTestApp } } +# BApplication::BApplication() test apps +# + SimpleBAppTestApp BApplicationTestApp1.cpp ; SimpleBAppTestApp BApplicationTestApp1a.cpp ; SimpleBAppTestApp BApplicationTestApp1b.cpp ; @@ -65,6 +68,10 @@ SimpleBAppTestApp BApplicationTestApp5.cpp : BApplicationTestApp5.rsrc ; SimpleBAppTestApp BApplicationTestApp5a.cpp : BApplicationTestApp5.rsrc ; SimpleBAppTestApp BApplicationTestApp5b.cpp : BApplicationTestApp5.rsrc ; + +# BApplication::Run() test apps +# + SimpleBAppTestApp AppRunTestApp1.cpp CommonTestApp.cpp : AppRunTestApp1.rsrc ; SimpleBAppTestApp2 AppRunTestApp2 : AppRunTestApp1.o CommonTestApp.o : AppRunTestApp2.rsrc ; @@ -81,3 +88,18 @@ CopyBAppTestApp AppRunTestApp3a : AppRunTestApp3 ; CopyBAppTestApp AppRunTestApp4a : AppRunTestApp4 ; CopyBAppTestApp AppRunTestApp5a : AppRunTestApp5 ; CopyBAppTestApp AppRunTestApp6a : AppRunTestApp6 ; + + +# BApplication::Quit() test apps +# + +SimpleBAppTestApp AppQuitTestApp1.cpp CommonTestApp.o ; +SimpleBAppTestApp AppQuitTestApp2.cpp CommonTestApp.o ; +SimpleBAppTestApp AppQuitTestApp3.cpp CommonTestApp.o ; +SimpleBAppTestApp AppQuitTestApp4.cpp CommonTestApp.o ; + + +# BApplication::QuitRequested() test apps +# + +SimpleBAppTestApp AppQuitRequestedTestApp1.cpp CommonTestApp.o ;