Merge pull request #588 from getgrav/feature/introduce-testing

Introduce testing
This commit is contained in:
Andy Miller
2016-01-26 10:54:15 -07:00
31 changed files with 5618 additions and 52 deletions

4
.gitignore vendored
View File

@@ -36,3 +36,7 @@ Thumbs.db
# phpstorm
.idea/*
user/config/security.yaml
tests/_output/*
tests/_support/_generated/*
tests/cache/*

View File

@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block access to specific file types for these user folders

View File

@@ -104,7 +104,7 @@ What you mainly want to know is that:
* If you have questions, check out `#grav` on irc.freenode.net
* Have fun!
# Exploring more
# Exploring More
* Have a look at our [Basic Tutorial](http://learn.getgrav.org/basics/basic-tutorial)
* Dive into more [advanced](http://learn.getgrav.org/advanced) functions
@@ -116,3 +116,10 @@ See [LICENSE](LICENSE.txt)
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
[gitflow-extensions]: https://github.com/nvie/gitflow
# Running Tests
First install the dev dependencies by running `composer update` from the Grav root.
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`

16
codeception.yml Normal file
View File

@@ -0,0 +1,16 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
extensions:
enabled:
- Codeception\Extension\RunFailed
modules:
config:

View File

@@ -27,6 +27,10 @@
"ext-openssl": "*",
"ext-curl": "*"
},
"require-dev": {
"codeception/codeception": "^2.1",
"fzaninotto/faker": "^1.5"
},
"repositories": [
{
"type": "vcs",
@@ -43,7 +47,8 @@
"exclude": ["VERSION"]
},
"scripts": {
"post-create-project-cmd": "bin/grav install"
"post-create-project-cmd": "bin/grav install",
"test": "vendor/bin/codecept run unit"
},
"extra": {
"branch-alias": {

1520
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -170,7 +170,6 @@ class Assets
$this->timestamp = '?' . self::getGrav()['cache']->getKey();
}
return $this;
}
@@ -685,6 +684,7 @@ class Assets
// Write file
if (strlen(trim($buffer)) > 0) {
file_put_contents($absolute_path, $buffer);
return $relative_path . $key;
} else {
return false;

View File

@@ -2,11 +2,15 @@
namespace Grav\Common;
/**
* Simple wrapper for the very simple parse_user_agent() function
* Handles browser and platform versions
*
* Internally uses the PhpUserAgent package https://github.com/donatj/PhpUserAgent
*
* @author RocketTHeme
* @licence MIT
*/
class Browser
{
protected $useragent = [];
public function __construct()
@@ -18,21 +22,88 @@ class Browser
}
}
/**
* Get the current browser identifier
*
* Currently detected browsers:
*
* Android Browser
* BlackBerry Browser
* Camino
* Kindle / Silk
* Firefox / Iceweasel
* Safari
* Internet Explorer
* IEMobile
* Chrome
* Opera
* Midori
* Vivaldi
* TizenBrowser
* Lynx
* Wget
* Curl
*
* @return string the lowercase browser name
*/
public function getBrowser()
{
return strtolower($this->useragent['browser']);
}
/**
* Get the current platform identifier
*
* Currently detected platforms:
*
* Desktop
* -> Windows
* -> Linux
* -> Macintosh
* -> Chrome OS
* Mobile
* -> Android
* -> iPhone
* -> iPad / iPod Touch
* -> Windows Phone OS
* -> Kindle
* -> Kindle Fire
* -> BlackBerry
* -> Playbook
* -> Tizen
* Console
* -> Nintendo 3DS
* -> New Nintendo 3DS
* -> Nintendo Wii
* -> Nintendo WiiU
* -> PlayStation 3
* -> PlayStation 4
* -> PlayStation Vita
* -> Xbox 360
* -> Xbox One
*
* @return string the lowercase platform name
*/
public function getPlatform()
{
return strtolower($this->useragent['platform']);
}
/**
* Get the current full version identifier
*
* @return string the browser full version identifier
*/
public function getLongVersion()
{
return $this->useragent['version'];
}
/**
* Get the current major version identifier
*
* @return string the browser major version identifier
*/
public function getVersion()
{
$version = explode('.', $this->getLongVersion());
@@ -41,6 +112,8 @@ class Browser
/**
* Determine if the request comes from a human, or from a bot/crawler
*
* @return bool
*/
public function isHuman()
{

View File

@@ -15,38 +15,99 @@ class Uri
public $url;
protected $basename;
protected $base;
protected $root;
protected $basename;
protected $bits;
protected $content_path;
protected $extension;
protected $host;
protected $content_path;
protected $params;
protected $path;
protected $paths;
protected $query;
protected $params;
protected $port;
protected $uri;
protected $query;
protected $root;
protected $root_path;
protected $uri;
/**
* Constructor.
* Constructor
*/
public function __construct()
{
// resets
$this->paths = [];
$this->params = [];
$this->query = [];
$this->name = $this->buildHostname();
$this->port = $this->buildPort();
$this->uri = $this->buildUri();
$this->base = $this->buildBaseUrl();
$this->host = $this->buildHost();
$this->root_path = $this->buildRootPath();
$this->root = $this->base . $this->root_path;
$this->url = $this->base . $this->uri;
}
/**
* Return the hostname from $_SERVER, validated and without port
*
* @return string
*/
private function buildHostname()
{
$name = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
// Remove port from HTTP_HOST generated $name
$name = Utils::substrToString($name, ':');
// Validate the hostname
$name = preg_match(Uri::HOSTNAME_REGEX, $name) ? $name : 'unknown';
$name = $this->validateHostname($name) ? $name : 'unknown';
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
return $name;
}
$root_path = str_replace(' ', '%20', rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/'));
/**
* Validate a hostname
*
* @param string $hostname The hostname
*
* @return boolean
*/
public function validateHostname($hostname)
{
return (bool)preg_match(Uri::HOSTNAME_REGEX, $hostname);
}
/**
* Get the port from $_SERVER
*
* @return string
*/
private function buildPort()
{
$port = isset($_SERVER['SERVER_PORT']) ? (string)$_SERVER['SERVER_PORT'] : '80';
return $port;
}
/**
* Get the Uri from $_SERVER
*
* @return string
*/
private function buildUri()
{
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
return $uri;
}
/**
* Get the base URI with port if needed
*
* @return string
*/
private function buildBaseUrl()
{
// set the base
if (isset($_SERVER['HTTPS'])) {
$base = (strtolower(@$_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
@@ -54,29 +115,99 @@ class Uri
$base = 'http://';
}
// add the sever name
$base .= $name;
// add the server name
$base .= $this->name;
return $base;
}
/**
* Get the Grav Root Path
*
* @return string
*/
private function buildRootPath()
{
$root_path = str_replace(' ', '%20', rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/'));
// check if userdir in the path and workaround PHP bug with PHP_SELF
if (strpos($uri, '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
$root_path = substr($uri, 0, strpos($uri, '/', 1)) . $root_path;
if (strpos($this->uri, '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
$root_path = substr($uri, 0, strpos($this->uri, '/', 1)) . $root_path;
}
return $root_path;
}
/**
* Returns the hostname
*
* @return string
*/
private function buildHost()
{
// set hostname
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
// check for localhost variations
if ($name == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
$this->host = 'localhost';
if ($this->name == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
$host = 'localhost';
} else {
$this->host = $name;
$host = $this->name;
}
$this->port = $port;
$this->base = $base;
$this->uri = $uri;
$this->root_path = $root_path;
return $host;
}
/**
* Initialize the URI class with a url passed via parameter.
* Used for testing purposes.
*
* @param string $url the URL to use in the class
*
* @return string
*/
public function initializeWithUrl($url = '')
{
if (!$url) return;
$this->paths = [];
$this->params = [];
$this->query = [];
$this->name = [];
$this->port = [];
$this->uri = [];
$this->base = [];
$this->host = [];
$this->root = [];
$this->url = [];
$params = parse_url($url);
$this->name = $params['host'];
$this->port = isset($params['port']) ? $params['port'] : '80';
$this->uri = $params['path'];
if (isset($params['query'])) {
$this->uri .= '?' . $params['query'];
parse_str($params['query'], $this->query);
}
$this->base = $this->buildBaseUrl();
$this->host = $this->buildHost();
$this->root_path = $this->buildRootPath();
$this->root = $this->base . $this->root_path;
$this->url = $this->base . $this->uri;
return $this;
}
public function initializeWithUrlAndRootPath($url, $root_path)
{
$this->initializeWithUrl($url);
$this->root_path = $root_path;
$this->root = $this->base . $this->root_path;
return $this;
}
/**
@@ -89,11 +220,6 @@ class Uri
$config = $grav['config'];
$language = $grav['language'];
// resets
$this->paths = [];
$this->params = [];
$this->query = [];
// add the port to the base for non-standard ports
if ($config->get('system.reverse_proxy_setup') == false && $this->port != '80' && $this->port != '443') {
$this->base .= ":".$this->port;
@@ -131,7 +257,9 @@ class Uri
// process query string
if (isset($bits['query']) && isset($bits['path'])) {
$this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
if (!$this->query) {
$this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
}
$uri = $bits['path'];
}
@@ -232,6 +360,9 @@ class Uri
if ($raw) {
return $this->query;
} else {
if (!$this->query) {
return '';
}
return http_build_query($this->query);
}
}
@@ -502,12 +633,12 @@ class Uri
}
/**
* Converts links from absolute '/' or relative (../..) to a grav friendly format
* Converts links from absolute '/' or relative (../..) to a Grav friendly format
*
* @param Page|the $page the current page to use as reference
* @param string $markdown_url the URL as it was written in the markdown
* @param string $type the type of URL, image | link
* @param null $relative if null, will use system default, if true will use relative links internally
* @param Page $page the current page to use as reference
* @param string $markdown_url the URL as it was written in the markdown
* @param string $type the type of URL, image | link
* @param null $relative if null, will use system default, if true will use relative links internally
*
* @return string the more friendly formatted url
*/
@@ -574,7 +705,6 @@ class Uri
$page_path = $path_info['dirname'];
$filename = '';
if ($markdown_url == '..') {
$page_path = $full_path;
} else {
@@ -614,5 +744,4 @@ class Uri
$urlWithNonce = $url . '/' . $nonceParamName . Grav::instance()['config']->get('system.param_sep', ':') . Utils::getNonce($action);
return $urlWithNonce;
}
}

View File

@@ -18,6 +18,8 @@ abstract class Utils
protected static $nonces = [];
/**
* Check if the $haystack string starts with the substring $needle
*
* @param string $haystack
* @param string $needle
*
@@ -41,6 +43,8 @@ abstract class Utils
}
/**
* Check if the $haystack string ends with the substring $needle
*
* @param string $haystack
* @param string $needle
*
@@ -64,6 +68,8 @@ abstract class Utils
}
/**
* Check if the $haystack string contains the substring $needle
*
* @param string $haystack
* @param string $needle
*
@@ -103,6 +109,8 @@ abstract class Utils
}
/**
* Return the Grav date formats allowed
*
* @return array
*/
public static function dateFormats()
@@ -264,7 +272,7 @@ abstract class Utils
/**
* Return the mimetype based on filename
*
* @param $extension Extension of file (eg .txt)
* @param $extension Extension of file (eg "txt")
*
* @return string
*/
@@ -283,7 +291,7 @@ abstract class Utils
/**
* Normalize path by processing relative `.` and `..` syntax and merging path
*
* @param $path
* @param string $path
*
* @return string
*/
@@ -308,7 +316,9 @@ abstract class Utils
}
/**
* @param $function
* Check whether a function is disabled in the PHP settings
*
* @param string $function the name of the function to check
*
* @return bool
*/
@@ -318,6 +328,8 @@ abstract class Utils
}
/**
* Get the formatted timezones list
*
* @return array
*/
public static function timezones()
@@ -344,12 +356,13 @@ abstract class Utils
}
return $timezone_list;
}
/**
* @param array $source
* @param $fn
* Recursively filter an array, filtering values by processing them through the $fn function argument
*
* @param array $source the Array to filter
* @param $fn the function to pass through each array item
*
* @return array
*/
@@ -373,12 +386,18 @@ abstract class Utils
}
/**
* @param $string
* Checks if the passed path contains the language code prefix
*
* @param $string The path
*
* @return bool
*/
public static function pathPrefixedByLangCode($string)
{
if (strlen($string) <= 3) {
return false;
}
$languages_enabled = self::getGrav()['config']->get('system.languages.supported', []);
if ($string[0] == '/' && $string[3] == '/' && in_array(substr($string, 1, 2), $languages_enabled)) {
@@ -389,9 +408,11 @@ abstract class Utils
}
/**
* @param $date
* Get the timestamp of a date
*
* @return int
* @param $date a String expressed in the system.pages.dateformat.default format, with fallback to a strtotime argument
*
* @return int the timestamp
*/
public static function date2timestamp($date)
{
@@ -414,7 +435,13 @@ abstract class Utils
}
/**
* Get value of an array using dot notation
* Get value of an array element using dot notation
*
* @param array $array the Array to check
* @param string $path the dot notation path to check
* @param $default a value to be returned if $path is not found in $array
*
* @return mixed the value found
*/
public static function resolve(array $array, $path, $default = null)
{

49
tests/_bootstrap.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
// This is global bootstrap for autoloading
namespace Grav;
use Codeception\Util\Fixtures;
use Faker\Factory;
// Ensure vendor libraries exist
$autoload = __DIR__ . '/../vendor/autoload.php';
if (!is_file($autoload)) {
throw new \RuntimeException("Please run: <i>bin/grav install</i>");
}
use Grav\Common\Grav;
// Register the auto-loader.
$loader = require_once $autoload;
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
throw new \RuntimeException(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
}
// Set timezone to default, falls back to system if php.ini not set
date_default_timezone_set(@date_default_timezone_get());
// Set internal encoding if mbstring loaded
if (!extension_loaded('mbstring')) {
throw new \RuntimeException("'mbstring' extension is not loaded. This is required for Grav to run correctly");
}
mb_internal_encoding('UTF-8');
// Get the Grav instance
$grav = Grav::instance(
array(
'loader' => $loader
)
);
$grav['debugger']->init();
$grav['assets']->init();
// Set default $_SERVER value used for nonces
empty( $_SERVER['HTTP_CLIENT_IP'] ) && $_SERVER['HTTP_CLIENT_IP'] = '127.0.0.1';
$fake = Factory::create();
Fixtures::add('grav', $grav);
Fixtures::add('fake', $fake);

View File

@@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
/**
* Define custom actions here
*/
}

View File

@@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends \Codeception\Actor
{
use _generated\FunctionalTesterActions;
/**
* Define custom actions here
*/
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Acceptance extends \Codeception\Module
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Functional extends \Codeception\Module
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Unit extends \Codeception\Module
{
}

View File

@@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;
/**
* Define custom actions here
*/
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
<?php //[STAMP] 217732cfcf1663b385a9cfd121bbeed3
namespace _generated;
// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile
use Helper\Functional;
trait FunctionalTesterActions
{
/**
* @return \Codeception\Scenario
*/
abstract protected function getScenario();
}

View File

@@ -0,0 +1,348 @@
<?php //[STAMP] 8c2b6acdd1e147b7717797f40c58c89c
namespace _generated;
// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile
use Codeception\Module\Asserts;
use Helper\Unit;
trait UnitTesterActions
{
/**
* @return \Codeception\Scenario
*/
abstract protected function getScenario();
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are equal.
*
* @param $expected
* @param $actual
* @param string $message
*
* @return mixed
* @see \Codeception\Module\Asserts::assertEquals()
*/
public function assertEquals($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEquals', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are not equal
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotEquals()
*/
public function assertNotEquals($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are same
*
* @param $expected
* @param $actual
* @param string $message
*
* @return mixed
* @see \Codeception\Module\Asserts::assertSame()
*/
public function assertSame($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertSame', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are not same
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotSame()
*/
public function assertNotSame($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is greater than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertGreaterThan()
*/
public function assertGreaterThan($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* @deprecated
* @see \Codeception\Module\Asserts::assertGreaterThen()
*/
public function assertGreaterThen($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is greater or equal than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertGreaterThanOrEqual()
*/
public function assertGreaterThanOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* @deprecated
* @see \Codeception\Module\Asserts::assertGreaterThenOrEqual()
*/
public function assertGreaterThenOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is less than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertLessThan()
*/
public function assertLessThan($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is less or equal than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertLessThanOrEqual()
*/
public function assertLessThanOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that haystack contains needle
*
* @param $needle
* @param $haystack
* @param string $message
* @see \Codeception\Module\Asserts::assertContains()
*/
public function assertContains($needle, $haystack, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContains', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that haystack doesn't contain needle.
*
* @param $needle
* @param $haystack
* @param string $message
* @see \Codeception\Module\Asserts::assertNotContains()
*/
public function assertNotContains($needle, $haystack, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that string match with pattern
*
* @param string $pattern
* @param string $string
* @param string $message
* @see \Codeception\Module\Asserts::assertRegExp()
*/
public function assertRegExp($pattern, $string, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertRegExp', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that string not match with pattern
*
* @param string $pattern
* @param string $string
* @param string $message
* @see \Codeception\Module\Asserts::assertNotRegExp()
*/
public function assertNotRegExp($pattern, $string, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotRegExp', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is empty.
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertEmpty()
*/
public function assertEmpty($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is not empty.
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotEmpty()
*/
public function assertNotEmpty($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is NULL
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNull()
*/
public function assertNull($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNull', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is not NULL
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotNull()
*/
public function assertNotNull($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that condition is positive.
*
* @param $condition
* @param string $message
* @see \Codeception\Module\Asserts::assertTrue()
*/
public function assertTrue($condition, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertTrue', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that condition is negative.
*
* @param $condition
* @param string $message
* @see \Codeception\Module\Asserts::assertFalse()
*/
public function assertFalse($condition, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFalse', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks if file exists
*
* @param string $filename
* @param string $message
* @see \Codeception\Module\Asserts::assertFileExists()
*/
public function assertFileExists($filename, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileExists', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks if file doesn't exist
*
* @param string $filename
* @param string $message
* @see \Codeception\Module\Asserts::assertFileNotExists()
*/
public function assertFileNotExists($filename, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotExists', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Fails the test with message.
*
* @param $message
* @see \Codeception\Module\Asserts::fail()
*/
public function fail($message) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('fail', func_get_args()));
}
}

View File

@@ -0,0 +1,12 @@
# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser:
url: http://localhost:8080/grav
- \Helper\Acceptance

View File

@@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests

View File

@@ -0,0 +1,11 @@
# Codeception Test Suite Configuration
#
# Suite for functional (integration) tests
# Emulate web requests and make application process them
# Include one of framework modules (Symfony2, Yii2, Laravel5) to use it
class_name: FunctionalTester
modules:
enabled:
# add framework module here
- \Helper\Functional

View File

@@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests

9
tests/unit.suite.yml Normal file
View File

@@ -0,0 +1,9 @@
# Codeception Test Suite Configuration
#
# Suite for unit (internal) tests.
class_name: UnitTester
modules:
enabled:
- Asserts
- \Helper\Unit

View File

@@ -0,0 +1,260 @@
<?php
use Codeception\Util\Fixtures;
class AssetsTest extends \Codeception\TestCase\Test
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
public function grav()
{
$grav = Fixtures::get('grav');
return $grav;
}
public function assets()
{
return $this->grav()['assets'];
}
public function testAddingAssets()
{
$assets = $this->assets();
//test add()
$assets->add('test.css');
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
$assets->add('test.js');
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
//test addCss(). Test adding asset to a separate group
$assets->reset();
$assets->addCSS('test.css');
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//test addJs()
$assets->reset();
$assets->addJs('test.js');
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
//Test CSS Groups
$assets->reset();
$assets->addCSS('test.css', null, true, 'footer');
$css = $assets->css();
$this->assertEmpty($css);
$css = $assets->css('footer');
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//Test JS Groups
$assets->reset();
$assets->addJs('test.js', null, true, null, 'footer');
$js = $assets->js();
$this->assertEmpty($js);
$js = $assets->js('footer');
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
//Test async / defer
$assets->reset();
$assets->addJs('test.js', null, true, 'async', null);
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL);
$assets->reset();
$assets->addJs('test.js', null, true, 'defer', null);
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" defer></script>' . PHP_EOL);
}
public function testAddingAssetPropertiesWithArray()
{
$assets = $this->assets();
//Test adding assets with object to define properties
$assets->reset();
$assets->addJs('test.js', ['loading' => 'async']);
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL);
$assets->reset();
}
public function testAddingJSAssetPropertiesWithArrayFromCollection()
{
$assets = $this->assets();
//Test adding properties with array
$assets->reset();
$assets->addJs('jquery', ['loading' => 'async']);
$js = $assets->js();
$this->assertSame($js, '<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" async></script>' . PHP_EOL);
//Test priority too
$assets->reset();
$assets->addJs('jquery', ['loading' => 'async', 'priority' => 1]);
$assets->addJs('test.js', ['loading' => 'async', 'priority' => 2]);
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL .
'<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" async></script>' . PHP_EOL);
//Test multiple groups
$assets->reset();
$assets->addJs('jquery', ['loading' => 'async', 'priority' => 1, 'group' => 'footer']);
$assets->addJs('test.js', ['loading' => 'async', 'priority' => 2]);
$js = $assets->js();
$this->assertSame($js, '<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL);
$js = $assets->js('footer');
$this->assertSame($js, '<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" async></script>' . PHP_EOL);
//Test adding array of assets
//Test priority too
$assets->reset();
$assets->addJs(['jquery', 'test.js'], ['loading' => 'async']);
$js = $assets->js();
$this->assertSame($js, '<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" async></script>' . PHP_EOL .
'<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL);
}
public function testAddingCSSAssetPropertiesWithArrayFromCollection()
{
$assets = $this->assets();
$assets->registerCollection('test', ['/system/assets/whoops.css']);
//Test priority too
$assets->reset();
$assets->addCss('test', ['priority' => 1]);
$assets->addCss('test.css', ['priority' => 2]);
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/system/assets/whoops.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//Test multiple groups
$assets->reset();
$assets->addCss('test', ['priority' => 1, 'group' => 'footer']);
$assets->addCss('test.css', ['priority' => 2]);
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
$css = $assets->css('footer');
$this->assertSame($css, '<link href="/system/assets/whoops.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//Test adding array of assets
//Test priority too
$assets->reset();
$assets->addCss(['test', 'test.css'], ['loading' => 'async']);
$css = $assets->css();
$this->assertSame($css, '<link href="/system/assets/whoops.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
}
public function testPriorityOfAssets()
{
$assets = $this->assets();
$assets->reset();
$assets->add('test.css');
$assets->add('test-after.css');
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/test-after.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//----------------
$assets->reset();
$assets->add('test-after.css', 1);
$assets->add('test.css', 2);
$css = $assets->css();
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/test-after.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
//----------------
$assets->reset();
$assets->add('test-after.css', 1);
$assets->add('test.css', 2);
$assets->add('test-before.css', 3);
$css = $assets->css();
$this->assertSame($css, '<link href="/test-before.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL .
'<link href="/test-after.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
}
public function testPipeline()
{
$assets = $this->assets();
$assets->reset();
//File not existing. Pipeline searches for that file without reaching it. Output is empty.
$assets->add('test.css', null, true);
$assets->setCssPipeline(true);
$css = $assets->css();
$this->assertSame($css, '');
//Add a core Grav CSS file, which is found. Pipeline will now return a file
$assets->add('/system/assets/debugger.css', null, true);
$css = $assets->css();
$this->assertContains('<link href=', $css);
$this->assertContains('type="text/css" rel="stylesheet" />', $css);
}
public function testAddAsyncJs()
{
$assets = $this->assets();
$assets->reset();
$assets->addAsyncJs('jquery');
$js = $assets->js();
$this->assertSame($js, '<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" async></script>' . PHP_EOL);
}
public function testAddDeferJs()
{
$assets = $this->assets();
$assets->reset();
$assets->addDeferJs('jquery');
$js = $assets->js();
$this->assertSame($js, '<script src="/system/assets/jquery/jquery-2.x.min.js" type="text/javascript" defer></script>' . PHP_EOL);
}
public function testAddInlineCss()
{
$assets = $this->assets();
$assets->reset();
$assets->addInlineCss('body { color: black }');
$css = $assets->css();
$this->assertSame($css, PHP_EOL. '<style>' .PHP_EOL . 'body { color: black }' . PHP_EOL.PHP_EOL .'</style>' . PHP_EOL);
}
public function testAddInlineJs()
{
$assets = $this->assets();
$assets->reset();
$assets->addInlineJs('alert("test")');
$js = $assets->js();
$this->assertSame($js, PHP_EOL. '<script>' .PHP_EOL . 'alert("test")' . PHP_EOL.PHP_EOL .'</script>' . PHP_EOL);
}
}

View File

@@ -0,0 +1,38 @@
<?php
use Codeception\Util\Fixtures;
class BrowserTest extends \Codeception\TestCase\Test
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
public function grav()
{
return Fixtures::get('grav');
}
public function testGetBrowser() { /* Already covered by PhpUserAgent tests */ }
public function testGetPlatform() { /* Already covered by PhpUserAgent tests */ }
public function testGetLongVersion() { /* Already covered by PhpUserAgent tests */ }
public function testGetVersion() { /* Already covered by PhpUserAgent tests */ }
public function testIsHuman()
{
//Already Partially covered by PhpUserAgent tests
//Make sure it recognizes the test as not human
$this->assertFalse($this->grav()['browser']->isHuman());
}
}

View File

@@ -0,0 +1,38 @@
<?php
use Codeception\Util\Fixtures;
use Grav\Common\Composer;
class ComposerTest extends \Codeception\TestCase\Test
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
public function testGetComposerLocation()
{
$composerLocation = Composer::getComposerLocation();
$this->assertTrue(is_string($composerLocation));
$this->assertTrue($composerLocation[0] == '/');
}
public function testGetComposerExecutor()
{
$composerExecutor = Composer::getComposerExecutor();
$this->assertTrue(is_string($composerExecutor));
$this->assertTrue($composerExecutor[0] == '/');
$this->assertTrue(strstr($composerExecutor, 'php') !== null);
$this->assertTrue(strstr($composerExecutor, 'composer') !== null);
}
}

View File

@@ -0,0 +1,456 @@
<?php
use Codeception\Util\Fixtures;
use Grav\Common\Utils;
class UriTest extends \Codeception\TestCase\Test
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
public function grav()
{
return Fixtures::get('grav');
}
public function getURI()
{
return $this->grav()['uri'];
}
public function testValidatingHostname()
{
$uri = $this->getURI();
$this->assertTrue($uri->validateHostname('localhost') == 1);
$this->assertTrue($uri->validateHostname('google.com') == 1);
$this->assertTrue($uri->validateHostname('google.it') == 1);
$this->assertTrue($uri->validateHostname('goog.le') == 1);
$this->assertTrue($uri->validateHostname('goog.wine') == 1);
$this->assertTrue($uri->validateHostname('goog.localhost') == 1);
$this->assertFalse($uri->validateHostname('localhost:80') == 1);
$this->assertFalse($uri->validateHostname('http://localhost') == 1);
$this->assertFalse($uri->validateHostname('localhost!') == 1);
}
public function testInitializingUris()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertTrue($uri->params() == null);
$this->assertTrue($uri->query() == '');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertFalse($uri->params() == null);
$this->assertTrue($uri->query() == '');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertTrue($uri->params() == null);
$this->assertTrue($uri->query() != '');
$this->assertTrue($uri->query() == 'test=x');
$this->assertTrue($uri->port() == '8080');
$uri->initializeWithURL('http://localhost:80/grav/it/ueper?test=x')->init();
$this->assertTrue($uri->port() == '80');
$uri->initializeWithURL('http://localhost/grav/it/ueper?test=x')->init();
$this->assertTrue($uri->port() == '80');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertTrue($uri->params() == null);
$uri->initializeWithURL('http://grav/grav/it/ueper')->init();
$this->assertTrue($uri->params() == null);
}
public function testPaths()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->paths(), ['grav', 'it', 'ueper']);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->paths(), ['grav', 'it']);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->paths(), ['grav', 'it', 'ueper']);
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->paths(), ['a', 'b', 'c', 'd']);
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->paths(), ['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c', 'd', 'e', 'f']);
}
public function testRoute()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->route(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->route(), '/grav/it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->route(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->route(), '/a/b/c/d');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->route(), '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f');
}
public function testQuery()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->query(), '');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->query(), '');
$this->assertSame($uri->query('id'), null);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->query(), 'test=x');
$this->assertSame($uri->query('id'), null);
$this->assertSame($uri->query('test'), 'x');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init();
$this->assertSame($uri->query(), 'test=x&test2=y');
$this->assertSame($uri->query('id'), null);
$this->assertSame($uri->query('test'), 'x');
$this->assertSame($uri->query('test2'), 'y');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init();
$this->assertSame($uri->query(), 'test=x&test2=y&test3=x&test4=y');
$this->assertSame($uri->query('id'), null);
$this->assertSame($uri->query('test'), 'x');
$this->assertSame($uri->query('test2'), 'y');
$this->assertSame($uri->query('test4'), 'y');
//Test all after the ? is encoded in the query
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init();
$this->assertSame($uri->query(), 'test=x&test2=y&test3=x&test4=y%2Ftest');
$this->assertSame($uri->query('id'), null);
$this->assertSame($uri->query('test'), 'x');
$this->assertSame($uri->query('test2'), 'y');
$this->assertSame($uri->query('test4'), 'y/test');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->query(), '');
$this->assertSame($uri->query('id'), null);
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->query(), '');
$this->assertSame($uri->query('id'), null);
}
public function testParams()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->params(), null);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->params(), '/ueper:xxx');
$this->assertSame($uri->params('ueper'), '/ueper:xxx');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init();
$this->assertSame($uri->params(), '/ueper:xxx/test:yyy');
$this->assertSame($uri->params('ueper'), '/ueper:xxx');
$this->assertSame($uri->params('test'), '/test:yyy');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->params(), null);
$this->assertSame($uri->params('ueper'), null);
}
public function testParam()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->param('ueper'), 'xxx');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init();
$this->assertSame($uri->param('ueper'), 'xxx');
$this->assertSame($uri->param('test'), 'yyy');
}
public function testUrl()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->url(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->url(), '/grav/it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init();
$this->assertSame($uri->url(), '/grav/it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->url(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init();
$this->assertSame($uri->url(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init();
$this->assertSame($uri->url(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init();
$this->assertSame($uri->url(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->url(), '/a/b/c/d');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->url(), '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f');
}
public function testPath()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->path(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->path(), '/grav/it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init();
$this->assertSame($uri->path(), '/grav/it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->path(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init();
$this->assertSame($uri->path(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init();
$this->assertSame($uri->path(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init();
$this->assertSame($uri->path(), '/grav/it/ueper');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->path(), '/a/b/c/d');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->path(), '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f');
$uri->initializeWithURL('http://localhost/')->init();
$this->assertSame($uri->path(), '/');
}
public function testExtension()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->extension(), null);
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->extension('x'), 'x');
$uri->initializeWithURL('http://localhost/a-page.html')->init();
$this->assertSame($uri->extension(), 'html');
$uri->initializeWithURL('http://localhost/a-page.xml')->init();
$this->assertSame($uri->extension(), 'xml');
$uri->initializeWithURL('http://localhost/a-page.foo')->init();
$this->assertSame($uri->extension(), 'foo');
}
public function testHost()
{
$uri = $this->getURI();
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
if ($uri->host() == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
$address = 'localhost';
}
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->host(), $address);
$uri->initializeWithURL('http://localhost/')->init();
$this->assertSame($uri->host(), $address);
//Host is set to localhost when running from local
$uri->initializeWithURL('http://google.com/')->init();
$this->assertSame($uri->host(), $address);
}
public function testPort()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->port(), '80');
$uri->initializeWithURL('http://localhost:8080/a-page')->init();
$this->assertSame($uri->port(), 8080);
$uri->initializeWithURL('http://localhost:443/a-page')->init();
$this->assertSame($uri->port(), 443);
$uri->initializeWithURL('https://localhost/a-page')->init();
$this->assertSame($uri->port(), '80');
}
public function testEnvironment()
{
$uri = $this->getURI();
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
if ($uri->host() == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
$address = 'localhost';
}
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->environment(), $address);
$uri->initializeWithURL('http://localhost:8080/a-page')->init();
$this->assertSame($uri->environment(), $address);
$uri->initializeWithURL('http://foobar.it:443/a-page')->init();
$this->assertSame($uri->environment(), $address);
$uri->initializeWithURL('https://google.com/a-page')->init();
$this->assertSame($uri->environment(), $address);
}
public function testBasename()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper')->init();
$this->assertSame($uri->basename(), 'ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init();
$this->assertSame($uri->basename(), 'it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init();
$this->assertSame($uri->basename(), 'it');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init();
$this->assertSame($uri->basename(), 'ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init();
$this->assertSame($uri->basename(), 'ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init();
$this->assertSame($uri->basename(), 'ueper');
$uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init();
$this->assertSame($uri->basename(), 'ueper');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init();
$this->assertSame($uri->basename(), 'd');
$uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init();
$this->assertSame($uri->basename(), 'f');
$uri->initializeWithURL('http://localhost/')->init();
$this->assertSame($uri->basename(), '');
$uri->initializeWithURL('http://localhost/test.xml')->init();
$this->assertSame($uri->basename(), 'test.xml');
}
public function testBase()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->base(), 'http://localhost');
$uri->initializeWithURL('http://localhost:8080/a-page')->init();
$this->assertSame($uri->base(), 'http://localhost:8080');
$uri->initializeWithURL('http://foobar.it:80/a-page')->init();
$this->assertSame($uri->base(), 'http://foobar.it');
$uri->initializeWithURL('https://google.com/a-page')->init();
$this->assertSame($uri->base(), 'http://google.com');
}
public function testRootUrl()
{
$uri = $this->getURI();
//Without explicitly adding the root path via `initializeWithUrlAndRootPath`,
//tests always default to the base empty root path
$uri->initializeWithURL('http://localhost/a-page')->init();
$this->assertSame($uri->rootUrl(true), 'http://localhost');
$uri->initializeWithURL('http://localhost:8080/a-page')->init();
$this->assertSame($uri->rootUrl(true), 'http://localhost:8080');
$uri->initializeWithURL('http://foobar.it:80/a-page')->init();
$this->assertSame($uri->rootUrl(true), 'http://foobar.it');
$uri->initializeWithURL('https://google.com/a-page/xxx')->init();
$this->assertSame($uri->rootUrl(true), 'http://google.com');
$uri->initializeWithUrlAndRootPath('https://localhost/grav/page-foo', '/grav')->init();
$this->assertSame($uri->rootUrl(), '/grav');
$this->assertSame($uri->rootUrl(true), 'http://localhost/grav');
}
public function testCurrentPage()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/foo/page:test')->init();
$this->assertSame($uri->currentPage(), 'test');
$uri->initializeWithURL('http://localhost:8080/a-page')->init();
$this->assertSame($uri->currentPage(), 1);
$uri->initializeWithURL('http://localhost:8080/a-page/page:2')->init();
$this->assertSame($uri->currentPage(), '2');
$uri->initializeWithURL('http://localhost:8080/a-page/page:x')->init();
$this->assertSame($uri->currentPage(), 'x');
$uri->initializeWithURL('http://localhost:8080/a-page/page:')->init();
$this->assertSame($uri->currentPage(), '');
}
public function testReferrer()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/foo/page:test')->init();
$this->assertSame($uri->referrer(), '/foo');
$uri->initializeWithURL('http://localhost/foo/bar/page:test')->init();
$this->assertSame($uri->referrer(), '/foo/bar');
}
public function testIp()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/foo/page:test')->init();
$this->assertSame($uri->ip(), 'UNKNOWN');
}
public function testIsExternal()
{
$uri = $this->getURI();
$uri->initializeWithURL('http://localhost/')->init();
$this->assertFalse($uri->isExternal('/test'));
$this->assertFalse($uri->isExternal('/foo/bar'));
$this->assertTrue($uri->isExternal('http://localhost/test'));
$this->assertTrue($uri->isExternal('http://google.it/test'));
}
public function testBuildUrl()
{
$parsed_url = [
'scheme' => 'http',
'host' => 'localhost',
'port' => '8080',
];
$this->assertSame($this->grav()['uri']::buildUrl($parsed_url), 'http://localhost:8080');
$parsed_url = [
'scheme' => 'http',
'host' => 'localhost',
'port' => '8080',
'user' => 'foo',
'pass' => 'bar',
'path' => '/test',
'query' => 'x=2',
'fragment' => 'xxx',
];
$this->assertSame($this->grav()['uri']::buildUrl($parsed_url), 'http://foo:bar@localhost:8080/test?x=2#xxx');
}
public function testConvertUrl()
{
//TODO when we have a fixed testing page structure
}
public function testAddNonce()
{
$url = 'http://localhost/foo';
$this->assertStringStartsWith($url, $this->grav()['uri']::addNonce($url, 'test-action'));
$this->assertStringStartsWith($url . '/nonce:', $this->grav()['uri']::addNonce($url, 'test-action'));
$uri = $this->getURI();
$uri->initializeWithURL($this->grav()['uri']::addNonce($url, 'test-action'))->init();
$this->assertTrue(is_string($uri->param('nonce')));
$this->assertSame($uri->param('nonce'), Utils::getNonce('test-action'));
}
}

View File

@@ -0,0 +1,260 @@
<?php
use Codeception\Util\Fixtures;
use Grav\Common\Utils;
class UtilsTest extends \Codeception\TestCase\Test
{
/**
* @var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
public function grav()
{
$grav = Fixtures::get('grav');
return $grav;
}
public function testStartsWith()
{
$this->assertTrue(Utils::startsWith('english', 'en'));
$this->assertTrue(Utils::startsWith('English', 'En'));
$this->assertTrue(Utils::startsWith('ENGLISH', 'EN'));
$this->assertTrue(Utils::startsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'EN'));
$this->assertFalse(Utils::startsWith('english', 'En'));
$this->assertFalse(Utils::startsWith('English', 'EN'));
$this->assertFalse(Utils::startsWith('ENGLISH', 'en'));
$this->assertFalse(Utils::startsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'e'));
}
public function testEndsWith()
{
$this->assertTrue(Utils::endsWith('english', 'sh'));
$this->assertTrue(Utils::endsWith('EngliSh', 'Sh'));
$this->assertTrue(Utils::endsWith('ENGLISH', 'SH'));
$this->assertTrue(Utils::endsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'ENGLISH'));
$this->assertFalse(Utils::endsWith('english', 'de'));
$this->assertFalse(Utils::endsWith('EngliSh', 'sh'));
$this->assertFalse(Utils::endsWith('ENGLISH', 'Sh'));
$this->assertFalse(Utils::endsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'DEUSTCH'));
}
public function testContains()
{
$this->assertTrue(Utils::contains('english', 'nglis'));
$this->assertTrue(Utils::contains('EngliSh', 'gliSh'));
$this->assertTrue(Utils::contains('ENGLISH', 'ENGLI'));
$this->assertTrue(Utils::contains('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'ENGLISH'));
$this->assertFalse(Utils::contains('EngliSh', 'GLI')); $this->assertFalse(Utils::contains('EngliSh', 'English'));
$this->assertFalse(Utils::contains('ENGLISH', 'SCH'));
$this->assertFalse(Utils::contains('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', 'DEUSTCH'));
}
public function testSubstrToString()
{
$this->assertEquals(Utils::substrToString('english', 'glish'), 'en');
$this->assertEquals(Utils::substrToString('english', 'test'), 'english');
$this->assertNotEquals(Utils::substrToString('english', 'lish'), 'en');
}
public function testMergeObjects()
{
$obj1 = new stdClass();
$obj1->test1 = 'x';
$obj2 = new stdClass();
$obj2->test2 = 'y';
$objMerged = Utils::mergeObjects($obj1, $obj2);
$this->assertObjectHasAttribute('test1', $objMerged);
$this->assertObjectHasAttribute('test2', $objMerged);
}
public function testDateFormats()
{
$grav = $this->grav();
$dateFormats = Utils::dateFormats();
$this->assertTrue(is_array($dateFormats));
$this->assertContainsOnly('string', $dateFormats);
$default_format = $grav['config']->get('system.pages.dateformat.default');
if ($default_format !== null) {
$this->assertTrue(isset($dateFormats[$default_format]));
}
}
public function testTruncate()
{
$this->assertEquals(Utils::truncate('english', 5), 'engli' . '&hellip;');
$this->assertEquals(Utils::truncate('english'), 'english');
$this->assertEquals(Utils::truncate('This is a string to truncate'), 'This is a string to truncate');
$this->assertEquals(Utils::truncate('This is a string to truncate', 2), 'Th' . '&hellip;');
$this->assertEquals(Utils::truncate('english', 5, true, " ", "..."), 'engli' . '...');
$this->assertEquals(Utils::truncate('english'), 'english');
$this->assertEquals(Utils::truncate('This is a string to truncate'), 'This is a string to truncate');
$this->assertEquals(Utils::truncate('This is a string to truncate', 3, true), 'This ');
}
public function testSafeTruncate()
{
$this->assertEquals(Utils::safeTruncate('This is a string to truncate', 1), 'This ');
$this->assertEquals(Utils::safeTruncate('This is a string to truncate', 4), 'This ');
$this->assertEquals(Utils::safeTruncate('This is a string to truncate', 5), 'This is ');
}
public function testTruncateHtml()
{
$this->assertEquals(Utils::truncateHtml('<p>This is a string to truncate</p>', 1), '<p>T…</p>');
$this->assertEquals(Utils::truncateHtml('<p>This is a string to truncate</p>', 4), '<p>This…</p>');
}
public function testSafeTruncateHtml()
{
$this->assertEquals(Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 1), '<p>This…</p>');
$this->assertEquals(Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 4), '<p>This…</p>');
}
public function testGenerateRandomString()
{
$this->assertNotEquals(Utils::generateRandomString(), Utils::generateRandomString());
$this->assertNotEquals(Utils::generateRandomString(20), Utils::generateRandomString(20));
}
public function download()
{
}
public function testGetMimeType()
{
$this->assertEquals(Utils::getMimeType(''), 'application/octet-stream');
$this->assertEquals(Utils::getMimeType('jpg'), 'image/jpeg');
$this->assertEquals(Utils::getMimeType('png'), 'image/png');
$this->assertEquals(Utils::getMimeType('txt'), 'text/plain');
$this->assertEquals(Utils::getMimeType('doc'), 'application/msword');
}
public function testNormalizePath()
{
$this->assertEquals(Utils::normalizePath('/test'), '/test');
$this->assertEquals(Utils::normalizePath('test'), 'test');
$this->assertEquals(Utils::normalizePath('../test'), 'test');
$this->assertEquals(Utils::normalizePath('/../test'), '/test');
$this->assertEquals(Utils::normalizePath('/test/../test2'), '/test2');
$this->assertEquals(Utils::normalizePath('/test/./test2'), '/test/test2');
}
public function testIsFunctionDisabled()
{
$disabledFunctions = explode(',', ini_get('disable_functions'));
if ($disabledFunctions[0]) {
$this->assertEquals(Utils::isFunctionDisabled($disabledFunctions[0]), true);
}
}
public function testTimezones()
{
$timezones = Utils::timezones();
$this->assertTrue(is_array($timezones));
$this->assertContainsOnly('string', $timezones);
}
public function testArrayFilterRecursive()
{
$array = [
'test' => '',
'test2' => 'test2'
];
$array = Utils::arrayFilterRecursive($array, function($k, $v) {
return !(is_null($v) || $v === '');
});
$this->assertContainsOnly('string', $array);
$this->assertFalse(isset($array['test']));
$this->assertTrue(isset($array['test2']));
$this->assertEquals($array['test2'], 'test2');
}
public function testPathPrefixedByLangCode()
{
$languagesEnabled = $this->grav()['config']->get('system.languages.supported', []);
$arrayOfLanguages = ['en', 'de', 'it', 'es', 'dk', 'el'];
$languagesNotEnabled = array_diff($arrayOfLanguages, $languagesEnabled);
$oneLanguageNotEnabled = reset($languagesNotEnabled);
if (count($languagesEnabled)) {
$this->assertTrue(Utils::pathPrefixedByLangCode('/' . $languagesEnabled[0] . '/test'));
}
$this->assertFalse(Utils::pathPrefixedByLangCode('/' . $oneLanguageNotEnabled . '/test'));
$this->assertFalse(Utils::pathPrefixedByLangCode('/test'));
$this->assertFalse(Utils::pathPrefixedByLangCode('/xx'));
$this->assertFalse(Utils::pathPrefixedByLangCode('/xx/'));
$this->assertFalse(Utils::pathPrefixedByLangCode('/'));
}
public function testDate2timestamp()
{
$timestamp = strtotime('10 September 2000');
$this->assertSame(Utils::date2timestamp('10 September 2000'), $timestamp);
$this->assertSame(Utils::date2timestamp('2000-09-10 00:00:00'), $timestamp);
}
public function testResolve()
{
$array = [
'test' => [
'test2' => 'test2Value'
]
];
$this->assertEquals(Utils::resolve($array, 'test.test2'), 'test2Value');
}
public function testIsPositive()
{
$this->assertTrue(Utils::isPositive(true));
$this->assertTrue(Utils::isPositive(1));
$this->assertTrue(Utils::isPositive('1'));
$this->assertTrue(Utils::isPositive('yes'));
$this->assertTrue(Utils::isPositive('on'));
$this->assertTrue(Utils::isPositive('true'));
$this->assertFalse(Utils::isPositive(false));
$this->assertFalse(Utils::isPositive(0));
$this->assertFalse(Utils::isPositive('0'));
$this->assertFalse(Utils::isPositive('no'));
$this->assertFalse(Utils::isPositive('off'));
$this->assertFalse(Utils::isPositive('false'));
$this->assertFalse(Utils::isPositive('some'));
$this->assertFalse(Utils::isPositive(2));
}
public function testGetNonce()
{
$this->assertTrue(is_string(Utils::getNonce('test-action')));
$this->assertTrue(is_string(Utils::getNonce('test-action', true)));
$this->assertSame(Utils::getNonce('test-action'), Utils::getNonce('test-action'));
$this->assertNotSame(Utils::getNonce('test-action'), Utils::getNonce('test-action2'));
}
public function testVerifyNonce()
{
$this->assertTrue(Utils::verifyNonce(Utils::getNonce('test-action'), 'test-action'));
}
}

View File

@@ -0,0 +1,4 @@
<?php
// Here you can initialize variables that will be available to your tests
define('GRAV_CLI', true);