Bug 522791. Add basic tests for NPN_SetException.
authorJonathan Griffin <jgriffin@mozilla.com>
Mon, 19 Oct 2009 14:00:59 -0700
changeset 34252 6c793e95c534f3cd0902e5f60532c427273beaea
parent 34251 3314dc670ff48b1420ee6564e15d98cd047c751c
child 34253 f55bc23654b930fa9a9cedd7b4a0caf349ebc4a0
push id115
push userbmcbride@mozilla.com
push dateMon, 19 Oct 2009 23:27:00 +0000
bugs522791
milestone1.9.3a1pre
Bug 522791. Add basic tests for NPN_SetException.
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/mochitest/test_npruntime_npnsetexception.html
modules/plugin/test/testplugin/README
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest.h
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/modules/plugin/test/mochitest/Makefile.in
@@ -43,16 +43,17 @@ relativesrcdir  = modules/plugin/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _MOCHITEST_FILES = \
 		test_npobject_getters.html \
 		test_npruntime_npninvoke.html \
 		test_npruntime_npninvokedefault.html \
+		test_npruntime_npnsetexception.html \
 		loremipsum.txt \
 		loremipsum_file.txt \
 		post.sjs \
 		pluginstream.js \
 		plugin_window.html \
 		test_pluginstream_err.html \
 		test_pluginstream_src.html \
 		test_pluginstream_geturl.html \
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_npruntime_npnsetexception.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+  <title>NPN_SetException Tests</title>
+  <script type="text/javascript" 
+          src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" 
+          src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" 
+        href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="runTests()">
+  <p id="display"></p>
+
+  <embed id="plugin1" type="application/x-test" width="400" height="100">
+  </embed>
+
+  <script class="testbody" type="application/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  function runTests() {
+    // test a single exception thrown in scriptable invoke
+    var plugin = document.getElementById("plugin1");
+    plugin.throwExceptionNextInvoke();
+    try {
+      plugin.npnInvokeTest("badFunction");
+      ok(false, "exception not thrown");
+    }
+    catch (e) {
+      is(e, "badFunction", "wrong exception thrown");
+    }
+    
+    // test multiple exceptions thrown in scriptable invokedefault
+    plugin.throwExceptionNextInvoke();
+    try {
+      plugin("first exception", "second exception");
+      ok(false, "exception not thrown");
+    }
+    catch (e) {
+      is(e, "second exception", "wrong exception thrown");
+    }    
+            
+    SimpleTest.finish();
+  }
+  </script>
+  
+  <div id="verbose">
+  </div>
+ </body>
+ </html>
--- a/modules/plugin/test/testplugin/README
+++ b/modules/plugin/test/testplugin/README
@@ -42,16 +42,26 @@ return true.  Otherwise, it will return 
 * npnInvokeDefaultTest(object, argument)
 Causes the plugin to call NPN_InvokeDefault on the specified object,
 with the specified argument.  Returns the result of the invocation.
 
 * getError()
 If an error has occurred during the last stream or npruntime function,
 this will return a string error message, otherwise it returns "pass".
 
+* throwExceptionNextInvoke()
+Sets a flag which causes the next call to a scriptable method to throw
+one or more exceptions.  If no parameters are passed to the next
+scriptable method call, it will cause a generic exception to be thrown. 
+Otherwise there will be one exception thrown per argument, with the argument
+used as the exception message.  Example:
+
+  plugin.throwExceptionNextInvoke();
+  plugin.npnInvokeTest("first exception message", "second exception message");
+
 * () - default method
 Returns a string consisting of the plugin name, concatenated with any 
 arguments passed to the method.
 
 == Private browsing ==
 
 The test plugin object supports the following scriptable methods:
 
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -80,16 +80,17 @@ static bool startWatchingInstanceCount(N
 static bool getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool unscheduleAllTimers(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static bool throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 
 static const NPUTF8* sPluginMethodIdentifierNames[] = {
   "npnInvokeTest",
   "npnInvokeDefaultTest",
   "setUndefinedValueTest",
   "identifierToStringTest",
   "timerTest",
   "queryPrivateModeState",
@@ -102,16 +103,17 @@ static const NPUTF8* sPluginMethodIdenti
   "getInstanceCount",
   "stopWatchingInstanceCount",
   "unscheduleAllTimers",
   "getLastMouseX",
   "getLastMouseY",
   "getError",
   "doInternalConsistencyCheck",
   "setColor",
+  "throwExceptionNextInvoke",
 };
 static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
 static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
   npnInvokeTest,
   npnInvokeDefaultTest,
   setUndefinedValueTest,
   identifierToStringTest,
   timerTest,
@@ -125,16 +127,17 @@ static const ScriptableFunction sPluginM
   getInstanceCount,
   stopWatchingInstanceCount,
   unscheduleAllTimers,
   getLastMouseX,
   getLastMouseY,
   getError,
   doInternalConsistencyCheck,
   setColor,
+  throwExceptionNextInvoke,
 };
 
 static const char* NPN_GetURLNotifyCookie = "NPN_GetURLNotify_Cookie";
 
 static const char* SUCCESS_STRING = "pass";
 
 static bool sIdentifiersInitialized = false;
 
@@ -443,16 +446,17 @@ NPP_New(NPMIMEType pluginType, NPP insta
   instanceData->testFunction = FUNCTION_NONE;
   instanceData->functionToFail = FUNCTION_NONE;
   instanceData->failureCode = 0;
   instanceData->streamChunkSize = 1024;
   instanceData->streamBuf = NULL;
   instanceData->streamBufSize = 0;
   instanceData->fileBuf = NULL;
   instanceData->fileBufSize = 0;
+  instanceData->throwOnNextInvoke = false;
   instanceData->testrange = NULL;
   instanceData->hasWidget = false;
   instanceData->npnNewStream = false;
   instanceData->writeCount = 0;
   instanceData->writeReadyCount = 0;
   memset(&instanceData->window, 0, sizeof(instanceData->window));
   instance->pdata = instanceData;
 
@@ -1139,16 +1143,22 @@ bool
 NPN_GetProperty(NPP instance,
                 NPObject *npobj,
                 NPIdentifier propertyName,
                 NPVariant *result)
 {
   return sBrowserFuncs->getproperty(instance, npobj, propertyName, result);
 }
 
+void
+NPN_SetException(NPObject *npobj, const NPUTF8 *message)
+{
+  return sBrowserFuncs->setexception(npobj, message);
+}
+
 //
 // npruntime object functions
 //
 
 NPObject*
 scriptableAllocate(NPP npp, NPClass* aClass)
 {
   TestNPObject* object = (TestNPObject*)NPN_MemAlloc(sizeof(TestNPObject));
@@ -1177,26 +1187,58 @@ scriptableHasMethod(NPObject* npobj, NPI
       return true;
   }
   return false;
 }
 
 bool
 scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
 {
+  NPP npp = static_cast<TestNPObject*>(npobj)->npp;
+  InstanceData* id = static_cast<InstanceData*>(npp->pdata);
+  if (id->throwOnNextInvoke) {
+    id->throwOnNextInvoke = false;
+    if (argCount == 0) {
+      NPN_SetException(npobj, NULL);
+    }
+    else {
+      for (uint32_t i = 0; i < argCount; i++) {
+        const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
+        NPN_SetException(npobj, argstr->UTF8Characters);
+      }
+    }
+    return false;
+  }
+  
   for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) {
     if (name == sPluginMethodIdentifiers[i])
       return sPluginMethodFunctions[i](npobj, args, argCount, result);
   }
   return false;
 }
 
 bool
 scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
 {
+  NPP npp = static_cast<TestNPObject*>(npobj)->npp;
+  InstanceData* id = static_cast<InstanceData*>(npp->pdata);
+  if (id->throwOnNextInvoke) {
+    id->throwOnNextInvoke = false;
+    if (argCount == 0) {
+      NPN_SetException(npobj, NULL);
+    }
+    else {
+      for (uint32_t i = 0; i < argCount; i++) {
+        const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
+        NPN_SetException(npobj, argstr->UTF8Characters);
+      }
+    }
+    return false;
+  }
+
   ostringstream value;
   value << PLUGIN_NAME;
   for (uint32_t i = 0; i < argCount; i++) {
     switch(args[i].type) {
       case NPVariantType_Int32:
         value << ";" << NPVARIANT_TO_INT32(args[i]);
         break;
       case NPVariantType_String: {
@@ -1362,16 +1404,26 @@ compareVariants(NPP instance, const NPVa
       id->err << "Unknown variant type";
       success = false;
   }
   
   return success;
 }
 
 static bool
+throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+  NPP npp = static_cast<TestNPObject*>(npobj)->npp;
+  InstanceData* id = static_cast<InstanceData*>(npp->pdata);
+  id->throwOnNextInvoke = true;
+  BOOLEAN_TO_NPVARIANT(true, *result);
+  return true;  
+}
+
+static bool
 npnInvokeDefaultTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
 {
   bool success = false;
   NPP npp = static_cast<TestNPObject*>(npobj)->npp;
  
   NPObject* windowObject;
   NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
   if (!windowObject)
--- a/modules/plugin/test/testplugin/nptest.h
+++ b/modules/plugin/test/testplugin/nptest.h
@@ -86,16 +86,17 @@ typedef struct InstanceData {
   NPP npp;
   NPWindow window;
   TestNPObject* scriptableObject;
   PlatformData* platformData;
   int32_t instanceCountWatchGeneration;
   bool lastReportedPrivateModeState;
   bool hasWidget;
   bool npnNewStream;
+  bool throwOnNextInvoke;
   uint32_t timerID1;
   uint32_t timerID2;
   int32_t lastMouseX;
   int32_t lastMouseY;
   int32_t writeCount;
   int32_t writeReadyCount;
   TestFunction testFunction;
   TestFunction functionToFail;