|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/* @author Edward Hieatt, edward@jsunit.net */
function jsUnitTestManager()
{
this._windowForAllProblemMessages = null;
this.container = top.frames.testContainer
this.documentLoader = top.frames.documentLoader;
this.mainFrame = top.frames.mainFrame;
this.containerController = this.container.frames.testContainerController;
this.containerTestFrame = this.container.frames.testFrame;
var mainData = this.mainFrame.frames.mainData;
// form elements on mainData frame
this.testFileName = mainData.document.testRunnerForm.testFileName;
this.runButton = mainData.document.testRunnerForm.runButton;
this.traceLevel = mainData.document.testRunnerForm.traceLevel;
this.closeTraceWindowOnNewRun = mainData.document.testRunnerForm.closeTraceWindowOnNewRun;
this.timeout = mainData.document.testRunnerForm.timeout;
this.setUpPageTimeout = mainData.document.testRunnerForm.setUpPageTimeout;
// image output
this.progressBar = this.mainFrame.frames.mainProgress.document.progress;
this.problemsListField = this.mainFrame.frames.mainErrors.document.testRunnerForm.problemsList;
this.testCaseResultsField = this.mainFrame.frames.mainResults.document.resultsForm.testCases;
this.resultsTimeField = this.mainFrame.frames.mainResults.document.resultsForm.time;
// 'layer' output frames
this.uiFrames = new Object();
this.uiFrames.mainStatus = this.mainFrame.frames.mainStatus;
var mainCounts = this.mainFrame.frames.mainCounts;
this.uiFrames.mainCountsErrors = mainCounts.frames.mainCountsErrors;
this.uiFrames.mainCountsFailures = mainCounts.frames.mainCountsFailures;
this.uiFrames.mainCountsRuns = mainCounts.frames.mainCountsRuns;
this._baseURL = "";
this.setup();
}
// seconds to wait for each test page to load
jsUnitTestManager.TESTPAGE_WAIT_SEC = 20;
jsUnitTestManager.TIMEOUT_LENGTH = 20;
// seconds to wait for setUpPage to complete
jsUnitTestManager.SETUPPAGE_TIMEOUT = 60;
// milliseconds to wait between polls on setUpPages
jsUnitTestManager.SETUPPAGE_INTERVAL = 100;
jsUnitTestManager.prototype.setup = function ()
{
this.totalCount = 0;
this.errorCount = 0;
this.failureCount = 0;
this._suiteStack = Array();
var initialSuite = new top.jsUnitTestSuite();
push(this._suiteStack, initialSuite);
}
jsUnitTestManager.prototype.start = function ()
{
this._baseURL = this.resolveUserEnteredTestFileName();
var firstQuery = this._baseURL.indexOf("?");
if (firstQuery >= 0) {
this._baseURL = this._baseURL.substring(0, firstQuery);
}
var lastSlash = this._baseURL.lastIndexOf("/");
var lastRevSlash = this._baseURL.lastIndexOf("\\");
if (lastRevSlash > lastSlash) {
lastSlash = lastRevSlash;
}
if (lastSlash > 0) {
this._baseURL = this._baseURL.substring(0, lastSlash + 1);
}
this._timeRunStarted = new Date();
this.initialize();
setTimeout('top.testManager._nextPage();', jsUnitTestManager.TIMEOUT_LENGTH);
}
jsUnitTestManager.prototype.getBaseURL = function () {
return this._baseURL;
}
jsUnitTestManager.prototype.doneLoadingPage = function (pageName)
{
//this.containerTestFrame.setTracer(top.tracer);
this._testFileName = pageName;
if (this.isTestPageSuite())
this._handleNewSuite();
else
{
this._testIndex = 0;
this._testsInPage = this.getTestFunctionNames();
this._numberOfTestsInPage = this._testsInPage.length;
this._runTest();
}
}
jsUnitTestManager.prototype._handleNewSuite = function ()
{
var allegedSuite = this.containerTestFrame.suite();
if (allegedSuite.isjsUnitTestSuite) {
var newSuite = allegedSuite.clone();
if (newSuite.containsTestPages())
push(this._suiteStack, newSuite);
this._nextPage();
}
else {
alert('Invalid test suite in file ' + this._testFileName);
this.abort();
}
}
jsUnitTestManager.prototype._runTest = function ()
{
if (this._testIndex + 1 > this._numberOfTestsInPage)
{
this._nextPage();
return;
}
if (this._testIndex == 0 && typeof(this.containerTestFrame.setUpPage) == 'function')
{
// first test for this page and a setUpPage is defined
if (typeof(this.containerTestFrame.setUpPageStatus) == 'undefined')
{
// setUpPage() not called yet, so call it
this.containerTestFrame.setUpPageStatus = false;
this.containerTestFrame.startTime = new Date();
this.containerTestFrame.setUpPage();
// try test again later
setTimeout('top.testManager._runTest()', jsUnitTestManager.SETUPPAGE_INTERVAL);
return;
}
if (this.containerTestFrame.setUpPageStatus != 'complete')
{
// setUpPage called, but not complete yet
top.status = 'setUpPage not completed... ' + this.containerTestFrame.setUpPageStatus + ' ' + (new Date());
if ((new Date() - this.containerTestFrame.startTime) /1000 > this.getsetUpPageTimeout()) {
alert('setUpPage timed out without completing.');
if (prompt('Retry or Cancel ?', 'Retry') != 'Retry')
{
this.abort();
return;
}
this.containerTestFrame.startTime = (new Date());
}
// try test again later
setTimeout('top.testManager._runTest()', jsUnitTestManager.SETUPPAGE_INTERVAL);
return;
}
}
top.status = '';
// either not first test, or no setUpPage defined, or setUpPage completed
this.executeTestFunction(this._testsInPage[this._testIndex]);
this.totalCount++;
this.updateProgressIndicators();
this._testIndex++;
setTimeout('top.testManager._runTest()', jsUnitTestManager.TIMEOUT_LENGTH);
}
jsUnitTestManager.prototype._done = function ()
{
var secondsSinceRunBegan=(new Date() - this._timeRunStarted)/1000;
this.setStatus('Done (' + secondsSinceRunBegan + ' seconds)');
this._cleanUp();
if (top.shouldSubmitResults()) {
this.resultsTimeField.value = secondsSinceRunBegan;
top.submitResults();
}
}
jsUnitTestManager.prototype._nextPage = function ()
{
if (this._currentSuite().hasMorePages()) {
this.loadPage(this._currentSuite().nextPage());
}
else {
pop(this._suiteStack);
if (this._currentSuite() == null)
this._done();
else
this._nextPage();
}
}
jsUnitTestManager.prototype._currentSuite = function ()
{
var suite = null;
if (this._suiteStack && this._suiteStack.length > 0)
suite = this._suiteStack[this._suiteStack.length-1];
return suite;
}
jsUnitTestManager.prototype.calculateProgressBarProportion = function ()
{
if (this.totalCount == 0)
return 0;
var currentDivisor = 1;
var result = 0;
for (var i = 0; i < this._suiteStack.length; i++) {
var aSuite = this._suiteStack[i];
currentDivisor *= aSuite.testPages.length;
result += (aSuite.pageIndex - 1)/currentDivisor;
}
result += (this._testIndex + 1)/(this._numberOfTestsInPage * currentDivisor);
return result;
}
jsUnitTestManager.prototype._cleanUp = function ()
{
this.containerController.setTestPage('./app/emptyPage.html');
this.finalize();
top.tracer.finalize();
}
jsUnitTestManager.prototype.abort = function ()
{
this.setStatus('Aborted');
this._cleanUp();
}
jsUnitTestManager.prototype.getTimeout = function ()
{
var result = jsUnitTestManager.TESTPAGE_WAIT_SEC;
try {
result = eval(this.timeout.value);
}
catch (e) {
}
return result;
}
jsUnitTestManager.prototype.getsetUpPageTimeout = function ()
{
var result = jsUnitTestManager.SETUPPAGE_TIMEOUT;
try {
result = eval(this.setUpPageTimeout.value);
}
catch (e) {
}
return result;
}
jsUnitTestManager.prototype.isTestPageSuite = function ()
{
var result = false;
if (typeof(this.containerTestFrame.suite) == 'function')
{
result = true;
}
return result;
}
jsUnitTestManager.prototype.getTestFunctionNames = function ()
{
var testFrame = this.containerTestFrame;
var testFunctionNames = new Array();
var i;
if (testFrame && typeof(testFrame.exposeTestFunctionNames) == 'function')
return testFrame.exposeTestFunctionNames();
if (testFrame &&
testFrame.document &&
typeof(testFrame.document.scripts) != 'undefined') { // IE5 and up
var scriptsInTestFrame = testFrame.document.scripts;
for (i = 0; i < scriptsInTestFrame.length; i++) {
var someNames = this._extractTestFunctionNamesFromScript(scriptsInTestFrame[i]);
if (someNames)
testFunctionNames=testFunctionNames.concat(someNames);
}
}
else {
for (i in testFrame) {
if (i.substring(0, 4) == 'test' && typeof(testFrame[i]) == 'function')
push(testFunctionNames, i);
}
}
return testFunctionNames;
}
jsUnitTestManager.prototype._extractTestFunctionNamesFromScript = function (aScript)
{
var result;
var remainingScriptToInspect = aScript.text;
var currentIndex = remainingScriptToInspect.indexOf('function test');
while (currentIndex != -1) {
if (!result)
result=new Array();
var fragment = remainingScriptToInspect.substring(currentIndex, remainingScriptToInspect.length);
result = result.concat(fragment.substring('function '.length, fragment.indexOf('(')));
remainingScriptToInspect=remainingScriptToInspect.substring(currentIndex+12, remainingScriptToInspect.length);
currentIndex=remainingScriptToInspect.indexOf('function test');
}
return result;
}
jsUnitTestManager.prototype.loadPage = function (testFileName)
{
this._testFileName = testFileName;
this._loadAttemptStartTime = new Date();
this.setStatus('Opening Test Page "' + this._testFileName + '"');
this.containerController.setTestPage(this._testFileName);
this._callBackWhenPageIsLoaded();
}
jsUnitTestManager.prototype._callBackWhenPageIsLoaded = function ()
{
if ((new Date() - this._loadAttemptStartTime) / 1000 > this.getTimeout()) {
alert('Reading Test Page ' + this._testFileName + ' timed out.\nMake sure that the file exists and is a Test Page.');
if (prompt('Retry or Cancel ?', 'Retry') != 'Retry')
{
this.abort();
return;
}
}
if (!this._isTestFrameLoaded()) {
setTimeout('top.testManager._callBackWhenPageIsLoaded();', jsUnitTestManager.TIMEOUT_LENGTH);
return;
}
this.doneLoadingPage(this._testFileName);
}
jsUnitTestManager.prototype._isTestFrameLoaded = function ()
{
try {
return this.containerController.isPageLoaded();
}
catch (e) {
}
return false;
}
jsUnitTestManager.prototype.executeTestFunction = function (functionName)
{
this._testFunctionName=functionName;
this.setStatus('Running test "' + this._testFunctionName + '"');
var excep=null;
var timeBefore = new Date();
try {
this.containerTestFrame.setUp();
eval('this.containerTestFrame.' + this._testFunctionName + '();');
}
catch (e1) {
excep = e1;
}
finally {
try {
this.containerTestFrame.tearDown();
}
catch (e2) {
excep = e2;
}
}
var timeTaken = (new Date() - timeBefore) / 1000;
if (excep != null)
this._handleTestException(excep);
var serializedTestCaseString = this._fullyQualifiedCurrentTestFunctionName()+"|"+timeTaken+"|";
if (excep==null)
serializedTestCaseString+="S||";
else {
if (typeof(excep.isJsUnitException) != 'undefined' && excep.isJsUnitException)
serializedTestCaseString+="F|";
else {
serializedTestCaseString+="E|";
}
serializedTestCaseString+=this._problemDetailMessageFor(excep);
}
var newOption = new Option(serializedTestCaseString);
this.testCaseResultsField[this.testCaseResultsField.length]=newOption;
}
jsUnitTestManager.prototype._fullyQualifiedCurrentTestFunctionName = function() {
var testURL = this.containerTestFrame.location.href;
var testQuery = testURL.indexOf("?");
if (testQuery >= 0) {
testURL = testURL.substring(0, testQuery);
}
if (testURL.substring(0, this._baseURL.length) == this._baseURL) {
testURL = testURL.substring(this._baseURL.length);
}
return testURL + ':' + this._testFunctionName;
}
jsUnitTestManager.prototype._handleTestException = function (excep)
{
var problemMessage = this._fullyQualifiedCurrentTestFunctionName() + ' ';
var errOption;
if (typeof(excep.isJsUnitException) == 'undefined' || !excep.isJsUnitException) {
problemMessage += 'had an error';
this.errorCount++;
}
else {
problemMessage += 'failed';
this.failureCount++;
}
var listField = this.problemsListField;
var problemDocument = this.mainFrame.frames.mainErrors.document;
if (typeof(problemDocument.createElement) != 'undefined') {
// DOM Level 2 HTML method.
// this is required for Opera 7 since appending to the end of the
// options array does not work, and adding an Option created by new Option()
// and appended by listField.options.add() fails due to WRONG_DOCUMENT_ERR
errOption = problemDocument.createElement('option');
errOption.setAttribute('value', this._problemDetailMessageFor(excep));
errOption.appendChild(problemDocument.createTextNode(problemMessage));
listField.appendChild(errOption);
}
else {
// new Option() is DOM 0
errOption = new Option(problemMessage, this._problemDetailMessageFor(excep));
if (typeof(listField.add) != 'undefined') {
// DOM 2 HTML
listField.add( errOption , null);
}
else if (typeof(listField.options.add) != 'undefined') {
// DOM 0
listField.options.add( errOption, null);
}
else {
// DOM 0
listField.options[listField.length]= errOption;
}
}
}
jsUnitTestManager.prototype._problemDetailMessageFor = function (excep)
{
var result=null;
if (typeof(excep.isJsUnitException) != 'undefined' && excep.isJsUnitException) {
result = '';
if (excep.comment != null)
result+=('"'+excep.comment+'"\n');
result += excep.jsUnitMessage;
if (excep.stackTrace)
result+='\n\nStack trace follows:\n'+excep.stackTrace;
}
else {
result = 'Error message is:\n"';
result +=
(typeof(excep.description) == 'undefined') ?
excep :
excep.description;
result += '"';
if (typeof(excep.stack) != 'undefined') // Mozilla only
result+='\n\nStack trace follows:\n'+excep.stack;
}
return result;
}
jsUnitTestManager.prototype._setTextOnLayer = function (layerName, str)
{
var html = '';
html += '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
html += '<html><\/head>';
html += '<body>';
html += str;
html += '<\/div><\/body>';
html += '<\/html>';
this.uiFrames[layerName].document.write(html);
this.uiFrames[layerName].document.close();
}
jsUnitTestManager.prototype.setStatus = function (str)
{
this._setTextOnLayer('mainStatus', '<b>Status:<\/b> '+str);
}
jsUnitTestManager.prototype._setErrors = function (n)
{
this._setTextOnLayer('mainCountsErrors', '<b>Errors: <\/b>' + n);
}
jsUnitTestManager.prototype._setFailures = function (n)
{
this._setTextOnLayer('mainCountsFailures', '<b>Failures:<\/b> ' + n);
}
jsUnitTestManager.prototype._setTotal = function (n)
{
this._setTextOnLayer('mainCountsRuns', '<b>Runs:<\/b> ' + n);
}
jsUnitTestManager.prototype._setProgressBarImage = function (imgName)
{
this.progressBar.src=imgName;
}
jsUnitTestManager.prototype._setProgressBarWidth = function (w)
{
this.progressBar.width=w;
}
jsUnitTestManager.prototype.updateProgressIndicators = function ()
{
this._setTotal(this.totalCount);
this._setErrors(this.errorCount);
this._setFailures(this.failureCount);
this._setProgressBarWidth(300 * this.calculateProgressBarProportion());
if (this.errorCount > 0 || this.failureCount > 0)
this._setProgressBarImage('../images/red.gif');
else
this._setProgressBarImage('../images/green.gif');
}
jsUnitTestManager.prototype.showMessageForSelectedProblemTest = function ()
{
var problemTestIndex = this.problemsListField.selectedIndex;
if (problemTestIndex != -1)
alert(this.problemsListField[problemTestIndex].value);
}
jsUnitTestManager.prototype.showMessagesForAllProblemTests = function ()
{
if (this.problemsListField.length == 0)
return;
try
{
if (this._windowForAllProblemMessages && !this._windowForAllProblemMessages.closed)
this._windowForAllProblemMessages.close();
}
catch(e)
{
}
this._windowForAllProblemMessages = window.open('','','width=600, height=350,status=no,resizable=yes,scrollbars=yes');
var resDoc = this._windowForAllProblemMessages.document;
resDoc.write('<html> Tests with problems - JsUnit<\/title><head><body>');
resDoc.write('<p class="jsUnitSubHeading">Tests with problems (' + this.problemsListField.length + ' total) - JsUnit<\/p>');
resDoc.write('<p class="jsUnitSubSubHeading"><i>Running on '+navigator.userAgent+'</i></p>');
for (var i = 0; i < this.problemsListField.length; i++)
{
resDoc.write('<p class="jsUnitDefault">');
resDoc.write('<b>' + (i + 1) + '. ');
resDoc.write(this.problemsListField[i].text);
resDoc.write('<\/b><\/p><p><pre>');
resDoc.write(this.problemsListField[i].value);
resDoc.write('<\/pre><\/p>');
}
resDoc.write('<\/body><\/html>');
resDoc.close();
}
jsUnitTestManager.prototype._clearProblemsList = function ()
{
var listField = this.problemsListField;
var initialLength=listField.options.length;
for (var i = 0; i < initialLength; i++)
listField.remove(0);
}
jsUnitTestManager.prototype.initialize = function ()
{
this.setStatus('Initializing...');
this._setRunButtonEnabled(false);
this._clearProblemsList();
this.updateProgressIndicators();
this.setStatus('Done initializing');
}
jsUnitTestManager.prototype.finalize = function ()
{
this._setRunButtonEnabled(true);
}
jsUnitTestManager.prototype._setRunButtonEnabled = function (b)
{
this.runButton.disabled = !b;
}
jsUnitTestManager.prototype.getTestFileName = function ()
{
var rawEnteredFileName = this.testFileName.value;
var result = rawEnteredFileName;
while (result.indexOf('\\') != -1)
result = result.replace('\\', '/');
return result;
}
jsUnitTestManager.prototype.resolveUserEnteredTestFileName = function (rawText)
{
var userEnteredTestFileName = top.testManager.getTestFileName();
// only test for file:// since Opera uses a different format
if (userEnteredTestFileName.indexOf('http://') == 0 || userEnteredTestFileName.indexOf('https://') == 0 || userEnteredTestFileName.indexOf('file://') == 0)
return userEnteredTestFileName;
return getTestFileProtocol() + this.getTestFileName();
}
function getTestFileProtocol()
{
return getDocumentProtocol();
}
function getDocumentProtocol()
{
var protocol = top.document.location.protocol;
if (protocol == "file:")
return "file:///";
if (protocol == "http:")
return "http://";
if (protocol == 'https:')
return 'https://';
if (protocol == "chrome:")
return "chrome://";
return null;
}
function isBeingRunOverHTTP() {
return getDocumentProtocol()=="http://";
}
function getWebserver() {
if (isBeingRunOverHTTP()) {
var myUrl = location.href;
var myUrlWithProtocolStripped = myUrl.substring(myUrl.indexOf("/") + 2);
return myUrlWithProtocolStripped.substring(0, myUrlWithProtocolStripped.indexOf("/"));
}
return null;
}
// the functions push(anArray, anObject) and pop(anArray)
// exist because the JavaScript Array.push(anObject) and Array.pop()
// functions are not available in IE 5.0
function push(anArray, anObject)
{
anArray[anArray.length]=anObject;
}
function pop(anArray)
{
if (anArray.length>=1) {
delete anArray[anArray.length - 1];
anArray.length--;
}
}
if (xbDEBUG.on)
{
xbDebugTraceObject('window', 'jsUnitTestManager');
xbDebugTraceFunction('window', 'getTestFileProtocol');
xbDebugTraceFunction('window', 'getDocumentProtocol');
}
</pre>
</td>
</tr>
</table>
</div>
<div style="padding-top: 1em; width: 310px; margin-left: auto; margin-right: auto; table {border-collapse: collapse; border: none;}; tr {border-collapse: collapse; border: none; text-align: center;};">
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td colspan="2" style="border-collapse: collapse; border: none; text-align: center;};">
<em>... this post is sponsored by my books ...</em>
</td>
</tr>
<tr>
<td width="150" style="border-collapse: collapse; border: none; text-align: center;};">
<a href="https://kbhr.co/ckbk-v2"><img
src="/images/books/scala-cookbook-v2-cover-220h.jpg"
title="The Scala Cookbook, by Alvin Alexander" height="220" />
<br /><span style="opacity: 0.4;">#1 New Release!</span></a>
</td>
<td width="150" style="border-collapse: collapse; border: none; text-align: center; padding-left: 8px;">
<a href="http://kbhr.co/fps-book"><img
src="/images/books/functional-programming-simplified-small.jpg"
title="Functional Programming, Simplified, by Alvin Alexander"
height="220" />
<br /><span style="opacity: 0.4;">FP Best Seller</span></a>
</td>
</tr>
</table>
<p> </p>
</div>
<div id="whats_new">
<h2>new blog posts</h2>
<div id="whats_new_list">
<ul>
<li><a class="whats_new_link" href="/personal/sanctify-yourself-dream-january-21-2017">Sanctify Yourself</a></li>
<li><a class="whats_new_link" href="/photos/alvin-alexander-leaving-hospital">A picture of yours truly</a></li>
<li><a class="whats_new_link" href="/misc/each-instant-put-your-heart-into-it-again">Each instant, put your heart into it again</a></li>
<br/>
<li><a class="whats_new_link" href="/misc/ive-been-seeing-a-therapist-dream-telekinesis-moving-furniture">I'''ve been seeing a therapist ...</a></li>
<li><a class="whats_new_link" href="/misc/virginia-ginny-schick-teacher-artist-colorado">Virginia '''Ginny''' Schick: A great teacher and artist, in Colorado</a></li>
<li><a class="whats_new_link" href="/personal/quotes-service-anandamayi-ma-gospel-book-review">Quotes on '''service''' from Anandamayi Ma (via The Gospel of Shri Anandamayi Ma)</a></li>
<br/>
<li><a class="whats_new_link" href="/photos/green-mile-im-tired-boss-john-coffee">I'''m tired, boss ... Mostly I'''m tired of people being ugly to each other</a></li>
<li><a class="whats_new_link" href="/misc/next-time-i-fall-in-love-song">Next Time I Fall In Love</a></li>
<li><a class="whats_new_link" href="/photos/you-got-the-gift-looks-like-youre-waiting-for-something-matrix-quote">You got the gift, but it looks like you'''re waiting for something ...</a></li>
<br/>
<br/>
</div>
</ul>
</div>
<p> </p>
<p align="center"><font color="#000000" size="2"
face="Verdana,Arial">Copyright 1998-2024 Alvin Alexander, alvinalexander.com<br/>
All Rights Reserved.<br/>
<br/>
A percentage of advertising revenue from<br/>
pages under the <a href="/java/jwarehouse">/java/jwarehouse</a>
URI on this website is<br/>
paid back to open source projects.</p>
<script>
shuffle(books);
var div = document.getElementById("leftcol");
var pre = '<div style="margin: 0; padding-right: 1.6em"><h2 align="center">favorite books</h2>';
var post = '</div>';
if (adblock) {
var str = books.slice(0,3).join(" ");
div.insertAdjacentHTML('beforeend', pre + str + post);
} else {
var str = books.slice(0,1).join(" ");
div.insertAdjacentHTML('beforeend', pre + str + post);
}
</script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3075717592179848"
crossorigin="anonymous"></script>
<p style="padding-bottom: 80px;"> </p>
</body>
|