Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
ab07b4cd
Commit
ab07b4cd
authored
Sep 10, 2008
by
webchick
Browse files
#305077
by DamZ, boombatower, and cwgordon7: Rework SimpleTest backend.
parent
5ba4c533
Changes
5
Hide whitespace changes
Inline
Side-by-side
includes/common.inc
View file @
ab07b4cd
...
...
@@ -627,6 +627,35 @@ function drupal_error_handler($errno, $message, $filename, $line, $context) {
}
}
/**
* Gets the last caller (file name and line of the call, function in which the
* call originated) from a backtrace.
*
* @param $backtrace
* A standard PHP backtrace.
* @return
* An associative array with keys 'file', 'line' and 'function'.
*/
function
_drupal_get_last_caller
(
$backtrace
)
{
// The first trace is the call itself.
// It gives us the line and the file of the last call.
$call
=
$backtrace
[
0
];
// The second call give us the function where the call originated.
if
(
isset
(
$backtrace
[
1
]))
{
if
(
isset
(
$backtrace
[
1
][
'class'
]))
{
$call
[
'function'
]
=
$backtrace
[
1
][
'class'
]
.
$backtrace
[
1
][
'type'
]
.
$backtrace
[
1
][
'function'
]
.
'()'
;
}
else
{
$call
[
'function'
]
=
$backtrace
[
1
][
'function'
]
.
'()'
;
}
}
else
{
$call
[
'function'
]
=
'main()'
;
}
return
$call
;
}
function
_fix_gpc_magic
(
&
$item
)
{
if
(
is_array
(
$item
))
{
array_walk
(
$item
,
'_fix_gpc_magic'
);
...
...
modules/simpletest/drupal_web_test_case.php
View file @
ab07b4cd
...
...
@@ -43,55 +43,75 @@ function __construct($test_id = NULL) {
* The message string.
* @param $group
* WHich group this assert belongs to.
* @param $
custom_
caller
* @param $caller
* By default, the assert comes from a function which names start with
* 'test'. Instead, you can specify where this assert originates from
* by passing in an associative array as $
custom_
caller. Key 'file' is
* by passing in an associative array as $caller. Key 'file' is
* the name of the source file, 'line' is the line number and 'function'
* is the caller function itself.
*/
protected
function
_assert
(
$status
,
$message
=
''
,
$group
=
'Other'
,
$
custom_
caller
=
NULL
)
{
protected
function
_assert
(
$status
,
$message
=
''
,
$group
=
'Other'
,
$caller
=
NULL
)
{
global
$db_prefix
;
// Convert boolean status to string status.
if
(
is_bool
(
$status
))
{
$status
=
$status
?
'pass'
:
'fail'
;
}
// Increment summary result counter.
$this
->
_results
[
'#'
.
$status
]
++
;
if
(
!
isset
(
$custom_caller
))
{
$callers
=
debug_backtrace
();
array_shift
(
$callers
);
foreach
(
$callers
as
$function
)
{
if
(
substr
(
$function
[
'function'
],
0
,
6
)
!=
'assert'
&&
$function
[
'function'
]
!=
'pass'
&&
$function
[
'function'
]
!=
'fail'
)
{
break
;
}
}
}
else
{
$function
=
$custom_caller
;
// Get the function information about the call to the assertion method.
if
(
!
$caller
)
{
$caller
=
$this
->
getAssertionCall
();
}
// Switch to non-testing database to store results in.
$current_db_prefix
=
$db_prefix
;
$db_prefix
=
$this
->
db_prefix_original
;
db_insert
(
'simpletest'
)
->
fields
(
array
(
// Creation assertion array that can be displayed while tests are running.
$this
->
_assertions
[]
=
$assertion
=
array
(
'test_id'
=>
$this
->
test_id
,
'test_class'
=>
get_class
(
$this
),
'status'
=>
$status
,
'message'
=>
substr
(
$message
,
0
,
255
),
// Some messages are too long for the database.
'message_group'
=>
$group
,
'caller'
=>
$function
[
'function'
],
'line'
=>
$function
[
'line'
],
'file'
=>
$function
[
'file'
],
))
->
execute
();
$this
->
_assertions
[]
=
array
(
'test_class'
=>
get_class
(
$this
),
'status'
=>
$status
,
'message'
=>
$message
,
'group'
=>
$group
,
'function'
=>
$
function
[
'function'
],
'line'
=>
$
function
[
'line'
],
'file'
=>
$
function
[
'file'
],
'
message_
group'
=>
$group
,
'function'
=>
$
caller
[
'function'
],
'line'
=>
$
caller
[
'line'
],
'file'
=>
$
caller
[
'file'
],
);
// Store assertion for display after the test has completed.
db_insert
(
'simpletest'
)
->
fields
(
$assertion
)
->
execute
();
// Return to testing prefix.
$db_prefix
=
$current_db_prefix
;
return
$status
;
}
/**
* Cycles through backtrace until the first non-assertion method is found.
*
* @return
* Array representing the true caller.
*/
protected
function
getAssertionCall
()
{
$backtrace
=
debug_backtrace
();
// The first element is the call. The second element is the caller.
// We skip calls that occured in one of the methods of DrupalWebTestCase
// or in an assertion function.
while
((
$caller
=
$backtrace
[
1
])
&&
((
isset
(
$caller
[
'class'
])
&&
$caller
[
'class'
]
==
'DrupalWebTestCase'
)
||
substr
(
$caller
[
'function'
],
0
,
6
)
==
'assert'
))
{
// We remove that call.
array_shift
(
$backtrace
);
}
return
_drupal_get_last_caller
(
$backtrace
);
}
/**
* Check to see if a value is not false (not an empty string, 0, NULL, or FALSE).
*
...
...
@@ -263,11 +283,11 @@ protected function fail($message = NULL, $group = 'Other') {
* The message to display along with the assertion.
* @param $group
* The type of assertion - examples are "Browser", "PHP".
* @param $
custom_
caller
* @param $caller
* The caller of the error.
*/
protected
function
error
(
$message
=
''
,
$group
=
'Other'
,
$
custom_
caller
=
NULL
)
{
return
$this
->
_assert
(
'exception'
,
$message
,
$group
,
$
custom_
caller
);
protected
function
error
(
$message
=
''
,
$group
=
'Other'
,
$caller
=
NULL
)
{
return
$this
->
_assert
(
'exception'
,
$message
,
$group
,
$caller
);
}
/**
...
...
@@ -281,8 +301,13 @@ function run() {
// If the current method starts with "test", run it - it's a test.
if
(
strtolower
(
substr
(
$method
,
0
,
4
))
==
'test'
)
{
$this
->
setUp
();
$this
->
$method
();
// Finish up.
try
{
$this
->
$method
();
// Finish up.
}
catch
(
Exception
$e
)
{
$this
->
exceptionHandler
(
$e
);
}
$this
->
tearDown
();
}
}
...
...
@@ -308,15 +333,28 @@ function errorHandler($severity, $message, $file = NULL, $line = NULL) {
E_USER_NOTICE
=>
'User notice'
,
E_RECOVERABLE_ERROR
=>
'Recoverable error'
,
);
$this
->
error
(
$message
,
$error_map
[
$severity
],
array
(
'function'
=>
''
,
'line'
=>
$line
,
'file'
=>
$file
,
));
$backtrace
=
debug_backtrace
();
$this
->
error
(
$message
,
$error_map
[
$severity
],
_drupal_get_last_caller
(
$backtrace
));
}
return
TRUE
;
}
/**
* Handle exceptions.
*
* @see set_exception_handler
*/
function
exceptionHandler
(
$exception
)
{
$backtrace
=
$exception
->
getTrace
();
// Push on top of the backtrace the call that generated the exception.
array_unshift
(
$backtrace
,
array
(
'line'
=>
$exception
->
getLine
(),
'file'
=>
$exception
->
getFile
(),
));
$this
->
error
(
$exception
->
getMessage
(),
'Uncaught exception'
,
_drupal_get_last_caller
(
$backtrace
));
}
/**
* Creates a node based on default settings.
*
...
...
@@ -405,7 +443,7 @@ function drupalCreateContentType($settings = array()) {
node_types_rebuild
();
$this
->
assertEqual
(
$saved_type
,
SAVED_NEW
,
t
(
'Created content type %type.'
,
array
(
'%type'
=>
$type
->
type
)));
// Reset permissions so that permissions for this content type are available.
$this
->
checkPermissions
(
array
(),
TRUE
);
...
...
@@ -645,7 +683,7 @@ function setUp() {
// Generate temporary prefixed database to ensure that tests have a clean starting point.
$db_prefix
=
'simpletest'
.
mt_rand
(
1000
,
1000000
);
include_once
'./includes/install.inc'
;
drupal_install_system
();
...
...
@@ -659,7 +697,7 @@ function setUp() {
// stale data for the previous run's database prefix and all
// calls to it will fail.
drupal_get_schema
(
NULL
,
TRUE
);
// Run default profile tasks.
$task
=
'profile'
;
default_profile_tasks
(
$task
,
''
);
...
...
@@ -732,7 +770,6 @@ function tearDown() {
// Close the CURL handler.
$this
->
curlClose
();
restore_error_handler
();
}
}
...
...
@@ -807,7 +844,7 @@ protected function parse() {
// them.
@
$htmlDom
=
DOMDocument
::
loadHTML
(
$this
->
_content
);
if
(
$htmlDom
)
{
$this
->
ass
ertTrue
(
TRUE
,
t
(
'Valid HTML found on "@path"'
,
array
(
'@path'
=>
$this
->
getUrl
())),
t
(
'Browser'
));
$this
->
p
ass
(
t
(
'Valid HTML found on "@path"'
,
array
(
'@path'
=>
$this
->
getUrl
())),
t
(
'Browser'
));
// It's much easier to work with simplexml than DOM, luckily enough
// we can just simply import our DOM tree.
$this
->
elements
=
simplexml_import_dom
(
$htmlDom
);
...
...
@@ -1290,7 +1327,7 @@ function assertNoRaw($raw, $message = '%s found', $group = 'Other') {
* TRUE on pass, FALSE on fail.
*/
function
assertText
(
$text
,
$message
=
''
,
$group
=
'Other'
)
{
return
$this
->
assertTextHelper
(
$text
,
$message
,
$group
=
'Other'
,
FALSE
);
return
$this
->
assertTextHelper
(
$text
,
$message
,
$group
,
FALSE
);
}
/**
...
...
modules/simpletest/simpletest.install
View file @
ab07b4cd
...
...
@@ -177,25 +177,25 @@ function simpletest_schema() {
'default'
=>
''
,
'description'
=>
t
(
'The message group this message belongs to. For example: warning, browser, user.'
),
),
'
caller
'
=>
array
(
'
function
'
=>
array
(
'type'
=>
'varchar'
,
'length'
=>
255
,
'not null'
=>
TRUE
,
'default'
=>
''
,
'description'
=>
t
(
'Name of the
caller
function or method that created this message.'
),
'description'
=>
t
(
'Name of the
assertion
function or method that created this message.'
),
),
'line'
=>
array
(
'type'
=>
'int'
,
'not null'
=>
TRUE
,
'default'
=>
0
,
'description'
=>
t
(
'Line number o
f the
calle
r
.'
),
'description'
=>
t
(
'Line number o
n which the function is
calle
d
.'
),
),
'file'
=>
array
(
'type'
=>
'varchar'
,
'length'
=>
255
,
'not null'
=>
TRUE
,
'default'
=>
''
,
'description'
=>
t
(
'Name of the file where the calle
r is
.'
),
'description'
=>
t
(
'Name of the file where the
function is
calle
d
.'
),
),
),
'primary key'
=>
array
(
'message_id'
),
...
...
modules/simpletest/simpletest.module
View file @
ab07b4cd
...
...
@@ -106,7 +106,7 @@ function simpletest_test_form() {
$result
->
message_group
,
basename
(
$result
->
file
),
$result
->
line
,
$result
->
caller
,
$result
->
function
,
$map
[
$status
],
),
'class'
=>
"simpletest-
$status
"
,
...
...
modules/simpletest/simpletest.test
View file @
ab07b4cd
...
...
@@ -106,17 +106,36 @@ class SimpleTestTestCase extends DrupalWebTestCase {
$this
->
drupalCreateUser
(
array
(
$this
->
invalid_permission
));
$this
->
pass
(
t
(
'Test ID is @id.'
,
array
(
'@id'
=>
$this
->
test_id
)));
// Generates a warning
$i
=
1
/
0
;
// Call an assert function specific to that class.
$this
->
assertNothing
();
}
/**
* Assert nothing.
*/
function
assertNothing
()
{
$this
->
pass
(
"This is nothing."
);
}
/**
* Confirm that the stub test produced the desired results.
*/
function
confirmStubTestResults
()
{
$this
->
assertAssertion
(
$this
->
pass
,
'Other'
,
'Pass'
);
$this
->
assertAssertion
(
$this
->
fail
,
'Other'
,
'Fail'
);
$this
->
assertAssertion
(
$this
->
pass
,
'Other'
,
'Pass'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()'
);
$this
->
assertAssertion
(
$this
->
fail
,
'Other'
,
'Fail'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()'
);
$this
->
assertAssertion
(
t
(
'Created permissions: @perms'
,
array
(
'@perms'
=>
$this
->
valid_permission
)),
'Role'
,
'Pass'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()'
);
$this
->
assertAssertion
(
t
(
'Invalid permission %permission.'
,
array
(
'%permission'
=>
$this
->
invalid_permission
)),
'Role'
,
'Fail'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()'
);
// Check that a warning is catched by simpletest.
$this
->
assertAssertion
(
'Division by zero'
,
'Warning'
,
'Fail'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()'
);
$this
->
assertAssertion
(
t
(
'Created permissions: @perms'
,
array
(
'@perms'
=>
$this
->
valid_permission
)),
'Role'
,
'Pass'
);
$this
->
assertAssertion
(
t
(
'Invalid permission %permission.'
,
array
(
'%permission'
=>
$this
->
invalid_permission
)),
'Role'
,
'Fail
'
);
// Check that the backtracing code works for specific assert function.
$this
->
assertAssertion
(
'This is nothing.'
,
'Other'
,
'Pass'
,
'simpletest.test'
,
'SimpleTestTestCase->stubTest()
'
);
$this
->
test_ids
[]
=
$test_id
=
$this
->
getTestIdFromResults
();
$this
->
assertTrue
(
$test_id
,
t
(
'Found test ID in results.'
));
...
...
@@ -141,20 +160,24 @@ class SimpleTestTestCase extends DrupalWebTestCase {
* @param string $message Assertion message.
* @param string $type Assertion type.
* @param string $status Assertion status.
* @param string $file File where the assertion originated.
* @param string $functuion Function where the assertion originated.
* @return Assertion result.
*/
function
assertAssertion
(
$message
,
$type
,
$status
)
{
function
assertAssertion
(
$message
,
$type
,
$status
,
$file
,
$function
)
{
$message
=
trim
(
strip_tags
(
$message
));
$found
=
FALSE
;
foreach
(
$this
->
results
[
'assertions'
]
as
$assertion
)
{
if
(
$assertion
[
'message'
]
==
$message
&&
$assertion
[
'type'
]
==
$type
&&
$assertion
[
'status'
]
==
$status
)
{
$assertion
[
'status'
]
==
$status
&&
$assertion
[
'file'
]
==
$file
&&
$assertion
[
'function'
]
==
$function
)
{
$found
=
TRUE
;
break
;
}
}
return
$this
->
assertTrue
(
$found
,
t
(
'Found assertion {"@message", "@type", "@status"}.'
,
array
(
'@message'
=>
$message
,
'@type'
=>
$type
,
'@status'
=>
$status
)));
return
$this
->
assertTrue
(
$found
,
t
(
'Found assertion {"@message", "@type", "@status"
, "@file", "@function"
}.'
,
array
(
'@message'
=>
$message
,
'@type'
=>
$type
,
'@status'
=>
$status
,
"@file"
=>
$file
,
"@function"
=>
$function
)));
}
/**
...
...
@@ -175,6 +198,9 @@ class SimpleTestTestCase extends DrupalWebTestCase {
$assertion
=
array
();
$assertion
[
'message'
]
=
$this
->
asText
(
$row
->
td
[
0
]);
$assertion
[
'type'
]
=
$this
->
asText
(
$row
->
td
[
1
]);
$assertion
[
'file'
]
=
$this
->
asText
(
$row
->
td
[
2
]);
$assertion
[
'line'
]
=
$this
->
asText
(
$row
->
td
[
3
]);
$assertion
[
'function'
]
=
$this
->
asText
(
$row
->
td
[
4
]);
$ok_url
=
(
url
(
'misc/watchdog-ok.png'
)
==
'misc/watchdog-ok.png'
)
?
'misc/watchdog-ok.png'
:
(
base_path
()
.
'misc/watchdog-ok.png'
);
$assertion
[
'status'
]
=
(
$row
->
td
[
5
]
->
img
[
'src'
]
==
$ok_url
)
?
'Pass'
:
'Fail'
;
$results
[
'assertions'
][]
=
$assertion
;
...
...
@@ -212,7 +238,7 @@ class SimpleTestTestCase extends DrupalWebTestCase {
if
(
!
is_object
(
$element
))
{
return
$this
->
fail
(
'The element is not an element.'
);
}
return
trim
(
strip_tags
(
$element
->
asXML
()));
return
trim
(
html_entity_decode
(
strip_tags
(
$element
->
asXML
()))
)
;
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment