ajout SAE PHP 19/20 Meilleure note de la promo

This commit is contained in:
EmmanuelTiamzon
2025-12-05 10:30:43 +01:00
parent b05817dbcd
commit 0ae7d097f9
290 changed files with 69511 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
<?php
// Errors on full!
ini_set('display_errors', 1);
if (version_compare(PHP_VERSION, '8.4', '>=')) {
error_reporting(E_ALL);
} else {
error_reporting(E_ALL | E_STRICT);
}
$dir = realpath(dirname(__FILE__));
// Path constants
defined('PROJECT_BASE') OR define('PROJECT_BASE', realpath($dir.'/../').'/');
defined('SYSTEM_PATH') OR define('SYSTEM_PATH', PROJECT_BASE.'system/');
// Get vfsStream either via PEAR or composer
foreach (explode(PATH_SEPARATOR, get_include_path()) as $path)
{
if (file_exists($path.DIRECTORY_SEPARATOR.'vfsStream/vfsStream.php'))
{
require_once 'vfsStream/vfsStream.php';
break;
}
}
if ( ! class_exists('vfsStream') && file_exists(PROJECT_BASE.'vendor/autoload.php'))
{
include_once PROJECT_BASE.'vendor/autoload.php';
class_alias('org\bovigo\vfs\vfsStream', 'vfsStream');
class_alias('org\bovigo\vfs\vfsStreamDirectory', 'vfsStreamDirectory');
class_alias('org\bovigo\vfs\vfsStreamWrapper', 'vfsStreamWrapper');
}
// Define CI path constants to VFS (filesystem setup in CI_TestCase::setUp)
defined('BASEPATH') OR define('BASEPATH', vfsStream::url('system/'));
defined('APPPATH') OR define('APPPATH', vfsStream::url('application/'));
defined('VIEWPATH') OR define('VIEWPATH', APPPATH.'views/');
defined('ENVIRONMENT') OR define('ENVIRONMENT', 'development');
// Set localhost "remote" IP
isset($_SERVER['REMOTE_ADDR']) OR $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
// Prep our test environment
include_once $dir.'/mocks/core/common.php';
include_once SYSTEM_PATH.'core/Common.php';
ini_set('default_charset', 'UTF-8');
if (extension_loaded('mbstring'))
{
defined('MB_ENABLED') OR define('MB_ENABLED', TRUE);
@ini_set('mbstring.internal_encoding', 'UTF-8');
mb_substitute_character('none');
}
else
{
defined('MB_ENABLED') OR define('MB_ENABLED', FALSE);
}
if (extension_loaded('iconv'))
{
defined('ICONV_ENABLED') OR define('ICONV_ENABLED', TRUE);
@ini_set('iconv.internal_encoding', 'UTF-8');
}
else
{
defined('ICONV_ENABLED') OR define('ICONV_ENABLED', FALSE);
}
is_php('5.6') && ini_set('php.internal_encoding', 'UTF-8');
if (is_php('7.0'))
{
$test_case_code = file_get_contents(PROJECT_BASE.'vendor/phpunit/phpunit/src/Framework/TestCase.php');
$test_case_code = preg_replace('/^\s+((?:protected|public)(?: static)? function \w+\(\)): void/m', '$1', $test_case_code);
file_put_contents(PROJECT_BASE.'vendor/phpunit/phpunit/src/Framework/TestCase.php', $test_case_code);
}
include_once SYSTEM_PATH.'core/compat/mbstring.php';
include_once SYSTEM_PATH.'core/compat/hash.php';
include_once SYSTEM_PATH.'core/compat/password.php';
include_once SYSTEM_PATH.'core/compat/standard.php';
include_once $dir.'/mocks/autoloader.php';
spl_autoload_register('autoload');
unset($dir);

View File

@@ -0,0 +1,226 @@
# CodeIgniter Unit Tests #
Status : [![Build Status](https://secure.travis-ci.org/bcit-ci/CodeIgniter.png?branch=develop)](https://travis-ci.org/bcit-ci/CodeIgniter)
### Introduction:
This is the preliminary CodeIgniter testing documentation. It
will cover both internal as well as external APIs and the reasoning
behind their implementation, where appropriate. As with all CodeIgniter
documentation, this file should maintain a mostly human readable
format to facilitate clean api design. [see https://arrenbrecht.ch/testing/]
*First public draft: everything is subject to change*
### Requirements
PHP Unit >= 3.5.6
pear channel-discover pear.phpunit.de
pear channel-discover pear.symfony.com
pear install phpunit/PHPUnit
vfsStream
pear channel-discover pear.bovigo.org
pear install bovigo/vfsStream-beta
#### Installation of PEAR and PHPUnit on Ubuntu
Installation on Ubuntu requires a few steps. Depending on your setup you may
need to use 'sudo' to install these. Mileage may vary but these steps are a
good start.
# Install the PEAR package
sudo apt-get install php-pear
# Add a few sources to PEAR
pear channel-discover pear.phpunit.de
pear channel-discover pear.symfony-project.com
pear channel-discover components.ez.no
pear channel-discover pear.bovigo.org
# Finally install PHPUnit and vfsStream (including dependencies)
pear install --alldeps phpunit/PHPUnit
pear install --alldeps bovigo/vfsStream-beta
# Finally, run 'phpunit' from within the ./tests directory
# and you should be on your way!
## Test Suites:
CodeIgniter bootstraps a request very directly, with very flat class
hierarchy. As a result, there is no main CodeIgniter class until the
controller is instantiated.
This has forced the core classes to be relatively decoupled, which is
a good thing. However, it makes that portion of code relatively hard
to test.
Right now that means we'll probably have two core test suites, along
with a base for application and package tests. That gives us:
1. Bootstrap Test - test common.php and sanity check codeigniter.php [in planning]
2. System Test - test core components in relative isolation [in development]
3. Application Test - bootstrapping for application/tests [not started]
4. Package Test - bootstrapping for <package>/tests [not started]
### Test Environment:
The test/Bootstrap.php file establishes global constants such as BASEPATH,
APPPATH, and VIEWPATH, initializing them to point to VFS locations. The
test case class employs vfsStream to make a clean virtual filesystem with
the necessary paths for every individual test.
Within each test case, VFS directory objects are available to use as arguments
to the VFS convenience functions (see below):
- ci_vfs_root: VFS filesystem root
- ci_app_root: Application directory
- ci_base_root: System directory
- ci_view_root: Views directory
Classes being instantiated for testing are read from the actual filesystem
by the unit test autoloader, as are mockups created in tests/mocks. If you
need access to the real system directory, the SYSTEM_PATH constant always
points to it.
Any other resources which need to be read from the path constants must be
created or cloned within your test. Functions for doing so are outlined
below.
### CI_TestCase Documentation
Test cases should extend CI_TestCase. This internally extends
PHPUnit\_Framework\_TestCase, so you have access to all of your
usual PHPUnit methods.
We need to provide a simple way to modify the globals and the
common function output. We also need to be able to mock up
the super object as we please.
Current API is *not stable*. Names and implementations will change.
$this->ci_set_config($key, $val)
Set the global config variables in a mock Config object. If key is an array,
it will replace the entire config array. They are _not_ merged. If called
without any parameters, it will create the mock object but not set any values.
The mock Config object also provides rudimentary item() and load() stubs for
delivering configured values to classes being tested and handling config load
calls, respectively. The load() stub does _not_ actually load any files, it
only records the filename provided. Check the config->loaded array to verify
calls made.
$this->ci_instance($obj)
Set the object to use as the "super object", in a lot
of cases this will be a simple stdClass with the attributes
you need it to have. If no parameter, will return the instance.
$this->ci_instance_var($name, $val)
Add an attribute to the super object. This is useful if you
set up a simple instance in setUp and then need to add different
class mockups to your super object.
$this->ci_core_class($name)
Get the _class name_ of a core class, so that you can instantiate
it. The variable is returned by reference and is tied to the correct
$GLOBALS key. For example:
$cfg =& $this->ci_core_class('cfg'); // returns 'CI_Config'
$cfg = new $cfg; // instantiates config and overwrites the CFG global
$this->ci_set_core_class($name, $obj)
An alternative way to set one of the core globals.
$this->ci_vfs_mkdir($name, $root)
Creates a new directory in the test VFS. Pass a directory object to be the
parent directory or none to create a root-level directory. Returns the new
directory object.
$this->ci_vfs_create($file, $content, $root, $path)
Creates a new VFS file. '.php' is automatically appended to the filename if
it has no extension. Pass a directory object as the root, and an optional path
to recurse and/or create for containing the file. Path may be a string (such
as 'models/subdir') or an array (e.g. - array('models', 'subdir') ). Existing
directories in the VFS root will be recursed until a new directory is
identified - all others in the path will be created, so you can mix-and-match
old and new directories. If $file is an array (key = name, value = content),
multiple files will be created in the same path.
$this->ci_vfs_clone($path)
Clones an existing file from the real filesystem to exist in the same path of
the VFS. Path must be relative to the project root (i.e. - starting with
'system' or 'application').
$this->ci_vfs_path($path, $base)
Creates a VFS file path string suitable for use with PHP file operations. Path
may be absolute from the VFS root, or relative to a base path. It is often
useful to use APPPATH or BASEPATH as the base.
$this->helper($name)
Loads a helper from the real filesystem.
$this->lang($name)
Loads a language file from the real filesystem and returns the $lang array.
$this->ci_get_config() __internal__
Returns the global config array. Internal as you shouldn't need to
call this (you're setting it, after all). Used internally to make
CI's get_config() work.
CI_TestCase::instance() __internal__
Returns an instance of the current test case. We force phpunit to
run with backup-globals enabled, so this will always be the instance
of the currently running test class.
### Going forward
#### 1. Bootstrap Test
Testing common.php should be pretty simple. Include the file, and test the
functions. May require some tweaking so that we can grab the statics from all
methods (see is_loaded()). Testing the actual CodeIgniter.php file will most
likely be an output test for the default view, with some object checking after
the file runs. Needs consideration.
#### 2. System Test
Testing the core system relies on being able to isolate the core components
as much as possible. A few of them access other core classes as globals. These
should be mocked up and easy to manipulate.
All functions in common.php should be a minimal implementation, or and mapped
to a method in the test's parent class to gives us full control of their output.
#### 3. Application Test:
Not sure yet, needs to handle:
- Libraries
- Helpers
- Models
- MY_* files
- Controllers (uh...?)
- Views? (watir, selenium, cucumber?)
- Database Testing
#### 4. Package Test:
I don't have a clue how this will work.
Needs to be able to handle packages
that are used multiple times within the application (i.e. EE/Pyro modules)
as well as packages that are used by multiple applications (library distributions)

View File

@@ -0,0 +1,118 @@
<?php
// This autoloader provide convenient way to working with mock object
// make the test looks natural. This autoloader support cascade file loading as well
// within mocks directory.
//
// Prototype :
//
// $mock_table = new Mock_Libraries_Table(); // Will load ./mocks/libraries/table.php
// $mock_database_driver = new Mock_Database_Driver(); // Will load ./mocks/database/driver.php
// and so on...
function autoload($class)
{
$dir = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR;
$ci_core = array(
'Benchmark',
'Config',
'Controller',
'Exceptions',
'Hooks',
'Input',
'Lang',
'Loader',
'Log',
'Model',
'Output',
'Router',
'Security',
'URI',
'Utf8'
);
$ci_libraries = array(
'Calendar',
'Driver_Library',
'Email',
'Encrypt',
'Encryption',
'Form_validation',
'Ftp',
'Image_lib',
'Javascript',
'Migration',
'Pagination',
'Parser',
'Profiler',
'Table',
'Trackback',
'Typography',
'Unit_test',
'Upload',
'User_agent',
'Xmlrpc',
'Zip'
);
$ci_drivers = array('Session', 'Cache');
if (strpos($class, 'Mock_') === 0)
{
$class = strtolower(str_replace(array('Mock_', '_'), array('', DIRECTORY_SEPARATOR), $class));
}
elseif (strpos($class, 'CI_') === 0)
{
$subclass = substr($class, 3);
if (in_array($subclass, $ci_core))
{
$dir = SYSTEM_PATH.'core'.DIRECTORY_SEPARATOR;
$class = $subclass;
}
elseif (in_array($subclass, $ci_libraries))
{
$dir = SYSTEM_PATH.'libraries'.DIRECTORY_SEPARATOR;
$class = ($subclass === 'Driver_Library') ? 'Driver' : $subclass;
}
elseif (in_array($subclass, $ci_drivers))
{
$dir = SYSTEM_PATH.'libraries'.DIRECTORY_SEPARATOR.$subclass.DIRECTORY_SEPARATOR;
$class = $subclass;
}
elseif (in_array(($parent = strtok($subclass, '_')), $ci_drivers)) {
$dir = SYSTEM_PATH.'libraries'.DIRECTORY_SEPARATOR.$parent.DIRECTORY_SEPARATOR.'drivers'.DIRECTORY_SEPARATOR;
$class = $subclass;
}
elseif (preg_match('/^CI_DB_(.+)_(.+)_(driver|forge|result|utility)$/', $class, $m) && count($m) === 4)
{
$driver_path = SYSTEM_PATH.'database'.DIRECTORY_SEPARATOR.'drivers'.DIRECTORY_SEPARATOR;
$dir = $driver_path.$m[1].DIRECTORY_SEPARATOR.'subdrivers'.DIRECTORY_SEPARATOR;
$file = $dir.$m[1].'_'.$m[2].'_'.$m[3].'.php';
}
elseif (preg_match('/^CI_DB_(.+)_(driver|forge|result|utility)$/', $class, $m) && count($m) === 3)
{
$driver_path = SYSTEM_PATH.'database'.DIRECTORY_SEPARATOR.'drivers'.DIRECTORY_SEPARATOR;
$dir = $driver_path.$m[1].DIRECTORY_SEPARATOR;
$file = $dir.$m[1].'_'.$m[2].'.php';
}
elseif (strpos($class, 'CI_DB') === 0)
{
$dir = SYSTEM_PATH.'database'.DIRECTORY_SEPARATOR;
$file = $dir.str_replace(array('CI_DB','active_record'), array('DB', 'active_rec'), $subclass).'.php';
}
else
{
$class = strtolower($class);
}
}
$file = isset($file) ? $file : $dir.$class.'.php';
if ( ! file_exists($file))
{
return FALSE;
}
include_once($file);
}

View File

@@ -0,0 +1,401 @@
<?php
#[AllowDynamicProperties]
class CI_TestCase extends \PHPUnit\Framework\TestCase {
public $ci_vfs_root;
public $ci_app_root;
public $ci_base_root;
public $ci_readonly_dir;
protected $ci_instance;
protected static $ci_test_instance;
private $global_map = array(
'benchmark' => 'bm',
'config' => 'cfg',
'hooks' => 'ext',
'utf8' => 'uni',
'router' => 'rtr',
'output' => 'out',
'security' => 'sec',
'input' => 'in',
'lang' => 'lang',
'loader' => 'load',
'model' => 'model'
);
// --------------------------------------------------------------------
public function __construct($name = null, array $data = array(), $dataName = '')
{
parent::__construct($name, $data, $dataName);
$this->ci_instance = new stdClass();
}
// --------------------------------------------------------------------
public function setUp()
{
// Setup VFS with base directories
$this->ci_vfs_root = vfsStream::setup('');
$this->ci_app_root = vfsStream::newDirectory('application')->at($this->ci_vfs_root);
$this->ci_base_root = vfsStream::newDirectory('system')->at($this->ci_vfs_root);
$this->ci_view_root = vfsStream::newDirectory('views')->at($this->ci_app_root);
$this->ci_readonly_dir = vfsStream::newDirectory('readonly', 555)->at($this->ci_app_root);
if (method_exists($this, 'set_up'))
{
$this->set_up();
}
}
// --------------------------------------------------------------------
public function tearDown()
{
if (method_exists($this, 'tear_down'))
{
$this->tear_down();
}
}
// --------------------------------------------------------------------
public static function instance()
{
return self::$ci_test_instance;
}
// --------------------------------------------------------------------
public function ci_set_config($key = '', $val = '')
{
// Add test config
if ( ! isset($this->ci_instance->config))
{
$this->ci_instance->config = new CI_TestConfig();
}
// Empty key means just do setup above
if ($key === '')
{
return;
}
if (is_array($key))
{
$this->ci_instance->config->config = $key;
}
else
{
$this->ci_instance->config->config[$key] = $val;
}
}
// --------------------------------------------------------------------
public function ci_get_config()
{
return isset($this->ci_instance->config) ? $this->ci_instance->config->config : array();
}
// --------------------------------------------------------------------
public function ci_instance($obj = FALSE)
{
if ( ! is_object($obj))
{
return $this->ci_instance;
}
$this->ci_instance = $obj;
}
// --------------------------------------------------------------------
public function ci_instance_var($name, $obj = FALSE)
{
if ( ! is_object($obj))
{
return $this->ci_instance->$name;
}
$this->ci_instance->$name =& $obj;
}
// --------------------------------------------------------------------
/**
* Grab a core class
*
* Loads the correct core class without extensions
* and returns a reference to the class name in the
* globals array with the correct key. This way the
* test can modify the variable it assigns to and
* still maintain the global.
*/
public function &ci_core_class($name)
{
$name = strtolower($name);
if (isset($this->global_map[$name]))
{
$class_name = ucfirst($name);
$global_name = $this->global_map[$name];
}
elseif (in_array($name, $this->global_map))
{
$class_name = ucfirst(array_search($name, $this->global_map));
$global_name = $name;
}
else
{
throw new Exception('Not a valid core class.');
}
if ( ! class_exists('CI_'.$class_name))
{
require_once SYSTEM_PATH.'core/'.$class_name.'.php';
}
$GLOBALS[strtoupper($global_name)] = 'CI_'.$class_name;
return $GLOBALS[strtoupper($global_name)];
}
// --------------------------------------------------------------------
// convenience function for global mocks
public function ci_set_core_class($name, $obj)
{
$orig =& $this->ci_core_class($name);
$orig = $obj;
}
/**
* Create VFS directory
*
* @param string Directory name
* @param object Optional root to create in
* @return object New directory object
*/
public function ci_vfs_mkdir($name, $root = NULL)
{
// Check for root
if ( ! $root)
{
$root = $this->ci_vfs_root;
}
// Return new directory object
return vfsStream::newDirectory($name)->at($root);
}
// --------------------------------------------------------------------
/**
* Create VFS content
*
* @param string File name
* @param string File content
* @param object VFS directory object
* @param mixed Optional subdirectory path or array of subs
* @return void
*/
public function ci_vfs_create($file, $content = '', $root = NULL, $path = NULL)
{
// Check for array
if (is_array($file))
{
foreach ($file as $name => $content)
{
$this->ci_vfs_create($name, $content, $root, $path);
}
return;
}
// Assert .php extension if none given
if (pathinfo($file, PATHINFO_EXTENSION) == '')
{
$file .= '.php';
}
// Build content
$tree = array($file => $content);
// Check for path
$subs = array();
if ($path)
{
// Explode if not array
$subs = is_array($path) ? $path : explode('/', trim($path, '/'));
}
// Check for root
if ( ! $root)
{
// Use base VFS root
$root = $this->ci_vfs_root;
}
// Handle subdirectories
while (($dir = array_shift($subs)))
{
// See if subdir exists under current root
$dir_root = $root->getChild($dir);
if ($dir_root)
{
// Yes - recurse into subdir
$root = $dir_root;
}
else
{
// No - put subdirectory back and quit
array_unshift($subs, $dir);
break;
}
}
// Create any remaining subdirectories
if ($subs)
{
foreach (array_reverse($subs) as $dir)
{
// Wrap content in subdirectory for creation
$tree = array($dir => $tree);
}
}
// Create tree
vfsStream::create($tree, $root);
}
// --------------------------------------------------------------------
/**
* Clone a real file into VFS
*
* @param string Path from base directory
* @return bool TRUE on success, otherwise FALSE
*/
public function ci_vfs_clone($path, $dest='')
{
// Check for array
if (is_array($path))
{
foreach ($path as $file)
{
$this->ci_vfs_clone($file, $dest);
}
return;
}
// Get real file contents
$content = file_get_contents(PROJECT_BASE.$path);
if ($content === FALSE)
{
// Couldn't find file to clone
return FALSE;
}
if (empty($dest))
{
$dest = dirname($path);
}
$this->ci_vfs_create(basename($path), $content, NULL, $dest);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Helper to get a VFS URL path
*
* @param string Path
* @param string Optional base path
* @return string Path URL
*/
public function ci_vfs_path($path, $base = '')
{
// Check for base path
if ($base)
{
// Prepend to path
$path = rtrim($base, '/').'/'.ltrim($path, '/');
// Is it already in URL form?
if (strpos($path, '://') !== FALSE)
{
// Done - return path
return $path;
}
}
// Trim leading slash and return URL
return vfsStream::url(ltrim($path, '/'));
}
// --------------------------------------------------------------------
// Internals
// --------------------------------------------------------------------
/**
* Overwrite runBare
*
* PHPUnit instantiates the test classes before
* running them individually. So right before a test
* runs we set our instance. Normally this step would
* happen in setUp, but someone is bound to forget to
* call the parent method and debugging this is no fun.
*/
public function runBare()
{
self::$ci_test_instance = $this;
parent::runBare();
}
// --------------------------------------------------------------------
public function helper($name)
{
require_once(SYSTEM_PATH.'helpers/'.$name.'_helper.php');
}
// --------------------------------------------------------------------
public function lang($name)
{
require(SYSTEM_PATH.'language/english/'.$name.'_lang.php');
return $lang;
}
// --------------------------------------------------------------------
/**
* This overload is useful to create a stub, that need to have a specific method.
*/
public function __call($method, $args)
{
if ($this->{$method} instanceof Closure)
{
return call_user_func_array($this->{$method},$args);
}
return parent::__call($method, $args);
}
public function setExpectedException($exception_class, $exception_message = '', $exception_code = null)
{
$use_expect_exception = method_exists($this, 'expectException');
if ($use_expect_exception)
{
$this->expectException($exception_class);
$exception_message !== '' && $this->expectExceptionMessage($exception_message);
}
else
{
parent::setExpectedException($exception_class, $exception_message, $exception_code);
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
class CI_TestConfig extends CI_Config {
public $config = array();
public $_config_paths = array(APPPATH);
public $loaded = array();
public function item($key, $index = '')
{
return isset($this->config[$key]) ? $this->config[$key] : FALSE;
}
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
$this->loaded[] = $file;
return TRUE;
}
}

View File

@@ -0,0 +1,153 @@
<?php
// Set up the global CI functions in their most minimal core representation
if ( ! function_exists('get_instance'))
{
function &get_instance()
{
$test = CI_TestCase::instance();
$test = $test->ci_instance();
return $test;
}
}
// --------------------------------------------------------------------
if ( ! function_exists('get_config'))
{
function &get_config()
{
$test = CI_TestCase::instance();
$config = $test->ci_get_config();
return $config;
}
}
if ( ! function_exists('config_item'))
{
function config_item($item)
{
$config =& get_config();
if ( ! isset($config[$item]))
{
return NULL;
}
return $config[$item];
}
}
if ( ! function_exists('get_mimes'))
{
/**
* Returns the MIME types array from config/mimes.php
*
* @return array
*/
function &get_mimes()
{
static $_mimes = array();
if (empty($_mimes))
{
$path = realpath(PROJECT_BASE.'application/config/mimes.php');
if (is_file($path))
{
$_mimes = include($path);
}
}
return $_mimes;
}
}
// --------------------------------------------------------------------
/*
if ( ! function_exists('load_class'))
{
function load_class($class, $directory = 'libraries', $prefix = 'CI_')
{
if ($directory !== 'core' OR $prefix !== 'CI_')
{
throw new Exception('Not Implemented: Non-core load_class()');
}
$test = CI_TestCase::instance();
$obj =& $test->ci_core_class($class);
if (is_string($obj))
{
throw new Exception('Bad Isolation: Use ci_set_core_class to set '.$class);
}
return $obj;
}
}
*/
// Clean up error messages
// --------------------------------------------------------------------
if ( ! function_exists('show_error'))
{
function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
{
throw new RuntimeException('CI Error: '.$message);
}
}
if ( ! function_exists('show_404'))
{
function show_404($page = '', $log_error = TRUE)
{
throw new RuntimeException('CI Error: 404');
}
}
if ( ! function_exists('_exception_handler'))
{
function _exception_handler($severity, $message, $filepath, $line)
{
throw new RuntimeException('CI Exception: '.$message.' | '.$filepath.' | '.$line);
}
}
// We assume a few things about our environment ...
// --------------------------------------------------------------------
if ( ! function_exists('is_loaded'))
{
function &is_loaded()
{
$loaded = array();
return $loaded;
}
}
if ( ! function_exists('log_message'))
{
function log_message($level, $message)
{
return TRUE;
}
}
if ( ! function_exists('set_status_header'))
{
function set_status_header($code = 200, $text = '')
{
return TRUE;
}
}
if ( ! function_exists('is_cli'))
{
// In order to test HTTP functionality, we need to lie about this
function is_cli()
{
return FALSE;
}
}

View File

@@ -0,0 +1,35 @@
<?php
class Mock_Core_Security extends CI_Security {
public function csrf_set_cookie()
{
// 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 : ./tests/codeigniter/core/Security_test.php, line 8
return $this;
}
// Override inaccessible protected properties
public function __get($property)
{
return isset($this->{'_'.$property}) ? $this->{'_'.$property} : NULL;
}
public function remove_evil_attributes($str, $is_image)
{
return $this->_remove_evil_attributes($str, $is_image);
}
// Override inaccessible protected method
public function __call($method, $params)
{
if (is_callable(array($this, '_'.$method)))
{
return call_user_func_array(array($this, '_'.$method), $params);
}
throw new BadMethodCallException('Method '.$method.' was not found');
}
}

View File

@@ -0,0 +1,32 @@
<?php
class Mock_Core_URI extends CI_URI {
public function __construct()
{
$test = CI_TestCase::instance();
$cls =& $test->ci_core_class('cfg');
// set predictable config values
$test->ci_set_config(array(
'index_page' => 'index.php',
'base_url' => 'http://example.com/',
'subclass_prefix' => 'MY_',
'enable_query_strings' => FALSE,
'permitted_uri_chars' => 'a-z 0-9~%.:_\-'
));
$this->config = new $cls;
if ($this->config->item('enable_query_strings') !== TRUE OR is_cli())
{
$this->_permitted_uri_chars = $this->config->item('permitted_uri_chars');
}
}
public function _set_permitted_uri_chars($value)
{
$this->_permitted_uri_chars = $value;
}
}

View File

@@ -0,0 +1,34 @@
<?php
return array(
// Typical Database configuration
'mysql' => array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'mysql'
),
// Database configuration with failover
'mysql_failover' => array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'not_travis',
'password' => 'wrong password',
'database' => 'not_ci_test',
'dbdriver' => 'mysql',
'failover' => array(
array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'mysql',
)
)
)
);

View File

@@ -0,0 +1,34 @@
<?php
return array(
// Typical Database configuration
'mysqli' => array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'mysqli'
),
// Database configuration with failover
'mysqli_failover' => array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'not_travis',
'password' => 'wrong password',
'database' => 'not_ci_test',
'dbdriver' => 'mysqli',
'failover' => array(
array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'mysqli',
)
)
)
);

View File

@@ -0,0 +1,37 @@
<?php
return array(
// Typical Database configuration
'pdo/mysql' => array(
'dsn' => 'mysql:host=127.0.0.1;dbname=ci_test',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'mysql'
),
// Database configuration with failover
'pdo/mysql_failover' => array(
'dsn' => '',
'hostname' => '127.0.0.1',
'username' => 'not_travis',
'password' => 'wrong password',
'database' => 'not_ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'mysql',
'failover' => array(
array(
'dsn' => 'mysql:host=127.0.0.1;dbname=ci_test',
'hostname' => '127.0.0.1',
'username' => 'travis',
'password' => 'travis',
'database' => 'ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'mysql'
)
)
)
);

View File

@@ -0,0 +1,37 @@
<?php
return array(
// Typical Database configuration
'pdo/pgsql' => array(
'dsn' => 'pgsql:host=localhost;port=5432;dbname=ci_test;',
'hostname' => 'localhost',
'username' => 'postgres',
'password' => 'postgres',
'database' => 'ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'pgsql'
),
// Database configuration with failover
'pdo/pgsql_failover' => array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'not_travis',
'password' => 'wrong password',
'database' => 'not_ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'pgsql',
'failover' => array(
array(
'dsn' => 'pgsql:host=localhost;port=5432;dbname=ci_test;',
'hostname' => 'localhost',
'username' => 'postgres',
'password' => 'postgres',
'database' => 'ci_test',
'dbdriver' => 'pdo',
'subdriver' => 'pgsql'
)
)
)
);

View File

@@ -0,0 +1,37 @@
<?php
return array(
// Typical Database configuration
'pdo/sqlite' => array(
'dsn' => 'sqlite:/'.realpath(__DIR__.'/../..').'/ci_test.sqlite',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => 'sqlite',
'dbdriver' => 'pdo',
'subdriver' => 'sqlite'
),
// Database configuration with failover
'pdo/sqlite_failover' => array(
'dsn' => 'sqlite:not_exists.sqlite',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => 'sqlite',
'dbdriver' => 'pdo',
'subdriver' => 'sqlite',
'failover' => array(
array(
'dsn' => 'sqlite:/'.realpath(__DIR__.'/../..').'/ci_test.sqlite',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => 'sqlite',
'dbdriver' => 'pdo',
'subdriver' => 'sqlite'
)
)
)
);

View File

@@ -0,0 +1,34 @@
<?php
return array(
// Typical Database configuration
'pgsql' => array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'postgres',
'password' => 'postgres',
'database' => 'ci_test',
'dbdriver' => 'postgre'
),
// Database configuration with failover
'pgsql_failover' => array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'not_travis',
'password' => 'wrong password',
'database' => 'not_ci_test',
'dbdriver' => 'postgre',
'failover' => array(
array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'postgres',
'password' => 'postgres',
'database' => 'ci_test',
'dbdriver' => 'postgre',
)
)
)
);

View File

@@ -0,0 +1,34 @@
<?php
return array(
// Typical Database configuration
'sqlite' => array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => realpath(__DIR__.'/..').'/ci_test.sqlite',
'dbdriver' => 'sqlite3'
),
// Database configuration with failover
'sqlite_failover' => array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => '../not_exists.sqlite',
'dbdriver' => 'sqlite3',
'failover' => array(
array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'sqlite',
'password' => 'sqlite',
'database' => realpath(__DIR__.'/..').'/ci_test.sqlite',
'dbdriver' => 'sqlite3'
)
)
)
);

View File

@@ -0,0 +1,142 @@
<?php
class Mock_Database_DB {
/**
* @var array DB configuration
*/
private $config = array();
/**
* @var string DB driver name
*/
private static $dbdriver = '';
/**
* @var string DB sub-driver name
*/
private static $subdriver = '';
/**
* Prepare database configuration skeleton
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
$this->config = $config;
}
/**
* Build DSN connection string for DB driver instantiate process
*
* @param string Group name
* @return string DSN Connection string
*/
public function set_dsn($group = 'default')
{
if ( ! isset($this->config[$group]))
{
throw new InvalidArgumentException('Group '.$group.' not exists');
}
self::$dbdriver = $this->config[$group]['dbdriver'];
if (isset($this->config[$group]['subdriver']))
{
self::$subdriver = $this->config[$group]['subdriver'];
}
$params = array(
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => FALSE,
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'stricton' => FALSE
);
$config = array_merge($this->config[$group], $params);
$dsnstring = empty($config['dsn']) ? FALSE : $config['dsn'];
$subdriver = empty($config['subdriver']) ? FALSE: $config['subdriver'];
$failover = empty($config['failover']) ? FALSE : $config['failover'];
$dsn = $config['dbdriver'].'://'.$config['username'].':'.$config['password']
.'@'.$config['hostname'].'/'.$config['database'];
// Build the parameter
$other_params = array_slice($config, 6);
if ($dsnstring) $other_params['dsn'] = $dsnstring;
if ($subdriver) $other_params['subdriver'] = $subdriver;
if ($failover) $other_params['failover'] = $failover;
return $dsn.'?'.http_build_query($other_params);
}
/**
* Return a database config array
*
* @see ./config
* @param string Driver based configuration
* @return array
*/
public static function config($driver)
{
$dir = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR;
return include($dir.'config'.DIRECTORY_SEPARATOR.$driver.'.php');
}
/**
* Main DB method wrapper
*
* @param string Group or DSN string
* @param bool
* @return object
*/
public static function DB($group, $query_builder = FALSE)
{
// Create dummy driver and builder files to "load" - the mocks have
// already triggered autoloading of the real files
$case = CI_TestCase::instance();
$driver = self::$dbdriver;
$subdriver = self::$subdriver;
$case->ci_vfs_create(array(
'DB_driver.php' => '',
'DB_result.php' => '',
'DB_forge.php' => '',
'DB_query_builder.php' => ''
), '', $case->ci_base_root, 'database');
if (file_exists(SYSTEM_PATH.'database/drivers/'.$driver.'/'.$driver.'_driver.php'))
{
$case->ci_vfs_create(array(
$driver.'_driver.php' => '',
$driver.'_result.php' => '',
$driver.'_forge.php' => ''
), '', $case->ci_base_root, 'database/drivers/'.$driver);
}
if ($subdriver)
{
$case->ci_vfs_create(array(
$driver.'_'.$subdriver.'_driver.php' => '',
$driver.'_'.$subdriver.'_forge.php' => ''
), '', $case->ci_base_root, 'database/drivers/'.$driver.'/subdrivers');
}
include_once(SYSTEM_PATH.'database/DB.php');
try
{
$db = DB($group, $query_builder);
}
catch (Exception $e)
{
throw new RuntimeException($e->getMessage());
}
return $db;
}
}

View File

@@ -0,0 +1,40 @@
<?php
class Mock_Database_DB_Driver extends CI_DB_driver {
/**
* @var object The actual Driver
*/
protected $ci_db_driver;
/**
* Instantiate the database driver
*
* @param string DB Driver class name
* @param array DB configuration to set
* @return void
*/
public function __construct($driver_class, $config = array())
{
if (is_string($driver_class))
{
$this->ci_db_driver = new $driver_class($config);
}
}
/**
* Overloading method, emulate the actual driver method (multiple inheritance workaround)
*/
public function __call($method, $arguments)
{
if ( ! is_callable(array($this->ci_db_driver, $method)))
{
throw new BadMethodCallException($method. ' not exists or not implemented');
}
return call_user_func_array(array($this->ci_db_driver, $method), $arguments);
}
}
class CI_DB extends CI_DB_query_builder {}

View File

@@ -0,0 +1,16 @@
<?php
class Mock_Database_Drivers_Mysql extends Mock_Database_DB_Driver {
/**
* Instantiate the database driver
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
parent::__construct('CI_DB_mysql_driver', $config);
}
}

View File

@@ -0,0 +1,16 @@
<?php
class Mock_Database_Drivers_Mysqli extends Mock_Database_DB_Driver {
/**
* Instantiate the database driver
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
parent::__construct('CI_DB_mysqli_driver', $config);
}
}

View File

@@ -0,0 +1,15 @@
<?php
class Mock_Database_Drivers_PDO extends Mock_Database_DB_Driver {
/**
* Instantiate the database driver
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
parent::__construct('CI_DB_pdo_driver', $config);
}
}

View File

@@ -0,0 +1,16 @@
<?php
class Mock_Database_Drivers_Postgre extends Mock_Database_DB_Driver {
/**
* Instantiate the database driver
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
parent::__construct('CI_DB_postgre_driver', $config);
}
}

View File

@@ -0,0 +1,16 @@
<?php
class Mock_Database_Drivers_Sqlite extends Mock_Database_DB_Driver {
/**
* Instantiate the database driver
*
* @param array DB configuration to set
* @return void
*/
public function __construct($config = array())
{
parent::__construct('CI_DB_sqlite3_driver', $config);
}
}

View File

@@ -0,0 +1,155 @@
<?php
class Mock_Database_Schema_Skeleton {
/**
* @var object Database Holder
*/
public static $db;
/**
* @var object Forge Holder
*/
public static $forge;
/**
* @var object Driver Holder
*/
public static $driver;
/**
* Initialize both database and forge components
*/
public static function init($driver)
{
if (empty(self::$db) && empty(self::$forge))
{
// E_DEPRECATED notices thrown by mysql_connect(), mysql_pconnect()
// on PHP 5.5+ cause the tests to fail
if ($driver === 'mysql' && version_compare(PHP_VERSION, '5.5', '>='))
{
error_reporting(E_ALL & ~E_DEPRECATED);
}
$config = Mock_Database_DB::config($driver);
$connection = new Mock_Database_DB($config);
$db = Mock_Database_DB::DB($connection->set_dsn($driver), TRUE);
CI_TestCase::instance()->ci_instance_var('db', $db);
$loader = new CI_Loader();
$loader->dbforge();
$forge = CI_TestCase::instance()->ci_instance_var('dbforge');
self::$db = $db;
self::$forge = $forge;
self::$driver = $driver;
}
return self::$db;
}
/**
* Create the dummy tables
*
* @return void
*/
public static function create_tables()
{
// User Table
self::$forge->add_field(array(
'id' => array(
'type' => 'INTEGER',
'constraint' => 3
),
'name' => array(
'type' => 'VARCHAR',
'constraint' => 40
),
'email' => array(
'type' => 'VARCHAR',
'constraint' => 100
),
'country' => array(
'type' => 'VARCHAR',
'constraint' => 40
)
));
self::$forge->add_key('id', TRUE);
self::$forge->create_table('user', TRUE) OR show_error('Unable to create the `user` table');
// Job Table
self::$forge->add_field(array(
'id' => array(
'type' => 'INTEGER',
'constraint' => 3
),
'name' => array(
'type' => 'VARCHAR',
'constraint' => 40
),
'description' => array(
'type' => 'TEXT'
)
));
self::$forge->add_key('id', TRUE);
self::$forge->create_table('job', TRUE) OR show_error('Unable to create the `job` table');
// Misc Table
self::$forge->add_field(array(
'id' => array(
'type' => 'INTEGER',
'constraint' => 3
),
'key' => array(
'type' => 'VARCHAR',
'constraint' => 40
),
'value' => array(
'type' => 'TEXT'
)
));
self::$forge->add_key('id', TRUE);
self::$forge->create_table('misc', TRUE) OR show_error('Unable to create the `misc` table');
}
/**
* Create the dummy datas
*
* @return void
*/
public static function create_data()
{
// Job Data
$data = array(
'user' => array(
array('id' => 1, 'name' => 'Derek Jones', 'email' => 'derek@world.com', 'country' => 'US'),
array('id' => 2, 'name' => 'Ahmadinejad', 'email' => 'ahmadinejad@world.com', 'country' => 'Iran'),
array('id' => 3, 'name' => 'Richard A Causey', 'email' => 'richard@world.com', 'country' => 'US'),
array('id' => 4, 'name' => 'Chris Martin', 'email' => 'chris@world.com', 'country' => 'UK')
),
'job' => array(
array('id' => 1, 'name' => 'Developer', 'description' => 'Awesome job, but sometimes makes you bored'),
array('id' => 2, 'name' => 'Politician', 'description' => 'This is not really a job'),
array('id' => 3, 'name' => 'Accountant', 'description' => 'Boring job, but you will get free snack at lunch'),
array('id' => 4, 'name' => 'Musician', 'description' => 'Only Coldplay can actually called Musician')
),
'misc' => array(
array('id' => 1, 'key' => '\\xxxfoo456', 'value' => 'Entry with \\xxx'),
array('id' => 2, 'key' => '\\%foo456', 'value' => 'Entry with \\%'),
array('id' => 3, 'key' => 'spaces and tabs', 'value' => ' One two three tab')
)
);
foreach ($data as $table => $dummy_data)
{
self::$db->truncate($table) OR show_error("Unable to truncate `{$table}` table");
foreach ($dummy_data as $single_dummy_data)
{
self::$db->insert($table, $single_dummy_data) OR show_error("Unable to insert data into `{$table}` table");
}
}
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Mock library to subclass Driver for testing
*/
class Mock_Libraries_Driver extends CI_Driver_Library {
/**
* Set valid drivers list
*/
public function driver_list($drivers = NULL)
{
if (empty($drivers))
{
return $this->valid_drivers;
}
$this->valid_drivers = (array) $drivers;
}
/**
* Get library name
*/
public function get_name()
{
return $this->lib_name;
}
}

View File

@@ -0,0 +1,39 @@
<?php
class Mock_Libraries_Encryption extends CI_Encryption {
/**
* __get_params()
*
* Allows public calls to the otherwise protected _get_params().
*/
public function __get_params($params)
{
return $this->_get_params($params);
}
// --------------------------------------------------------------------
/**
* get_key()
*
* Allows checking for key changes.
*/
public function get_key()
{
return $this->_key;
}
// --------------------------------------------------------------------
/**
* __driver_get_handle()
*
* Allows checking for _mcrypt_get_handle(), _openssl_get_handle()
*/
public function __driver_get_handle($driver, $cipher, $mode)
{
return $this->{'_'.$driver.'_get_handle'}($cipher, $mode);
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* Mock library to add testing features to Session driver library
*/
class Mock_Libraries_Session extends CI_Session {
/**
* Simulate new page load
*/
public function reload()
{
$this->_flashdata_sweep();
$this->_flashdata_mark();
$this->_tempdata_sweep();
}
}
/**
* Mock cookie driver to overload cookie setting
*/
class Mock_Libraries_Session_cookie extends CI_Session_cookie {
/**
* Overload _setcookie to manage $_COOKIE values, since actual cookies can't be set in unit testing
*/
protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = FALSE, $httponly = FALSE)
{
if (empty($value) OR $expire <= time())
{
unset($_COOKIE[$name]);
}
else
{
$_COOKIE[$name] = $value;
}
}
}
class Mock_Libraries_Session_native extends CI_Session_native {}

View File

@@ -0,0 +1,16 @@
<?php
class Mock_Libraries_Table extends CI_Table {
// Override inaccessible protected method
public function __call($method, $params)
{
if (is_callable(array($this, '_'.$method)))
{
return call_user_func_array(array($this, '_'.$method), $params);
}
throw new BadMethodCallException('Method '.$method.' was not found');
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="./Bootstrap.php"
colors="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
beStrictAboutTestsThatDoNotTestAnything="false">
<testsuites>
<testsuite name="CodeIgniter Core Test Suite">
<directory suffix="test.php">./codeigniter/core</directory>
<directory suffix="test.php">./codeigniter/helpers</directory>
<directory suffix="test.php">./codeigniter/libraries</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../system/</directory>
</whitelist>
</filter>
</phpunit>