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 += " FAIL, 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"', "");
0092 test('"\\33\\133m"', "");
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