public function testMemoized()
{
$calculationsPerformed = 0;
$f = function ($arg1, $arg2) use(&$calculationsPerformed) {
++$calculationsPerformed;
return $arg1;
};
$object = (object) array('name' => 'Hello wordl', 'answer' => 42);
$memoized = memoized($f);
$result = $memoized(1, 'a');
$this->assertEquals(1, $result);
$this->assertEquals(1, $calculationsPerformed);
$result = $memoized(1, 'a');
$this->assertEquals(1, $result);
$this->assertEquals(1, $calculationsPerformed);
$result = $memoized(1, ['b']);
$result = $memoized(1, ['b']);
$this->assertEquals(1, $result);
$this->assertEquals(2, $calculationsPerformed);
$result = $memoized(null, ['b']);
$result = $memoized(null, ['b']);
$this->assertEquals(null, $result);
$this->assertEquals(3, $calculationsPerformed);
$result = $memoized($object, true);
$result = $memoized($object, true);
$this->assertEquals($object, $result);
$this->assertEquals(4, $calculationsPerformed);
$calculationsPerformed = 0;
$memoized = call_user_func(memoized, $f);
$result = $memoized(1, 'a');
$this->assertEquals(1, $result);
$this->assertEquals(1, $calculationsPerformed);
$result = $memoized(1, 'a');
$this->assertEquals(1, $result);
$this->assertEquals(1, $calculationsPerformed);
$result = $memoized(1, ['b']);
$result = $memoized(1, ['b']);
$this->assertEquals(1, $result);
$this->assertEquals(2, $calculationsPerformed);
$result = $memoized(null, ['b']);
$result = $memoized(null, ['b']);
$this->assertEquals(null, $result);
$this->assertEquals(3, $calculationsPerformed);
$result = $memoized($object, true);
$result = $memoized($object, true);
$this->assertEquals($object, $result);
$this->assertEquals(4, $calculationsPerformed);
$this->assertEquals('\\nspl\\f\\memoized', memoized);
}