Overview

Namespaces

  • Alchemy
    • core
      • query
      • schema
    • dialect
    • engine
    • orm
    • tests
    • util
      • promise
  • PHP

Classes

  • ANSICompilerTest
  • ANSIDeleteTest
  • ANSIInsertTest
  • ANSISelectTest
  • ANSIUpdateTest
  • BaseTest
  • ColumnTypeTest
  • CompilerTest
  • DataTypeLexerTest
  • ElementTest
  • ExpressionTest
  • ForeignTest
  • InsertTest
  • Language
  • MapperTest
  • MockElement
  • MockPromisable
  • ORMQueryTest
  • PromiseTest
  • QueryTest
  • RelationshipTest
  • ScalarTest
  • SessionIntegrationTest
  • SignalTest
  • UploadedFile
  • WaitableTest
  • Overview
  • Namespace
  • Class
  • Tree
  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:         // ignores second resolve
 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:         // once it resolves, it ignores future changes
 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:         // magic-mapped to resolved object
 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:         // promisable methods can be called on an unresolved typed promise
 52:         $promiseA = new Promise(null, $cls);
 53:         $promiseB = $promiseA
 54:             ->promisableMethod(3, 'q')
 55:             ->promisableMethod(3, 'q');
 56: 
 57:         // B is a Promise of calling ->promisableMethod(3, 'q') on A's result
 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:         // this call will force the Promise to resolve
 69:         $this->assertEquals("value", $promiseB->normalMethod());
 70: 
 71:         // cache simple promisable methods
 72:         $this->assertEquals($promiseA->promisableMethod(), $promiseA->promisableMethod());
 73:     }
 74: 
 75: 
 76:     public function testThenComposition() {
 77:         $promise = new Promise(4);
 78: 
 79:         // called with non-null, non-Exception values
 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:         // catches non-null, non-Exception values
 91:         $this->expectsCallback($this->once())->with(12)
 92:             ->will($this->returnValue(17));
 93:         $fnThen = $this->fnCallback;
 94: 
 95:         // catches Exception values
 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)           // ignores Exception
104:             ->then(null, $fnFail)     // catches Exception, returns 12
105:             ->then($fnThen, $fnFail); // catches 12, returns 17
106: 
107:         // then()'s won't be called until the Promise resolves
108:         $this->assertEquals(null, $promise());
109: 
110:         // automatically cascades through then()'s
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:         // cascades to $promise, which forwards to Promise($then)
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: 
API documentation generated by ApiGen 2.8.0