File indexing completed on 2024-04-28 15:28:39
0001 #!/usr/bin/env kjscmd5 0002 0003 var failures = 0; 0004 var total = 0; 0005 0006 /* Literalise a string for printing purposes */ 0007 function literal(v) { 0008 switch (typeof v) { 0009 case "string": 0010 return '"' + v.replace(/[\\'"]/, "\\$1") + '"'; 0011 default: 0012 return String(v); 0013 } 0014 } 0015 0016 /* Run a test, and check that the result is that expected */ 0017 function test(expr, expected) { 0018 0019 var result, msg, ok, result_str, expected_str; 0020 0021 try { 0022 result = eval(expr); 0023 ok = (result === expected); 0024 } catch (e) { 0025 ok = (expected == "exception"); 0026 result = e.name; 0027 // result = String(e); 0028 } 0029 0030 try { result_str = literal(result); } 0031 catch (e) { result_str = "<cannot represent as string>"; } 0032 0033 0034 msg = expr + ' = ' + result_str; 0035 if (ok) { 0036 msg += " PASS"; 0037 } else { 0038 try { expected_str = literal(expected); } 0039 catch (e) { expected_str = "<cannot represent as string>"; } 0040 msg += " [7mFAIL[m, expected " + expected_str; 0041 failures++; 0042 } 0043 println(msg); 0044 total++; 0045 } 0046 0047 /* Tests begin here */ 0048 0049 /* FutureReservedWord */ 0050 test("abstract", "exception"); 0051 test("boolean", "exception"); 0052 test("byte", "exception"); 0053 test("char", "exception"); 0054 test("class", "exception"); 0055 test("const", "exception"); 0056 test("debugger", "exception"); 0057 test("enum", "exception"); 0058 test("export", "exception"); 0059 test("extends", "exception"); 0060 test("final", "exception"); 0061 test("float", "exception"); 0062 test("goto", "exception"); 0063 test("implements", "exception"); 0064 test("int", "exception"); 0065 test("interface", "exception"); 0066 test("long", "exception"); 0067 test("native", "exception"); 0068 test("package", "exception"); 0069 test("private", "exception"); 0070 test("protected", "exception"); 0071 test("short", "exception"); 0072 test("static", "exception"); 0073 test("super", "exception"); 0074 test("synchronized", "exception"); 0075 test("throws", "exception"); 0076 test("transient", "exception"); 0077 test("volatile", "exception"); 0078 test("double", "exception"); 0079 test("import", "exception"); 0080 test("public", "exception"); 0081 0082 test("1 + +1", 2); 0083 test("1 - +1", 0); 0084 test("1 + -1", 0); 0085 test("1 + +1", 2); 0086 0087 test("this", this); 0088 test("null", null); 0089 test("undefined", undefined); 0090 test("'\\u0041'", "A"); 0091 test('"\\x1b\\x5bm"', "[m"); 0092 test('"\\33\\133m"', "[m"); 0093 ident = "ident"; test("ident", "ident"); 0094 test("[1,2,3].length", 3); 0095 test("({'foo':5}.foo)", 5); 0096 test("((((3))))", 3); 0097 0098 function constr() { 0099 return constr; 0100 } 0101 constr.prototype = Object.prototype 0102 0103 test("new new new constr()", constr); 0104 test("(1,2,3)", 3); 0105 test("i = 3; i++", 3); test("i", 4); 0106 test("i = 3; ++i", 4); test("i", 4); 0107 test("i = 3; i--", 3); test("i", 2); 0108 test("i = 3; --i", 2); test("i", 2); 0109 test("i = 3; i ++ ++", "exception"); 0110 test("i = 3; --i++", "exception"); /* only inc/decrement lvalues */ 0111 test("i = 3; ++i--", "exception"); /* only inc/decrement lvalues */ 0112 0113 test("!true", false); 0114 test("~0", -1); 0115 test("void 'hi'", undefined); 0116 test("i = 3; delete i", true); test("i", "exception"); 0117 0118 test("3 * 6 + 1", 19); 0119 test("1 + 3 * 6", 19); 0120 test("17 % 11 * 5", 30); 0121 test("30 / 3 / 5", 2); 0122 test("30 / 3 * 5", 50); 0123 0124 test("1 - 1 - 1", -1); 0125 0126 test("i=3;j=5; i*=j+=i", 24); 0127 0128 /* instanceof only supports objects */ 0129 test("1 instanceof 1", "exception"); 0130 test("1 instanceof Number.prototype", "exception"); 0131 0132 /* Only function objects should support HasInstance: */ 0133 test("new Number(1) instanceof Number.prototype", "exception"); 0134 0135 0136 /* Test the instanceof keyword and the new operator applied to functions. */ 0137 function Employee(age, name) { 0138 this.age = age; 0139 this.name = name; 0140 } 0141 Employee.prototype = new Object() 0142 Employee.prototype.constructor = Employee 0143 Employee.prototype.toString = function() { 0144 return "Name: " + this.name + ", age: " + this.age; 0145 } 0146 Employee.prototype.retireable = function() { return this.age > 55; } 0147 0148 function Manager(age, name, group) { 0149 this.age = age; 0150 this.name = name; 0151 this.group = group; 0152 } 0153 Manager.prototype = new Employee(); 0154 Manager.prototype.toString = function() { 0155 return "Name: " + this.name + ", age: " + this.age 0156 + ", group: " + this.group; 0157 } 0158 0159 e = new Employee(24, "Tony"); 0160 m = new Manager(62, "Paul", "Finance"); 0161 test("m.retireable()", true); 0162 test("m instanceof Employee", true); 0163 test("e instanceof Manager", false); 0164 0165 test("{true;}", true); 0166 test(";", undefined); 0167 test("{}", undefined); 0168 test("i=0; do { i++; } while(i<10); i", 10); 0169 test("i=0; while (i<10) { i++; }; i", 10); 0170 test("for (i = 0; i < 10; i++); i", 10); 0171 test("i=0; for (; i < 10; i++); i", 10); 0172 test("i=0; for (; i < 10; ) i++; i", 10); 0173 test("i=0; for (; ;i++) if (i==10) break; i", 10); 0174 test("a=[1,2,3,4]; c=0; for (var v in a) c+=a[v]; c", 10); 0175 test("delete t; t", "exception"); 0176 test("{var t;} t", undefined); 0177 test("continue", "exception"); 0178 test("return", "exception"); 0179 test("break", "exception"); 0180 test("x = 0; outer: for (;;) { for (;;) break outer; x++; }; x", 0); 0181 test("x = 0; for (i = 0; i < 3; i++) { continue; x++; } x", 0); 0182 test("x = 0; it:for (i = 0; i < 3; i++) { for (;;) continue it; x++; } x", 0); 0183 test("c = 9; o = { a:'a', b: { c: 'c' }, c:7 }; with (o.b) x = c; x", 'c'); 0184 test("x = ''; for (i = 0; i < 8; i++) switch (i) {" + 0185 "case 0: x+='a'; case 1: x+='b'; break;" + 0186 "case 2: x+='c'; break; case 3: x+='d'; default: x+='e';" + 0187 "case 4: x+='f'; break; case 5: x+='g'; case 6: x+='h';}; x", 0188 "abbcdeffghhef"); 0189 test("foo:bar:baz:;", undefined); 0190 test("throw {}", "exception"); 0191 test("x=0;try{throw {a:1}} catch(e){x=e.a};x", 1); 0192 test("x=y=0;try{" + 0193 " try { throw {a:1} } finally {x=2}; " + 0194 "} catch(e) {y=e.a}; x+y", 3); 0195 test("x=y=0; try{throw {a:2};y=1;} catch(e){x=e.a;y=-7;} finally{y=3}; x+y", 5); 0196 0197 0198 test("String(/a|ab/.exec('abc'))", "a"); 0199 test("String(/((a)|(ab))((c)|(bc))/.exec('abc'))", "abc,a,a,,bc,,bc"); 0200 test("String(/a[a-z]{2,4}/.exec('abcdefghi'))", "abcde"); 0201 test("String(/a[a-z]{2,4}?/.exec('abcdefghi'))", "abc"); 0202 test("String(/(aa|aabaac|ba|b|c)*/.exec('aabaac'))", "aaba,ba"); 0203 test("'aaaaaaaaaa,aaaaaaaaaaaaaaa'.replace(/^(a+)\\1*,\\1+$/,'$1')", "aaaaa"); 0204 test("String(/(z)((a+)?(b+)?(c))*/.exec('zaacbbbcac'))", "zaacbbbcac,z,ac,a,,c") 0205 test("String(/(a*)*/.exec('b'))",","); 0206 test("String(/(a*)b\\1+/.exec('baaaac'))","b,"); 0207 test("String(/(?=(a+))/.exec('baaabac'))",",aaa"); 0208 test("String(/(?=(a+))a*b\\1/.exec('baaabac'))", "aba,a"); 0209 test("String(/(.*?)a(?!(a+)b\\2c)\\2(.*)/.exec('baaabaac'))", 0210 "baaabaac,ba,,abaac"); 0211 0212 test("'$1,$2'.replace(/(\\$(\\d))/g, '$$1-$1$2')", "$1-$11,$1-$22"); 0213 test("String('ab'.split(/a*?/))", "a,b"); 0214 test("String('ab'.split(/a*/))", ",b"); 0215 0216 /* Print a summary of what went right, and what went wrong */ 0217 0218 println(); 0219 println((total - failures) + " out of " + total + " passed."); 0220 0221 /* Throw an error on failure */ 0222 if (failures > 0) 0223 throw new Error("tests failure"); 0224