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 <abstract/aacore.h>
25 #include "nsStringAPI.h"
26 #include "nsEmbedString.h"
27 #include "nsWeakReference.h"
28 #include "nsIWebProgressListener.h"
29 #include "nsIComponentManager.h"
30 #include "nsComponentManagerUtils.h"
31 #include "nsServiceManagerUtils.h"
32 #include "nsIPrefBranch.h"
33 #include "nsIWindowWatcher.h"
34 #include "nsIDOMWindow.h"
35 #include "nsIInterfaceRequestorUtils.h"
36 #include "nsIWebProgress.h"
37 #include "nsIDOMDocument.h"
38 #include "nsIDOMElement.h"
39 #include "nsIDOMEventTarget.h"
40 #include "nsIDOMDocumentEvent.h"
41 #include "nsIDOMEvent.h"
42 #include "nsIDOMAbstractView.h"
44 /* Unfrozen interfaces */
45 #include "unstable/nsITimer.h"
46 #include "unstable/nsICommandLineHandler.h"
47 #include "unstable/nsDeque.h"
48 #include "unstable/nsAutoPtr.h"
49 #include "unstable/nsICommandLine.h"
50 #include "unstable/nsIWebNavigation.h"
51 #include "unstable/nsIAppStartup.h"
52 #include "unstable/nsIConsoleListener.h"
53 #include "unstable/nsIConsoleService.h"
54 #include "unstable/nsIConsoleMessage.h"
55 #include "unstable/nsIScriptError.h"
56 #include "unstable/jspubtd.h"
57 #include "unstable/nsIJSContextStack.h"
58 #include "unstable/nsIRDFService.h"
59 #include "unstable/nsIRDFDataSource.h"
60 #include "unstable/nsIRDFResource.h"
61 #include "unstable/nsIDOMXULDocument.h"
62 #include "unstable/nsIDOMXULCommandDispatcher.h"
63 #include "unstable/nsIDOMXULCommandEvent.h"
64 #include "unstable/nsIStringEnumerator.h"
66 /* Project includes */
67 #include <abstract/cxxunit/nsITestRunner.h>
68 #include <abstract/cxxunit/nsITestResult.h>
69 #include <abstract/cxxunit/nsITest.h>
71 #include "nsTestRunner.h"
72 #include "nsTestFailure.h"
74 #include <abstract/cxxunit/nsTestUtils.h>
76 class nsFormatJSMessage
: public nsTestFailure
79 nsFormatJSMessage(nsIConsoleMessage
*aMessage
);
80 nsFormatJSMessage(const char *aFile
);
81 ~nsFormatJSMessage() {;}
83 nsresult
parseScriptError(nsIConsoleMessage
*aMessage
);
84 nsresult
formatErrorMessage(nsIScriptError
*error
);
85 PRBool
parseException(const nsACString
&aMessage
);
86 nsresult
getSourceFile();
87 nsresult
parseLocalFile();
88 nsresult
parseChrome();
91 nsRefPtr
<nsTestRunner
> mResolver
;
95 /******************** nsTestRunner ***********************************/
96 nsTestRunner
* nsTestRunner::gTestRunner
= nsnull
;
98 nsTestRunner::nsTestRunner() : mTestTree(nsnull
)
104 nsTestRunner::~nsTestRunner()
108 NS_IMPL_THREADSAFE_ISUPPORTS6(nsTestRunner
,
111 nsIWebProgressListener
,
112 nsISupportsWeakReference
,
114 nsICommandLineHandler
);
117 nsTestRunner::MarkTestStart()
119 return mTestResult
->MarkTestStart();
123 nsTestRunner::AddFailure(const char *aFile
, PRUint32 aLine
, const char *aText
)
125 return mTestResult
->AddFailure(aFile
, aLine
, aText
, PR_FALSE
);
129 nsTestRunner::AddJSFailure(const char *aText
)
132 JSContext
*cx
= nsnull
;
136 mJSStack
= do_GetService("@mozilla.org/js/xpc/ContextStack;1");
137 NS_ENSURE_TRUE(mJSStack
, NS_ERROR_FAILURE
);
139 rv
= mJSStack
->Peek( &cx
);
140 NS_ENSURE_TRUE(cx
, NS_ERROR_FAILURE
);
142 nsFormatJSMessage
m(ns_test_js_caller_filename(cx
));
144 return mTestResult
->AddFailure(m
.getFile(),
145 ns_test_js_caller_lineno(cx
) + 1, aText
, PR_FALSE
);
149 nsTestRunner::AddError(PRUint32 aCode
, const char *aComment
)
151 return mTestResult
->AddFailure(nsnull
, aCode
, aComment
, PR_TRUE
);
155 nsTestRunner::MarkTestEnd(nsITest
*aTest
)
157 if (aTest
!= (nsITest
*) mTestTree
.Peek())
158 return NS_ERROR_ILLEGAL_VALUE
;
161 mTimerStop
->Cancel();
162 if(NS_FAILED(mTimer
->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT
)))
169 nsTestRunner::GetTestWindow(nsIDOMWindow
* *aTestWindow
)
171 NS_ENSURE_ARG_POINTER( aTestWindow
);
172 if ( !mTestWindow
) {
173 *aTestWindow
= nsnull
;
174 return NS_ERROR_NOT_INITIALIZED
;
176 *aTestWindow
= mTestWindow
;
177 NS_ADDREF( *aTestWindow
);
183 nsTestRunner::GetWatchWindow(nsIDOMWindow
* *aWatchWindow
)
185 NS_ENSURE_ARG_POINTER( aWatchWindow
);
186 if ( !mWatchWindow
) {
187 *aWatchWindow
= nsnull
;
188 return NS_ERROR_NOT_INITIALIZED
;
190 *aWatchWindow
= mWatchWindow
;
191 NS_ADDREF( *aWatchWindow
);
197 nsTestRunner::SetWatchWindow(nsIDOMWindow
*aWatchWindow
)
202 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(mWatchWindow
, &rv
));
203 NS_ENSURE_SUCCESS(rv
, rv
);
205 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
206 NS_ENSURE_SUCCESS(rv
, rv
);
208 rv
= webProgress
->RemoveProgressListener(this);
209 NS_ENSURE_SUCCESS(rv
, rv
);
213 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(aWatchWindow
, &rv
));
214 NS_ENSURE_SUCCESS(rv
, rv
);
216 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
217 NS_ENSURE_SUCCESS(rv
, rv
);
219 rv
= webProgress
->AddProgressListener(this,
220 nsIWebProgress::NOTIFY_STATE_WINDOW
);
221 NS_ENSURE_SUCCESS(rv
, rv
);
223 mWatchWindow
= aWatchWindow
;
229 nsTestRunner::ArmTimer()
232 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
234 nsCOMPtr
<nsITimerCallback
> callback(do_QueryInterface(test
, &rv
));
235 NS_ENSURE_SUCCESS(rv
, rv
);
236 rv
= mTimer
->InitWithCallback(callback
, 0, nsITimer::TYPE_ONE_SHOT
);
237 NS_ENSURE_SUCCESS(rv
, rv
);
244 nsTestRunner::DoCommand(const nsAString
& aCommand
)
247 nsCOMPtr
<nsIDOMWindow
> wnd(mTestWindow
);
249 nsCOMPtr
<nsIDOMDocument
> doc
;
250 nsCOMPtr
<nsIDOMXULDocument
> xulDoc
;
251 nsCOMPtr
<nsIDOMXULCommandDispatcher
> dispatcher
;
252 nsCOMPtr
<nsIDOMElement
> element
;
255 rv
= wnd
->GetDocument(getter_AddRefs( doc
));
256 NS_ENSURE_SUCCESS(rv
, rv
);
258 rv
= doc
->GetElementById(aCommand
, getter_AddRefs( element
));
262 xulDoc
= do_QueryInterface(doc
, &rv
);
263 NS_ENSURE_SUCCESS(rv
, NS_ERROR_ILLEGAL_VALUE
);
265 rv
= xulDoc
->GetCommandDispatcher(getter_AddRefs( dispatcher
));
266 NS_ENSURE_SUCCESS(rv
, rv
);
268 rv
= dispatcher
->GetFocusedWindow( &next
);
269 NS_ENSURE_SUCCESS(rv
, rv
);
274 wnd
= getter_AddRefs( next
);
278 NS_ENSURE_TRUE(element
, NS_ERROR_ILLEGAL_VALUE
);
281 rv
= element
->HasAttribute(NS_LITERAL_STRING("disabled"), &isDisabled
);
282 NS_ENSURE_SUCCESS(rv
, rv
);
284 return NS_ERROR_NOT_AVAILABLE
;
286 nsCOMPtr
<nsIDOMEventTarget
> evtTgt(do_QueryInterface(element
, &rv
));
287 NS_ENSURE_SUCCESS(rv
, rv
);
289 nsCOMPtr
<nsIDOMDocumentEvent
> docEvent(do_QueryInterface(doc
, &rv
));
290 NS_ENSURE_SUCCESS(rv
, rv
);
292 nsCOMPtr
<nsIDOMEvent
> evt
;
293 rv
= docEvent
->CreateEvent(NS_LITERAL_STRING("XULCommandEvent"),
294 getter_AddRefs(evt
));
295 NS_ENSURE_SUCCESS(rv
, rv
);
297 nsCOMPtr
<nsIDOMXULCommandEvent
> cmdEvt(do_QueryInterface(evt
, &rv
));
298 NS_ENSURE_SUCCESS(rv
, rv
);
300 nsCOMPtr
<nsIDOMAbstractView
> view(do_QueryInterface(wnd
, &rv
));
301 NS_ENSURE_SUCCESS(rv
, rv
);
303 rv
= cmdEvt
->InitCommandEvent(NS_LITERAL_STRING("command"), PR_TRUE
, PR_TRUE
,
304 view
, 0, 0, 0, 0, 0, nsnull
);
305 NS_ENSURE_SUCCESS(rv
, rv
);
308 rv
= evtTgt
->DispatchEvent( evt
, &isDefault
);
309 NS_ENSURE_SUCCESS(rv
, rv
);
315 nsTestRunner::Observe(nsIConsoleMessage
*aMessage
)
317 NS_ENSURE_TRUE(mTestResult
, NS_ERROR_UNEXPECTED
);
319 nsFormatJSMessage
m(aMessage
);
320 mTestResult
->AddFailure(m
.getFile(), m
.getLine(), m
.getText(), PR_TRUE
);
325 nsTestRunner::openMainWindow()
328 nsCOMPtr
<nsIConsoleService
> jsConsole
;
329 nsCOMPtr
<nsIPrefBranch
> pref
;
330 nsEmbedCString chromeURI
;
331 nsCOMPtr
<nsIWindowWatcher
> ww
;
332 nsCOMPtr
<nsIDOMWindow
> wnd
;
334 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
335 NS_ENSURE_SUCCESS(rv
, rv
);
336 rv
= pref
->GetCharPref("toolkit.defaultChromeURI",getter_Copies(chromeURI
));
337 NS_ENSURE_SUCCESS(rv
, rv
);
338 ww
= do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv
);
339 NS_ENSURE_SUCCESS(rv
, rv
);
340 rv
= ww
->OpenWindow(0, chromeURI
.get(), "_blank", "chrome,dialog=no,all",
341 0, getter_AddRefs(wnd
) );
342 NS_ENSURE_SUCCESS(rv
, rv
);
345 jsConsole
= do_GetService("@mozilla.org/consoleservice;1", &rv
);
346 NS_ENSURE_TRUE(jsConsole
, NS_OK
);
347 jsConsole
->RegisterListener( this );
355 if ( init() != NS_ERROR_ABORT
)
363 nsCOMPtr
<nsIPrefBranch
> pref
;
365 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
366 NS_ENSURE_SUCCESS(rv
, rv
);
367 rv
= pref
->GetCharPref("cxxunit.firstTest",getter_Copies(mTestID
));
368 NS_ENSURE_SUCCESS(rv
, rv
);
370 rv
= pushTest( mTestID
.get() );
371 NS_ENSURE_SUCCESS(rv
, rv
);
373 return runCurrentTest();
377 nsTestRunner::pushTest(const char * aContractID
)
381 nsCOMPtr
<nsIComponentManager
> componentManager
;
383 rv
= NS_GetComponentManager(getter_AddRefs( componentManager
));
384 NS_ENSURE_SUCCESS(rv
, rv
);
385 rv
= componentManager
->CreateInstanceByContractID(aContractID
, nsnull
,
386 NS_GET_IID(nsITest
), (void **) &test
);
388 AddError(nsITestRunner::errorLoad
, aContractID
);
392 mTestTree
.Push( (void *) test
);
397 nsTestRunner::runCurrentTest()
399 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
402 if ( mRunning
|| mWatchWindow
) {
405 mTimerStop
->InitWithCallback(this, 1000, nsITimer::TYPE_ONE_SHOT
);
406 return NS_ERROR_ABORT
;
413 nsTestRunner::getNextTest(nsACString
&aContractID
)
418 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
419 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
421 nsCOMPtr
<nsIUTF8StringEnumerator
> testNode(do_QueryInterface(test
, &rv
));
422 if (rv
== NS_NOINTERFACE
)
423 return NS_ERROR_NOT_AVAILABLE
;
424 NS_ENSURE_SUCCESS(rv
, rv
);
426 rv
= testNode
->HasMore( &hasMore
);
427 NS_ENSURE_SUCCESS(rv
, rv
);
429 return NS_ERROR_NOT_AVAILABLE
;
431 rv
= testNode
->GetNext( aContractID
);
432 NS_ENSURE_SUCCESS(rv
, rv
);
438 nsTestRunner::traverse()
441 nsEmbedCString
nextContractID(0);
444 while (mTestTree
.GetSize()) {
446 rv
= getNextTest( mTestID
);
449 test
= (nsITest
*) mTestTree
.Pop();
452 if (NS_FAILED( pushTest( mTestID
.get() ) ))
454 if (NS_FAILED( runCurrentTest() ))
459 if (NS_FAILED( mTimer
->InitWithFuncCallback(done
, this, 0,
460 nsITimer::TYPE_ONE_SHOT
) )) {
466 nsTestRunner::closeMainWindow()
469 nsCOMPtr
<nsIAppStartup
> app
;
470 app
= do_GetService("@mozilla.org/toolkit/app-startup;1", &rv
);
471 NS_ENSURE_SUCCESS(rv
, rv
);
472 rv
= app
->Quit(app
->eForceQuit
);
473 NS_ENSURE_SUCCESS(rv
, rv
);
478 nsTestRunner::done(nsITimer
*aTimer
, void *aClosure
)
480 nsTestRunner
*self
= static_cast<nsTestRunner
*>(aClosure
);
481 nsCOMPtr
<nsIConsoleService
> jsConsole
;
483 jsConsole
= do_GetService("@mozilla.org/consoleservice;1");
485 jsConsole
->UnregisterListener( self
);
487 self
->closeMainWindow();
488 self
->mTestResult
->Done();
489 self
->mTestResult
= nsnull
;
490 self
->mTimer
= nsnull
;
494 nsTestRunner::Handle(nsICommandLine
*aCommandLine
)
499 rv
= aCommandLine
->HandleFlag(NS_LITERAL_STRING("test"), PR_TRUE
, &isTest
);
500 NS_ENSURE_SUCCESS(rv
,rv
);
502 aCommandLine
->SetPreventDefault(PR_TRUE
);
504 mTimer
= do_CreateInstance("@mozilla.org/timer;1");
505 NS_ENSURE_TRUE(mTimer
, NS_ERROR_ABORT
);
507 mTimerStop
= do_CreateInstance("@mozilla.org/timer;1");
508 NS_ENSURE_TRUE(mTimer
, NS_ERROR_ABORT
);
510 mTestResult
= do_CreateInstance("@aasii.org/cxxunit/testresult", &rv
);
511 NS_ENSURE_SUCCESS(rv
, NS_ERROR_ABORT
);
513 if (NS_FAILED( openMainWindow() )) {
523 nsTestRunner::GetHelpInfo(nsACString
& aHelpInfo
)
525 aHelpInfo
.Assign(" --test Run unit test collection\n");
530 nsTestRunner::resolve(nsACString
&aURL
, const PRUnichar
* *result
)
533 nsCOMPtr
<nsIRDFService
> rdfSrv
;
534 nsCOMPtr
<nsIRDFResource
> src
, prop
;
535 nsCOMPtr
<nsIRDFNode
> target
;
536 nsCOMPtr
<nsIRDFLiteral
> targetLiteral
;
538 NS_ENSURE_ARG_POINTER(result
);
540 rdfSrv
= do_GetService("@mozilla.org/rdf/rdf-service;1", &rv
);
541 NS_ENSURE_SUCCESS( rv
, rv
);
544 nsCOMPtr
<nsIPrefBranch
> pref
;
547 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
548 NS_ENSURE_SUCCESS(rv
, rv
);
549 rv
= pref
->GetCharPref("cxxunit.fileMap",getter_Copies(url
));
550 NS_ENSURE_SUCCESS(rv
, rv
);
552 rv
= rdfSrv
->GetDataSourceBlocking(url
.get(),
553 getter_AddRefs( mFileMap
));
554 NS_ENSURE_TRUE( mFileMap
, rv
);
557 rv
= rdfSrv
->GetResource( aURL
, getter_AddRefs( src
));
558 NS_ENSURE_SUCCESS(rv
, rv
);
559 rv
= rdfSrv
->GetResource(
560 NS_LITERAL_CSTRING("http://www.aasii.org/AA-rdf#File"),
561 getter_AddRefs( prop
));
562 NS_ENSURE_SUCCESS(rv
, rv
);
564 rv
= mFileMap
->GetTarget(src
, prop
, PR_TRUE
, getter_AddRefs( target
));
567 targetLiteral
= do_QueryInterface( target
, &rv
);
568 NS_ENSURE_TRUE( target
, rv
);
569 targetLiteral
->GetValueConst( result
);
570 NS_ENSURE_TRUE( target
, rv
);
576 nsTestRunner::Notify(nsITimer
*timer
)
580 AddError(nsITestRunner::errorTimeout
, mTestID
.get());
588 nsTestRunner::OnStateChange(nsIWebProgress
*aWebProgress
,
589 nsIRequest
*aRequest
, PRUint32 aStateFlags
, nsresult aStatus
)
591 if (! aStateFlags
& nsIWebProgressListener::STATE_STOP
)
594 nsCOMPtr
<nsIDOMWindow
> wnd
;
595 aWebProgress
->GetDOMWindow(getter_AddRefs( wnd
));
596 if ( wnd
!= mWatchWindow
) {
600 mWatchWindow
= nsnull
;
601 aWebProgress
->RemoveProgressListener( this );
603 NS_ENSURE_TRUE(mArmed
, NS_ERROR_UNEXPECTED
);
605 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
606 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
608 nsCOMPtr
<nsIWebProgressListener
> listener(do_QueryInterface(test
));
609 NS_ENSURE_TRUE(listener
, NS_ERROR_UNEXPECTED
);
611 listener
->OnStateChange(aWebProgress
, aRequest
, aStateFlags
, aStatus
);
617 nsTestRunner::OnProgressChange(nsIWebProgress
*aWebProgress
,
618 nsIRequest
*aRequest
, PRInt32 aCurSelfProgress
, PRInt32 aMaxSelfProgress
,
619 PRInt32 aCurTotalProgress
, PRInt32 aMaxTotalProgress
)
621 return NS_ERROR_NOT_IMPLEMENTED
;
625 nsTestRunner::OnLocationChange(nsIWebProgress
*aWebProgress
,
626 nsIRequest
*aRequest
, nsIURI
*aLocation
)
628 return NS_ERROR_NOT_IMPLEMENTED
;
632 nsTestRunner::OnStatusChange(nsIWebProgress
*aWebProgress
,
633 nsIRequest
*aRequest
, nsresult aStatus
, const PRUnichar
*aMessage
)
635 return NS_ERROR_NOT_IMPLEMENTED
;
639 nsTestRunner::OnSecurityChange(nsIWebProgress
*aWebProgress
,
640 nsIRequest
*aRequest
, PRUint32 aState
)
642 return NS_ERROR_NOT_IMPLEMENTED
;
646 nsTestRunner::GetTestRunner()
648 if ( nsTestRunner::gTestRunner
== nsnull
) {
649 nsTestRunner::gTestRunner
= new nsTestRunner
;
652 if ( nsTestRunner::gTestRunner
!= nsnull
) {
653 NS_ADDREF( nsTestRunner::gTestRunner
);
656 return nsTestRunner::gTestRunner
;
659 /******************** nsFormatJSMessage ***********************************/
660 nsFormatJSMessage::nsFormatJSMessage(nsIConsoleMessage
*aMessage
)
663 if (NS_SUCCEEDED( parseScriptError( aMessage
) )) {
667 aMessage
->GetMessage(getter_Copies( wstr
));
668 mFile
.Assign(nsnull
,0);
669 mLine
= nsITestRunner::errorNoError
;
670 mText
.Assign( NS_ConvertUTF16toUTF8(wstr
));
673 nsFormatJSMessage::nsFormatJSMessage(const char *aFile
)
681 nsFormatJSMessage::parseScriptError(nsIConsoleMessage
*aMessage
)
684 nsCOMPtr
<nsIScriptError
> error
;
687 error
= do_QueryInterface( aMessage
, &rv
);
691 rv
= formatErrorMessage(error
);
692 NS_ENSURE_SUCCESS(rv
, rv
);
694 if (NS_FAILED( getSourceFile() )) {
695 mFile
.Assign(nsnull
, 0);
696 mLine
= nsITestRunner::errorJS
;
698 if (mFile
.Length()>2 && !mIsChrome
)
705 nsFormatJSMessage::formatErrorMessage(nsIScriptError
*error
)
710 rv
= error
->GetErrorMessage( wstr
);
711 NS_ENSURE_SUCCESS(rv
, rv
);
713 nsEmbedCString text
= NS_ConvertUTF16toUTF8( wstr
);
715 rv
= error
->GetLineNumber( &mLine
);
716 if (NS_SUCCEEDED( rv
))
717 rv
= error
->GetSourceName( wstr
);
718 if (NS_SUCCEEDED( rv
))
719 mFile
= NS_ConvertUTF16toUTF8(wstr
);
721 if ( parseException(text
) )
725 rv
= error
->GetFlags( &flags
);
729 if ( flags
& nsIScriptError::warningFlag
) {
730 mText
.Assign("warning: ");
732 mText
.Assign("error: ");
734 mText
.Append( text
);
739 nsFormatJSMessage::parseException(const nsACString
&aMessage
)
741 const char *head
, *pos
, *res
, *end
;
744 head
= aMessage
.BeginReading();
745 pos
= strstr(head
, "[Exception... \"");
749 mText
.Assign("exception: ");
751 if (pos
[15] == '\'') {
752 end
= strchr(&pos
[16], '\'');
754 mText
.Append(&pos
[15], end
- pos
- 14);
756 } else if ( (res
= strstr(&pos
[15], "nsresult: \"0x")) && strlen(res
) > 23) {
757 end
= strchr(&res
[23], ')');
759 mText
.Append(&res
[23], end
- res
- 23);
762 mText
.Append(&pos
[15],strlen(pos
) - 16);
765 if ( ! mFile
.Length() ) {
766 res
= strstr(&pos
[15],"location: \"JS frame :: ");
767 if (!res
|| strlen(res
) < 25)
769 end
= strstr(&res
[23], " :: ");
772 mFile
.Assign(Substring(&res
[23], end
- res
- 23));
773 res
= strstr(&end
[4], ":: line ");
774 if (!res
&& strlen(res
) < 10)
776 end
= strchr(&res
[8], '"');
779 mLine
= Substring(&res
[8], end
- res
- 8).ToInteger(&rv
);
785 nsFormatJSMessage::getSourceFile()
787 if ( StringHead(mFile
, 7).Equals(NS_LITERAL_CSTRING("file://")) ) {
788 mIsChrome
= PR_FALSE
;
789 return parseLocalFile();
790 } else if (! StringHead(mFile
, 9).Equals(NS_LITERAL_CSTRING("chrome://")) ) {
791 return NS_ERROR_FILE_UNRECOGNIZED_PATH
;
793 return parseChrome();
797 nsFormatJSMessage::parseLocalFile()
799 nsEmbedCString leafName
;
800 const PRUnichar
* resolved
;
802 leafName
= "file://";
803 leafName
+= strrchr(mFile
.BeginReading(), '/');
805 mResolver
= nsTestRunner::GetTestRunner();
806 NS_ENSURE_TRUE( mResolver
, NS_OK
);
808 mResolver
->resolve( leafName
, &resolved
);
812 mFile
.Assign(NS_ConvertUTF16toUTF8( resolved
));
818 nsFormatJSMessage::parseChrome()
821 const char *tail
, *ptr
= 0;
823 const PRUnichar
* resolved
;
825 len
= mFile
.Length();
826 tail
= strrchr(mFile
.BeginReading(), '/');
827 head
= StringHead(mFile
, len
- strlen(tail
) );
829 mResolver
= nsTestRunner::GetTestRunner();
830 NS_ENSURE_TRUE( mResolver
, NS_OK
);
832 mResolver
->resolve( head
, &resolved
);
833 while( ! resolved
&& (head
.Length() > 9) ) {
834 ptr
= strrchr(head
.BeginReading(), '/');
836 head
= StringHead(mFile
, len
- strlen(tail
) );
837 mResolver
->resolve( head
, &resolved
);
842 head
= NS_ConvertUTF16toUTF8(resolved
);
844 mFile
.Assign( head
);