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 "nsNetUtil.h"
27 #include "nsIComponentManager.h"
28 #include "nsComponentManagerUtils.h"
29 #include "nsServiceManagerUtils.h"
30 #include "nsIPrefBranch.h"
31 #include "nsIWindowWatcher.h"
32 #include "nsIDOMWindow.h"
33 #include "nsIDOMWindowCollection.h"
34 #include "nsIInterfaceRequestorUtils.h"
35 #include "nsIWebProgress.h"
36 #include "nsIDOMDocument.h"
37 #include "nsIDOMDocumentView.h"
38 #include "nsIDOMElement.h"
39 #include "nsIDOMEventTarget.h"
40 #include "nsIDOMDocumentEvent.h"
41 #include "nsIDOMEvent.h"
42 #include "nsIDOMAbstractView.h"
43 #include "nsIThreadManager.h"
44 #include "nsIThread.h"
45 #include "nsILineInputStream.h"
46 #include "nsIComponentRegistrar.h"
47 #include "nsDirectoryServiceDefs.h"
49 /* Unfrozen interfaces */
50 #include "nsAutoPtr.h"
51 #include "nsICommandLine.h"
52 #include "nsIWebNavigation.h"
53 #include "nsIAppStartup.h"
54 #include "nsIConsoleService.h"
55 #include "nsIConsoleMessage.h"
56 #include "nsIScriptError.h"
58 #include "nsIJSContextStack.h"
59 #include "nsIRDFService.h"
60 #include "nsIRDFDataSource.h"
61 #include "nsIRDFResource.h"
62 #include "nsIDOMXULDocument.h"
63 #include "nsIDOMXULCommandDispatcher.h"
64 #include "nsIDOMXULCommandEvent.h"
65 #include "nsIStringEnumerator.h"
68 /* Project includes */
69 #include "nsITestRunner.h"
70 #include "nsITestResult.h"
73 #include "nsTestRunner.h"
74 #include "nsTestFailure.h"
75 #include "nsOneLineDiff.h"
76 #include "nsTestXmlFactory.h"
78 #include "nsTestUtils.h"
80 class nsFormatJSMessage
: public nsTestFailure
83 nsFormatJSMessage(nsIConsoleMessage
*aMessage
);
84 nsFormatJSMessage(const char *aFile
);
85 ~nsFormatJSMessage() {;}
87 nsresult
parseScriptError(nsIConsoleMessage
*aMessage
);
88 nsresult
formatErrorMessage(nsIScriptError
*error
);
89 PRBool
parseException(const nsACString
&aMessage
);
90 nsresult
getSourceFile();
91 nsresult
parseLocalFile();
92 nsresult
parseChrome();
94 nsRefPtr
<nsTestRunner
> mResolver
;
98 /******************** nsTestRunner ***********************************/
99 nsTestRunner::nsTestRunner()
100 :mTestTree(nsnull
), mArmed(PR_FALSE
), mHasWindow(PR_FALSE
)
104 nsTestRunner::~nsTestRunner()
108 nsTestRunner
* nsTestRunner::gTestRunner
= nsnull
;
110 NS_IMPL_THREADSAFE_ISUPPORTS8(nsTestRunner
,
113 nsIWebProgressListener
,
114 nsISupportsWeakReference
,
116 nsICommandLineHandler
,
121 nsTestRunner::MarkTestStart()
123 return mTestResult
->MarkTestStart();
127 nsTestRunner::AddFailure(const char *aFile
, PRUint32 aLine
, const char *aText
)
129 return mTestResult
->AddFailure(aFile
, aLine
, aText
, PR_FALSE
);
133 nsTestRunner::AddJSFailure(const char *aText
)
136 JSContext
*cx
= nsnull
;
140 mJSStack
= do_GetService("@mozilla.org/js/xpc/ContextStack;1");
141 NS_ENSURE_TRUE(mJSStack
, NS_ERROR_FAILURE
);
143 rv
= mJSStack
->Peek( &cx
);
144 NS_ENSURE_TRUE(cx
, NS_ERROR_FAILURE
);
146 nsFormatJSMessage
m(ns_test_js_caller_filename(cx
));
148 return mTestResult
->AddFailure(m
.getFile(),
149 ns_test_js_caller_lineno(cx
), aText
, PR_FALSE
);
153 nsTestRunner::AddError(PRUint32 aCode
, const char *aComment
)
155 return mTestResult
->AddFailure(nsnull
, aCode
, aComment
, PR_TRUE
);
159 nsTestRunner::MarkTestEnd(nsITest
*aTest
)
161 if (aTest
!= (nsITest
*) mTestTree
.Peek())
162 return NS_ERROR_ILLEGAL_VALUE
;
166 if(NS_FAILED(mTimer
->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT
)))
173 nsTestRunner::GetHasWindow(PRBool
*aHasWindow
)
175 NS_ENSURE_ARG_POINTER(aHasWindow
);
176 *aHasWindow
= mHasWindow
;
181 nsTestRunner::GetTestWindow(nsIDOMWindow
* *aTestWindow
)
183 NS_ENSURE_ARG_POINTER( aTestWindow
);
184 if ( !mTestWindow
) {
185 *aTestWindow
= nsnull
;
186 return NS_ERROR_NOT_INITIALIZED
;
188 *aTestWindow
= mTestWindow
;
189 NS_ADDREF( *aTestWindow
);
195 nsTestRunner::GetWatchWindow(nsIDOMWindow
* *aWatchWindow
)
197 NS_ENSURE_ARG_POINTER( aWatchWindow
);
198 if ( !mWatchWindow
) {
199 *aWatchWindow
= nsnull
;
200 return NS_ERROR_NOT_INITIALIZED
;
202 *aWatchWindow
= mWatchWindow
;
203 NS_ADDREF( *aWatchWindow
);
209 nsTestRunner::SetWatchWindow(nsIDOMWindow
*aWatchWindow
)
213 if (mWatchWindow
== aWatchWindow
)
215 if (mWatchWindow
&& !mHasWindow
)
218 NS_ENSURE_SUCCESS(rv
, rv
);
224 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(mWatchWindow
, &rv
));
225 NS_ENSURE_SUCCESS(rv
, rv
);
227 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
228 NS_ENSURE_SUCCESS(rv
, rv
);
230 rv
= webProgress
->RemoveProgressListener(this);
231 NS_ENSURE_SUCCESS(rv
, rv
);
233 mWatchWindow
= nsnull
;
237 nsCOMPtr
<nsIWebNavigation
> web(do_GetInterface(aWatchWindow
, &rv
));
238 NS_ENSURE_SUCCESS(rv
, rv
);
240 nsCOMPtr
<nsIWebProgress
> webProgress(do_QueryInterface(web
, &rv
));
241 NS_ENSURE_SUCCESS(rv
, rv
);
243 rv
= webProgress
->AddProgressListener(this,
244 nsIWebProgress::NOTIFY_STATE_WINDOW
);
245 NS_ENSURE_SUCCESS(rv
, rv
);
249 NS_ENSURE_SUCCESS(rv
, rv
);
252 mWatchWindow
= aWatchWindow
;
258 nsTestRunner::ArmTimer(PRUint32 aDelay
)
260 NS_ENSURE_TRUE(!mArmed
, NS_ERROR_ALREADY_INITIALIZED
);
263 rv
= mTimer
->InitWithCallback(this, aDelay
<< 1, nsITimer::TYPE_ONE_SHOT
);
264 NS_ENSURE_SUCCESS(rv
, rv
);
271 findElement(const nsAString
& aCommand
, nsIDOMWindow
*wnd
,
272 nsIDOMElement
**element
)
276 nsCOMPtr
<nsIDOMWindowCollection
> list
;
277 nsCOMPtr
<nsIDOMWindow
> next
;
278 nsCOMPtr
<nsIDOMDocument
> doc
;
281 rv
= wnd
->GetDocument(getter_AddRefs(doc
));
282 NS_ENSURE_SUCCESS(rv
, rv
);
284 rv
= doc
->GetElementById(aCommand
, element
);
285 NS_ENSURE_SUCCESS(rv
, rv
);
289 rv
= wnd
->GetFrames(getter_AddRefs(list
));
290 NS_ENSURE_SUCCESS(rv
, rv
);
292 rv
= list
->GetLength(&count
);
293 NS_ENSURE_SUCCESS(rv
, rv
);
295 for (i
= 0; i
< count
; i
++) {
296 rv
= list
->Item(i
, getter_AddRefs(next
));
297 NS_ENSURE_SUCCESS(rv
, rv
); NS_ENSURE_STATE(next
);
299 rv
= findElement(aCommand
, next
, element
);
300 NS_ENSURE_SUCCESS(rv
, rv
);
305 return NS_ERROR_ILLEGAL_VALUE
;
310 nsTestRunner::DoCommand(const nsAString
& aCommand
)
313 nsCOMPtr
<nsIDOMElement
> element
;
315 rv
= findElement(aCommand
, mTestWindow
, getter_AddRefs(element
));
316 NS_ENSURE_SUCCESS(rv
, rv
);
319 rv
= element
->HasAttribute(NS_LITERAL_STRING("disabled"), &isDisabled
);
320 NS_ENSURE_SUCCESS(rv
, rv
);
322 return NS_ERROR_NOT_AVAILABLE
;
324 nsCOMPtr
<nsIDOMEventTarget
> evtTgt(do_QueryInterface(element
, &rv
));
325 NS_ENSURE_SUCCESS(rv
, rv
);
327 nsCOMPtr
<nsIDOMDocument
> doc
;
328 rv
= element
->GetOwnerDocument(getter_AddRefs(doc
));
329 NS_ENSURE_SUCCESS(rv
, rv
);
331 nsCOMPtr
<nsIDOMDocumentEvent
> docEvent(do_QueryInterface(doc
, &rv
));
332 NS_ENSURE_SUCCESS(rv
, rv
);
334 nsCOMPtr
<nsIDOMEvent
> evt
;
335 rv
= docEvent
->CreateEvent(NS_LITERAL_STRING("XULCommandEvent"),
336 getter_AddRefs(evt
));
337 NS_ENSURE_SUCCESS(rv
, rv
);
339 nsCOMPtr
<nsIDOMXULCommandEvent
> cmdEvt(do_QueryInterface(evt
, &rv
));
340 NS_ENSURE_SUCCESS(rv
, rv
);
342 nsCOMPtr
<nsIDOMDocumentView
> docView(do_QueryInterface(doc
, &rv
));
343 NS_ENSURE_SUCCESS(rv
, rv
);
344 nsCOMPtr
<nsIDOMAbstractView
> view
;
345 rv
= docView
->GetDefaultView(getter_AddRefs(view
));
346 NS_ENSURE_SUCCESS(rv
, rv
);
348 rv
= cmdEvt
->InitCommandEvent(NS_LITERAL_STRING("command"), PR_TRUE
, PR_TRUE
,
349 view
, 0, 0, 0, 0, 0, nsnull
);
350 NS_ENSURE_SUCCESS(rv
, rv
);
353 rv
= evtTgt
->DispatchEvent( evt
, &isDefault
);
354 NS_ENSURE_SUCCESS(rv
, rv
);
360 nsTestRunner::CompareWithFile(const char* aFile
, PRUint32 aLine
,
361 nsIChannel
*dataChannel
, nsIURI
*reference
)
366 nsCOMPtr
<nsOneLineDiff
> differ
= new nsOneLineDiff();
367 NS_ENSURE_TRUE(differ
, NS_ERROR_OUT_OF_MEMORY
);
369 nsCOMPtr
<nsIChannel
> refChannel
;
370 rv
= NS_NewChannel(getter_AddRefs(refChannel
), reference
);
371 NS_ENSURE_SUCCESS(rv
, rv
);
373 nsCOMPtr
<nsIThreadManager
> threadMngr
=
374 do_GetService("@mozilla.org/thread-manager;1", &rv
);
375 NS_ENSURE_SUCCESS(rv
, rv
);
377 nsCOMPtr
<nsIThread
> thread
;
378 rv
= threadMngr
->GetCurrentThread(getter_AddRefs(thread
));
379 NS_ENSURE_SUCCESS(rv
, rv
);
381 mCompareURI
= reference
;
382 mCompareFile
= aFile
;
383 mCompareLine
= aLine
;
384 rv
= differ
->Compare(refChannel
, dataChannel
, this);
385 NS_ENSURE_SUCCESS(rv
, rv
);
389 PRBool isProcessed
= PR_FALSE
;
390 rv
= thread
->ProcessNextEvent(PR_TRUE
, &isProcessed
);
391 NS_ENSURE_SUCCESS(rv
, rv
);
398 nsTestRunner::Observe(nsIConsoleMessage
*aMessage
)
400 NS_ENSURE_TRUE(mTestResult
, NS_ERROR_UNEXPECTED
);
402 nsFormatJSMessage
m(aMessage
);
403 mTestResult
->AddFailure(m
.getFile(), m
.getLine(), m
.getText(), PR_TRUE
);
408 nsTestRunner::openMainWindow()
411 nsCOMPtr
<nsIConsoleService
> jsConsole
;
412 nsCOMPtr
<nsIPrefBranch
> pref
;
413 nsCAutoString chromeURI
;
414 nsCOMPtr
<nsIWindowWatcher
> ww
;
415 nsCOMPtr
<nsIDOMWindow
> wnd
;
417 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
418 NS_ENSURE_SUCCESS(rv
, rv
);
419 rv
= pref
->GetCharPref("toolkit.defaultChromeURI",getter_Copies(chromeURI
));
420 NS_ENSURE_SUCCESS(rv
, rv
);
421 ww
= do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv
);
422 NS_ENSURE_SUCCESS(rv
, rv
);
423 rv
= ww
->OpenWindow(0, chromeURI
.get(), "_blank", "chrome,dialog=no,all",
424 0, getter_AddRefs(wnd
) );
425 NS_ENSURE_SUCCESS(rv
, rv
);
427 rv
= SetWatchWindow(wnd
);
428 NS_ENSURE_SUCCESS(rv
, rv
);
431 jsConsole
= do_GetService("@mozilla.org/consoleservice;1", &rv
);
432 NS_ENSURE_TRUE(jsConsole
, NS_OK
);
433 jsConsole
->RegisterListener( this );
442 nsCOMPtr
<nsIPrefBranch
> pref
;
444 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
445 NS_ENSURE_SUCCESS(rv
, rv
);
446 (void) pref
->GetCharPref("xpunit.firstTest",getter_Copies(mTestID
));
447 if (!mTestID
.get() || !mTestID
.get()[0]) {
448 printf_stderr("Please provide first test contractID in any pref file:\n");
449 printf_stderr("pref(\"xpunit.firstTest\",\"@test.org/contract/id\");\n");
450 return NS_ERROR_NOT_AVAILABLE
;
453 mTimer
= do_CreateInstance("@mozilla.org/timer;1", &rv
);
454 NS_ENSURE_SUCCESS(rv
, rv
);
456 mTestResult
= do_CreateInstance("@aasii.org/cxxunit/testresult", &rv
);
457 NS_ENSURE_SUCCESS(rv
, rv
);
459 rv
= openMainWindow();
460 NS_ENSURE_SUCCESS(rv
, rv
);
462 rv
= registerXmlTests();
463 NS_ENSURE_SUCCESS(rv
, rv
);
465 rv
= pushTest(mTestID
.get());
466 NS_ENSURE_SUCCESS(rv
, rv
);
472 nsTestRunner::pushTest(const char * aContractID
)
475 nsCOMPtr
<nsITest
> test
= do_CreateInstance(aContractID
, &rv
);
478 AddError(nsITestRunner::errorLoad
, aContractID
);
482 mTestTree
.Push( (void *) test
.get() );
484 rv
= test
->Test(this);
485 if (NS_FAILED(rv
)) return rv
;
487 test
.get()->AddRef();
492 nsTestRunner::getNextTest(nsACString
&aContractID
)
497 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
498 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
500 nsCOMPtr
<nsIUTF8StringEnumerator
> testNode(do_QueryInterface(test
, &rv
));
501 if (rv
== NS_NOINTERFACE
)
502 return NS_ERROR_NOT_AVAILABLE
;
503 NS_ENSURE_SUCCESS(rv
, rv
);
505 rv
= testNode
->HasMore( &hasMore
);
506 NS_ENSURE_SUCCESS(rv
, rv
);
508 return NS_ERROR_NOT_AVAILABLE
;
510 rv
= testNode
->GetNext( aContractID
);
511 NS_ENSURE_SUCCESS(rv
, rv
);
517 nsTestRunner::traverse()
522 while (mTestTree
.GetSize()) {
524 rv
= getNextTest( mTestID
);
527 test
= (nsITest
*) mTestTree
.Pop();
530 rv
= pushTest(mTestID
.get());
539 mTestWindow
= nsnull
;
540 rv
= mTimer
->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT
);
541 if (NS_SUCCEEDED(rv
))
549 nsTestRunner::closeMainWindow()
553 nsCOMPtr
<nsIAppStartup
> app
;
554 app
= do_GetService("@mozilla.org/toolkit/app-startup;1", &rv
);
555 NS_ENSURE_SUCCESS(rv
, rv
);
556 rv
= app
->Quit(app
->eForceQuit
);
557 NS_ENSURE_SUCCESS(rv
, rv
);
565 nsCOMPtr
<nsIConsoleService
> jsConsole
;
569 mTestWindow
= nsnull
;
572 jsConsole
= do_GetService("@mozilla.org/consoleservice;1");
574 (void) jsConsole
->UnregisterListener(this);
576 (void) closeMainWindow();
577 (void) mTestResult
->Done();
578 mTestResult
= nsnull
;
583 nsTestRunner::Handle(nsICommandLine
*aCommandLine
)
588 rv
= aCommandLine
->HandleFlag(NS_LITERAL_STRING("test"), PR_TRUE
, &isTest
);
589 NS_ENSURE_SUCCESS(rv
,rv
);
593 aCommandLine
->SetPreventDefault(PR_TRUE
);
597 printf_stderr("Failed to initialize test framework\n");
598 return NS_ERROR_ABORT
;
606 nsTestRunner::GetHelpInfo(nsACString
& aHelpInfo
)
608 aHelpInfo
.Assign(" --test Run unit test collection\n");
613 nsTestRunner::resolve(nsACString
&aURL
, const PRUnichar
* *result
)
616 nsCOMPtr
<nsIRDFService
> rdfSrv
;
617 nsCOMPtr
<nsIRDFResource
> src
, prop
;
618 nsCOMPtr
<nsIRDFNode
> target
;
619 nsCOMPtr
<nsIRDFLiteral
> targetLiteral
;
621 NS_ENSURE_ARG_POINTER(result
);
623 rdfSrv
= do_GetService("@mozilla.org/rdf/rdf-service;1", &rv
);
624 NS_ENSURE_SUCCESS( rv
, rv
);
627 nsCOMPtr
<nsIPrefBranch
> pref
;
630 pref
= do_GetService("@mozilla.org/preferences-service;1", &rv
);
631 NS_ENSURE_SUCCESS(rv
, rv
);
632 rv
= pref
->GetCharPref("xpunit.fileMap",getter_Copies(url
));
633 NS_ENSURE_SUCCESS(rv
, rv
);
635 rv
= rdfSrv
->GetDataSourceBlocking(url
.get(),
636 getter_AddRefs( mFileMap
));
637 NS_ENSURE_TRUE( mFileMap
, rv
);
640 rv
= rdfSrv
->GetResource( aURL
, getter_AddRefs( src
));
641 NS_ENSURE_SUCCESS(rv
, rv
);
642 rv
= rdfSrv
->GetResource(
643 NS_LITERAL_CSTRING("http://www.aasii.org/AA-rdf#File"),
644 getter_AddRefs( prop
));
645 NS_ENSURE_SUCCESS(rv
, rv
);
647 rv
= mFileMap
->GetTarget(src
, prop
, PR_TRUE
, getter_AddRefs( target
));
650 targetLiteral
= do_QueryInterface( target
, &rv
);
651 NS_ENSURE_TRUE( target
, rv
);
652 targetLiteral
->GetValueConst( result
);
653 NS_ENSURE_TRUE( target
, rv
);
659 nsTestRunner::Notify(nsITimer
*timer
)
663 AddError(nsITestRunner::errorTimeout
, mTestID
.get());
670 nsTestRunner::OnStateChange(nsIWebProgress
*aWebProgress
,
671 nsIRequest
*aRequest
, PRUint32 aStateFlags
, nsresult aStatus
)
673 if (! (aStateFlags
& nsIWebProgressListener::STATE_STOP
) )
676 nsCOMPtr
<nsIDOMWindow
> wnd
;
677 aWebProgress
->GetDOMWindow(getter_AddRefs( wnd
));
678 if ( wnd
!= mWatchWindow
) {
682 mWatchWindow
= nsnull
;
683 aWebProgress
->RemoveProgressListener( this );
687 mHasWindow
= PR_TRUE
;
693 NS_ENSURE_TRUE(mArmed
, NS_ERROR_UNEXPECTED
);
695 nsITest
*test
= (nsITest
*) mTestTree
.Peek();
696 NS_ENSURE_TRUE(test
, NS_ERROR_UNEXPECTED
);
698 nsCOMPtr
<nsIWebProgressListener
> listener(do_QueryInterface(test
));
699 NS_ENSURE_TRUE(listener
, NS_ERROR_UNEXPECTED
);
701 listener
->OnStateChange(aWebProgress
, aRequest
, aStateFlags
, aStatus
);
707 nsTestRunner::OnProgressChange(nsIWebProgress
*aWebProgress
,
708 nsIRequest
*aRequest
, PRInt32 aCurSelfProgress
, PRInt32 aMaxSelfProgress
,
709 PRInt32 aCurTotalProgress
, PRInt32 aMaxTotalProgress
)
711 return NS_ERROR_NOT_IMPLEMENTED
;
715 nsTestRunner::OnLocationChange(nsIWebProgress
*aWebProgress
,
716 nsIRequest
*aRequest
, nsIURI
*aLocation
)
718 return NS_ERROR_NOT_IMPLEMENTED
;
722 nsTestRunner::OnStatusChange(nsIWebProgress
*aWebProgress
,
723 nsIRequest
*aRequest
, nsresult aStatus
, const PRUnichar
*aMessage
)
725 return NS_ERROR_NOT_IMPLEMENTED
;
729 nsTestRunner::OnSecurityChange(nsIWebProgress
*aWebProgress
,
730 nsIRequest
*aRequest
, PRUint32 aState
)
732 return NS_ERROR_NOT_IMPLEMENTED
;
736 nsTestRunner::OnMismatch(const nsACString
& aText
, PRUint32 aLine
)
739 nsCOMPtr
<nsIURI
> reference
= mCompareURI
;
741 mCompareURI
= nsnull
;
744 rv
= reference
->GetSpec(spec
);
745 NS_ENSURE_SUCCESS(rv
, rv
);
747 nsCAutoString message
;
748 message
.AssignLiteral("\"");
749 message
.Append(aText
);
750 message
.AppendLiteral("\"");
751 rv
= AddFailure(spec
.get(), aLine
, message
.get());
752 NS_ENSURE_SUCCESS(rv
, rv
);
753 rv
= AddFailure(mCompareFile
, mCompareLine
, "included from here");
754 NS_ENSURE_SUCCESS(rv
, rv
);
755 mCompareFile
= nsnull
;
762 nsTestRunner::OnError(const nsACString
& aText
, PRUint32 aLine
)
765 nsCOMPtr
<nsIURI
> reference
= mCompareURI
;
767 mCompareURI
= nsnull
;
770 rv
= reference
->GetSpec(spec
);
771 NS_ENSURE_SUCCESS(rv
, rv
);
773 nsCAutoString message
;
774 message
.Append(aText
);
775 rv
= AddFailure(spec
.get(), aLine
, message
.get());
776 NS_ENSURE_SUCCESS(rv
, rv
);
777 rv
= AddFailure(mCompareFile
, mCompareLine
, "included from here");
778 NS_ENSURE_SUCCESS(rv
, rv
);
779 mCompareFile
= nsnull
;
786 nsTestRunner::OnSuccess()
788 mCompareURI
= nsnull
;
789 mCompareFile
= nsnull
;
795 nsTestRunner::registerXmlTests()
799 nsCOMPtr
<nsIComponentRegistrar
> compReg
;
800 rv
= NS_GetComponentRegistrar(getter_AddRefs(compReg
));
801 NS_ENSURE_SUCCESS(rv
, rv
);
803 nsCOMPtr
<nsIProperties
> procDirProp(
804 do_CreateInstance("@mozilla.org/file/directory_service;1", &rv
));
805 NS_ENSURE_SUCCESS(rv
, rv
);
807 nsCOMPtr
<nsIFile
> testDir
;
808 rv
= procDirProp
->Get(NS_OS_CURRENT_PROCESS_DIR
, NS_GET_IID(nsIFile
),
809 getter_AddRefs(testDir
));
810 NS_ENSURE_SUCCESS(rv
, rv
);
812 rv
= testDir
->Append(NS_LITERAL_STRING("tests"));
813 NS_ENSURE_SUCCESS(rv
, rv
);
815 PRBool dirExist
= PR_FALSE
;
816 rv
= testDir
->Exists(&dirExist
);
817 NS_ENSURE_SUCCESS(rv
, rv
);
819 PRBool testIsDir
= PR_FALSE
;
820 rv
= testDir
->IsDirectory(&testIsDir
);
821 NS_ENSURE_SUCCESS(rv
, rv
);
823 if (dirExist
&& testIsDir
)
825 rv
= testDir
->Append(NS_LITERAL_STRING("xml"));
826 NS_ENSURE_SUCCESS(rv
, rv
);
828 rv
= testDir
->Exists(&dirExist
);
829 NS_ENSURE_SUCCESS(rv
, rv
);
831 rv
= testDir
->IsDirectory(&testIsDir
);
832 NS_ENSURE_SUCCESS(rv
, rv
);
834 if (dirExist
&& testIsDir
)
836 nsCOMPtr
<nsISimpleEnumerator
> entries
;
837 rv
= testDir
->GetDirectoryEntries(getter_AddRefs(entries
));
838 NS_ENSURE_SUCCESS(rv
, rv
);
840 PRBool hasMore
= PR_FALSE
;
841 while (NS_SUCCEEDED(rv
= entries
->HasMoreElements(&hasMore
)) && hasMore
)
843 nsCOMPtr
<nsISupports
> item
;
844 rv
= entries
->GetNext(getter_AddRefs(item
));
845 NS_ENSURE_SUCCESS(rv
, rv
);
847 nsCOMPtr
<nsILocalFile
> file(do_QueryInterface(item
, &rv
));
848 NS_ENSURE_SUCCESS(rv
, rv
);
850 PRBool fileIsFile
= PR_FALSE
;
851 rv
= file
->IsFile(&fileIsFile
);
852 NS_ENSURE_SUCCESS(rv
, rv
);
856 nsCAutoString leafName
;
857 rv
= file
->GetNativeLeafName(leafName
);
858 NS_ENSURE_SUCCESS(rv
, rv
);
860 nsCAutoString baseUri
;
861 baseUri
.AssignLiteral("resource:///tests/xml/");
862 baseUri
.Append(leafName
);
864 nsCOMPtr
<nsIURI
> uri
;
865 rv
= NS_NewURI(getter_AddRefs(uri
), baseUri
.get());
866 NS_ENSURE_SUCCESS(rv
, rv
);
868 nsCOMPtr
<nsTestXmlFactory
> xmlFactory
=
869 do_CreateInstance(NS_TEST_XML_FACTORY_CONTRACT
, &rv
);
870 NS_ENSURE_SUCCESS(rv
, rv
);
871 NS_ENSURE_TRUE(!!(xmlFactory
), NS_ERROR_OUT_OF_MEMORY
);
873 rv
= xmlFactory
->RegisterSelf(uri
, compReg
);
874 NS_ENSURE_SUCCESS(rv
, rv
);
884 nsTestRunner::GetTestRunner()
886 if ( nsTestRunner::gTestRunner
== nsnull
) {
887 nsTestRunner::gTestRunner
= new nsTestRunner
;
890 if ( nsTestRunner::gTestRunner
!= nsnull
) {
891 NS_ADDREF( nsTestRunner::gTestRunner
);
894 return nsTestRunner::gTestRunner
;
897 /******************** nsFormatJSMessage ***********************************/
898 nsFormatJSMessage::nsFormatJSMessage(nsIConsoleMessage
*aMessage
)
900 if (NS_SUCCEEDED( parseScriptError( aMessage
) )) {
904 aMessage
->GetMessageMoz(getter_Copies( wstr
));
905 mFile
.Assign(nsnull
,0);
906 mLine
= nsITestRunner::errorNoError
;
907 mText
.Assign( NS_ConvertUTF16toUTF8(wstr
));
910 nsFormatJSMessage::nsFormatJSMessage(const char *aFile
)
917 nsFormatJSMessage::parseScriptError(nsIConsoleMessage
*aMessage
)
920 nsCOMPtr
<nsIScriptError
> error
;
923 error
= do_QueryInterface( aMessage
, &rv
);
927 rv
= formatErrorMessage(error
);
928 NS_ENSURE_SUCCESS(rv
, rv
);
930 if (NS_FAILED( getSourceFile() )) {
931 mFile
.Assign(nsnull
, 0);
932 mLine
= nsITestRunner::errorJS
;
939 nsFormatJSMessage::formatErrorMessage(nsIScriptError
*error
)
944 rv
= error
->GetErrorMessage( wstr
);
945 NS_ENSURE_SUCCESS(rv
, rv
);
947 nsCAutoString text
= NS_ConvertUTF16toUTF8( wstr
);
949 rv
= error
->GetLineNumber( &mLine
);
950 if (NS_SUCCEEDED( rv
))
951 rv
= error
->GetSourceName( wstr
);
952 if (NS_SUCCEEDED( rv
))
953 mFile
= NS_ConvertUTF16toUTF8(wstr
);
955 if ( parseException(text
) )
959 rv
= error
->GetFlags( &flags
);
963 if ( flags
& nsIScriptError::warningFlag
) {
964 mText
.Assign("warning: ");
966 mText
.Assign("error: ");
968 mText
.Append( text
);
973 nsFormatJSMessage::parseException(const nsACString
&aMessage
)
975 const char *head
, *pos
, *res
, *end
;
978 head
= aMessage
.BeginReading();
979 pos
= strstr(head
, "[Exception... \"");
983 mText
.Assign("exception: ");
985 if (pos
[15] == '\'') {
986 end
= strchr(&pos
[16], '\'');
988 mText
.Append(&pos
[15], end
- pos
- 14);
990 } else if ( (res
= strstr(&pos
[15], "nsresult: \"0x")) && strlen(res
) > 23) {
991 end
= strchr(&res
[23], ')');
993 mText
.Append(&res
[23], end
- res
- 23);
996 mText
.Append(&pos
[15],strlen(pos
) - 16);
999 if ( ! mFile
.Length() ) {
1000 res
= strstr(&pos
[15],"location: \"JS frame :: ");
1001 if (!res
|| strlen(res
) < 25)
1003 end
= strstr(&res
[23], " :: ");
1006 mFile
.Assign(Substring(&res
[23], end
- res
- 23));
1007 res
= strstr(&end
[4], ":: line ");
1008 if (!res
&& strlen(res
) < 10)
1010 end
= strchr(&res
[8], '"');
1013 mLine
= Substring(&res
[8], end
- res
- 8).ToInteger(&rv
);
1019 nsFormatJSMessage::getSourceFile()
1021 if ( StringHead(mFile
, 7).Equals(NS_LITERAL_CSTRING("file://")) ) {
1022 return parseLocalFile();
1023 } else if (! StringHead(mFile
, 9).Equals(NS_LITERAL_CSTRING("chrome://")) ) {
1024 return NS_ERROR_FILE_UNRECOGNIZED_PATH
;
1026 return parseChrome();
1030 nsFormatJSMessage::parseLocalFile()
1032 nsCAutoString leafName
;
1033 const PRUnichar
* resolved
;
1035 leafName
= "file://";
1036 leafName
+= strrchr(mFile
.BeginReading(), '/');
1038 mResolver
= nsTestRunner::GetTestRunner();
1039 NS_ENSURE_TRUE( mResolver
, NS_OK
);
1041 mResolver
->resolve( leafName
, &resolved
);
1045 mFile
.Assign(NS_ConvertUTF16toUTF8( resolved
));
1051 nsFormatJSMessage::parseChrome()
1054 const char *tail
, *ptr
= 0;
1056 const PRUnichar
* resolved
;
1058 len
= mFile
.Length();
1059 tail
= strrchr(mFile
.BeginReading(), '/');
1060 head
= StringHead(mFile
, len
- strlen(tail
) );
1062 mResolver
= nsTestRunner::GetTestRunner();
1063 NS_ENSURE_TRUE( mResolver
, NS_OK
);
1065 mResolver
->resolve( head
, &resolved
);
1066 while( ! resolved
&& (head
.Length() > 9) ) {
1067 ptr
= strrchr(head
.BeginReading(), '/');
1068 tail
-= strlen(ptr
);
1069 head
= StringHead(mFile
, len
- strlen(tail
) );
1070 mResolver
->resolve( head
, &resolved
);
1075 head
= NS_ConvertUTF16toUTF8(resolved
);
1077 mFile
.Assign( head
);