shell.js (7031B)
1 /* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /*--- 7 defines: [testRegExp, makeExpectedMatch, checkRegExpMatch] 8 allow_unused: True 9 ---*/ 10 11 /* 12 * Date: 07 February 2001 13 * 14 * Functionality common to RegExp testing - 15 */ 16 //----------------------------------------------------------------------------- 17 18 (function(global) { 19 20 var MSG_PATTERN = '\nregexp = '; 21 var MSG_STRING = '\nstring = '; 22 var MSG_EXPECT = '\nExpect: '; 23 var MSG_ACTUAL = '\nActual: '; 24 var ERR_LENGTH = '\nERROR !!! match arrays have different lengths:'; 25 var ERR_MATCH = '\nERROR !!! regexp failed to give expected match array:'; 26 var ERR_NO_MATCH = '\nERROR !!! regexp FAILED to match anything !!!'; 27 var ERR_UNEXP_MATCH = '\nERROR !!! regexp MATCHED when we expected it to fail !!!'; 28 var CHAR_LBRACKET = '['; 29 var CHAR_RBRACKET = ']'; 30 var CHAR_QT_DBL = '"'; 31 var CHAR_QT = "'"; 32 var CHAR_NL = '\n'; 33 var CHAR_COMMA = ','; 34 var CHAR_SPACE = ' '; 35 var TYPE_STRING = typeof 'abc'; 36 37 38 39 global.testRegExp = function testRegExp(statuses, patterns, strings, actualmatches, expectedmatches) 40 { 41 var status = ''; 42 var pattern = new RegExp(); 43 var string = ''; 44 var actualmatch = new Array(); 45 var expectedmatch = new Array(); 46 var state = ''; 47 var lActual = -1; 48 var lExpect = -1; 49 50 51 for (var i=0; i != patterns.length; i++) 52 { 53 status = statuses[i]; 54 pattern = patterns[i]; 55 string = strings[i]; 56 actualmatch=actualmatches[i]; 57 expectedmatch=expectedmatches[i]; 58 state = getState(status, pattern, string); 59 60 description = status; 61 62 if(actualmatch) 63 { 64 actual = formatArray(actualmatch); 65 if(expectedmatch) 66 { 67 // expectedmatch and actualmatch are arrays - 68 lExpect = expectedmatch.length; 69 lActual = actualmatch.length; 70 71 var expected = formatArray(expectedmatch); 72 73 if (lActual != lExpect) 74 { 75 reportCompare(lExpect, lActual, 76 state + ERR_LENGTH + 77 MSG_EXPECT + expected + 78 MSG_ACTUAL + actual + 79 CHAR_NL 80 ); 81 continue; 82 } 83 84 // OK, the arrays have same length - 85 if (expected != actual) 86 { 87 reportCompare(expected, actual, 88 state + ERR_MATCH + 89 MSG_EXPECT + expected + 90 MSG_ACTUAL + actual + 91 CHAR_NL 92 ); 93 } 94 else 95 { 96 reportCompare(expected, actual, state) 97 } 98 99 } 100 else //expectedmatch is null - that is, we did not expect a match - 101 { 102 expected = expectedmatch; 103 reportCompare(expected, actual, 104 state + ERR_UNEXP_MATCH + 105 MSG_EXPECT + expectedmatch + 106 MSG_ACTUAL + actual + 107 CHAR_NL 108 ); 109 } 110 111 } 112 else // actualmatch is null 113 { 114 if (expectedmatch) 115 { 116 actual = actualmatch; 117 reportCompare(expected, actual, 118 state + ERR_NO_MATCH + 119 MSG_EXPECT + expectedmatch + 120 MSG_ACTUAL + actualmatch + 121 CHAR_NL 122 ); 123 } 124 else // we did not expect a match 125 { 126 // Being ultra-cautious. Presumably expectedmatch===actualmatch===null 127 expected = expectedmatch; 128 actual = actualmatch; 129 reportCompare (expectedmatch, actualmatch, state); 130 } 131 } 132 } 133 } 134 135 function getState(status, pattern, string) 136 { 137 /* 138 * Escape \n's, etc. to make them LITERAL in the presentation string. 139 * We don't have to worry about this in |pattern|; such escaping is 140 * done automatically by pattern.toString(), invoked implicitly below. 141 * 142 * One would like to simply do: string = string.replace(/(\s)/g, '\$1'). 143 * However, the backreference $1 is not a literal string value, 144 * so this method doesn't work. 145 * 146 * Also tried string = string.replace(/(\s)/g, escape('$1')); 147 * but this just inserts the escape of the literal '$1', i.e. '%241'. 148 */ 149 string = string.replace(/\n/g, '\\n'); 150 string = string.replace(/\r/g, '\\r'); 151 string = string.replace(/\t/g, '\\t'); 152 string = string.replace(/\v/g, '\\v'); 153 string = string.replace(/\f/g, '\\f'); 154 155 return (status + MSG_PATTERN + pattern + MSG_STRING + singleQuote(string)); 156 } 157 158 159 160 /* 161 * If available, arr.toSource() gives more detail than arr.toString() 162 * 163 * var arr = Array(1,2,'3'); 164 * 165 * arr.toSource() 166 * [1, 2, "3"] 167 * 168 * arr.toString() 169 * 1,2,3 170 * 171 * But toSource() doesn't exist in Rhino, so use our own imitation, below - 172 * 173 */ 174 function formatArray(arr) 175 { 176 try 177 { 178 return arr.toSource(); 179 } 180 catch(e) 181 { 182 return toSource(arr); 183 } 184 } 185 186 187 /* 188 * Imitate SpiderMonkey's arr.toSource() method: 189 * 190 * a) Double-quote each array element that is of string type 191 * b) Represent |undefined| and |null| by empty strings 192 * c) Delimit elements by a comma + single space 193 * d) Do not add delimiter at the end UNLESS the last element is |undefined| 194 * e) Add square brackets to the beginning and end of the string 195 */ 196 function toSource(arr) 197 { 198 var delim = CHAR_COMMA + CHAR_SPACE; 199 var elt = ''; 200 var ret = ''; 201 var len = arr.length; 202 203 for (i=0; i<len; i++) 204 { 205 elt = arr[i]; 206 207 switch(true) 208 { 209 case (typeof elt === TYPE_STRING) : 210 ret += doubleQuote(elt); 211 break; 212 213 case (elt === undefined || elt === null) : 214 break; // add nothing but the delimiter, below - 215 216 default: 217 ret += elt.toString(); 218 } 219 220 if ((i < len-1) || (elt === undefined)) 221 ret += delim; 222 } 223 224 return CHAR_LBRACKET + ret + CHAR_RBRACKET; 225 } 226 227 228 function doubleQuote(text) 229 { 230 return CHAR_QT_DBL + text + CHAR_QT_DBL; 231 } 232 233 234 function singleQuote(text) 235 { 236 return CHAR_QT + text + CHAR_QT; 237 } 238 239 global.makeExpectedMatch = function makeExpectedMatch(arr, index, input) { 240 var expectedMatch = { 241 index: index, 242 input: input, 243 length: arr.length, 244 }; 245 246 for (var i = 0; i < arr.length; ++i) 247 expectedMatch[i] = arr[i]; 248 249 return expectedMatch; 250 } 251 252 global.checkRegExpMatch = function checkRegExpMatch(actual, expected) { 253 assertEq(actual.length, expected.length); 254 for (var i = 0; i < actual.length; ++i) 255 assertEq(actual[i], expected[i]); 256 257 assertEq(actual.index, expected.index); 258 assertEq(actual.input, expected.input); 259 } 260 261 })(this);