| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // This should output "PROXY success:80" if all the tests pass. | |
| 6 // Otherwise it will output "PROXY failure:<num-failures>". | |
| 7 // | |
| 8 // This aims to unit-test the PAC library functions, which are | |
| 9 // exposed in the PAC's execution environment. (Namely, dnsDomainLevels, | |
| 10 // timeRange, etc.) | |
| 11 | |
| 12 function FindProxyForURL(url, host) { | |
| 13 var numTestsFailed = 0; | |
| 14 | |
| 15 // Run all the tests | |
| 16 for (var test in Tests) { | |
| 17 var t = new TestContext(test); | |
| 18 | |
| 19 // Run the test. | |
| 20 Tests[test](t); | |
| 21 | |
| 22 if (t.failed()) { | |
| 23 numTestsFailed++; | |
| 24 } | |
| 25 } | |
| 26 | |
| 27 if (numTestsFailed == 0) { | |
| 28 return "PROXY success:80"; | |
| 29 } | |
| 30 return "PROXY failure:" + numTestsFailed; | |
| 31 } | |
| 32 | |
| 33 // -------------------------- | |
| 34 // Tests | |
| 35 // -------------------------- | |
| 36 | |
| 37 var Tests = {}; | |
| 38 | |
| 39 Tests.testDnsDomainIs = function(t) { | |
| 40 t.expectTrue(dnsDomainIs("google.com", ".com")); | |
| 41 t.expectTrue(dnsDomainIs("google.co.uk", ".co.uk")); | |
| 42 t.expectFalse(dnsDomainIs("google.com", ".co.uk")); | |
| 43 t.expectFalse(dnsDomainIs("www.adobe.com", ".ad")); | |
| 44 }; | |
| 45 | |
| 46 Tests.testDnsDomainLevels = function(t) { | |
| 47 t.expectEquals(0, dnsDomainLevels("www")); | |
| 48 t.expectEquals(2, dnsDomainLevels("www.google.com")); | |
| 49 t.expectEquals(3, dnsDomainLevels("192.168.1.1")); | |
| 50 }; | |
| 51 | |
| 52 Tests.testIsInNet = function(t) { | |
| 53 t.expectTrue( | |
| 54 isInNet("192.89.132.25", "192.89.132.25", "255.255.255.255")); | |
| 55 t.expectFalse( | |
| 56 isInNet("193.89.132.25", "192.89.132.25", "255.255.255.255")); | |
| 57 | |
| 58 t.expectTrue(isInNet("192.89.132.25", "192.89.0.0", "255.255.0.0")); | |
| 59 t.expectFalse(isInNet("193.89.132.25", "192.89.0.0", "255.255.0.0")); | |
| 60 | |
| 61 t.expectFalse( | |
| 62 isInNet("192.89.132.a", "192.89.0.0", "255.255.0.0")); | |
| 63 }; | |
| 64 | |
| 65 Tests.testIsPlainHostName = function(t) { | |
| 66 t.expectTrue(isPlainHostName("google")); | |
| 67 t.expectFalse(isPlainHostName("google.com")); | |
| 68 t.expectFalse(isPlainHostName("192.168.1.1")); | |
| 69 t.expectFalse(isPlainHostName(".")); | |
| 70 t.expectFalse(isPlainHostName(".:")); | |
| 71 | |
| 72 // Valid IPv6 address | |
| 73 t.expectFalse(isPlainHostName("::1")); | |
| 74 | |
| 75 // Valid IPv6 address containing periods. | |
| 76 t.expectFalse(isPlainHostName("::192.186.1.1")); | |
| 77 | |
| 78 // Not a valid IPv6 address | |
| 79 t.expectTrue(isPlainHostName("foopy::1")); | |
| 80 t.expectTrue(isPlainHostName("foo:112")); | |
| 81 t.expectTrue(isPlainHostName(":")); | |
| 82 t.expectTrue(isPlainHostName("[:]")); | |
| 83 | |
| 84 // Not considered a valid IPv6 address because of surrounding brackets. | |
| 85 t.expectTrue(isPlainHostName("[::1]")); | |
| 86 | |
| 87 // Calling with more than 1 argument is allowed. | |
| 88 t.expectTrue(isPlainHostName("foo", "foo", "foo")); | |
| 89 | |
| 90 // Calling with no arguments is an error. | |
| 91 try { | |
| 92 isPlainHostName(); | |
| 93 t.expectTrue(false); // Not reached. | |
| 94 } catch (e) { | |
| 95 t.expectEquals('TypeError: Requires 1 string parameter', e.toString()); | |
| 96 } | |
| 97 | |
| 98 // Calling with the wrong argument type is an error. | |
| 99 try { | |
| 100 isPlainHostName(null); | |
| 101 t.expectTrue(false); // Not reached. | |
| 102 } catch (e) { | |
| 103 t.expectEquals('TypeError: Requires 1 string parameter', e.toString()); | |
| 104 } | |
| 105 | |
| 106 // Calling with the wrong argument type is an error. | |
| 107 try { | |
| 108 isPlainHostName(1); | |
| 109 t.expectTrue(false); // Not reached. | |
| 110 } catch (e) { | |
| 111 t.expectEquals('TypeError: Requires 1 string parameter', e.toString()); | |
| 112 } | |
| 113 | |
| 114 // Calling with the wrong argument type is an error. | |
| 115 try { | |
| 116 isPlainHostName(function() {}); | |
| 117 t.expectTrue(false); // Not reached. | |
| 118 } catch (e) { | |
| 119 t.expectEquals('TypeError: Requires 1 string parameter', e.toString()); | |
| 120 } | |
| 121 }; | |
| 122 | |
| 123 Tests.testLocalHostOrDomainIs = function(t) { | |
| 124 t.expectTrue(localHostOrDomainIs("www.google.com", "www.google.com")); | |
| 125 t.expectTrue(localHostOrDomainIs("www", "www.google.com")); | |
| 126 t.expectFalse(localHostOrDomainIs("maps.google.com", "www.google.com")); | |
| 127 }; | |
| 128 | |
| 129 Tests.testShExpMatch = function(t) { | |
| 130 t.expectTrue(shExpMatch("foo.jpg", "*.jpg")); | |
| 131 t.expectTrue(shExpMatch("foo5.jpg", "*o?.jpg")); | |
| 132 t.expectFalse(shExpMatch("foo.jpg", ".jpg")); | |
| 133 t.expectFalse(shExpMatch("foo.jpg", "foo")); | |
| 134 }; | |
| 135 | |
| 136 Tests.testSortIpAddressList = function(t) { | |
| 137 t.expectEquals("::1;::2;::3", sortIpAddressList("::2;::3;::1")); | |
| 138 t.expectEquals( | |
| 139 "2001:4898:28:3:201:2ff:feea:fc14;fe80::5efe:157:9d3b:8b16;157.59.139.22", | |
| 140 sortIpAddressList("157.59.139.22;" + | |
| 141 "2001:4898:28:3:201:2ff:feea:fc14;" + | |
| 142 "fe80::5efe:157:9d3b:8b16")); | |
| 143 | |
| 144 // Single IP address (v4 and v6). | |
| 145 t.expectEquals("127.0.0.1", sortIpAddressList("127.0.0.1")); | |
| 146 t.expectEquals("::1", sortIpAddressList("::1")) | |
| 147 | |
| 148 // Verify that IPv6 address is not re-written (not reduced). | |
| 149 t.expectEquals("0:0::1;192.168.1.1", sortIpAddressList("192.168.1.1;0:0::1")); | |
| 150 | |
| 151 // Input is already sorted. | |
| 152 t.expectEquals("::1;192.168.1.3", sortIpAddressList("::1;192.168.1.3")); | |
| 153 | |
| 154 // Same-valued IP addresses (also tests stability). | |
| 155 t.expectEquals("0::1;::1;0:0::1", sortIpAddressList("0::1;::1;0:0::1")); | |
| 156 | |
| 157 // Contains extra semi-colons. | |
| 158 t.expectEquals("127.0.0.1", sortIpAddressList(";127.0.0.1;")); | |
| 159 | |
| 160 // Contains whitespace (spaces and tabs). | |
| 161 t.expectEquals("192.168.0.1;192.168.0.2", | |
| 162 sortIpAddressList("192.168.0.1; 192.168.0.2")); | |
| 163 t.expectEquals("127.0.0.0;127.0.0.1;127.0.0.2", | |
| 164 sortIpAddressList("127.0.0.1; 127.0.0.2; 127.0.0.0")); | |
| 165 | |
| 166 // Empty lists. | |
| 167 t.expectFalse(sortIpAddressList("")); | |
| 168 t.expectFalse(sortIpAddressList(" ")); | |
| 169 t.expectFalse(sortIpAddressList(";")); | |
| 170 t.expectFalse(sortIpAddressList(";;")); | |
| 171 t.expectFalse(sortIpAddressList(" ; ; ")); | |
| 172 | |
| 173 // Invalid IP addresses. | |
| 174 t.expectFalse(sortIpAddressList("256.0.0.1")); | |
| 175 t.expectFalse(sortIpAddressList("192.168.1.1;0:0:0:1;127.0.0.1")); | |
| 176 | |
| 177 // Call sortIpAddressList() with wonky arguments. | |
| 178 t.expectEquals(null, sortIpAddressList()); | |
| 179 t.expectEquals(null, sortIpAddressList(null)); | |
| 180 t.expectEquals(null, sortIpAddressList(null, null)); | |
| 181 }; | |
| 182 | |
| 183 Tests.testIsInNetEx = function(t) { | |
| 184 t.expectTrue(isInNetEx("198.95.249.79", "198.95.249.79/32")); | |
| 185 t.expectTrue(isInNetEx("198.95.115.10", "198.95.0.0/16")); | |
| 186 t.expectTrue(isInNetEx("198.95.1.1", "198.95.0.0/16")); | |
| 187 t.expectTrue(isInNetEx("198.95.1.1", "198.95.3.3/16")); | |
| 188 t.expectTrue(isInNetEx("0:0:0:0:0:0:7f00:1", "0:0:0:0:0:0:7f00:1/32")); | |
| 189 t.expectTrue(isInNetEx("3ffe:8311:ffff:abcd:1234:dead:beef:101", | |
| 190 "3ffe:8311:ffff::/48")); | |
| 191 | |
| 192 // IPv4 and IPv6 mix. | |
| 193 t.expectFalse(isInNetEx("127.0.0.1", "0:0:0:0:0:0:7f00:1/16")); | |
| 194 t.expectFalse(isInNetEx("192.168.24.3", "fe80:0:0:0:0:0:c0a8:1803/32")); | |
| 195 | |
| 196 t.expectFalse(isInNetEx("198.95.249.78", "198.95.249.79/32")); | |
| 197 t.expectFalse(isInNetEx("198.96.115.10", "198.95.0.0/16")); | |
| 198 t.expectFalse(isInNetEx("3fff:8311:ffff:abcd:1234:dead:beef:101", | |
| 199 "3ffe:8311:ffff::/48")); | |
| 200 | |
| 201 // Call isInNetEx with wonky arguments. | |
| 202 t.expectEquals(null, isInNetEx()); | |
| 203 t.expectEquals(null, isInNetEx(null)); | |
| 204 t.expectEquals(null, isInNetEx(null, null)); | |
| 205 t.expectEquals(null, isInNetEx(null, null, null)); | |
| 206 t.expectEquals(null, isInNetEx("198.95.249.79")); | |
| 207 | |
| 208 // Invalid IP address. | |
| 209 t.expectFalse(isInNetEx("256.0.0.1", "198.95.249.79")); | |
| 210 t.expectFalse(isInNetEx("127.0.0.1 ", "127.0.0.1/32")); // Extra space. | |
| 211 | |
| 212 // Invalid prefix. | |
| 213 t.expectFalse(isInNetEx("198.95.115.10", "198.95.0.0/34")); | |
| 214 t.expectFalse(isInNetEx("127.0.0.1", "127.0.0.1")); // Missing '/' in prefix. | |
| 215 }; | |
| 216 | |
| 217 Tests.testWeekdayRange = function(t) { | |
| 218 // Test with local time. | |
| 219 MockDate.setCurrent("Tue Mar 03 2009"); | |
| 220 t.expectEquals(true, weekdayRange("MON", "FRI")); | |
| 221 t.expectEquals(true, weekdayRange("TUE", "FRI")); | |
| 222 t.expectEquals(true, weekdayRange("TUE", "TUE")); | |
| 223 t.expectEquals(true, weekdayRange("TUE")); | |
| 224 t.expectEquals(false, weekdayRange("WED", "FRI")); | |
| 225 t.expectEquals(false, weekdayRange("SUN", "MON")); | |
| 226 t.expectEquals(false, weekdayRange("SAT")); | |
| 227 t.expectEquals(false, weekdayRange("FRI", "MON")); | |
| 228 | |
| 229 // Test with GMT time. | |
| 230 MockDate.setCurrent("Tue Mar 03 2009 GMT"); | |
| 231 t.expectEquals(true, weekdayRange("MON", "FRI", "GMT")); | |
| 232 t.expectEquals(true, weekdayRange("TUE", "FRI", "GMT")); | |
| 233 t.expectEquals(true, weekdayRange("TUE", "TUE", "GMT")); | |
| 234 t.expectEquals(true, weekdayRange("TUE", "GMT")); | |
| 235 t.expectEquals(false, weekdayRange("WED", "FRI", "GMT")); | |
| 236 t.expectEquals(false, weekdayRange("SUN", "MON", "GMT")); | |
| 237 t.expectEquals(false, weekdayRange("SAT", "GMT")); | |
| 238 }; | |
| 239 | |
| 240 Tests.testDateRange = function(t) { | |
| 241 // dateRange(day) | |
| 242 MockDate.setCurrent("Mar 03 2009"); | |
| 243 t.expectEquals(true, dateRange(3)); | |
| 244 t.expectEquals(false, dateRange(1)); | |
| 245 | |
| 246 // dateRange(day, "GMT") | |
| 247 MockDate.setCurrent("Mar 03 2009 GMT"); | |
| 248 t.expectEquals(true, dateRange(3, "GMT")); | |
| 249 t.expectEquals(false, dateRange(1, "GMT")); | |
| 250 | |
| 251 // dateRange(day1, day2) | |
| 252 MockDate.setCurrent("Mar 03 2009"); | |
| 253 t.expectEquals(true, dateRange(1, 4)); | |
| 254 t.expectEquals(false, dateRange(4, 20)); | |
| 255 | |
| 256 // dateRange(day, month) | |
| 257 MockDate.setCurrent("Mar 03 2009"); | |
| 258 t.expectEquals(true, dateRange(3, "MAR")); | |
| 259 MockDate.setCurrent("Mar 03 2014"); | |
| 260 t.expectEquals(true, dateRange(3, "MAR")); | |
| 261 // TODO(eroman): | |
| 262 //t.expectEquals(false, dateRange(2, "MAR")); | |
| 263 //t.expectEquals(false, dateRange(3, "JAN")); | |
| 264 | |
| 265 // dateRange(day, month, year) | |
| 266 MockDate.setCurrent("Mar 03 2009"); | |
| 267 t.expectEquals(true, dateRange(3, "MAR", 2009)); | |
| 268 t.expectEquals(false, dateRange(4, "MAR", 2009)); | |
| 269 t.expectEquals(false, dateRange(3, "FEB", 2009)); | |
| 270 MockDate.setCurrent("Mar 03 2014"); | |
| 271 t.expectEquals(false, dateRange(3, "MAR", 2009)); | |
| 272 | |
| 273 // dateRange(month1, month2) | |
| 274 MockDate.setCurrent("Mar 03 2009"); | |
| 275 t.expectEquals(true, dateRange("JAN", "MAR")); | |
| 276 t.expectEquals(true, dateRange("MAR", "APR")); | |
| 277 t.expectEquals(false, dateRange("MAY", "SEP")); | |
| 278 | |
| 279 // dateRange(day1, month1, day2, month2) | |
| 280 MockDate.setCurrent("Mar 03 2009"); | |
| 281 t.expectEquals(true, dateRange(1, "JAN", 3, "MAR")); | |
| 282 t.expectEquals(true, dateRange(3, "MAR", 4, "SEP")); | |
| 283 t.expectEquals(false, dateRange(4, "MAR", 4, "SEP")); | |
| 284 | |
| 285 // dateRange(month1, year1, month2, year2) | |
| 286 MockDate.setCurrent("Mar 03 2009"); | |
| 287 t.expectEquals(true, dateRange("FEB", 2009, "MAR", 2009)); | |
| 288 MockDate.setCurrent("Apr 03 2009"); | |
| 289 t.expectEquals(true, dateRange("FEB", 2009, "MAR", 2010)); | |
| 290 t.expectEquals(false, dateRange("FEB", 2009, "MAR", 2009)); | |
| 291 | |
| 292 // dateRange(day1, month1, year1, day2, month2, year2) | |
| 293 MockDate.setCurrent("Mar 03 2009"); | |
| 294 t.expectEquals(true, dateRange(1, "JAN", 2009, 3, "MAR", 2009)); | |
| 295 t.expectEquals(true, dateRange(3, "MAR", 2009, 4, "SEP", 2009)); | |
| 296 t.expectEquals(true, dateRange(3, "JAN", 2009, 4, "FEB", 2010)); | |
| 297 t.expectEquals(false, dateRange(4, "MAR", 2009, 4, "SEP", 2009)); | |
| 298 }; | |
| 299 | |
| 300 Tests.testTimeRange = function(t) { | |
| 301 // timeRange(hour) | |
| 302 MockDate.setCurrent("Mar 03, 2009 03:34:01"); | |
| 303 t.expectEquals(true, timeRange(3)); | |
| 304 t.expectEquals(false, timeRange(2)); | |
| 305 | |
| 306 // timeRange(hour1, hour2) | |
| 307 MockDate.setCurrent("Mar 03, 2009 03:34:01"); | |
| 308 t.expectEquals(true, timeRange(2, 3)); | |
| 309 t.expectEquals(true, timeRange(2, 4)); | |
| 310 t.expectEquals(true, timeRange(3, 5)); | |
| 311 t.expectEquals(false, timeRange(1, 2)); | |
| 312 t.expectEquals(false, timeRange(11, 12)); | |
| 313 | |
| 314 // timeRange(hour1, min1, hour2, min2) | |
| 315 MockDate.setCurrent("Mar 03, 2009 03:34:01"); | |
| 316 t.expectEquals(true, timeRange(1, 0, 3, 34)); | |
| 317 t.expectEquals(true, timeRange(1, 0, 3, 35)); | |
| 318 t.expectEquals(true, timeRange(3, 34, 5, 0)); | |
| 319 t.expectEquals(false, timeRange(1, 0, 3, 0)); | |
| 320 t.expectEquals(false, timeRange(11, 0, 16, 0)); | |
| 321 | |
| 322 // timeRange(hour1, min1, sec1, hour2, min2, sec2) | |
| 323 MockDate.setCurrent("Mar 03, 2009 03:34:14"); | |
| 324 t.expectEquals(true, timeRange(1, 0, 0, 3, 34, 14)); | |
| 325 t.expectEquals(false, timeRange(1, 0, 0, 3, 34, 0)); | |
| 326 t.expectEquals(true, timeRange(1, 0, 0, 3, 35, 0)); | |
| 327 t.expectEquals(true, timeRange(3, 34, 0, 5, 0, 0)); | |
| 328 t.expectEquals(false, timeRange(1, 0, 0, 3, 0, 0)); | |
| 329 t.expectEquals(false, timeRange(11, 0, 0, 16, 0, 0)); | |
| 330 }; | |
| 331 | |
| 332 // -------------------------- | |
| 333 // TestContext | |
| 334 // -------------------------- | |
| 335 | |
| 336 // |name| is the name of the test being executed, it will be used when logging | |
| 337 // errors. | |
| 338 function TestContext(name) { | |
| 339 this.numFailures_ = 0; | |
| 340 this.name_ = name; | |
| 341 }; | |
| 342 | |
| 343 TestContext.prototype.failed = function() { | |
| 344 return this.numFailures_ != 0; | |
| 345 }; | |
| 346 | |
| 347 TestContext.prototype.expectEquals = function(expectation, actual) { | |
| 348 if (!(expectation === actual)) { | |
| 349 this.numFailures_++; | |
| 350 this.log("FAIL: expected: " + expectation + ", actual: " + actual); | |
| 351 } | |
| 352 }; | |
| 353 | |
| 354 TestContext.prototype.expectTrue = function(x) { | |
| 355 this.expectEquals(true, x); | |
| 356 }; | |
| 357 | |
| 358 TestContext.prototype.expectFalse = function(x) { | |
| 359 this.expectEquals(false, x); | |
| 360 }; | |
| 361 | |
| 362 TestContext.prototype.log = function(x) { | |
| 363 // Prefix with the test name that generated the log. | |
| 364 try { | |
| 365 alert(this.name_ + ": " + x); | |
| 366 } catch(e) { | |
| 367 // In case alert() is not defined. | |
| 368 } | |
| 369 }; | |
| 370 | |
| 371 // -------------------------- | |
| 372 // MockDate | |
| 373 // -------------------------- | |
| 374 | |
| 375 function MockDate() { | |
| 376 this.wrappedDate_ = new MockDate.super_(MockDate.currentDateString_); | |
| 377 }; | |
| 378 | |
| 379 // Setup the MockDate so it forwards methods to "this.wrappedDate_" (which is a | |
| 380 // real Date object). We can't simply chain the prototypes since Date() doesn't | |
| 381 // allow it. | |
| 382 MockDate.init = function() { | |
| 383 MockDate.super_ = Date; | |
| 384 | |
| 385 function createProxyMethod(methodName) { | |
| 386 return function() { | |
| 387 return this.wrappedDate_[methodName] | |
| 388 .apply(this.wrappedDate_, arguments); | |
| 389 } | |
| 390 }; | |
| 391 | |
| 392 for (i in MockDate.methodNames_) { | |
| 393 var methodName = MockDate.methodNames_[i]; | |
| 394 // Don't define the closure directly in the loop body, since Javascript's | |
| 395 // crazy scoping rules mean |methodName| actually bleeds out of the loop! | |
| 396 MockDate.prototype[methodName] = createProxyMethod(methodName); | |
| 397 } | |
| 398 | |
| 399 // Replace the native Date() with our mock. | |
| 400 Date = MockDate; | |
| 401 }; | |
| 402 | |
| 403 // Unfortunately Date()'s methods are non-enumerable, therefore list manually. | |
| 404 MockDate.methodNames_ = [ | |
| 405 "toString", "toDateString", "toTimeString", "toLocaleString", | |
| 406 "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime", | |
| 407 "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth", | |
| 408 "getDate", "getUTCDate", "getDay", "getUTCDay", "getHours", "getUTCHours", | |
| 409 "getMinutes", "getUTCMinutes", "getSeconds", "getUTCSeconds", | |
| 410 "getMilliseconds", "getUTCMilliseconds", "getTimezoneOffset", "setTime", | |
| 411 "setMilliseconds", "setUTCMilliseconds", "setSeconds", "setUTCSeconds", | |
| 412 "setMinutes", "setUTCMinutes", "setHours", "setUTCHours", "setDate", | |
| 413 "setUTCDate", "setMonth", "setUTCMonth", "setFullYear", "setUTCFullYear", | |
| 414 "toGMTString", "toUTCString", "getYear", "setYear" | |
| 415 ]; | |
| 416 | |
| 417 MockDate.setCurrent = function(currentDateString) { | |
| 418 MockDate.currentDateString_ = currentDateString; | |
| 419 } | |
| 420 | |
| 421 // Bind the methods to proxy requests to the wrapped Date(). | |
| 422 MockDate.init(); | |
| 423 | |
| OLD | NEW |