/[drupal]/contributions/modules/simpletest_unit/simpletest_unit.module
ViewVC logotype

Contents of /contributions/modules/simpletest_unit/simpletest_unit.module

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


Revision 1.17 - (show annotations) (download) (as text)
Sun Apr 20 17:20:20 2008 UTC (19 months, 1 week ago) by boombatower
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +6 -3 lines
File MIME type: text/x-php
Add array around function name in steps array.
1 <?php
2 // $Id: simpletest_unit.module,v 1.16 2008/04/20 07:41:46 boombatower Exp $
3
4 define('SIMPLETEST_UNIT_CALLBACK', 'test_clearinghouse');
5
6 /**
7 * Implementation of hook_menu().
8 */
9 function simpletest_unit_menu() {
10 $items['admin/build/simpletest/simpletest_unit'] = array(
11 'title' => 'SimpleTest unit',
12 'description' => 'Generate unit test stubs.',
13 'page callback' => 'drupal_get_form',
14 'page arguments' => array('simpletest_unit_settings'),
15 'access arguments' => array('access administration pages')
16 );
17 return $items;
18 }
19
20 /**
21 * Stub generation form.
22 */
23 function simpletest_unit_settings() {
24 $form = array();
25 $form['generate'] = array(
26 '#type' => 'fieldset',
27 '#title' => t('Generate Test Stubs'),
28 '#description' => t('Unit test stubs will be generated in the <i>simpletest_unit</i> directory so as to not
29 override with the <i>simpletest</i> module. Running the stub generation will override any files in the
30 <i>tests</i> directory in the <i>simpletest_unit</i> module directory. Please be patient while stubs are
31 generated as the process is know to take about 20 seconds.')
32 );
33 $form['generate']['op'] = array(
34 '#type' => 'submit',
35 '#value' => t('Generate stubs'),
36 '#submit' => array('simpletest_unit_generate')
37 );
38 return $form;
39 }
40
41 /**
42 * Generate unit test stubs.
43 */
44 function simpletest_unit_generate() {
45 require_once(drupal_get_path('module', 'simpletest_unit') .'/simpletest_unit_token_wrapper.php');
46
47 $directories = array('includes', 'modules'); // Directories to scan recursively.
48
49 // Scan files to determine what functions are define by drupal.
50 $wrappers = array();
51 foreach ($directories as $directory) {
52 $wrappers += simpletest_unit_scan_directory($directory);
53 }
54
55 // Get list of all drupal defined functions.
56 $function_names = array();
57 foreach ($wrappers as $wrapper) {
58 $function_names = array_merge($function_names, $wrapper->get_function_names());
59 }
60
61 drupal_set_message(t('Found %functions functions defined in %files files.', array('%functions' => count($function_names), '%files' => count($wrappers))));
62
63 // Remove non-drupal function calls, since only drupal functions need to be overridden.
64 foreach ($wrappers as $wrapper) {
65 $wrapper->clean_calls($function_names);
66 }
67
68 // Generate stub tests.
69 $tests_folder = drupal_get_path('module', 'simpletest_unit') .'/tests/';
70 $drupal_stub_folder = drupal_get_path('module', 'simpletest_unit') .'/drupal_stub/';
71 $drupal_orginal_folder = drupal_get_path('module', 'simpletest_unit') .'/drupal_original/';
72 foreach ($wrappers as $wrapper) {
73 $out = '';
74 foreach ($wrapper->get_functions() as $function) {
75 $out .= simpletest_unit_wrap_function($function['name'], $function['calls']);
76 }
77 $filename = basename($wrapper->get_file_path());
78 $out = simpletest_unit_wrap_test($filename, $out);
79 file_put_contents($tests_folder . $filename .'.test', $out);
80
81 simpletest_unit_check_directories($drupal_stub_folder, dirname($wrapper->get_file_path()));
82 file_put_contents($drupal_stub_folder . $wrapper->get_file_path(), simpletest_unit_generate_stub($wrapper->get_functions()));
83 copy($wrapper->get_file_path(), $drupal_orginal_folder . $wrapper->get_file_path());
84 simpletest_unit_prefix_original($drupal_orginal_folder . $wrapper->get_file_path(), $wrapper->get_functions());
85 }
86
87 drupal_set_message(t('Code stubs generated.'));
88 }
89
90 function simpletest_unit_prefix_original($file, array $functions) {
91 $contents = file_get_contents($file);
92 foreach ($functions as $function) {
93 $contents = str_replace("function {$function['name']}", "function original_{$function['name']}", $contents);
94 }
95 file_put_contents($file, $contents);
96 }
97
98 function simpletest_unit_check_directories($base, $location) {
99 $path = $base;
100 $parts = explode('/', $location);
101 foreach ($parts as $part) {
102 $path = $path . $part;
103 file_check_directory($path, FILE_CREATE_DIRECTORY);
104 file_check_directory(str_replace('drupal_stub', 'drupal_original', $path), FILE_CREATE_DIRECTORY);
105 $path .= '/';
106 }
107 }
108
109 function simpletest_unit_generate_stub(array $functions) {
110 $out = '';
111 foreach ($functions as $function) {
112 $out .= "function {$function['name']}(" . simpletest_unit_export_parameters($function['parameters']) . ") {\n";
113 $out .= " return " . SIMPLETEST_UNIT_CALLBACK . "('{$function['name']}'";
114 $out .= (count($function['parameters']) ? ', ' . implode(', ', str_replace('&', '', array_keys($function['parameters']))) : '');
115 $out .= ");\n";
116 $out .= "}\n\n";
117 }
118 return
119 "<?php
120 // \$Id\$
121
122 " . trim($out) . "\n";
123 }
124
125 /**
126 * Scan derectory recursively, scan appropriate files, and return
127 * token wrappers for further processing.
128 *
129 * @param string $directory Directory to scan.
130 * @return array List of token wrappers.
131 */
132 function simpletest_unit_scan_directory($directory) {
133 static $wrappers = array();
134 $path = $directory .'/';
135 $files = scandir($path);
136 foreach ($files as $file) {
137 $file_path = $path . $file;
138 if (simpletest_unit_match($file)) {
139 $wrappers[] = simpletest_unit_scan_file($file_path);
140 }
141 else if (simpletest_unit_check_directory($file_path)) {
142 simpletest_unit_scan_directory($file_path);
143 }
144 }
145 return $wrappers;
146 }
147
148 /**
149 * Parse specified file into tokens and return token wrapper.
150 *
151 * @param string $file File to scan.
152 * @return simpletest_unit_token_wrapper Token wrapper for specified file.
153 */
154 function simpletest_unit_scan_file($file) {
155 $contents = file_get_contents($file);
156
157 // Remove comments.
158 $contents = preg_replace('/^.*?\/\/.*?$/m', '', $contents); // Single line comments.
159 $contents = preg_replace('/\/\*.*?\*\//s', '', $contents); // Block comments.
160
161 $wrapper = new simpletest_unit_token_wrapper($contents, $file);
162 $wrapper->find_functions();
163 $wrapper->clear_tokens(); // Save memory.
164 return $wrapper;
165 }
166
167 /**
168 * Wrap a function for inclusion in test case.
169 *
170 * @param string $function Name of function.
171 * @return string Wrapped function.
172 */
173 function simpletest_unit_wrap_function($function, array $calls) {
174 $steps = array();
175 foreach ($calls as $call) {
176 $steps[]= array('incoming' => array($call), 'return' => NULL);
177 }
178
179 $out = 'function test_'. $function ."() {\n";
180 if (count($steps)) {
181 $out .= ' ' . SIMPLETEST_UNIT_CALLBACK . "(\n";
182 $steps_out = simpletest_unit_export_array($steps);
183 $steps_out = preg_replace("/'incoming' => array\(\s+(.*?),\s+\)/", "'incoming' => array(\${1})", $steps_out);
184 $steps_out = preg_replace("/.*?\n/", ' ${0}', $steps_out);
185 $out .= $steps_out;
186 $out .= " );\n";
187 $out .= ' ' . SIMPLETEST_UNIT_CALLBACK . "('$function');\n";
188 }
189 $out .= "\n\n // TODO Auto-generated stub.\n";
190 $out .= "}\n\n";
191 return $out;
192 }
193
194 function simpletest_unit_export_array(array &$array) {
195 $out = var_export($array, TRUE) . "\n";
196 $out = preg_replace('/\d+ => /', '', $out);
197 $out = str_replace('array (', 'array(', $out);
198 $out = preg_replace('/=>\s+array\(/', '=> array(', $out);
199 $out = preg_replace('/^\s+$\n/m', '', $out);
200 return $out;
201 }
202
203 /**
204 * Wrap unit test for output.
205 *
206 * @param string $filename Name of file related to test.
207 * @param string $test Contents of test.
208 * @return string Wrapped test case.
209 */
210 function simpletest_unit_wrap_test($filename, $test) {
211 $class = str_replace(array('.', '-'), '_', $filename);
212 $name = ucwords(str_replace('_', ' ', $class));
213 $class = str_replace(' ', '', $name);
214 return
215 "<?php
216 // \$Id\$
217
218 class {$class}TestCase extends DrupalUnitTestCase {
219 /**
220 * Implementation of getInfo().
221 */
222 function getInfo() {
223 return array(
224 'name' => t('$name'),
225 'description' => t('Unit tests.'),
226 'group' => t('$name')
227 );
228 }
229
230 ". trim(preg_replace('/(.+?)\n/', " $1\n", $test)) ."
231 }
232 ";
233 }
234
235 /**
236 * Export the array of paramters as valid PHP syntax.
237 *
238 * @param array $paramters Parameters to be export.
239 * @return string Valid PHP syntax representing paramters.
240 */
241 function simpletest_unit_export_parameters(array $paramters) {
242 $out = '';
243 foreach ($paramters as $name => $default) {
244 $out .= $name . ($default ? ' = ' . $default : '') . ', ';
245 }
246 return trim($out, ', ');
247 }
248
249 /**
250 * Make sure filename matches the requirements to be included in unit testing.
251 *
252 * @param string $file File to be checked.
253 * @return boolean File matches requirements.
254 */
255 function simpletest_unit_match($file) {
256 static $patterns = array('*.php', '*.inc', '*.module');
257 foreach ($patterns as $pattern) {
258 if (fnmatch($pattern, $file) && !fnmatch('*.tpl.*', $file)) {
259 return TRUE;
260 }
261 }
262 return FALSE;
263 }
264
265 /**
266 * Make sure the directory is not on the list of directories to ingore.
267 *
268 * @param string $directory Directory to check.
269 * @return boolean Directory is not on the list of directories to ignore.
270 */
271 function simpletest_unit_check_directory($directory) {
272 static $ignore = array('.', '..', 'CVS');
273 return is_dir($directory) && !in_array(basename($directory), $ignore);
274 }

  ViewVC Help
Powered by ViewVC 1.1.2