1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
4 * Copyright (C) 2007 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "xpcom-config.h"
25 #include "nsStringAPI.h"
26 #include "nsIComponentManager.h"
27 #include "nsComponentManagerUtils.h"
28 #include "nsServiceManagerUtils.h"
29 #include "nsIPrefBranch.h"
30 #include "nsIWindowWatcher.h"
31 #include "nsIDOMWindow.h"
32 #include "nsIDOMWindowCollection.h"
33 #include "nsIInterfaceRequestorUtils.h"
34 #include "nsIWebProgress.h"
35 #include "nsIDOMDocument.h"
36 #include "nsIDOMDocumentView.h"
37 #include "nsIDOMElement.h"
38 #include "nsIDOMEventTarget.h"
39 #include "nsIDOMDocumentEvent.h"
40 #include "nsIDOMEvent.h"
41 #include "nsIDOMAbstractView.h"
43 /* Unfrozen interfaces */
44 #include "nsAutoPtr.h"
45 #include "nsICommandLine.h"
46 #include "nsIWebNavigation.h"
47 #include "nsIAppStartup.h"
48 #include "nsIConsoleService.h"
49 #include "nsIConsoleMessage.h"
50 #include "nsIScriptError.h"
52 #include "nsIJSContextStack.h"
53 #include "nsIRDFService.h"
54 #include "nsIRDFDataSource.h"
55 #include "nsIRDFResource.h"
56 #include "nsIDOMXULDocument.h"
57 #include "nsIDOMXULCommandDispatcher.h"
58 #include "nsIDOMXULCommandEvent.h"
59 #include "nsIStringEnumerator.h"
62 /* Project includes */
63 #include "nsITestRunner.h"
64 #include "nsITestResult.h"
67 #include "nsTestRunner.h"
68 #include "nsTestFailure.h"
70 #include "nsTestUtils.h"
72 class nsFormatJSMessage
: public nsTestFailure
75 nsFormatJSMessage(nsIConsoleMessage
*aMessage
);
76 nsFormatJSMessage(const char *aFile
);
77 ~nsFormatJSMessage() {;}
79 nsresult
parseScriptError(nsIConsoleMessage
*aMessage
);
80 nsresult
formatErrorMessage(nsIScriptError
*error
);
81 PRBool
parseException(const nsACString
&aMessage
);
82 nsresult
getSourceFile();
83 nsresult
parseLocalFile();
84 nsresult
parseChrome();
86 nsRefPtr
<nsTestRunner
> mResolver
;
90 /******************** nsTestRunner ***********************************/
91 nsTestRunner::nsTestRunner()
92 :mTestTree(nsnull
), mArmed(PR_FALSE
), mHasWindow(PR_FALSE
)
96 nsTestRunner::~nsTestRunner()
100 nsTestRunner
* nsTestRunner::gTestRunner
= nsnull
;
102 NS_IMPL_THREADSAFE_ISUPPORTS7(nsTestRunner
,
105 nsIWebProgressListener
,
106 nsISupportsWeakReference
,
108 nsICommandLineHandler
,
112 nsTestRunner::MarkTestStart()
114 return mTestResult
->MarkTestStart();
118 nsTestRunner::AddFailure(const char *aFile
, PRUint32 aLine
, const char *aText
)
120 return mTestResult
->AddFailure(aFile
, aLine
, aText
, PR_FALSE
);
124 nsTestRunner::AddJSFailure(const char *aText
)
127 JSContext
*cx
= nsnull
;
131 mJSStack
= do_GetService("@mozilla.org/js/xpc/ContextStack;1");
132 NS_ENSURE_TRUE(mJSStack
, NS_ERROR_FAILURE
);
134 rv
= mJSStack
->Peek( &cx
);
135 NS_ENSURE_TRUE(cx
, NS_ERROR_FAILURE
);
137 nsFormatJSMessage
m(ns_test_js_caller_filename(cx
));
139 return mTestResult
->AddFailure(m
.getFile(),
140 ns_test_js_caller_lineno(cx
), aText
, PR_FALSE
);
144 nsTestRunner::AddError(PRUint32 aCode
, const char *aComment
)
146 return mTestResult
->AddFailure(nsnull
, aCode
, aComment
, PR_TRUE
);
150 nsTestRunner::MarkTestEnd(nsITest
*aTest
)
152 if (aTest
!= (nsITest
*) mTestTree
.Peek())
153 return NS_ERROR_ILLEGAL_VALUE
;
157 if(NS_FAILED(mTimer
->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT
)))
164 nsTestRunner::GetHasWindow(PRBool
*aHasWindow
)
166 NS_ENSURE_ARG_POINTER(aHasWindow
);
167 *aHasWindow
= mHasWindow
;
172 nsTestRunner::GetTestWindow(nsIDOMWindow
* *aTestWindow
)
174 NS_ENSURE_ARG_POINTER( aTestWindow
);
175 if ( !mTestWindow
) {
176 *aTestWindow
= nsnull
;
177 return NS_ERROR_NOT_INITIALIZED
;
179 *aTestWindow
= mTestWindow
;
180 NS_ADDREF( *aTestWindow
);
186 nsTestRunner::GetWatchWindow(nsIDOMWindow
* *aWatchWindow
)
188 NS_ENSURE_ARG_POINTER( aWatchWindow
);
189 if ( !mWatchWindow
) {
190 *aWatchWindow
= nsnull
;
191 return NS_ERROR_NOT_INITIALIZED
;
193 *aWatchWindow
= mWatchWindow
;
194 NS_ADDREF( *aWatchWindow
);
200 nsTestRunner::SetWatchWindow(nsIDOMWindow
*aWatchWindow
)
204 if (mWatchWindow
== aWatchWindow
)
206 if (mWatchWindow
&& !mHasWindow
)
209 NS_ENSURE_SUCCESS(rv
, rv
);
215 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(mWatchWindow
, &rv
));
216 NS_ENSURE_SUCCESS(rv
, rv
);
218 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
219 NS_ENSURE_SUCCESS(rv
, rv
);
221 rv
= webProgress
->RemoveProgressListener(this);
222 NS_ENSURE_SUCCESS(rv
, rv
);
224 mWatchWindow
= nsnull
;
228 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(aWatchWindow
, &rv
));
229 NS_ENSURE_SUCCESS(rv
, rv
);
231 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
232 NS_ENSURE_SUCCESS(rv
, rv
);
234 rv
= webProgress
->AddProgressListener(this,
235 nsIWebProgress::NOTIFY_STATE_WINDOW
);
236 NS_ENSURE_SUCCESS(rv
, rv
);
240 NS_ENSURE_SUCCESS(rv
, rv
);
243 mWatchWindow
= aWatchWindow
;
249 nsTestRunner::ArmTimer(PRUint32 aDelay
)
251 NS_ENSURE_TRUE(!mArmed
, NS_ERROR_ALREADY_INITIALIZED
);
254 rv
= mTimer
->InitWithCallback(this, aDelay
<< 1, nsITimer::TYPE_ONE_SHOT
);
255 NS_ENSURE_SUCCESS(rv
, rv
);
262 findElement(const nsAString
& aCommand
, nsIDOMWindow
*wnd
,
263 nsIDOMElement
**element
)
267 nsCOMPtr
<nsIDOMWindowCollection
> list
;
268 nsCOMPtr
<nsIDOMWindow
> next
;
269 nsCOMPtr
<nsIDOMDocument
> doc
;
272 rv
= wnd
->GetDocument(getter_AddRefs(doc
));
273 NS_ENSURE_SUCCESS(rv
, rv
);
275 rv
= doc
->GetElementById(aCommand
, element
);
276 NS_ENSURE_SUCCESS(rv
, rv
);
280 rv
= wnd
->GetFrames(getter_AddRefs(list
));
281 NS_ENSURE_SUCCESS(rv
, rv
);
283 rv
= list
->GetLength(&count
);
284 NS_ENSURE_SUCCESS(rv
, rv
);
286 for (i
= 0; i
< count
; i
++) {
287 rv
= list
->Item(i
, getter_AddRefs(next
));
288 NS_ENSURE_SUCCESS(rv
, rv
); NS_ENSURE_STATE(next
);
290 rv
= findElement(aCommand
, next
, element
);
291 NS_ENSURE_SUCCESS(rv
, rv
);
296 return NS_ERROR_ILLEGAL_VALUE
;
301 nsTestRunner::DoCommand(const nsAString
& aCommand
)
304 nsCOMPtr
<nsIDOMElement
> element
;
306 rv
= findElement(aCommand
, mTestWindow
, getter_AddRefs(element
));
307 NS_ENSURE_SUCCESS(rv
, rv
);
310 rv
= element
->HasAttribute(NS_LITERAL_STRING("disabled"), &isDisabled
);
311 NS_ENSURE_SUCCESS(rv
, rv
);
313 return NS_ERROR_NOT_AVAILABLE
;
315 nsCOMPtr
<nsIDOMEventTarget
> evtTgt(do_QueryInterface(element
, &rv
));
316 NS_ENSURE_SUCCESS(rv
, rv
);
318 nsCOMPtr
<nsIDOMDocument
> doc
;
319 rv
= element
->GetOwnerDocument(getter_AddRefs(doc
));
320 NS_ENSURE_SUCCESS(rv
, rv
);
322 nsCOMPtr
<nsIDOMDocumentEvent
> docEvent(do_QueryInterface(doc
, &rv
));
323 NS_ENSURE_SUCCESS(rv
, rv
);
325 nsCOMPtr
<nsIDOMEvent
> evt
;
326 rv
= docEvent
->CreateEvent(NS_LITERAL_STRING("XULCommandEvent"),
327 getter_AddRefs(evt
));
328 NS_ENSURE_SUCCESS(rv
, rv
);
330 nsCOMPtr
<nsIDOMXULCommandEvent
> cmdEvt(do_QueryInterface(evt
, &rv
));
331 NS_ENSURE_SUCCESS(rv
, rv
);
333 nsCOMPtr
<nsIDOMDocumentView
> docView(do_QueryInterface(doc
, &rv
));
334 NS_ENSURE_SUCCESS(rv
, rv
);
335 nsCOMPtr
<nsIDOMAbstractView
> view
;
336 rv
= docView
->GetDefaultView(getter_AddRefs(view
));
337 NS_ENSURE_SUCCESS(rv
, rv
);
339 rv
= cmdEvt
->InitCommandEvent(NS_LITERAL_STRING("command"), PR_TRUE
, PR_TRUE
,
340 view
, 0, 0, 0, 0, 0, nsnull
);
341 NS_ENSURE_SUCCESS(rv
, rv
);
344 rv
= evtTgt
->DispatchEvent( evt
, &isDefault
);
345 NS_ENSURE_SUCCESS(rv
, rv
);
351 nsTestRunner::CompareWithFile(nsIChannel
*dataChannel
,
357 rv
= reference
->GetSpec(spec
);
358 NS_ENSURE_SUCCESS(rv
, rv
);
360 this->AddFailure(spec
.get(), 2, "\"3\"");
365 nsTestRunner::Observe(nsIConsoleMessage
*aMessage
)
367 NS_ENSURE_TRUE(mTestResult
, NS_ERROR_UNEXPECTED
);
369 nsFormatJSMessage
m(aMessage
);
370 mTestResult
->AddFailure(m
.getFile(), m
.getLine(), m
.getText(), PR_TRUE
);
375 nsTestRunner::openMainWindow()
378 nsCOMPtr
<nsIConsoleService
> jsConsole
;
379 nsCOMPtr
<nsIPrefBranch
> pref
;
380 nsCAutoString chromeURI
;
381 nsCOMPtr
<nsIWindowWatcher
> ww
;
382 nsCOMPtr
<nsIDOMWindow
> wnd
;
384 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
385 NS_ENSURE_SUCCESS(rv
, rv
);
386 rv
= pref
->GetCharPref("toolkit.defaultChromeURI",getter_Copies(chromeURI
));
387 NS_ENSURE_SUCCESS(rv
, rv
);
388 ww
= do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv
);
389 NS_ENSURE_SUCCESS(rv
, rv
);
390 rv
= ww
->OpenWindow(0, chromeURI
.get(), "_blank", "chrome,dialog=no,all",
391 0, getter_AddRefs(wnd
) );
392 NS_ENSURE_SUCCESS(rv
, rv
);
394 rv
= SetWatchWindow(wnd
);
395 NS_ENSURE_SUCCESS(rv
, rv
);
398 jsConsole
= do_GetService("@mozilla.org/consoleservice;1", &rv
);
399 NS_ENSURE_TRUE(jsConsole
, NS_OK
);
400 jsConsole
->RegisterListener( this );
409 nsCOMPtr
<nsIPrefBranch
> pref
;
411 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
412 NS_ENSURE_SUCCESS(rv
, rv
);
413 (void) pref
->GetCharPref("xpunit.firstTest",getter_Copies(mTestID
));
414 if (!mTestID
.get() || !mTestID
.get()[0]) {
415 printf_stderr("Please provide first test contractID in any pref file:\n");
416 printf_stderr("pref(\"xpunit.firstTest\",\"@test.org/contract/id\");\n");
417 return NS_ERROR_NOT_AVAILABLE
;
420 mTimer
= do_CreateInstance("@mozilla.org/timer;1", &rv
);
421 NS_ENSURE_SUCCESS(rv
, rv
);
423 mTestResult
= do_CreateInstance("@aasii.org/cxxunit/testresult", &rv
);
424 NS_ENSURE_SUCCESS(rv
, rv
);
426 rv
= openMainWindow();
427 NS_ENSURE_SUCCESS(rv
, rv
);
429 rv
= pushTest(mTestID
.get());
430 NS_ENSURE_SUCCESS(rv
, rv
);
436 nsTestRunner::pushTest(const char * aContractID
)
439 nsCOMPtr
<nsITest
> test
= do_CreateInstance(aContractID
, &rv
);
442 AddError(nsITestRunner::errorLoad
, aContractID
);
446 mTestTree
.Push( (void *) test
.get() );
448 rv
= test
->Test(this);
449 if (NS_FAILED(rv
)) return rv
;
451 test
.get()->AddRef();
456 nsTestRunner::getNextTest(nsACString
&aContractID
)
461 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
462 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
464 nsCOMPtr
<nsIUTF8StringEnumerator
> testNode(do_QueryInterface(test
, &rv
));
465 if (rv
== NS_NOINTERFACE
)
466 return NS_ERROR_NOT_AVAILABLE
;
467 NS_ENSURE_SUCCESS(rv
, rv
);
469 rv
= testNode
->HasMore( &hasMore
);
470 NS_ENSURE_SUCCESS(rv
, rv
);
472 return NS_ERROR_NOT_AVAILABLE
;
474 rv
= testNode
->GetNext( aContractID
);
475 NS_ENSURE_SUCCESS(rv
, rv
);
481 nsTestRunner::traverse()
486 while (mTestTree
.GetSize()) {
488 rv
= getNextTest( mTestID
);
491 test
= (nsITest
*) mTestTree
.Pop();
494 rv
= pushTest(mTestID
.get());
503 mTestWindow
= nsnull
;
504 rv
= mTimer
->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT
);
505 if (NS_SUCCEEDED(rv
))
513 nsTestRunner::closeMainWindow()
517 nsCOMPtr
<nsIAppStartup
> app
;
518 app
= do_GetService("@mozilla.org/toolkit/app-startup;1", &rv
);
519 NS_ENSURE_SUCCESS(rv
, rv
);
520 rv
= app
->Quit(app
->eForceQuit
);
521 NS_ENSURE_SUCCESS(rv
, rv
);
529 nsCOMPtr
<nsIConsoleService
> jsConsole
;
533 mTestWindow
= nsnull
;
536 jsConsole
= do_GetService("@mozilla.org/consoleservice;1");
538 (void) jsConsole
->UnregisterListener(this);
540 (void) closeMainWindow();
541 (void) mTestResult
->Done();
542 mTestResult
= nsnull
;
547 nsTestRunner::Handle(nsICommandLine
*aCommandLine
)
552 rv
= aCommandLine
->HandleFlag(NS_LITERAL_STRING("test"), PR_TRUE
, &isTest
);
553 NS_ENSURE_SUCCESS(rv
,rv
);
557 aCommandLine
->SetPreventDefault(PR_TRUE
);
561 printf_stderr("Failed to initialize test framework\n");
562 return NS_ERROR_ABORT
;
570 nsTestRunner::GetHelpInfo(nsACString
& aHelpInfo
)
572 aHelpInfo
.Assign(" --test Run unit test collection\n");
577 nsTestRunner::resolve(nsACString
&aURL
, const PRUnichar
* *result
)
580 nsCOMPtr
<nsIRDFService
> rdfSrv
;
581 nsCOMPtr
<nsIRDFResource
> src
, prop
;
582 nsCOMPtr
<nsIRDFNode
> target
;
583 nsCOMPtr
<nsIRDFLiteral
> targetLiteral
;
585 NS_ENSURE_ARG_POINTER(result
);
587 rdfSrv
= do_GetService("@mozilla.org/rdf/rdf-service;1", &rv
);
588 NS_ENSURE_SUCCESS( rv
, rv
);
591 nsCOMPtr
<nsIPrefBranch
> pref
;
594 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
595 NS_ENSURE_SUCCESS(rv
, rv
);
596 rv
= pref
->GetCharPref("xpunit.fileMap",getter_Copies(url
));
597 NS_ENSURE_SUCCESS(rv
, rv
);
599 rv
= rdfSrv
->GetDataSourceBlocking(url
.get(),
600 getter_AddRefs( mFileMap
));
601 NS_ENSURE_TRUE( mFileMap
, rv
);
604 rv
= rdfSrv
->GetResource( aURL
, getter_AddRefs( src
));
605 NS_ENSURE_SUCCESS(rv
, rv
);
606 rv
= rdfSrv
->GetResource(
607 NS_LITERAL_CSTRING("http://www.aasii.org/AA-rdf#File"),
608 getter_AddRefs( prop
));
609 NS_ENSURE_SUCCESS(rv
, rv
);
611 rv
= mFileMap
->GetTarget(src
, prop
, PR_TRUE
, getter_AddRefs( target
));
614 targetLiteral
= do_QueryInterface( target
, &rv
);
615 NS_ENSURE_TRUE( target
, rv
);
616 targetLiteral
->GetValueConst( result
);
617 NS_ENSURE_TRUE( target
, rv
);
623 nsTestRunner::Notify(nsITimer
*timer
)
627 AddError(nsITestRunner::errorTimeout
, mTestID
.get());
634 nsTestRunner::OnStateChange(nsIWebProgress
*aWebProgress
,
635 nsIRequest
*aRequest
, PRUint32 aStateFlags
, nsresult aStatus
)
637 if (! (aStateFlags
& nsIWebProgressListener::STATE_STOP
) )
640 nsCOMPtr
<nsIDOMWindow
> wnd
;
641 aWebProgress
->GetDOMWindow(getter_AddRefs( wnd
));
642 if ( wnd
!= mWatchWindow
) {
646 mWatchWindow
= nsnull
;
647 aWebProgress
->RemoveProgressListener( this );
651 mHasWindow
= PR_TRUE
;
657 NS_ENSURE_TRUE(mArmed
, NS_ERROR_UNEXPECTED
);
659 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
660 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
662 nsCOMPtr
<nsIWebProgressListener
> listener(do_QueryInterface(test
));
663 NS_ENSURE_TRUE(listener
, NS_ERROR_UNEXPECTED
);
665 listener
->OnStateChange(aWebProgress
, aRequest
, aStateFlags
, aStatus
);
671 nsTestRunner::OnProgressChange(nsIWebProgress
*aWebProgress
,
672 nsIRequest
*aRequest
, PRInt32 aCurSelfProgress
, PRInt32 aMaxSelfProgress
,
673 PRInt32 aCurTotalProgress
, PRInt32 aMaxTotalProgress
)
675 return NS_ERROR_NOT_IMPLEMENTED
;
679 nsTestRunner::OnLocationChange(nsIWebProgress
*aWebProgress
,
680 nsIRequest
*aRequest
, nsIURI
*aLocation
)
682 return NS_ERROR_NOT_IMPLEMENTED
;
686 nsTestRunner::OnStatusChange(nsIWebProgress
*aWebProgress
,
687 nsIRequest
*aRequest
, nsresult aStatus
, const PRUnichar
*aMessage
)
689 return NS_ERROR_NOT_IMPLEMENTED
;
693 nsTestRunner::OnSecurityChange(nsIWebProgress
*aWebProgress
,
694 nsIRequest
*aRequest
, PRUint32 aState
)
696 return NS_ERROR_NOT_IMPLEMENTED
;
700 nsTestRunner::GetTestRunner()
702 if ( nsTestRunner::gTestRunner
== nsnull
) {
703 nsTestRunner::gTestRunner
= new nsTestRunner
;
706 if ( nsTestRunner::gTestRunner
!= nsnull
) {
707 NS_ADDREF( nsTestRunner::gTestRunner
);
710 return nsTestRunner::gTestRunner
;
713 /******************** nsFormatJSMessage ***********************************/
714 nsFormatJSMessage::nsFormatJSMessage(nsIConsoleMessage
*aMessage
)
716 if (NS_SUCCEEDED( parseScriptError( aMessage
) )) {
720 aMessage
->GetMessageMoz(getter_Copies( wstr
));
721 mFile
.Assign(nsnull
,0);
722 mLine
= nsITestRunner::errorNoError
;
723 mText
.Assign( NS_ConvertUTF16toUTF8(wstr
));
726 nsFormatJSMessage::nsFormatJSMessage(const char *aFile
)
733 nsFormatJSMessage::parseScriptError(nsIConsoleMessage
*aMessage
)
736 nsCOMPtr
<nsIScriptError
> error
;
739 error
= do_QueryInterface( aMessage
, &rv
);
743 rv
= formatErrorMessage(error
);
744 NS_ENSURE_SUCCESS(rv
, rv
);
746 if (NS_FAILED( getSourceFile() )) {
747 mFile
.Assign(nsnull
, 0);
748 mLine
= nsITestRunner::errorJS
;
755 nsFormatJSMessage::formatErrorMessage(nsIScriptError
*error
)
760 rv
= error
->GetErrorMessage( wstr
);
761 NS_ENSURE_SUCCESS(rv
, rv
);
763 nsCAutoString text
= NS_ConvertUTF16toUTF8( wstr
);
765 rv
= error
->GetLineNumber( &mLine
);
766 if (NS_SUCCEEDED( rv
))
767 rv
= error
->GetSourceName( wstr
);
768 if (NS_SUCCEEDED( rv
))
769 mFile
= NS_ConvertUTF16toUTF8(wstr
);
771 if ( parseException(text
) )
775 rv
= error
->GetFlags( &flags
);
779 if ( flags
& nsIScriptError::warningFlag
) {
780 mText
.Assign("warning: ");
782 mText
.Assign("error: ");
784 mText
.Append( text
);
789 nsFormatJSMessage::parseException(const nsACString
&aMessage
)
791 const char *head
, *pos
, *res
, *end
;
794 head
= aMessage
.BeginReading();
795 pos
= strstr(head
, "[Exception... \"");
799 mText
.Assign("exception: ");
801 if (pos
[15] == '\'') {
802 end
= strchr(&pos
[16], '\'');
804 mText
.Append(&pos
[15], end
- pos
- 14);
806 } else if ( (res
= strstr(&pos
[15], "nsresult: \"0x")) && strlen(res
) > 23) {
807 end
= strchr(&res
[23], ')');
809 mText
.Append(&res
[23], end
- res
- 23);
812 mText
.Append(&pos
[15],strlen(pos
) - 16);
815 if ( ! mFile
.Length() ) {
816 res
= strstr(&pos
[15],"location: \"JS frame :: ");
817 if (!res
|| strlen(res
) < 25)
819 end
= strstr(&res
[23], " :: ");
822 mFile
.Assign(Substring(&res
[23], end
- res
- 23));
823 res
= strstr(&end
[4], ":: line ");
824 if (!res
&& strlen(res
) < 10)
826 end
= strchr(&res
[8], '"');
829 mLine
= Substring(&res
[8], end
- res
- 8).ToInteger(&rv
);
835 nsFormatJSMessage::getSourceFile()
837 if ( StringHead(mFile
, 7).Equals(NS_LITERAL_CSTRING("file://")) ) {
838 return parseLocalFile();
839 } else if (! StringHead(mFile
, 9).Equals(NS_LITERAL_CSTRING("chrome://")) ) {
840 return NS_ERROR_FILE_UNRECOGNIZED_PATH
;
842 return parseChrome();
846 nsFormatJSMessage::parseLocalFile()
848 nsCAutoString leafName
;
849 const PRUnichar
* resolved
;
851 leafName
= "file://";
852 leafName
+= strrchr(mFile
.BeginReading(), '/');
854 mResolver
= nsTestRunner::GetTestRunner();
855 NS_ENSURE_TRUE( mResolver
, NS_OK
);
857 mResolver
->resolve( leafName
, &resolved
);
861 mFile
.Assign(NS_ConvertUTF16toUTF8( resolved
));
867 nsFormatJSMessage::parseChrome()
870 const char *tail
, *ptr
= 0;
872 const PRUnichar
* resolved
;
874 len
= mFile
.Length();
875 tail
= strrchr(mFile
.BeginReading(), '/');
876 head
= StringHead(mFile
, len
- strlen(tail
) );
878 mResolver
= nsTestRunner::GetTestRunner();
879 NS_ENSURE_TRUE( mResolver
, NS_OK
);
881 mResolver
->resolve( head
, &resolved
);
882 while( ! resolved
&& (head
.Length() > 9) ) {
883 ptr
= strrchr(head
.BeginReading(), '/');
885 head
= StringHead(mFile
, len
- strlen(tail
) );
886 mResolver
->resolve( head
, &resolved
);
891 head
= NS_ConvertUTF16toUTF8(resolved
);
893 mFile
.Assign( head
);