SuperCommit 2

This commit is contained in:
Timothy Warren 2014-05-14 10:32:31 -04:00
parent 4280489558
commit cc54862f2f
28 changed files with 638 additions and 204 deletions

25
.scrutinizer.yml Executable file
View File

@ -0,0 +1,25 @@
imports:
- php
tools:
external_code_coverage:
timeout: 1000
# PHP
# Don't like PSR standards, not going to get messages for them!
php_code_sniffer: false
php_sim: true
# Can't be used with similarity analyzer
php_cpd: false
php_mess_detector: true
php_pdepend: true
php_loc: true
php_analyzer:
config:
metrics_lack_of_cohesion_methods:
enabled: true
doc_comment_fixes:
enabled: true
php_hhvm: true

19
.travis.yml Normal file
View File

@ -0,0 +1,19 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
script:
- mkdir -p build/logs
- cd tests && phpunit --coverage-clover build/logs/clover.xml
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
matrix:
allow_failures:
- hhvm

View File

@ -7,17 +7,17 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/core
*/ */
namespace Sleepy\Core; namespace Sleepy\Core\Abstracts;
use Sleepy\Core\Interfaces\Type as iType;
use Sleepy\Exception\NotImplementedException; use Sleepy\Exception\NotImplementedException;
/** /**
* Abstract class with helpful functionality implementing type functionality * Abstract class with helpful functionality implementing type functionality
*/ */
abstract class aType implements iType { abstract class Type implements iType {
/** /**
* The data in the current type wrapper * The data in the current type wrapper
@ -41,16 +41,32 @@ abstract class aType implements iType {
*/ */
public function __construct($data = NULL) public function __construct($data = NULL)
{ {
if (empty($this->mime)) if (empty($this->mime))
{ {
throw new NotImplementedException("Output types must have a mime type defined."); throw new NotImplementedException("Output types must have a mime type defined.");
} }
$this->set_data($data);
}
/**
* Set data to serialize
*
* @param mixed $data
* @return mixed
*/
protected function set_data(&$data)
{
if ( ! is_null($data)) if ( ! is_null($data))
{ {
$this->data = $data; $this->data = $data;
} }
else
{
$data = $this->data;
}
return $data;
} }
/** /**
@ -75,4 +91,4 @@ abstract class aType implements iType {
} }
} }
// End of core/aType.php // End of Core/Abstracts/Type.php

66
Sleepy/Core/Config.php Executable file
View File

@ -0,0 +1,66 @@
<?php
/**
* Sleepy - a REST framework
*
*
* A PHP Rest Framework valuing convention over configuration,
* but aiming to be as flexible as possible
*
* @author Timothy J. Warren
*/
namespace Sleepy\Core;
/**
* Class for managing configuration values
*/
class Config {
/**
* The config array
* @var array
*/
protected $data = [];
/**
* Load the specified config file and return
* the config array
*
* @throws \InvalidArugmentException
* @param string $name
* @return array
*/
public function load($name)
{
$file = APPPATH . 'config/'. $name . '.php';
if (is_file($file))
{
$conf =require_once($file);
}
else
{
throw new \InvalidArgumentException("The config file doesn't exist");
}
$this->data[$name] = $conf;
}
/**
* Get the specific parameter from the specified file
*
* @param string $file
* @param string $key
* @return mixed
*/
public function get($file, $key=NULL)
{
if (is_null($key))
{
return $this->data[$file];
}
return $this->data[$file][$key];
}
}
// End of Core/Config.php

View File

@ -7,13 +7,20 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/core
*/ */
namespace Sleepy\Core; namespace Sleepy\Core;
/** /**
* Class for accessing request data * Class for accessing request data
*
* @method array server()
* @method array env()
* @method array get()
* @method array post()
* @method array put()
* @method array delete()
* @method array cookie()
*/ */
class Input { class Input {
@ -42,6 +49,13 @@ class Input {
*/ */
protected $delete = []; protected $delete = [];
/**
* Class member for options data
*
* @var array
*/
protected $options = [];
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Working around PHP for nicer usability // ! Working around PHP for nicer usability
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -82,12 +96,13 @@ class Input {
$this->verb = \strtolower($_SERVER['REQUEST_METHOD']); $this->verb = \strtolower($_SERVER['REQUEST_METHOD']);
// Parse put and delete requests into input variables // Parse put and delete requests into input variables
// @codeCoverageIgnoreStart
if (isset($this->{$this->verb})) if (isset($this->{$this->verb}))
{ {
$raw = \file_get_contents('php://input'); $raw = \file_get_contents('php://input');
\parse_str($raw, $this->{$this->verb}); \parse_str($raw, $this->{$this->verb});
} }
// Set mapping for superglobals, since // Set mapping for superglobals, since
// variable variables don't seem to work // variable variables don't seem to work
// with superglobals :/ // with superglobals :/
@ -98,13 +113,17 @@ class Input {
'env' => $_ENV, 'env' => $_ENV,
'cookie' => $_COOKIE 'cookie' => $_COOKIE
]; ];
// @codeCoverageIgnoreEnd
// Parse request headers from $_SERVER // Parse request headers from $_SERVER
foreach($_SERVER as $key => $val) foreach($_SERVER as $key => $val)
{ {
if (strpos($key, 'HTTP_') === 0) if (strpos($key, 'HTTP_') === 0)
{ {
$new_key = strtolower(str_replace('HTTP_', '', $key)); $new_key = \strtolower(\strtr($key, [
'HTTP_' => '',
'_' => '-'
]));
$this->request_headers[$new_key] = $val; $this->request_headers[$new_key] = $val;
} }
} }
@ -119,7 +138,7 @@ class Input {
* @param string $name - name of input array * @param string $name - name of input array
* @param array $args - function arguments * @param array $args - function arguments
* @return mixed * @return mixed
* @throws DomainException * @throws \DomainException
*/ */
public function __call($name, $args=[]) public function __call($name, $args=[])
{ {
@ -134,11 +153,12 @@ class Input {
// Get a superglobal ($_VAR) value // Get a superglobal ($_VAR) value
return $this->get_superglobal_var($name, $index, $filter); return $this->get_superglobal_var($name, $index, $filter);
} }
else if(isset($this->$name)) else if(isset($this->$name)) // @codeCoverageIgnoreStart
{ {
// Get a input variable not in a superglobal (eg. PUT/DELETE) // Get a input variable not in a superglobal (eg. PUT/DELETE)
return $this->get_request_var($name, $index, $filter); return $this->get_request_var($name, $index, $filter);
} }
// @codeCoverageIgnoreEnd
// What kind of request are you trying to make?! // What kind of request are you trying to make?!
throw new \DomainException('Invalid input array.'); throw new \DomainException('Invalid input array.');
@ -154,7 +174,7 @@ class Input {
{ {
if ($index !== NULL) if ($index !== NULL)
{ {
$index = (str_replace([' ', '-'], '_', $index)); $index = (\strtolower(\str_replace([' ', '_'], '-', $index)));
if (isset($this->request_headers[$index])) if (isset($this->request_headers[$index]))
{ {
@ -209,7 +229,7 @@ class Input {
$has_eq = strpos($value, '=') !== FALSE; $has_eq = strpos($value, '=') !== FALSE;
// Parse the user agent separately // Parse the user agent separately
if ($header === 'user_agent') if ($header === 'user-agent')
{ {
$this->parsed_headers[$header] = $this->parse_user_agent($value); $this->parsed_headers[$header] = $this->parse_user_agent($value);
continue; continue;
@ -231,21 +251,6 @@ class Input {
parse_str($value, $this->parsed_headers[$header]); parse_str($value, $this->parsed_headers[$header]);
continue; continue;
} }
// For headers with commas and semicolons, break first on commas,
// then on semicolons
else if ($has_semi && $has_comma)
{
$values = explode(",", $value);
foreach($values as &$v)
{
if (strpos($v, ";") !== FALSE)
{
$v = explode(";", $v);
}
}
$this->parsed_headers[$header] = $values;
}
// Anything else, just leave it as a string // Anything else, just leave it as a string
else else
{ {
@ -308,29 +313,48 @@ class Input {
*/ */
protected function parse_accept_header($value) protected function parse_accept_header($value)
{ {
$q_types = [];
// A fake value so I can shift it off to have a 1-indexed array
$high_types = [];
$output = []; $output = [];
$index = 0; $count = 1;
// Split into segments of different values // Split into segments of different values
$groups = explode(',', $value); $groups = explode(',', $value);
foreach($groups as $group) foreach($groups as $group)
{ {
$group = \trim($group);
$pair = explode(';q=', $group); $pair = explode(';q=', $group);
if (count($pair) === 2) if (count($pair) === 2)
{ {
list($val, $q) = $pair; list($val, $q) = $pair;
$output[$q] = $val; $q_types[$q] = $val;
} }
else else
{ {
$index++; $high_types[$count] = current($pair);
$output[$index] = current($pair); $count++;
} }
} }
ksort($output, SORT_NATURAL); // Add an additional fake value so we can
// have a 1-indexed array
$high_types[$count] = 'foo';
$high_types = array_reverse($high_types);
unset($high_types[0]);
$output = $q_types;
// Merge the arrays manually to maintain
// keys, and thus ordering
foreach($high_types as $k => $v)
{
$output[$k] = $v;
}
krsort($output, SORT_NUMERIC);
return $output; return $output;
} }
@ -338,6 +362,7 @@ class Input {
/** /**
* Get input var(s) from non-defined superglobal * Get input var(s) from non-defined superglobal
* *
* @codeCoverageIgnore
* @param string $type - input array * @param string $type - input array
* @param string $index - variable in the input array * @param string $index - variable in the input array
* @param int $filter - PHP filter_var flag * @param int $filter - PHP filter_var flag

View File

@ -7,15 +7,14 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/core
*/ */
namespace Sleepy\core; namespace Sleepy\Core\Interfaces;
/** /**
* Interface for output formats * Interface for output formats
*/ */
interface iType { interface Type {
/** /**
* Convert the data to the output format * Convert the data to the output format
@ -34,4 +33,4 @@ interface iType {
public function unserialize($data_string); public function unserialize($data_string);
} }
// End of core/iType.php // End of Core/Interfaces/Type.php

View File

@ -7,10 +7,9 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/core
*/ */
namespace Sleepy\core; namespace Sleepy\Core;
/** /**
* Default output class * Default output class
@ -34,16 +33,23 @@ class Output {
/** /**
* The serialization object for the current data type * The serialization object for the current data type
* *
* @var Sleepy\core\aType * @var Sleepy\Core\aType
*/ */
protected $type_wrapper; protected $type_wrapper;
/** /**
* The input object * The input object
* *
* @var Sleepy\core\Input * @var Sleepy\Core\Input
*/ */
protected $input; protected $input;
/**
* Config object
*
* @var Sleepy\Core\Config;
*/
protected $config;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Methods // ! Methods
@ -52,10 +58,12 @@ class Output {
/** /**
* Create the output object * Create the output object
* *
* @param array $config * @param Config $config
* @param Input $input
*/ */
public function __construct(Input $input) public function __construct(Config $config, Input $input)
{ {
$this->config = $config;
$this->input = $input; $this->input = $input;
} }
@ -92,15 +100,23 @@ class Output {
/** /**
* Set the data to be output to the endpoint * Set the data to be output to the endpoint
* *
* @param string $type - The datatype to send * @param string $type - The data format to send
* @param mixed $data * @param mixed $data - The data to send
* @return void * @return void
*/ */
public function set_data($type = 'json', $data) public function set_data($type = 'html', $data = NULL)
{ {
if (is_null($data) && ! empty($this->data))
{
$data = $this->data;
}
// Set instance data
$this->data = $data;
// Get the appropriate output format for the client // Get the appropriate output format for the client
// And set the data // And set the data
$this->get_accepted_type($type, $data); $this->get_accepted_type($type, $this->data);
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -135,16 +151,32 @@ class Output {
$type_map[$mime] = $type_class; $type_map[$mime] = $type_class;
} }
foreach($accept as $type => $q) // Order type preference first by
// input, then by accept flags
foreach($type_map as $type => $obj)
{ {
if (array_key_exists($type, $type_map)) if (\array_key_exists($type, $accept))
{ {
$accepted[$q] = $type; $q = $accept[$type];
if ($q >= 1)
{
$accepted[] = $type;
}
else
{
$accepted[$q] = $type;
}
} }
} }
krsort($accepted); // Default to html fow wildcard accept values
if (empty($accepted) && \array_key_exists('*/*', $accept))
{
$accepted[1] = 'text/html';
}
// Use the first output type to output the data
$class = $type_map[current($accepted)]; $class = $type_map[current($accepted)];
$this->type_wrapper = $classes[$class]; $this->type_wrapper = $classes[$class];
@ -178,4 +210,4 @@ class Output {
} }
} }
} }
// End of core/Output.php // End of Core/Output.php

View File

@ -7,7 +7,6 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/core
*/ */
namespace Sleepy\Core; namespace Sleepy\Core;

View File

@ -7,7 +7,6 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/exceptions
*/ */
namespace Sleepy\Exception; namespace Sleepy\Exception;

52
Sleepy/Traits/getSet.php Normal file
View File

@ -0,0 +1,52 @@
<?php
/**
* Sleepy - a REST framework
*
*
* A PHP Rest Framework valuing convention over configuration,
* but aiming to be as flexible as possible
*
* @author Timothy J. Warren
*/
namespace Sleepy\Traits;
/**
* Trait to get rid of naive getter/setter boilerplate
*/
trait GetSet
{
/**
* Dynamically create getters/setters
*
* @param string $func
* @param array $args
* @return mixed
*/
public function __call($func, $args)
{
$type = substr($func, 0, 3);
$val = strtolower(substr($func, 3));
$valid_types = array(
'get' => 'get',
'set' => 'set'
);
if ( ! property_exists($this, $val) || ! isset($valid_types[$type]))
{
return NULL;
}
// Auto-magical getters and setters
if ($type === 'get')
{
return $this->$val;
}
elseif ($type === 'set')
{
$this->$val = current($args);
}
}
}
// End of GetSet.php

View File

@ -7,12 +7,11 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/types
*/ */
namespace Sleepy\Type; namespace Sleepy\Type;
use Sleepy\Core\aType; use \Sleepy\Core\Abstracts\Type as aType;
/** /**
* Class for HTML output * Class for HTML output
@ -34,14 +33,7 @@ class HTML extends aType {
*/ */
public function serialize($data = NULL) public function serialize($data = NULL)
{ {
if ( ! is_null($data)) $this->set_data($data);
{
$this->data = $data;
}
else
{
$data = $this->data;
}
if (is_string($data)) return $data; if (is_string($data)) return $data;
@ -62,19 +54,4 @@ class HTML extends aType {
} }
// --------------------------------------------------------------------------
// ! Helper function
// --------------------------------------------------------------------------
/**
* Function to simplify type instantiation
*
* @param mixed $data
* @return JSON
*/
function HTML($data = NULL)
{
return new JSON($data);
}
// End of types/JSON.php // End of types/JSON.php

View File

@ -7,12 +7,11 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/types
*/ */
namespace Sleepy\Type; namespace Sleepy\Type;
use Sleepy\Core\aType; use \Sleepy\Core\Abstracts\Type as aType;
/** /**
* Class for JSON output * Class for JSON output
@ -34,15 +33,7 @@ class JSON extends aType {
*/ */
public function serialize($data = NULL) public function serialize($data = NULL)
{ {
if ( ! is_null($data)) $this->set_data($data);
{
$this->data = $data;
}
else
{
$data = $this->data;
}
return json_encode($data, JSON_PRETTY_PRINT); return json_encode($data, JSON_PRETTY_PRINT);
} }
@ -59,19 +50,4 @@ class JSON extends aType {
} }
// --------------------------------------------------------------------------
// ! Helper function
// --------------------------------------------------------------------------
/**
* Function to simplify type instantiation
*
* @param mixed $data
* @return JSON
*/
function JSON($data = NULL)
{
return new JSON($data);
}
// End of types/JSON.php // End of types/JSON.php

100
Sleepy/Type/XML.php Normal file
View File

@ -0,0 +1,100 @@
<?php
/**
* Sleepy - a REST framework
*
*
* A PHP Rest Framework valuing convention over configuration,
* but aiming to be as flexible as possible
*
* @author Timothy J. Warren
*/
namespace Sleepy\Type;
use \Sleepy\Core\Abstracts\Type as aType;
/**
* Implementation of XML data type
*/
class XML extends aType {
/**
* The mime type for output
*
* @var string
*/
protected $mime = 'application/xml';
/**
* Convert php array/object to xml
*
* @param array|object $data
* @return string
*/
public function serialize($data = NULL)
{
$this->set_data($data);
$xmlObject = new \SimpleXMLElement('<?xml version="1.0"?><root></root>');
$this->array_to_xml($data, $xmlObject);
return $xmlObject->asXML();
}
/**
* Convert xml to php data
*
* @param string $string
* @return object
*/
public function unserialize($string)
{
$xml = \simplexml_load_string($string);
$json = json_encode($xml);
$object = json_decode($json);
return $object;
}
/**
* Recursively generate xml from an array or object
*
* @param array|object $array
* @param \SimpleXMLElement $xmlObject
*/
private function array_to_xml($array, \SimpleXMLElement &$xmlObject)
{
foreach($array as $key => $val)
{
$key = $this->fix_xml_key($key);
if ( ! is_scalar($val))
{
$subnode = $xmlObject->addChild($key);
$this->array_to_xml($val, $subnode);
}
else
{
$xmlObject->addChild($key, \htmlspecialchars($val, ENT_XML1, 'UTF-8'));
}
}
}
/**
* Make an invalid xml key more valid
*
* @param string $key
* @return string
*/
private function fix_xml_key($key)
{
if (is_numeric($key))
{
$key = "item_{$key}";
}
return preg_replace('`[^a-zA-Z0-9_:]`', '_', $key);
}
}
// End of Type/XML.php

View File

@ -7,16 +7,15 @@
* but aiming to be as flexible as possible * but aiming to be as flexible as possible
* *
* @author Timothy J. Warren * @author Timothy J. Warren
* @package Sleepy/types
*/ */
namespace Sleepy\types; namespace Sleepy\Type;
use Sleepy\core\aType; use \Sleepy\Core\Abstracts\Type as aType;
use Symfony\Component\Yaml as YML; use Symfony\Component\Yaml\Yaml as YML;
/** /**
* Class for YAML output * Class for YAML output
*/ */
class YAML extends aType { class YAML extends aType {
@ -26,7 +25,7 @@ class YAML extends aType {
* @var string * @var string
*/ */
protected $mime = 'text/yaml'; protected $mime = 'text/yaml';
/** /**
* Convert the data into the output format * Convert the data into the output format
* *
@ -35,21 +34,14 @@ class YAML extends aType {
*/ */
public function serialize($data = null) public function serialize($data = null)
{ {
if ( ! is_null($data)) $this->set_data($data);
{
$this->data = $data;
}
else
{
$data = $this->data;
}
// Yaml class doesn't support objects, cast them to arrays // Yaml class doesn't support objects, cast them to arrays
$data = (array) $data; $data = (array) $data;
return YML::dump($data); return YML::dump($data);
} }
/** /**
* Convert the encoded data to a native format * Convert the encoded data to a native format
* *

40
Sleepy/autoload.php Normal file
View File

@ -0,0 +1,40 @@
<?php
/**
* Sleepy - a REST framework
*
*
* A PHP Rest Framework valuing convention over configuration,
* but aiming to be as flexible as possible
*
* @author Timothy J. Warren
* @package Sleepy
*/
namespace Sleepy;
/**
* Autoloader
*/
\spl_autoload_register(function($item) {
$path_items = \explode('\\', \ltrim($item, '\\'));
// If the namespace is a straight mapping to the class, just load it
$simple_path = \implode('/', $path_items);
$file = BASEPATH . "{$simple_path}.php";
if (file_exists($file))
{
require_once($file);
return;
}
// Check the application folder
$file = str_replace(SLEEPY_DIR, APP_DIR, $file);
if (file_exists($file))
{
require_once($file);
return;
}
});
// End of autoload.php

View File

@ -10,7 +10,7 @@
* @package Sleepy * @package Sleepy
*/ */
$config = [ return [
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// The default format of data to be sent. Can be overwritten in controllers // The default format of data to be sent. Can be overwritten in controllers

View File

@ -10,14 +10,13 @@
* @package Sleepy * @package Sleepy
*/ */
$routes = [ return [
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// The index controller, called if not specified in the routes or url // The index controller, called if not specified in the routes or url
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
'default_controller' => 'index', 'default_controller' => 'index',
]; ];
// End of config/routes.php // End of config/routes.php

View File

@ -0,0 +1,26 @@
<?php
/**
* Sleepy - a REST framework
*
*
* A PHP Rest Framework valuing convention over configuration,
* but aiming to be as flexible as possible
*
* @author Timothy J. Warren
* @package Sleepy
*/
return [
// --------------------------------------------------------------------------
// Map mime types to type classes
// --------------------------------------------------------------------------
'application/json' => 'JSON',
'text/yaml' => 'YAML',
'application/yaml' => 'YAML',
'text/html' => 'HTML',
'application/xhtml+xml' => 'HTML',
'*/*' => 'HTML'
];
// End of config/type_class_map.php

View File

@ -9,6 +9,9 @@
"phpunit/phpunit":"3.7.*" "phpunit/phpunit":"3.7.*"
}, },
"require": { "require": {
"symfony/yaml": "2.4.*",
"aura/router": "2.0.*@dev",
"aura/di": "2.0.*@dev",
"php": ">=5.4.0" "php": ">=5.4.0"
} }
} }

View File

@ -10,41 +10,36 @@
* @package Sleepy * @package Sleepy
*/ */
namespace Sleepy; namespace Sleepy\Core;
// Include namespaces
use Aura\Di\Container as DiContainer;
use Aura\Di\Factory as DiFactory;
use Aura\Router\RouterFactory;
define('BASEPATH', __DIR__ . '/'); define('BASEPATH', __DIR__ . '/');
define('SLEEPY_DIR', 'Sleepy');
define('APP_DIR', 'application');
define('APPPATH', __DIR__ . '/application/'); define('APPPATH', __DIR__ . '/application/');
\spl_autoload_register(function($item) { // Include 3rd party dependencies
$path_items = \explode('\\', \ltrim($item, '\\')); include BASEPATH . '/vendor/autoload.php';
// If the namespace is a straight mapping to the class, just load it // Load the autoloader
$simple_path = \implode('/', $path_items); require BASEPATH . SLEEPY_DIR . '/autoload.php';
$file = BASEPATH . "{$simple_path}.php";
if (file_exists($file))
{
require_once($file);
return;
}
// Check the application folder $di = new DiContainer(new DiFactory());
$file = str_replace("Sleepy", 'application', $file); $di->set('config', new Config());
if (file_exists($file)) $di->set('input', new Input());
{ $di->set('output', new Output($di->get('config'), $di->get('input')));
require_once($file);
return;
}
});
$i = new \Sleepy\Core\Input(); $browser->browser_name_regex = \utf8_encode($browser->browser_name_regex);
$o = new \Sleepy\Core\Output($i); $di->get('output')->set_data(['json','yaml','html'], [
$browser = \get_browser(NULL);
$browser->browser_name_regex = utf8_encode($browser->browser_name_regex);
$o->set_data(['json','html'], [
'$_SERVER' => $i->server(), '$_SERVER' => $i->server(),
'$_GET' => $i->get(), '$_GET' => $i->get(),
'$_POST' => $i->post(), '$_POST' => $i->post(),
'$_PUT' => $i->put(),
'$_DELETE' => $i->delete(),
'$_ENV' => $i->env(), '$_ENV' => $i->env(),
'$_COOKIE' => $i->cookie(), '$_COOKIE' => $i->cookie(),
'browser' => $browser, 'browser' => $browser,

View File

@ -1,27 +1,18 @@
<?php <?php
define('BASEPATH', realpath('../Sleepy/').'/'); // Use the same autoloader as the app for consistency
define('SPATH', realpath('../').'/'); define('BASEPATH', '../');
define('SLEEPY_DIR', 'Sleepy');
define('APP_DIR', 'application');
define('APPPATH', BASEPATH . 'application/');
include BASEPATH . '/vendor/autoload.php';
require BASEPATH . SLEEPY_DIR . '/autoload.php';
/** /**
* Autoloader for Sleepy * Base testcase class
*/ */
\spl_autoload_register(function($item) {
$path_items = \explode('\\', \ltrim($item, '\\'));
// If the namespace is a straight mapping to the class, just load it
$simple_path = \implode('/', $path_items);
$file = SPATH . "{$simple_path}.php";
if (file_exists($file))
{
require_once($file);
return;
}
});
class Sleepy_TestCase extends PHPUnit_Framework_TestCase { class Sleepy_TestCase extends PHPUnit_Framework_TestCase {
public function setUp() public function setUp()
{ {
if ( ! isset($_SERVER['REQUEST_METHOD'])) if ( ! isset($_SERVER['REQUEST_METHOD']))

View File

@ -1,7 +1,5 @@
<?php <?php
require_once(BASEPATH . 'core/Input.php');
class InputTest extends Sleepy_TestCase { class InputTest extends Sleepy_TestCase {
public function setUp() public function setUp()
@ -32,7 +30,7 @@ class InputTest extends Sleepy_TestCase {
'tisket' => 'tasket' 'tisket' => 'tasket'
]; ];
$this->input = new Sleepy\core\Input(); $this->input = new Sleepy\Core\Input();
} }
public function dataTestHeader() public function dataTestHeader()
@ -41,7 +39,7 @@ class InputTest extends Sleepy_TestCase {
'all' => [ 'all' => [
'index' => NULL, 'index' => NULL,
'expected' => [ 'expected' => [
'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36 OPR/18.0.1284.49', 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36 OPR/18.0.1284.49',
'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'cookie' => 'thp_tcms_session_id=9h4nvk15tjjegbeg8uvejncc9blkd81m', 'cookie' => 'thp_tcms_session_id=9h4nvk15tjjegbeg8uvejncc9blkd81m',
'host' => 'www.example.com', 'host' => 'www.example.com',
@ -65,7 +63,7 @@ class InputTest extends Sleepy_TestCase {
'all' => [ 'all' => [
'index' => NULL, 'index' => NULL,
'expected' => [ 'expected' => [
'user_agent' => [ 'user-agent' => [
'versions' => [ 'versions' => [
'Mozilla' => '5.0', 'Mozilla' => '5.0',
'AppleWebKit' => '537.36', 'AppleWebKit' => '537.36',
@ -80,10 +78,10 @@ class InputTest extends Sleepy_TestCase {
'misc' => 'KHTML, like Gecko' 'misc' => 'KHTML, like Gecko'
], ],
'accept' => [ 'accept' => [
'text/html', '0.8' => '*/*',
'application/xhtml+xml', '0.9' => 'application/xml',
['application/xml', 'q=0.9'], 1 => 'application/xhtml+xml',
['*/*', 'q=0.8'] 2 => 'text/html'
], ],
'cookie' => [ 'cookie' => [
'thp_tcms_session_id' => '9h4nvk15tjjegbeg8uvejncc9blkd81m' 'thp_tcms_session_id' => '9h4nvk15tjjegbeg8uvejncc9blkd81m'
@ -185,5 +183,15 @@ class InputTest extends Sleepy_TestCase {
$result = $this->input->get($index); $result = $this->input->get($index);
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
public function testBadVar()
{
try {
$foo = $this->input->applesauce();
}
catch (DomainException $e) {
$this->assertTrue(true);
}
}
} }
// End of InputTest.php // End of InputTest.php

28
tests/Core/OutputTest.php Normal file
View File

@ -0,0 +1,28 @@
<?php
use Sleepy\Core\Input;
use Sleepy\Core\Config;
use Sleepy\Core\Output;
class OutputTest extends Sleepy_Testcase {
protected $output;
public function setUp()
{
parent::setUp();
$c = new Config();
$i = new Input();
$this->output = new Output($c, $i);
}
public function testGetAcceptedType()
{
}
}
// End of OutputTest.php

View File

@ -1,17 +1,19 @@
<?php <?php
require_once(BASEPATH . 'core/iType.php'); use Sleepy\Core\Interfaces\Type as iType;
require_once(BASEPATH . 'core/aType.php'); use Sleepy\Core\Abstracts\Type as aType;
use Sleepy\core\iType;
use Sleepy\core\aType;
class aTypeTest extends Sleepy_TestCase { class aTypeTest extends Sleepy_TestCase {
public function testSanity() public function testSanity()
{ {
$this->assertEquals(['Sleepy\\core\\iType' => 'Sleepy\\core\\iType'], class_implements('Sleepy\\core\\aType')); $this->assertEquals(
['Sleepy\\Core\\Interfaces\\Type' => 'Sleepy\\Core\\Interfaces\\Type'],
class_implements('Sleepy\\Core\\Abstracts\\Type')
);
} }
} }
// End of aTypeTest.php // End of aTypeTest.php

View File

@ -1,41 +1,40 @@
<?php <?php
require_once(BASEPATH . 'core/iType.php'); use Sleepy\Type\JSON;
require_once(BASEPATH . 'core/aType.php');
require_once(BASEPATH . 'types/JSON.php');
use Sleepy\core;
use Sleepy\types\JSON;
use Sleepy\execeptions;
class MockJSON extends JSON { class MockJSON extends JSON {
protected $mime = ''; protected $mime = '';
} }
class JSONTest extends Sleepy_Testcase { class JSONTest extends Sleepy_Testcase {
public function setUp() { public function setUp() {
$this->JSON = new JSON([]); $this->JSON = new JSON(['foo'=>'bar']);
} }
public function testSanity() { public function testSanity() {
$this->assertTrue(is_a($this->JSON, 'Sleepy\\types\\JSON')); $this->assertTrue(is_a($this->JSON, 'Sleepy\\Type\\JSON'));
$this->assertTrue(is_a($this->JSON, 'Sleepy\\core\\aType')); $this->assertTrue(is_a($this->JSON, 'Sleepy\\Core\\Abstracts\\Type'));
$this->assertEquals(['Sleepy\\core\\iType' => 'Sleepy\\core\\iType'], class_implements('Sleepy\\types\\JSON')); $this->assertEquals(
['Sleepy\\Core\\Interfaces\\Type' => 'Sleepy\\Core\\Interfaces\\Type'],
class_implements('Sleepy\\Type\\JSON')
);
} }
public function testFunction()
public function testNIE() { public function testNIE() {
try { try {
$json = new MockJSON([]); $json = new MockJSON([]);
} }
catch (Sleepy\exceptions\NotImplementedException $e) { catch (Sleepy\Exception\NotImplementedException $e) {
$this->assertTrue(TRUE); $this->assertTrue(TRUE);
} }
} }
public function testGetMime()
{
$mime = $this->JSON->get_mime();
$this->assertEquals('application/json', $mime);
}
} }
// End of JSONTest // End of JSONTest

62
tests/Type/XMLTest.php Normal file
View File

@ -0,0 +1,62 @@
<?php
use Sleepy\Type\XML;
class MockXML extends XML {
protected $mime = '';
}
class XMLTest extends Sleepy_Testcase {
public function setUp() {
$test_array = [
'foo' => 'bar',
'baz' => [
0 => ['x' => 'y']
]
];
$this->XML = new XML($test_array);
}
public function testSanity() {
$this->assertTrue(is_a($this->XML, 'Sleepy\\Type\\XML'));
$this->assertTrue(is_a($this->XML, 'Sleepy\\Core\\Abstracts\\Type'));
$this->assertEquals(
['Sleepy\\Core\\Interfaces\\Type' => 'Sleepy\\Core\\Interfaces\\Type'],
class_implements('Sleepy\\Type\\XML')
);
}
public function testNIE() {
try {
$xml = new MockXML([]);
}
catch (Sleepy\Exception\NotImplementedException $e) {
$this->assertTrue(TRUE);
}
}
public function testSerialize()
{
$xml = $this->XML->serialize();
$xml_tostring = $this->XML->__toString();
$expected = '<?xml version="1.0"?>' .
"\n<root><foo>bar</foo><baz><item_0><x>y</x></item_0></baz></root>\n";
$this->assertEquals($expected, $xml);
$this->assertEquals($xml, $xml_tostring);
}
public function testUnSerialize()
{
$object = $this->XML->unserialize('<?xml version="1.0"?>' . "\n<root><foo>bar</foo></root>\n");
$expected = (object) ['foo' => 'bar'];
$this->assertEquals($expected, $object);
}
}
// End of XMLTest

View File

@ -11,12 +11,16 @@
stopOnSkipped="false"> stopOnSkipped="false">
<testsuites> <testsuites>
<testsuite name="Sleepy Core Test Suite"> <testsuite name="Sleepy Core Test Suite">
<directory suffix="Test.php">./core</directory> <directory suffix="Test.php">Core</directory>
<directory suffix="Test.php">./exceptions</directory> <directory suffix="Test.php">Exception</directory>
<directory suffix="Test.php">./types</directory> <directory suffix="Test.php">Type</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<filter> <filter>
<whitelist>
<directory>../../sleepy/Sleepy</directory>
<directory>../../sleepy/application</directory>
</whitelist>
<blacklist> <blacklist>
<directory suffix=".php">PEAR_INSTALL_DIR</directory> <directory suffix=".php">PEAR_INSTALL_DIR</directory>
<directory suffix=".php">PHP_LIBDIR</directory> <directory suffix=".php">PHP_LIBDIR</directory>