Remove unused nParamNum values from JS method tables.
authorTom Sepez <tsepez@chromium.org>
Fri, 24 Apr 2015 00:50:57 +0000 (17:50 -0700)
committerTom Sepez <tsepez@chromium.org>
Fri, 24 Apr 2015 00:50:57 +0000 (17:50 -0700)
The code to validate the number of parameters happens inside each particular
method, rather than prior to method dispatch. As such, there's no point in
having this number take up space in the table.

Add some test to cover at least some of the per-method validations, and
update error messages to be more useful.

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1084183008

16 files changed:
fpdfsdk/include/javascript/JS_Define.h
fpdfsdk/include/javascript/resource.h
fpdfsdk/include/jsapi/fxjs_v8.h
fpdfsdk/src/javascript/Document.cpp
fpdfsdk/src/javascript/Field.cpp
fpdfsdk/src/javascript/PublicMethods.cpp
fpdfsdk/src/javascript/app.cpp
fpdfsdk/src/javascript/color.cpp
fpdfsdk/src/javascript/console.cpp
fpdfsdk/src/javascript/global.cpp
fpdfsdk/src/javascript/report.cpp
fpdfsdk/src/javascript/resource.cpp
fpdfsdk/src/javascript/util.cpp
fpdfsdk/src/jsapi/fxjs_v8.cpp
testing/resources/javascript/document_methods.in [new file with mode: 0644]
testing/resources/javascript/document_methods_expected.txt [new file with mode: 0644]

index 2a033d1..1c3c64e 100644 (file)
@@ -32,7 +32,6 @@ struct JSMethodSpec
 {
        const wchar_t* pName;
        v8::FunctionCallback pMethodCall;
-       unsigned nParamNum;
 };
 
 /* ====================================== PUBLIC DEFINE SPEC ============================================== */
@@ -48,8 +47,8 @@ struct JSMethodSpec
 #define END_JS_STATIC_PROP() {0, 0, 0}};
 
 #define BEGIN_JS_STATIC_METHOD(js_class_name) JSMethodSpec js_class_name::JS_Class_Methods[] = {
-#define JS_STATIC_METHOD_ENTRY(method_name, nargs) {JS_WIDESTRING(method_name), method_name##_static, nargs},
-#define END_JS_STATIC_METHOD() {0, 0, 0}};
+#define JS_STATIC_METHOD_ENTRY(method_name) {JS_WIDESTRING(method_name), method_name##_static},
+#define END_JS_STATIC_METHOD() {0, 0}};
 
 /* ======================================== PROP CALLBACK ============================================ */
 
@@ -194,7 +193,7 @@ int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
                }\
                for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
                {\
-                       if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName, JS_Class_Methods[k].pMethodCall, JS_Class_Methods[k].nParamNum) < 0) return -1;\
+                       if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName, JS_Class_Methods[k].pMethodCall) < 0) return -1;\
                }\
                return nObjDefnID;\
        }\
@@ -372,7 +371,7 @@ int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
 \
                for (int k=0, szk=sizeof(JS_Class_Methods)/sizeof(JSMethodSpec)-1; k<szk; k++)\
                {\
-                       if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName,JS_Class_Methods[k].pMethodCall,JS_Class_Methods[k].nParamNum)<0)return -1;\
+                       if (JS_DefineObjMethod(pRuntime, nObjDefnID,JS_Class_Methods[k].pName,JS_Class_Methods[k].pMethodCall)<0)return -1;\
                }\
                if (JS_DefineObjAllProperties(pRuntime, nObjDefnID, js_class_name::queryprop_##js_class_name##_static, js_class_name::getprop_##js_class_name##_static,js_class_name::putprop_##js_class_name##_static,js_class_name::delprop_##js_class_name##_static)<0) return -1;\
 \
@@ -419,7 +418,7 @@ static int Init(IJS_Runtime* pRuntime)
 #define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
 JSMethodSpec js_class_name::global_methods[] = {
 
-#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name,nargs) JS_STATIC_METHOD_ENTRY(method_name,nargs)
+#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) JS_STATIC_METHOD_ENTRY(method_name)
 
 #define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
 
@@ -430,8 +429,7 @@ int js_class_name::Init(IJS_Runtime* pRuntime)\
        {\
                if (JS_DefineGlobalMethod(pRuntime,\
                                js_class_name::global_methods[i].pName,\
-                               js_class_name::global_methods[i].pMethodCall,\
-                               js_class_name::global_methods[i].nParamNum\
+                               js_class_name::global_methods[i].pMethodCall\
                                ) < 0\
                        )return -1;\
        }\
index 8f0a250..88011f2 100644 (file)
@@ -28,6 +28,8 @@ class CJS_Context;
 #define IDS_STRING_JSPRINT2             25633
 #define IDS_STRING_JSNOGLOBAL           25635
 #define IDS_STRING_JSREADONLY           25636
+#define IDS_STRING_JSTYPEERROR          25637
+#define IDS_STRING_JSVALUEERROR         25638
 
 CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id);
 CFX_WideString JSFormatErrorString(const char* class_name,
index 739fd2d..a32ace6 100644 (file)
@@ -54,11 +54,11 @@ typedef void (*LP_DESTRUCTOR)(v8::Handle<v8::Object> obj);
 
 
 int                                                            JS_DefineObj(IJS_Runtime* pJSRuntime, const wchar_t* sObjName, FXJSOBJTYPE eObjType, LP_CONSTRUCTOR pConstructor, LP_DESTRUCTOR pDestructor, unsigned bApplyNew);
-int                                                            JS_DefineObjMethod(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall, unsigned nParamNum);
+int                                                            JS_DefineObjMethod(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall);
 int                                                            JS_DefineObjProperty(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sPropName, v8::AccessorGetterCallback pPropGet, v8::AccessorSetterCallback pPropPut);
 int                                                            JS_DefineObjAllProperties(IJS_Runtime* pJSRuntime, int nObjDefnID, v8::NamedPropertyQueryCallback pPropQurey, v8::NamedPropertyGetterCallback pPropGet, v8::NamedPropertySetterCallback pPropPut, v8::NamedPropertyDeleterCallback pPropDel);
 int                                                            JS_DefineObjConst(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sConstName, v8::Handle<v8::Value> pDefault);
-int                                                            JS_DefineGlobalMethod(IJS_Runtime* pJSRuntime, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall, unsigned nParamNum);
+int                                                            JS_DefineGlobalMethod(IJS_Runtime* pJSRuntime, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall);
 int                                                            JS_DefineGlobalConst(IJS_Runtime* pJSRuntime, const wchar_t* sConstName, v8::Handle<v8::Value> pDefault);
 
 void                                                   JS_InitialRuntime(IJS_Runtime* pJSRuntime,IFXJS_Runtime* pFXRuntime, IFXJS_Context* context, v8::Persistent<v8::Context>& v8PersistentContext);
index 00721bd..624cad7 100644 (file)
@@ -98,46 +98,46 @@ BEGIN_JS_STATIC_PROP(CJS_Document)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Document)
-       JS_STATIC_METHOD_ENTRY(addAnnot,0)
-       JS_STATIC_METHOD_ENTRY(addField, 4)
-       JS_STATIC_METHOD_ENTRY(addLink, 0)
-       JS_STATIC_METHOD_ENTRY(addIcon, 0)
-       JS_STATIC_METHOD_ENTRY(calculateNow, 0)
-       JS_STATIC_METHOD_ENTRY(closeDoc, 0)
-       JS_STATIC_METHOD_ENTRY(createDataObject, 0)
-       JS_STATIC_METHOD_ENTRY(deletePages, 2)
-       JS_STATIC_METHOD_ENTRY(exportAsText, 3)
-       JS_STATIC_METHOD_ENTRY(exportAsFDF, 6)
-       JS_STATIC_METHOD_ENTRY(exportAsXFDF, 5)
-       JS_STATIC_METHOD_ENTRY(extractPages, 3)
-       JS_STATIC_METHOD_ENTRY(getAnnot, 0)
-       JS_STATIC_METHOD_ENTRY(getAnnots, 2)
-       JS_STATIC_METHOD_ENTRY(getAnnot3D, 2)
-       JS_STATIC_METHOD_ENTRY(getAnnots3D, 1)
-       JS_STATIC_METHOD_ENTRY(getField, 1)
-       JS_STATIC_METHOD_ENTRY(getIcon, 0)
-       JS_STATIC_METHOD_ENTRY(getLinks, 0)
-       JS_STATIC_METHOD_ENTRY(getNthFieldName, 1)
-       JS_STATIC_METHOD_ENTRY(getOCGs, 0)
-       JS_STATIC_METHOD_ENTRY(getPageBox, 0)
-       JS_STATIC_METHOD_ENTRY(getPageNthWord, 3)
-       JS_STATIC_METHOD_ENTRY(getPageNthWordQuads, 2)
-       JS_STATIC_METHOD_ENTRY(getPageNumWords, 1)
-       JS_STATIC_METHOD_ENTRY(getPrintParams, 0)
-       JS_STATIC_METHOD_ENTRY(getURL, 2)
-       JS_STATIC_METHOD_ENTRY(importAnFDF, 1)
-       JS_STATIC_METHOD_ENTRY(importAnXFDF, 1)
-       JS_STATIC_METHOD_ENTRY(importTextData, 2)
-       JS_STATIC_METHOD_ENTRY(insertPages, 4)
-       JS_STATIC_METHOD_ENTRY(mailForm, 6)
-       JS_STATIC_METHOD_ENTRY(print, 9)
-       JS_STATIC_METHOD_ENTRY(removeField, 1)
-       JS_STATIC_METHOD_ENTRY(replacePages, 4)
-       JS_STATIC_METHOD_ENTRY(resetForm, 1)
-       JS_STATIC_METHOD_ENTRY(removeIcon, 0)
-       JS_STATIC_METHOD_ENTRY(saveAs, 5)
-       JS_STATIC_METHOD_ENTRY(submitForm, 23)
-       JS_STATIC_METHOD_ENTRY(mailDoc, 0)
+       JS_STATIC_METHOD_ENTRY(addAnnot)
+       JS_STATIC_METHOD_ENTRY(addField)
+       JS_STATIC_METHOD_ENTRY(addLink)
+       JS_STATIC_METHOD_ENTRY(addIcon)
+       JS_STATIC_METHOD_ENTRY(calculateNow)
+       JS_STATIC_METHOD_ENTRY(closeDoc)
+       JS_STATIC_METHOD_ENTRY(createDataObject)
+       JS_STATIC_METHOD_ENTRY(deletePages)
+       JS_STATIC_METHOD_ENTRY(exportAsText)
+       JS_STATIC_METHOD_ENTRY(exportAsFDF)
+       JS_STATIC_METHOD_ENTRY(exportAsXFDF)
+       JS_STATIC_METHOD_ENTRY(extractPages)
+       JS_STATIC_METHOD_ENTRY(getAnnot)
+       JS_STATIC_METHOD_ENTRY(getAnnots)
+       JS_STATIC_METHOD_ENTRY(getAnnot3D)
+       JS_STATIC_METHOD_ENTRY(getAnnots3D)
+       JS_STATIC_METHOD_ENTRY(getField)
+       JS_STATIC_METHOD_ENTRY(getIcon)
+       JS_STATIC_METHOD_ENTRY(getLinks)
+       JS_STATIC_METHOD_ENTRY(getNthFieldName)
+       JS_STATIC_METHOD_ENTRY(getOCGs)
+       JS_STATIC_METHOD_ENTRY(getPageBox)
+       JS_STATIC_METHOD_ENTRY(getPageNthWord)
+       JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
+       JS_STATIC_METHOD_ENTRY(getPageNumWords)
+       JS_STATIC_METHOD_ENTRY(getPrintParams)
+       JS_STATIC_METHOD_ENTRY(getURL)
+       JS_STATIC_METHOD_ENTRY(importAnFDF)
+       JS_STATIC_METHOD_ENTRY(importAnXFDF)
+       JS_STATIC_METHOD_ENTRY(importTextData)
+       JS_STATIC_METHOD_ENTRY(insertPages)
+       JS_STATIC_METHOD_ENTRY(mailForm)
+       JS_STATIC_METHOD_ENTRY(print)
+       JS_STATIC_METHOD_ENTRY(removeField)
+       JS_STATIC_METHOD_ENTRY(replacePages)
+       JS_STATIC_METHOD_ENTRY(resetForm)
+       JS_STATIC_METHOD_ENTRY(removeIcon)
+       JS_STATIC_METHOD_ENTRY(saveAs)
+       JS_STATIC_METHOD_ENTRY(submitForm)
+       JS_STATIC_METHOD_ENTRY(mailDoc)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Document, Document)
@@ -321,58 +321,51 @@ FX_BOOL Document::exportAsXFDF(IFXJS_Context* cc, const CJS_Parameters& params,
 
 FX_BOOL Document::getField(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
-       v8::Isolate* isolate = GetIsolate(cc);
-       ASSERT(m_pDocument != NULL);
-
-       if (params.size() < 1) return FALSE;
+       CJS_Context* pContext = (CJS_Context*)cc;
+       if (params.size() < 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
 
        CFX_WideString wideName = params[0].ToCFXWideString();
 
        CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
-       ASSERT(pInterForm != NULL);
-
        CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-       ASSERT(pPDFForm != NULL);
-
        if (pPDFForm->CountFields(wideName) <= 0)
        {
                vRet.SetNull();
                return TRUE;
        }
 
-       CJS_Context* pContext = (CJS_Context*)cc;
-       ASSERT(pContext != NULL);
        CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-       ASSERT(pRuntime != NULL);
-
-       JSFXObject  pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));
-
-       CJS_Field * pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj);
-       ASSERT(pJSField != NULL);
-
-       Field * pField = (Field *)pJSField->GetEmbedObject();
-       ASSERT(pField != NULL);
+       JSFXObject pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));
 
+       v8::Isolate* isolate = GetIsolate(cc);
+       CJS_Field* pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj);
+       Field* pField = (Field *)pJSField->GetEmbedObject();
        pField->AttachField(this, wideName);
-       vRet = pJSField;
 
+       vRet = pJSField;
        return TRUE;
 }
 
 //Gets the name of the nth field in the document
 FX_BOOL Document::getNthFieldName(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
-       ASSERT(m_pDocument != NULL);
+       CJS_Context* pContext = (CJS_Context*)cc;
+       if (params.size() != 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
 
-       int nIndex = params.size() > 0 ? params[0].ToInt() : -1;
-       if (nIndex == -1) return FALSE;
+       int nIndex = params[0].ToInt();
+       if (nIndex < 0) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
+               return FALSE;
+       }
 
        CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
-       ASSERT(pInterForm != NULL);
-
        CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-       ASSERT(pPDFForm != NULL);
-
        CPDF_FormField* pField = pPDFForm->GetField(nIndex);
        if (!pField)
                return FALSE;
@@ -523,11 +516,13 @@ FX_BOOL Document::removeField(IFXJS_Context* cc, const CJS_Parameters& params, C
        if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
                m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM))) return FALSE;
 
-       if (params.size() < 1)
-               return TRUE;
+       CJS_Context* pContext = (CJS_Context*)cc;
+       if (params.size() != 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
 
        CFX_WideString sFieldName = params[0].ToCFXWideString();
-
        CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
        ASSERT(pInterForm != NULL);
 
@@ -641,11 +636,12 @@ FX_BOOL Document::saveAs(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Va
 FX_BOOL Document::submitForm(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
        ASSERT(m_pDocument != NULL);
-
-//     if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
-
+       CJS_Context* pContext = (CJS_Context*)cc;
        int nSize = params.size();
-       if (nSize < 1) return FALSE;
+       if (nSize < 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
 
        CFX_WideString strURL;
        FX_BOOL bFDF = TRUE;
@@ -1457,22 +1453,28 @@ void IconTree::DeleteIconElement(CFX_WideString swIconName)
 
 FX_BOOL Document::addIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
-       if (params.size() != 2)return FALSE;
-
        CJS_Context* pContext = (CJS_Context*)cc;
-       ASSERT(pContext != NULL);
-       CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-       ASSERT(pRuntime != NULL);
+       if (params.size() != 2) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
 
        CFX_WideString swIconName = params[0].ToCFXWideString();
-
        JSFXObject pJSIcon = params[1].ToV8Object();
-       if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) return FALSE;
+
+       CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+       if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
+               return FALSE;
+       }
 
        CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
-       if (!pEmbedObj)return FALSE;
-       Icon* pIcon = (Icon*)pEmbedObj;
+       if (!pEmbedObj) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
+               return FALSE;
+       }
 
+       Icon* pIcon = (Icon*)pEmbedObj;
        if (!m_pIconTree)
                m_pIconTree = new IconTree();
 
@@ -1529,13 +1531,17 @@ FX_BOOL Document::icons(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sE
 
 FX_BOOL Document::getIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
-       if (params.size() != 1)return FALSE;
+       CJS_Context* pContext = (CJS_Context *)cc;
+       if (params.size() != 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
+
        if(!m_pIconTree)
                return FALSE;
        CFX_WideString swIconName = params[0].ToCFXWideString();
        int iIconCounts = m_pIconTree->GetLength();
 
-       CJS_Context* pContext = (CJS_Context *)cc;
        CJS_Runtime* pRuntime = pContext->GetJSRuntime();
 
        for (int i = 0; i < iIconCounts; i++)
@@ -1565,7 +1571,12 @@ FX_BOOL Document::getIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_V
 
 FX_BOOL Document::removeIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
-       if (params.size() != 1)return FALSE;
+       CJS_Context* pContext = (CJS_Context *)cc;
+       if (params.size() != 1) {
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               return FALSE;
+       }
+
        if(!m_pIconTree)
                return FALSE;
        CFX_WideString swIconName = params[0].ToCFXWideString();
@@ -1615,10 +1626,10 @@ FX_BOOL Document::getPageNthWord(IFXJS_Context* cc, const CJS_Parameters& params
        CPDF_Document* pDocument = m_pDocument->GetDocument();
        if (!pDocument) return FALSE;
 
+       CJS_Context* pContext = static_cast<CJS_Context*>(cc);
        if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
        {
-               CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
                return FALSE;
        }
 
@@ -1685,10 +1696,10 @@ FX_BOOL Document::getPageNumWords(IFXJS_Context* cc, const CJS_Parameters& param
        CPDF_Document* pDocument = m_pDocument->GetDocument();
        ASSERT(pDocument != NULL);
 
+       CJS_Context* pContext = static_cast<CJS_Context*>(cc);
        if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
        {
-               CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-               sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
+               sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
                return FALSE;
        }
 
@@ -1724,13 +1735,12 @@ FX_BOOL Document::getPageNumWords(IFXJS_Context* cc, const CJS_Parameters& param
 FX_BOOL Document::getPrintParams(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
 {
        CJS_Context* pContext = (CJS_Context*)cc;
-       ASSERT(pContext != NULL);
        CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-       ASSERT(pRuntime != NULL);
        JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"));
-       //not implemented yet.
-       vRet = pRetObj;
 
+       // Not implemented yet.
+
+       vRet = pRetObj;
        return TRUE;
 }
 
index 36bd1ca..e5572da 100644 (file)
@@ -81,32 +81,32 @@ BEGIN_JS_STATIC_PROP(CJS_Field)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Field)
-       JS_STATIC_METHOD_ENTRY(browseForFileToSubmit,      0)
-       JS_STATIC_METHOD_ENTRY(buttonGetCaption,           1)
-       JS_STATIC_METHOD_ENTRY(buttonGetIcon,              1)
-       JS_STATIC_METHOD_ENTRY(buttonImportIcon,           0)
-       JS_STATIC_METHOD_ENTRY(buttonSetCaption,           2)
-       JS_STATIC_METHOD_ENTRY(buttonSetIcon,              2)
-       JS_STATIC_METHOD_ENTRY(checkThisBox,               2)
-       JS_STATIC_METHOD_ENTRY(clearItems,                 0)
-       JS_STATIC_METHOD_ENTRY(defaultIsChecked,           2)
-       JS_STATIC_METHOD_ENTRY(deleteItemAt,               1)
-       JS_STATIC_METHOD_ENTRY(getArray ,                  0)
-       JS_STATIC_METHOD_ENTRY(getItemAt,                  0)
-       JS_STATIC_METHOD_ENTRY(getLock,                    0)
-       JS_STATIC_METHOD_ENTRY(insertItemAt,               0)
-       JS_STATIC_METHOD_ENTRY(isBoxChecked,               1)
-       JS_STATIC_METHOD_ENTRY(isDefaultChecked,           1)
-       JS_STATIC_METHOD_ENTRY(setAction,                  2)
-       JS_STATIC_METHOD_ENTRY(setFocus,                   0)
-       JS_STATIC_METHOD_ENTRY(setItems,                   1)
-       JS_STATIC_METHOD_ENTRY(setLock,                    0)
-       JS_STATIC_METHOD_ENTRY(signatureGetModifications,  0)
-       JS_STATIC_METHOD_ENTRY(signatureGetSeedValue,      0)
-       JS_STATIC_METHOD_ENTRY(signatureInfo,              0)
-       JS_STATIC_METHOD_ENTRY(signatureSetSeedValue,      0)
-       JS_STATIC_METHOD_ENTRY(signatureSign,              0)
-       JS_STATIC_METHOD_ENTRY(signatureValidate,          0)
+       JS_STATIC_METHOD_ENTRY(browseForFileToSubmit)
+       JS_STATIC_METHOD_ENTRY(buttonGetCaption)
+       JS_STATIC_METHOD_ENTRY(buttonGetIcon)
+       JS_STATIC_METHOD_ENTRY(buttonImportIcon)
+       JS_STATIC_METHOD_ENTRY(buttonSetCaption)
+       JS_STATIC_METHOD_ENTRY(buttonSetIcon)
+       JS_STATIC_METHOD_ENTRY(checkThisBox)
+       JS_STATIC_METHOD_ENTRY(clearItems)
+       JS_STATIC_METHOD_ENTRY(defaultIsChecked)
+       JS_STATIC_METHOD_ENTRY(deleteItemAt)
+       JS_STATIC_METHOD_ENTRY(getArray )
+       JS_STATIC_METHOD_ENTRY(getItemAt)
+       JS_STATIC_METHOD_ENTRY(getLock)
+       JS_STATIC_METHOD_ENTRY(insertItemAt)
+       JS_STATIC_METHOD_ENTRY(isBoxChecked)
+       JS_STATIC_METHOD_ENTRY(isDefaultChecked)
+       JS_STATIC_METHOD_ENTRY(setAction)
+       JS_STATIC_METHOD_ENTRY(setFocus)
+       JS_STATIC_METHOD_ENTRY(setItems)
+       JS_STATIC_METHOD_ENTRY(setLock)
+       JS_STATIC_METHOD_ENTRY(signatureGetModifications)
+       JS_STATIC_METHOD_ENTRY(signatureGetSeedValue)
+       JS_STATIC_METHOD_ENTRY(signatureInfo)
+       JS_STATIC_METHOD_ENTRY(signatureSetSeedValue)
+       JS_STATIC_METHOD_ENTRY(signatureSign)
+       JS_STATIC_METHOD_ENTRY(signatureValidate)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Field, Field)
index ff5b9a7..6a9839e 100644 (file)
@@ -36,28 +36,28 @@ static v8::Isolate* GetIsolate(IFXJS_Context* cc)
 #define DOUBLE_CORRECT 0.000000000000001
 
 BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format,6)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke,6)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format,2)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke,2)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple,3)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate,2)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate,4)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange,1)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx,2)
-       JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums,1)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
+       JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
 END_JS_STATIC_GLOBAL_FUN()
 
 IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
index 57d9cfe..2cb7f67 100644 (file)
@@ -93,27 +93,27 @@ BEGIN_JS_STATIC_PROP(CJS_App)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_App)
-       JS_STATIC_METHOD_ENTRY(alert, 6)
-       JS_STATIC_METHOD_ENTRY(beep, 1)
-       JS_STATIC_METHOD_ENTRY(browseForDoc, 0)
-       JS_STATIC_METHOD_ENTRY(clearInterval, 1)
-       JS_STATIC_METHOD_ENTRY(clearTimeOut, 1)
-       JS_STATIC_METHOD_ENTRY(execDialog, 3)
-       JS_STATIC_METHOD_ENTRY(execMenuItem,  1)
-       JS_STATIC_METHOD_ENTRY(findComponent, 1)
-       JS_STATIC_METHOD_ENTRY(goBack, 0)
-       JS_STATIC_METHOD_ENTRY(goForward, 0)
-       JS_STATIC_METHOD_ENTRY(launchURL, 0)
-       JS_STATIC_METHOD_ENTRY(mailMsg, 0)
-       JS_STATIC_METHOD_ENTRY(newFDF, 0)
-       JS_STATIC_METHOD_ENTRY(newDoc, 0)
-       JS_STATIC_METHOD_ENTRY(openDoc, 0)
-       JS_STATIC_METHOD_ENTRY(openFDF, 5)
-       JS_STATIC_METHOD_ENTRY(popUpMenuEx, 0)
-       JS_STATIC_METHOD_ENTRY(popUpMenu, 0)
-       JS_STATIC_METHOD_ENTRY(response, 0)
-       JS_STATIC_METHOD_ENTRY(setInterval, 2)
-       JS_STATIC_METHOD_ENTRY(setTimeOut, 2)
+       JS_STATIC_METHOD_ENTRY(alert)
+       JS_STATIC_METHOD_ENTRY(beep)
+       JS_STATIC_METHOD_ENTRY(browseForDoc)
+       JS_STATIC_METHOD_ENTRY(clearInterval)
+       JS_STATIC_METHOD_ENTRY(clearTimeOut)
+       JS_STATIC_METHOD_ENTRY(execDialog)
+       JS_STATIC_METHOD_ENTRY(execMenuItem)
+       JS_STATIC_METHOD_ENTRY(findComponent)
+       JS_STATIC_METHOD_ENTRY(goBack)
+       JS_STATIC_METHOD_ENTRY(goForward)
+       JS_STATIC_METHOD_ENTRY(launchURL)
+       JS_STATIC_METHOD_ENTRY(mailMsg)
+       JS_STATIC_METHOD_ENTRY(newFDF)
+       JS_STATIC_METHOD_ENTRY(newDoc)
+       JS_STATIC_METHOD_ENTRY(openDoc)
+       JS_STATIC_METHOD_ENTRY(openFDF)
+       JS_STATIC_METHOD_ENTRY(popUpMenuEx)
+       JS_STATIC_METHOD_ENTRY(popUpMenu)
+       JS_STATIC_METHOD_ENTRY(response)
+       JS_STATIC_METHOD_ENTRY(setInterval)
+       JS_STATIC_METHOD_ENTRY(setTimeOut)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_App,app)
index ddf6ed4..7f36be0 100644 (file)
@@ -45,8 +45,8 @@ BEGIN_JS_STATIC_PROP(CJS_Color)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Color)
-       JS_STATIC_METHOD_ENTRY(convert, 2)
-       JS_STATIC_METHOD_ENTRY(equal, 2)
+       JS_STATIC_METHOD_ENTRY(convert)
+       JS_STATIC_METHOD_ENTRY(equal)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Color,color)
index 9d67b4d..f130170 100644 (file)
@@ -22,10 +22,10 @@ BEGIN_JS_STATIC_PROP(CJS_Console)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Console)
-       JS_STATIC_METHOD_ENTRY(clear, 0)
-       JS_STATIC_METHOD_ENTRY(hide, 0)
-       JS_STATIC_METHOD_ENTRY(println, 1)
-       JS_STATIC_METHOD_ENTRY(show, 0)
+       JS_STATIC_METHOD_ENTRY(clear)
+       JS_STATIC_METHOD_ENTRY(hide)
+       JS_STATIC_METHOD_ENTRY(println)
+       JS_STATIC_METHOD_ENTRY(show)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Console,console)
index 6b5d5e2..c3d11b0 100644 (file)
@@ -91,7 +91,7 @@ BEGIN_JS_STATIC_PROP(CJS_Global)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Global)
-       JS_STATIC_METHOD_ENTRY(setPersistent, 2)
+       JS_STATIC_METHOD_ENTRY(setPersistent)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, global_alternate, global);
index 0f60f12..1478feb 100644 (file)
@@ -20,8 +20,8 @@ BEGIN_JS_STATIC_PROP(CJS_Report)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Report)
-       JS_STATIC_METHOD_ENTRY(save, 1)
-       JS_STATIC_METHOD_ENTRY(writeText,1)
+       JS_STATIC_METHOD_ENTRY(save)
+       JS_STATIC_METHOD_ENTRY(writeText)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Report, Report)
index be24ccd..4375da3 100644 (file)
@@ -43,6 +43,10 @@ CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id)
         return L"Global value not found.";
     case IDS_STRING_JSREADONLY:
         return L"Cannot assign to readonly property.";
+    case IDS_STRING_JSTYPEERROR:
+        return L"Incorrect parameter type.";
+    case IDS_STRING_JSVALUEERROR:
+        return L"Incorrect parameter value.";
     default:
         return L"";
     }
index 6898d0c..f7e97ac 100644 (file)
@@ -38,11 +38,11 @@ BEGIN_JS_STATIC_PROP(CJS_Util)
 END_JS_STATIC_PROP()
 
 BEGIN_JS_STATIC_METHOD(CJS_Util)
-       JS_STATIC_METHOD_ENTRY(printd, 3)
-       JS_STATIC_METHOD_ENTRY(printf, 20)
-       JS_STATIC_METHOD_ENTRY(printx, 2)
-       JS_STATIC_METHOD_ENTRY(scand, 2)
-       JS_STATIC_METHOD_ENTRY(byteToChar, 1)
+       JS_STATIC_METHOD_ENTRY(printd)
+       JS_STATIC_METHOD_ENTRY(printf)
+       JS_STATIC_METHOD_ENTRY(printx)
+       JS_STATIC_METHOD_ENTRY(scand)
+       JS_STATIC_METHOD_ENTRY(byteToChar)
 END_JS_STATIC_METHOD()
 
 IMPLEMENT_JS_CLASS(CJS_Util,util)
index 5a77713..c55c092 100644 (file)
@@ -90,7 +90,7 @@ int JS_DefineObj(IJS_Runtime* pJSRuntime, const wchar_t* sObjName, FXJSOBJTYPE e
        return pArray->GetSize()-1;
 }
 
-int JS_DefineObjMethod(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall, unsigned nParamNum)
+int JS_DefineObjMethod(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall)
 {
        v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
        v8::Isolate::Scope isolate_scope(isolate);
@@ -185,7 +185,7 @@ static v8::Persistent<v8::ObjectTemplate>& _getGlobalObjectTemplate(IJS_Runtime*
        return gloabalObjectTemplate;
 }
 
-int JS_DefineGlobalMethod(IJS_Runtime* pJSRuntime, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall, unsigned nParamNum)
+int JS_DefineGlobalMethod(IJS_Runtime* pJSRuntime, const wchar_t* sMethodName, v8::FunctionCallback pMethodCall)
 {
        v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
        v8::Isolate::Scope isolate_scope(isolate);
diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in
new file mode 100644 (file)
index 0000000..662c05c
--- /dev/null
@@ -0,0 +1,340 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 4
+  /Kids [
+    3 0 R
+    4 0 R
+    5 0 R
+    6 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Contents 8 0 R
+>>
+% Page number 1.
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+>>
+% Page number 2.
+{{object 5 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+>>
+% Page number 3.
+{{object 6 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+>>
+% Contents of the page.
+{{object 8 0}} <<
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+endstream
+endobj
+% Info
+{{object 9 0}} <<
+  /Author (Joe Random Author)
+  /Creator (Joe Random Creator)
+>>
+endobj
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+% JS program to exexute
+{{object 11 0}} <<
+>>
+stream
+function expect(str, expected) {
+  try {
+    var result = eval(str);
+    if (result == expected) {
+      app.alert('PASS: ' + str + ' = ' + result);
+    } else {
+      app.alert('FAIL: ' + str + ' = ' + result + ', expected = ' + expected);
+    }
+  } catch (e) {
+    app.alert('ERROR: ' + e.toString());
+  }
+}
+
+function expectError(str) {
+  try {
+    var result = eval(str);
+    app.alert('FAIL: ' + str + ' = ' + result + ', expected to throw error');
+  } catch (e) {
+    app.alert('PASS: ' + str + ' threw error ' + e.toString());
+  }
+}
+
+// "Unsupported" methods are present in the document object, but not
+// implemented. They always return |undefined| regardless of arguments.
+function testUnsupported(str) {
+  expect('typeof ' + str, 'function');
+  expect(str + '()', undefined);
+  expect(str + '(1, 2, "clams", [1, 2, 3])', undefined);
+}
+
+function testAddIcon() {
+   // Method is present.
+   expect('typeof this.addIcon', 'function');
+
+   // Method takes exactly two arguments.
+   expectError('this.addIcon()');
+   expectError('this.addIcon(1)');
+   expectError('this.addIcon(1, 2, 3)');
+
+   // Second argument must actually be an icon.
+   expectError('this.addIcon("myicon", 3)');
+
+   // TODO(tsepez): test success cases.
+}
+
+function testCalculateNow() {
+   // Method is present.
+   expect('typeof this.calculateNow', 'function');
+
+   // TODO(tsepez): test with no permissions.
+   // TODO(tsepez): test success cases.
+}
+
+function testDeletePages() {
+   // Method is present.
+   expect('typeof this.deletePages', 'function');
+
+   // TODO(tsepez): test with no permissions.
+   // TODO(tsepez): test success cases.
+}
+
+function testGetField() {
+   // Method is present.
+   expect('typeof this.getField', 'function');
+
+   // Method needs at least one argument.
+   expectError('this.getField()');
+
+   // TODO(tsepez): test success cases.
+}
+
+function testGetIcon() {
+   // Method is present.
+   expect('typeof this.getIcon', 'function');
+
+   // Method needs exactly one argument.
+   expectError('this.getIcon()');
+   expectError('this.getIcon(1, 2)');
+
+  // TODO(tsepez): test success cases.
+}
+
+function testGetNthFieldName() {
+  // Method is present.
+  expect('typeof this.getNthFieldName', 'function');
+
+  // Method needs at least one argument.
+  expectError('this.getNthFieldName()');
+
+  // Argument can not be negative.
+  expectError('this.getNthFieldName(-1)');
+
+  // TODO(tsepez): test success cases.
+}
+
+function testGetPageNthWord() {
+  // Method is present.
+  expect('typeof this.getPageNthWord', 'function');
+
+  // Method accepts any number of parameters.
+  expect('this.getPageNthWord(0, 0, true, "clams", [1, 2])', 'Hello,');
+
+  // Arguments can't be negative or out of range.
+  expectError('this.getPageNthWord(-1, 0, true)');
+  expectError('this.getPageNthWord(6, 0, true)');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testGetPageNthWordQuads() {
+   // Method is present.
+   expect('typeof this.getPageNthWordQuads', 'function');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testGetPageNumWords() {
+   // Method is present.
+   expect('typeof this.getPageNumWords', 'function');
+
+  // Method accepts any number of parameters.
+  expect('this.getPageNumWords(0, "clams", [1, 2])', 2);
+
+  // Arguments can't be negative or out of range.
+  expectError('this.getPageNumWords(-1)');
+  expectError('this.getPageNumWords(6)');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testGetPrintParams() {
+   // Method is present.
+   expect('typeof this.getPrintParams', 'function');
+
+  // TODO(tsepez): test success cases.
+}
+
+function testMailDoc() {
+   // Method is present.
+   expect('typeof this.mailDoc', 'function');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testMailForm() {
+   // Method is present.
+   expect('typeof this.mailForm', 'function');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testPrint() {
+   // Method is present.
+   expect('typeof this.print', 'function');
+
+  // TODO(tsepez): test success cases.
+}
+
+function testRemoveField() {
+  // Method is present.
+  expect('typeof this.removeField', 'function');
+
+  // Method requires at least one argument.
+  expectError('this.removeField()');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testRemoveIcon() {
+   // Method is present.
+   expect('typeof this.removeIcon', 'function');
+
+  // Method requires at least one argument.
+  expectError('this.removeIcon()');
+
+  // TODO(tsepez): test success cases.
+}
+
+function testResetForm() {
+   // Method is present.
+   expect('typeof this.resetForm', 'function');
+
+  // TODO(tsepez): test with no permissions.
+  // TODO(tsepez): test success cases.
+}
+
+function testSubmitForm() {
+   // Method is present.
+   expect('typeof this.submitForm', 'function');
+
+  // Method requires at least one argument.
+  expectError('this.submitForm()');
+
+  // TODO(tsepez): test success cases.
+}
+
+try {
+  app.alert('*** Testing Unsupported Methods ***');
+  testUnsupported('this.addAnnot');
+  testUnsupported('this.addField');
+  testUnsupported('this.addLink');
+  testUnsupported('this.closeDoc');
+  testUnsupported('this.createDataObject');
+  testUnsupported('this.exportAsFDF');
+  testUnsupported('this.exportAsText');
+  testUnsupported('this.exportAsXFDF');
+  testUnsupported('this.extractPages');
+  testUnsupported('this.getAnnot');
+  testUnsupported('this.getAnnot3D');
+  testUnsupported('this.getAnnots');
+  testUnsupported('this.getLinks');
+  testUnsupported('this.getOCGs');
+  testUnsupported('this.getPageBox');
+  testUnsupported('this.getURL');
+  testUnsupported('this.importAnFDF');
+  testUnsupported('this.importAnXFDF');
+  testUnsupported('this.importTextData');
+  testUnsupported('this.insertPages');
+  testUnsupported('this.replacePages');
+  testUnsupported('this.saveAs');
+
+  app.alert('*** Testing Supported Methods ***');
+  testAddIcon();
+  testCalculateNow();
+  testDeletePages();
+  testGetField();
+  testGetIcon();
+  testGetNthFieldName();
+  testGetPageNthWord();
+  testGetPageNthWordQuads();
+  testGetPageNumWords();
+  testGetPrintParams();
+  testMailDoc();
+  testMailForm();
+  testPrint();
+  testRemoveField();
+  testRemoveIcon();
+  testResetForm();
+  testSubmitForm();
+} catch (e) {
+  app.alert('FATAL: ' + e.toString());
+}
+endstream
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+  /Info 9 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/document_methods_expected.txt b/testing/resources/javascript/document_methods_expected.txt
new file mode 100644 (file)
index 0000000..445b48d
--- /dev/null
@@ -0,0 +1,103 @@
+Alert: *** Testing Unsupported Methods ***
+Alert: PASS: typeof this.addAnnot = function
+Alert: PASS: this.addAnnot() = undefined
+Alert: PASS: this.addAnnot(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.addField = function
+Alert: PASS: this.addField() = undefined
+Alert: PASS: this.addField(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.addLink = function
+Alert: PASS: this.addLink() = undefined
+Alert: PASS: this.addLink(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.closeDoc = function
+Alert: PASS: this.closeDoc() = undefined
+Alert: PASS: this.closeDoc(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.createDataObject = function
+Alert: PASS: this.createDataObject() = undefined
+Alert: PASS: this.createDataObject(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.exportAsFDF = function
+Alert: PASS: this.exportAsFDF() = undefined
+Alert: PASS: this.exportAsFDF(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.exportAsText = function
+Alert: PASS: this.exportAsText() = undefined
+Alert: PASS: this.exportAsText(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.exportAsXFDF = function
+Alert: PASS: this.exportAsXFDF() = undefined
+Alert: PASS: this.exportAsXFDF(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.extractPages = function
+Alert: PASS: this.extractPages() = undefined
+Alert: PASS: this.extractPages(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getAnnot = function
+Alert: PASS: this.getAnnot() = undefined
+Alert: PASS: this.getAnnot(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getAnnot3D = function
+Alert: PASS: this.getAnnot3D() = undefined
+Alert: PASS: this.getAnnot3D(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getAnnots = function
+Alert: PASS: this.getAnnots() = undefined
+Alert: PASS: this.getAnnots(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getLinks = function
+Alert: PASS: this.getLinks() = undefined
+Alert: PASS: this.getLinks(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getOCGs = function
+Alert: PASS: this.getOCGs() = undefined
+Alert: PASS: this.getOCGs(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getPageBox = function
+Alert: PASS: this.getPageBox() = undefined
+Alert: PASS: this.getPageBox(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.getURL = function
+Alert: PASS: this.getURL() = undefined
+Alert: PASS: this.getURL(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.importAnFDF = function
+Alert: PASS: this.importAnFDF() = undefined
+Alert: PASS: this.importAnFDF(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.importAnXFDF = function
+Alert: PASS: this.importAnXFDF() = undefined
+Alert: PASS: this.importAnXFDF(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.importTextData = function
+Alert: PASS: this.importTextData() = undefined
+Alert: PASS: this.importTextData(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.insertPages = function
+Alert: PASS: this.insertPages() = undefined
+Alert: PASS: this.insertPages(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.replacePages = function
+Alert: PASS: this.replacePages() = undefined
+Alert: PASS: this.replacePages(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: PASS: typeof this.saveAs = function
+Alert: PASS: this.saveAs() = undefined
+Alert: PASS: this.saveAs(1, 2, "clams", [1, 2, 3]) = undefined
+Alert: *** Testing Supported Methods ***
+Alert: PASS: typeof this.addIcon = function
+Alert: PASS: this.addIcon() threw error Document.addIcon: Incorrect number of parameters passed to function.
+Alert: PASS: this.addIcon(1) threw error Document.addIcon: Incorrect number of parameters passed to function.
+Alert: PASS: this.addIcon(1, 2, 3) threw error Document.addIcon: Incorrect number of parameters passed to function.
+Alert: PASS: this.addIcon("myicon", 3) threw error Document.addIcon: Incorrect parameter type.
+Alert: PASS: typeof this.calculateNow = function
+Alert: PASS: typeof this.deletePages = function
+Alert: PASS: typeof this.getField = function
+Alert: PASS: this.getField() threw error Document.getField: Incorrect number of parameters passed to function.
+Alert: PASS: typeof this.getIcon = function
+Alert: PASS: this.getIcon() threw error Document.getIcon: Incorrect number of parameters passed to function.
+Alert: PASS: this.getIcon(1, 2) threw error Document.getIcon: Incorrect number of parameters passed to function.
+Alert: PASS: typeof this.getNthFieldName = function
+Alert: PASS: this.getNthFieldName() threw error Document.getNthFieldName: Incorrect number of parameters passed to function.
+Alert: PASS: this.getNthFieldName(-1) threw error Document.getNthFieldName: Incorrect parameter value.
+Alert: PASS: typeof this.getPageNthWord = function
+Alert: PASS: this.getPageNthWord(0, 0, true, "clams", [1, 2]) = Hello,
+Alert: PASS: this.getPageNthWord(-1, 0, true) threw error Document.getPageNthWord: Incorrect parameter value.
+Alert: PASS: this.getPageNthWord(6, 0, true) threw error Document.getPageNthWord: Incorrect parameter value.
+Alert: PASS: typeof this.getPageNthWordQuads = function
+Alert: PASS: typeof this.getPageNumWords = function
+Alert: PASS: this.getPageNumWords(0, "clams", [1, 2]) = 2
+Alert: PASS: this.getPageNumWords(-1) threw error Document.getPageNumWords: Incorrect parameter value.
+Alert: PASS: this.getPageNumWords(6) threw error Document.getPageNumWords: Incorrect parameter value.
+Alert: PASS: typeof this.getPrintParams = function
+Alert: PASS: typeof this.mailDoc = function
+Alert: PASS: typeof this.mailForm = function
+Alert: PASS: typeof this.print = function
+Alert: PASS: typeof this.removeField = function
+Alert: PASS: this.removeField() threw error Document.removeField: Incorrect number of parameters passed to function.
+Alert: PASS: typeof this.removeIcon = function
+Alert: PASS: this.removeIcon() threw error Document.removeIcon: Incorrect number of parameters passed to function.
+Alert: PASS: typeof this.resetForm = function
+Alert: PASS: typeof this.submitForm = function
+Alert: PASS: this.submitForm() threw error Document.submitForm: Incorrect number of parameters passed to function.