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.
5 // This should output "PROXY success:80" if all the tests pass.
6 // Otherwise it will output "PROXY failure:<num-failures>".
8 // This aims to unit-test the PAC library functions, which are
9 // exposed in the PAC's execution environment. (Namely, dnsDomainLevels,
12 function FindProxyForURL(url, host) {
13 var numTestsFailed = 0;
16 for (var test in Tests) {
17 var t = new TestContext(test);
27 if (numTestsFailed == 0) {
28 return "PROXY success:80";
30 return "PROXY failure:" + numTestsFailed;
33 // --------------------------
35 // --------------------------
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"));
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"));
52 Tests.testIsInNet = function(t) {
54 isInNet("192.89.132.25", "192.89.132.25", "255.255.255.255"));
56 isInNet("193.89.132.25", "192.89.132.25", "255.255.255.255"));
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"));
62 isInNet("192.89.132.a", "192.89.0.0", "255.255.0.0"));
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(".:"));
73 t.expectFalse(isPlainHostName("::1"));
75 // Valid IPv6 address containing periods.
76 t.expectFalse(isPlainHostName("::192.186.1.1"));
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("[:]"));
84 // Not considered a valid IPv6 address because of surrounding brackets.
85 t.expectTrue(isPlainHostName("[::1]"));
87 // Calling with more than 1 argument is allowed.
88 t.expectTrue(isPlainHostName("foo", "foo", "foo"));
90 // Calling with no arguments is an error.
93 t.expectTrue(false); // Not reached.
95 t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
98 // Calling with the wrong argument type is an error.
100 isPlainHostName(null);
101 t.expectTrue(false); // Not reached.
103 t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
106 // Calling with the wrong argument type is an error.
109 t.expectTrue(false); // Not reached.
111 t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
114 // Calling with the wrong argument type is an error.
116 isPlainHostName(function() {});
117 t.expectTrue(false); // Not reached.
119 t.expectEquals('TypeError: Requires 1 string parameter', e.toString());
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"));
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"));
136 Tests.testSortIpAddressList = function(t) {
137 t.expectEquals("::1;::2;::3", sortIpAddressList("::2;::3;::1"));
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"));
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"))
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"));
151 // Input is already sorted.
152 t.expectEquals("::1;192.168.1.3", sortIpAddressList("::1;192.168.1.3"));
154 // Same-valued IP addresses (also tests stability).
155 t.expectEquals("0::1;::1;0:0::1", sortIpAddressList("0::1;::1;0:0::1"));
157 // Contains extra semi-colons.
158 t.expectEquals("127.0.0.1", sortIpAddressList(";127.0.0.1;"));
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"));
167 t.expectFalse(sortIpAddressList(""));
168 t.expectFalse(sortIpAddressList(" "));
169 t.expectFalse(sortIpAddressList(";"));
170 t.expectFalse(sortIpAddressList(";;"));
171 t.expectFalse(sortIpAddressList(" ; ; "));
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"));
177 // Call sortIpAddressList() with wonky arguments.
178 t.expectEquals(null, sortIpAddressList());
179 t.expectEquals(null, sortIpAddressList(null));
180 t.expectEquals(null, sortIpAddressList(null, null));
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"));
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"));
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"));
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"));
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.
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.
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"));
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"));
240 Tests.testDateRange = function(t) {
242 MockDate.setCurrent("Mar 03 2009");
243 t.expectEquals(true, dateRange(3));
244 t.expectEquals(false, dateRange(1));
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"));
251 // dateRange(day1, day2)
252 MockDate.setCurrent("Mar 03 2009");
253 t.expectEquals(true, dateRange(1, 4));
254 t.expectEquals(false, dateRange(4, 20));
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"));
262 //t.expectEquals(false, dateRange(2, "MAR"));
263 //t.expectEquals(false, dateRange(3, "JAN"));
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));
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"));
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"));
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));
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));
300 Tests.testTimeRange = function(t) {
302 MockDate.setCurrent("Mar 03, 2009 03:34:01");
303 t.expectEquals(true, timeRange(3));
304 t.expectEquals(false, timeRange(2));
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));
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));
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));
332 // --------------------------
334 // --------------------------
336 // |name| is the name of the test being executed, it will be used when logging
338 function TestContext(name) {
339 this.numFailures_ = 0;
343 TestContext.prototype.failed = function() {
344 return this.numFailures_ != 0;
347 TestContext.prototype.expectEquals = function(expectation, actual) {
348 if (!(expectation === actual)) {
350 this.log("FAIL: expected: " + expectation + ", actual: " + actual);
354 TestContext.prototype.expectTrue = function(x) {
355 this.expectEquals(true, x);
358 TestContext.prototype.expectFalse = function(x) {
359 this.expectEquals(false, x);
362 TestContext.prototype.log = function(x) {
363 // Prefix with the test name that generated the log.
365 alert(this.name_ + ": " + x);
367 // In case alert() is not defined.
371 // --------------------------
373 // --------------------------
375 function MockDate() {
376 this.wrappedDate_ = new MockDate.super_(MockDate.currentDateString_);
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
382 MockDate.init = function() {
383 MockDate.super_ = Date;
385 function createProxyMethod(methodName) {
387 return this.wrappedDate_[methodName]
388 .apply(this.wrappedDate_, arguments);
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);
399 // Replace the native Date() with our mock.
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"
417 MockDate.setCurrent = function(currentDateString) {
418 MockDate.currentDateString_ = currentDateString;
421 // Bind the methods to proxy requests to the wrapped Date().