-- Eventloop behavior tests for the CraftOS-PC harness. local createEventLoop = require('/apis/eventloop'); local createLibTest = require('/apis/libtest'); local testlib = createLibTest({ ... }); testlib.test('register dispatches queued event args', function() local events = createEventLoop(); local called = 0; events.register('eventloop_test_basic', function(a, b) called = called + 1; testlib.assertEquals(a, 'first'); testlib.assertEquals(b, 42); events.stopLoop(); end); os.queueEvent('eventloop_test_basic', 'first', 42); events.runLoop(); testlib.assertEquals(called, 1); testlib.assertTrue(not events.isRunningLoop()); end); testlib.test('STOP unregisters handler after first call', function() local events = createEventLoop(); local stoppedHandlerCalls = 0; local observerCalls = 0; events.register('eventloop_test_stop', function() stoppedHandlerCalls = stoppedHandlerCalls + 1; return events.STOP; end); events.register('eventloop_test_stop', function() observerCalls = observerCalls + 1; if observerCalls == 1 then os.queueEvent('eventloop_test_stop'); else events.stopLoop(); end end); os.queueEvent('eventloop_test_stop'); events.runLoop(); testlib.assertEquals(stoppedHandlerCalls, 1); testlib.assertEquals(observerCalls, 2); end); testlib.test('manual unregister prevents dispatch', function() local events = createEventLoop(); local called = 0; local dispose = events.register('eventloop_test_unregister', function() called = called + 1; end); events.setTimeout(function() events.stopLoop(); end, 0); dispose(); os.queueEvent('eventloop_test_unregister'); events.runLoop(); testlib.assertEquals(called, 0); end); testlib.test('setTimeout before runLoop fires once', function() local events = createEventLoop(); local called = 0; events.setTimeout(function() called = called + 1; events.stopLoop(); end, 0); events.runLoop(); testlib.assertEquals(called, 1); end); testlib.test('setTimeout during runLoop fires after event handler', function() local events = createEventLoop(); local order = ''; events.register('eventloop_test_runtime_timeout', function() order = order .. 'event>'; events.setTimeout(function() order = order .. 'timeout'; events.stopLoop(); end, 0); return events.STOP; end); os.queueEvent('eventloop_test_runtime_timeout'); events.runLoop(); testlib.assertEquals(order, 'event>timeout'); end); testlib.test('cleared timeout before runLoop does not fire', function() local events = createEventLoop(); local called = 0; local clear = events.setTimeout(function() called = called + 1; end, 0); clear(); events.setTimeout(function() events.stopLoop(); end, 0); events.runLoop(); testlib.assertEquals(called, 0); end); testlib.test('onStart and onStop run around loop', function() local events = createEventLoop(); local order = ''; events.onStart(function() order = order .. 'start>'; end); events.onStop(function() order = order .. 'stop'; end); events.setTimeout(function() order = order .. 'timeout>'; events.stopLoop(); end, 0); events.runLoop(); testlib.assertEquals(order, 'start>timeout>stop'); end); testlib.test('empty loop returns and runs onStop', function() local events = createEventLoop(); local stopped = false; events.onStop(function() stopped = true; end); events.runLoop(); testlib.assertTrue(stopped); testlib.assertTrue(not events.isRunningLoop()); end); testlib.test('error contracts are enforced', function() local events = createEventLoop(); local function handler() end events.register('eventloop_test_errors', handler); testlib.assertErrors(function() events.register('eventloop_test_errors', handler); end, 'handler already registered'); testlib.assertErrors(function() events.stopLoop(); end, 'loop is already stopped'); testlib.assertErrors(function() events.register(1, handler); end, 'string expected'); testlib.assertErrors(function() events.register('eventloop_test_errors_2', 'not a function'); end, 'function expected'); end); testlib.run();