| ' | |
| ' Copyright 2014 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 | |
| ' | |
| Option Explicit | |
| const E_TESTERROR = &h80080008& | |
| const VB_E_FORLOOPNOTINITIALIZED = 92 | |
| const VB_E_OBJNOTCOLLECTION = 451 | |
| const E_NOTIMPL = &h80004001& | |
| const E_NOINTERFACE = &h80004002& | |
| const DISP_E_UNKNOWNINTERFACE = &h80020001& | |
| const DISP_E_MEMBERNOTFOUND = &h80020003& | |
| const DISP_E_PARAMNOTFOUND = &h80020004& | |
| const DISP_E_TYPEMISMATCH = &h80020005& | |
| const DISP_E_UNKNOWNNAME = &h80020006& | |
| const DISP_E_NONAMEDARGS = &h80020007& | |
| const DISP_E_BADVARTYPE = &h80020008& | |
| const DISP_E_OVERFLOW = &h8002000A& | |
| const DISP_E_BADINDEX = &h8002000B& | |
| const DISP_E_UNKNOWNLCID = &h8002000C& | |
| const DISP_E_ARRAYISLOCKED = &h8002000D& | |
| const DISP_E_BADPARAMCOUNT = &h8002000E& | |
| const DISP_E_PARAMNOTOPTIONAL = &h8002000F& | |
| const DISP_E_NOTACOLLECTION = &h80020011& | |
| const TYPE_E_DLLFUNCTIONNOTFOUND = &h8002802F& | |
| const TYPE_E_TYPEMISMATCH = &h80028CA0& | |
| const TYPE_E_OUTOFBOUNDS = &h80028CA1& | |
| const TYPE_E_IOERROR = &h80028CA2& | |
| const TYPE_E_CANTCREATETMPFILE = &h80028CA3& | |
| const STG_E_FILENOTFOUND = &h80030002& | |
| const STG_E_PATHNOTFOUND = &h80030003& | |
| const STG_E_TOOMANYOPENFILES = &h80030004& | |
| const STG_E_ACCESSDENIED = &h80030005& | |
| const STG_E_INSUFFICIENTMEMORY = &h80030008& | |
| const STG_E_NOMOREFILES = &h80030012& | |
| const STG_E_DISKISWRITEPROTECTED = &h80030013& | |
| const STG_E_WRITEFAULT = &h8003001D& | |
| const STG_E_READFAULT = &h8003001E& | |
| const STG_E_SHAREVIOLATION = &h80030020& | |
| const STG_E_LOCKVIOLATION = &h80030021& | |
| const STG_E_FILEALREADYEXISTS = &h80030050& | |
| const STG_E_MEDIUMFULL = &h80030070& | |
| const STG_E_INVALIDNAME = &h800300FC& | |
| const STG_E_INUSE = &h80030100& | |
| const STG_E_NOTCURRENT = &h80030101& | |
| const STG_E_CANTSAVE = &h80030103& | |
| const REGDB_E_CLASSNOTREG = &h80040154& | |
| const MK_E_UNAVAILABLE = &h800401E3& | |
| const MK_E_INVALIDEXTENSION = &h800401E6& | |
| const MK_E_CANTOPENFILE = &h800401EA& | |
| const CO_E_CLASSSTRING = &h800401F3& | |
| const CO_E_APPNOTFOUND = &h800401F5& | |
| const O_E_APPDIDNTREG = &h800401FE& | |
| const E_ACCESSDENIED = &h80070005& | |
| const E_OUTOFMEMORY = &h8007000E& | |
| const E_INVALIDARG = &h80070057& | |
| const RPC_S_SERVER_UNAVAILABLE = &h800706BA& | |
| const CO_E_SERVER_EXEC_FAILURE = &h80080005& | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| call ok(getVT(Err.Number) = "VT_I4", "getVT(Err.Number) = " & getVT(Err.Number)) | |
| dim calledFunc | |
| sub returnTrue | |
| calledFunc = true | |
| returnTrue = true | |
| end sub | |
| sub testThrow | |
| on error resume next | |
| dim x, y | |
| call throwInt(1000) | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| call throwInt(E_TESTERROR) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call throwInt(1000) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call Err.clear() | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| x = 6 | |
| calledFunc = false | |
| x = throwInt(E_TESTERROR) and returnTrue() | |
| call ok(x = 6, "x = " & x) | |
| call ok(not calledFunc, "calledFunc = " & calledFunc) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = false | |
| call Err.clear() | |
| if false and throwInt(E_TESTERROR) then | |
| x = true | |
| else | |
| call ok(false, "unexpected if else branch on throw") | |
| end if | |
| call ok(x, "if branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = false | |
| call Err.clear() | |
| if throwInt(E_TESTERROR) then x = true | |
| call ok(x, "if branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = false | |
| call Err.clear() | |
| if false then | |
| call ok(false, "unexpected if else branch on throw") | |
| elseif throwInt(E_TESTERROR) then | |
| x = true | |
| else | |
| call ok(false, "unexpected if else branch on throw") | |
| end if | |
| call ok(x, "elseif branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call Err.clear() | |
| if true then | |
| call throwInt(E_TESTERROR) | |
| else | |
| call ok(false, "unexpected if else branch on throw") | |
| end if | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = false | |
| call Err.clear() | |
| do while throwInt(E_TESTERROR) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = true | |
| exit do | |
| loop | |
| call ok(x, "if branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = 0 | |
| call Err.clear() | |
| do | |
| x = x+1 | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| loop while throwInt(E_TESTERROR) | |
| call ok(x = 1, "if branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = 0 | |
| call Err.clear() | |
| do | |
| x = x+1 | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| loop until throwInt(E_TESTERROR) | |
| call ok(x = 1, "if branch not taken") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call Err.clear() | |
| x = 0 | |
| while x < 2 | |
| x = x+1 | |
| call throwInt(E_TESTERROR) | |
| wend | |
| call ok(x = 2, "x = " & x) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call Err.clear() | |
| x = 2 | |
| y = 0 | |
| for each x in throwInt(E_TESTERROR) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| y = y+1 | |
| next | |
| call ok(x = 2, "x = " & x) | |
| call ok(y = 1, "y = " & y) | |
| 'todo_wine call ok(Err.Number = VB_E_OBJNOTCOLLECTION, "Err.Number = " & Err.Number) | |
| Err.clear() | |
| y = 0 | |
| x = 6 | |
| for x = throwInt(E_TESTERROR) to 100 | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| call ok(x = 6, "x = " & x) | |
| y = y+1 | |
| next | |
| call ok(y = 1, "y = " & y) | |
| call ok(x = 6, "x = " & x) | |
| 'todo_wine call ok(Err.Number = VB_E_FORLOOPNOTINITIALIZED, "Err.Number = " & Err.Number) | |
| Err.clear() | |
| y = 0 | |
| x = 6 | |
| for x = 100 to throwInt(E_TESTERROR) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| 'todo_wine call ok(x = 6, "x = " & x) | |
| y = y+1 | |
| next | |
| call ok(y = 1, "y = " & y) | |
| 'todo_wine call ok(x = 6, "x = " & x) | |
| 'todo_wine call ok(Err.Number = VB_E_FORLOOPNOTINITIALIZED, "Err.Number = " & Err.Number) | |
| select case throwInt(E_TESTERROR) | |
| case true | |
| call ok(false, "unexpected case true") | |
| case false | |
| call ok(false, "unexpected case false") | |
| case empty | |
| call ok(false, "unexpected case empty") | |
| case else | |
| call ok(false, "unexpected case else") | |
| end select | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| x = false | |
| select case false | |
| case true | |
| call ok(false, "unexpected case true") | |
| case throwInt(E_TESTERROR) | |
| x = true | |
| case else | |
| call ok(false, "unexpected case else") | |
| end select | |
| call ok(x, "case not executed") | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| 'Exception in non-trivial stack context | |
| for x = 1 to 1 | |
| for each y in collectionObj | |
| select case 3 | |
| case 1 | |
| call ok(false, "unexpected case") | |
| case throwInt(E_TESTERROR) | |
| exit for | |
| case 2 | |
| call ok(false, "unexpected case") | |
| end select | |
| next | |
| next | |
| end sub | |
| call testThrow | |
| dim x | |
| sub testOnError(resumeNext) | |
| if resumeNext then | |
| on error resume next | |
| else | |
| on error goto 0 | |
| end if | |
| x = 1 | |
| throwInt(E_TESTERROR) | |
| x = 2 | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| end sub | |
| sub callTestOnError(resumeNext) | |
| on error resume next | |
| call testOnError(resumeNext) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| end sub | |
| x = 0 | |
| call callTestOnError(true) | |
| call ok(x = 2, "x = " & x) | |
| x = 0 | |
| call callTestOnError(false) | |
| call ok(x = 1, "x = " & x) | |
| sub testOnErrorClear() | |
| on error resume next | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| throwInt(E_TESTERROR) | |
| call ok(Err.Number = E_TESTERROR, "Err.Number = " & Err.Number) | |
| on error goto 0 | |
| call ok(Err.Number = 0, "Err.Number = " & Err.Number) | |
| x = "ok" | |
| end sub | |
| call testOnErrorClear() | |
| call ok(x = "ok", "testOnErrorClear failed") | |
| sub testForEachError() | |
| on error resume next | |
| dim x, y | |
| y = false | |
| for each x in empty | |
| y = true | |
| next | |
| call ok(y, "for each not executed") | |
| 'todo_wine call ok(Err.Number = VB_E_OBJNOTCOLLECTION, "Err.Number = " & Err.Number) | |
| end sub | |
| call testForEachError() | |
| sub testHresMap(hres, code) | |
| on error resume next | |
| call Err.Clear() | |
| call throwInt(hres) | |
| call ok(Err.Number = code, "throw(" & hex(hres) & ") Err.Number = " & Err.Number) | |
| end sub | |
| testHresMap E_NOTIMPL, 445 | |
| testHresMap E_NOINTERFACE, 430 | |
| testHresMap DISP_E_UNKNOWNINTERFACE, 438 | |
| testHresMap DISP_E_MEMBERNOTFOUND, 438 | |
| testHresMap DISP_E_PARAMNOTFOUND, 448 | |
| testHresMap DISP_E_TYPEMISMATCH, 13 | |
| testHresMap DISP_E_UNKNOWNNAME, 438 | |
| testHresMap DISP_E_NONAMEDARGS, 446 | |
| testHresMap DISP_E_BADVARTYPE, 458 | |
| testHresMap DISP_E_OVERFLOW, 6 | |
| testHresMap DISP_E_BADINDEX, 9 | |
| testHresMap DISP_E_UNKNOWNLCID, 447 | |
| testHresMap DISP_E_ARRAYISLOCKED, 10 | |
| testHresMap DISP_E_BADPARAMCOUNT, 450 | |
| testHresMap DISP_E_PARAMNOTOPTIONAL, 449 | |
| testHresMap DISP_E_NOTACOLLECTION, 451 | |
| testHresMap TYPE_E_DLLFUNCTIONNOTFOUND, 453 | |
| testHresMap TYPE_E_TYPEMISMATCH, 13 | |
| testHresMap TYPE_E_OUTOFBOUNDS, 9 | |
| testHresMap TYPE_E_IOERROR, 57 | |
| testHresMap TYPE_E_CANTCREATETMPFILE, 322 | |
| testHresMap STG_E_FILENOTFOUND, 432 | |
| testHresMap STG_E_PATHNOTFOUND, 76 | |
| testHresMap STG_E_TOOMANYOPENFILES, 67 | |
| testHresMap STG_E_ACCESSDENIED, 70 | |
| testHresMap STG_E_INSUFFICIENTMEMORY, 7 | |
| testHresMap STG_E_NOMOREFILES, 67 | |
| testHresMap STG_E_DISKISWRITEPROTECTED, 70 | |
| testHresMap STG_E_WRITEFAULT, 57 | |
| testHresMap STG_E_READFAULT, 57 | |
| testHresMap STG_E_SHAREVIOLATION, 75 | |
| testHresMap STG_E_LOCKVIOLATION, 70 | |
| testHresMap STG_E_FILEALREADYEXISTS, 58 | |
| testHresMap STG_E_MEDIUMFULL, 61 | |
| testHresMap STG_E_INVALIDNAME, 53 | |
| testHresMap STG_E_INUSE, 70 | |
| testHresMap STG_E_NOTCURRENT, 70 | |
| testHresMap STG_E_CANTSAVE, 57 | |
| testHresMap REGDB_E_CLASSNOTREG, 429 | |
| testHresMap MK_E_UNAVAILABLE, 429 | |
| testHresMap MK_E_INVALIDEXTENSION, 432 | |
| testHresMap MK_E_CANTOPENFILE, 432 | |
| testHresMap CO_E_CLASSSTRING, 429 | |
| testHresMap CO_E_APPNOTFOUND, 429 | |
| testHresMap O_E_APPDIDNTREG, 429 | |
| testHresMap E_ACCESSDENIED, 70 | |
| testHresMap E_OUTOFMEMORY, 7 | |
| testHresMap E_INVALIDARG, 5 | |
| testHresMap RPC_S_SERVER_UNAVAILABLE, 462 | |
| testHresMap CO_E_SERVER_EXEC_FAILURE, 429 | |
| sub testVBErrorCodes() | |
| on error resume next | |
| Err.clear() | |
| throwInt(&h800a00aa&) | |
| call ok(Err.number = 170, "Err.number = " & Err.number) | |
| Err.clear() | |
| throwInt(&h800a10aa&) | |
| call ok(Err.number = 4266, "Err.number = " & Err.number) | |
| end sub | |
| call testVBErrorCodes | |
| call reportSuccess() |