Back to index

lightning-sunbird  0.9+nobinonly
TestXPC.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   IBM Corp.
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /* API tests for XPConnect - use xpcshell for JS tests. */
00042 
00043 #include <stdio.h>
00044 
00045 #include "nsIXPConnect.h"
00046 #include "nsIScriptError.h"
00047 #include "nsIServiceManager.h"
00048 #include "nsIComponentManager.h"
00049 #include "nsIComponentRegistrar.h"
00050 #include "nsIJSContextStack.h"
00051 #include "nsIJSRuntimeService.h"
00052 #include "nsMemory.h"
00053 #include "nsIXPCSecurityManager.h"
00054 #include "nsICategoryManager.h"
00055 #include "nsString.h"
00056 #include "nsIVariant.h"
00057 
00058 #include "jsapi.h"
00059 
00060 #include "xpctest.h"
00061 
00062 /***************************************************************************/
00063 // host support for jsengine
00064 
00065 FILE *gOutFile = NULL;
00066 FILE *gErrFile = NULL;
00067 
00068 JS_STATIC_DLL_CALLBACK(JSBool)
00069 Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
00070 {
00071     uintN i, n;
00072     JSString *str;
00073 
00074     for (i = n = 0; i < argc; i++) {
00075         str = JS_ValueToString(cx, argv[i]);
00076         if (!str)
00077             return JS_FALSE;
00078         fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str));
00079     }
00080     n++;
00081     if (n)
00082         fputc('\n', gOutFile);
00083     return JS_TRUE;
00084 }
00085 
00086 JS_STATIC_DLL_CALLBACK(JSBool)
00087 Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
00088 {
00089     uintN i;
00090     JSString *str;
00091     const char *filename;
00092     JSScript *script;
00093     JSBool ok;
00094     jsval result;
00095 
00096     for (i = 0; i < argc; i++) {
00097         str = JS_ValueToString(cx, argv[i]);
00098         if (!str)
00099             return JS_FALSE;
00100         argv[i] = STRING_TO_JSVAL(str);
00101         filename = JS_GetStringBytes(str);
00102         script = JS_CompileFile(cx, obj, filename);
00103         if (!script)
00104             ok = JS_FALSE;
00105         else {
00106             ok = JS_ExecuteScript(cx, obj, script, &result);
00107             JS_DestroyScript(cx, script);
00108         }
00109         if (!ok)
00110             return JS_FALSE;
00111     }
00112     return JS_TRUE;
00113 }
00114 
00115 static JSFunctionSpec glob_functions[] = {
00116     {"print",           Print,          0},
00117     {"load",            Load,           1},
00118     {0}
00119 };
00120 
00121 static JSClass global_class = {
00122     "global", 0,
00123     JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
00124     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub
00125 };
00126 
00127 JS_STATIC_DLL_CALLBACK(void)
00128 my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
00129 {
00130     printf(message);
00131 }
00132 
00133 /***************************************************************************/
00134 // Foo class for used with some of the tests
00135 
00136 class nsTestXPCFoo : public nsITestXPCFoo2
00137 {
00138     NS_DECL_ISUPPORTS
00139     NS_DECL_NSITESTXPCFOO
00140 
00141     nsTestXPCFoo();
00142     virtual ~nsTestXPCFoo();
00143     char* mFoo;
00144 };
00145 
00146 NS_IMETHODIMP nsTestXPCFoo::Test(int p1, int p2, int* retval)
00147 {
00148 //    printf("nsTestXPCFoo::Test called with p1 = %d and p2 = %d\n", p1, p2);
00149     *retval = p1+p2;
00150     return NS_OK;
00151 }
00152 NS_IMETHODIMP nsTestXPCFoo::Test2()
00153 {
00154 //    printf("nsTestXPCFoo::Test2 called ");
00155     return NS_OK;
00156 }
00157 
00158 NS_IMETHODIMP nsTestXPCFoo::GetFoo(char * *aFoo)
00159 {
00160 //    printf("nsTestXPCFoo::Get called ");
00161     if(!aFoo)
00162         return NS_ERROR_NULL_POINTER;
00163     if(mFoo)
00164         *aFoo = (char*) nsMemory::Clone(mFoo, strlen(mFoo)+1);
00165     else
00166         *aFoo = NULL;
00167     return NS_OK;
00168 }
00169 
00170 NS_IMETHODIMP nsTestXPCFoo::SetFoo(const char * aFoo)
00171 {
00172 //    printf("nsTestXPCFoo::Set called ");
00173     if(mFoo)
00174     {
00175         nsMemory::Free(mFoo);
00176         mFoo = NULL;
00177     }
00178     if(aFoo)
00179         mFoo = (char*) nsMemory::Clone(aFoo, strlen(aFoo)+1);
00180     return NS_OK;
00181 }
00182 
00183 NS_IMPL_ISUPPORTS2(nsTestXPCFoo, nsITestXPCFoo, nsITestXPCFoo2)
00184 
00185 nsTestXPCFoo::nsTestXPCFoo()
00186     : mFoo(NULL)
00187 {
00188     NS_ADDREF_THIS();
00189 }
00190 
00191 nsTestXPCFoo::~nsTestXPCFoo()
00192 {
00193     if(mFoo)
00194         nsMemory::Free(mFoo);
00195 }
00196 
00197 /***************************************************************************/
00198 // test for nsIXPCSecurityManager
00199 
00200 class MySecMan : public nsIXPCSecurityManager
00201 {
00202 public:
00203   NS_DECL_ISUPPORTS
00204   NS_DECL_NSIXPCSECURITYMANAGER
00205 
00206   enum Mode { OK_ALL    ,
00207               VETO_ALL
00208             };
00209 
00210   void SetMode(Mode mode) {mMode = mode;}
00211 
00212   MySecMan();
00213 
00214 private:
00215   Mode mMode;
00216 };
00217 
00218 NS_IMPL_ISUPPORTS1(MySecMan, nsIXPCSecurityManager)
00219 
00220 MySecMan::MySecMan()
00221     : mMode(OK_ALL)
00222 {
00223     NS_ADDREF_THIS();
00224 }
00225 
00226 NS_IMETHODIMP
00227 MySecMan::CanCreateWrapper(JSContext * aJSContext, const nsIID & aIID, nsISupports *aObj, nsIClassInfo *aClassInfo, void * *aPolicy)
00228 {
00229     switch(mMode)
00230     {
00231         case OK_ALL:
00232             return NS_OK;
00233         case VETO_ALL:
00234             JS_SetPendingException(aJSContext,
00235                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
00236                     "security exception")));
00237             return NS_ERROR_FAILURE;
00238         default:
00239             NS_ASSERTION(0,"bad case");
00240             return NS_OK;
00241     }
00242 }
00243 
00244 NS_IMETHODIMP
00245 MySecMan::CanCreateInstance(JSContext * aJSContext, const nsCID & aCID)
00246 {
00247     switch(mMode)
00248     {
00249         case OK_ALL:
00250             return NS_OK;
00251         case VETO_ALL:
00252             JS_SetPendingException(aJSContext,
00253                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
00254                     "security exception")));
00255             return NS_ERROR_FAILURE;
00256         default:
00257             NS_ASSERTION(0,"bad case");
00258             return NS_OK;
00259     }
00260 }
00261 
00262 NS_IMETHODIMP
00263 MySecMan::CanGetService(JSContext * aJSContext, const nsCID & aCID)
00264 {
00265     switch(mMode)
00266     {
00267         case OK_ALL:
00268             return NS_OK;
00269         case VETO_ALL:
00270             JS_SetPendingException(aJSContext,
00271                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
00272                     "security exception")));
00273             return NS_ERROR_FAILURE;
00274         default:
00275             NS_ASSERTION(0,"bad case");
00276             return NS_OK;
00277     }
00278 }
00279 
00280 /* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in JSVal aName, inout voidPtr aPolicy); */
00281 NS_IMETHODIMP 
00282 MySecMan::CanAccess(PRUint32 aAction, nsIXPCNativeCallContext *aCallContext, JSContext * aJSContext, JSObject * aJSObject, nsISupports *aObj, nsIClassInfo *aClassInfo, jsval aName, void * *aPolicy)
00283 {
00284     switch(mMode)
00285     {
00286         case OK_ALL:
00287             return NS_OK;
00288         case VETO_ALL:
00289             JS_SetPendingException(aJSContext,
00290                 STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
00291                     "security exception")));
00292             return NS_ERROR_FAILURE;
00293         default:
00294             NS_ASSERTION(0,"bad case");
00295             return NS_OK;
00296     }
00297 }
00298 
00299 /**********************************************/
00300 
00301 static void
00302 TestSecurityManager(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
00303 {
00304     const char* t;
00305     jsval rval;
00306     JSBool success = JS_TRUE;
00307     MySecMan* sm = new MySecMan();
00308     nsTestXPCFoo* foo = new nsTestXPCFoo();
00309 
00310     if(!sm || ! foo)
00311     {
00312         success = JS_FALSE;
00313         printf("FAILED to create object!\n");
00314         goto sm_test_done;
00315     }
00316 
00317     rval = JSVAL_FALSE;
00318     JS_SetProperty(jscontext, glob, "failed", &rval);
00319     printf("Individual SecurityManager tests...\n");
00320     if(NS_FAILED(xpc->SetSecurityManagerForJSContext(jscontext, sm,
00321                                         nsIXPCSecurityManager::HOOK_ALL)))
00322     {
00323         success = JS_FALSE;
00324         printf("SetSecurityManagerForJSContext FAILED!\n");
00325         goto sm_test_done;
00326     }
00327 
00328     printf("  build wrapper with veto: TEST NOT RUN\n");
00329 /*
00330     // This test is broken because xpconnect now detects that this is a
00331     // call from native code and lets it succeed without calling the security manager
00332 
00333     sm->SetMode(MySecMan::VETO_ALL);
00334     printf("  build wrapper with veto: ");
00335     if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, NS_GET_IID(nsITestXPCFoo2), &wrapper)))
00336     {
00337         success = JS_FALSE;
00338         printf("FAILED\n");
00339         NS_RELEASE(wrapper);
00340     }
00341     else
00342     {
00343         printf("passed\n");
00344     }
00345 */
00346     sm->SetMode(MySecMan::OK_ALL);
00347     printf("  build wrapper no veto: ");
00348     nsIXPConnectJSObjectHolder* holder;
00349     if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, 
00350                     NS_GET_IID(nsITestXPCFoo2), &holder)))
00351     {
00352         printf("passed\n");
00353         JSObject* obj;
00354         if(NS_SUCCEEDED(holder->GetJSObject(&obj)))
00355         {
00356             rval = OBJECT_TO_JSVAL(obj);
00357             JS_SetProperty(jscontext, glob, "foo", &rval);
00358         }
00359             
00360         NS_RELEASE(holder);
00361     }
00362     else
00363     {
00364         success = JS_FALSE;
00365         printf("FAILED\n");
00366     }
00367 
00368     sm->SetMode(MySecMan::OK_ALL);
00369     printf("  getService no veto: ");
00370     t = "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); print('passed');}catch(e){failed = true; print('FAILED');}";
00371     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00372 
00373     sm->SetMode(MySecMan::VETO_ALL);
00374     printf("  getService with veto: ");
00375     t = "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); failed = true; print('FAILED');}catch(e){print('passed');}";
00376     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00377 
00378 
00379     sm->SetMode(MySecMan::OK_ALL);
00380     printf("  createInstance no veto: ");
00381     t = "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); print('passed');}catch(e){failed = true; print('FAILED');}";
00382     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00383 
00384     sm->SetMode(MySecMan::VETO_ALL);
00385     printf("  getService with veto: ");
00386     t = "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); failed = true; print('FAILED');}catch(e){print('passed');}";
00387     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00388 
00389 
00390     sm->SetMode(MySecMan::OK_ALL);
00391     printf("  call method no veto: ");
00392     t = "try{foo.Test2(); print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
00393     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00394 
00395     sm->SetMode(MySecMan::VETO_ALL);
00396     printf("  call method with veto: ");
00397     t = "try{foo.Test2(); failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
00398     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00399 
00400 
00401     sm->SetMode(MySecMan::OK_ALL);
00402     printf("  get attribute no veto: ");
00403     t = "try{foo.Foo; print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
00404     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00405 
00406     sm->SetMode(MySecMan::VETO_ALL);
00407     printf("  get attribute with veto: ");
00408     t = "try{foo.Foo; failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
00409     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00410 
00411 
00412     sm->SetMode(MySecMan::OK_ALL);
00413     printf("  set attribute no veto: ");
00414     t = "try{foo.Foo = 0; print(' : passed');}catch(e){failed = true; print(' : FAILED');}";
00415     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00416 
00417     sm->SetMode(MySecMan::VETO_ALL);
00418     printf("  set attribute with veto: ");
00419     t = "try{foo.Foo = 0; failed = true; print(' : FAILED');}catch(e){print(' : passed');}";
00420     JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
00421 
00422 sm_test_done:
00423     success = success && JS_GetProperty(jscontext, glob, "failed", &rval) && JSVAL_TRUE != rval;
00424     printf("SecurityManager tests : %s\n", success ? "passed" : "FAILED");
00425     NS_IF_RELEASE(foo);
00426     xpc->SetSecurityManagerForJSContext(jscontext, nsnull, 0);
00427 }
00428 
00429 
00430 /***************************************************************************/
00431 // arg formatter test...
00432 
00433 static void
00434 TestArgFormatter(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
00435 {
00436     jsval* argv;
00437     void* mark;
00438 
00439     const char*                  a_in = "some string";
00440     nsCOMPtr<nsITestXPCFoo>      b_in = new nsTestXPCFoo();
00441     nsCOMPtr<nsIWritableVariant> c_in = do_CreateInstance("@mozilla.org/variant;1"); 
00442     static NS_NAMED_LITERAL_STRING(d_in, "foo bar");
00443     const char*                  e_in = "another meaningless chunck of text";
00444     
00445 
00446     char*                   a_out;
00447     nsCOMPtr<nsISupports>   b_out;
00448     nsCOMPtr<nsIVariant>    c_out;
00449     nsAutoString            d_out;
00450     char*                   e_out;
00451 
00452     nsCOMPtr<nsITestXPCFoo> specified;
00453     PRInt32                 val;
00454 
00455     printf("ArgumentFormatter test: ");
00456 
00457     if(!b_in || !c_in || NS_FAILED(c_in->SetAsInt32(5)))
00458     {
00459         printf(" failed to construct test objects -- FAILED!\n");
00460         return;
00461     }
00462 
00463     argv = JS_PushArguments(jscontext, &mark, "s %ip %iv %is s",
00464                             a_in, 
00465                             &NS_GET_IID(nsITestXPCFoo2), b_in.get(), 
00466                             c_in.get(),
00467                             NS_STATIC_CAST(const nsAString*, &d_in), 
00468                             e_in);
00469 
00470     if(!argv)
00471     {
00472         printf(" could not convert from native to JS -- FAILED!\n");
00473         return;
00474     }
00475 
00476     if(!JS_ConvertArguments(jscontext, 5, argv, "s %ip %iv %is s",
00477                             &a_out, 
00478                             NS_STATIC_CAST(nsISupports**, getter_AddRefs(b_out)), 
00479                             NS_STATIC_CAST(nsIVariant**, getter_AddRefs(c_out)),
00480                             NS_STATIC_CAST(nsAString*, &d_out), 
00481                             &e_out))
00482     {
00483         printf(" could not convert from JS to native -- FAILED!\n");
00484         goto out;
00485     }
00486 
00487     if(!b_out)
00488     {
00489         printf(" JS to native for %%ip returned NULL -- FAILED!\n");
00490         goto out;
00491     }
00492 
00493     specified = do_QueryInterface(b_out);
00494     if(!specified)
00495     {
00496         printf(" could not QI value JS to native returned -- FAILED!\n");
00497         goto out;
00498     }
00499 
00500     if(specified.get() != b_in.get())
00501     {
00502         printf(" JS to native returned wrong value -- FAILED!\n");
00503         goto out;
00504     }
00505 
00506     if(!c_out)
00507     {
00508         printf(" JS to native for %%iv returned NULL -- FAILED!\n");
00509         goto out;
00510     }
00511 
00512     if(NS_FAILED(c_out->GetAsInt32(&val)) || val != 5)
00513     {
00514         printf(" JS to native for %%iv holds wrong value -- FAILED!\n");
00515         goto out;
00516     }
00517 
00518     if(d_in != d_out)
00519     {
00520         printf(" JS to native for %%is returned the wrong value -- FAILED!\n");
00521         goto out;
00522     }
00523 
00524     if(!strcmp(a_in, a_out) && !strcmp(e_in, e_out))
00525         printf("passed\n");
00526     else
00527         printf(" conversion OK, but surrounding was mangled -- FAILED!\n");
00528 
00529 out:
00530     JS_PopArguments(jscontext, mark);
00531 }
00532 
00533 /***************************************************************************/
00534 // ThreadJSContextStack test
00535 
00536 static void
00537 TestThreadJSContextStack(JSContext* jscontext)
00538 {
00539 
00540     printf("ThreadJSContextStack tests...\n");
00541 
00542     nsresult rv;
00543     nsCOMPtr<nsIJSContextStack> stack = 
00544              do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
00545 
00546     if(NS_SUCCEEDED(rv))
00547     {
00548         PRInt32 count;
00549         PRInt32 base_count;
00550 
00551         if(NS_SUCCEEDED(stack->GetCount(&base_count)))
00552             printf("\tstack->GetCount() : passed\n");
00553         else
00554             printf("\tstack->GetCount() FAILED!\n");
00555 
00556         if(NS_FAILED(stack->Push(jscontext)))
00557             printf("\tstack->Push() FAILED!\n");
00558         else
00559             printf("\tstack->Push() passed\n");
00560 
00561         if(NS_SUCCEEDED(stack->GetCount(&count)))
00562             printf("\tstack->GetCount() : %s\n",
00563                     count == base_count+1 ? "passed" : "FAILED!");
00564         else
00565             printf("\tstack->GetCount() FAILED!\n");
00566 
00567         JSContext* testCX;
00568         if(NS_FAILED(stack->Peek(&testCX)))
00569             printf("\tstack->Peek() FAILED!\n");
00570 
00571         if(jscontext == testCX)
00572             printf("\tstack->Push/Peek : passed\n");
00573         else
00574             printf("\tstack->Push/Peek : FAILED\n");
00575 
00576         if(NS_FAILED(stack->Pop(&testCX)))
00577             printf("\tstack->Pop() FAILED!\n");
00578 
00579         if(jscontext == testCX)
00580             printf("\tstack->Push/Pop : passed\n");
00581         else
00582             printf("\tstack->Push/Pop : FAILED\n");
00583 
00584         if(NS_SUCCEEDED(stack->GetCount(&count)))
00585             printf("\tstack->GetCount() : %s\n",
00586                     count == base_count ? "passed" : "FAILED!");
00587         else
00588             printf("\tstack->GetCount() FAILED!\n");
00589     }
00590     else
00591         printf("\tFAILED to get nsThreadJSContextStack service!\n");
00592 }
00593 
00594 /***************************************************************************/
00595 
00596 static void ShowXPCException()
00597 {
00598     nsresult rv;
00599     nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
00600     if(NS_SUCCEEDED(rv) && xpc)
00601     {
00602         nsCOMPtr<nsIException> e;
00603         xpc->GetPendingException(getter_AddRefs(e));
00604         if(e)
00605         {
00606             char* str;
00607             rv = e->ToString(&str);
00608             if(NS_SUCCEEDED(rv) && str)
00609             {
00610                 printf(str);
00611                 printf("\n");
00612                 nsMemory::Free(str);
00613 
00614                 nsresult res;
00615                 e->GetResult(&res);
00616                 if(res == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS)
00617                 {
00618                     nsCOMPtr<nsISupports> data;
00619                     e->GetData(getter_AddRefs(data));
00620                     if(data)
00621                     {
00622                         nsCOMPtr<nsIScriptError> report = do_QueryInterface(data);
00623                         if(report)
00624                         {
00625                             nsCAutoString str2;
00626                             rv = report->ToString(str2);
00627                             if(NS_SUCCEEDED(rv))
00628                             {
00629                                 printf("%s\n", str2.get());
00630                             }                            
00631                         }                            
00632                     }                            
00633                     else        
00634                         printf("can't get data for pending XPC exception\n");    
00635                 }
00636             }
00637             else        
00638                 printf("can't get string for pending XPC exception\n");    
00639         }
00640         else        
00641             printf("no pending XPC exception\n");    
00642     }
00643     else
00644         printf("can't get xpconnect\n");    
00645 }
00646 
00647 static void TestCategoryManmager()
00648 {
00649     printf("\n");    
00650 
00651     nsresult rv;
00652     nsCOMPtr<nsICategoryManager> catman = 
00653              do_GetService("@mozilla.org/categorymanager;1", &rv);
00654     if(NS_SUCCEEDED(rv) && catman)
00655     {
00656         printf("got category manager\n");    
00657  
00658         nsCOMPtr<nsISimpleEnumerator> e;
00659         rv = catman->EnumerateCategory("foo", getter_AddRefs(e));
00660         if(NS_SUCCEEDED(rv) && e)
00661         {
00662             printf("got enumerator\n");
00663 
00664             nsCOMPtr<nsISupports> el;
00665             rv = e->GetNext(getter_AddRefs(el));
00666             if(NS_SUCCEEDED(rv) && el)
00667             {
00668                 printf("e.GetNext() succeeded\n");
00669             }
00670             else
00671             {
00672                 printf("e.GetNext() FAILED with result %0x\n", (int)rv);        
00673                 ShowXPCException();
00674             }
00675                         
00676         }
00677         else
00678             printf("get of enumerator FAILED with result %0x\n", (int)rv);        
00679     }
00680     else
00681         printf("!!! can't get category manager\n");    
00682 
00683 
00684     printf("\n");    
00685 }
00686 
00687 
00688 /***************************************************************************/
00689 /***************************************************************************/
00690 // our main...
00691 
00692 #define DIE(_msg) \
00693     PR_BEGIN_MACRO  \
00694         printf(_msg); \
00695         printf("\n"); \
00696         return 1; \
00697     PR_END_MACRO
00698 
00699 int main()
00700 {
00701     JSRuntime *rt;
00702     JSContext *jscontext;
00703     JSObject *glob;
00704     nsresult rv;
00705 
00706     gErrFile = stderr;
00707     gOutFile = stdout;
00708     {
00709         nsCOMPtr<nsIServiceManager> servMan;
00710         NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
00711         nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
00712         NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00713         if(registrar)
00714             registrar->AutoRegister(nsnull);
00715     
00716         // get the JSRuntime from the runtime svc, if possible
00717         nsCOMPtr<nsIJSRuntimeService> rtsvc =
00718                  do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
00719         if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt)
00720             DIE("FAILED to get a JSRuntime");
00721 
00722         jscontext = JS_NewContext(rt, 8192);
00723         if(!jscontext)
00724             DIE("FAILED to create a JSContext");
00725 
00726         JS_SetErrorReporter(jscontext, my_ErrorReporter);
00727 
00728         nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
00729         if(!xpc)
00730             DIE("FAILED to get xpconnect service\n");
00731 
00732         nsCOMPtr<nsIJSContextStack> cxstack =
00733                  do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
00734         if(NS_FAILED(rv))
00735             DIE("FAILED to get the nsThreadJSContextStack service!\n");
00736 
00737         if(NS_FAILED(cxstack->Push(jscontext)))
00738             DIE("FAILED to push the current jscontext on the nsThreadJSContextStack service!\n");
00739 
00740         // XXX I'd like to replace this with code that uses a wrapped xpcom object
00741         // as the global object. The old TextXPC did this. The support for this
00742         // is not working now in the new xpconnect code.
00743 
00744         glob = JS_NewObject(jscontext, &global_class, NULL, NULL);
00745         if (!glob)
00746             DIE("FAILED to create global object");
00747         if (!JS_InitStandardClasses(jscontext, glob))
00748             DIE("FAILED to init standard classes");
00749         if (!JS_DefineFunctions(jscontext, glob, glob_functions))
00750             DIE("FAILED to define global functions");
00751         if (NS_FAILED(xpc->InitClasses(jscontext, glob)))
00752             DIE("FAILED to init xpconnect classes");
00753 
00754         /**********************************************/
00755         // run the tests...
00756 
00757         TestCategoryManmager();
00758         TestSecurityManager(jscontext, glob, xpc);
00759         TestArgFormatter(jscontext, glob, xpc);
00760         TestThreadJSContextStack(jscontext);
00761 
00762         /**********************************************/
00763 
00764         if(NS_FAILED(cxstack->Pop(nsnull)))
00765             DIE("FAILED to pop the current jscontext from the nsThreadJSContextStack service!\n");
00766 
00767         JS_ClearScope(jscontext, glob);
00768         JS_GC(jscontext);
00769         JS_GC(jscontext);
00770         JS_DestroyContext(jscontext);
00771         xpc->SyncJSContexts();
00772         xpc->DebugDump(4);
00773 
00774         cxstack = nsnull;   // release service held by nsCOMPtr
00775         xpc     = nsnull;   // release service held by nsCOMPtr
00776         rtsvc   = nsnull;   // release service held by nsCOMPtr
00777     }
00778     rv = NS_ShutdownXPCOM( NULL );
00779     NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM FAILED");
00780 
00781     return 0;
00782 }
00783