Input class code-coverage
diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php
index 2bec364..9f89d1b 100644
--- a/tests/Bootstrap.php
+++ b/tests/Bootstrap.php
@@ -12,9 +12,6 @@
 define('APPPATH',		PROJECT_BASE.'application/');
 define('VIEWPATH',		PROJECT_BASE.'');
 
-// Set cookie for security test
-$_COOKIE['ci_csrf_cookie'] = md5(uniqid(rand(), TRUE));
-
 // Prep our test environment
 require_once 'vfsStream/vfsStream.php';
 include_once $dir.'/mocks/core/common.php';
diff --git a/tests/codeigniter/core/Input_test.php b/tests/codeigniter/core/Input_test.php
new file mode 100644
index 0000000..fd0576e
--- /dev/null
+++ b/tests/codeigniter/core/Input_test.php
@@ -0,0 +1,144 @@
+<?php
+
+class Input_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		// Set server variable to GET as default, since this will leave unset in STDIN env
+		$_SERVER['REQUEST_METHOD'] = 'GET';
+
+		// Set config for Input class
+		$this->ci_set_config('allow_get_array',	TRUE);
+		$this->ci_set_config('global_xss_filtering', FALSE);
+		$this->ci_set_config('csrf_protection', FALSE);
+
+		$security = new Mock_Core_Security();
+		$utf8 = new Mock_Core_Utf8();
+
+		$this->input = new Mock_Core_Input($security, $utf8);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_get_not_exists()
+	{
+		$this->assertEmpty($this->input->get());
+		$this->assertEmpty($this->input->get('foo'));
+
+		$this->assertTrue( ! $this->input->get());
+		$this->assertTrue( ! $this->input->get('foo'));
+
+		$this->assertTrue($this->input->get() == FALSE);
+		$this->assertTrue($this->input->get('foo') == FALSE);
+
+		$this->assertTrue($this->input->get() === FALSE);
+		$this->assertTrue($this->input->get('foo') === FALSE);
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_get_exist()
+	{
+		$_SERVER['REQUEST_METHOD'] = 'GET';
+		$_GET['foo'] = 'bar';
+
+		$this->assertArrayHasKey('foo', $this->input->get());
+		$this->assertEquals('bar', $this->input->get('foo'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_get_exist_with_xss_clean()
+	{
+		$_SERVER['REQUEST_METHOD'] = 'GET';
+		$_GET['harm'] = "Hello, i try to <script>alert('Hack');</script> your site";
+
+		$this->assertArrayHasKey('harm', $this->input->get());
+		$this->assertEquals("Hello, i try to <script>alert('Hack');</script> your site", $this->input->get('harm'));
+		$this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $this->input->get('harm', TRUE));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_post_not_exists()
+	{
+		$this->assertEmpty($this->input->post());
+		$this->assertEmpty($this->input->post('foo'));
+
+		$this->assertTrue( ! $this->input->post());
+		$this->assertTrue( ! $this->input->post('foo'));
+
+		$this->assertTrue($this->input->post() == FALSE);
+		$this->assertTrue($this->input->post('foo') == FALSE);
+
+		$this->assertTrue($this->input->post() === FALSE);
+		$this->assertTrue($this->input->post('foo') === FALSE);
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_post_exist()
+	{
+		$_SERVER['REQUEST_METHOD'] = 'POST';
+		$_POST['foo'] = 'bar';
+
+		$this->assertArrayHasKey('foo', $this->input->post());
+		$this->assertEquals('bar', $this->input->post('foo'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_post_exist_with_xss_clean()
+	{
+		$_SERVER['REQUEST_METHOD'] = 'POST';
+		$_POST['harm'] = "Hello, i try to <script>alert('Hack');</script> your site";
+
+		$this->assertArrayHasKey('harm', $this->input->post());
+		$this->assertEquals("Hello, i try to <script>alert('Hack');</script> your site", $this->input->post('harm'));
+		$this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $this->input->post('harm', TRUE));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_get_post()
+	{
+		$_SERVER['REQUEST_METHOD'] = 'POST';
+		$_POST['foo'] = 'bar';
+
+		$this->assertEquals('bar', $this->input->get_post('foo'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_cookie()
+	{
+		$_COOKIE['foo'] = 'bar';
+
+		$this->assertEquals('bar', $this->input->cookie('foo'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_server()
+	{
+		$this->assertEquals('GET', $this->input->server('REQUEST_METHOD'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_fetch_from_array()
+	{
+		$data = array(
+			'foo' => 'bar',
+			'harm' => 'Hello, i try to <script>alert(\'Hack\');</script> your site',
+		);
+
+		$foo = $this->input->fetch_from_array($data, 'foo');
+		$harm = $this->input->fetch_from_array($data, 'harm');
+		$harmless = $this->input->fetch_from_array($data, 'harm', TRUE);
+
+		$this->assertEquals('bar', $foo);
+		$this->assertEquals("Hello, i try to <script>alert('Hack');</script> your site", $harm);
+		$this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $harmless);
+	}
+}
\ No newline at end of file
diff --git a/tests/codeigniter/core/Security_test.php b/tests/codeigniter/core/Security_test.php
index c3b5269..1796ba7 100644
--- a/tests/codeigniter/core/Security_test.php
+++ b/tests/codeigniter/core/Security_test.php
@@ -4,19 +4,13 @@
 	
 	public function set_up()
 	{
+		// Set cookie for security test
+		$_COOKIE['ci_csrf_cookie'] = md5(uniqid(rand(), TRUE));
+
+		// Set config for Security class
 		$this->ci_set_config('csrf_protection', TRUE);
 		$this->ci_set_config('csrf_token_name', 'ci_csrf_token');
-		// @see : ./Bootstrap.php Line 16
 		$this->ci_set_config('csrf_cookie_name', 'ci_csrf_cookie');
-		$this->ci_set_config('csrf_expire', 7200);
-		$this->ci_set_config('csrf_regenerate', TRUE);
-		$this->ci_set_config('csrf_exclude_uris', array());
-
-		$this->ci_set_config('cookie_prefix', "");
-		$this->ci_set_config('cookie_domain', "");
-		$this->ci_set_config('cookie_path', "/");
-		$this->ci_set_config('cookie_secure', FALSE);
-		$this->ci_set_config('cookie_httponly',	FALSE);
 
 		$this->security = new Mock_Core_Security();
 	}
diff --git a/tests/mocks/core/input.php b/tests/mocks/core/input.php
new file mode 100644
index 0000000..8a337d2
--- /dev/null
+++ b/tests/mocks/core/input.php
@@ -0,0 +1,31 @@
+<?php
+
+class Mock_Core_Input extends CI_Input {
+	
+	/**
+	 * Since we use GLOBAL to fetch Security and Utf8 classes, 
+	 * we need to use inversion of control to mock up 
+	 * the same process within CI_Input class constructor.
+	 *
+	 * @covers CI_Input::__construct()
+	 */
+	public function __construct($security, $utf8)
+	{
+		$this->_allow_get_array	= (config_item('allow_get_array') === TRUE);
+		$this->_enable_xss	= (config_item('global_xss_filtering') === TRUE);
+		$this->_enable_csrf	= (config_item('csrf_protection') === TRUE);
+
+		// Assign Security and Utf8 classes
+		$this->security = $security;
+		$this->uni = $utf8;
+
+		// Sanitize global arrays
+		$this->_sanitize_globals();
+	}
+
+	public function fetch_from_array($array, $index = '', $xss_clean = FALSE)
+	{
+		return parent::_fetch_from_array($array, $index, $xss_clean);
+	}
+
+}
\ No newline at end of file
diff --git a/tests/mocks/core/security.php b/tests/mocks/core/security.php
index c5269fb..d7ea0e6 100644
--- a/tests/mocks/core/security.php
+++ b/tests/mocks/core/security.php
@@ -6,7 +6,7 @@
 	{
 		// We cannot set cookie in CLI mode, so for csrf test, who rely on $_COOKIE,
 		// we superseded set_cookie with directly set the cookie variable,
-		// @see : ./Bootstrap.php, line 16
+		// @see : ./tests/codeigniter/core/Security_test.php, line 8
 		return $this;
 	}
 
diff --git a/tests/mocks/core/utf8.php b/tests/mocks/core/utf8.php
new file mode 100644
index 0000000..b77d717
--- /dev/null
+++ b/tests/mocks/core/utf8.php
@@ -0,0 +1,27 @@
+<?php
+
+class Mock_Core_Utf8 extends CI_Utf8 {
+	
+	/**
+	 * We need to define several constants as 
+	 * the same process within CI_Utf8 class constructor.
+	 *
+	 * @covers CI_Utf8::__construct()
+	 */
+	public function __construct()
+	{
+		defined('UTF8_ENABLED') or define('UTF8_ENABLED', TRUE);
+
+		if (extension_loaded('mbstring'))
+		{
+			defined('MB_ENABLED') or define('MB_ENABLED', TRUE);
+			mb_internal_encoding('UTF-8');
+		}
+		else
+		{
+			defined('MB_ENABLED') or define('MB_ENABLED', FALSE);
+		}
+		
+	}
+
+}
\ No newline at end of file