https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7d76303d2d96afbb3a1b65...
commit 7d76303d2d96afbb3a1b6587a03127b034c8bfeb Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Sun Dec 1 19:43:01 2019 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Sun Dec 1 19:43:01 2019 +0100
[VBSCRIPT_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/vbscript/api.vbs | 184 +++++++ modules/rostests/winetests/vbscript/lang.vbs | 134 +++++ modules/rostests/winetests/vbscript/run.c | 706 +++++++++++++++++++++++-- modules/rostests/winetests/vbscript/vbscript.c | 206 +++++++- 4 files changed, 1189 insertions(+), 41 deletions(-)
diff --git a/modules/rostests/winetests/vbscript/api.vbs b/modules/rostests/winetests/vbscript/api.vbs index 8ebbfb6c5c8..49dd4959f77 100644 --- a/modules/rostests/winetests/vbscript/api.vbs +++ b/modules/rostests/winetests/vbscript/api.vbs @@ -129,6 +129,16 @@ TestCStr 3, "3" if isEnglishLang then TestCStr 3.5, "3.5" if isEnglishLang then TestCStr true, "True"
+sub testCStrError() + on error resume next + Error.clear() + CStr(null) + call ok(Err.number = 94, "Err.number = " & Err.number) + if isEnglishLang then call ok(Err.source = "Microsoft VBScript runtime error", "Err.source = " & Err.source) + if isEnglishLang then call ok(Err.description = "Invalid use of Null", "Err.description = " & Err.description) +end sub +call testCStrError() + Call ok(getVT(Chr(120)) = "VT_BSTR", "getVT(Chr(120)) = " & getVT(Chr(120))) Call ok(getVT(Chr(255)) = "VT_BSTR", "getVT(Chr(255)) = " & getVT(Chr(255))) Call ok(Chr(120) = "x", "Chr(120) = " & Chr(120)) @@ -144,6 +154,7 @@ sub testChrError call Err.clear() call Chr(-1) call ok(Err.number = 5, "Err.number = " & Err.number) + if isEnglishLang then call ok(Err.description = "Invalid procedure call or argument", "Err.description = " & Err.description)
call Err.clear() call Chr(256) @@ -237,6 +248,19 @@ Call ok(UBound(arr2) = 2, "UBound(x) = " & UBound(x)) Call ok(UBound(arr2, 1) = 2, "UBound(x) = " & UBound(x)) Call ok(UBound(arr2, 2) = 4, "UBound(x) = " & UBound(x))
+sub testUBoundError() + on error resume next + call Err.clear() + call UBound() + call ok(Err.number = 450, "Err.number = " & Err.number) + call Err.clear() + call UBound(arr, 1, 2) + call ok(Err.number = 450, "Err.number = " & Err.number) + if isEnglishLang then call ok(Err.description = "Wrong number of arguments or invalid property assignment", _ + "Err.description = " & Err.description) +end sub +call testUBoundError() + Dim newObject Set newObject = New ValClass newObject.myval = 1 @@ -494,6 +518,17 @@ TestStrComp "ABC", Empty, 1, 1 TestStrComp vbNull, vbNull, 1, 0 TestStrComp "", vbNull, 1, -1
+sub testStrCompError() + on error resume next + call Err.clear() + call StrComp() + call ok(Err.number = 450, "Err.number = " & Err.number) + call Err.clear() + call StrComp("a", "a", 0, 1) + call ok(Err.number = 450, "Err.number = " & Err.number) +end sub +call testStrCompError() + Call ok(Len("abc") = 3, "Len(abc) = " & Len("abc")) Call ok(Len("") = 0, "Len() = " & Len("")) Call ok(Len(1) = 1, "Len(1) = " & Len(1)) @@ -1066,6 +1101,9 @@ Call ok(VarType(Null) = vbNull, "VarType(Null) = " & VarType(Null)) Call ok(getVT(VarType(Null)) = "VT_I2", "getVT(VarType(Null)) = " & getVT(VarType(Null))) Call ok(VarType(255) = vbInteger, "VarType(255) = " & VarType(255)) Call ok(getVT(VarType(255)) = "VT_I2", "getVT(VarType(255)) = " & getVT(VarType(255))) +set x = new EmptyClass +Call ok(VarType(x) = vbObject, "VarType(x) = " & VarType(x)) +Call ok(getVT(VarType(x)) = "VT_I2", "getVT(VarType(x)) = " & getVT(VarType(x))) Call ok(VarType(32768) = vbLong, "VarType(32768) = " & VarType(32768)) Call ok(getVT(VarType(32768)) = "VT_I2", "getVT(VarType(32768)) = " & getVT(VarType(32768))) Call ok(VarType(CSng(0.5)) = vbSingle, "VarType(CSng(0.5)) = " & VarType(CSng(0.5))) @@ -1080,6 +1118,8 @@ Call ok(VarType(CBool(0.5)) = vbBoolean, "VarType(CBool(0.5)) = " & VarType(CBoo Call ok(getVT(VarType(CBool(0.5))) = "VT_I2", "getVT(VarType(CBool(0.5))) = " & getVT(VarType(CBool(0.5)))) Call ok(VarType(CByte(255)) = vbByte, "VarType(CByte(255)) = " & VarType(CByte(255))) Call ok(getVT(VarType(CByte(255))) = "VT_I2", "getVT(VarType(CByte(255))) = " & getVT(VarType(CByte(255)))) +Call ok(VarType(arr) = (vbArray or vbVariant), "VarType(arr) = " & VarType(arr)) +Call ok(getVT(VarType(arr)) = "VT_I2", "getVT(VarType(arr)) = " & getVT(VarType(arr)))
Call ok(Sgn(Empty) = 0, "Sgn(MyEmpty) = " & Sgn(Empty)) Call ok(getVT(Sgn(Empty)) = "VT_I2", "getVT(Sgn(MyEmpty)) = " & getVT(Sgn(Empty))) @@ -1407,6 +1447,21 @@ Call ok(getVT(Log(CByte(2))) = "VT_R8", "getVT(Log(CByte(2))) = " & getVT(Log(CB Call ok(getVT(Date) = "VT_DATE", "getVT(Date) = " & getVT(Date)) Call ok(getVT(Time) = "VT_DATE", "getVT(Time) = " & getVT(Time))
+Call ok(getVT(Day(now)) = "VT_I2", "getVT(Day(now)) = " & getVT(Day(now))) +Call ok(Day(2) = 1, "Day(2) = " & Day(2)) +Call ok(getVT(Month(now)) = "VT_I2", "getVT(Month(now)) = " & getVT(Month(now))) +Call ok(Month(2) = 1, "Month(2) = " & Month(2)) +Call ok(getVT(Year(now)) = "VT_I2", "getVT(Year(now)) = " & getVT(Year(now))) +Call ok(Year(2) = 1900, "Year(2) = " & Year(2)) +Call ok(getVT(Hour(now)) = "VT_I2", "getVT(Hour(now)) = " & getVT(Hour(now))) +Call ok(Hour(2) = 0, "Hour(2) = " & Hour(2)) +Call ok(Hour(2.75) = 18, "Hour(2) = " & Hour(2.75)) +Call ok(getVT(Minute(now)) = "VT_I2", "getVT(Minute(now)) = " & getVT(Minute(now))) +Call ok(Minute(2) = 0, "Minute(2) = " & Minute(2)) +Call ok(Minute(2.02083) = 30, "Minute(2.02083) = " & Minute(2.02083)) +Call ok(getVT(Second(now)) = "VT_I2", "getVT(Second(now)) = " & getVT(Second(now))) +Call ok(Second(2) = 0, "Second(2) = " & Second(2)) + Sub testRGBError(arg1, arg2, arg3, error_num) on error resume next Dim x @@ -1431,4 +1486,133 @@ Call testRGBError(&h4d&, -2, &h2f&, 5)
Call ok(getVT(Timer) = "VT_R4", "getVT(Timer) = " & getVT(Timer))
+sub testAsc(arg, expected) + dim x + x = Asc(arg) + call ok(x = expected, "x = " & x & " expected " & expected) + call ok(getVT(x) = "VT_I2*", "getVT = " & getVT(x)) +end sub + +sub testAscError() + on error resume next + call Err.clear() + call Asc(null) + Call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Asc(empty) + Call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Asc() + Call ok(Err.number = 450, "Err.number = " & Err.number) + call Err.clear() + call Asc(Chr(260)) ' some versions of vista allow it + Call ok(Err.number = 5 or Err.number = 0, "asc4 Err.number = " & Err.number) + call Err.clear() + call Asc("") + Call ok(Err.number = 5, "Err.number = " & Err.number) +end sub + +call testAsc("T", 84) +call testAsc("test", 116) +call testAsc("3", 51) +call testAsc(3, 51) +call testAsc(" ", 32) +call testAsc(Chr(255), 255) +call testAsc(Chr(0), 0) +if isEnglishLang then testAsc true, 84 +call testAscError() + +sub testErrNumber(n) + call ok(err.number = n, "err.number = " & err.number & " expected " & n) +end sub + +sub testErrRaise() + on error resume next + call ok(err.number = 0, "err.number = " & err.number) + err.raise 1 + call ok(err.number = 1, "err.number = " & err.number) + err.raise + call ok(err.number = 450, "err.number = " & err.number) + call testErrNumber(450) + err.raise &h10000& + call ok(err.number = 5, "err.number = " & err.number) + + err.clear + call ok(getVT(err.source) = "VT_BSTR", "err.source = " & err.source) + call ok(getVT(err.description) = "VT_BSTR", "err.description = " & err.description) + call ok(getVT(err.helpfile) = "VT_BSTR", "err.helpfile = " & err.helpfile) + call ok(getVT(err.helpcontext) = "VT_I4", "err.helpcontext = " & err.helpcontext) + call ok(err.source = "", "err.source = " & err.source) + call ok(err.description = "", "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + call ok(err.helpcontext = 0, "err.helpcontext = " & err.helpcontext) + + err.raise 1, "abc" + call ok(err.number = 1, "err.number = " & err.number) + call ok(err.source = "abc", "err.source = " & err.source) + if isEnglishLang then call ok(err.description = "Unknown runtime error", "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + + err.raise 1, 2, "desc", "hf", 1 + call ok(err.number = 1, "err.number = " & err.number) + call ok(getVT(err.source) = "VT_BSTR", "err.source = " & err.source) + call ok(err.source = "2", "err.source = " & err.source) + call ok(err.description = "desc", "err.description = " & err.description) + call ok(err.helpfile = "hf", "err.helpfile = " & err.helpfile) + call ok(getVT(err.helpcontext) = "VT_I4", "err.helpcontext = " & err.helpcontext) + call ok(err.helpcontext = 1, "err.helpcontext = " & err.helpcontext) + + err.raise 5 + call ok(err.number = 5, "err.number = " & err.number) + call ok(err.source = "2", "err.source = " & err.source) + call ok(err.description = "desc", "err.description = " & err.description) + call ok(err.helpfile = "hf", "err.helpfile = " & err.helpfile) + call ok(getVT(err.helpcontext) = "VT_I4", "err.helpcontext = " & err.helpcontext) + call ok(err.helpcontext = 1, "err.helpcontext = " & err.helpcontext) + + err.clear + err.raise &h8007000E& + call ok(err.number = 7, "err.number = " & err.number) + if isEnglishLang then call ok(err.source = "Microsoft VBScript runtime error", "err.source = " & err.source) + if isEnglishLang then call ok(err.description = "Out of memory", "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + call ok(err.helpcontext = 0, "err.helpcontext = " & err.helpcontext) + + err.clear + err.raise 1, "test" + err.raise &h8007000E& + call ok(err.number = 7, "err.number = " & err.number) + call ok(err.source = "test", "err.source = " & err.source) + if isEnglishLang then call ok(err.description = "Unknown runtime error", "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + call ok(err.helpcontext = 0, "err.helpcontext = " & err.helpcontext) + + err.raise 1, 2, "desc", "hf", 1 + err.unknownIdent + call ok(err.number = 438, "err.number = " & err.number) + if isEnglishLang then call ok(err.source = "Microsoft VBScript runtime error", "err.source = " & err.source) + if isEnglishLang then call ok(err.description = "Object doesn't support this property or method", _ + "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + call ok(err.helpcontext = 0, "err.helpcontext = " & err.helpcontext) + + e = err + call ok(getVT(e) = "VT_I4*", "getVT(e) = " & getVT(e)) + call ok(e = 438, "e = " & e) + + err.raise 1, 2, "desc", "hf", 1 + on error goto 0 + call ok(err.number = 0, "err.number = " & err.number) + call ok(err.source = "", "err.source = " & err.source) + call ok(err.description = "", "err.description = " & err.description) + call ok(err.helpfile = "", "err.helpfile = " & err.helpfile) + call ok(err.helpcontext = 0, "err.helpcontext = " & err.helpcontext) + + dim e + e = err + call ok(getVT(e) = "VT_I4*", "getVT(e) = " & getVT(e)) + call ok(e = 0, "e = " & e) +end sub +call testErrRaise() + Call reportSuccess() diff --git a/modules/rostests/winetests/vbscript/lang.vbs b/modules/rostests/winetests/vbscript/lang.vbs index 2af77bdfcc4..6ddb2e79f51 100644 --- a/modules/rostests/winetests/vbscript/lang.vbs +++ b/modules/rostests/winetests/vbscript/lang.vbs @@ -41,6 +41,7 @@ Call ok(10. = 10, "10. <> 10") Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1") Call ok(&hffFFffFF& = -1, "&hffFFffFF& <> -1") Call ok(34e5 = 3400000, "34e5 <> 3400000") +Call ok(34e+5 = 3400000, "34e+5 <> 3400000") Call ok(56.789e5 = 5678900, "56.789e5 = 5678900") Call ok(56.789e-2 = 0.56789, "56.789e-2 <> 0.56789") Call ok(1e-94938484 = 0, "1e-... <> 0") @@ -1093,6 +1094,14 @@ Call ok(getVT(cs) = "VT_BSTR", "getVT(cs) = " & getVT(cs)) Call ok(isNull(cnull), "cnull = " & cnull) Call ok(getVT(cnull) = "VT_NULL", "getVT(cnull) = " & getVT(cnull))
+Call ok(+1 = 1, "+1 != 1") +Call ok(+true = true, "+1 != 1") +Call ok(getVT(+true) = "VT_BOOL", "getVT(+true) = " & getVT(+true)) +Call ok(+"true" = "true", """+true"" != true") +Call ok(getVT(+"true") = "VT_BSTR", "getVT(+""true"") = " & getVT(+"true")) +Call ok(+obj is obj, "+obj != obj") +Call ok(+--+-+1 = -1, "+--+-+1 != -1") + if false then Const conststr = "str" Call ok(conststr = "str", "conststr = " & conststr) Call ok(getVT(conststr) = "VT_BSTR", "getVT(conststr) = " & getVT(conststr)) @@ -1345,4 +1354,129 @@ end class set x = new RegExp Call ok(x.Global = false, "x.Global = " & x.Global)
+sub test_nothing_errors + dim x + on error resume next + + x = 1 + err.clear + x = nothing + call ok(err.number = 91, "err.number = " & err.number) + call ok(x = 1, "x = " & x) + + err.clear + x = not nothing + call ok(err.number = 91, "err.number = " & err.number) + call ok(x = 1, "x = " & x) + + err.clear + x = "" & nothing + call ok(err.number = 91, "err.number = " & err.number) + call ok(x = 1, "x = " & x) +end sub +call test_nothing_errors() + +sub test_identifiers + ' test keywords that can also be a declared identifier + Dim default + default = "xx" + Call ok(default = "xx", "default = " & default & " expected ""xx""") + + Dim error + error = "xx" + Call ok(error = "xx", "error = " & error & " expected ""xx""") + + Dim explicit + explicit = "xx" + Call ok(explicit = "xx", "explicit = " & explicit & " expected ""xx""") + + Dim step + step = "xx" + Call ok(step = "xx", "step = " & step & " expected ""xx""") +end sub +call test_identifiers() + +sub test_dotIdentifiers + ' test keywords that can also be an identifier after a dot + ' Call ok(testObj.rem = 10, "testObj.rem = " & testObj.rem & " expected 10") + Call ok(testObj.true = 10, "testObj.true = " & testObj.true & " expected 10") + Call ok(testObj.false = 10, "testObj.false = " & testObj.false & " expected 10") + Call ok(testObj.not = 10, "testObj.not = " & testObj.not & " expected 10") + Call ok(testObj.and = 10, "testObj.and = " & testObj.and & " expected 10") + Call ok(testObj.or = 10, "testObj.or = " & testObj.or & " expected 10") + Call ok(testObj.xor = 10, "testObj.xor = " & testObj.xor & " expected 10") + Call ok(testObj.eqv = 10, "testObj.eqv = " & testObj.eqv & " expected 10") + Call ok(testObj.imp = 10, "testObj.imp = " & testObj.imp & " expected 10") + Call ok(testObj.is = 10, "testObj.is = " & testObj.is & " expected 10") + Call ok(testObj.mod = 10, "testObj.mod = " & testObj.mod & " expected 10") + Call ok(testObj.call = 10, "testObj.call = " & testObj.call & " expected 10") + Call ok(testObj.dim = 10, "testObj.dim = " & testObj.dim & " expected 10") + Call ok(testObj.sub = 10, "testObj.sub = " & testObj.sub & " expected 10") + Call ok(testObj.function = 10, "testObj.function = " & testObj.function & " expected 10") + Call ok(testObj.get = 10, "testObj.get = " & testObj.get & " expected 10") + Call ok(testObj.let = 10, "testObj.let = " & testObj.let & " expected 10") + Call ok(testObj.const = 10, "testObj.const = " & testObj.const & " expected 10") + Call ok(testObj.if = 10, "testObj.if = " & testObj.if & " expected 10") + Call ok(testObj.else = 10, "testObj.else = " & testObj.else & " expected 10") + Call ok(testObj.elseif = 10, "testObj.elseif = " & testObj.elseif & " expected 10") + Call ok(testObj.end = 10, "testObj.end = " & testObj.end & " expected 10") + Call ok(testObj.then = 10, "testObj.then = " & testObj.then & " expected 10") + Call ok(testObj.exit = 10, "testObj.exit = " & testObj.exit & " expected 10") + Call ok(testObj.while = 10, "testObj.while = " & testObj.while & " expected 10") + Call ok(testObj.wend = 10, "testObj.wend = " & testObj.wend & " expected 10") + Call ok(testObj.do = 10, "testObj.do = " & testObj.do & " expected 10") + Call ok(testObj.loop = 10, "testObj.loop = " & testObj.loop & " expected 10") + Call ok(testObj.until = 10, "testObj.until = " & testObj.until & " expected 10") + Call ok(testObj.for = 10, "testObj.for = " & testObj.for & " expected 10") + Call ok(testObj.to = 10, "testObj.to = " & testObj.to & " expected 10") + Call ok(testObj.each = 10, "testObj.each = " & testObj.each & " expected 10") + Call ok(testObj.in = 10, "testObj.in = " & testObj.in & " expected 10") + Call ok(testObj.select = 10, "testObj.select = " & testObj.select & " expected 10") + Call ok(testObj.case = 10, "testObj.case = " & testObj.case & " expected 10") + Call ok(testObj.byref = 10, "testObj.byref = " & testObj.byref & " expected 10") + Call ok(testObj.byval = 10, "testObj.byval = " & testObj.byval & " expected 10") + Call ok(testObj.option = 10, "testObj.option = " & testObj.option & " expected 10") + Call ok(testObj.nothing = 10, "testObj.nothing = " & testObj.nothing & " expected 10") + Call ok(testObj.empty = 10, "testObj.empty = " & testObj.empty & " expected 10") + Call ok(testObj.null = 10, "testObj.null = " & testObj.null & " expected 10") + Call ok(testObj.class = 10, "testObj.class = " & testObj.class & " expected 10") + Call ok(testObj.set = 10, "testObj.set = " & testObj.set & " expected 10") + Call ok(testObj.new = 10, "testObj.new = " & testObj.new & " expected 10") + Call ok(testObj.public = 10, "testObj.public = " & testObj.public & " expected 10") + Call ok(testObj.private = 10, "testObj.private = " & testObj.private & " expected 10") + Call ok(testObj.next = 10, "testObj.next = " & testObj.next & " expected 10") + Call ok(testObj.on = 10, "testObj.on = " & testObj.on & " expected 10") + Call ok(testObj.resume = 10, "testObj.resume = " & testObj.resume & " expected 10") + Call ok(testObj.goto = 10, "testObj.goto = " & testObj.goto & " expected 10") +end sub +call test_dotIdentifiers + +' Test End statements not required to be preceeded by a newline or separator +Sub EndTestSub + x = 1 End Sub + +Sub EndTestSubWithCall + x = 1 + Call ok(x = 1, "x = " & x)End Sub +Call EndTestSubWithCall() + +Function EndTestFunc(x) + Call ok(x > 0, "x = " & x)End Function +EndTestFunc(1) + +Class EndTestClassWithStorageId + Public x End Class + +Class EndTestClassWithDim + Dim x End Class + +Class EndTestClassWithFunc + Function test(ByVal x) + x = 0 End Function End Class + +Class EndTestClassWithProperty + Public x + Public default Property Get defprop + defprop = x End Property End Class + reportSuccess() diff --git a/modules/rostests/winetests/vbscript/run.c b/modules/rostests/winetests/vbscript/run.c index 191f5a79a0d..2d34a8c80f2 100644 --- a/modules/rostests/winetests/vbscript/run.c +++ b/modules/rostests/winetests/vbscript/run.c @@ -58,6 +58,9 @@ extern const CLSID CLSID_VBScriptRegExp; #define SET_EXPECT(func) \ expect_ ## func = TRUE
+#define REF_EXPECT(func) \ + (&expect_ ## func), (&called_ ## func) + #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ @@ -76,6 +79,12 @@ extern const CLSID CLSID_VBScriptRegExp; expect_ ## func = called_ ## func = FALSE; \ }while(0)
+#define CHECK_NOT_CALLED(func) \ + do { \ + ok(!called_ ## func, "unexpected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + #define CLEAR_CALLED(func) \ expect_ ## func = called_ ## func = FALSE
@@ -85,6 +94,7 @@ DEFINE_EXPECT(global_vbvar_d); DEFINE_EXPECT(global_vbvar_i); DEFINE_EXPECT(global_letobj_i); DEFINE_EXPECT(global_setobj_i); +DEFINE_EXPECT(global_globalcallback_i); DEFINE_EXPECT(testobj_propget_d); DEFINE_EXPECT(testobj_propget_i); DEFINE_EXPECT(testobj_propput_d); @@ -95,12 +105,15 @@ DEFINE_EXPECT(global_propargput_i); DEFINE_EXPECT(global_propargput1_d); DEFINE_EXPECT(global_propargput1_i); DEFINE_EXPECT(global_testoptionalarg_i); +DEFINE_EXPECT(global_testerrorobject_i); DEFINE_EXPECT(collectionobj_newenum_i); DEFINE_EXPECT(Next); DEFINE_EXPECT(GetWindow); DEFINE_EXPECT(GetUIBehavior); DEFINE_EXPECT(EnableModeless); DEFINE_EXPECT(OnScriptError); +DEFINE_EXPECT(OnEnterScript); +DEFINE_EXPECT(OnLeaveScript);
#define DISPID_GLOBAL_REPORTSUCCESS 1000 #define DISPID_GLOBAL_TRACE 1001 @@ -124,9 +137,12 @@ DEFINE_EXPECT(OnScriptError); #define DISPID_GLOBAL_SETOBJ 1019 #define DISPID_GLOBAL_TODO_WINE_OK 1020 #define DISPID_GLOBAL_WEEKSTARTDAY 1021 +#define DISPID_GLOBAL_GLOBALCALLBACK 1022 +#define DISPID_GLOBAL_TESTERROROBJECT 1023
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 +#define DISPID_TESTOBJ_KEYWORD 2002
#define DISPID_COLLOBJ_RESET 3000
@@ -143,6 +159,7 @@ static int test_counter; static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR; static IDispatchEx testObj; static HRESULT onerror_hres = E_NOTIMPL; +static BOOL strict_enter_script;
static BSTR a2bstr(const char *str) { @@ -163,6 +180,13 @@ static int strcmp_wa(LPCWSTR strw, const char *stra) return lstrcmpA(buf, stra); }
+static int stricmp_wa(LPCWSTR strw, const char *stra) +{ + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0); + return lstrcmpiA(buf, stra); +} + static const char *vt2a(VARIANT *v) { if(V_VT(v) == (VT_BYREF|VT_VARIANT)) { @@ -685,7 +709,6 @@ static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pcti static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
@@ -756,17 +779,81 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { - if(!strcmp_wa(bstrName, "propget")) { - CHECK_EXPECT(testobj_propget_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPGET; - return S_OK; - } - if(!strcmp_wa(bstrName, "propput")) { - CHECK_EXPECT(testobj_propput_d); - test_grfdex(grfdex, fdexNameCaseInsensitive); - *pid = DISPID_TESTOBJ_PROPPUT; - return S_OK; + typedef struct { + const char * const name; + DISPID pid; + BOOL *expect; + BOOL *called; + } dispid_t; + + dispid_t dispids[] = { + { "propget", DISPID_TESTOBJ_PROPGET, REF_EXPECT(testobj_propget_d) }, + { "propput", DISPID_TESTOBJ_PROPPUT, REF_EXPECT(testobj_propput_d) }, + { "rem", DISPID_TESTOBJ_KEYWORD, NULL }, + { "true", DISPID_TESTOBJ_KEYWORD, NULL }, + { "false", DISPID_TESTOBJ_KEYWORD, NULL }, + { "not", DISPID_TESTOBJ_KEYWORD, NULL }, + { "and", DISPID_TESTOBJ_KEYWORD, NULL }, + { "or", DISPID_TESTOBJ_KEYWORD, NULL }, + { "xor", DISPID_TESTOBJ_KEYWORD, NULL }, + { "eqv", DISPID_TESTOBJ_KEYWORD, NULL }, + { "imp", DISPID_TESTOBJ_KEYWORD, NULL }, + { "is", DISPID_TESTOBJ_KEYWORD, NULL }, + { "mod", DISPID_TESTOBJ_KEYWORD, NULL }, + { "call", DISPID_TESTOBJ_KEYWORD, NULL }, + { "dim", DISPID_TESTOBJ_KEYWORD, NULL }, + { "sub", DISPID_TESTOBJ_KEYWORD, NULL }, + { "function", DISPID_TESTOBJ_KEYWORD, NULL }, + { "get", DISPID_TESTOBJ_KEYWORD, NULL }, + { "let", DISPID_TESTOBJ_KEYWORD, NULL }, + { "const", DISPID_TESTOBJ_KEYWORD, NULL }, + { "if", DISPID_TESTOBJ_KEYWORD, NULL }, + { "else", DISPID_TESTOBJ_KEYWORD, NULL }, + { "elseif", DISPID_TESTOBJ_KEYWORD, NULL }, + { "end", DISPID_TESTOBJ_KEYWORD, NULL }, + { "then", DISPID_TESTOBJ_KEYWORD, NULL }, + { "exit", DISPID_TESTOBJ_KEYWORD, NULL }, + { "while", DISPID_TESTOBJ_KEYWORD, NULL }, + { "wend", DISPID_TESTOBJ_KEYWORD, NULL }, + { "do", DISPID_TESTOBJ_KEYWORD, NULL }, + { "loop", DISPID_TESTOBJ_KEYWORD, NULL }, + { "until", DISPID_TESTOBJ_KEYWORD, NULL }, + { "for", DISPID_TESTOBJ_KEYWORD, NULL }, + { "to", DISPID_TESTOBJ_KEYWORD, NULL }, + { "each", DISPID_TESTOBJ_KEYWORD, NULL }, + { "in", DISPID_TESTOBJ_KEYWORD, NULL }, + { "select", DISPID_TESTOBJ_KEYWORD, NULL }, + { "case", DISPID_TESTOBJ_KEYWORD, NULL }, + { "byref", DISPID_TESTOBJ_KEYWORD, NULL }, + { "byval", DISPID_TESTOBJ_KEYWORD, NULL }, + { "option", DISPID_TESTOBJ_KEYWORD, NULL }, + { "nothing", DISPID_TESTOBJ_KEYWORD, NULL }, + { "empty", DISPID_TESTOBJ_KEYWORD, NULL }, + { "null", DISPID_TESTOBJ_KEYWORD, NULL }, + { "class", DISPID_TESTOBJ_KEYWORD, NULL }, + { "set", DISPID_TESTOBJ_KEYWORD, NULL }, + { "new", DISPID_TESTOBJ_KEYWORD, NULL }, + { "public", DISPID_TESTOBJ_KEYWORD, NULL }, + { "private", DISPID_TESTOBJ_KEYWORD, NULL }, + { "next", DISPID_TESTOBJ_KEYWORD, NULL }, + { "on", DISPID_TESTOBJ_KEYWORD, NULL }, + { "resume", DISPID_TESTOBJ_KEYWORD, NULL }, + { "goto", DISPID_TESTOBJ_KEYWORD, NULL }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(dispids); i++) { + if(!stricmp_wa(bstrName, dispids[i].name)) { + dispid_t *d = &dispids[i]; + if(d->expect) { + ok(*d->expect, "unexpected call %s\n", d->name); + *d->called = TRUE; + *d->expect = FALSE; + } + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = d->pid; + return S_OK; + } }
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName)); @@ -831,6 +918,11 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg)); return S_OK; + + case DISPID_TESTOBJ_KEYWORD: + V_VT(pvarRes) = VT_I2; + V_I2(pvarRes) = 10; + return S_OK; }
ok(0, "unexpected call %d\n", id); @@ -1024,6 +1116,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD *pid = DISPID_GLOBAL_WEEKSTARTDAY; return S_OK; } + if(!strcmp_wa(bstrName, "globalCallback")) { + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = DISPID_GLOBAL_GLOBALCALLBACK; + return S_OK; + } if(!strcmp_wa(bstrName, "testObj")) { test_grfdex(grfdex, fdexNameCaseInsensitive); *pid = DISPID_GLOBAL_TESTOBJ; @@ -1102,6 +1199,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD *pid = DISPID_GLOBAL_TESTOPTIONALARG; return S_OK; } + if(!strcmp_wa(bstrName, "testErrorObject")) { + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = DISPID_GLOBAL_TESTERROROBJECT; + return S_OK; + }
if(strict_dispid_check && strcmp_wa(bstrName, "x")) ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex); @@ -1480,6 +1582,115 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v)); return S_OK; } + case DISPID_GLOBAL_GLOBALCALLBACK: { + DISPPARAMS dp = {0}; + IDispatchEx *dispex; + EXCEPINFO ei; + VARIANT v; + DISPID id; + BSTR str; + HRESULT hres; + + CHECK_EXPECT(global_globalcallback_i); + CHECK_CALLED(OnEnterScript); + + ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg)); + 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"); + + hres = IDispatch_QueryInterface(V_DISPATCH(pdp->rgvarg), &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres); + + str = SysAllocString(L"callback"); + hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + memset(&ei, 0, sizeof(ei)); + hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, pspCaller); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v)); + + IDispatchEx_Release(dispex); + + SET_EXPECT(OnLeaveScript); + return S_OK; + } + case DISPID_GLOBAL_TESTERROROBJECT: { + ITypeInfo *typeinfo; + IDispatchEx *dispex; + DISPPARAMS dp; + VARIANT v, r; + EXCEPINFO ei; + IDispatch *disp; + WCHAR *names[1]; + UINT count, i; + DISPID id; + HRESULT hres; + + static WCHAR props[][32] = { L"clear", L"description", L"helpcontext", L"helpFILE", L"number", L"raise", L"source" }; + + CHECK_EXPECT(global_testerrorobject_i); + + 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_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg)); + disp = V_DISPATCH(pdp->rgvarg); + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + ok(hres == E_NOINTERFACE, "Could not get IDispatchEx iface: %08x\n", hres); + + hres = IDispatch_GetTypeInfoCount(disp, &count); + ok(hres == S_OK, "GetTypeInfoCount returned: %08x\n", hres); + ok(count == 0, "count = %u\n", count); + + hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo); + ok(hres == DISP_E_BADINDEX, "GetTypeInfo returned: %08x\n", hres); + + for(i = 0; i < ARRAY_SIZE(props); i++) { + names[0] = props[i]; + hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, names, 1, 0, &id); + ok(hres == S_OK, "GetIDsOfNames failed: %08x\n", hres); + ok(id == i + 1, "%s id = %u\n", wine_dbgstr_w(props[i]), id); + } + + memset(&dp, 0, sizeof(dp)); + memset(&ei, 0, sizeof(ei)); + V_VT(&v) = VT_ERROR; + hres = IDispatch_Invoke(disp, 5, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v)); + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v)); + + dp.rgvarg = &v; + V_VT(&v) = VT_I4; + V_I4(&v) = 6; + V_VT(&r) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 6, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dp, &r, &ei, NULL); + ok(hres == S_OK, "Invoke failed: %08x\n", hres); + return S_OK; + } }
ok(0, "unexpected call %d\n", id); @@ -1651,9 +1862,11 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S return E_NOTIMPL; }
+static IActiveScriptError **store_script_error; + static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) { - HRESULT hr = onerror_hres; + HRESULT hr = onerror_hres, hres;
if(!expect_OnScriptError) { EXCEPINFO info; @@ -1664,7 +1877,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I if(SUCCEEDED(hres)) hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info); if(SUCCEEDED(hres)) - trace("Error in line %u: %s\n", line+1, wine_dbgstr_w(info.bstrDescription)); + trace("Error in line %u: %x %s\n", line+1, info.wCode, wine_dbgstr_w(info.bstrDescription)); + }else { + IDispatchEx *dispex; + + hres = IActiveScriptError_QueryInterface(pscripterror, &IID_IDispatchEx, (void**)&dispex); + ok(hres == E_NOINTERFACE, "QI(IDispatchEx) returned: %08x\n", hres); + } + + if(store_script_error) { + IActiveScriptError_AddRef(pscripterror); + *store_script_error = pscripterror; + store_script_error = NULL; }
CHECK_EXPECT(OnScriptError); @@ -1675,16 +1899,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I
static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface) { + if(strict_enter_script) + CHECK_EXPECT(OnEnterScript); return E_NOTIMPL; }
static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface) { + if(strict_enter_script) + CHECK_EXPECT(OnLeaveScript); return E_NOTIMPL; }
-#undef ACTSCPSITE_THIS - static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = { ActiveScriptSite_QueryInterface, ActiveScriptSite_AddRef, @@ -1713,7 +1939,7 @@ static IActiveScript *create_script(void) return script; }
-static IActiveScript *create_and_init_script(DWORD flags) +static IActiveScript *create_and_init_script(DWORD flags, BOOL start) { IActiveScriptParse *parser; IActiveScript *engine; @@ -1738,8 +1964,11 @@ static IActiveScript *create_and_init_script(DWORD flags) SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags); 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); + if (start) + { + hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + }
return engine; } @@ -1764,7 +1993,7 @@ static HRESULT parse_script(DWORD flags, BSTR script_str, const WCHAR *delim) LONG ref; HRESULT hres;
- engine = create_and_init_script(flags); + engine = create_and_init_script(flags, TRUE); if(!engine) return S_OK;
@@ -1828,13 +2057,17 @@ static void test_parse_context(void) static const WCHAR yW[] = {'y',0};
global_ref = 1; - engine = create_and_init_script(0); + engine = create_and_init_script(0, TRUE); if(!engine) return;
hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+ /* NULL code text succeeds but does nothing */ + hres = IActiveScriptParse_ParseScriptText(parser, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + /* unknown identifier context is not a valid argument */ str = a2bstr("Call reportSuccess()\n"); hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL); @@ -1891,7 +2124,7 @@ static void _parse_htmlscript_a(unsigned line, const char *src) ok_(__FILE__,line)(hres == S_OK, "parse_script failed: %08x\n", hres); }
-static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src) +static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src, DWORD flags) { IDispatchEx *dispex; IDispatch *disp; @@ -1902,7 +2135,7 @@ static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, co
str = a2bstr(src); hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0, - SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp); + SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS|flags, &disp); SysFreeString(str); ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres); ok(disp != NULL, "disp = NULL\n"); @@ -1921,26 +2154,220 @@ static void test_procedures(void) DISPPARAMS dp = {NULL}; IActiveScript *script; IDispatchEx *proc; + IDispatch *disp; EXCEPINFO ei = {0}; VARIANT v; HRESULT hres;
- script = create_and_init_script(0); + strict_enter_script = TRUE; + script = create_and_init_script(0, TRUE);
hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc); ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
- proc = parse_procedure(parse_proc, "dim x\nif true then x=false"); + hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, NULL, NULL, emptyW, NULL, NULL, NULL, 0, 0, 0, &disp); + ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres); + IDispatch_Release(disp); + + proc = parse_procedure(parse_proc, "dim x\nif true then x=false", 0);
+ SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + VariantClear(&v); + IDispatchEx_Release(proc); + + proc = parse_procedure(parse_proc, ""foobar"", SCRIPTPROC_ISEXPRESSION);
+ SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&v)); + ok(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); IDispatchEx_Release(proc);
IActiveScriptParseProcedure2_Release(parse_proc);
close_script(script); + strict_enter_script = FALSE; +} + +static void free_ei(EXCEPINFO *ei) +{ + SysFreeString(ei->bstrSource); + SysFreeString(ei->bstrDescription); + SysFreeString(ei->bstrHelpFile); +} + +static void test_callbacks(void) +{ + IActiveScriptError *error1, *error2; + IActiveScriptParse *parser; + DISPPARAMS dp = {NULL}; + IActiveScript *script; + IDispatchEx *dispex; + IDispatch *disp; + DISPID id; + EXCEPINFO ei = {0}; + BSTR str; + VARIANT v; + HRESULT hres; + + strict_enter_script = TRUE; + script = create_and_init_script(SCRIPTITEM_GLOBALMEMBERS, TRUE); + + hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres); + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parser, + L"class CallbackClass\n" + L" public function callback()\n" + L" call ok(err.number = 2, "err.number = " & err.number)\n" + L" callback = true\n" + L" end function\n" + L"end class\n" + L"function callGlobalCallback()\n" + L" on error resume next\n" + L" err.raise 2\n" + L" call test.globalCallback(new CallbackClass)\n" + L" call ok(err.number = 2, "err.number = " & err.numner)\n" + L"end function\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + + hres = IActiveScript_GetScriptDispatch(script, NULL, &disp); + ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres); + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres); + IDispatch_Release(disp); + + str = SysAllocString(L"callGlobalCallback"); + hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(OnEnterScript); + /* OnLeaveScript will be set in global callback */ + SET_EXPECT(global_globalcallback_i); + hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + /* OnEnterScript was checked in global callback */ + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(global_globalcallback_i); + + store_script_error = &error1; + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise 2\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == MAKE_VBSERROR(2), "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(OnScriptError); + + store_script_error = &error2; + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, + L"call ok(err.number = 0, "err.number = " & err.number)\n" + L"err.raise &h86664004&, "src", "desc", "help", 1\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == SCRIPT_E_RECORDED, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(OnScriptError); + + memset(&ei, 0xcc, sizeof(ei)); + hres = IActiveScriptError_GetExceptionInfo(error1, &ei); + ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres); + ok(!ei.wCode, "wCode = %x\n", ei.wCode); + ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved); + if(is_english) { + ok(!wcscmp(ei.bstrSource, L"Microsoft VBScript runtime error"), + "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource)); + ok(!wcscmp(ei.bstrDescription, L"Object doesn't support this property or method"), + "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription)); + } + ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); + ok(!ei.dwHelpContext, "dwHelpContext = %x\n", ei.dwHelpContext); + ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); + ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn); + ok(ei.scode == MAKE_VBSERROR(2), "scode = %x\n", ei.scode); + free_ei(&ei); + + IActiveScriptError_Release(error1); + + memset(&ei, 0xcc, sizeof(ei)); + hres = IActiveScriptError_GetExceptionInfo(error2, &ei); + ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres); + ok(!ei.wCode, "wCode = %x\n", ei.wCode); + ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved); + ok(!wcscmp(ei.bstrSource, L"src"), "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource)); + ok(!wcscmp(ei.bstrDescription, L"desc"), "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription)); + ok(!wcscmp(ei.bstrHelpFile, L"help"), "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); + ok(ei.dwHelpContext == 1, "dwHelpContext = %x\n", ei.dwHelpContext); + ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); + ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn); + ok(ei.scode == SCRIPT_E_RECORDED, "scode = %x\n", ei.scode); + free_ei(&ei); + + IActiveScriptError_Release(error2); + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &hffff&\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == MAKE_VBSERROR(0xffff), "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(OnScriptError); + + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &h80102030&\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == 0x80102030, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(OnScriptError); + + SET_EXPECT(OnEnterScript); + SET_EXPECT(global_testerrorobject_i); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parser, + L"on error resume next\n" + L"err.raise 1\n" + L"testErrorObject err\n", + NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(global_testerrorobject_i); + CHECK_CALLED(OnLeaveScript); + + IDispatchEx_Release(dispex); + + IActiveScriptParse_Release(parser); + close_script(script); + strict_enter_script = FALSE; }
static void test_gc(void) @@ -1998,6 +2425,62 @@ static void test_gc(void) IActiveScriptParse_Release(parser); }
+static void test_parse_errors(void) +{ + static const char *invalid_scripts[] = + { + /* If...End If */ + "If 0 > 1 Then\n" + " x = 0 End If\n", + + /* While...End While */ + "While False\n" + " x = 0 End While\n", + + /* While...Wend */ + "While False\n" + " x = 0 Wend\n", + + /* Do While...Loop */ + "Do While False\n" + " x = 0 Loop\n", + + /* Do Until...Loop */ + "Do Until True\n" + " x = 0 Loop\n", + + /* Do...Loop While */ + "Do\n" + " x = 0 Loop While False\n", + + /* Do...Loop Until */ + "Do\n" + " x = 0 Loop Until True\n", + + /* Select...End Select */ + "x = False\n" + "Select Case 42\n" + " Case 0\n" + " Call ok(False, "unexpected case")\n" + " Case 42\n" + " x = True End Select\n" + "Call ok(x, "wrong case")\n", + + /* Class...End Class (empty) */ + "Class C End Class" + }; + HRESULT hres; + UINT i; + + for (i = 0; i < ARRAY_SIZE(invalid_scripts); i++) + { + SET_EXPECT(OnScriptError); + hres = parse_script_ar(invalid_scripts[i]); + ok(FAILED(hres), "[%u] script did not fail\n", i); + CHECK_CALLED(OnScriptError); + } +} + static void test_msgbox(void) { HRESULT hres; @@ -2035,7 +2518,7 @@ static void test_msgbox(void) CHECK_CALLED(GetUIBehavior); CHECK_CALLED(GetWindow); CHECK_CALLED(EnableModeless); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
uic_handling = SCRIPTUICHANDLING_NOUIERROR;
@@ -2044,7 +2527,7 @@ static void test_msgbox(void) hres = parse_script_ar("MsgBox "testing...""); ok(FAILED(hres), "script not failed\n"); CHECK_CALLED(GetUIBehavior); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError); }
static HRESULT test_global_vars_ref(BOOL use_close) @@ -2104,6 +2587,141 @@ static HRESULT test_global_vars_ref(BOOL use_close) return hres; }
+static void test_isexpression(void) +{ + IActiveScriptParse *parser; + IActiveScript *engine; + SCRIPTSTATE ss; + HRESULT hres; + VARIANT var; + BSTR str; + + if (!(engine = create_and_init_script(0, FALSE))) + return; + + hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + if (FAILED(hres)) + { + close_script(engine); + return; + } + + /* Expression when script is not started is still executed */ + hres = IActiveScript_GetScriptState(engine, &ss); + ok(hres == S_OK, "GetScriptState failed: %08x\n", hres); + ok(ss == SCRIPTSTATE_INITIALIZED, "Wrong script state %u\n", ss); + + str = a2bstr("13"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + + /* Empty expressions */ + V_VT(&var) = VT_I2; + str = a2bstr(""); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var)); + VariantClear(&var); + SysFreeString(str); + + /* Two expressions fail */ + str = a2bstr("1\n3"); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres); + CHECK_CALLED(OnScriptError); + VariantClear(&var); + SysFreeString(str); + + /* Simple numerical expression */ + str = a2bstr("(1 + 7) * 2 - 3"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + /* An expression can also refer to a variable, function, class, etc previously set */ + V_VT(&var) = VT_I2; + str = a2bstr("If True Then foo = 42 Else foo = 0\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("foo\n\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var)); + ok(V_I2(&var) == 42, "Expected 42, got %d\n", V_I2(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("foo : "); + SET_EXPECT(OnScriptError); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres); + CHECK_CALLED(OnScriptError); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr(""foo is " & CStr(foo) \n \n\n "); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&var)); + ok(!strcmp_wa(V_BSTR(&var), "foo is 42"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("Function test(x)\n" + " test = x + 0.5\n" + "End Function\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("test(4) * 3\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_R8, "Expected VT_R8, got %s\n", vt2a(&var)); + ok(V_R8(&var) == 13.5, "Expected %lf, got %lf\n", 13.5, V_R8(&var)); + VariantClear(&var); + SysFreeString(str); + + str = a2bstr("Class C\n" + " Public x\n" + "End Class\n" + "Set obj = New C\n" + "obj.x = True\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("obj.x"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_BOOL, "Expected VT_BOOL, got %s\n", vt2a(&var)); + ok(V_BOOL(&var) == VARIANT_TRUE, "Expected %x, got %x\n", VARIANT_TRUE, V_BOOL(&var)); + VariantClear(&var); + SysFreeString(str); + + IActiveScriptParse_Release(parser); + close_script(engine); +} + static BSTR get_script_from_file(const char *filename) { DWORD size, len; @@ -2186,6 +2804,7 @@ static void run_from_res(const char *name)
ok(hres == S_OK, "parse_script failed: %08x\n", hres); SysFreeString(str); + test_name = ""; }
static void run_tests(void) @@ -2255,6 +2874,13 @@ static void run_tests(void) parse_script_a("Option Explicit\nset test.setobj = testObj"); CHECK_CALLED(global_setobj_i);
+ SET_EXPECT(OnScriptError); + hres = parse_script_ar("dim x\nx = testObj.rem"); + todo_wine + ok(hres == S_OK, "use of 'rem' as dot identifier failed: %x08\n", hres); + todo_wine + CHECK_NOT_CALLED(OnScriptError); + SET_EXPECT(testobj_propget_d); SET_EXPECT(testobj_propget_i); parse_script_a("dim x\nx = testObj.propget"); @@ -2299,7 +2925,7 @@ static void run_tests(void) SET_EXPECT(OnScriptError); hres = parse_script_ar("<!--"); ok(FAILED(hres), "script didn't fail\n"); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
SET_EXPECT(global_success_d); SET_EXPECT(global_success_i); @@ -2325,36 +2951,36 @@ static void run_tests(void) SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h80080008&)"); ok(hres == 0x80080008, "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
/* DISP_E_BADINDEX */ SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h8002000b&)"); ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h800a0009&)"); ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
onerror_hres = S_OK; SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h800a0009&)"); - todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres); + CHECK_CALLED(OnScriptError);
/* E_NOTIMPL */ SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h80004001&)"); ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
onerror_hres = S_OK; SET_EXPECT(OnScriptError); hres = parse_script_ar("throwInt(&h80004001&)"); - todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres); - todo_wine CHECK_CALLED(OnScriptError); + ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres); + CHECK_CALLED(OnScriptError);
SET_EXPECT(global_testoptionalarg_i); parse_script_a("call testOptionalArg(1,,2)"); @@ -2392,11 +3018,14 @@ static void run_tests(void) SET_EXPECT(OnScriptError); hres = parse_script_ar("x = y("a")"); ok(FAILED(hres), "script didn't fail\n"); - todo_wine CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnScriptError);
SET_EXPECT(global_success_d); SET_EXPECT(global_success_i); parse_script_a("' comment\r" + "x = _\r3\r" + "x = _\n3\r" + "x = _\r\n3\r" "Sub testsub(arg)\r" "If arg = 1 Then\r\r" "Call reportSuccess()\n\n" @@ -2414,7 +3043,10 @@ static void run_tests(void) test_procedures(); test_gc(); test_msgbox(); + test_isexpression(); + test_parse_errors(); test_parse_context(); + test_callbacks(); }
static BOOL check_vbscript(void) diff --git a/modules/rostests/winetests/vbscript/vbscript.c b/modules/rostests/winetests/vbscript/vbscript.c index 9e86a5f9198..08edfc1be79 100644 --- a/modules/rostests/winetests/vbscript/vbscript.c +++ b/modules/rostests/winetests/vbscript/vbscript.c @@ -84,6 +84,9 @@ DEFINE_EXPECT(OnStateChange_CLOSED); DEFINE_EXPECT(OnStateChange_INITIALIZED); DEFINE_EXPECT(OnEnterScript); DEFINE_EXPECT(OnLeaveScript); +DEFINE_EXPECT(GetItemInfo_global); +DEFINE_EXPECT(GetItemInfo_visible); +DEFINE_EXPECT(testCall);
DEFINE_GUID(CLSID_VBScript, 0xb54f3741, 0x5b07, 0x11cf, 0xa4,0xb0, 0x00,0xaa,0x00,0x4a,0x55,0xe8); DEFINE_GUID(CLSID_VBScriptRegExp, 0x3f4daca4, 0x160d, 0x11d2, 0xa8,0xe9, 0x00,0x10,0x4b,0x36,0x5c,0x9f); @@ -111,6 +114,95 @@ static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstat ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate); }
+static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) { + *ppv = iface; + IDispatch_AddRef(iface); + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG global_named_item_ref, visible_named_item_ref; + +static ULONG WINAPI global_AddRef(IDispatch *iface) +{ + return ++global_named_item_ref; +} + +static ULONG WINAPI global_Release(IDispatch *iface) +{ + return --global_named_item_ref; +} + +static ULONG WINAPI visible_AddRef(IDispatch *iface) +{ + return ++visible_named_item_ref; +} + +static ULONG WINAPI visible_Release(IDispatch *iface) +{ + return --visible_named_item_ref; +} + +static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + return DISP_E_BADINDEX; +} + +static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_cnt, + LCID lcid, DISPID *ids) +{ + ok(name_cnt == 1, "name_cnt = %u\n", name_cnt); + ok(!wcscmp(names[0], L"testCall"), "names[0] = %s\n", wine_dbgstr_w(names[0])); + *ids = 1; + return S_OK; +} + +static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID id, REFIID riid, LCID lcid, WORD flags, + DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, UINT *err) +{ + CHECK_EXPECT(testCall); + ok(id == 1, "id = %u\n", id); + ok(flags == DISPATCH_METHOD, "flags = %x\n", flags); + ok(!dp->cArgs, "cArgs = %u\n", dp->cArgs); + ok(!res, "res = %p\n", res); + return S_OK; +} + +static const IDispatchVtbl global_named_item_vtbl = { + Dispatch_QueryInterface, + global_AddRef, + global_Release, + Dispatch_GetTypeInfoCount, + Dispatch_GetTypeInfo, + Dispatch_GetIDsOfNames, + Dispatch_Invoke +}; + +static IDispatch global_named_item = { &global_named_item_vtbl }; + +static const IDispatchVtbl visible_named_item_vtbl = { + Dispatch_QueryInterface, + visible_AddRef, + visible_Release, + Dispatch_GetTypeInfoCount, + Dispatch_GetTypeInfo, + Dispatch_GetIDsOfNames, + Dispatch_Invoke +}; + +static IDispatch visible_named_item = { &visible_named_item_vtbl }; + static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -142,10 +234,23 @@ static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *p return E_NOTIMPL; }
-static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName, - DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) +static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, + DWORD return_mask, IUnknown **item_unk, ITypeInfo **item_ti) { - ok(0, "unexpected call\n"); + ok(return_mask == SCRIPTINFO_IUNKNOWN, "return_mask = %x\n", return_mask); + if(!wcscmp(name, L"globalItem")) { + CHECK_EXPECT(GetItemInfo_global); + IDispatch_AddRef(&global_named_item); + *item_unk = (IUnknown*)&global_named_item; + return S_OK; + } + if(!wcscmp(name, L"visibleItem")) { + CHECK_EXPECT(GetItemInfo_visible); + IDispatch_AddRef(&visible_named_item); + *item_unk = (IUnknown*)&visible_named_item; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_w(name)); return E_NOTIMPL; }
@@ -392,8 +497,8 @@ static IActiveScript *create_vbscript(void)
static void test_scriptdisp(void) { + IDispatchEx *script_disp, *script_disp2; IActiveScriptParse *parser; - IDispatchEx *script_disp; IActiveScript *vbscript; DISPID id, id2; DISPPARAMS dp; @@ -415,6 +520,8 @@ static void test_scriptdisp(void) ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres); CHECK_CALLED(GetLCID);
+ script_disp2 = get_script_dispatch(vbscript); + test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
SET_EXPECT(OnStateChange_INITIALIZED); @@ -432,6 +539,8 @@ static void test_scriptdisp(void) test_state(vbscript, SCRIPTSTATE_CONNECTED);
script_disp = get_script_dispatch(vbscript); + ok(script_disp == script_disp2, "script_disp != script_disp2\n"); + IDispatchEx_Release(script_disp2);
id = 100; get_disp_id(script_disp, "LCase", DISP_E_UNKNOWNNAME, &id); @@ -529,6 +638,7 @@ static void test_vbscript(void)
test_state(vbscript, SCRIPTSTATE_UNINITIALIZED); test_safety(vbscript); + test_no_script_dispatch(vbscript);
SET_EXPECT(GetLCID); hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite); @@ -600,6 +710,8 @@ static void test_vbscript_uninitializing(void) hres = IActiveScriptParse_InitNew(parse); ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+ test_no_script_dispatch(script); + SET_EXPECT(GetLCID); SET_EXPECT(OnStateChange_INITIALIZED); hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite); @@ -685,6 +797,9 @@ static void test_vbscript_uninitializing(void)
test_state(script, SCRIPTSTATE_CLOSED);
+ hres = IActiveScriptParse_InitNew(parse); + ok(hres == E_UNEXPECTED, "InitNew failed: %08x\n", hres); + IActiveScriptParse_Release(parse);
ref = IActiveScript_Release(script); @@ -794,6 +909,88 @@ static void test_vbscript_initializing(void) ok(!ref, "ref = %d\n", ref); }
+static void test_named_items(void) +{ + IActiveScriptParse *parse; + IActiveScript *script; + ULONG ref; + HRESULT hres; + + script = create_vbscript(); + + hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + + test_state(script, SCRIPTSTATE_UNINITIALIZED); + + hres = IActiveScript_AddNamedItem(script, L"visibleItem", SCRIPTITEM_ISVISIBLE); + ok(hres == E_UNEXPECTED, "AddNamedItem returned: %08x\n", hres); + hres = IActiveScript_AddNamedItem(script, L"globalItem", SCRIPTITEM_GLOBALMEMBERS); + ok(hres == E_UNEXPECTED, "AddNamedItem returned: %08x\n", hres); + + SET_EXPECT(GetLCID); + hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite); + ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres); + CHECK_CALLED(GetLCID); + + SET_EXPECT(GetItemInfo_global); + hres = IActiveScript_AddNamedItem(script, L"globalItem", SCRIPTITEM_GLOBALMEMBERS); + ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); + CHECK_CALLED(GetItemInfo_global); + + hres = IActiveScript_AddNamedItem(script, L"visibleItem", SCRIPTITEM_ISVISIBLE); + ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); + + ok(global_named_item_ref > 0, "global_named_item_ref = %u\n", global_named_item_ref); + ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); + + SET_EXPECT(OnStateChange_INITIALIZED); + hres = IActiveScriptParse_InitNew(parse); + ok(hres == S_OK, "InitNew failed: %08x\n", hres); + CHECK_CALLED(OnStateChange_INITIALIZED); + + 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); + + SET_EXPECT(testCall); + parse_script(parse, "testCall\n"); + CHECK_CALLED(testCall); + + SET_EXPECT(GetItemInfo_visible); + SET_EXPECT(testCall); + parse_script(parse, "visibleItem.testCall\n"); + CHECK_CALLED(GetItemInfo_visible); + CHECK_CALLED(testCall); + + ok(global_named_item_ref > 0, "global_named_item_ref = %u\n", global_named_item_ref); + ok(visible_named_item_ref == 1, "visible_named_item_ref = %u\n", visible_named_item_ref); + + SET_EXPECT(testCall); + parse_script(parse, "visibleItem.testCall\n"); + CHECK_CALLED(testCall); + + 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); + + ok(global_named_item_ref == 0, "global_named_item_ref = %u\n", global_named_item_ref); + ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); + + test_state(script, SCRIPTSTATE_CLOSED); + + IActiveScriptParse_Release(parse); + + ref = IActiveScript_Release(script); + ok(!ref, "ref = %d\n", ref); +} + static void test_RegExp(void) { IRegExp2 *regexp; @@ -957,6 +1154,7 @@ START_TEST(vbscript) test_vbscript_release(); test_vbscript_simplecreate(); test_vbscript_initializing(); + test_named_items(); test_scriptdisp(); test_RegExp(); }else {