add jscript winetest from wine 1.1.11
authorChristoph von Wittich <christoph_vw@reactos.org>
Mon, 29 Dec 2008 09:41:56 +0000 (09:41 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Mon, 29 Dec 2008 09:41:56 +0000 (09:41 +0000)
svn path=/trunk/; revision=38445

rostests/winetests/directory.rbuild
rostests/winetests/jscript/api.js [new file with mode: 0644]
rostests/winetests/jscript/jscript.c [new file with mode: 0644]
rostests/winetests/jscript/jscript.rbuild [new file with mode: 0644]
rostests/winetests/jscript/lang.js [new file with mode: 0644]
rostests/winetests/jscript/regexp.js [new file with mode: 0644]
rostests/winetests/jscript/rsrc.rc [new file with mode: 0644]
rostests/winetests/jscript/run.c [new file with mode: 0644]
rostests/winetests/jscript/testlist.c [new file with mode: 0644]

index 2024968..5ac3594 100644 (file)
@@ -37,6 +37,9 @@
        <directory name="imm32">
                <xi:include href="imm32/imm32.rbuild" />
        </directory>
+       <directory name="jscript">
+               <xi:include href="jscript/jscript.rbuild" />
+       </directory>
        <directory name="kernel32">
                <xi:include href="kernel32/kernel32.rbuild" />
        </directory>
diff --git a/rostests/winetests/jscript/api.js b/rostests/winetests/jscript/api.js
new file mode 100644 (file)
index 0000000..16fba15
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+var tmp, i;
+
+i = parseInt("0");
+ok(i === 0, "parseInt('0') = " + i);
+i = parseInt("123");
+ok(i === 123, "parseInt('123') = " + i);
+i = parseInt("-123");
+ok(i === -123, "parseInt('-123') = " + i);
+i = parseInt("0xff");
+ok(i === 0xff, "parseInt('0xff') = " + i);
+i = parseInt("11", 8);
+ok(i === 9, "parseInt('11', 8) = " + i);
+i = parseInt("1j", 22);
+ok(i === 41, "parseInt('1j', 32) = " + i);
+i = parseInt("123", 0);
+ok(i === 123, "parseInt('123', 0) = " + i);
+i = parseInt("123", 10, "test");
+ok(i === 123, "parseInt('123', 10, 'test') = " + i);
+i = parseInt("11", "8");
+ok(i === 9, "parseInt('11', '8') = " + i);
+
+tmp = encodeURI("abc");
+ok(tmp === "abc", "encodeURI('abc') = " + tmp);
+tmp = encodeURI("{abc}");
+ok(tmp === "%7Babc%7D", "encodeURI('{abc}') = " + tmp);
+tmp = encodeURI("");
+ok(tmp === "", "encodeURI('') = " + tmp);
+tmp = encodeURI("\01\02\03\04");
+ok(tmp === "%01%02%03%04", "encodeURI('\\01\\02\\03\\04') = " + tmp);
+tmp = encodeURI("{#@}");
+ok(tmp === "%7B#@%7D", "encodeURI('{#@}') = " + tmp);
+tmp = encodeURI("\xa1 ");
+ok(tmp === "%C2%A1%20", "encodeURI(\\xa1 ) = " + tmp);
+tmp = encodeURI("\xffff");
+ok(tmp.length === 8, "encodeURI('\\xffff').length = " + tmp.length);
+tmp = encodeURI("abcABC123;/?:@&=+$,-_.!~*'()");
+ok(tmp === "abcABC123;/?:@&=+$,-_.!~*'()", "encodeURI('abcABC123;/?:@&=+$,-_.!~*'()') = " + tmp);
+tmp = encodeURI();
+ok(tmp === "undefined", "encodeURI() = " + tmp);
+tmp = encodeURI("abc", "test");
+ok(tmp === "abc", "encodeURI('abc') = " + tmp);
+
+tmp = "" + new Object();
+ok(tmp === "[object Object]", "'' + new Object() = " + tmp);
+
+ok("".length === 0, "\"\".length = " + "".length);
+ok(getVT("".length) == "VT_I4", "\"\".length = " + "".length);
+ok("abc".length === 3, "\"abc\".length = " + "abc".length);
+ok(String.prototype.length === 0, "String.prototype.length = " + String.prototype.length);
+
+tmp = "".toString();
+ok(tmp === "", "''.toString() = " + tmp);
+tmp = "test".toString();
+ok(tmp === "test", "''.toString() = " + tmp);
+tmp = "test".toString(3);
+ok(tmp === "test", "''.toString(3) = " + tmp);
+
+tmp = "".valueOf();
+ok(tmp === "", "''.valueOf() = " + tmp);
+tmp = "test".valueOf();
+ok(tmp === "test", "''.valueOf() = " + tmp);
+tmp = "test".valueOf(3);
+ok(tmp === "test", "''.valueOf(3) = " + tmp);
+
+var str = new String("test");
+ok(str.toString() === "test", "str.toString() = " + str.toString());
+var str = new String();
+ok(str.toString() === "", "str.toString() = " + str.toString());
+var str = new String("test", "abc");
+ok(str.toString() === "test", "str.toString() = " + str.toString());
+
+tmp = "value " + str;
+ok(tmp === "value test", "'value ' + str = " + tmp);
+
+tmp = String();
+ok(tmp === "", "String() = " + tmp);
+tmp = String(false);
+ok(tmp === "false", "String(false) = " + tmp);
+tmp = String(null);
+ok(tmp === "null", "String(null) = " + tmp);
+tmp = String("test");
+ok(tmp === "test", "String('test') = " + tmp);
+tmp = String("test", "abc");
+ok(tmp === "test", "String('test','abc') = " + tmp);
+
+tmp = "abc".charAt(0);
+ok(tmp === "a", "'abc',charAt(0) = " + tmp);
+tmp = "abc".charAt(1);
+ok(tmp === "b", "'abc',charAt(1) = " + tmp);
+tmp = "abc".charAt(2);
+ok(tmp === "c", "'abc',charAt(2) = " + tmp);
+tmp = "abc".charAt(3);
+ok(tmp === "", "'abc',charAt(3) = " + tmp);
+tmp = "abc".charAt(4);
+ok(tmp === "", "'abc',charAt(4) = " + tmp);
+tmp = "abc".charAt();
+ok(tmp === "a", "'abc',charAt() = " + tmp);
+tmp = "abc".charAt(-1);
+ok(tmp === "", "'abc',charAt(-1) = " + tmp);
+tmp = "abc".charAt(0,2);
+ok(tmp === "a", "'abc',charAt(0.2) = " + tmp);
+
+tmp = "abc".charCodeAt(0);
+ok(tmp === 0x61, "'abc'.charCodeAt(0) = " + tmp);
+tmp = "abc".charCodeAt(1);
+ok(tmp === 0x62, "'abc'.charCodeAt(1) = " + tmp);
+tmp = "abc".charCodeAt(2);
+ok(tmp === 0x63, "'abc'.charCodeAt(2) = " + tmp);
+tmp = "abc".charCodeAt();
+ok(tmp === 0x61, "'abc'.charCodeAt() = " + tmp);
+tmp = "abc".charCodeAt(true);
+ok(tmp === 0x62, "'abc'.charCodeAt(true) = " + tmp);
+tmp = "abc".charCodeAt(0,2);
+ok(tmp === 0x61, "'abc'.charCodeAt(0,2) = " + tmp);
+
+tmp = "abcd".substring(1,3);
+ok(tmp === "bc", "'abcd'.substring(1,3) = " + tmp);
+tmp = "abcd".substring(-1,3);
+ok(tmp === "abc", "'abcd'.substring(-1,3) = " + tmp);
+tmp = "abcd".substring(1,6);
+ok(tmp === "bcd", "'abcd'.substring(1,6) = " + tmp);
+tmp = "abcd".substring(3,1);
+ok(tmp === "bc", "'abcd'.substring(3,1) = " + tmp);
+tmp = "abcd".substring(2,2);
+ok(tmp === "", "'abcd'.substring(2,2) = " + tmp);
+tmp = "abcd".substring(true,"3");
+ok(tmp === "bc", "'abcd'.substring(true,'3') = " + tmp);
+tmp = "abcd".substring(1,3,2);
+ok(tmp === "bc", "'abcd'.substring(1,3,2) = " + tmp);
+tmp = "abcd".substring();
+ok(tmp === "abcd", "'abcd'.substring() = " + tmp);
+
+tmp = "abcd".slice(1,3);
+ok(tmp === "bc", "'abcd'.slice(1,3) = " + tmp);
+tmp = "abcd".slice(1,-1);
+ok(tmp === "bc", "'abcd'.slice(1,-1) = " + tmp);
+tmp = "abcd".slice(-3,3);
+ok(tmp === "bc", "'abcd'.slice(-3,3) = " + tmp);
+tmp = "abcd".slice(-6,3);
+ok(tmp === "abc", "'abcd'.slice(-6,3) = " + tmp);
+tmp = "abcd".slice(3,1);
+ok(tmp === "", "'abcd'.slice(3,1) = " + tmp);
+tmp = "abcd".slice(true,3);
+ok(tmp === "bc", "'abcd'.slice(true,3) = " + tmp);
+tmp = "abcd".slice();
+ok(tmp === "abcd", "'abcd'.slice() = " + tmp);
+tmp = "abcd".slice(1);
+ok(tmp === "bcd", "'abcd'.slice(1) = " + tmp);
+
+tmp = "abc".concat(["d",1],2,false);
+ok(tmp === "abcd,12false", "concat returned " + tmp);
+var arr = new Array(2,"a");
+arr.concat = String.prototype.concat;
+tmp = arr.concat("d");
+ok(tmp === "2,ad", "arr.concat = " + tmp);
+
+m = "a+bcabc".match("a+");
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 1, "m.length is not 1");
+ok(m["0"] === "a", "m[0] is not \"ab\"");
+
+r = "- [test] -".replace("[test]", "success");
+ok(r === "- success -", "r = " + r + " expected '- success -'");
+
+r = "- [test] -".replace("[test]", "success", "test");
+ok(r === "- success -", "r = " + r + " expected '- success -'");
+
+r = "test".replace();
+ok(r === "test", "r = " + r + " expected 'test'");
+
+function replaceFunc3(m, off, str) {
+    ok(arguments.length === 3, "arguments.length = " + arguments.length);
+    ok(m === "[test]", "m = " + m + " expected [test1]");
+    ok(off === 1, "off = " + off + " expected 0");
+    ok(str === "-[test]-", "str = " + arguments[3]);
+    return "ret";
+}
+
+r = "-[test]-".replace("[test]", replaceFunc3);
+ok(r === "-ret-", "r = " + r + " expected '-ret-'");
+
+r = "-[test]-".replace("[test]", replaceFunc3, "test");
+ok(r === "-ret-", "r = " + r + " expected '-ret-'");
+
+r = "1,2,3".split(",");
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+
+r = "1,2,3".split(",*");
+ok(r.length === 1, "r.length = " + r.length);
+ok(r[0] === "1,2,3", "r[0] = " + r[0]);
+
+r = "123".split("");
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "123".split(2);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "3", "r[1] = " + r[1]);
+
+r = "1,2,".split(",");
+ok(typeof(r) === "object", "typeof(r) = " + typeof(r));
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "", "r[2] = " + r[2]);
+
+tmp = "abcd".indexOf("bc",0);
+ok(tmp === 1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("bc",1);
+ok(tmp === 1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("bc");
+ok(tmp === 1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("ac");
+ok(tmp === -1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("bc",2);
+ok(tmp === -1, "indexOf = " + tmp);
+tmp = "abcd".indexOf("a",0);
+ok(tmp === 0, "indexOf = " + tmp);
+tmp = "abcd".indexOf("bc",0,"test");
+ok(tmp === 1, "indexOf = " + tmp);
+tmp = "abcd".indexOf();
+ok(tmp == -1, "indexOf = " + tmp);
+
+tmp = "".toLowerCase();
+ok(tmp === "", "''.toLowerCase() = " + tmp);
+tmp = "test".toLowerCase();
+ok(tmp === "test", "''.toLowerCase() = " + tmp);
+tmp = "test".toLowerCase(3);
+ok(tmp === "test", "''.toLowerCase(3) = " + tmp);
+tmp = "tEsT".toLowerCase();
+ok(tmp === "test", "''.toLowerCase() = " + tmp);
+tmp = "tEsT".toLowerCase(3);
+ok(tmp === "test", "''.toLowerCase(3) = " + tmp);
+
+tmp = "".toUpperCase();
+ok(tmp === "", "''.toUpperCase() = " + tmp);
+tmp = "TEST".toUpperCase();
+ok(tmp === "TEST", "''.toUpperCase() = " + tmp);
+tmp = "TEST".toUpperCase(3);
+ok(tmp === "TEST", "''.toUpperCase(3) = " + tmp);
+tmp = "tEsT".toUpperCase();
+ok(tmp === "TEST", "''.toUpperCase() = " + tmp);
+tmp = "tEsT".toUpperCase(3);
+ok(tmp === "TEST", "''.toUpperCase(3) = " + tmp);
+
+tmp = "".big();
+ok(tmp === "<BIG></BIG>", "''.big() = " + tmp);
+tmp = "".big(3);
+ok(tmp === "<BIG></BIG>", "''.big(3) = " + tmp);
+tmp = "test".big();
+ok(tmp === "<BIG>test</BIG>", "'test'.big() = " + tmp);
+tmp = "test".big(3);
+ok(tmp === "<BIG>test</BIG>", "'test'.big(3) = " + tmp);
+
+tmp = "".blink();
+ok(tmp === "<BLINK></BLINK>", "''.blink() = " + tmp);
+tmp = "".blink(3);
+ok(tmp === "<BLINK></BLINK>", "''.blink(3) = " + tmp);
+tmp = "test".blink();
+ok(tmp === "<BLINK>test</BLINK>", "'test'.blink() = " + tmp);
+tmp = "test".blink(3);
+ok(tmp === "<BLINK>test</BLINK>", "'test'.blink(3) = " + tmp);
+
+tmp = "".bold();
+ok(tmp === "<B></B>", "''.bold() = " + tmp);
+tmp = "".bold(3);
+ok(tmp === "<B></B>", "''.bold(3) = " + tmp);
+tmp = "test".bold();
+ok(tmp === "<B>test</B>", "'test'.bold() = " + tmp);
+tmp = "test".bold(3);
+ok(tmp === "<B>test</B>", "'test'.bold(3) = " + tmp);
+
+tmp = "".fixed();
+ok(tmp === "<TT></TT>", "''.fixed() = " + tmp);
+tmp = "".fixed(3);
+ok(tmp === "<TT></TT>", "''.fixed(3) = " + tmp);
+tmp = "test".fixed();
+ok(tmp === "<TT>test</TT>", "'test'.fixed() = " + tmp);
+tmp = "test".fixed(3);
+ok(tmp === "<TT>test</TT>", "'test'.fixed(3) = " + tmp);
+
+tmp = "".italics();
+ok(tmp === "<I></I>", "''.italics() = " + tmp);
+tmp = "".italics(3);
+ok(tmp === "<I></I>", "''.italics(3) = " + tmp);
+tmp = "test".italics();
+ok(tmp === "<I>test</I>", "'test'.italics() = " + tmp);
+tmp = "test".italics(3);
+ok(tmp === "<I>test</I>", "'test'.italics(3) = " + tmp);
+
+tmp = "".small();
+ok(tmp === "<SMALL></SMALL>", "''.small() = " + tmp);
+tmp = "".small(3);
+ok(tmp === "<SMALL></SMALL>", "''.small(3) = " + tmp);
+tmp = "test".small();
+ok(tmp === "<SMALL>test</SMALL>", "'test'.small() = " + tmp);
+tmp = "test".small(3);
+ok(tmp === "<SMALL>test</SMALL>", "'test'.small(3) = " + tmp);
+
+tmp = "".strike();
+ok(tmp === "<STRIKE></STRIKE>", "''.strike() = " + tmp);
+tmp = "".strike(3);
+ok(tmp === "<STRIKE></STRIKE>", "''.strike(3) = " + tmp);
+tmp = "test".strike();
+ok(tmp === "<STRIKE>test</STRIKE>", "'test'.strike() = " + tmp);
+tmp = "test".strike(3);
+ok(tmp === "<STRIKE>test</STRIKE>", "'test'.strike(3) = " + tmp);
+
+tmp = "".sub();
+ok(tmp === "<SUB></SUB>", "''.sub() = " + tmp);
+tmp = "".sub(3);
+ok(tmp === "<SUB></SUB>", "''.sub(3) = " + tmp);
+tmp = "test".sub();
+ok(tmp === "<SUB>test</SUB>", "'test'.sub() = " + tmp);
+tmp = "test".sub(3);
+ok(tmp === "<SUB>test</SUB>", "'test'.sub(3) = " + tmp);
+
+tmp = "".sup();
+ok(tmp === "<SUP></SUP>", "''.sup() = " + tmp);
+tmp = "".sup(3);
+ok(tmp === "<SUP></SUP>", "''.sup(3) = " + tmp);
+tmp = "test".sup();
+ok(tmp === "<SUP>test</SUP>", "'test'.sup() = " + tmp);
+tmp = "test".sup(3);
+ok(tmp === "<SUP>test</SUP>", "'test'.sup(3) = " + tmp);
+
+var arr = new Array();
+ok(typeof(arr) === "object", "arr () is not object");
+ok((arr.length === 0), "arr.length is not 0");
+ok(arr["0"] === undefined, "arr[0] is not undefined");
+
+var arr = new Array(1, 2, "test");
+ok(typeof(arr) === "object", "arr (1,2,test) is not object");
+ok((arr.length === 3), "arr.length is not 3");
+ok(arr["0"] === 1, "arr[0] is not 1");
+ok(arr["1"] === 2, "arr[1] is not 2");
+ok(arr["2"] === "test", "arr[2] is not \"test\"");
+
+arr["7"] = true;
+ok((arr.length === 8), "arr.length is not 8");
+
+tmp = "" + [];
+ok(tmp === "", "'' + [] = " + tmp);
+tmp = "" + [1,true];
+ok(tmp === "1,true", "'' + [1,true] = " + tmp);
+
+var arr = new Array(6);
+ok(typeof(arr) === "object", "arr (6) is not object");
+ok((arr.length === 6), "arr.length is not 6");
+ok(arr["0"] === undefined, "arr[0] is not undefined");
+
+ok(arr.push() === 6, "arr.push() !== 6");
+ok(arr.push(1) === 7, "arr.push(1) !== 7");
+ok(arr[6] === 1, "arr[6] != 1");
+ok(arr.length === 7, "arr.length != 10");
+ok(arr.push(true, 'b', false) === 10, "arr.push(true, 'b', false) !== 10");
+ok(arr[8] === "b", "arr[8] != 'b'");
+ok(arr.length === 10, "arr.length != 10");
+
+arr = [3,4,5];
+tmp = arr.pop();
+ok(arr.length === 2, "arr.length = " + arr.length);
+ok(tmp === 5, "pop() = " + tmp);
+tmp = arr.pop(2);
+ok(arr.length === 1, "arr.length = " + arr.length);
+ok(tmp === 4, "pop() = " + tmp);
+tmp = arr.pop();
+ok(arr.length === 0, "arr.length = " + arr.length);
+ok(tmp === 3, "pop() = " + tmp);
+for(tmp in arr)
+    ok(false, "not deleted " + tmp);
+tmp = arr.pop();
+ok(arr.length === 0, "arr.length = " + arr.length);
+ok(tmp === undefined, "tmp = " + tmp);
+arr = [,,,,,];
+tmp = arr.pop();
+ok(arr.length === 5, "arr.length = " + arr.length);
+ok(tmp === undefined, "tmp = " + tmp);
+
+arr = [1,2,null,false,undefined,,"a"];
+
+tmp = arr.join();
+ok(tmp === "1,2,,false,,,a", "arr.join() = " + tmp);
+tmp = arr.join(";");
+ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp);
+tmp = arr.join(";","test");
+ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp);
+tmp = arr.join("");
+ok(tmp === "12falsea", "arr.join('') = " + tmp);
+
+tmp = arr.toString();
+ok(tmp === "1,2,,false,,,a", "arr.toString() = " + tmp);
+tmp = arr.toString("test");
+ok(tmp === "1,2,,false,,,a", "arr.toString() = " + tmp);
+
+arr = [5,true,2,-1,3,false,"2.5"];
+tmp = arr.sort(function(x,y) { return y-x; });
+ok(tmp === arr, "tmp !== arr");
+tmp = [5,3,"2.5",2,true,false,-1];
+for(var i=0; i < arr.length; i++)
+    ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]);
+
+arr = [5,false,2,0,"abc",3,"a",-1];
+tmp = arr.sort();
+ok(tmp === arr, "tmp !== arr");
+tmp = [-1,0,2,3,5,"a","abc",false];
+for(var i=0; i < arr.length; i++)
+    ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]);
+
+arr = ["a", "b", "ab"];
+tmp = ["a", "ab", "b"];
+ok(arr.sort() === arr, "arr.sort() !== arr");
+for(var i=0; i < arr.length; i++)
+    ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]);
+
+var num = new Number(6);
+arr = [0,1,2];
+tmp = arr.concat(3, [4,5], num);
+ok(tmp !== arr, "tmp === arr");
+for(var i=0; i<6; i++)
+    ok(tmp[i] === i, "tmp[" + i + "] = " + tmp[i]);
+ok(tmp[6] === num, "tmp[6] !== num");
+ok(tmp.length === 7, "tmp.length = " + tmp.length);
+
+arr = [].concat();
+ok(arr.length === 0, "arr.length = " + arr.length);
+
+arr = [1,];
+tmp = arr.concat([2]);
+ok(tmp.length === 3, "tmp.length = " + tmp.length);
+ok(tmp[1] === undefined, "tmp[1] = " + tmp[1]);
+
+var num = new Number(2);
+ok(num.toString() === "2", "num(2).toString !== 2");
+var num = new Number();
+ok(num.toString() === "0", "num().toString !== 0");
+
+ok(Number() === 0, "Number() = " + Number());
+ok(Number(false) === 0, "Number(false) = " + Number(false));
+ok(Number("43") === 43, "Number('43') = " + Number("43"));
+
+tmp = (new Number(1)).valueOf();
+ok(tmp === 1, "(new Number(1)).valueOf = " + tmp);
+tmp = (new Number(1,2)).valueOf();
+ok(tmp === 1, "(new Number(1,2)).valueOf = " + tmp);
+tmp = (new Number()).valueOf();
+ok(tmp === 0, "(new Number()).valueOf = " + tmp);
+tmp = Number.prototype.valueOf();
+ok(tmp === 0, "Number.prototype.valueOf = " + tmp);
+
+tmp = Math.min(1);
+ok(tmp === 1, "Math.min(1) = " + tmp);
+
+tmp = Math.min(1, false);
+ok(tmp === 0, "Math.min(1, false) = " + tmp);
+
+tmp = Math.min();
+ok(tmp === Infinity, "Math.min() = " + tmp);
+
+tmp = Math.min(1, NaN, -Infinity, false);
+ok(isNaN(tmp), "Math.min(1, NaN, -Infinity, false) is not NaN");
+
+tmp = Math.min(1, false, true, null, -3);
+ok(tmp === -3, "Math.min(1, false, true, null, -3) = " + tmp);
+
+tmp = Math.max(1);
+ok(tmp === 1, "Math.max(1) = " + tmp);
+
+tmp = Math.max(true, 0);
+ok(tmp === 1, "Math.max(true, 0) = " + tmp);
+
+tmp = Math.max(-2, false, true, null, 1);
+ok(tmp === 1, "Math.max(-2, false, true, null, 1) = " + tmp);
+
+tmp = Math.max();
+ok(tmp === -Infinity, "Math.max() = " + tmp);
+
+tmp = Math.max(true, NaN, 0);
+ok(isNaN(tmp), "Math.max(true, NaN, 0) is not NaN");
+
+tmp = Math.round(0.5);
+ok(tmp === 1, "Math.round(0.5) = " + tmp);
+
+tmp = Math.round(-0.5);
+ok(tmp === 0, "Math.round(-0.5) = " + tmp);
+
+tmp = Math.round(1.1);
+ok(tmp === 1, "Math.round(1.1) = " + tmp);
+
+tmp = Math.round(true);
+ok(tmp === 1, "Math.round(true) = " + tmp);
+
+tmp = Math.round(1.1, 3, 4);
+ok(tmp === 1, "Math.round(1.1, 3, 4) = " + tmp);
+
+tmp = Math.ceil(0.5);
+ok(tmp === 1, "Math.ceil(0.5) = " + tmp);
+
+tmp = Math.ceil(-0.5);
+ok(tmp === 0, "Math.ceil(-0.5) = " + tmp);
+
+tmp = Math.ceil(1.1);
+ok(tmp === 2, "Math.round(1.1) = " + tmp);
+
+tmp = Math.ceil(true);
+ok(tmp === 1, "Math.ceil(true) = " + tmp);
+
+tmp = Math.ceil(1.1, 3, 4);
+ok(tmp === 2, "Math.ceil(1.1, 3, 4) = " + tmp);
+
+tmp = Math.ceil();
+ok(isNaN(tmp), "ceil() is not NaN");
+
+tmp = Math.floor(0.5);
+ok(tmp === 0, "Math.floor(0.5) = " + tmp);
+
+tmp = Math.floor(-0.5);
+ok(tmp === -1, "Math.floor(-0.5) = " + tmp);
+
+tmp = Math.floor(1.1);
+ok(tmp === 1, "Math.floor(1.1) = " + tmp);
+
+tmp = Math.floor(true);
+ok(tmp === 1, "Math.floor(true) = " + tmp);
+
+tmp = Math.floor(1.1, 3, 4);
+ok(tmp === 1, "Math.floor(1.1, 3, 4) = " + tmp);
+
+tmp = Math.floor();
+ok(isNaN(tmp), "floor is not NaN");
+
+tmp = Math.abs(3);
+ok(tmp === 3, "Math.abs(3) = " + tmp);
+
+tmp = Math.abs(-3);
+ok(tmp === 3, "Math.abs(-3) = " + tmp);
+
+tmp = Math.abs(true);
+ok(tmp === 1, "Math.abs(true) = " + tmp);
+
+tmp = Math.abs();
+ok(isNaN(tmp), "Math.abs() is not NaN");
+
+tmp = Math.abs(NaN);
+ok(isNaN(tmp), "Math.abs() is not NaN");
+
+tmp = Math.abs(-Infinity);
+ok(tmp === Infinity, "Math.abs(-Infinite) = " + tmp);
+
+tmp = Math.abs(-3, 2);
+ok(tmp === 3, "Math.abs(-3, 2) = " + tmp);
+
+tmp = Math.pow(2, 2);
+ok(tmp === 4, "Math.pow(2, 2) = " + tmp);
+
+tmp = Math.pow(4, 0.5);
+ok(tmp === 2, "Math.pow(2, 2) = " + tmp);
+
+tmp = Math.pow(2, 2, 3);
+ok(tmp === 4, "Math.pow(2, 2, 3) = " + tmp);
+
+var func = function  (a) {
+        var a = 1;
+        if(a) return;
+    }.toString();
+ok(func.toString() === "function  (a) {\n        var a = 1;\n        if(a) return;\n    }",
+   "func.toString() = " + func.toString());
+ok("" + func === "function  (a) {\n        var a = 1;\n        if(a) return;\n    }",
+   "'' + func.toString() = " + func);
+
+function testFuncToString(x,y) {
+    return x+y;
+}
+
+ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n    return x+y;\n}",
+   "testFuncToString.toString() = " + testFuncToString.toString());
+ok("" + testFuncToString === "function testFuncToString(x,y) {\n    return x+y;\n}",
+   "'' + testFuncToString = " + testFuncToString);
+
+var date = new Date();
+
+date = new Date(100);
+ok(date.getTime() === 100, "date.getTime() = " + date.getTime());
+ok(Date.prototype.getTime() === 0, "date.prototype.getTime() = " + Date.prototype.getTime());
+
+ok(typeof(Math.PI) === "number", "typeof(Math.PI) = " + typeof(Math.PI));
+ok(Math.floor(Math.PI*100) === 314, "Math.PI = " + Math.PI);
+Math.PI = "test";
+ok(Math.floor(Math.PI*100) === 314, "modified Math.PI = " + Math.PI);
+
+ok(typeof(Math.E) === "number", "typeof(Math.E) = " + typeof(Math.E));
+ok(Math.floor(Math.E*100) === 271, "Math.E = " + Math.E);
+Math.E = "test";
+ok(Math.floor(Math.E*100) === 271, "modified Math.E = " + Math.E);
+
+ok(typeof(Math.LOG2E) === "number", "typeof(Math.LOG2E) = " + typeof(Math.LOG2E));
+ok(Math.floor(Math.LOG2E*100) === 144, "Math.LOG2E = " + Math.LOG2E);
+Math.LOG2E = "test";
+ok(Math.floor(Math.LOG2E*100) === 144, "modified Math.LOG2E = " + Math.LOG2E);
+
+ok(typeof(Math.LOG10E) === "number", "typeof(Math.LOG10E) = " + typeof(Math.LOG10E));
+ok(Math.floor(Math.LOG10E*100) === 43, "Math.LOG10E = " + Math.LOG10E);
+Math.LOG10E = "test";
+ok(Math.floor(Math.LOG10E*100) === 43, "modified Math.LOG10E = " + Math.LOG10E);
+
+reportSuccess();
diff --git a/rostests/winetests/jscript/jscript.c b/rostests/winetests/jscript/jscript.c
new file mode 100644 (file)
index 0000000..4cc01c9
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <initguid.h>
+#include <ole2.h>
+#include <activscp.h>
+#include <objsafe.h>
+#include <dispex.h>
+
+#include "wine/test.h"
+
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
+static const CLSID CLSID_JScript =
+    {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
+
+#define DEFINE_EXPECT(func) \
+    static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+    expect_ ## func = TRUE
+
+#define SET_CALLED(func) \
+    called_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+    do { \
+        ok(expect_ ##func, "unexpected call " #func "\n"); \
+        called_ ## func = TRUE; \
+    }while(0)
+
+#define CHECK_EXPECT(func) \
+    do { \
+        CHECK_EXPECT2(func); \
+        expect_ ## func = FALSE; \
+    }while(0)
+
+#define CHECK_CALLED(func) \
+    do { \
+        ok(called_ ## func, "expected " #func "\n"); \
+        expect_ ## func = called_ ## func = FALSE; \
+    }while(0)
+
+DEFINE_EXPECT(GetLCID);
+DEFINE_EXPECT(OnStateChange_STARTED);
+DEFINE_EXPECT(OnStateChange_CONNECTED);
+DEFINE_EXPECT(OnStateChange_DISCONNECTED);
+DEFINE_EXPECT(OnStateChange_CLOSED);
+DEFINE_EXPECT(OnStateChange_INITIALIZED);
+DEFINE_EXPECT(OnEnterScript);
+DEFINE_EXPECT(OnLeaveScript);
+
+#define test_state(s,ss) _test_state(__LINE__,s,ss)
+static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstate)
+{
+    SCRIPTSTATE state = -1;
+    HRESULT hres;
+
+    hres = IActiveScript_GetScriptState(script, &state);
+    ok_(__FILE__,line) (hres == S_OK, "GetScriptState failed: %08x\n", hres);
+    ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate);
+}
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid))
+        *ppv = iface;
+    else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
+        *ppv = iface;
+    else
+        return E_NOINTERFACE;
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+    CHECK_EXPECT(GetLCID);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+        DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+        const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+    switch(ssScriptState) {
+    case SCRIPTSTATE_STARTED:
+        CHECK_EXPECT(OnStateChange_STARTED);
+        return S_OK;
+    case SCRIPTSTATE_CONNECTED:
+        CHECK_EXPECT(OnStateChange_CONNECTED);
+        return S_OK;
+    case SCRIPTSTATE_DISCONNECTED:
+        CHECK_EXPECT(OnStateChange_DISCONNECTED);
+        return S_OK;
+    case SCRIPTSTATE_CLOSED:
+        CHECK_EXPECT(OnStateChange_CLOSED);
+        return S_OK;
+    case SCRIPTSTATE_INITIALIZED:
+        CHECK_EXPECT(OnStateChange_INITIALIZED);
+        return S_OK;
+    default:
+        ok(0, "unexpected call %d\n", ssScriptState);
+    }
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+    CHECK_EXPECT(OnEnterScript);
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+    CHECK_EXPECT(OnLeaveScript);
+    return S_OK;
+}
+
+#undef ACTSCPSITE_THIS
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+    ActiveScriptSite_QueryInterface,
+    ActiveScriptSite_AddRef,
+    ActiveScriptSite_Release,
+    ActiveScriptSite_GetLCID,
+    ActiveScriptSite_GetItemInfo,
+    ActiveScriptSite_GetDocVersionString,
+    ActiveScriptSite_OnScriptTerminate,
+    ActiveScriptSite_OnStateChange,
+    ActiveScriptSite_OnScriptError,
+    ActiveScriptSite_OnEnterScript,
+    ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+static void test_script_dispatch(IActiveScript *script, BOOL initialized)
+{
+    IDispatchEx *dispex;
+    IDispatch *disp;
+    HRESULT hres;
+
+    disp = (void*)0xdeadbeef;
+    hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
+    if(!initialized) {
+        ok(hres == E_UNEXPECTED, "hres = %08x, expected E_UNEXPECTED\n", hres);
+        ok(!disp, "disp != NULL\n");
+        return;
+    }
+
+    ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    ok(disp != NULL, "disp == NULL\n");
+    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+    IDispatch_Release(disp);
+    ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
+
+    IDispatchEx_Release(dispex);
+}
+
+static void test_safety(IUnknown *unk)
+{
+    IObjectSafety *safety;
+    DWORD supported, enabled;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&safety);
+    ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, NULL);
+    ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, NULL, &enabled);
+    ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScript, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
+
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER
+                |INTERFACESAFE_FOR_UNTRUSTED_CALLER,
+            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+    ok(hres == E_FAIL, "SetInterfaceSafetyOptions failed: %08x, expected E_FAIL\n", hres);
+
+    hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
+            INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+    ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
+
+    supported = enabled = 0xdeadbeef;
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "supported=%x\n", supported);
+    ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
+       "enabled=%x\n", enabled);
+
+    IObjectSafety_Release(safety);
+}
+
+static void test_jscript(void)
+{
+    IActiveScriptParse *parse;
+    IActiveScript *script;
+    IUnknown *unk;
+    ULONG ref;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IUnknown, (void**)&unk);
+    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IActiveScript, (void**)&script);
+    ok(hres == S_OK, "Could not get IActiveScript: %08x\n", hres);
+
+    hres = IUnknown_QueryInterface(unk, &IID_IActiveScriptParse, (void**)&parse);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+    test_safety(unk);
+
+    hres = IActiveScriptParse_InitNew(parse);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parse);
+    ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
+
+    hres = IActiveScript_SetScriptSite(script, NULL);
+    ok(hres == E_POINTER, "SetScriptSite failed: %08x, expected E_POINTER\n", hres);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+    test_script_dispatch(script, FALSE);
+
+    SET_EXPECT(GetLCID);
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+    CHECK_CALLED(GetLCID);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+
+    test_state(script, SCRIPTSTATE_INITIALIZED);
+
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
+
+    test_script_dispatch(script, TRUE);
+
+    SET_EXPECT(OnStateChange_STARTED);
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_STARTED);
+
+    test_state(script, SCRIPTSTATE_STARTED);
+
+    SET_EXPECT(OnStateChange_CLOSED);
+    hres = IActiveScript_Close(script);
+    ok(hres == S_OK, "Close failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_CLOSED);
+
+    test_state(script, SCRIPTSTATE_CLOSED);
+    test_script_dispatch(script, FALSE);
+
+    IActiveScriptParse_Release(parse);
+    IActiveScript_Release(script);
+
+    ref = IUnknown_Release(unk);
+    ok(!ref, "ref = %d\n", ref);
+}
+
+static void test_jscript2(void)
+{
+    IActiveScriptParse *parse;
+    IActiveScript *script;
+    IUnknown *unk;
+    ULONG ref;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IUnknown, (void**)&unk);
+    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IActiveScript, (void**)&script);
+    ok(hres == S_OK, "Could not get IActiveScript: %08x\n", hres);
+
+    hres = IUnknown_QueryInterface(unk, &IID_IActiveScriptParse, (void**)&parse);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+    SET_EXPECT(GetLCID);
+    hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+    CHECK_CALLED(GetLCID);
+
+    test_state(script, SCRIPTSTATE_UNINITIALIZED);
+
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    hres = IActiveScriptParse_InitNew(parse);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+
+    hres = IActiveScriptParse_InitNew(parse);
+    ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
+
+    SET_EXPECT(OnStateChange_CONNECTED);
+    hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_CONNECTED);
+
+    test_state(script, SCRIPTSTATE_CONNECTED);
+
+    SET_EXPECT(OnStateChange_DISCONNECTED);
+    SET_EXPECT(OnStateChange_INITIALIZED);
+    SET_EXPECT(OnStateChange_CLOSED);
+    hres = IActiveScript_Close(script);
+    ok(hres == S_OK, "Close failed: %08x\n", hres);
+    CHECK_CALLED(OnStateChange_DISCONNECTED);
+    CHECK_CALLED(OnStateChange_INITIALIZED);
+    CHECK_CALLED(OnStateChange_CLOSED);
+
+    test_state(script, SCRIPTSTATE_CLOSED);
+    test_script_dispatch(script, FALSE);
+
+    IActiveScriptParse_Release(parse);
+    IActiveScript_Release(script);
+
+    ref = IUnknown_Release(unk);
+    ok(!ref, "ref = %d\n", ref);
+}
+
+START_TEST(jscript)
+{
+    CoInitialize(NULL);
+
+    test_jscript();
+    test_jscript2();
+
+    CoUninitialize();
+}
diff --git a/rostests/winetests/jscript/jscript.rbuild b/rostests/winetests/jscript/jscript.rbuild
new file mode 100644 (file)
index 0000000..2e1a1a5
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<group>
+<module name="jscript_winetest" type="win32cui" installbase="bin" installname="jscript_winetest.exe" allowwarnings="true">
+       <compilerflag compiler="cc">-Wno-format</compilerflag>
+       <include base="jscript_winetest">.</include>
+       <file>jscript.c</file>
+       <file>run.c</file>
+       <file>testlist.c</file>
+       <file>rsrc.rc</file>
+       <library>wine</library>
+       <library>ole32</library>
+       <library>oleaut32</library>
+       <library>kernel32</library>
+       <library>ntdll</library>
+</module>
+</group>
diff --git a/rostests/winetests/jscript/lang.js b/rostests/winetests/jscript/lang.js
new file mode 100644 (file)
index 0000000..0d68f37
--- /dev/null
@@ -0,0 +1,874 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+var tmp;
+
+ok(true, "true is not true?");
+ok(!false, "!false is not true");
+ok(!undefined, "!undefined is not true");
+ok(!null, "!null is not true");
+ok(!0, "!0 is not true");
+ok(!0.0, "!0.0 is not true");
+
+ok(1 === 1, "1 === 1 is false");
+ok(!(1 === 2), "!(1 === 2) is false");
+ok(1.0 === 1, "1.0 === 1 is false");
+ok("abc" === "abc", "\"abc\" === \"abc\" is false");
+ok(true === true, "true === true is false");
+ok(null === null, "null === null is false");
+ok(undefined === undefined, "undefined === undefined is false");
+ok(!(undefined === null), "!(undefined === null) is false");
+
+ok(1 !== 2, "1 !== 2 is false");
+ok(null !== undefined, "null !== undefined is false");
+
+ok(1 == 1, "1 == 1 is false");
+ok(!(1 == 2), "!(1 == 2) is false");
+ok(1.0 == 1, "1.0 == 1 is false");
+ok("abc" == "abc", "\"abc\" == \"abc\" is false");
+ok(true == true, "true == true is false");
+ok(null == null, "null == null is false");
+ok(undefined == undefined, "undefined == undefined is false");
+ok(undefined == null, "undefined == null is false");
+ok(true == 1, "true == 1 is false");
+ok(!(true == 2), "true == 2");
+ok(0 == false, "0 == false is false");
+
+ok(1 != 2, "1 != 2 is false");
+ok(false != 1, "false != 1 is false");
+
+var trueVar = true;
+ok(trueVar, "trueVar is not true");
+
+ok(ScriptEngine.length === 0, "ScriptEngine.length is not 0");
+
+function testFunc1(x, y) {
+    ok(this !== undefined, "this is undefined");
+    ok(x === true, "x is not 1");
+    ok(y === "test", "y is not \"test\"");
+    ok(arguments.length === 2, "arguments.length is not 2");
+    ok(arguments["0"] === true, "arguments[0] is not true");
+    ok(arguments["1"] === "test", "arguments[1] is not \"test\"");
+
+    return true;
+}
+
+ok(testFunc1.length === 2, "testFunc1.length is not 2");
+
+ok(Object.prototype !== undefined, "Object.prototype is undefined");
+ok(Object.prototype.prototype === undefined, "Object.prototype is not undefined");
+ok(String.prototype !== undefined, "String.prototype is undefined");
+ok(Array.prototype !== undefined, "Array.prototype is undefined");
+ok(Boolean.prototype !== undefined, "Boolean.prototype is undefined");
+ok(Number.prototype !== undefined, "Number.prototype is undefined");
+ok(RegExp.prototype !== undefined, "RegExp.prototype is undefined");
+ok(Math !== undefined, "Math is undefined");
+ok(Math.prototype === undefined, "Math.prototype is not undefined");
+ok(Function.prototype !== undefined, "Function.prototype is undefined");
+ok(Function.prototype.prototype === undefined, "Function.prototype is not undefined");
+ok(Date.prototype !== undefined, "Date.prototype is undefined");
+ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined");
+
+Function.prototype.test = true;
+ok(testFunc1.test === true, "testFunc1.test !== true");
+ok(Function.test === true, "Function.test !== true");
+
+ok(typeof(0) === "number", "typeof(0) is not number");
+ok(typeof(1.5) === "number", "typeof(1.5) is not number");
+ok(typeof("abc") === "string", "typeof(\"abc\") is not string");
+ok(typeof("") === "string", "typeof(\"\") is not string");
+ok(typeof(true) === "boolean", "typeof(true) is not boolean");
+ok(typeof(null) === "object", "typeof(null) is not object");
+ok(typeof(undefined) === "undefined", "typeof(undefined) is not undefined");
+ok(typeof(Math) === "object", "typeof(Math) is not object");
+ok(typeof(String.prototype) === "object", "typeof(String.prototype) is not object");
+ok(typeof(testFunc1) === "function", "typeof(testFunc1) is not function");
+ok(typeof(String) === "function", "typeof(String) is not function");
+ok(typeof(ScriptEngine) === "function", "typeof(ScriptEngine) is not function");
+ok(typeof(this) === "object", "typeof(this) is not object");
+
+ok(testFunc1(true, "test") === true, "testFunc1 not returned true");
+
+var obj1 = new Object();
+ok(typeof(obj1) === "object", "typeof(obj1) is not object");
+obj1.test = true;
+obj1.func = function () {
+    ok(this === obj1, "this is not obj1");
+    ok(this.test === true, "this.test is not true");
+    ok(arguments.length === 1, "arguments.length is not 1");
+    ok(arguments["0"] === true, "arguments[0] is not true");
+
+    return "test";
+};
+
+ok(obj1.func(true) === "test", "obj1.func(true) is not \"test\"");
+
+function testConstr1() {
+    this.var1 = 1;
+
+    ok(this !== undefined, "this is undefined");
+    ok(arguments.length === 1, "arguments.length is not 1");
+    ok(arguments["0"] === true, "arguments[0] is not 1");
+
+    return false;
+}
+
+testConstr1.prototype.pvar = 1;
+
+var obj2 = new testConstr1(true);
+ok(typeof(obj2) === "object", "typeof(obj2) is not object");
+ok(obj2.pvar === 1, "obj2.pvar is not 1");
+
+testConstr1.prototype.pvar = 2;
+ok(obj2.pvar === 2, "obj2.pvar is not 2");
+
+obj2.pvar = 3;
+testConstr1.prototype.pvar = 1;
+ok(obj2.pvar === 3, "obj2.pvar is not 3");
+
+var obj3 = new Object;
+ok(typeof(obj3) === "object", "typeof(obj3) is not object");
+
+for(var iter in "test")
+    ok(false, "unexpected forin call, test = " + iter);
+
+for(var iter in null)
+    ok(false, "unexpected forin call, test = " + iter);
+
+for(var iter in false)
+    ok(false, "unexpected forin call, test = " + iter);
+
+tmp = 0;
+if(true)
+    tmp = 1;
+else
+    ok(false, "else evaluated");
+ok(tmp === 1, "tmp !== 1, if not evaluated?");
+
+tmp = 0;
+if(1 === 0)
+    ok(false, "if evaluated");
+else
+    tmp = 1;
+ok(tmp === 1, "tmp !== 1, if not evaluated?");
+
+if(false)
+    ok(false, "if(false) evaluated");
+
+tmp = 0;
+if(true)
+    tmp = 1;
+ok(tmp === 1, "tmp !== 1, if(true) not evaluated?");
+
+if(false) {
+}else {
+}
+
+var obj3 = { prop1: 1,  prop2: typeof(false) };
+ok(obj3.prop1 === 1, "obj3.prop1 is not 1");
+ok(obj3.prop2 === "boolean", "obj3.prop2 is not \"boolean\"");
+
+{
+    var blockVar = 1;
+    blockVar = 2;
+}
+ok(blockVar === 2, "blockVar !== 2");
+
+ok((true ? 1 : 2) === 1, "conditional expression true is not 1");
+ok((0 === 2 ? 1 : 2) === 2, "conditional expression true is not 2");
+
+ok(getVT(undefined) === "VT_EMPTY", "getVT(undefined) is not VT_EMPTY");
+ok(getVT(null) === "VT_NULL", "getVT(null) is not VT_NULL");
+ok(getVT(0) === "VT_I4", "getVT(0) is not VT_I4");
+ok(getVT(0.5) === "VT_R8", "getVT(1.5) is not VT_R8");
+ok(getVT("test") === "VT_BSTR", "getVT(\"test\") is not VT_BSTR");
+ok(getVT(Math) === "VT_DISPATCH", "getVT(Math) is not VT_DISPATCH");
+ok(getVT(false) === "VT_BOOL", "getVT(false) is not VT_BOOL");
+
+tmp = 2+2;
+ok(tmp === 4, "2+2 !== 4");
+ok(getVT(tmp) === "VT_I4", "getVT(2+2) !== VT_I4");
+
+tmp = 2+2.5;
+ok(tmp === 4.5, "2+2.5 !== 4.5");
+ok(getVT(tmp) === "VT_R8", "getVT(2+2.5) !== VT_R8");
+
+tmp = 1.5+2.5;
+ok(tmp === 4, "1.4+2.5 !== 4");
+ok(getVT(tmp) === "VT_I4", "getVT(1.5+2.5) !== VT_I4");
+
+tmp = 4-2;
+ok(tmp === 2, "4-2 !== 2");
+ok(getVT(tmp) === "VT_I4", "getVT(4-2) !== VT_I4");
+
+tmp = 4.5-2;
+ok(tmp === 2.5, "4.5-2 !== 2.5");
+ok(getVT(tmp) === "VT_R8", "getVT(4-2) !== VT_R8");
+
+tmp = -2;
+ok(tmp === 0-2, "-2 !== 0-2");
+ok(getVT(tmp) === "VT_I4", "getVT(-2) !== VT_I4");
+
+tmp = 2*3;
+ok(tmp === 6, "2*3 !== 6");
+ok(getVT(tmp) === "VT_I4", "getVT(2*3) !== VT_I4");
+
+tmp = 2*3.5;
+ok(tmp === 7, "2*3.5 !== 7");
+ok(getVT(tmp) === "VT_I4", "getVT(2*3.5) !== VT_I4");
+
+tmp = 2.5*3.5;
+ok(tmp === 8.75, "2.5*3.5 !== 8.75");
+ok(getVT(tmp) === "VT_R8", "getVT(2.5*3.5) !== VT_R8");
+
+tmp = 4/2;
+ok(tmp === 2, "4/2 !== 2");
+ok(getVT(tmp) === "VT_I4", "getVT(4/2) !== VT_I4");
+
+tmp = 4.5/1.5;
+ok(tmp === 3, "4.5/1.5 !== 3");
+ok(getVT(tmp) === "VT_I4", "getVT(4.5/1.5) !== VT_I4");
+
+tmp = 3/2;
+ok(tmp === 1.5, "3/2 !== 1.5");
+ok(getVT(tmp) === "VT_R8", "getVT(3/2) !== VT_R8");
+
+tmp = 3%2;
+ok(tmp === 1, "3%2 = " + tmp);
+
+tmp = 4%2;
+ok(tmp ===0, "4%2 = " + tmp);
+
+tmp = 3.5%1.5;
+ok(tmp === 0.5, "3.5%1.5 = " + tmp);
+
+tmp = 3%true;
+ok(tmp === 0, "3%true = " + tmp);
+
+tmp = "ab" + "cd";
+ok(tmp === "abcd", "\"ab\" + \"cd\" !== \"abcd\"");
+
+tmp = 1;
+ok((tmp += 1) === 2, "tmp += 1 !== 2");
+ok(tmp === 2, "tmp !== 2");
+
+tmp = 2;
+ok((tmp -= 1) === 1, "tmp -= 1 !== 1");
+ok(tmp === 1, "tmp !=== 1");
+
+tmp = 2;
+ok((tmp *= 1.5) === 3, "tmp *= 1.5 !== 3");
+ok(tmp === 3, "tmp !=== 3");
+
+tmp = 5;
+ok((tmp /= 2) === 2.5, "tmp /= 2 !== 2.5");
+ok(tmp === 2.5, "tmp !=== 2.5");
+
+tmp = 3;
+ok((tmp %= 2) === 1, "tmp %= 2 !== 1");
+ok(tmp === 1, "tmp !== 1");
+
+tmp = 8;
+ok((tmp <<= 1) === 16, "tmp <<= 1 !== 16");
+
+tmp = 8;
+ok((tmp >>= 1) === 4, "tmp >>= 1 !== 4");
+
+tmp = 8;
+ok((tmp >>>= 1) === 4, "tmp >>>= 1 !== 4");
+
+tmp = 3 || ok(false, "second or expression called");
+ok(tmp === 3, "3 || (...) is not 3");
+
+tmp = false || 2;
+ok(tmp === 2, "false || 2 is not 2");
+
+tmp = 0 && ok(false, "second and expression called");
+ok(tmp === 0, "0 && (...) is not 0");
+
+tmp = true && "test";
+ok(tmp === "test", "true && \"test\" is not \"test\"");
+
+tmp = true && 0;
+ok(tmp === 0, "true && 0 is not 0");
+
+tmp = 3 | 4;
+ok(tmp === 7, "3 | 4 !== 7");
+ok(getVT(tmp) === "VT_I4", "getVT(3|4) = " + getVT(tmp));
+
+tmp = 3.5 | 0;
+ok(tmp === 3, "3.5 | 0 !== 3");
+ok(getVT(tmp) === "VT_I4", "getVT(3.5|0) = " + getVT(tmp));
+
+tmp = -3.5 | 0;
+ok(tmp === -3, "-3.5 | 0 !== -3");
+ok(getVT(tmp) === "VT_I4", "getVT(3.5|0) = " + getVT(tmp));
+
+tmp = 10;
+ok((tmp |= 0x10) === 26, "tmp(10) |= 0x10 !== 26");
+ok(getVT(tmp) === "VT_I4", "getVT(tmp |= 10) = " + getVT(tmp));
+
+tmp = 3 & 5;
+ok(tmp === 1, "3 & 5 !== 1");
+ok(getVT(tmp) === "VT_I4", "getVT(3|5) = " + getVT(tmp));
+
+tmp = 3.5 & 0xffff;
+ok(tmp === 3, "3.5 & 0xffff !== 3 ");
+ok(getVT(tmp) === "VT_I4", "getVT(3.5&0xffff) = " + getVT(tmp));
+
+tmp = (-3.5) & 0xffffffff;
+ok(tmp === -3, "-3.5 & 0xffff !== -3");
+ok(getVT(tmp) === "VT_I4", "getVT(3.5&0xffff) = " + getVT(tmp));
+
+tmp = 2 << 3;
+ok(tmp === 16, "2 << 3 = " + tmp);
+
+tmp = 2 << 35;
+ok(tmp === 16, "2 << 35 = " + tmp);
+
+tmp = 8 >> 2;
+ok(tmp === 2, "8 >> 2 = " + tmp);
+
+tmp = -64 >> 4;
+ok(tmp === -4, "-64 >> 4 = " + tmp);
+
+tmp = 8 >>> 2;
+ok(tmp === 2, "8 >> 2 = " + tmp);
+
+tmp = -64 >>> 4;
+ok(tmp === 0x0ffffffc, "-64 >>> 4 = " + tmp);
+
+tmp = 10;
+ok((tmp &= 8) === 8, "tmp(10) &= 8 !== 8");
+ok(getVT(tmp) === "VT_I4", "getVT(tmp &= 8) = " + getVT(tmp));
+
+tmp = 0xf0f0^0xff00;
+ok(tmp === 0x0ff0, "0xf0f0^0xff00 !== 0x0ff0");
+ok(getVT(tmp) === "VT_I4", "getVT(0xf0f0^0xff00) = " + getVT(tmp));
+
+tmp = 5;
+ok((tmp ^= 3) === 6, "tmp(5) ^= 3 !== 6");
+ok(getVT(tmp) === "VT_I4", "getVT(tmp ^= 3) = " + getVT(tmp));
+
+tmp = ~1;
+ok(tmp === -2, "~1 !== -2");
+ok(getVT(tmp) === "VT_I4", "getVT(~1) = " + getVT(tmp));
+
+ok((3,4) === 4, "(3,4) !== 4");
+
+ok(+3 === 3, "+3 !== 3");
+ok(+true === 1, "+true !== 1");
+ok(+false === 0, "+false !== 0");
+ok(+null === 0, "+null !== 0");
+ok(+"0" === 0, "+'0' !== 0");
+ok(+"3" === 3, "+'3' !== 3");
+ok(+"-3" === -3, "+'-3' !== -3");
+ok(+"0xff" === 255, "+'0xff' !== 255");
+ok(+"3e3" === 3000, "+'3e3' !== 3000");
+
+tmp = new Number(1);
+ok(+tmp === 1, "ToNumber(new Number(1)) = " + (+tmp));
+tmp = new String("1");
+ok(+tmp === 1, "ToNumber(new String('1')) = " + (+tmp));
+
+ok("" + 0 === "0", "\"\" + 0 !== \"0\"");
+ok("" + 123 === "123", "\"\" + 123 !== \"123\"");
+ok("" + (-5) === "-5", "\"\" + (-5) !== \"-5\"");
+ok("" + null === "null", "\"\" + null !== \"null\"");
+ok("" + undefined === "undefined", "\"\" + undefined !== \"undefined\"");
+ok("" + true === "true", "\"\" + true !== \"true\"");
+ok("" + false === "false", "\"\" + false !== \"false\"");
+ok("" + 0.5 === "0.5", "'' + 0.5 = " + 0.5);
+ok("" + (-0.5432) === "-0.5432", "'' + (-0.5432) = " + (-0.5432));
+
+ok(1 < 3.4, "1 < 3.4 failed");
+ok(!(3.4 < 1), "3.4 < 1");
+ok("abc" < "abcd", "abc < abcd failed");
+ok("abcd" < "abce", "abce < abce failed");
+ok("" < "x", "\"\" < \"x\" failed");
+ok(!(0 < 0), "0 < 0");
+
+ok(1 <= 3.4, "1 <= 3.4 failed");
+ok(!(3.4 <= 1), "3.4 <= 1");
+ok("abc" <= "abcd", "abc <= abcd failed");
+ok("abcd" <= "abce", "abce <= abce failed");
+ok("" <= "x", "\"\" <= \"x\" failed");
+ok(0 <= 0, "0 <= 0 failed");
+
+ok(3.4 > 1, "3.4 > 1 failed");
+ok(!(1 > 3.4), "1 > 3.4");
+ok("abcd" > "abc", "abc > abcd failed");
+ok("abce" > "abcd", "abce > abce failed");
+ok("x" > "", "\"x\" > \"\" failed");
+ok(!(0 > 0), "0 > 0");
+
+ok(3.4 >= 1, "3.4 >= 1 failed");
+ok(!(1 >= 3.4), "1 >= 3.4");
+ok("abcd" >= "abc", "abc >= abcd failed");
+ok("abce" >= "abcd", "abce >= abce failed");
+ok("x" >= "", "\"x\" >= \"\" failed");
+ok(0 >= 0, "0 >= 0");
+
+tmp = 1;
+ok(++tmp === 2, "++tmp (1) is not 2");
+ok(tmp === 2, "incremented tmp is not 2");
+ok(--tmp === 1, "--tmp (2) is not 1");
+ok(tmp === 1, "decremented tmp is not 1");
+ok(tmp++ === 1, "tmp++ (1) is not 1");
+ok(tmp === 2, "incremented tmp(1) is not 2");
+ok(tmp-- === 2, "tmp-- (2) is not 2");
+ok(tmp === 1, "decremented tmp is not 1");
+
+String.prototype.test = true;
+ok("".test === true, "\"\".test is not true");
+
+Boolean.prototype.test = true;
+ok(true.test === true, "true.test is not true");
+
+Number.prototype.test = true;
+ok((0).test === true, "(0).test is not true");
+ok((0.5).test === true, "(0.5).test is not true");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+}catch(ex) {
+    ok(false, "unexpected catch");
+}
+ok(state === "try", "state = " + state + " expected try");
+
+state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+}finally {
+    ok(state === "try", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+}catch(ex) {
+    ok(false, "unexpected catch");
+}finally {
+    ok(state === "try", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    throw "except";
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === "except", "ex is not \"except\"");
+    state = "catch";
+}
+ok(state === "catch", "state = " + state + " expected catch");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    throw true;
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === true, "ex is not true");
+    state = "catch";
+}finally {
+    ok(state === "catch", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    try { throw true; } finally {}
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === true, "ex is not true");
+    state = "catch";
+}finally {
+    ok(state === "catch", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    try { throw "except"; } catch(ex) { throw true; }
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === true, "ex is not true");
+    state = "catch";
+}finally {
+    ok(state === "catch", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+function throwFunc(x) {
+    throw x;
+}
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    throwFunc(true);
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === true, "ex is not true");
+    state = "catch";
+}finally {
+    ok(state === "catch", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+state = "";
+switch(1) {
+case "1":
+    ok(false, "unexpected case \"1\"");
+case 1:
+    ok(state === "", "case 1: state = " + state);
+    state = "1";
+default:
+    ok(state === "1", "default: state = " + state);
+    state = "default";
+case false:
+    ok(state === "default", "case false: state = " + state);
+    state = "false";
+}
+ok(state === "false", "state = " + state);
+
+state = "";
+switch("") {
+case "1":
+case 1:
+    ok(false, "unexpected case 1");
+default:
+    ok(state === "", "default: state = " + state);
+    state = "default";
+case false:
+    ok(state === "default", "case false: state = " + state);
+    state = "false";
+}
+ok(state === "false", "state = " + state);
+
+state = "";
+switch(1) {
+case "1":
+    ok(false, "unexpected case \"1\"");
+case 1:
+    ok(state === "", "case 1: state = " + state);
+    state = "1";
+default:
+    ok(state === "1", "default: state = " + state);
+    state = "default";
+    break;
+case false:
+    ok(false, "unexpected case false");
+}
+ok(state === "default", "state = " + state);
+
+tmp = eval("1");
+ok(tmp === 1, "eval(\"1\") !== 1");
+eval("{ ok(tmp === 1, 'eval: tmp !== 1'); } tmp = 2;");
+ok(tmp === 2, "tmp !== 2");
+
+ok(eval(false) === false, "eval(false) !== false");
+ok(eval() === undefined, "eval() !== undefined");
+
+tmp = eval("1", "2");
+ok(tmp === 1, "eval(\"1\", \"2\") !== 1");
+
+var state = "";
+try {
+    ok(state === "", "try: state = " + state);
+    state = "try";
+    eval("throwFunc(true);");
+}catch(ex) {
+    ok(state === "try", "catch: state = " + state);
+    ok(ex === true, "ex is not true");
+    state = "catch";
+}finally {
+    ok(state === "catch", "funally: state = " + state);
+    state = "finally";
+}
+ok(state === "finally", "state = " + state + " expected finally");
+
+tmp = [,,1,2,,,true];
+ok(tmp.length === 7, "tmp.length !== 7");
+ok(tmp["0"] === undefined, "tmp[0] is not undefined");
+ok(tmp["3"] === 2, "tmp[3] !== 2");
+ok(tmp["6"] === true, "tmp[6] !== true");
+ok(tmp[2] === 1, "tmp[2] !== 1");
+
+ok([1,].length === 2, "[1,].length !== 2");
+ok([,,].length === 3, "[,,].length !== 3");
+ok([,].length === 2, "[].length != 2");
+ok([].length === 0, "[].length != 0");
+
+tmp = 0;
+while(tmp < 4) {
+    ok(tmp < 4, "tmp >= 4");
+    tmp++;
+}
+ok(tmp === 4, "tmp !== 4");
+
+tmp = 0;
+while(true) {
+    ok(tmp < 4, "tmp >= 4");
+    tmp++;
+    if(tmp === 4) {
+        break;
+        ok(false, "break did not break");
+    }
+}
+ok(tmp === 4, "tmp !== 4");
+
+tmp = 0;
+do {
+    ok(tmp < 4, "tmp >= 4");
+    tmp++;
+} while(tmp < 4);
+ok(tmp === 4, "tmp !== 4");
+
+tmp = 0;
+do {
+    ok(tmp === 0, "tmp !=== 0");
+    tmp++;
+} while(false);
+ok(tmp === 1, "tmp !== 1");
+
+tmp = 0;
+while(tmp < 4) {
+    tmp++;
+    if(tmp === 2) {
+        continue;
+        ok(false, "break did not break");
+    }
+    ok(tmp <= 4 && tmp != 2, "tmp = " + tmp);
+}
+ok(tmp === 4, "tmp !== 4");
+
+for(tmp=0; tmp < 4; tmp++)
+    ok(tmp < 4, "tmp = " + tmp);
+ok(tmp === 4, "tmp !== 4");
+
+for(tmp=0; tmp < 4; tmp++) {
+    if(tmp === 2)
+        break;
+    ok(tmp < 2, "tmp = " + tmp);
+}
+ok(tmp === 2, "tmp !== 2");
+
+for(tmp=0; tmp < 4; tmp++) {
+    if(tmp === 2)
+        continue;
+    ok(tmp < 4 && tmp != 2, "tmp = " + tmp);
+}
+ok(tmp === 4, "tmp !== 4");
+
+for(var fi=0; fi < 4; fi++)
+    ok(fi < 4, "fi = " + fi);
+ok(fi === 4, "fi !== 4");
+
+ok((void 1) === undefined, "(void 1) !== undefined");
+
+var inobj = new Object();
+
+for(var iter in inobj)
+    ok(false, "unexpected iter = " + iter);
+
+inobj.test = true;
+tmp = 0;
+for(iter in inobj) {
+    ok(iter == "test", "unexpected iter = " + iter);
+    tmp++;
+}
+ok(tmp === 1, "for..in tmp = " + tmp);
+
+function forinTestObj() {}
+
+forinTestObj.prototype.test3 = true;
+
+var arr = new Array();
+inobj = new forinTestObj();
+inobj.test1 = true;
+inobj.test2 = true;
+
+tmp = 0;
+for(iter in inobj) {
+    arr[iter] = true;
+    tmp++;
+}
+
+ok(tmp === 3, "for..in tmp = " + tmp);
+ok(arr["test1"] === true, "arr[test1] !== true");
+ok(arr["test2"] === true, "arr[test2] !== true");
+ok(arr["test3"] === true, "arr[test3] !== true");
+
+tmp = new Object();
+tmp.test = false;
+ok((delete tmp.test) === true, "delete returned false");
+ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+for(iter in tmp)
+    ok(false, "tmp has prop " + iter);
+
+tmp.testWith = true;
+with(tmp)
+    ok(testWith === true, "testWith !== true");
+
+if(false) {
+    var varTest1 = true;
+}
+
+ok(varTest1 === undefined, "varTest1 = " + varTest1);
+ok(varTest2 === undefined, "varTest2 = " + varTest1);
+
+var varTest2;
+
+function varTestFunc(varTest3) {
+    var varTest3;
+
+    ok(varTest3 === 3, "varTest3 = " + varTest3);
+    ok(varTest4 === undefined, "varTest4 = " + varTest4);
+
+    var varTest4;
+}
+
+varTestFunc(3);
+
+deleteTest = 1;
+delete deleteTest;
+try {
+    tmp = deleteTest;
+    ok(false, "deleteTest not throwed exception?");
+}catch(ex) {}
+
+if (false)
+    if (true)
+        ok(false, "if evaluated");
+    else
+        ok(false, "else should be associated with nearest if statement");
+
+if (true)
+    if (false)
+        ok(false, "if evaluated");
+    else
+        ok(true, "else should be associated with nearest if statement");
+
+ok(isNaN(NaN) === true, "isNaN(NaN) !== true");
+ok(isNaN(0.5) === false, "isNaN(0.5) !== false");
+ok(isNaN(Infinity) === false, "isNaN(Infinity) !== false");
+ok(isNaN() === true, "isNaN() !== true");
+ok(isNaN(NaN, 0) === true, "isNaN(NaN, 0) !== true");
+ok(isNaN(0.5, NaN) === false, "isNaN(0.5, NaN) !== false");
+ok(isNaN(+undefined) === true, "isNaN(+undefined) !== true");
+
+ok(isFinite(0.5) === true, "isFinite(0.5) !== true");
+ok(isFinite(Infinity) === false, "isFinite(Infinity) !== fals");
+ok(isFinite(-Infinity) === false, "isFinite(Infinity) !== fals");
+ok(isFinite(NaN) === false, "isFinite(NaN) !== false");
+ok(isFinite(0.5, NaN) === true, "isFinite(0.5, NaN) !== true");
+ok(isFinite(NaN, 0.5) === false, "isFinite(NaN, 0.5) !== false");
+ok(isFinite() === false, "isFinite() !== false");
+
+ok((1 < NaN) === false, "(1 < NaN) !== false");
+ok((1 > NaN) === false, "(1 > NaN) !== false");
+ok((1 <= NaN) === false, "(1 <= NaN) !== false");
+ok((1 >= NaN) === false, "(1 >= NaN) !== false");
+ok((NaN < 1) === false, "(NaN < 1) !== false");
+ok((NaN > 1) === false, "(NaN > 1) !== false");
+ok((NaN <= 1) === false, "(NaN <= 1) !== false");
+ok((NaN >= 1) === false, "(NaN >= 1) !== false");
+ok((Infinity < 2) === false, "(Infinity < 2) !== false");
+ok((Infinity > 2) === true, "(Infinity > 2) !== true");
+ok((-Infinity < 2) === true, "(-Infinity < 2) !== true");
+
+ok(isNaN(+"test") === true, "isNaN(+'test') !== true");
+ok(isNaN(+"123t") === true, "isNaN(+'123t') !== true");
+ok(isNaN(+"Infinity x") === true, "isNaN(+'Infinity x') !== true");
+ok(+"Infinity" === Infinity, "+'Infinity' !== Infinity");
+ok(+" Infinity " === Infinity, "+' Infinity ' !== Infinity");
+ok(+"-Infinity" === -Infinity, "+'-Infinity' !== -Infinity");
+
+ok((NaN !== NaN) === true, "(NaN !== NaN) !== true");
+ok((NaN === NaN) === false, "(NaN === NaN) !== false");
+ok((Infinity !== NaN) === true, "(Infinity !== NaN) !== true");
+ok((Infinity !== NaN) === true, "(Infinity !== NaN) !== true");
+ok((0 === NaN) === false, "(0 === NaN) !== false");
+
+ok((NaN != NaN) === true, "(NaN !== NaN) != true");
+ok((NaN == NaN) === false, "(NaN === NaN) != false");
+ok((Infinity != NaN) === true, "(Infinity != NaN) !== true");
+ok((Infinity != NaN) === true, "(Infinity != NaN) !== true");
+ok((0 == NaN) === false, "(0 === NaN) != false");
+
+
+ok(typeof(testFunc2) === "function", "typeof(testFunc2) = " + typeof(testFunc2));
+tmp = testFunc2(1);
+ok(tmp === 2, "testFunc2(1) = " + tmp);
+function testFunc2(x) { return x+1; }
+
+ok(typeof(testFunc3) === "function", "typeof(testFunc3) = " + typeof(testFunc3));
+tmp = testFunc3(1);
+ok(tmp === 3, "testFunc3(1) = " + tmp);
+tmp = function testFunc3(x) { return x+2; };
+
+tmp = testFunc4(1);
+ok(tmp === 5, "testFunc4(1) = " + tmp);
+tmp = function testFunc4(x) { return x+3; };
+tmp = testFunc4(1);
+testFunc4 = 1;
+ok(testFunc4 === 1, "testFunc4 = " + testFunc4);
+ok(tmp === 5, "testFunc4(1) = " + tmp);
+tmp = function testFunc4(x) { return x+4; };
+ok(testFunc4 === 1, "testFunc4 = " + testFunc4);
+
+function testEmbededFunctions() {
+    ok(typeof(testFunc5) === "function", "typeof(testFunc5) = " + typeof(testFunc5));
+    tmp = testFunc5(1);
+    ok(tmp === 3, "testFunc5(1) = " + tmp);
+    tmp = function testFunc5(x) { return x+2; };
+
+    tmp = testFunc6(1);
+    ok(tmp === 5, "testFunc6(1) = " + tmp);
+    tmp = function testFunc6(x) { return x+3; };
+    tmp = testFunc6(1);
+    ok(tmp === 5, "testFunc6(1) = " + tmp);
+    tmp = function testFunc6(x) { return x+4; };
+    testFunc6 = 1;
+    ok(testFunc6 === 1, "testFunc4 = " + testFunc6);
+}
+
+testEmbededFunctions();
+
+reportSuccess();
diff --git a/rostests/winetests/jscript/regexp.js b/rostests/winetests/jscript/regexp.js
new file mode 100644 (file)
index 0000000..6809101
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+var m;
+
+m = "abcabc".match(/ca/);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 1, "m.length is not 1");
+ok(m["0"] === "ca", "m[0] is not \"ca\"");
+
+m = "abcabc".match(/ab/);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 1, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+
+m = "abcabc".match(/ab/g);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+m = "abcabc".match(/Ab/g);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m === null, "m is not null");
+
+m = "abcabc".match(/Ab/gi);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+m = "aaabcabc".match(/a+b/g);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 2");
+ok(m["0"] === "aaab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+m = "aaa\\\\cabc".match(/\\/g);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 2");
+ok(m["0"] === "\\", "m[0] is not \"\\\"");
+ok(m["1"] === "\\", "m[1] is not \"\\\"");
+
+m = "abcabc".match(new RegExp("ab"));
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 1, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+
+m = "abcabc".match(new RegExp("ab","g"));
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+m = "abcabc".match(new RegExp(/ab/g));
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+m = "abcabc".match(new RegExp("ab","g", "test"));
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length is not 1");
+ok(m["0"] === "ab", "m[0] is not \"ab\"");
+ok(m["1"] === "ab", "m[1] is not \"ab\"");
+
+r = "- [test] -".replace(/\[([^\[]+)\]/g, "success");
+ok(r === "- success -", "r = " + r + " expected '- success -'");
+
+r = "[test] [test]".replace(/\[([^\[]+)\]/g, "aa");
+ok(r === "aa aa", "r = " + r + "aa aa");
+
+r = "[test] [test]".replace(/\[([^\[]+)\]/, "aa");
+ok(r === "aa [test]", "r = " + r + " expected 'aa [test]'");
+
+r = "- [test] -".replace(/\[([^\[]+)\]/g);
+ok(r === "- undefined -", "r = " + r + " expected '- undefined -'");
+
+r = "- [test] -".replace(/\[([^\[]+)\]/g, true);
+ok(r === "- true -", "r = " + r + " expected '- true -'");
+
+r = "- [test] -".replace(/\[([^\[]+)\]/g, true, "test");
+ok(r === "- true -", "r = " + r + " expected '- true -'");
+
+var tmp = 0;
+
+function replaceFunc1(m, off, str) {
+    ok(arguments.length === 3, "arguments.length = " + arguments.length);
+
+    switch(tmp) {
+    case 0:
+        ok(m === "[test1]", "m = " + m + " expected [test1]");
+        ok(off === 0, "off = " + off + " expected 0");
+        break;
+    case 1:
+        ok(m === "[test2]", "m = " + m + " expected [test2]");
+        ok(off === 8, "off = " + off + " expected 8");
+        break;
+    default:
+        ok(false, "unexpected call");
+    }
+
+    ok(str === "[test1] [test2]", "str = " + arguments[3]);
+    return "r" + tmp++;
+}
+
+r = "[test1] [test2]".replace(/\[[^\[]+\]/g, replaceFunc1);
+ok(r === "r0 r1", "r = " + r + " expected 'r0 r1'");
+
+tmp = 0;
+
+function replaceFunc2(m, subm, off, str) {
+    ok(arguments.length === 4, "arguments.length = " + arguments.length);
+
+    switch(tmp) {
+    case 0:
+        ok(subm === "test1", "subm = " + subm);
+        ok(m === "[test1]", "m = " + m + " expected [test1]");
+        ok(off === 0, "off = " + off + " expected 0");
+        break;
+    case 1:
+        ok(subm === "test2", "subm = " + subm);
+        ok(m === "[test2]", "m = " + m + " expected [test2]");
+        ok(off === 8, "off = " + off + " expected 8");
+        break;
+    default:
+        ok(false, "unexpected call");
+    }
+
+    ok(str === "[test1] [test2]", "str = " + arguments[3]);
+    return "r" + tmp++;
+}
+
+r = "[test1] [test2]".replace(/\[([^\[]+)\]/g, replaceFunc2);
+ok(r === "r0 r1", "r = '" + r + "' expected 'r0 r1'");
+
+r = "1,,2,3".split(/,+/g);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "1,,2,3".split(/,+/);
+ok(r.length === 3, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+ok(r[2] === "3", "r[2] = " + r[2]);
+
+r = "1,,2,".split(/,+/);
+ok(r.length === 2, "r.length = " + r.length);
+ok(r[0] === "1", "r[0] = " + r[0]);
+ok(r[1] === "2", "r[1] = " + r[1]);
+
+reportSuccess();
diff --git a/rostests/winetests/jscript/rsrc.rc b/rostests/winetests/jscript/rsrc.rc
new file mode 100644 (file)
index 0000000..ecb4212
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* @makedep: api.js */
+api.js 40 "api.js"
+
+/* @makedep: lang.js */
+lang.js 40 "lang.js"
+
+/* @makedep: regexp.js */
+regexp.js 40 "regexp.js"
diff --git a/rostests/winetests/jscript/run.c b/rostests/winetests/jscript/run.c
new file mode 100644 (file)
index 0000000..81de579
--- /dev/null
@@ -0,0 +1,786 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <ole2.h>
+#include <dispex.h>
+#include <activscp.h>
+
+#include "wine/test.h"
+
+static const CLSID CLSID_JScript =
+    {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
+
+#define DEFINE_EXPECT(func) \
+    static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
+
+#define SET_EXPECT(func) \
+    expect_ ## func = TRUE
+
+#define SET_CALLED(func) \
+    called_ ## func = TRUE
+
+#define CHECK_EXPECT2(func) \
+    do { \
+        ok(expect_ ##func, "unexpected call " #func "\n"); \
+        called_ ## func = TRUE; \
+    }while(0)
+
+#define CHECK_EXPECT(func) \
+    do { \
+        CHECK_EXPECT2(func); \
+        expect_ ## func = FALSE; \
+    }while(0)
+
+#define CHECK_CALLED(func) \
+    do { \
+        ok(called_ ## func, "expected " #func "\n"); \
+        expect_ ## func = called_ ## func = FALSE; \
+    }while(0)
+
+DEFINE_EXPECT(global_propget_d);
+DEFINE_EXPECT(global_propget_i);
+DEFINE_EXPECT(global_propput_d);
+DEFINE_EXPECT(global_propput_i);
+DEFINE_EXPECT(global_success_d);
+DEFINE_EXPECT(global_success_i);
+DEFINE_EXPECT(testobj_delete);
+DEFINE_EXPECT(GetItemInfo_testVal);
+
+#define DISPID_GLOBAL_TESTPROPGET   0x1000
+#define DISPID_GLOBAL_TESTPROPPUT   0x1001
+#define DISPID_GLOBAL_REPORTSUCCESS 0x1002
+#define DISPID_GLOBAL_TRACE         0x1003
+#define DISPID_GLOBAL_OK            0x1004
+#define DISPID_GLOBAL_GETVT         0x1005
+#define DISPID_GLOBAL_TESTOBJ       0x1006
+
+static const WCHAR testW[] = {'t','e','s','t',0};
+static const CHAR testA[] = "test";
+static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
+static const CHAR test_valA[] = "testVal";
+
+static BOOL strict_dispid_check;
+static const char *test_name = "(null)";
+
+static const char *debugstr_w(LPCWSTR str)
+{
+    static char buf[1024];
+
+    if(!str)
+        return "(null)";
+
+    WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
+    return buf;
+}
+
+static BSTR a2bstr(const char *str)
+{
+    BSTR ret;
+    int len;
+
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    ret = SysAllocStringLen(NULL, len-1);
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+    return ret;
+}
+
+static int strcmp_wa(LPCWSTR strw, const char *stra)
+{
+    CHAR buf[512];
+    WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
+    return lstrcmpA(buf, stra);
+}
+
+static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
+{
+    *ppv = NULL;
+
+    if(IsEqualGUID(riid, &IID_IUnknown)
+       || IsEqualGUID(riid, &IID_IDispatch)
+       || IsEqualGUID(riid, &IID_IDispatchEx))
+        *ppv = iface;
+    else
+        return E_NOINTERFACE;
+
+    return S_OK;
+}
+
+static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
+                                              LCID lcid, ITypeInfo **ppTInfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
+                                                LPOLESTR *rgszNames, UINT cNames,
+                                                LCID lcid, DISPID *rgDispId)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
+                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
+{
+    ok(0, "unexpected call %s %x\n", debugstr_w(bstrName), grfdex);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
+{
+    CHECK_EXPECT(testobj_delete);
+
+    ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", debugstr_w(bstrName));
+    ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+    return S_OK;
+}
+
+static IDispatchExVtbl testObjVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    DispatchEx_GetDispID,
+    DispatchEx_InvokeEx,
+    testObj_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx testObj = { &testObjVtbl };
+
+static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    if(!strcmp_wa(bstrName, "ok")) {
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_OK;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "trace")) {
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_TRACE;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "reportSuccess")) {
+        CHECK_EXPECT(global_success_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_REPORTSUCCESS;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "testPropGet")) {
+        CHECK_EXPECT(global_propget_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_TESTPROPGET;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "testPropPut")) {
+        CHECK_EXPECT(global_propput_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_TESTPROPPUT;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "getVT")) {
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_GETVT;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "testObj")) {
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_GLOBAL_TESTOBJ;
+        return S_OK;
+    }
+
+    if(strict_dispid_check)
+        ok(0, "unexpected call %s\n", debugstr_w(bstrName));
+    return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    switch(id) {
+    case DISPID_GLOBAL_OK:
+        ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        if(wFlags & INVOKE_PROPERTYGET)
+            ok(pvarRes != NULL, "pvarRes == NULL\n");
+        else
+            ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, debugstr_w(V_BSTR(pdp->rgvarg)));
+
+        return S_OK;
+
+     case DISPID_GLOBAL_TRACE:
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+        if(V_VT(pdp->rgvarg) == VT_BSTR)
+            trace("%s: %s\n", test_name, debugstr_w(V_BSTR(pdp->rgvarg)));
+
+        return S_OK;
+
+    case DISPID_GLOBAL_REPORTSUCCESS:
+        CHECK_EXPECT(global_success_i);
+
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        return S_OK;
+
+     case DISPID_GLOBAL_TESTPROPGET:
+        CHECK_EXPECT(global_propget_i);
+
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_I4;
+        V_I4(pvarRes) = 1;
+
+        return S_OK;
+
+    case DISPID_GLOBAL_TESTPROPPUT:
+        CHECK_EXPECT(global_propput_i);
+
+        ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+        ok(!pvarRes, "pvarRes != NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
+        ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
+        return S_OK;
+
+     case DISPID_GLOBAL_GETVT:
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_BSTR;
+        switch(V_VT(pdp->rgvarg)) {
+        case VT_EMPTY:
+            V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
+            break;
+        case VT_NULL:
+            V_BSTR(pvarRes) = a2bstr("VT_NULL");
+            break;
+        case VT_I4:
+            V_BSTR(pvarRes) = a2bstr("VT_I4");
+            break;
+        case VT_R8:
+            V_BSTR(pvarRes) = a2bstr("VT_R8");
+            break;
+        case VT_BSTR:
+            V_BSTR(pvarRes) = a2bstr("VT_BSTR");
+            break;
+        case VT_DISPATCH:
+            V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
+            break;
+        case VT_BOOL:
+            V_BSTR(pvarRes) = a2bstr("VT_BOOL");
+            break;
+        default:
+            ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
+            return E_FAIL;
+        }
+
+        return S_OK;
+
+    case DISPID_GLOBAL_TESTOBJ:
+        ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
+        ok(pei != NULL, "pei == NULL\n");
+
+        V_VT(pvarRes) = VT_DISPATCH;
+        V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
+        return S_OK;
+    }
+
+    ok(0, "unexpected call %x\n", id);
+    return DISP_E_MEMBERNOTFOUND;
+}
+
+static IDispatchExVtbl GlobalVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    Global_GetDispID,
+    Global_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx Global = { &GlobalVtbl };
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid))
+        *ppv = iface;
+    else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
+        *ppv = iface;
+    else
+        return E_NOINTERFACE;
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
+{
+    *plcid = GetUserDefaultLCID();
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
+        DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
+{
+    ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
+    ok(!ppti, "ppti != NULL\n");
+
+    if(!strcmp_wa(pstrName, test_valA))
+        CHECK_EXPECT(GetItemInfo_testVal);
+    else if(strcmp_wa(pstrName, testA))
+        ok(0, "unexpected pstrName %s\n", debugstr_w(pstrName));
+
+    *ppiunkItem = (IUnknown*)&Global;
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
+        const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+#undef ACTSCPSITE_THIS
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+    ActiveScriptSite_QueryInterface,
+    ActiveScriptSite_AddRef,
+    ActiveScriptSite_Release,
+    ActiveScriptSite_GetLCID,
+    ActiveScriptSite_GetItemInfo,
+    ActiveScriptSite_GetDocVersionString,
+    ActiveScriptSite_OnScriptTerminate,
+    ActiveScriptSite_OnStateChange,
+    ActiveScriptSite_OnScriptError,
+    ActiveScriptSite_OnEnterScript,
+    ActiveScriptSite_OnLeaveScript
+};
+
+static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
+
+static IActiveScript *create_script(void)
+{
+    IActiveScript *script;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IActiveScript, (void**)&script);
+    ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+
+    return script;
+}
+
+static void parse_script(BSTR script_str)
+{
+    IActiveScriptParse *parser;
+    IActiveScript *engine;
+    HRESULT hres;
+
+    engine = create_script();
+    if(!engine)
+        return;
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    hres = IActiveScript_AddNamedItem(engine, testW,
+            SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+    IActiveScript_Release(engine);
+    IActiveScriptParse_Release(parser);
+}
+
+static void parse_script_a(const char *src)
+{
+    BSTR tmp = a2bstr(src);
+    parse_script(tmp);
+    SysFreeString(tmp);
+}
+
+static BSTR get_script_from_file(const char *filename)
+{
+    DWORD size, len;
+    HANDLE file, map;
+    const char *file_map;
+    BSTR ret;
+
+    file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+    if(file == INVALID_HANDLE_VALUE) {
+        trace("Could not open file: %u\n", GetLastError());
+        return NULL;
+    }
+
+    size = GetFileSize(file, NULL);
+
+    map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+    CloseHandle(file);
+    if(map == INVALID_HANDLE_VALUE) {
+        trace("Could not create file mapping: %u\n", GetLastError());
+        return NULL;
+    }
+
+    file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
+    CloseHandle(map);
+    if(!file_map) {
+        trace("MapViewOfFile failed: %u\n", GetLastError());
+        return NULL;
+    }
+
+    len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
+    ret = SysAllocStringLen(NULL, len);
+    MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
+
+    UnmapViewOfFile(file_map);
+
+    return ret;
+}
+
+static void run_from_file(const char *filename)
+{
+    BSTR script_str = get_script_from_file(filename);
+
+    strict_dispid_check = FALSE;
+
+    if(script_str)
+        parse_script(script_str);
+
+    SysFreeString(script_str);
+}
+
+static void run_from_res(const char *name)
+{
+    const char *data;
+    DWORD size, len;
+    BSTR str;
+    HRSRC src;
+
+    strict_dispid_check = FALSE;
+    test_name = name;
+
+    src = FindResourceA(NULL, name, (LPCSTR)40);
+    ok(src != NULL, "Could not find resource %s\n", name);
+
+    size = SizeofResource(NULL, src);
+    data = LoadResource(NULL, src);
+
+    len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
+    str = SysAllocStringLen(NULL, len);
+    len = MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    parse_script(str);
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    SysFreeString(str);
+}
+
+static void test_isvisible(BOOL global_members)
+{
+    IActiveScriptParse *parser;
+    IActiveScript *engine;
+    HRESULT hres;
+
+    static const WCHAR script_textW[] =
+        {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
+
+    engine = create_script();
+    if(!engine)
+        return;
+
+    hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+    ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+    hres = IActiveScriptParse_InitNew(parser);
+    ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+    hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+    ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+    if(global_members)
+        SET_EXPECT(GetItemInfo_testVal);
+    hres = IActiveScript_AddNamedItem(engine, test_valW,
+            SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
+            (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+    if(global_members)
+        CHECK_CALLED(GetItemInfo_testVal);
+
+    hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+    ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+    if(!global_members)
+        SET_EXPECT(GetItemInfo_testVal);
+    hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    if(!global_members)
+        CHECK_CALLED(GetItemInfo_testVal);
+
+    hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+    IActiveScript_Release(engine);
+    IActiveScriptParse_Release(parser);
+}
+
+static void run_tests(void)
+{
+    strict_dispid_check = TRUE;
+
+    parse_script_a("");
+    parse_script_a("/* empty */ ;");
+
+    SET_EXPECT(global_propget_d);
+    SET_EXPECT(global_propget_i);
+    parse_script_a("testPropGet;");
+    CHECK_CALLED(global_propget_d);
+    CHECK_CALLED(global_propget_i);
+
+    SET_EXPECT(global_propput_d);
+    SET_EXPECT(global_propput_i);
+    parse_script_a("testPropPut = 1;");
+    CHECK_CALLED(global_propput_d);
+    CHECK_CALLED(global_propput_i);
+
+    SET_EXPECT(global_success_d);
+    SET_EXPECT(global_success_i);
+    parse_script_a("reportSuccess();");
+    CHECK_CALLED(global_success_d);
+    CHECK_CALLED(global_success_i);
+
+    SET_EXPECT(testobj_delete);
+    parse_script_a("delete testObj.deleteTest;");
+    CHECK_CALLED(testobj_delete);
+
+    parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
+
+    run_from_res("lang.js");
+    run_from_res("api.js");
+    run_from_res("regexp.js");
+
+    test_isvisible(FALSE);
+    test_isvisible(TRUE);
+}
+
+START_TEST(run)
+{
+    int argc;
+    char **argv;
+
+    argc = winetest_get_mainargs(&argv);
+
+    CoInitialize(NULL);
+
+    if(argc > 2)
+        run_from_file(argv[2]);
+    else
+        run_tests();
+
+    CoUninitialize();
+}
diff --git a/rostests/winetests/jscript/testlist.c b/rostests/winetests/jscript/testlist.c
new file mode 100644 (file)
index 0000000..fd13233
--- /dev/null
@@ -0,0 +1,17 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define STANDALONE
+#include "wine/test.h"
+
+extern void func_jscript(void);
+extern void func_run(void);
+
+const struct test winetest_testlist[] =
+{
+    { "jscript", func_jscript },
+    { "run", func_run },
+    { 0, 0 }
+};