/[drupal]/drupal/modules/simpletest/simpletest.pages.inc
ViewVC logotype

Contents of /drupal/modules/simpletest/simpletest.pages.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.19 - (show annotations) (download) (as text)
Tue Oct 20 00:05:38 2009 UTC (5 weeks, 3 days ago) by dries
Branch: MAIN
Changes since 1.18: +3 -3 lines
File MIME type: text/x-php
- Patch #598570 by asimmonds: Fixed test group checkboxes no longer selecting all groups tests.
1 <?php
2 // $Id: simpletest.pages.inc,v 1.18 2009/10/09 01:00:03 dries Exp $
3
4 /**
5 * @file
6 * Page callbacks for simpletest module.
7 */
8
9 /**
10 * List tests arranged in groups that can be selected and run.
11 */
12 function simpletest_test_form($form) {
13 $form['tests'] = array(
14 '#type' => 'fieldset',
15 '#title' => t('Tests'),
16 '#description' => t('Select the test(s) or test group(s) you would like to run, and click <em>Run tests</em>.'),
17 );
18
19 $form['tests']['table'] = array(
20 '#theme' => 'simpletest_test_table',
21 );
22
23 // Generate the list of tests arranged by group.
24 $groups = simpletest_test_get_all();
25 foreach ($groups as $group => $tests) {
26 $form['tests']['table'][$group] = array(
27 '#collapsed' => TRUE,
28 );
29
30 foreach ($tests as $class => $info) {
31 $form['tests']['table'][$group][$class] = array(
32 '#type' => 'checkbox',
33 '#title' => $info['name'],
34 '#description' => $info['description'],
35 );
36 }
37 }
38
39 // Operation buttons.
40 $form['tests']['op'] = array(
41 '#type' => 'submit',
42 '#value' => t('Run tests'),
43 );
44 $form['clean'] = array(
45 '#type' => 'fieldset',
46 '#collapsible' => FALSE,
47 '#collapsed' => FALSE,
48 '#title' => t('Clean test environment'),
49 '#description' => t('Remove tables with the prefix "simpletest" and temporary directories that are left over from tests that crashed. This is intended for developers when creating tests.'),
50 );
51 $form['clean']['op'] = array(
52 '#type' => 'submit',
53 '#value' => t('Clean environment'),
54 '#submit' => array('simpletest_clean_environment'),
55 );
56
57 return $form;
58 }
59
60 /**
61 * Theme the test list generated by simpletest_test_form() into a table.
62 *
63 * @param $variables
64 * An associative array containing:
65 * - table: Form array that represent a table.
66 *
67 * @return
68 * HTML output.
69 */
70 function theme_simpletest_test_table($variables) {
71 $table = $variables['table'];
72
73 drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
74 drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js');
75
76 // Create header for test selection table.
77 $header = array(
78 theme('table_select_header_cell'),
79 array('data' => t('Test'), 'class' => array('simpletest_test')),
80 array('data' => t('Description'), 'class' => array('simpletest_description')),
81 );
82
83 // Define the images used to expand/collapse the test groups.
84 $js = array(
85 'images' => array(
86 theme('image', array('path' => 'misc/menu-collapsed.png', 'alt' => 'Expand', 'title' => 'Expand')),
87 theme('image', array('path' => 'misc/menu-expanded.png', 'alt' => 'Collapsed', 'title' => 'Collapsed')),
88 ),
89 );
90
91 // Cycle through each test group and create a row.
92 $rows = array();
93 foreach (element_children($table) as $key) {
94 $element = &$table[$key];
95 $row = array();
96
97 // Make the class name safe for output on the page by replacing all
98 // non-word/decimal characters with a dash (-).
99 $test_class = strtolower(trim(preg_replace("/[^\w\d]/", "-", $key)));
100
101 // Select the right "expand"/"collapse" image, depending on whether the
102 // category is expanded (at least one test selected) or not.
103 $collapsed = !empty($element['#collapsed']);
104 $image_index = $collapsed ? 0 : 1;
105
106 // Place-holder for checkboxes to select group of tests.
107 $row[] = array('id' => $test_class, 'class' => array('simpletest-select-all'));
108
109 // Expand/collapse image and group title.
110 $row[] = array(
111 'data' => '<div class="simpletest-image" id="simpletest-test-group-' . $test_class . '"></div>&nbsp;' .
112 '<label for="' . $test_class . '-select-all" class="simpletest-group-label">' . $key . '</label>',
113 'style' => 'font-weight: bold;'
114 );
115
116 $row[] = '&nbsp;';
117
118 $rows[] = array('data' => $row, 'class' => array('simpletest-group'));
119
120 // Add individual tests to group.
121 $current_js = array(
122 'testClass' => $test_class . '-test',
123 'testNames' => array(),
124 'imageDirection' => $image_index,
125 'clickActive' => FALSE,
126 );
127
128 // Sorting $element by children's #title attribute instead of by class name.
129 uasort($element, '_simpletest_sort_by_title');
130
131 // Cycle through each test within the current group.
132 foreach (element_children($element) as $test_name) {
133 $test = $element[$test_name];
134 $row = array();
135
136 $current_js['testNames'][] = $test['#id'];
137
138 // Store test title and description so that checkbox won't render them.
139 $title = $test['#title'];
140 $description = $test['#description'];
141
142 unset($test['#title']);
143 unset($test['#description']);
144
145 // Test name is used to determine what tests to run.
146 $test['#name'] = $test_name;
147
148 $row[] = drupal_render($test);
149 $row[] = theme('indentation', array('size' => 1)) . '<label for="' . $test['#id'] . '">' . $title . '</label>';
150 $row[] = '<div class="description">' . $description . '</div>';
151
152 $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($collapsed ? 'js-hide' : '')));
153 }
154 $js['simpletest-test-group-' . $test_class] = $current_js;
155 unset($table[$key]);
156 }
157
158 // Add js array of settings.
159 drupal_add_js(array('simpleTest' => $js), 'setting');
160
161 if (empty($rows)) {
162 return '<strong>' . t('No tests to display.') . '</strong>';
163 }
164 else {
165 return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'simpletest-form-table')));
166 }
167 }
168
169 /**
170 * Sort element by title instead of by class name.
171 */
172 function _simpletest_sort_by_title($a, $b) {
173 // This is for parts of $element that are not an array.
174 if (!isset($a['#title']) || !isset($b['#title'])) {
175 return 1;
176 }
177
178 return strcasecmp($a['#title'], $b['#title']);
179 }
180
181 /**
182 * Run selected tests.
183 */
184 function simpletest_test_form_submit($form, &$form_state) {
185 // Get list of tests.
186 $tests_list = array();
187 foreach ($form_state['values'] as $class_name => $value) {
188 if (class_exists($class_name) && $value === 1) {
189 $tests_list[] = $class_name;
190 }
191 }
192 if (count($tests_list) > 0 ) {
193 simpletest_run_tests($tests_list, 'drupal');
194 }
195 else {
196 drupal_set_message(t('No test(s) selected.'), 'error');
197 }
198 }
199
200 /**
201 * Test results form for $test_id.
202 */
203 function simpletest_result_form($form, &$form_state, $test_id) {
204 // Make sure there are test results to display and a re-run is not being performed.
205 $results = array();
206 if (is_numeric($test_id) && !$results = simpletest_result_get($test_id)) {
207 drupal_set_message(t('No test results to display.'), 'error');
208 drupal_goto('admin/config/development/testing');
209 return $form;
210 }
211
212 // Load all classes and include CSS.
213 drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
214
215 // Keep track of which test cases passed or failed.
216 $filter = array(
217 'pass' => array(),
218 'fail' => array(),
219 );
220
221 // Summary result fieldset.
222 $form['result'] = array(
223 '#type' => 'fieldset',
224 '#title' => t('Results'),
225 );
226 $form['result']['summary'] = $summary = array(
227 '#theme' => 'simpletest_result_summary',
228 '#pass' => 0,
229 '#fail' => 0,
230 '#exception' => 0,
231 '#debug' => 0,
232 );
233
234 // Cycle through each test group.
235 $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status')));
236 $form['result']['results'] = array();
237 foreach ($results as $group => $assertions) {
238 // Create group fieldset with summary information.
239 $info = call_user_func(array($group, 'getInfo'));
240 $form['result']['results'][$group] = array(
241 '#type' => 'fieldset',
242 '#title' => $info['name'],
243 '#description' => $info['description'],
244 '#collapsible' => TRUE,
245 );
246 $form['result']['results'][$group]['summary'] = $summary;
247 $group_summary = &$form['result']['results'][$group]['summary'];
248
249 // Create table of assertions for the group.
250 $rows = array();
251 foreach ($assertions as $assertion) {
252 $row = array();
253 $row[] = $assertion->message;
254 $row[] = $assertion->message_group;
255 $row[] = basename($assertion->file);
256 $row[] = $assertion->line;
257 $row[] = $assertion->function;
258 $row[] = simpletest_result_status_image($assertion->status);
259
260 $class = 'simpletest-' . $assertion->status;
261 if ($assertion->message_group == 'Debug') {
262 $class = 'simpletest-debug';
263 }
264 $rows[] = array('data' => $row, 'class' => array($class));
265
266 $group_summary['#' . $assertion->status]++;
267 $form['result']['summary']['#' . $assertion->status]++;
268 }
269 $form['result']['results'][$group]['table'] = array(
270 '#theme' => 'table',
271 '#header' => $header,
272 '#rows' => $rows,
273 );
274
275 // Set summary information.
276 $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0;
277 $form['result']['results'][$group]['#collapsed'] = $group_summary['#ok'] && !$group_summary['#debug'];
278
279 // Store test group (class) as for use in filter.
280 $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
281 }
282
283 // Overal summary status.
284 $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
285
286 // Actions.
287 $form['#action'] = url('admin/config/development/testing/results/re-run');
288 $form['action'] = array(
289 '#type' => 'fieldset',
290 '#title' => t('Actions'),
291 '#attributes' => array('class' => array('container-inline')),
292 '#weight' => -11,
293 );
294
295 $form['action']['filter'] = array(
296 '#type' => 'select',
297 '#title' => 'Filter',
298 '#options' => array(
299 'all' => t('All (@count)', array('@count' => count($filter['pass']) + count($filter['fail']))),
300 'pass' => t('Pass (@count)', array('@count' => count($filter['pass']))),
301 'fail' => t('Fail (@count)', array('@count' => count($filter['fail']))),
302 ),
303 );
304 $form['action']['filter']['#default_value'] = ($filter['fail'] ? 'fail' : 'all');
305
306 // Catagorized test classes for to be used with selected filter value.
307 $form['action']['filter_pass'] = array(
308 '#type' => 'hidden',
309 '#default_value' => implode(',', $filter['pass']),
310 );
311 $form['action']['filter_fail'] = array(
312 '#type' => 'hidden',
313 '#default_value' => implode(',', $filter['fail']),
314 );
315
316 $form['action']['op'] = array(
317 '#type' => 'submit',
318 '#value' => t('Run tests'),
319 );
320
321 $form['action']['return'] = array(
322 '#markup' => l(t('Return to list'), 'admin/config/development/testing'),
323 );
324
325 if (is_numeric($test_id)) {
326 simpletest_clean_results_table($test_id);
327 }
328
329 return $form;
330 }
331
332 /**
333 * Re-run the tests that match the filter.
334 */
335 function simpletest_result_form_submit($form, &$form_state) {
336 $pass = $form_state['values']['filter_pass'] ? explode(',', $form_state['values']['filter_pass']) : array();
337 $fail = $form_state['values']['filter_fail'] ? explode(',', $form_state['values']['filter_fail']) : array();
338
339 if ($form_state['values']['filter'] == 'all') {
340 $classes = array_merge($pass, $fail);
341 }
342 else if ($form_state['values']['filter'] == 'pass') {
343 $classes = $pass;
344 }
345 else {
346 $classes = $fail;
347 }
348
349 if (!$classes) {
350 $form_state['redirect'] = 'admin/config/development/testing';
351 return;
352 }
353
354 $form_state_execute = array('values' => array());
355 foreach ($classes as $class) {
356 $form_state_execute['values'][$class] = 1;
357 }
358
359 simpletest_test_form_submit(array(), $form_state_execute);
360 }
361
362 /**
363 * Add wrapper div with class based on summary status.
364 *
365 * @return HTML output.
366 */
367 function theme_simpletest_result_summary($variables) {
368 $form = $variables['form'];
369 return '<div class="simpletest-' . ($form['#ok'] ? 'pass' : 'fail') . '">' . _simpletest_format_summary_line($form) . '</div>';
370 }
371
372 /**
373 * Get test results for $test_id.
374 *
375 * @param $test_id The test_id to retrieve results of.
376 * @return Array of results grouped by test_class.
377 */
378 function simpletest_result_get($test_id) {
379 $results = db_select('simpletest')
380 ->fields('simpletest')
381 ->condition('test_id', $test_id)
382 ->orderBy('test_class')
383 ->orderBy('message_id')
384 ->execute();
385
386 $test_results = array();
387 foreach ($results as $result) {
388 if (!isset($test_results[$result->test_class])) {
389 $test_results[$result->test_class] = array();
390 }
391 $test_results[$result->test_class][] = $result;
392 }
393 return $test_results;
394 }
395
396 /**
397 * Get the appropriate image for the status.
398 *
399 * @param $status Status string, either: pass, fail, exception.
400 * @return HTML image or false.
401 */
402 function simpletest_result_status_image($status) {
403 // $map does not use drupal_static() as its value never changes.
404 static $map;
405
406 if (!isset($map)) {
407 $map = array(
408 'pass' => theme('image', array('path' => 'misc/watchdog-ok.png', 'alt' => t('Pass'))),
409 'fail' => theme('image', array('path' => 'misc/watchdog-error.png', 'alt' => t('Fail'))),
410 'exception' => theme('image', array('path' => 'misc/watchdog-warning.png', 'alt' => t('Exception'))),
411 'debug' => theme('image', array('path' => 'misc/watchdog-warning.png', 'alt' => t('Debug'))),
412 );
413 }
414 if (isset($map[$status])) {
415 return $map[$status];
416 }
417 return FALSE;
418 }
419
420 /**
421 * Provides settings form for SimpleTest variables.
422 */
423 function simpletest_settings_form($form, &$form_state) {
424 $form['general'] = array(
425 '#type' => 'fieldset',
426 '#title' => t('General'),
427 );
428 $form['general']['simpletest_clear_results'] = array(
429 '#type' => 'checkbox',
430 '#title' => t('Clear results after each complete test suite run'),
431 '#description' => t('By default SimpleTest will clear the results after they have been viewed on the results page, but in some cases it may be useful to leave the results in the database. The results can then be viewed at <em>admin/config/development/testing/[test_id]</em>. The test ID can be found in the database, simpletest table, or kept track of when viewing the results the first time. Additionally, some modules may provide more analaysis or features that require this setting to be disabled.'),
432 '#default_value' => variable_get('simpletest_clear_results', TRUE),
433 );
434 $form['general']['simpletest_verbose'] = array(
435 '#type' => 'checkbox',
436 '#title' => t('Provide verbose information when running tests'),
437 '#description' => t('The verbose data will be printed along with the standard assertions and is useful for debugging. The verbose data will be erased between each test suite run. The verbose data output is very detailed and should only be used when debugging.'),
438 '#default_value' => variable_get('simpletest_verbose', FALSE),
439 );
440
441 $form['httpauth'] = array(
442 '#type' => 'fieldset',
443 '#title' => t('HTTP authentication credentials'),
444 '#description' => t('HTTP auth settings to be used by the SimpleTest browser during testing. Useful when the site requires basic HTTP authentication.'),
445 );
446 $form['httpauth']['simpletest_username'] = array(
447 '#type' => 'textfield',
448 '#title' => t('Username'),
449 '#default_value' => variable_get('simpletest_username', ''),
450 );
451 $form['httpauth']['simpletest_password'] = array(
452 '#type' => 'textfield',
453 '#title' => t('Password'),
454 '#default_value' => variable_get('simpletest_password', ''),
455 );
456
457 return system_settings_form($form);
458 }

  ViewVC Help
Powered by ViewVC 1.1.2