<?php

class Table_test extends CI_TestCase {

	public function set_up()
	{
		$this->table = new Mock_Libraries_Table();
		$this->ci_instance_var('table', $this->table);
	}

	// Setter Methods
	// --------------------------------------------------------------------

	public function test_set_template()
	{
		$this->assertFalse($this->table->set_template('not an array'));

		$template = array('a' => 'b');

		$this->table->set_template($template);
		$this->assertEquals($template, $this->table->template);
	}

	public function test_set_empty()
	{
		$this->table->set_empty('nada');
		$this->assertEquals('nada', $this->table->empty_cells);
	}

	public function test_set_caption()
	{
		$this->table->set_caption('awesome cap');
		$this->assertEquals('awesome cap', $this->table->caption);
	}

	/*
	 * @depends	test_prep_args
	 */
	public function test_set_heading()
	{
		// uses _prep_args internally, so we'll just do a quick
		// check to verify that func_get_args and prep_args are
		// being called.

		$this->table->set_heading('name', 'color', 'size');

		$this->assertEquals(
			array(
				array('data' => 'name'),
				array('data' => 'color'),
				array('data' => 'size')
			),
			$this->table->heading
		);
	}

	/*
	 * @depends	test_prep_args
	 */
	public function test_add_row()
	{
		// uses _prep_args internally, so we'll just do a quick
		// check to verify that func_get_args and prep_args are
		// being called.

		$this->table->add_row('my', 'pony', 'sings');
		$this->table->add_row('your', 'pony', 'stinks');
		$this->table->add_row('my pony', '>', 'your pony');

		$this->assertCount(3, $this->table->rows);

		$this->assertEquals(
			array(
				array('data' => 'your'),
				array('data' => 'pony'),
				array('data' => 'stinks')
			),
			$this->table->rows[1]
		);
	}

	// Uility Methods
	// --------------------------------------------------------------------

	public function test_prep_args()
	{
		$expected = array(
			array('data' => 'name'),
			array('data' => 'color'),
			array('data' => 'size')
		);

		$this->assertEquals(
			$expected,
			$this->table->prep_args(array('name', 'color', 'size'))
		);

		// with cell attributes
		// need to add that new argument row to our expected outcome
		$expected[] = array('data' => 'weight', 'class' => 'awesome');

		$this->assertEquals(
			$expected,
			$this->table->prep_args(array('name', 'color', 'size', array('data' => 'weight', 'class' => 'awesome')))
		);
	}

	public function test_default_template_keys()
	{
		$keys = array(
			'table_open',
			'thead_open', 'thead_close',
			'heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end',
			'tbody_open', 'tbody_close',
			'row_start', 'row_end', 'cell_start', 'cell_end',
			'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end',
			'table_close'
		);

		foreach ($keys as $key)
		{
			$this->assertArrayHasKey($key, $this->table->default_template());
		}
	}

	public function test_compile_template()
	{
		$this->assertFalse($this->table->set_template('invalid_junk'));

		// non default key
		$this->table->set_template(array('nonsense' => 'foo'));
		$this->table->compile_template();

		$this->assertArrayHasKey('nonsense', $this->table->template);
		$this->assertEquals('foo', $this->table->template['nonsense']);

		// override default
		$this->table->set_template(array('table_close' => '</table junk>'));
		$this->table->compile_template();

		$this->assertArrayHasKey('table_close', $this->table->template);
		$this->assertEquals('</table junk>', $this->table->template['table_close']);
	}

	public function test_make_columns()
	{
		// Test bogus parameters
		$this->assertFalse($this->table->make_columns('invalid_junk'));
		$this->assertFalse($this->table->make_columns(array()));
		$this->assertFalse($this->table->make_columns(array('one', 'two'), '2.5'));

		// Now on to the actual column creation

		$five_values = array(
			'Laura', 'Red', '15',
			'Katie', 'Blue'
		);

		// No column count - no changes to the array
		$this->assertEquals(
			$five_values,
			$this->table->make_columns($five_values)
		);

		// Column count of 3 leaves us with one &nbsp;
		$this->assertEquals(
			array(
				array('Laura', 'Red', '15'),
				array('Katie', 'Blue', '&nbsp;')
			),
			$this->table->make_columns($five_values, 3)
		);
	}

	public function test_clear()
	{
		$this->table->set_heading('Name', 'Color', 'Size');

		// Make columns changes auto_heading
		$rows = $this->table->make_columns(array(
			'Laura', 'Red', '15',
			'Katie', 'Blue'
		), 3);

		foreach ($rows as $row)
		{
			$this->table->add_row($row);
		}

		$this->assertFalse($this->table->auto_heading);
		$this->assertCount(3, $this->table->heading);
		$this->assertCount(2, $this->table->rows);

		$this->table->clear();

		$this->assertTrue($this->table->auto_heading);
		$this->assertEmpty($this->table->heading);
		$this->assertEmpty($this->table->rows);
	}

	public function test_set_from_array()
	{
		$data = array(
			array('name', 'color', 'number'),
			array('Laura', 'Red', '22'),
			array('Katie', 'Blue')
		);

		$this->table->auto_heading = FALSE;
		$this->table->set_from_array($data);
		$this->assertEmpty($this->table->heading);

		$this->table->clear();

		$this->table->set_from_array($data);
		$this->assertCount(2, $this->table->rows);

		$expected = array(
			array('data' => 'name'),
			array('data' => 'color'),
			array('data' => 'number')
		);

		$this->assertEquals($expected, $this->table->heading);

		$expected = array(
			array('data' => 'Katie'),
			array('data' => 'Blue'),
		);

		$this->assertEquals($expected, $this->table->rows[1]);
	}

	public function test_set_from_object()
	{
		// This needs to be passed by reference to CI_DB_result::__construct()
		$dummy = new stdClass();
		$dummy->conn_id = NULL;
		$dummy->result_id = NULL;

		$db_result = new DB_result_dummy($dummy);

		$this->table->set_from_db_result($db_result);

		$expected = array(
			array('data' => 'name'),
			array('data' => 'email')
		);

		$this->assertEquals($expected, $this->table->heading);

		$expected = array(
			'name' => array('data' => 'Foo Bar'),
			'email' => array('data' => 'foo@bar.com'),
		);

		$this->assertEquals($expected, $this->table->rows[1]);
	}

	public function test_generate()
	{
		// Prepare the data
		$data = array(
			array('Name', 'Color', 'Size'),
			array('Fred', 'Blue', 'Small'),
			array('Mary', 'Red', 'Large'),
			array('John', 'Green', 'Medium')
		);

		$table = $this->table->generate($data);

		// Test the table header
		$this->assertContains('<th>Name</th>', $table);
		$this->assertContains('<th>Color</th>', $table);
		$this->assertContains('<th>Size</th>', $table);

		// Test the first entry
		$this->assertContains('<td>Fred</td>', $table);
		$this->assertContains('<td>Blue</td>', $table);
		$this->assertContains('<td>Small</td>', $table);
	}

}

// We need this for the _set_from_db_result() test
class DB_result_dummy extends CI_DB_result
{
	public function list_fields()
	{
		return array('name', 'email');
	}

	public function result_array()
	{
		return array(
			array('name' => 'John Doe', 'email' => 'john@doe.com'),
			array('name' => 'Foo Bar', 'email' => 'foo@bar.com')
		);
	}
}
