A version of the stock PHPUnit testcase that includes some extra helpers and default settings[!!] This class, or a class parent, could not be found or loaded. This could be caused by a missing module or other dependancy. The documentation for class may not be complete!
Class declared in MODPATH/unittest/classes/Unittest/TestCase.php on line 3.
Kohana_Unittest_Helpers
$_helperslink to thisA set of unittest helpers that are shared between normal / database testcases
NULL
boolean
$backupGlobalslink to thisMake sure PHPUnit backs up globals
bool FALSE
array
$environmentDefaultlink to thisA default set of environment to be applied before each test
array(0)
This assertion is the exact opposite of assertTag
Rather than asserting that $matcher results in a match, it asserts that $matcher does not match
TODO: this should be removed when phpunit-dom-assertions gets released https://github.com/phpunit/phpunit-dom-assertions
array
$matcher
required - $matcher string
$actual
required - $actual string
$message
= string(0) "" - $message bool
$isHtml
= bool TRUE - $isHtml
public
static
function
assertNotTag(
$matcher
,
$actual
,
$message
=
''
,
$isHtml
= true)
{
$dom
= PHPUnit_Util_XML::load(
$actual
,
$isHtml
);
$tags
=
static
::findNodes(
$dom
,
$matcher
,
$isHtml
);
$matched
=
count
(
$tags
) > 0 &&
$tags
[0]
instanceof
DOMNode;
self::assertFalse(
$matched
,
$message
);
}
Evaluate an HTML or XML string and assert its structure and/or contents.
TODO: this should be removed when phpunit-dom-assertions gets released https://github.com/phpunit/phpunit-dom-assertions
array
$matcher
required - $matcher string
$actual
required - $actual string
$message
= string(0) "" - $message bool
$isHtml
= bool TRUE - $isHtml
public
static
function
assertTag(
$matcher
,
$actual
,
$message
=
''
,
$isHtml
= true)
{
$dom
= PHPUnit_Util_XML::load(
$actual
,
$isHtml
);
$tags
= self::findNodes(
$dom
,
$matcher
,
$isHtml
);
$matched
=
count
(
$tags
) > 0 &&
$tags
[0]
instanceof
DOMNode;
self::assertTrue(
$matched
,
$message
);
}
Validate list of keys in the associative array.
TODO: This should be removed when phpunit-dom-assertions gets released.
array
$hash
required - $hash array
$validKeys
required - $validKeys array
public
static
function
assertValidKeys(
array
$hash
,
array
$validKeys
)
{
$valids
= [];
// Normalize validation keys so that we can use both indexed and
// associative arrays.
foreach
(
$validKeys
as
$key
=>
$val
) {
is_int
(
$key
) ?
$valids
[
$val
] = null :
$valids
[
$key
] =
$val
;
}
$validKeys
=
array_keys
(
$valids
);
// Check for invalid keys.
foreach
(
$hash
as
$key
=>
$value
) {
if
(!in_array(
$key
,
$validKeys
)) {
$unknown
[] =
$key
;
}
}
if
(!
empty
(
$unknown
)) {
throw
new
PHPUnit_Framework_Exception(
'Unknown key(s): '
. implode(
', '
,
$unknown
)
);
}
// Add default values for any valid keys that are empty.
foreach
(
$valids
as
$key
=>
$value
) {
if
(!isset(
$hash
[
$key
])) {
$hash
[
$key
] =
$value
;
}
}
return
$hash
;
}
Removes all kohana related cache files in the cache directory
public
function
cleanCacheDir()
{
return
Unittest_Helpers::clean_cache_dir();
}
Helper function that replaces all occurences of '/' with the OS-specific directory separator
string
$path
required - The path to act on string
public
function
dirSeparator(
$path
)
{
return
Unittest_Helpers::dir_separator(
$path
);
}
Parse out the options from the tag using DOM object tree.
TODO: This should be removed when phpunit-dom-assertions gets released.
DOMDocument
$dom
required - $dom array
$options
required - $options bool
$isHtml
= bool TRUE - $isHtml array
public
static
function
findNodes(DOMDocument
$dom
,
array
$options
,
$isHtml
= true)
{
$valid
= [
'id'
,
'class'
,
'tag'
,
'content'
,
'attributes'
,
'parent'
,
'child'
,
'ancestor'
,
'descendant'
,
'children'
,
'adjacent-sibling'
];
$filtered
= [];
$options
= self::assertValidKeys(
$options
,
$valid
);
// find the element by id
if
(
$options
[
'id'
]) {
$options
[
'attributes'
][
'id'
] =
$options
[
'id'
];
}
if
(
$options
[
'class'
]) {
$options
[
'attributes'
][
'class'
] =
$options
[
'class'
];
}
$nodes
= [];
// find the element by a tag type
if
(
$options
[
'tag'
]) {
if
(
$isHtml
) {
$elements
= self::getElementsByCaseInsensitiveTagName(
$dom
,
$options
[
'tag'
]
);
}
else
{
$elements
=
$dom
->getElementsByTagName(
$options
[
'tag'
]);
}
foreach
(
$elements
as
$element
) {
$nodes
[] =
$element
;
}
if
(
empty
(
$nodes
)) {
return
false;
}
}
// no tag selected, get them all
else
{
$tags
= [
'a'
,
'abbr'
,
'acronym'
,
'address'
,
'area'
,
'b'
,
'base'
,
'bdo'
,
'big'
,
'blockquote'
,
'body'
,
'br'
,
'button'
,
'caption'
,
'cite'
,
'code'
,
'col'
,
'colgroup'
,
'dd'
,
'del'
,
'div'
,
'dfn'
,
'dl'
,
'dt'
,
'em'
,
'fieldset'
,
'form'
,
'frame'
,
'frameset'
,
'h1'
,
'h2'
,
'h3'
,
'h4'
,
'h5'
,
'h6'
,
'head'
,
'hr'
,
'html'
,
'i'
,
'iframe'
,
'img'
,
'input'
,
'ins'
,
'kbd'
,
'label'
,
'legend'
,
'li'
,
'link'
,
'map'
,
'meta'
,
'noframes'
,
'noscript'
,
'object'
,
'ol'
,
'optgroup'
,
'option'
,
'p'
,
'param'
,
'pre'
,
'q'
,
'samp'
,
'script'
,
'select'
,
'small'
,
'span'
,
'strong'
,
'style'
,
'sub'
,
'sup'
,
'table'
,
'tbody'
,
'td'
,
'textarea'
,
'tfoot'
,
'th'
,
'thead'
,
'title'
,
'tr'
,
'tt'
,
'ul'
,
'var'
,
// HTML5
'article'
,
'aside'
,
'audio'
,
'bdi'
,
'canvas'
,
'command'
,
'datalist'
,
'details'
,
'dialog'
,
'embed'
,
'figure'
,
'figcaption'
,
'footer'
,
'header'
,
'hgroup'
,
'keygen'
,
'mark'
,
'meter'
,
'nav'
,
'output'
,
'progress'
,
'ruby'
,
'rt'
,
'rp'
,
'track'
,
'section'
,
'source'
,
'summary'
,
'time'
,
'video'
,
'wbr'
];
foreach
(
$tags
as
$tag
) {
if
(
$isHtml
) {
$elements
= self::getElementsByCaseInsensitiveTagName(
$dom
,
$tag
);
}
else
{
$elements
=
$dom
->getElementsByTagName(
$tag
);
}
foreach
(
$elements
as
$element
) {
$nodes
[] =
$element
;
}
}
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by attributes
if
(
$options
[
'attributes'
]) {
foreach
(
$nodes
as
$node
) {
$invalid
= false;
foreach
(
$options
[
'attributes'
]
as
$name
=>
$value
) {
// match by regexp if like "regexp:/foo/i"
if
(preg_match(
'/^regexp\s*:\s*(.*)/i'
,
$value
,
$matches
)) {
if
(!preg_match(
$matches
[1],
$node
->getAttribute(
$name
))) {
$invalid
= true;
}
}
// class can match only a part
elseif
(
$name
==
'class'
) {
// split to individual classes
$findClasses
=
explode
(
' '
, preg_replace(
"/\s+/"
,
' '
,
$value
)
);
$allClasses
=
explode
(
' '
, preg_replace(
"/\s+/"
,
' '
,
$node
->getAttribute(
$name
))
);
// make sure each class given is in the actual node
foreach
(
$findClasses
as
$findClass
) {
if
(!in_array(
$findClass
,
$allClasses
)) {
$invalid
= true;
}
}
}
// match by exact string
else
{
if
(
$node
->getAttribute(
$name
) !=
$value
) {
$invalid
= true;
}
}
}
// if every attribute given matched
if
(!
$invalid
) {
$filtered
[] =
$node
;
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by content
if
(
$options
[
'content'
] !== null) {
foreach
(
$nodes
as
$node
) {
$invalid
= false;
// match by regexp if like "regexp:/foo/i"
if
(preg_match(
'/^regexp\s*:\s*(.*)/i'
,
$options
[
'content'
],
$matches
)) {
if
(!preg_match(
$matches
[1], self::getNodeText(
$node
))) {
$invalid
= true;
}
}
// match empty string
elseif
(
$options
[
'content'
] ===
''
) {
if
(self::getNodeText(
$node
) !==
''
) {
$invalid
= true;
}
}
// match by exact string
elseif
(
strstr
(self::getNodeText(
$node
),
$options
[
'content'
]) === false) {
$invalid
= true;
}
if
(!
$invalid
) {
$filtered
[] =
$node
;
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by parent node
if
(
$options
[
'parent'
]) {
$parentNodes
= self::findNodes(
$dom
,
$options
[
'parent'
],
$isHtml
);
$parentNode
= isset(
$parentNodes
[0]) ?
$parentNodes
[0] : null;
foreach
(
$nodes
as
$node
) {
if
(
$parentNode
!==
$node
->parentNode) {
continue
;
}
$filtered
[] =
$node
;
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by child node
if
(
$options
[
'child'
]) {
$childNodes
= self::findNodes(
$dom
,
$options
[
'child'
],
$isHtml
);
$childNodes
= !
empty
(
$childNodes
) ?
$childNodes
: [];
foreach
(
$nodes
as
$node
) {
foreach
(
$node
->childNodes
as
$child
) {
foreach
(
$childNodes
as
$childNode
) {
if
(
$childNode
===
$child
) {
$filtered
[] =
$node
;
}
}
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by adjacent-sibling
if
(
$options
[
'adjacent-sibling'
]) {
$adjacentSiblingNodes
= self::findNodes(
$dom
,
$options
[
'adjacent-sibling'
],
$isHtml
);
$adjacentSiblingNodes
= !
empty
(
$adjacentSiblingNodes
) ?
$adjacentSiblingNodes
: [];
foreach
(
$nodes
as
$node
) {
$sibling
=
$node
;
while
(
$sibling
=
$sibling
->nextSibling) {
if
(
$sibling
->nodeType !== XML_ELEMENT_NODE) {
continue
;
}
foreach
(
$adjacentSiblingNodes
as
$adjacentSiblingNode
) {
if
(
$sibling
===
$adjacentSiblingNode
) {
$filtered
[] =
$node
;
break
;
}
}
break
;
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by ancestor
if
(
$options
[
'ancestor'
]) {
$ancestorNodes
= self::findNodes(
$dom
,
$options
[
'ancestor'
],
$isHtml
);
$ancestorNode
= isset(
$ancestorNodes
[0]) ?
$ancestorNodes
[0] : null;
foreach
(
$nodes
as
$node
) {
$parent
=
$node
->parentNode;
while
(
$parent
&&
$parent
->nodeType != XML_HTML_DOCUMENT_NODE) {
if
(
$parent
===
$ancestorNode
) {
$filtered
[] =
$node
;
}
$parent
=
$parent
->parentNode;
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by descendant
if
(
$options
[
'descendant'
]) {
$descendantNodes
= self::findNodes(
$dom
,
$options
[
'descendant'
],
$isHtml
);
$descendantNodes
= !
empty
(
$descendantNodes
) ?
$descendantNodes
: [];
foreach
(
$nodes
as
$node
) {
foreach
(self::getDescendants(
$node
)
as
$descendant
) {
foreach
(
$descendantNodes
as
$descendantNode
) {
if
(
$descendantNode
===
$descendant
) {
$filtered
[] =
$node
;
}
}
}
}
$nodes
=
$filtered
;
$filtered
= [];
if
(
empty
(
$nodes
)) {
return
false;
}
}
// filter by children
if
(
$options
[
'children'
]) {
$validChild
= [
'count'
,
'greater_than'
,
'less_than'
,
'only'
];
$childOptions
= self::assertValidKeys(
$options
[
'children'
],
$validChild
);
foreach
(
$nodes
as
$node
) {
$childNodes
=
$node
->childNodes;
foreach
(
$childNodes
as
$childNode
) {
if
(
$childNode
->nodeType !== XML_CDATA_SECTION_NODE &&
$childNode
->nodeType !== XML_TEXT_NODE) {
$children
[] =
$childNode
;
}
}
// we must have children to pass this filter
if
(!
empty
(
$children
)) {
// exact count of children
if
(
$childOptions
[
'count'
] !== null) {
if
(
count
(
$children
) !==
$childOptions
[
'count'
]) {
break
;
}
}
// range count of children
elseif
(
$childOptions
[
'less_than'
] !== null &&
$childOptions
[
'greater_than'
] !== null) {
if
(
count
(
$children
) >=
$childOptions
[
'less_than'
] ||
count
(
$children
) <=
$childOptions
[
'greater_than'
]) {
break
;
}
}
// less than a given count
elseif
(
$childOptions
[
'less_than'
] !== null) {
if
(
count
(
$children
) >=
$childOptions
[
'less_than'
]) {
break
;
}
}
// more than a given count
elseif
(
$childOptions
[
'greater_than'
] !== null) {
if
(
count
(
$children
) <=
$childOptions
[
'greater_than'
]) {
break
;
}
}
// match each child against a specific tag
if
(
$childOptions
[
'only'
]) {
$onlyNodes
= self::findNodes(
$dom
,
$childOptions
[
'only'
],
$isHtml
);
// try to match each child to one of the 'only' nodes
foreach
(
$children
as
$child
) {
$matched
= false;
foreach
(
$onlyNodes
as
$onlyNode
) {
if
(
$onlyNode
===
$child
) {
$matched
= true;
}
}
if
(!
$matched
) {
break
2;
}
}
}
$filtered
[] =
$node
;
}
}
$nodes
=
$filtered
;
if
(
empty
(
$nodes
)) {
return
;
}
}
// return the first node that matches all criteria
return
!
empty
(
$nodes
) ?
$nodes
: [];
}
Check for internet connectivity
boolean
- Whether an internet connection is available
public
function
hasInternet()
{
return
Unittest_Helpers::has_internet();
}
Allows easy setting & backing up of enviroment config
Option types are checked in the following order:
array
$environment
required - List of environment to set
public
function
setEnvironment(
array
$environment
)
{
return
$this
->_helpers->set_environment(
$environment
);
}
Creates a predefined environment using the default environment
Extending classes that have their own setUp() should call parent::setUp()
public
function
setUp()
{
$this
->_helpers =
new
Unittest_Helpers;
$this
->setEnvironment(
$this
->environmentDefault);
}
Restores the original environment overriden with setEnvironment()
Extending classes that have their own tearDown() should call parent::tearDown()
public
function
tearDown()
{
$this
->_helpers->restore_environment();
}
Creates classes when they are otherwise not found.
Kodoc::create_class(
'ThisClassDoesNotExist'
);
All classes created will extend Kodoc_Missing.
string
$class
required - Class name boolean
public
static
function
create_class(
$class
)
{
if
(!
class_exists
(
$class
)) {
// Create a new missing class
eval
(
"class {$class} extends Kodoc_Missing {}"
);
}
return
true;
}
Recursively get flat array of all descendants of this node.
TODO: This should be removed when phpunit-dom-assertions gets released.
DOMNode
$node
required - $node array
protected
static
function
getDescendants(DOMNode
$node
)
{
$allChildren
= [];
$childNodes
=
$node
->childNodes ?
$node
->childNodes : [];
foreach
(
$childNodes
as
$child
) {
if
(
$child
->nodeType === XML_CDATA_SECTION_NODE ||
$child
->nodeType === XML_TEXT_NODE) {
continue
;
}
$children
= self::getDescendants(
$child
);
$allChildren
=
array_merge
(
$allChildren
,
$children
, [
$child
]);
}
return
isset(
$allChildren
) ?
$allChildren
: [];
}
Gets elements by case insensitive tagname.
TODO: This should be removed when phpunit-dom-assertions gets released.
DOMDocument
$dom
required - $dom string
$tag
required - $tag DOMNodeList
protected
static
function
getElementsByCaseInsensitiveTagName(DOMDocument
$dom
,
$tag
)
{
$elements
=
$dom
->getElementsByTagName(
strtolower
(
$tag
));
if
(
$elements
->length == 0) {
$elements
=
$dom
->getElementsByTagName(
strtoupper
(
$tag
));
}
return
$elements
;
}
Get the text value of this node's child text node.
TODO: This should be removed when phpunit-dom-assertions gets released.
DOMNode
$node
required - $node string
protected
static
function
getNodeText(DOMNode
$node
)
{
if
(!
$node
->childNodes
instanceof
DOMNodeList) {
return
''
;
}
$result
=
''
;
foreach
(
$node
->childNodes
as
$childNode
) {
if
(
$childNode
->nodeType === XML_TEXT_NODE ||
$childNode
->nodeType === XML_CDATA_SECTION_NODE) {
$result
.= trim(
$childNode
->data) .
' '
;
}
else
{
$result
.= self::getNodeText(
$childNode
);
}
}
return
str_replace
(
' '
,
' '
,
$result
);
}