1: <?php
2:
3: namespace Alchemy\tests;
4: use Alchemy\util\promise\Promise;
5: use Alchemy\util\promise\IPromisable;
6:
7:
8: class PromiseTest extends BaseTest {
9: public function testDoubleResolve() {
10: $promise = new Promise(null);
11: $this->assertEquals(null, $promise());
12:
13: $promise->resolve(4);
14: $this->assertEquals(4, $promise());
15:
16:
17: $promise->resolve(5);
18: $this->assertEquals(4, $promise());
19: }
20:
21:
22: public function testSignalChange() {
23: $this->expectsCallback($this->exactly(2))
24: ->will($this->onConsecutiveCalls(null, 5, 3));
25:
26: $promise = new Promise($this->fnCallback);
27:
28:
29: $this->assertEquals(null, $promise());
30: $this->assertEquals(5, $promise());
31: $this->assertEquals(5, $promise());
32: }
33:
34:
35: public function testMagicPassing() {
36: $obj = new \stdClass();
37: $promise = new Promise(null);
38: $promise->resolve($obj);
39:
40:
41: $obj->key = "value";
42: $this->assertEquals("value", $promise->key);
43: }
44:
45:
46: public function testPromisableCallChain() {
47: $cls = 'Alchemy\tests\MockPromisable';
48: $this->assertEquals($cls, Promise::get_return_type($cls, "promisableMethod"));
49: $this->assertEquals(false, Promise::get_return_type($cls, "normalMethod"));
50:
51:
52: $promiseA = new Promise(null, $cls);
53: $promiseB = $promiseA
54: ->promisableMethod(3, 'q')
55: ->promisableMethod(3, 'q');
56:
57:
58: $this->assertInstanceOf("Alchemy\util\promise\Promise", $promiseB);
59:
60: $mock = $this->getMock($cls, array('promisableMethod'));
61: $mock->expects($this->exactly(2))
62: ->method('promisableMethod')
63: ->with(3, 'q')
64: ->will($this->returnValue($mock));
65:
66: $promiseA->resolve($mock);
67:
68:
69: $this->assertEquals("value", $promiseB->normalMethod());
70:
71:
72: $this->assertEquals($promiseA->promisableMethod(), $promiseA->promisableMethod());
73: }
74:
75:
76: public function testThenComposition() {
77: $promise = new Promise(4);
78:
79:
80: $this->expectsCallback($this->once())->with(4)
81: ->will($this->returnValue(15));
82: $promise = $promise->then($this->fnCallback);
83:
84: $this->assertEquals(15, $promise());
85: $this->assertEquals(15, $promise());
86: }
87:
88:
89: public function testThenTypeCatching() {
90:
91: $this->expectsCallback($this->once())->with(12)
92: ->will($this->returnValue(17));
93: $fnThen = $this->fnCallback;
94:
95:
96: $obj = new \Exception();
97: $this->expectsCallback($this->once())->with($obj)
98: ->will($this->returnValue(12));
99: $fnFail = $this->fnCallback;
100:
101: $source = new Promise(null);
102: $promise = $source
103: ->then($fnThen)
104: ->then(null, $fnFail)
105: ->then($fnThen, $fnFail);
106:
107:
108: $this->assertEquals(null, $promise());
109:
110:
111: $source->resolve($obj);
112: }
113:
114:
115: public function testThenSourceForwarding() {
116: $this->expectsCallback($this->exactly(3))
117: ->will($this->onConsecutiveCalls(null, null, 4));
118: $then = $this->fnCallback;
119:
120: $fnThen = function() use ($then) {
121: return new Promise($then);
122: };
123:
124: $source = new Promise(null);
125: $promise = $source->then($fnThen);
126:
127:
128: $source->resolve(0);
129:
130: $this->assertEquals(null, $promise());
131: $this->assertEquals(4, $promise());
132: }
133: }
134:
135:
136: class MockPromisable implements IPromisable {
137:
138: public static function list_promisable_methods() {
139: return array('promisableMethod' => 'Alchemy\tests\MockPromisable');
140: }
141:
142: public function promisableMethod() {
143: return new self();
144: }
145:
146: public function normalMethod() {
147: return "value";
148: }
149: }
150: