<?php

declare(strict_types=1);

use Tester\Assert;
use React\EventLoop;

require(__DIR__ . '/vendor/autoload.php');
Tester\Environment::setup();

$loop = EventLoop\Factory::create();
$executions = [];

Assert::same('value', await(new React\Promise\FulfilledPromise('value'), $loop));

$loop->futureTick(function() use($loop, &$executions) {

	$deferred = new React\Promise\Deferred;

	$loop->addTimer(0, function() use($deferred) {
		$deferred->resolve('value');
	});

	$executions[] = 1;
	Assert::same('value', await($deferred->promise(), $loop));

	$loop->addTimer(0, function() use($loop, &$executions) {

		$deferred = new React\Promise\Deferred;

		$loop->addTimer(0, function() use($deferred) {
			$deferred->resolve('value');
		});

		$executions[] = 3;
		Assert::same('value', await($deferred->promise(), $loop));

	});

	$loop->addTimer(0, function() use($loop, &$executions) {

		$deferred = new React\Promise\Deferred;

		$loop->addTimer(0, function() use($deferred) {
			$deferred->resolve('value');
		});

		$executions[] = 4;
		Assert::same('value', await($deferred->promise(), $loop));

	});

});

$loop->futureTick(function() use($loop, &$executions) {

	$deferred = new React\Promise\Deferred;

	$loop->addTimer(0, function() use($deferred) {
		$deferred->reject(new Exception);
	});

	Assert::exception(function() use($deferred, $loop, &$executions) {
		$executions[] = 2;
		await($deferred->promise(), $loop);
	}, Exception::class);

});

$loop->run();

Assert::same([1, 2, 3, 4], $executions);