2019-04-10 13:42:17 -05:00
// 10 april 2019
2019-04-28 13:41:30 -05:00
# include <inttypes.h>
2019-04-19 11:10:45 -05:00
# include <string.h>
2019-05-04 15:53:54 -05:00
# include "lib/thread.h"
2019-04-28 12:12:40 -05:00
# include "test.h"
2019-04-10 13:42:17 -05:00
2019-04-20 20:38:26 -05:00
# define errInvalidOptions "options parameter to uiInit() must be NULL"
# define errAlreadyInitialized "libui already initialized"
2019-04-19 11:10:45 -05:00
2019-04-10 19:17:40 -05:00
testingTestBefore ( Init )
2019-04-10 13:42:17 -05:00
{
2019-04-20 20:38:26 -05:00
uiInitError err ;
2019-04-19 11:10:45 -05:00
int ret ;
ret = uiInit ( NULL , NULL ) ;
if ( ret ! = 0 )
testingTErrorf ( t , " uiInit() with NULL error succeeded with return value %d; expected failure " , ret ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = 2 ;
ret = uiInit ( NULL , & err ) ;
if ( ret ! = 0 )
testingTErrorf ( t , " uiInit() with error with invalid size succeeded with return value %d; expected failure " , ret ) ;
err . Size = sizeof ( uiInitError ) ;
ret = uiInit ( & err , & err ) ;
if ( ret ! = 0 )
testingTErrorf ( t , " uiInit() with non-NULL options succeeded with return value %d; expected failure " , err ) ;
2019-04-20 20:38:26 -05:00
if ( strcmp ( err . Message , errInvalidOptions ) ! = 0 )
2019-05-04 20:13:47 -05:00
diff ( t , " uiInit() with non-NULL options returned bad error message " , " %s " ,
err . Message , errInvalidOptions ) ;
2019-04-19 11:10:45 -05:00
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
ret = uiInit ( NULL , & err ) ;
if ( ret = = 0 )
testingTErrorf ( t , " uiInit() failed: %s " , err . Message ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
ret = uiInit ( NULL , & err ) ;
if ( ret ! = 0 )
testingTErrorf ( t , " uiInit() after a previous successful call succeeded with return value %d; expected failure " , ret ) ;
2019-04-20 20:38:26 -05:00
if ( strcmp ( err . Message , errAlreadyInitialized ) ! = 0 )
2019-05-04 20:13:47 -05:00
diff ( t , " uiInit() after a previous successful call returned bad error message " , " %s " ,
err . Message , errAlreadyInitialized ) ;
2019-04-10 13:42:17 -05:00
}
2019-05-04 18:21:57 -05:00
struct testParams {
uint32_t flag ;
timerSysError err ;
} ;
2019-04-10 13:42:17 -05:00
static void queued ( void * data )
{
2019-05-04 18:21:57 -05:00
struct testParams * p = ( struct testParams * ) data ;
2019-04-10 13:42:17 -05:00
2019-05-04 18:21:57 -05:00
p - > flag = 1 ;
2019-05-03 09:41:27 -05:00
uiQuit ( ) ;
2019-04-10 13:42:17 -05:00
}
2019-04-28 10:48:21 -05:00
testingTest ( QueueMain )
2019-04-10 13:42:17 -05:00
{
2019-05-04 18:21:57 -05:00
struct testParams p ;
2019-04-10 13:42:17 -05:00
2019-05-04 18:21:57 -05:00
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
p . flag = 0 ;
uiQueueMain ( queued , & p ) ;
2019-05-03 01:02:20 -05:00
timeout_uiMain ( t , 5 * timerSecond ) ;
2019-05-04 18:21:57 -05:00
if ( p . flag ! = 1 )
2019-05-04 20:13:47 -05:00
diff ( t , " uiQueueMain() didn't set flag properly " , " %d " ,
p . flag , 1 ) ;
2019-04-10 13:42:17 -05:00
}
2019-04-28 13:41:30 -05:00
# define queueOp(name, expr) \
static void name ( void * data ) \
{ \
2019-05-04 18:21:57 -05:00
struct testParams * p = ( struct testParams * ) data ; \
p - > flag = p - > flag expr ; \
2019-04-28 13:41:30 -05:00
}
queueOp ( sub2 , - 2 )
queueOp ( div3 , / 3 )
queueOp ( mul8 , * 8 )
static void done ( void * data )
{
uiQuit ( ) ;
}
static const struct {
uint32_t result ;
const char * order ;
} orders [ ] = {
{ 8 , " sub2 -> div3 -> mul8 " } , // the one we want
{ 13 , " sub2 -> mul8 -> div3 " } ,
{ 0 , " div3 -> sub2 -> mul8 " } ,
{ 14 , " div3 -> mul8 -> sub2 " } ,
{ 18 , " mul8 -> sub2 -> div3 " } ,
{ 16 , " mul8 -> div3 -> sub2 " } ,
} ;
2019-05-04 18:21:57 -05:00
static void queueOrder ( struct testParams * p )
2019-04-28 19:45:53 -05:00
{
2019-05-04 18:21:57 -05:00
p - > flag = 7 ;
uiQueueMain ( sub2 , p ) ;
uiQueueMain ( div3 , p ) ;
uiQueueMain ( mul8 , p ) ;
2019-04-28 19:45:53 -05:00
uiQueueMain ( done , NULL ) ;
}
// TODO somehow funnel the caller's file/line through
static void checkOrder ( testingT * t , uint32_t flag )
{
int i ;
if ( flag = = orders [ 0 ] . result )
return ;
for ( i = 1 ; i < 6 ; i + + )
if ( flag = = orders [ i ] . result ) {
2019-05-04 20:13:47 -05:00
diff2 ( t , " wrong order " , " % " PRIu32 " (%s) " ,
flag , orders [ i ] . order ,
orders [ 0 ] . result , orders [ 0 ] . order ) ;
2019-04-28 19:45:53 -05:00
return ;
}
2019-05-04 20:13:47 -05:00
diff2 ( t , " wrong result " , " % " PRIu32 " (%s) " ,
flag , " unknown order " ,
orders [ 0 ] . result , orders [ 0 ] . order ) ;
2019-04-28 19:45:53 -05:00
}
2019-04-28 10:48:21 -05:00
testingTest ( QueueMain_Sequence )
2019-04-10 13:42:17 -05:00
{
2019-05-04 18:21:57 -05:00
struct testParams p ;
2019-04-28 13:41:30 -05:00
2019-05-04 18:21:57 -05:00
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
queueOrder ( & p ) ;
2019-05-03 01:02:20 -05:00
timeout_uiMain ( t , 5 * timerSecond ) ;
2019-05-04 18:21:57 -05:00
checkOrder ( t , p . flag ) ;
2019-04-28 19:45:53 -05:00
}
static void queueThread ( void * data )
{
2019-05-04 18:21:57 -05:00
struct testParams * p = ( struct testParams * ) data ;
2019-04-28 19:45:53 -05:00
2019-05-04 18:21:57 -05:00
p - > err = timerSleep ( 1250 * timerMillisecond ) ;
uiQueueMain ( queued , p ) ;
2019-04-10 13:42:17 -05:00
}
2019-05-05 10:03:17 -05:00
/*
TODO if I remove the uiQuit ( ) from this test on Windows , I will occasionally get
= = = RUN TestQueueMain_DifferentThread
. . / test / initmain . c : 161 : uiMain ( ) timed out ( 5 s )
- - - FAIL : TestQueueMain_DifferentThread ( 4.9989539 s )
*/
2019-04-28 19:45:53 -05:00
testingTest ( QueueMain_DifferentThread )
{
2019-05-04 15:47:56 -05:00
threadThread * thread ;
2019-05-04 18:21:57 -05:00
threadSysError err ;
struct testParams p ;
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
p . flag = 0 ;
err = threadNewThread ( queueThread , & p , & thread ) ;
if ( err ! = 0 )
testingTFatalf ( t , " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2019-05-03 01:02:20 -05:00
timeout_uiMain ( t , 5 * timerSecond ) ;
2019-05-04 18:21:57 -05:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
testingTFatalf ( t , " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
if ( p . err ! = 0 )
testingTErrorf ( t , " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " timerSysErrorFmt , timerSysErrorFmtArg ( p . err ) ) ;
if ( p . flag ! = 1 )
2019-05-04 20:13:47 -05:00
diff ( t , " uiQueueMain() didn't set flag properly " , " %d " ,
p . flag , 1 ) ;
2019-04-28 19:45:53 -05:00
}
static void queueOrderThread ( void * data )
{
2019-05-04 18:21:57 -05:00
struct testParams * p = ( struct testParams * ) data ;
2019-04-28 19:45:53 -05:00
2019-05-04 18:21:57 -05:00
p - > err = timerSleep ( 1250 * timerMillisecond ) ;
queueOrder ( p ) ;
2019-04-28 19:45:53 -05:00
}
testingTest ( QueueMain_DifferentThreadSequence )
{
2019-05-04 15:47:56 -05:00
threadThread * thread ;
2019-05-04 18:21:57 -05:00
threadSysError err ;
struct testParams p ;
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
p . flag = 1 ; // make sure it's initialized just in case
err = threadNewThread ( queueOrderThread , & p , & thread ) ;
if ( err ! = 0 )
testingTFatalf ( t , " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2019-05-03 01:02:20 -05:00
timeout_uiMain ( t , 5 * timerSecond ) ;
2019-05-04 18:21:57 -05:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
testingTFatalf ( t , " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
if ( p . err ! = 0 )
testingTErrorf ( t , " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " timerSysErrorFmt , timerSysErrorFmtArg ( p . err ) ) ;
checkOrder ( t , p . flag ) ;
2019-04-28 19:45:53 -05:00
}
2019-04-28 10:48:21 -05:00
#if 0
static void timer ( void * data )
{
int * n = ( int * ) data ;
// TODO return stop if n == 5, continue otherwise
* n + + ;
}
2019-04-10 13:42:17 -05:00
2019-04-10 19:11:44 -05:00
testingTest ( Timer )
2019-04-10 13:42:17 -05:00
{
}
2019-04-28 10:48:21 -05:00
# endif