Initial Commit

This commit is contained in:
Timothy Warren 2014-05-07 14:05:13 -04:00
commit 4280489558
21 changed files with 1416 additions and 0 deletions

2
.gitignore vendored Executable file
View File

@ -0,0 +1,2 @@
vendor/*
coverage/*

391
Sleepy/Core/Input.php Executable file
View File

@ -0,0 +1,391 @@
<?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/core
*/
namespace Sleepy\Core;
/**
* Class for accessing request data
*/
class Input {
// --------------------------------------------------------------------------
// ! Stuff PHP Forgot
// --------------------------------------------------------------------------
/**
* The HTTP verb for the current request
*
* @var string
*/
protected $verb = 'get';
/**
* Class member for put data
*
* @var array
*/
protected $put = [];
/**
* Class member for delete data
*
* @var array
*/
protected $delete = [];
// --------------------------------------------------------------------------
// ! Working around PHP for nicer usability
// --------------------------------------------------------------------------
/**
* An array mapping the function to the appropriate superglobal
*
* @var array
*/
protected $var_map = [];
/**
* The request's HTTP headers from the $_SERVER superglobal
*
* @var array
*/
protected $request_headers = [];
/**
* The request headers parsed into a more useful array
*
* @var array
*/
protected $parsed_headers = [];
// --------------------------------------------------------------------------
// ! Methods
// --------------------------------------------------------------------------
/**
* Instantiates the class
*
* @param array $config
*/
public function __construct($config = [])
{
// Type of HTTP request
$this->verb = \strtolower($_SERVER['REQUEST_METHOD']);
// Parse put and delete requests into input variables
if (isset($this->{$this->verb}))
{
$raw = \file_get_contents('php://input');
\parse_str($raw, $this->{$this->verb});
}
// Set mapping for superglobals, since
// variable variables don't seem to work
// with superglobals :/
$this->var_map = [
'get' => $_GET,
'post' => $_POST,
'server' => $_SERVER,
'env' => $_ENV,
'cookie' => $_COOKIE
];
// Parse request headers from $_SERVER
foreach($_SERVER as $key => $val)
{
if (strpos($key, 'HTTP_') === 0)
{
$new_key = strtolower(str_replace('HTTP_', '', $key));
$this->request_headers[$new_key] = $val;
}
}
}
/**
* Wrapper method for input arrays
*
* Actually works as get,post,put,delete,cookie,server,and env functions
* all wrapped up in one - because boilerplate is bad!
*
* @param string $name - name of input array
* @param array $args - function arguments
* @return mixed
* @throws DomainException
*/
public function __call($name, $args=[])
{
// Predefine arguments for input array getters
if ( ! isset($args[0])) $args[0] = NULL;
if ( ! isset($args[1])) $args[1] = FILTER_SANITIZE_STRING;
$index = $args[0];
$filter = $args[1];
if (isset($this->var_map[$name]))
{
// Get a superglobal ($_VAR) value
return $this->get_superglobal_var($name, $index, $filter);
}
else if(isset($this->$name))
{
// Get a input variable not in a superglobal (eg. PUT/DELETE)
return $this->get_request_var($name, $index, $filter);
}
// What kind of request are you trying to make?!
throw new \DomainException('Invalid input array.');
}
/**
* Return header(s) sent from the request
*
* @param string $index
* @return mixed
*/
public function header($index = NULL)
{
if ($index !== NULL)
{
$index = (str_replace([' ', '-'], '_', $index));
if (isset($this->request_headers[$index]))
{
return $this->request_headers[$index];
}
return NULL;
}
return $this->request_headers;
}
/**
* Return parsed header(s) sent from the request
*
* @param string $index
* @return mixed
*/
public function header_array($index = NULL)
{
if (empty($this->parsed_headers))
{
$this->parsed_headers = $this->parse_headers();
}
if ($index !== NULL)
{
$index = (str_replace([' ', '-'], '_', $index));
if (isset($this->parsed_headers[$index]))
{
return $this->parsed_headers[$index];
}
return NULL;
}
return $this->parsed_headers;
}
/**
* Convert headers to a parsed array of values
*
* @return array
*/
protected function parse_headers()
{
foreach($this->request_headers as $header => $value)
{
$has_semi = strpos($value, ';') !== FALSE;
$has_comma = strpos($value, ',') !== FALSE;
$has_eq = strpos($value, '=') !== FALSE;
// Parse the user agent separately
if ($header === 'user_agent')
{
$this->parsed_headers[$header] = $this->parse_user_agent($value);
continue;
}
// Parse accept-type headers separately as well
else if (strpos($header, 'accept') === 0)
{
$this->parsed_headers[$header] = $this->parse_accept_header($value);
}
// If the header has a comma, and not a semicolon, split on the comma
else if ( ! $has_semi && $has_comma)
{
$this->parsed_headers[$header] = explode(",", $value);
continue;
}
// Parse cookies and other headers with values like query strings
else if ($has_eq && ! $has_semi)
{
parse_str($value, $this->parsed_headers[$header]);
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
else
{
$this->parsed_headers[$header] = $value;
continue;
}
}
return $this->parsed_headers;
}
/**
* Parse a browser useragent into a set of useful key-value pairs
*
* @param string $ua_string
* @return array
*/
protected function parse_user_agent($ua_string)
{
$user_agent = [];
$slash_matches = [];
$slash_pattern = "`[A-Z]+/[0-9]+((\.[0-9]+)+)?`i";
$paren_matches = [];
$paren_pattern = "`\(.*?\)`i";
// Get all the foo/12.3 paterns from the user agent string
preg_match_all($slash_pattern, $ua_string, $slash_matches);
foreach($slash_matches[0] as $arr)
{
list($key, $version) = explode("/", $arr);
$user_agent['versions'][$key] = $version;
}
// Get all the info from parenthasized items
preg_match_all($paren_pattern, $ua_string, $paren_matches);
foreach($paren_matches[0] as $arr)
{
$arr = str_replace(['(',')'], '', $arr);
if (strpos($arr, ';') !== FALSE)
{
$user_agent['os'] = explode('; ', $arr);
}
else
{
$user_agent['misc'] = $arr;
}
}
return $user_agent;
}
/**
* Parse an accept-type header into an ordered list
* of values
*
* @param string $value
* @return array
*/
protected function parse_accept_header($value)
{
$output = [];
$index = 0;
// Split into segments of different values
$groups = explode(',', $value);
foreach($groups as $group)
{
$pair = explode(';q=', $group);
if (count($pair) === 2)
{
list($val, $q) = $pair;
$output[$q] = $val;
}
else
{
$index++;
$output[$index] = current($pair);
}
}
ksort($output, SORT_NATURAL);
return $output;
}
/**
* Get input var(s) from non-defined superglobal
*
* @param string $type - input array
* @param string $index - variable in the input array
* @param int $filter - PHP filter_var flag
* @return mixed
*/
protected function get_request_var($type, $index=NULL, $filter=FILTER_SANITIZE_STRING)
{
// If index is null, return the whole array
if ($index === NULL)
{
return ($filter !== NULL) ? \filter_var_array($this->$type, $filter) : $this->$type;
}
// Prevent errors for non-existant variables
if ( ! isset($this->$type[$index]))
{
return NULL;
}
return ($filter !== NULL) ? \filter_var($this->$type[$index], $filter) : $this->$type[$index];
}
/**
* Get index from superglobal
*
* @param string $type - superglobal
* @param string $index - variable in the superglobal
* @param int $filter - PHP filter_var flag
* @return mixed
*/
protected function get_superglobal_var($type, $index=NULL, $filter=FILTER_SANITIZE_STRING)
{
$var =& $this->var_map[$type];
// Return the whole array if the index is null
if ($index === NULL)
{
return ($filter !== NULL) ? \filter_var_array($var, $filter) : $var;
}
// Prevent errors for non-existant variables
if ( ! isset($var[$index]))
{
return NULL;
}
return ($filter !== NULL) ? \filter_var($var[$index], $filter) : $var[$index];
}
}
// End of core/Input.php

181
Sleepy/Core/Output.php Executable file
View File

@ -0,0 +1,181 @@
<?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/core
*/
namespace Sleepy\core;
/**
* Default output class
*/
class Output {
/**
* The data to serialize and output
*
* @var mixed
*/
protected $data;
/**
* A list of HTTP headers to send with a response
*
* @var array
*/
protected $headers = [];
/**
* The serialization object for the current data type
*
* @var Sleepy\core\aType
*/
protected $type_wrapper;
/**
* The input object
*
* @var Sleepy\core\Input
*/
protected $input;
// --------------------------------------------------------------------------
// ! Methods
// --------------------------------------------------------------------------
/**
* Create the output object
*
* @param array $config
*/
public function __construct(Input $input)
{
$this->input = $input;
}
/**
* Output the data to the client
*/
public function __destruct()
{
// Output the headers
$this->_output_headers();
// Echo the response
echo $this->type_wrapper;
}
/**
* Add a header to be output
*
* @param mixed $header
* @return void
*/
public function set_header($header)
{
if (is_array($header))
{
array_merge($this->headers, $header);
}
else
{
$this->headers[] = $header;
}
}
/**
* Set the data to be output to the endpoint
*
* @param string $type - The datatype to send
* @param mixed $data
* @return void
*/
public function set_data($type = 'json', $data)
{
// Get the appropriate output format for the client
// And set the data
$this->get_accepted_type($type, $data);
}
// --------------------------------------------------------------------------
// ! Private helper methods
// --------------------------------------------------------------------------
/**
* Get the type more accepted for output
*
* @param mixed $types
* @param mixed $data
* @return void
*/
protected function get_accepted_type($types, $data)
{
$types = (array) $types;
$types = array_map('strtoupper', $types);
$headers = $this->input->header_array();
$accept = array_flip($headers['accept']);
$type_map = [];
$accepted = [];
$classes = [];
foreach($types as $t)
{
$type_class = "Sleepy\\Type\\{$t}";
$classes[$type_class] = new $type_class($data);
$mime = $classes[$type_class]->get_mime();
$type_map[$mime] = $type_class;
}
foreach($accept as $type => $q)
{
if (array_key_exists($type, $type_map))
{
$accepted[$q] = $type;
}
}
krsort($accepted);
$class = $type_map[current($accepted)];
$this->type_wrapper = $classes[$class];
// Make sure to set the content-type header
if (empty($this->headers))
{
$mime = $this->type_wrapper->get_mime();
$this->set_header("Content-type: {$mime}");
}
}
/**
* Set the applicable response headers
*
* @return void
*/
protected function _output_headers()
{
foreach($this->headers as $name => $val)
{
if (is_numeric($name))
{
$output_header = $val;
}
else
{
$output_header = implode(": ", [$name, $val]);
}
@header($output_header);
}
}
}
// End of core/Output.php

26
Sleepy/Core/Router.php Executable file
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/core
*/
namespace Sleepy\Core;
class Router {
protected $class;
protected $method;
public function __construct($config = [])
{
}
}
// End of core/Router.php

78
Sleepy/Core/aType.php Executable file
View File

@ -0,0 +1,78 @@
<?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/core
*/
namespace Sleepy\Core;
use Sleepy\Exception\NotImplementedException;
/**
* Abstract class with helpful functionality implementing type functionality
*/
abstract class aType implements iType {
/**
* The data in the current type wrapper
*
* @var mixed
*/
protected $data;
/**
* The mime type to output for the current type
*
* @var string
*/
protected $mime;
/**
* Create the type object with the specified data
*
* @param mixed $data
* @throws NotImplementedException
*/
public function __construct($data = NULL)
{
if (empty($this->mime))
{
throw new NotImplementedException("Output types must have a mime type defined.");
}
if ( ! is_null($data))
{
$this->data = $data;
}
}
/**
* Returns the mime type needed
* for the current type
*
* @return string
*/
public function get_mime()
{
return $this->mime;
}
/**
* Output the data as a string
*
* @return string
*/
public function __toString()
{
return $this->serialize($this->data);
}
}
// End of core/aType.php

37
Sleepy/Core/iType.php Executable file
View File

@ -0,0 +1,37 @@
<?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/core
*/
namespace Sleepy\core;
/**
* Interface for output formats
*/
interface iType {
/**
* Convert the data to the output format
*
* @param mixed $data
* @return string
*/
public function serialize($data);
/**
* Convert the format to php data
*
* @param string $data_string
* @return mixed
*/
public function unserialize($data_string);
}
// End of core/iType.php

View File

@ -0,0 +1,33 @@
<?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/exceptions
*/
namespace Sleepy\Exception;
/**
* Exception for enforcing properties that need to be defined,
* or covering methods that are not yet implemented.
*/
class NotImplementedException extends \LogicException {
/**
* Have a default message for the exception
*
* @param string $message - The exception message
*/
public function __construct($message = "Hmm...you stumbled onto something that is not implemented.")
{
parent::__construct($message);
}
};
// End of exceptions/NotImplementedException.php

80
Sleepy/Type/HTML.php Normal file
View File

@ -0,0 +1,80 @@
<?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/types
*/
namespace Sleepy\Type;
use Sleepy\Core\aType;
/**
* Class for HTML output
*/
class HTML extends aType {
/**
* The mime type for output
*
* @var string
*/
protected $mime = 'text/html';
/**
* Convert the data into the output format
*
* @param mixed $data
* @return string
*/
public function serialize($data = NULL)
{
if ( ! is_null($data))
{
$this->data = $data;
}
else
{
$data = $this->data;
}
if (is_string($data)) return $data;
// Lets use JSON as an output format if the value isn't scalar
return '<pre>' . json_encode($data, JSON_PRETTY_PRINT) . '</pre>';
}
/**
* Convert the encoded data to a native format
*
* @param string $data_string
* @return object
*/
public function unserialize($data_string)
{
return NULL;
}
}
// --------------------------------------------------------------------------
// ! 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

77
Sleepy/Type/JSON.php Executable file
View File

@ -0,0 +1,77 @@
<?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/types
*/
namespace Sleepy\Type;
use Sleepy\Core\aType;
/**
* Class for JSON output
*/
class JSON extends aType {
/**
* The mime type for output
*
* @var string
*/
protected $mime = 'application/json';
/**
* Convert the data into the output format
*
* @param mixed $data
* @return string
*/
public function serialize($data = NULL)
{
if ( ! is_null($data))
{
$this->data = $data;
}
else
{
$data = $this->data;
}
return json_encode($data, JSON_PRETTY_PRINT);
}
/**
* Convert the encoded data to a native format
*
* @param string $data_string
* @return object
*/
public function unserialize($data_string)
{
return json_decode($data_string);
}
}
// --------------------------------------------------------------------------
// ! 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

64
Sleepy/Type/YAML.php Executable file
View File

@ -0,0 +1,64 @@
<?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/types
*/
namespace Sleepy\types;
use Sleepy\core\aType;
use Symfony\Component\Yaml as YML;
/**
* Class for YAML output
*/
class YAML extends aType {
/**
* The mime type for output
*
* @var string
*/
protected $mime = 'text/yaml';
/**
* Convert the data into the output format
*
* @param mixed $data
* @return string
*/
public function serialize($data = null)
{
if ( ! is_null($data))
{
$this->data = $data;
}
else
{
$data = $this->data;
}
// Yaml class doesn't support objects, cast them to arrays
$data = (array) $data;
return YML::dump($data);
}
/**
* Convert the encoded data to a native format
*
* @param string $data_string
* @return object
*/
public function unserialize($data_string)
{
return YML::parse($data_string, FALSE, TRUE);
}
}
// End of types/YAML.php

28
application/config/general.php Executable file
View File

@ -0,0 +1,28 @@
<?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
*/
$config = [
// --------------------------------------------------------------------------
// The default format of data to be sent. Can be overwritten in controllers
// --------------------------------------------------------------------------
'default_output_format' => 'json',
// --------------------------------------------------------------------------
// The default format of data recieved. Can be form data or one of the
// types defined in either the application/types or Sleepy/types folders
// --------------------------------------------------------------------------
'default_input_format' => 'json',
];
// End of config/general.php

23
application/config/routes.php Executable file
View File

@ -0,0 +1,23 @@
<?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
*/
$routes = [
// --------------------------------------------------------------------------
// The index controller, called if not specified in the routes or url
// --------------------------------------------------------------------------
'default_controller' => 'index',
];
// End of config/routes.php

0
application/types/index.html Executable file
View File

14
composer.json Executable file
View File

@ -0,0 +1,14 @@
{
"authors": [{
"name": "Timothy J. Warren",
"email": "tim@timshomepage.net",
"homepage": "https://timshomepage.net",
"role": "Developer"
}],
"require-dev": {
"phpunit/phpunit":"3.7.*"
},
"require": {
"php": ">=5.4.0"
}
}

55
index.php Executable file
View File

@ -0,0 +1,55 @@
<?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;
define('BASEPATH', __DIR__ . '/');
define('APPPATH', __DIR__ . '/application/');
\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", 'application', $file);
if (file_exists($file))
{
require_once($file);
return;
}
});
$i = new \Sleepy\Core\Input();
$o = new \Sleepy\Core\Output($i);
$browser = \get_browser(NULL);
$browser->browser_name_regex = utf8_encode($browser->browser_name_regex);
$o->set_data(['json','html'], [
'$_SERVER' => $i->server(),
'$_GET' => $i->get(),
'$_POST' => $i->post(),
'$_ENV' => $i->env(),
'$_COOKIE' => $i->cookie(),
'browser' => $browser,
'raw headers' => $i->header(),
'parsed headers' => $i->header_array()
]);
// End of index.php

22
phpdoc.dist.xml Executable file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<phpdoc>
<title>Sleepy</title>
<parser>
<target>docs</target>
</parser>
<transformer>
<target>docs</target>
</transformer>
<transformations>
<template name="responsive" />
</transformations>
<files>
<directory>.</directory>
<directory>tests</directory>
<directory>application</directory>
<directory>vendor</directory>
<ignore>tests/*</ignore>
<ignore>application/*</ignore>
<ignore>vendor/*</ignore>
</files>
</phpdoc>

32
tests/Bootstrap.php Executable file
View File

@ -0,0 +1,32 @@
<?php
define('BASEPATH', realpath('../Sleepy/').'/');
define('SPATH', realpath('../').'/');
/**
* Autoloader for Sleepy
*/
\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 {
public function setUp()
{
if ( ! isset($_SERVER['REQUEST_METHOD']))
{
$_SERVER['REQUEST_METHOD'] = 'GET';
}
}
}

189
tests/Core/InputTest.php Executable file
View File

@ -0,0 +1,189 @@
<?php
require_once(BASEPATH . 'core/Input.php');
class InputTest extends Sleepy_TestCase {
public function setUp()
{
parent::setUp();
// Set some http headers as test items
$_SERVER['HTTP_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';
$_SERVER['HTTP_ACCEPT'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
$_SERVER['HTTP_COOKIE'] = 'thp_tcms_session_id=9h4nvk15tjjegbeg8uvejncc9blkd81m';
$_SERVER['HTTP_HOST'] = 'www.example.com';
$_SERVER['HTTP_FOO'] = 'foo,bar';
// Set test $_COOKIE array
$_COOKIE = [
'thp_tcms_session_id' => '9h4nvk15tjjegbeg8uvejncc9blkd81m'
];
// Set test $_GET array
$_GET = [
'foo' => 'bar',
'baz' => 'foobar'
];
// Set test $_POST array
$_POST = [
'this' => 'that',
'tisket' => 'tasket'
];
$this->input = new Sleepy\core\Input();
}
public function dataTestHeader()
{
return [
'all' => [
'index' => NULL,
'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',
'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'cookie' => 'thp_tcms_session_id=9h4nvk15tjjegbeg8uvejncc9blkd81m',
'host' => 'www.example.com',
'foo' => 'foo,bar'
]
],
'index' => [
'index' => 'cookie',
'expected' => 'thp_tcms_session_id=9h4nvk15tjjegbeg8uvejncc9blkd81m'
],
'invalid' => [
'index' => 'boo',
'expected' => NULL
]
];
}
public function dataHeaderArray()
{
return [
'all' => [
'index' => NULL,
'expected' => [
'user_agent' => [
'versions' => [
'Mozilla' => '5.0',
'AppleWebKit' => '537.36',
'Chrome' => '31.0.1650.57',
'Safari' => '537.36',
'OPR' => '18.0.1284.49',
],
'os' => [
'Macintosh',
'Intel Mac OS X 10_9_0',
],
'misc' => 'KHTML, like Gecko'
],
'accept' => [
'text/html',
'application/xhtml+xml',
['application/xml', 'q=0.9'],
['*/*', 'q=0.8']
],
'cookie' => [
'thp_tcms_session_id' => '9h4nvk15tjjegbeg8uvejncc9blkd81m'
],
'host' => 'www.example.com',
'foo' => [
'foo',
'bar'
]
]
],
'index' => [
'index' => 'cookie',
'expected' => [
'thp_tcms_session_id' => '9h4nvk15tjjegbeg8uvejncc9blkd81m'
]
],
'invalid' => [
'index' => 'red',
'expected' => NULL
]
];
}
public function dataTestPost()
{
return [
'all' => [
'index' => NULL,
'expected' => [
'this' => 'that',
'tisket' => 'tasket'
]
],
'index' => [
'index' => 'this',
'expected' => 'that'
],
'invalid' => [
'index' => 'puppies',
'expected' => NULL
]
];
}
public function dataTestGet()
{
return [
'all' => [
'index' => NULL,
'expected' => [
'foo' => 'bar',
'baz' => 'foobar'
]
],
'index' => [
'index' => 'foo',
'expected' => 'bar'
],
'invalid' => [
'index' => 'applesauce',
'expected' => NULL
]
];
}
/**
* @dataProvider dataTestHeader
*/
public function testHeader($index, $expected)
{
$res = $this->input->header($index);
$this->assertEquals($expected, $res);
}
/**
* @dataProvider dataHeaderArray
*/
public function testHeaderArray($index, $expected)
{
$result = $this->input->header_array($index);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider dataTestPost
*/
public function testPost($index, $expected)
{
$result = $this->input->post($index);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider dataTestGet
*/
public function testGet($index, $expected)
{
$result = $this->input->get($index);
$this->assertEquals($expected, $result);
}
}
// End of InputTest.php

17
tests/Core/aTypeTest.php Executable file
View File

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

41
tests/Type/JSONTest.php Executable file
View File

@ -0,0 +1,41 @@
<?php
require_once(BASEPATH . 'core/iType.php');
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 {
protected $mime = '';
}
class JSONTest extends Sleepy_Testcase {
public function setUp() {
$this->JSON = new JSON([]);
}
public function testSanity() {
$this->assertTrue(is_a($this->JSON, 'Sleepy\\types\\JSON'));
$this->assertTrue(is_a($this->JSON, 'Sleepy\\core\\aType'));
$this->assertEquals(['Sleepy\\core\\iType' => 'Sleepy\\core\\iType'], class_implements('Sleepy\\types\\JSON'));
}
public function testFunction()
public function testNIE() {
try {
$json = new MockJSON([]);
}
catch (Sleepy\exceptions\NotImplementedException $e) {
$this->assertTrue(TRUE);
}
}
}
// End of JSONTest

26
tests/phpunit.xml Executable file
View File

@ -0,0 +1,26 @@
<?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">
<testsuites>
<testsuite name="Sleepy Core Test Suite">
<directory suffix="Test.php">./core</directory>
<directory suffix="Test.php">./exceptions</directory>
<directory suffix="Test.php">./types</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php">PEAR_INSTALL_DIR</directory>
<directory suffix=".php">PHP_LIBDIR</directory>
<directory suffix=".php">../vendor</directory>
</blacklist>
</filter>
</phpunit>