* @author Kornel LesiĆski
* @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
* @version SVN: $Id: TalRepeatTest.php 888 2010-06-08 09:48:33Z kornel $
* @link http://phptal.org/
*/
class TalRepeatTest extends PHPTAL_TestCase
{
function testArrayRepeat()
{
$tpl = $this->newPHPTAL('input/tal-repeat.01.html');
$tpl->array = range(0, 4);
$res = normalize_html($tpl->execute());
$exp = normalize_html_file('output/tal-repeat.01.html');
$this->assertEquals($exp, $res);
}
function testOddEventAndFriends()
{
$tpl = $this->newPHPTAL('input/tal-repeat.02.html');
$tpl->array = range(0, 2);
$res = normalize_html($tpl->execute());
$exp = normalize_html_file('output/tal-repeat.02.html');
$this->assertEquals($exp, $res);
}
function testIterableUsage()
{
$tpl = $this->newPHPTAL('input/tal-repeat.03.html');
$tpl->result = new MyIterableWithSize(4);
$res = $tpl->execute();
$res = normalize_html($res);
$exp = normalize_html_file('output/tal-repeat.03.html');
$this->assertEquals($exp, $res);
}
function testArrayObject()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('');
$tpl->aobj = new MyArrayObj(array(1, 2, 3));
$this->assertEquals('', $tpl->execute());
}
function testArrayObjectOneElement()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('');
$tpl->aobj = new MyArrayObj(array(1));
$this->assertEquals('', $tpl->execute());
}
function testArrayObjectZeroElements()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('');
$tpl->aobj = new MyArrayObj(array());
$this->assertEquals('', $tpl->execute());
}
function testArrayObjectAggregated()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('');
$tpl->aobj = new MyArrayObj(new MyArrayObj(array("1", "2", "3", null)));
$this->assertEquals('', $tpl->execute());
}
function testArrayObjectNested()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('');
$tpl->aobj = new MyArrayObj(array("1", "2"));
$this->assertEquals('', $tpl->execute());
}
function testHashKey()
{
$tpl = $this->newPHPTAL('input/tal-repeat.04.html');
$tpl->result = array('a'=>0, 'b'=>1, 'c'=>2, 'd'=>3);
$res = $tpl->execute();
$res = normalize_html($res);
$exp = normalize_html_file('output/tal-repeat.04.html');
$this->assertEquals($exp, $res);
}
function testRepeatAttributesWithPhp()
{
$tpl = $this->newPHPTAL('input/tal-repeat.05.html');
$tpl->data = array(1, 2, 3);
$res = normalize_html($tpl->execute());
$exp = normalize_html_file('output/tal-repeat.05.html');
$this->assertEquals($exp, $res);
}
function testRepeatAttributesWithMacroPhp()
{
$tpl = $this->newPHPTAL('input/tal-repeat.06.html');
$tpl->data = array(1, 2, 3);
$res = normalize_html($tpl->execute());
$exp = normalize_html_file('output/tal-repeat.06.html');
$this->assertEquals($exp, $res);
}
function testPhpMode()
{
$tpl = $this->newPHPTAL('input/tal-repeat.07.html');
$tpl->result = array('a'=>0, 'b'=>1, 'c'=>2, 'd'=>3);
$res = normalize_html($tpl->execute());
$exp = normalize_html_file('output/tal-repeat.07.html');
$this->assertEquals($exp, $res);
}
function testInterpolatedPHP()
{
$tpl = $this->newPHPTAL();
$tpl->y = 'somearray';
$tpl->somearray = array(1=>9, 9, 9);
$tpl->setSource('${repeat/x/key}
');
$this->assertEquals('1
2
3
', $tpl->execute());
}
function testTraversableRepeat()
{
$doc = new DOMDocument();
$doc->loadXML('');
$tpl = $this->newPHPTAL();
$tpl->setSource('(len=${repeat/node/length})${repeat/node/key}${node/tagName}');
$tpl->nodes = $doc->getElementsByTagName('*');
$this->assertEquals('0a1b2c3d(len=7)4e5f6g', $tpl->execute());
}
function testLetter()
{
$tpl = $this->newPHPTAL();
$tpl->setSource( '' );
$tpl->items = range( 0, 32 );
$res = normalize_html( $tpl->execute() );
$exp = 'abcdefghijklmnopqrstuvwxyzaaabacadaeafag';
$this->assertEquals( $exp, $res );
}
function testRoman()
{
$tpl = $this->newPHPTAL();
$tpl->setSource( '' );
$tpl->items = range( 0, 16 );
$res = normalize_html( $tpl->execute() );
$exp = 'i,ii,iii,iv,v,vi,vii,viii,ix,x,xi,xii,xiii,xiv,xv,xvi,xvii,';
$this->assertEquals( $exp, $res );
}
function testGrouping()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('
'
);
$tpl->items = array( 'apple', 'apple', 'orange', 'orange', 'orange', 'pear', 'kiwi', 'kiwi' );
$res = normalize_html( $tpl->execute() );
$exp = normalize_html('
apple
apple
orange
orange
orange
pear
kiwi
kiwi
'
);
$this->assertEquals( $exp, $res );
}
function testGroupingPath()
{
$tpl = $this->newPHPTAL();
$tpl->setSource('
'
);
$tpl->items = array(
array( 'type' => 'car', 'name' => 'bmw' ),
array( 'type' => 'car', 'name' => 'audi' ),
array( 'type' => 'plane', 'name' => 'boeing' ),
array( 'type' => 'bike', 'name' => 'suzuki' ),
array( 'type' => 'bike', 'name' => 'honda' ),
);
$res = normalize_html( $tpl->execute() );
$exp = normalize_html('
car
bmw
audi
plane
boeing
bike
suzuki
honda
'
);
$this->assertEquals( $exp, $res );
}
function testSimpleXML()
{
$tpl = $this->newPHPTAL();
$tpl->setSource("\n");
$tpl->sxml = new SimpleXMLElement("testtest");
$this->assertEquals("test\ntest\n\n", $tpl->execute());
}
function testSameCallsAsForeach()
{
$foreach = new LogIteratorCalls(array(1, 2, 3));
foreach ($foreach as $k => $x) {
}
$controller = new LogIteratorCalls(array(1, 2, 3));
$phptal = $this->newPHPTAL();
$phptal->iter = $controller;
$phptal->setSource('');
$phptal->execute();
$this->assertEquals($foreach->log, $controller->log);
}
function testCountIsLazy()
{
$tpl = $this->newPHPTAL();
$tpl->i = new MyIterableThrowsOnSize(10);
$tpl->setSource('${repeat/i/start}[${repeat/i/key}]${repeat/i/end}');
$this->assertEquals("1[0]00[1]00[2]00[3]00[4]00[5]00[6]00[7]00[8]00[9]1", $tpl->execute());
try
{
$tpl->i = new MyIterableThrowsOnSize(10);
$tpl->setSource('aaaaa${repeat/i/length}aaaaa');
echo $tpl->execute();
$this->fail("Expected SizeCalledException");
}
catch(SizeCalledException $e) {}
}
function testReset()
{
$tpl = $this->newPHPTAL();
$tpl->iter = $i = new LogIteratorCalls(new MyIterableThrowsOnSize(10));
$tpl->setSource('${repeat/i/start}[${repeat/i/key}]${repeat/i/end}${repeat/i/start}[${repeat/i/key}]${repeat/i/end}');
$res = $tpl->execute();
$this->assertEquals("1[0]00[1]00[2]00[3]00[4]00[5]00[6]00[7]00[8]00[9]11[0]00[1]00[2]00[3]00[4]00[5]00[6]00[7]00[8]00[9]1", $res,$tpl->getCodePath());
$this->assertRegExp("/rewind.*rewind/s",$i->log);
$this->assertEquals("1[0]00[1]00[2]00[3]00[4]00[5]00[6]00[7]00[8]00[9]11[0]00[1]00[2]00[3]00[4]00[5]00[6]00[7]00[8]00[9]1", $tpl->execute());
}
function testFakedLength()
{
$tpl = $this->newPHPTAL();
$tpl->iter = new MyIterable(10);
$tpl->setSource('${repeat/i/start}[${repeat/i/key}/${repeat/i/length}]${repeat/i/end}');
$this->assertEquals("1[0/]00[1/]00[2/]00[3/]00[4/]00[5/]00[6/]00[7/]00[8/]00[9/10]1", $tpl->execute(), $tpl->getCodePath());
}
function testPushesContext()
{
$phptal = $this->newPHPTAL();
$phptal->setSource('
original=${user}
defined=${user}
repeat=${user}
repeat2=${user}
repeat=${user}
defined=${user}
original=${user}
');
$phptal->user = 'original';
$phptal->users = array('repeat');
$phptal->users2 = array('repeat2');
$this->assertEquals(
normalize_html(' original=original defined=defined repeat=repeat repeat2=repeat2 repeat=repeat defined=defined original=original'),
normalize_html($phptal->execute()));
}
}
class LogIteratorCalls implements Iterator
{
public $i, $log = '';
function __construct($arr)
{
if ($arr instanceof Iterator) $this->i = $arr; else $this->i = new ArrayIterator($arr);
}
function current()
{
$this->log .= "current\n";
return $this->i->current();
}
function next()
{
$this->log .= "next\n";
return $this->i->next();
}
function key()
{
$this->log .= "key\n";
return $this->i->key();
}
function rewind()
{
$this->log .= "rewind\n";
return $this->i->rewind();
}
function valid()
{
$this->log .= "valid\n";
return $this->i->valid();
}
}
class MyArrayObj extends ArrayObject
{
}
class MyIterable implements Iterator
{
public function __construct($size){
$this->_index = 0;
$this->_size= $size;
}
public function rewind(){
$this->_index = 0;
}
public function current(){
return $this->_index;
}
public function key(){
return $this->_index;
}
public function next(){
$this->_index++;
return $this->_index;
}
public function valid(){
return $this->_index < $this->_size;
}
private $_index;
protected $_size;
}
class MyIterableWithSize extends MyIterable
{
public function size(){
return $this->_size;
}
}
class SizeCalledException extends Exception {}
class MyIterableThrowsOnSize extends MyIterable implements Countable
{
public function count()
{
throw new SizeCalledException("count() called");
}
public function length()
{
throw new SizeCalledException("length() called");
}
public function size()
{
throw new SizeCalledException("size() called");
}
}