Adds more fancy look for test runner
|
@ -153,9 +153,18 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
}
|
||||
final Log log = getLog();
|
||||
new File(outputDir, "tests").mkdirs();
|
||||
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
||||
resourceToFile("org/teavm/maven/junit-support.js", "junit-support.js");
|
||||
resourceToFile("org/teavm/maven/junit.css", "junit.css");
|
||||
new File(outputDir, "res").mkdirs();
|
||||
resourceToFile("org/teavm/javascript/runtime.js", "res/runtime.js");
|
||||
resourceToFile("org/teavm/maven/res/junit-support.js", "res/junit-support.js");
|
||||
resourceToFile("org/teavm/maven/res/junit.css", "res/junit.css");
|
||||
resourceToFile("org/teavm/maven/res/class_obj.png", "res/class_obj.png");
|
||||
resourceToFile("org/teavm/maven/res/control-000-small.png", "res/control-000-small.png");
|
||||
resourceToFile("org/teavm/maven/res/methpub_obj.png", "res/methpub_obj.png");
|
||||
resourceToFile("org/teavm/maven/res/package_obj.png", "res/package_obj.png");
|
||||
resourceToFile("org/teavm/maven/res/tick-small-red.png", "res/tick-small-red.png");
|
||||
resourceToFile("org/teavm/maven/res/tick-small.png", "res/tick-small.png");
|
||||
resourceToFile("org/teavm/maven/res/toggle-small-expand.png", "res/toggle-small-expand.png");
|
||||
resourceToFile("org/teavm/maven/res/toggle-small.png", "res/toggle-small.png");
|
||||
resourceToFile("org/teavm/maven/junit.html", "junit.html");
|
||||
final ClassHolderSource classSource = new ClasspathClassHolderSource(classLoader);
|
||||
for (String testClass : testClasses) {
|
||||
|
@ -170,8 +179,8 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
includeAdditionalScripts(classLoader);
|
||||
File allTestsFile = new File(outputDir, "tests/all.js");
|
||||
try (Writer allTestsWriter = new OutputStreamWriter(new FileOutputStream(allTestsFile), "UTF-8")) {
|
||||
allTestsWriter.write("doRunTests = function() {\n");
|
||||
allTestsWriter.write(" new JUnitServer(document.body).runAllTests([");
|
||||
allTestsWriter.write("prepare = function() {\n");
|
||||
allTestsWriter.write(" return new JUnitServer(document.body).readTests([");
|
||||
boolean first = true;
|
||||
for (String testClass : testClasses) {
|
||||
if (!first) {
|
||||
|
@ -547,3 +556,4 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
JUnitServer = function(container) {
|
||||
this.container = container;
|
||||
this.timeSpent = 0;
|
||||
this.totalTimeSpent = 0;
|
||||
this.methodCount = 0;
|
||||
this.statusCell = null;
|
||||
this.exceptionCell = null;
|
||||
this.timeCell = null;
|
||||
this.startTime = 0;
|
||||
this.expectedExceptions = [];
|
||||
this.table = null;
|
||||
this.tableBody = null;
|
||||
this.frame = null;
|
||||
}
|
||||
JUnitServer.prototype = new Object();
|
||||
JUnitServer.prototype.handleEvent = function(message, callback) {
|
||||
endTime = new Date().getTime();
|
||||
if (message.status === "ok") {
|
||||
if (this.expectedExceptions.length > 0) {
|
||||
this.statusCell.appendChild(document.createTextNode("expected exception not thrown"));
|
||||
this.statusCell.style.color = 'yellow';
|
||||
} else {
|
||||
this.statusCell.appendChild(document.createTextNode("ok"));
|
||||
this.statusCell.style.color = 'green';
|
||||
}
|
||||
} else if (message.status === "exception") {
|
||||
if (message.exception && this.isExpectedException(message.exception)) {
|
||||
this.statusCell.appendChild(document.createTextNode("ok"));
|
||||
this.statusCell.style.color = 'green';
|
||||
} else {
|
||||
this.statusCell.appendChild(document.createTextNode("unexpected exception"));
|
||||
var exceptionText = document.createElement("pre");
|
||||
exceptionText.appendChild(document.createTextNode(message.stack));
|
||||
this.exceptionCell.appendChild(exceptionText);
|
||||
this.statusCell.style.color = 'red';
|
||||
}
|
||||
}
|
||||
++this.methodCount;
|
||||
var timeSpent = (endTime - this.startTime) / 1000;
|
||||
this.timeSpent += timeSpent;
|
||||
this.timeCell.appendChild(document.createTextNode(timeSpent.toFixed(3)));
|
||||
document.body.removeChild(this.frame);
|
||||
self.frame = null;
|
||||
callback();
|
||||
}
|
||||
JUnitServer.prototype.isExpectedException = function(ex) {
|
||||
for (var i = 0; i < this.expectedExceptions.length; ++i) {
|
||||
if (this.expectedExceptions[i] === ex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
JUnitServer.prototype.runTestCase = function(methodName, path, expectedExceptions, additionalScripts, callback) {
|
||||
this.createRow(methodName);
|
||||
this.startTime = new Date().getTime();
|
||||
this.expectedExceptions = expectedExceptions;
|
||||
var self = this;
|
||||
this.loadCode(path, additionalScripts, function() {
|
||||
messageHandler = function(event) {
|
||||
window.removeEventListener("message", messageHandler);
|
||||
self.handleEvent(JSON.parse(event.data), callback);
|
||||
};
|
||||
window.addEventListener("message", messageHandler);
|
||||
self.frame.contentWindow.postMessage("runTest", "*");
|
||||
});
|
||||
}
|
||||
JUnitServer.prototype.createRow = function(methodName) {
|
||||
var row = document.createElement("tr");
|
||||
this.tableBody.appendChild(row);
|
||||
var nameCell = document.createElement("td");
|
||||
row.appendChild(nameCell);
|
||||
nameCell.appendChild(document.createTextNode(methodName));
|
||||
this.statusCell = document.createElement("td");
|
||||
row.appendChild(this.statusCell);
|
||||
this.exceptionCell = document.createElement("td");
|
||||
row.appendChild(this.exceptionCell);
|
||||
this.timeCell = document.createElement("td");
|
||||
row.appendChild(this.timeCell);
|
||||
}
|
||||
JUnitServer.prototype.loadCode = function(path, additionalScripts, callback) {
|
||||
this.frame = document.createElement("iframe");
|
||||
document.body.appendChild(this.frame);
|
||||
var frameDoc = this.frame.contentWindow.document;
|
||||
var self = this;
|
||||
var sequence = ["junit-support.js", "runtime.js"];
|
||||
if (additionalScripts) {
|
||||
for (var i = 0; i < additionalScripts.length; ++i) {
|
||||
sequence.push(additionalScripts[i]);
|
||||
}
|
||||
}
|
||||
sequence.push(path);
|
||||
self.loadScripts(sequence, 0, callback);
|
||||
}
|
||||
JUnitServer.prototype.loadScripts = function(scripts, index, callback) {
|
||||
var self = this;
|
||||
if (index == scripts.length) {
|
||||
callback();
|
||||
} else {
|
||||
this.loadScript(scripts[index], function() { self.loadScripts(scripts, index + 1, callback) });
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.loadScript = function(name, callback) {
|
||||
var doc = this.frame.contentWindow.document;
|
||||
var script = doc.createElement("script");
|
||||
script.src = name;
|
||||
doc.body.appendChild(script);
|
||||
script.onload = function() {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.runTest = function(test, callback) {
|
||||
this.timeSpent = 0;
|
||||
this.methodCount = 0;
|
||||
this.createTable(test.name);
|
||||
var self = this;
|
||||
this.runMethodFromList(test.methods, 0, function() {
|
||||
self.createFooter();
|
||||
callback();
|
||||
});
|
||||
}
|
||||
JUnitServer.prototype.runAllTests = function(tests, callback) {
|
||||
this.runTestFromList(tests, 0, callback);
|
||||
}
|
||||
JUnitServer.prototype.runTestFromList = function(tests, index, callback) {
|
||||
if (index < tests.length) {
|
||||
var test = tests[index];
|
||||
var self = this;
|
||||
this.runTest(test, function() {
|
||||
self.runTestFromList(tests, index + 1, callback);
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.runMethodFromList = function(methods, index, callback) {
|
||||
if (index < methods.length) {
|
||||
var method = methods[index];
|
||||
var self = this;
|
||||
this.runTestCase(method.name, method.script, method.expected, method.additionalScripts, function() {
|
||||
self.runMethodFromList(methods, index + 1, callback);
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.createTable = function(name) {
|
||||
this.table = document.createElement("table");
|
||||
this.container.appendChild(this.table);
|
||||
var caption = document.createElement("caption");
|
||||
this.table.appendChild(caption);
|
||||
this.createHeader();
|
||||
caption.appendChild(document.createTextNode(name));
|
||||
this.tableBody = document.createElement("tbody");
|
||||
this.table.appendChild(this.tableBody);
|
||||
}
|
||||
JUnitServer.prototype.createHeader = function() {
|
||||
var head = document.createElement("thead");
|
||||
this.table.appendChild(head);
|
||||
var headRow = document.createElement("tr");
|
||||
head.appendChild(headRow);
|
||||
var headCell = document.createElement("th");
|
||||
headRow.appendChild(headCell);
|
||||
headCell.appendChild(document.createTextNode("Method"));
|
||||
headCell = document.createElement("th");
|
||||
headRow.appendChild(headCell);
|
||||
headCell.appendChild(document.createTextNode("Result"));
|
||||
headCell = document.createElement("th");
|
||||
headRow.appendChild(headCell);
|
||||
headCell.appendChild(document.createTextNode("Exception"));
|
||||
headCell = document.createElement("th");
|
||||
headRow.appendChild(headCell);
|
||||
headCell.appendChild(document.createTextNode("Time spent, s"));
|
||||
this.table.appendChild(head);
|
||||
}
|
||||
JUnitServer.prototype.createFooter = function() {
|
||||
var foot = document.createElement("tfoot");
|
||||
this.table.appendChild(foot);
|
||||
var footRow = document.createElement("tr");
|
||||
foot.appendChild(footRow);
|
||||
var footName = document.createElement("td");
|
||||
footRow.appendChild(footName);
|
||||
footName.appendChild(document.createTextNode("---"));
|
||||
var footMethods = document.createElement("td");
|
||||
footRow.appendChild(footMethods);
|
||||
footMethods.appendChild(document.createTextNode(this.methodCount));
|
||||
var footSpace = document.createElement("td");
|
||||
footRow.appendChild(footSpace);
|
||||
footSpace.appendChild(document.createTextNode("---"));
|
||||
var footTime = document.createElement("td");
|
||||
footRow.appendChild(footTime);
|
||||
footTime.appendChild(document.createTextNode(this.timeSpent.toFixed(3)));
|
||||
}
|
||||
|
||||
JUnitClient = {};
|
||||
JUnitClient.run = function() {
|
||||
var handler = window.addEventListener("message", function() {
|
||||
window.removeEventListener("message", handler);
|
||||
var message = {};
|
||||
try {
|
||||
var instance = new TestClass();
|
||||
initInstance(instance);
|
||||
runTest(instance);
|
||||
message.status = "ok";
|
||||
} catch (e) {
|
||||
message.status = "exception";
|
||||
if (e.$javaException && e.$javaException.constructor.$meta) {
|
||||
message.exception = e.$javaException.constructor.$meta.name;
|
||||
message.stack = e.$javaException.constructor.$meta.name + ": ";
|
||||
var exceptionMessage = extractException(e.$javaException);
|
||||
message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : "";
|
||||
message.stack += "\n" + e.stack;
|
||||
} else {
|
||||
message.stack = e.stack;
|
||||
}
|
||||
}
|
||||
window.parent.postMessage(JSON.stringify(message), "*");
|
||||
});
|
||||
}
|
||||
JUnitClient.reportError = function(error) {
|
||||
var handler = window.addEventListener("message", function() {
|
||||
window.removeEventListener("message", handler);
|
||||
var message = { status : "exception", stack : error };
|
||||
window.parent.postMessage(JSON.stringify(message), "*");
|
||||
});
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 2px solid black;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
table td, table th {
|
||||
border: 1px solid gray;
|
||||
padding: 0.1em 0.5em 0.2em 0.5em;
|
||||
}
|
||||
table thead, table tfoot {
|
||||
border: 2px solid black;
|
||||
}
|
||||
iframe {
|
||||
with: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border-style: none;
|
||||
}
|
|
@ -19,17 +19,35 @@
|
|||
<title>TeaVM JUnit tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||
<title>TeaVM JUnit tests</title>
|
||||
<link rel="stylesheet" href="junit.css" type="text/css"/>
|
||||
<script type="text/javascript" src="junit-support.js"></script>
|
||||
<link rel="stylesheet" href="res/junit.css" type="text/css"/>
|
||||
<script type="text/javascript" src="res/junit-support.js"></script>
|
||||
<script type="text/javascript" src="tests/all.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
function runTests() {
|
||||
document.getElementById("start-button").style.display = "none";
|
||||
doRunTests();
|
||||
document.getElementById("start-button").disabled = true;
|
||||
server.runAllTests(function() {
|
||||
document.getElementById("start-button").disabled = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<button id="start-button" onclick="runTests()">Run tests</button>
|
||||
<div class="test-header">
|
||||
<div class="test-count">Total tests:
|
||||
<span id="test-count"></span><span id="total-time" class="time-indicator"></span>
|
||||
</div>
|
||||
<div class="failed-test-count">Failed: <span id="failed-test-count"></span></div>
|
||||
<div class="progress-bar">
|
||||
<div id="progress-bar-content"></div>
|
||||
</div>
|
||||
<button id="start-button" onclick="runTests()">Run</button>
|
||||
</div>
|
||||
<div id="test-tree">
|
||||
</div>
|
||||
<div id="test-trace">
|
||||
</div>
|
||||
<script>
|
||||
server = prepare();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 774 B |
After Width: | Height: | Size: 297 B |
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
* Copyright 2013 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
JUnitServer = function() {
|
||||
this.tree = new Tree(document.getElementById("test-tree"));
|
||||
this.totalTimeSpent = 0;
|
||||
this.expectedExceptions = [];
|
||||
this.frame = null;
|
||||
this.tests = [];
|
||||
this.currentTestNode = null;
|
||||
this.testCaseCount = 0;
|
||||
this.progressElem = document.getElementById("progress-bar-content");
|
||||
this.runCount = 0;
|
||||
this.failCount = 0;
|
||||
this.traceElem = document.getElementById("test-trace");
|
||||
this.failedElem = document.getElementById("failed-test-count");
|
||||
this.totalTimeElem = document.getElementById("total-time");
|
||||
var self = this;
|
||||
this.tree.addSelectionListener(function(node) {
|
||||
while (self.traceElem.firstChild) {
|
||||
self.traceElem.removeChild(self.traceElem.firstChild);
|
||||
}
|
||||
if (node.error) {
|
||||
var pre = document.createElement("pre");
|
||||
pre.appendChild(document.createTextNode(node.error));
|
||||
self.traceElem.appendChild(pre);
|
||||
}
|
||||
});
|
||||
}
|
||||
JUnitServer.prototype = new Object();
|
||||
JUnitServer.prototype.handleEvent = function(message, callback) {
|
||||
if (message.status === "ok") {
|
||||
if (this.expectedExceptions.length > 0) {
|
||||
this.currentTestNode.success = false;
|
||||
this.currentTestNode.error = "Expected exception not thrown";
|
||||
this.failCount++;
|
||||
} else {
|
||||
this.currentTestNode.success = true;
|
||||
}
|
||||
} else if (message.status === "exception") {
|
||||
if (message.exception && this.isExpectedException(message.exception)) {
|
||||
this.currentTestNode.success = true;
|
||||
} else {
|
||||
this.currentTestNode.success = false;
|
||||
this.currentTestNode.error = message.stack;
|
||||
this.failCount++;
|
||||
}
|
||||
}
|
||||
this.currentTestNode.indicator.className = "complete-indicator " +
|
||||
(this.currentTestNode.success ? "successfull" : "failed");
|
||||
this.runCount++;
|
||||
this.progressElem.style.width = (100 * this.runCount / this.testCaseCount).toFixed(2) + "%";
|
||||
document.body.removeChild(this.frame);
|
||||
self.frame = null;
|
||||
callback();
|
||||
}
|
||||
JUnitServer.prototype.isExpectedException = function(ex) {
|
||||
for (var i = 0; i < this.expectedExceptions.length; ++i) {
|
||||
if (this.expectedExceptions[i] === ex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
JUnitServer.prototype.loadCode = function(path, additionalScripts, callback) {
|
||||
this.frame = document.createElement("iframe");
|
||||
document.body.appendChild(this.frame);
|
||||
var frameDoc = this.frame.contentWindow.document;
|
||||
var self = this;
|
||||
var sequence = ["res/junit-support.js", "res/runtime.js"];
|
||||
if (additionalScripts) {
|
||||
for (var i = 0; i < additionalScripts.length; ++i) {
|
||||
sequence.push(additionalScripts[i]);
|
||||
}
|
||||
}
|
||||
sequence.push(path);
|
||||
self.loadScripts(sequence, 0, callback);
|
||||
}
|
||||
JUnitServer.prototype.loadScripts = function(scripts, index, callback) {
|
||||
var self = this;
|
||||
if (index == scripts.length) {
|
||||
callback();
|
||||
} else {
|
||||
this.loadScript(scripts[index], function() { self.loadScripts(scripts, index + 1, callback) });
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.loadScript = function(name, callback) {
|
||||
var doc = this.frame.contentWindow.document;
|
||||
var script = doc.createElement("script");
|
||||
script.src = name;
|
||||
doc.body.appendChild(script);
|
||||
script.onload = function() {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.runTest = function(node, callback) {
|
||||
node.indicator.className = "complete-indicator in-progress";
|
||||
var startTime = new Date().getTime();
|
||||
if (node.testCase) {
|
||||
this.expectedExceptions = node.testCase.expected;
|
||||
this.currentTestNode = node;
|
||||
var self = this;
|
||||
this.loadCode(node.testCase.script, node.testCase.additionalScripts, function() {
|
||||
messageHandler = function(event) {
|
||||
window.removeEventListener("message", messageHandler);
|
||||
var timeSpent = new Date().getTime() - startTime;
|
||||
node.timeIndicator.appendChild(document.createTextNode(
|
||||
"(" + (timeSpent / 1000).toFixed(3) + ")"));
|
||||
self.handleEvent(JSON.parse(event.data), callback);
|
||||
};
|
||||
window.addEventListener("message", messageHandler);
|
||||
self.frame.contentWindow.postMessage("runTest", "*");
|
||||
});
|
||||
} else {
|
||||
var self = this;
|
||||
var nodes = node.getNodes();
|
||||
this.runTestFromList(nodes, 0, function() {
|
||||
node.success = true;
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (!nodes[i].success) {
|
||||
node.success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node.indicator.className = "complete-indicator " +
|
||||
(node.success ? "successfull" : "failed");
|
||||
if (!node.success) {
|
||||
node.open();
|
||||
}
|
||||
var timeSpent = new Date().getTime() - startTime;
|
||||
node.timeIndicator.appendChild(document.createTextNode(
|
||||
"(" + (timeSpent / 1000).toFixed(3) + ")"));
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.readTests = function(tests) {
|
||||
var groups = this.groupTests(tests);
|
||||
var groupNames = [];
|
||||
for (var groupName in groups) {
|
||||
groupNames.push(groupName);
|
||||
}
|
||||
groupNames.sort();
|
||||
this.tests = [];
|
||||
for (var i = 0; i < groupNames.length; ++i) {
|
||||
var groupName = groupNames[i];
|
||||
var group = groups[groupName];
|
||||
var pkgNode = this.createNode(this.tree, "package", groupName);
|
||||
group.sort();
|
||||
for (var j = 0; j < group.length; ++j) {
|
||||
var test = group[j];
|
||||
var simpleName = test.name.substring(groupName.length + 1);
|
||||
var testNode = this.createNode(pkgNode, "test", simpleName);
|
||||
var methods = test.methods.slice();
|
||||
methods.sort();
|
||||
for (var k = 0; k < methods.length; ++k) {
|
||||
var method = methods[k];
|
||||
var caseNode = this.createNode(testNode, "case", method.name);
|
||||
caseNode.testCase = method;
|
||||
++this.testCaseCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
document.getElementById("test-count").appendChild(document.createTextNode(this.testCaseCount));
|
||||
return this;
|
||||
}
|
||||
JUnitServer.prototype.createNode = function(parent, className, name) {
|
||||
var elem = document.createElement("div");
|
||||
elem.className = className;
|
||||
elem.appendChild(document.createTextNode(name));
|
||||
var node = parent.add(elem);
|
||||
node.indicator = document.createElement("div");
|
||||
node.indicator.className = "complete-indicator";
|
||||
elem.appendChild(node.indicator);
|
||||
node.timeIndicator = document.createElement("span");
|
||||
node.timeIndicator.className = "time-indicator";
|
||||
elem.appendChild(node.timeIndicator);
|
||||
return node;
|
||||
}
|
||||
JUnitServer.prototype.groupTests = function(tests) {
|
||||
var groups = {};
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
var test = tests[i];
|
||||
var pkg = test.name.substring(0, test.name.lastIndexOf('.'));
|
||||
var group = groups[pkg];
|
||||
if (!group) {
|
||||
group = [];
|
||||
groups[pkg] = group;
|
||||
}
|
||||
group.push(test);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
JUnitServer.prototype.runAllTests = function(callback) {
|
||||
this.cleanupTests();
|
||||
var self = this;
|
||||
var startTime = new Date().getTime();
|
||||
this.runTestFromList(this.tree.getNodes(), 0, function() {
|
||||
self.failedElem.appendChild(document.createTextNode(self.failCount));
|
||||
var totalTime = new Date().getTime() - startTime;
|
||||
self.totalTimeElem.appendChild(document.createTextNode("(" +
|
||||
(totalTime / 1000).toFixed(3) + ")"));
|
||||
callback();
|
||||
});
|
||||
}
|
||||
JUnitServer.prototype.runTestFromList = function(nodes, index, callback) {
|
||||
if (index < nodes.length) {
|
||||
var node = nodes[index];
|
||||
var self = this;
|
||||
this.runTest(node, function() {
|
||||
self.runTestFromList(nodes, index + 1, callback);
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.cleanupTests = function() {
|
||||
if (this.failedElem.firstChild) {
|
||||
this.failedElem.removeChild(this.failedElem.firstChild);
|
||||
}
|
||||
if (this.totalTimeElem.firstChild) {
|
||||
this.totalTimeElem.removeChild(this.totalTimeElem.firstChild);
|
||||
}
|
||||
this.runCount = 0;
|
||||
this.progressElem.style.width = "0%";
|
||||
var nodes = this.tree.getNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
this.cleanupNode(nodes[i]);
|
||||
}
|
||||
}
|
||||
JUnitServer.prototype.cleanupNode = function(node) {
|
||||
delete node.error;
|
||||
node.indicator.className = "complete-indicator";
|
||||
if (node.timeIndicator.firstChild) {
|
||||
node.timeIndicator.removeChild(node.timeIndicator.firstChild);
|
||||
}
|
||||
var nodes = node.getNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
this.cleanupNode(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Tree = function(container) {
|
||||
this.container = container;
|
||||
this.nodes = [];
|
||||
this.selectedNode = null;
|
||||
this.selectionListeners = [];
|
||||
}
|
||||
Tree.prototype.createNode = function(content) {
|
||||
var elem = document.createElement("div");
|
||||
elem.className = "tree-node";
|
||||
var contentElem = document.createElement("div");
|
||||
contentElem.className = "tree-node-content";
|
||||
elem.appendChild(contentElem);
|
||||
contentElem.appendChild(content);
|
||||
var buttonElem = document.createElement("div");
|
||||
buttonElem.className = "tree-node-button closed";
|
||||
buttonElem.style.display = "none";
|
||||
elem.appendChild(buttonElem);
|
||||
var childrenElem = document.createElement("div");
|
||||
childrenElem.className = "tree-node-children closed";
|
||||
childrenElem.style.display = "none";
|
||||
elem.appendChild(childrenElem);
|
||||
return new TreeNode(elem, contentElem, buttonElem, childrenElem, this);
|
||||
}
|
||||
Tree.prototype.add = function(content) {
|
||||
var node = this.createNode(content);
|
||||
this.container.appendChild(node.elem);
|
||||
this.nodes.push(node);
|
||||
return node;
|
||||
}
|
||||
Tree.prototype.getNodes = function() {
|
||||
return this.nodes;
|
||||
}
|
||||
Tree.prototype.addSelectionListener = function(listener) {
|
||||
this.selectionListeners.push(listener);
|
||||
}
|
||||
TreeNode = function(elem, content, button, children, tree) {
|
||||
this.elem = elem;
|
||||
this.content = content;
|
||||
this.button = button;
|
||||
this.children = children;
|
||||
this.opened = false;
|
||||
this.parent = null;
|
||||
this.nodes = [];
|
||||
this.tree = tree;
|
||||
var self = this;
|
||||
this.button.onclick = function() {
|
||||
self.toggle();
|
||||
}
|
||||
this.content.onclick = function() {
|
||||
self.select();
|
||||
}
|
||||
}
|
||||
TreeNode.prototype.add = function(content) {
|
||||
var node = this.tree.createNode(content);
|
||||
this.children.appendChild(node.elem);
|
||||
this.button.style.display = "";
|
||||
this.children.style.display = "";
|
||||
this.content.className = "tree-node-content";
|
||||
node.parent = this;
|
||||
this.nodes.push(node);
|
||||
return node;
|
||||
}
|
||||
TreeNode.prototype.isOpened = function() {
|
||||
return this.opened;
|
||||
}
|
||||
TreeNode.prototype.open = function() {
|
||||
if (this.isOpened()) {
|
||||
return;
|
||||
}
|
||||
this.opened = true;
|
||||
this.children.className = "tree-node-children opened";
|
||||
this.button.className = "tree-node-button opened";
|
||||
}
|
||||
TreeNode.prototype.close = function() {
|
||||
if (!this.isOpened()) {
|
||||
return;
|
||||
}
|
||||
this.opened = false;
|
||||
this.children.className = "tree-node-children closed";
|
||||
this.button.className = "tree-node-button closed";
|
||||
}
|
||||
TreeNode.prototype.toggle = function() {
|
||||
if (this.isOpened()) {
|
||||
this.close();
|
||||
} else {
|
||||
this.open();
|
||||
}
|
||||
}
|
||||
TreeNode.prototype.getNodes = function() {
|
||||
return this.nodes;
|
||||
}
|
||||
TreeNode.prototype.getParent = function() {
|
||||
return this.parent;
|
||||
}
|
||||
TreeNode.prototype.getTree = function() {
|
||||
return this.tree;
|
||||
}
|
||||
TreeNode.prototype.isSelected = function() {
|
||||
return this.tree.selectedNode === this;
|
||||
}
|
||||
TreeNode.prototype.select = function() {
|
||||
if (this.isSelected()) {
|
||||
return;
|
||||
}
|
||||
if (this.tree.selectedNode != null) {
|
||||
this.tree.selectedNode.content.className = "tree-node-content";
|
||||
}
|
||||
this.content.className = "tree-node-content selected";
|
||||
this.tree.selectedNode = this;
|
||||
for (var i = 0; i < this.tree.selectionListeners.length; ++i) {
|
||||
this.tree.selectionListeners[i](this);
|
||||
}
|
||||
}
|
||||
|
||||
JUnitClient = {};
|
||||
JUnitClient.run = function() {
|
||||
var handler = window.addEventListener("message", function() {
|
||||
window.removeEventListener("message", handler);
|
||||
var message = {};
|
||||
try {
|
||||
var instance = new TestClass();
|
||||
initInstance(instance);
|
||||
runTest(instance);
|
||||
message.status = "ok";
|
||||
} catch (e) {
|
||||
message.status = "exception";
|
||||
if (e.$javaException && e.$javaException.constructor.$meta) {
|
||||
message.exception = e.$javaException.constructor.$meta.name;
|
||||
message.stack = e.$javaException.constructor.$meta.name + ": ";
|
||||
var exceptionMessage = extractException(e.$javaException);
|
||||
message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : "";
|
||||
message.stack += "\n" + e.stack;
|
||||
} else {
|
||||
message.stack = e.stack;
|
||||
}
|
||||
}
|
||||
window.parent.postMessage(JSON.stringify(message), "*");
|
||||
});
|
||||
}
|
||||
JUnitClient.reportError = function(error) {
|
||||
var handler = window.addEventListener("message", function() {
|
||||
window.removeEventListener("message", handler);
|
||||
var message = { status : "exception", stack : error };
|
||||
window.parent.postMessage(JSON.stringify(message), "*");
|
||||
});
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright 2013 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
iframe {
|
||||
with: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border-style: none;
|
||||
}
|
||||
* {
|
||||
font-family: sans;
|
||||
font-size: 10pt;
|
||||
}
|
||||
html, body {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
.test-header {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
height: 40px;
|
||||
border-bottom-color: gray;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
.test-count, .failed-test-count {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
line-height: 40px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.test-count {
|
||||
left: 5px;
|
||||
width: 200px;
|
||||
}
|
||||
.failed-test-count {
|
||||
left: 205px;
|
||||
width: 130px;
|
||||
}
|
||||
#start-button {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 340px;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
width: 70px;
|
||||
}
|
||||
.progress-bar {
|
||||
position: absolute;
|
||||
left: 420px;
|
||||
right: 20px;
|
||||
top: 5px;
|
||||
height: 30px;
|
||||
border-color: grey;
|
||||
border-radius: 2px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
#progress-bar-content {
|
||||
position: absolute;
|
||||
background-color: green;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
width: 0%;
|
||||
}
|
||||
#test-tree {
|
||||
position: absolute;
|
||||
top: 41px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: 50%;
|
||||
border-right-color: grey;
|
||||
border-right-width: 1px;
|
||||
border-right-style: solid;
|
||||
overflow: auto;
|
||||
}
|
||||
#test-trace {
|
||||
position: absolute;
|
||||
top: 41px;
|
||||
bottom: 0px;
|
||||
left: 50%;
|
||||
right: 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
.tree-node {
|
||||
position: relative;
|
||||
}
|
||||
.tree-node-content {
|
||||
margin-left: 18px;
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tree-node-content.selected {
|
||||
background-color: rgb(160,160,255);
|
||||
}
|
||||
.tree-node-children {
|
||||
padding-left: 18px;
|
||||
}
|
||||
.tree-node-children.closed {
|
||||
display: none;
|
||||
}
|
||||
.tree-node-button {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0px 0px;
|
||||
}
|
||||
.tree-node-button.opened {
|
||||
background-image: url(toggle-small.png);
|
||||
}
|
||||
.tree-node-button.closed {
|
||||
background-image: url(toggle-small-expand.png);
|
||||
}
|
||||
.package, .test, .case {
|
||||
min-height: 18px;
|
||||
padding-left: 20px;
|
||||
background-position: 2px 1px;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
}
|
||||
.package {
|
||||
background-image: url(package_obj.png);
|
||||
}
|
||||
.test {
|
||||
background-image: url(class_obj.png);
|
||||
}
|
||||
.case {
|
||||
background-image: url(methpub_obj.png);
|
||||
}
|
||||
.complete-indicator {
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: 5px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: 0px 0px;
|
||||
background-repeat: no-repeat;
|
||||
display: none;
|
||||
}
|
||||
.complete-indicator.successfull {
|
||||
display: block;
|
||||
background-image: url(tick-small.png);
|
||||
}
|
||||
.complete-indicator.failed {
|
||||
display: block;
|
||||
background-image: url(tick-small-red.png);
|
||||
}
|
||||
.complete-indicator.in-progress {
|
||||
display: block;
|
||||
background-image: url(control-000-small.png);
|
||||
}
|
||||
.time-indicator {
|
||||
font-size: 9pt;
|
||||
font-style: italic;
|
||||
color: rgb(0,80,160);
|
||||
padding-left: 0.5em;
|
||||
}
|
After Width: | Height: | Size: 325 B |
After Width: | Height: | Size: 345 B |
|
@ -0,0 +1,732 @@
|
|||
/*
|
||||
* Copyright 2013 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
$rt_lastObjectId = 0;
|
||||
$rt_nextId = function() {
|
||||
return $rt_lastObjectId++;
|
||||
}
|
||||
$rt_compare = function(a, b) {
|
||||
return a > b ? 1 : a < b ? -1 : 0;
|
||||
}
|
||||
$rt_isInstance = function(obj, cls) {
|
||||
return obj != null && obj.constructor.$meta && $rt_isAssignable(obj.constructor, cls);
|
||||
}
|
||||
$rt_isAssignable = function(from, to) {
|
||||
if (from === to) {
|
||||
return true;
|
||||
}
|
||||
var supertypes = from.$meta.supertypes;
|
||||
for (var i = 0; i < supertypes.length; i = (i + 1) | 0) {
|
||||
if ($rt_isAssignable(supertypes[i], to)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$rt_createArray = function(cls, sz) {
|
||||
var data = new Array(sz);
|
||||
var arr = new ($rt_arraycls(cls))(data);
|
||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||
data[i] = null;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
$rt_wrapArray = function(cls, data) {
|
||||
var arr = new ($rt_arraycls(cls))(data);
|
||||
return arr;
|
||||
}
|
||||
$rt_createUnfilledArray = function(cls, sz) {
|
||||
return new ($rt_arraycls(cls))(new Array(sz));
|
||||
}
|
||||
$rt_createLongArray = function(sz) {
|
||||
var data = new Array(sz);
|
||||
var arr = new ($rt_arraycls($rt_longcls()))(data);
|
||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||
data[i] = Long.ZERO;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
if (ArrayBuffer) {
|
||||
$rt_createNumericArray = function(cls, nativeArray) {
|
||||
return new ($rt_arraycls(cls))(nativeArray);
|
||||
}
|
||||
$rt_createByteArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_bytecls(), new Int8Array(new ArrayBuffer(sz)), 0);
|
||||
};
|
||||
$rt_createShortArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_shortcls(), new Int16Array(new ArrayBuffer(sz << 1)), 0);
|
||||
};
|
||||
$rt_createIntArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_intcls(), new Int32Array(new ArrayBuffer(sz << 2)), 0);
|
||||
};
|
||||
$rt_createBooleanArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_booleancls(), new Int8Array(new ArrayBuffer(sz)), 0);
|
||||
};
|
||||
$rt_createFloatArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_floatcls(), new Float32Array(new ArrayBuffer(sz << 2)), 0);
|
||||
};
|
||||
$rt_createDoubleArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_doublecls(), new Float64Array(new ArrayBuffer(sz << 3)), 0);
|
||||
};
|
||||
$rt_createCharArray = function(sz) {
|
||||
return $rt_createNumericArray($rt_charcls(), new Uint16Array(new ArrayBuffer(sz << 1)), 0);
|
||||
};
|
||||
} else {
|
||||
$rt_createNumericArray = function(cls, sz) {
|
||||
var data = new Array(sz);
|
||||
var arr = new ($rt_arraycls(cls))(data);
|
||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||
data[i] = 0;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
$rt_createByteArray = function(sz) { return $rt_createNumericArray($rt_bytecls(), sz); }
|
||||
$rt_createShortArray = function(sz) { return $rt_createNumericArray($rt_shortcls(), sz); }
|
||||
$rt_createIntArray = function(sz) { return $rt_createNumericArray($rt_intcls(), sz); }
|
||||
$rt_createBooleanArray = function(sz) { return $rt_createNumericArray($rt_booleancls(), sz); }
|
||||
$rt_createFloatArray = function(sz) { return $rt_createNumericArray($rt_floatcls(), sz); }
|
||||
$rt_createDoubleArray = function(sz) { return $rt_createNumericArray($rt_doublecls(), sz); }
|
||||
$rt_createCharArray = function(sz) { return $rt_createNumericArray($rt_charcls(), sz); }
|
||||
}
|
||||
$rt_arraycls = function(cls) {
|
||||
if (cls.$array == undefined) {
|
||||
var arraycls = function(data) {
|
||||
this.data = data;
|
||||
this.$id = $rt_nextId();
|
||||
};
|
||||
arraycls.prototype = new ($rt_objcls())();
|
||||
arraycls.prototype.constructor = arraycls;
|
||||
arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false, superclass : $rt_objcls() };
|
||||
cls.$array = arraycls;
|
||||
}
|
||||
return cls.$array;
|
||||
}
|
||||
$rt_createcls = function() {
|
||||
return {
|
||||
$meta : {
|
||||
supertypes : []
|
||||
}
|
||||
};
|
||||
}
|
||||
$rt_booleanclsCache = null;
|
||||
$rt_booleancls = function() {
|
||||
if ($rt_booleanclsCache == null) {
|
||||
$rt_booleanclsCache = $rt_createcls();
|
||||
$rt_booleanclsCache.primitive = true;
|
||||
$rt_booleanclsCache.name = "boolean";
|
||||
}
|
||||
return $rt_booleanclsCache;
|
||||
}
|
||||
$rt_charclsCache = null;
|
||||
$rt_charcls = function() {
|
||||
if ($rt_charclsCache == null) {
|
||||
$rt_charclsCache = $rt_createcls();
|
||||
$rt_charclsCache.primitive = true;
|
||||
$rt_charclsCache.name = "char";
|
||||
}
|
||||
return $rt_charclsCache;
|
||||
}
|
||||
$rt_byteclsCache = null;
|
||||
$rt_bytecls = function() {
|
||||
if ($rt_byteclsCache == null) {
|
||||
$rt_byteclsCache = $rt_createcls();
|
||||
$rt_byteclsCache.primitive = true;
|
||||
$rt_byteclsCache.name = "byte";
|
||||
}
|
||||
return $rt_byteclsCache;
|
||||
}
|
||||
$rt_shortclsCache = null;
|
||||
$rt_shortcls = function() {
|
||||
if ($rt_shortclsCache == null) {
|
||||
$rt_shortclsCache = $rt_createcls();
|
||||
$rt_shortclsCache.primitive = true;
|
||||
$rt_shortclsCache.name = "short";
|
||||
}
|
||||
return $rt_shortclsCache;
|
||||
}
|
||||
$rt_intclsCache = null;
|
||||
$rt_intcls = function() {
|
||||
if ($rt_intclsCache === null) {
|
||||
$rt_intclsCache = $rt_createcls();
|
||||
$rt_intclsCache.primitive = true;
|
||||
$rt_intclsCache.name = "int";
|
||||
}
|
||||
return $rt_intclsCache;
|
||||
}
|
||||
$rt_longclsCache = null;
|
||||
$rt_longcls = function() {
|
||||
if ($rt_longclsCache === null) {
|
||||
$rt_longclsCache = $rt_createcls();
|
||||
$rt_longclsCache.primitive = true;
|
||||
$rt_longclsCache.name = "long";
|
||||
}
|
||||
return $rt_longclsCache;
|
||||
}
|
||||
$rt_floatclsCache = null;
|
||||
$rt_floatcls = function() {
|
||||
if ($rt_floatclsCache === null) {
|
||||
$rt_floatclsCache = $rt_createcls();
|
||||
$rt_floatclsCache.primitive = true;
|
||||
$rt_floatclsCache.name = "float";
|
||||
}
|
||||
return $rt_floatclsCache;
|
||||
}
|
||||
$rt_doubleclsCache = null;
|
||||
$rt_doublecls = function() {
|
||||
if ($rt_doubleclsCache === null) {
|
||||
$rt_doubleclsCache = $rt_createcls();
|
||||
$rt_doubleclsCache.primitive = true;
|
||||
$rt_doubleclsCache.name = "double";
|
||||
}
|
||||
return $rt_doubleclsCache;
|
||||
}
|
||||
$rt_voidclsCache = null;
|
||||
$rt_voidcls = function() {
|
||||
if ($rt_voidclsCache === null) {
|
||||
$rt_voidclsCache = $rt_createcls();
|
||||
$rt_voidclsCache.primitive = true;
|
||||
$rt_voidclsCache.name = "void";
|
||||
}
|
||||
return $rt_voidclsCache;
|
||||
}
|
||||
$rt_equals = function(a, b) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
if (a === null || b === null) {
|
||||
return false;
|
||||
}
|
||||
if (typeof(a) == 'object') {
|
||||
return a.equals(b);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$rt_clinit = function(cls) {
|
||||
if (cls.$clinit) {
|
||||
var f = cls.$clinit;
|
||||
delete cls.$clinit;
|
||||
f();
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
$rt_init = function(cls, constructor, args) {
|
||||
var obj = new cls();
|
||||
cls.prototype[constructor].apply(obj, args);
|
||||
return obj;
|
||||
}
|
||||
$rt_throw = function(ex) {
|
||||
var err = ex.$jsException;
|
||||
if (!err) {
|
||||
var err = new Error("Java exception thrown");
|
||||
err.$javaException = ex;
|
||||
ex.$jsException = err;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
$rt_byteToInt = function(value) {
|
||||
return value > 0xFF ? value | 0xFFFFFF00 : value;
|
||||
}
|
||||
$rt_shortToInt = function(value) {
|
||||
return value > 0xFFFF ? value | 0xFFFF0000 : value;
|
||||
}
|
||||
$rt_createMultiArray = function(cls, dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createArray(cls, firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl(cls, arrays, dimensions);
|
||||
}
|
||||
$rt_createByteMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createByteArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_bytecls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createBooleanMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createBooleanArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_booleancls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createShortMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createShortArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_shortcls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createIntMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createIntArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_intcls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createLongMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createLongArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_longcls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createFloatMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createFloatArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_floatcls(), arrays, dimensions);
|
||||
}
|
||||
$rt_createDoubleMultiArray = function(dimensions) {
|
||||
var arrays = new Array($rt_primitiveArrayCount(dimensions));
|
||||
var firstDim = dimensions[0] | 0;
|
||||
for (var i = 0 | 0; i < arrays.length; i = (i + 1) | 0) {
|
||||
arrays[i] = $rt_createDoubleArray(firstDim);
|
||||
}
|
||||
return $rt_createMultiArrayImpl($rt_doublecls(), arrays, dimensions);
|
||||
}
|
||||
$rt_primitiveArrayCount = function(dimensions) {
|
||||
var val = dimensions[1] | 0;
|
||||
for (var i = 2 | 0; i < dimensions.length; i = (i + 1) | 0) {
|
||||
val = (val * (dimensions[i] | 0)) | 0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
$rt_createMultiArrayImpl = function(cls, arrays, dimensions) {
|
||||
var limit = arrays.length;
|
||||
for (var i = 1 | 0; i < dimensions.length; i = (i + 1) | 0) {
|
||||
cls = $rt_arraycls(cls);
|
||||
var dim = dimensions[i];
|
||||
var index = 0;
|
||||
var packedIndex = 0;
|
||||
while (index < limit) {
|
||||
var arr = $rt_createUnfilledArray(cls, dim);
|
||||
for (var j = 0; j < dim; j = (j + 1) | 0) {
|
||||
arr.data[j] = arrays[index];
|
||||
index = (index + 1) | 0;
|
||||
}
|
||||
arrays[packedIndex] = arr;
|
||||
packedIndex = (packedIndex + 1) | 0;
|
||||
}
|
||||
limit = packedIndex;
|
||||
}
|
||||
return arrays[0];
|
||||
}
|
||||
$rt_assertNotNaN = function(value) {
|
||||
if (typeof value == 'number' && isNaN(value)) {
|
||||
throw "NaN";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
$rt_methodStubs = function(clinit, names) {
|
||||
for (var i = 0; i < names.length; i = (i + 1) | 0) {
|
||||
window[names[i]] = (function(name) {
|
||||
return function() {
|
||||
clinit();
|
||||
return window[name].apply(window, arguments);
|
||||
}
|
||||
})(names[i]);
|
||||
}
|
||||
}
|
||||
$rt_stdoutBuffer = "";
|
||||
$rt_putStdout = function(ch) {
|
||||
if (ch === 0xA) {
|
||||
if (console) {
|
||||
console.info($rt_stdoutBuffer);
|
||||
}
|
||||
$rt_stdoutBuffer = "";
|
||||
} else {
|
||||
$rt_stdoutBuffer += String.fromCharCode(ch);
|
||||
}
|
||||
}
|
||||
$rt_stderrBuffer = "";
|
||||
$rt_putStderr = function(ch) {
|
||||
if (ch === 0xA) {
|
||||
if (console) {
|
||||
console.info($rt_stderrBuffer);
|
||||
}
|
||||
$rt_stderrBuffer = "";
|
||||
} else {
|
||||
$rt_stderrBuffer += String.fromCharCode(ch);
|
||||
}
|
||||
}
|
||||
function $rt_declClass(cls, data) {
|
||||
cls.name = data.name;
|
||||
cls.$meta = {};
|
||||
cls.$meta.superclass = data.superclass;
|
||||
cls.$meta.supertypes = data.interfaces ? data.interfaces.slice() : [];
|
||||
if (data.superclass) {
|
||||
cls.$meta.supertypes.push(data.superclass);
|
||||
cls.prototype = new data.superclass();
|
||||
} else {
|
||||
cls.prototype = new Object();
|
||||
}
|
||||
cls.$meta.name = data.name;
|
||||
cls.$meta.enum = data.enum;
|
||||
cls.prototype.constructor = cls;
|
||||
cls.$clinit = data.clinit;
|
||||
}
|
||||
function $rt_virtualMethods(cls) {
|
||||
for (var i = 1; i < arguments.length; i += 2) {
|
||||
var name = arguments[i];
|
||||
var func = arguments[i + 1];
|
||||
if (typeof name == 'string') {
|
||||
cls.prototype[name] = func;
|
||||
} else {
|
||||
for (var j = 0; j < name.length; ++j) {
|
||||
cls.prototype[name[j]] = func;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Long = function(lo, hi) {
|
||||
this.lo = lo | 0;
|
||||
this.hi = hi | 0;
|
||||
}
|
||||
Long_ZERO = new Long(0, 0);
|
||||
Long_fromInt = function(val) {
|
||||
return val >= 0 ? new Long(val, 0) : new Long(val, -1);
|
||||
}
|
||||
Long_fromNumber = function(val) {
|
||||
return new Long(val | 0, (val / 0x100000000) | 0);
|
||||
}
|
||||
Long_toNumber = function(val) {
|
||||
return val.hi >= 0 ? val.lo + 0x100000000 * val.hi : -0x100000000 * (val.hi ^ 0xFFFFFFFF) + val.lo;
|
||||
}
|
||||
Long_add = function(a, b) {
|
||||
var a_lolo = a.lo & 0xFFFF;
|
||||
var a_lohi = a.lo >>> 16;
|
||||
var a_hilo = a.hi & 0xFFFF;
|
||||
var a_hihi = a.hi >>> 16;
|
||||
var b_lolo = b.lo & 0xFFFF;
|
||||
var b_lohi = b.lo >>> 16;
|
||||
var b_hilo = b.hi & 0xFFFF;
|
||||
var b_hihi = b.hi >>> 16;
|
||||
|
||||
var lolo = (a_lolo + b_lolo) | 0;
|
||||
var lohi = (a_lohi + b_lohi + (lolo >> 16)) | 0;
|
||||
var hilo = (a_hilo + b_hilo + (lohi >> 16)) | 0;
|
||||
var hihi = (a_hihi + b_hihi + (hilo >> 16)) | 0;
|
||||
return new Long((lolo & 0xFFFF) | ((lohi & 0xFFFF) << 16),
|
||||
(hilo & 0xFFFF) | ((hihi & 0xFFFF) << 16));
|
||||
}
|
||||
Long_inc = function(a) {
|
||||
var lo = (a.lo + 1) | 0;
|
||||
var hi = a.hi;
|
||||
if (lo === 0) {
|
||||
hi = (hi + 1) | 0;
|
||||
}
|
||||
return new Long(lo, hi);
|
||||
}
|
||||
Long_dec = function(a) {
|
||||
var lo = (a.lo - 1) | 0;
|
||||
var hi = a.hi;
|
||||
if (lo === -1) {
|
||||
hi = (hi - 1) | 0;
|
||||
}
|
||||
return new Long(lo, hi);
|
||||
}
|
||||
Long_neg = function(a) {
|
||||
return Long_inc(new Long(a.lo ^ 0xFFFFFFFF, a.hi ^ 0xFFFFFFFF));
|
||||
}
|
||||
Long_sub = function(a, b) {
|
||||
var a_lolo = a.lo & 0xFFFF;
|
||||
var a_lohi = a.lo >>> 16;
|
||||
var a_hilo = a.hi & 0xFFFF;
|
||||
var a_hihi = a.hi >>> 16;
|
||||
var b_lolo = b.lo & 0xFFFF;
|
||||
var b_lohi = b.lo >>> 16;
|
||||
var b_hilo = b.hi & 0xFFFF;
|
||||
var b_hihi = b.hi >>> 16;
|
||||
|
||||
var lolo = (a_lolo - b_lolo) | 0;
|
||||
var lohi = (a_lohi - b_lohi + (lolo >> 16)) | 0;
|
||||
var hilo = (a_hilo - b_hilo + (lohi >> 16)) | 0;
|
||||
var hihi = (a_hihi - b_hihi + (hilo >> 16)) | 0;
|
||||
return new Long((lolo & 0xFFFF) | ((lohi & 0xFFFF) << 16),
|
||||
(hilo & 0xFFFF) | ((hihi & 0xFFFF) << 16));
|
||||
}
|
||||
Long_compare = function(a, b) {
|
||||
var r = a.hi - b.hi;
|
||||
if (r !== 0) {
|
||||
return r;
|
||||
}
|
||||
var r = (a.lo >>> 1) - (b.lo >>> 1);
|
||||
if (r !== 0) {
|
||||
return r;
|
||||
}
|
||||
return (a.lo & 1) - (b.lo & 1);
|
||||
}
|
||||
Long_isPositive = function(a) {
|
||||
return (a.hi & 0x80000000) === 0;
|
||||
}
|
||||
Long_isNegative = function(a) {
|
||||
return (a.hi & 0x80000000) !== 0;
|
||||
}
|
||||
Long_mul = function(a, b) {
|
||||
var positive = Long_isNegative(a) === Long_isNegative(b);
|
||||
if (Long_isNegative(a)) {
|
||||
a = Long_neg(a);
|
||||
}
|
||||
if (Long_isNegative(b)) {
|
||||
b = Long_neg(b);
|
||||
}
|
||||
var a_lolo = a.lo & 0xFFFF;
|
||||
var a_lohi = a.lo >>> 16;
|
||||
var a_hilo = a.hi & 0xFFFF;
|
||||
var a_hihi = a.hi >>> 16;
|
||||
var b_lolo = b.lo & 0xFFFF;
|
||||
var b_lohi = b.lo >>> 16;
|
||||
var b_hilo = b.hi & 0xFFFF;
|
||||
var b_hihi = b.hi >>> 16;
|
||||
|
||||
var lolo = (a_lolo * b_lolo) | 0;
|
||||
var lohi = (a_lohi * b_lolo + a_lolo * b_lohi + (lolo >> 16)) | 0;
|
||||
var hilo = (a_hilo * b_lolo + a_lohi * b_lohi + a_lolo * b_hilo + (lohi >> 16)) | 0;
|
||||
var hihi = (a_hihi * b_lolo + a_hilo * b_lohi + a_lohi * b_hilo + a_lolo * b_hihi + (hilo >> 16)) | 0;
|
||||
var result = new Long((lolo & 0xFFFF) | ((lohi & 0xFFFF) << 16), (hilo & 0xFFFF) | ((hihi & 0xFFFF) << 16));
|
||||
return positive ? result : Long_neg(result);
|
||||
}
|
||||
Long_div = function(a, b) {
|
||||
return Long_divRem(a, b)[0];
|
||||
}
|
||||
Long_rem = function(a, b) {
|
||||
return Long_divRem(a, b)[1];
|
||||
}
|
||||
Long_divRem = function(a, b) {
|
||||
var positive = Long_isNegative(a) === Long_isNegative(b);
|
||||
if (Long_isNegative(a)) {
|
||||
a = Long_neg(a);
|
||||
}
|
||||
if (Long_isNegative(b)) {
|
||||
b = Long_neg(b);
|
||||
}
|
||||
a = new LongInt(a.lo, a.hi, 0);
|
||||
b = new LongInt(b.lo, b.hi, 0);
|
||||
var q = LongInt_div(a, b);
|
||||
a = new Long(a.lo, a.hi);
|
||||
q = new Long(q.lo, q.hi);
|
||||
return positive ? [q, a] : [Long_neg(q), Long_neg(a)];
|
||||
}
|
||||
Long_shiftLeft16 = function(a) {
|
||||
return new Long(a.lo << 16, (a.lo >>> 16) | (a.hi << 16));
|
||||
}
|
||||
Long_shiftRight16 = function(a) {
|
||||
return new Long((a.lo >>> 16) | (a.hi << 16), a.hi >>> 16);
|
||||
}
|
||||
Long_and = function(a, b) {
|
||||
return new Long(a.lo & b.lo, a.hi & b.hi);
|
||||
}
|
||||
Long_or = function(a, b) {
|
||||
return new Long(a.lo | b.lo, a.hi | b.hi);
|
||||
}
|
||||
Long_xor = function(a, b) {
|
||||
return new Long(a.lo ^ b.lo, a.hi ^ b.hi);
|
||||
}
|
||||
Long_shl = function(a, b) {
|
||||
if (b < 32) {
|
||||
return new Long(a.lo << b, (a.lo >>> (32 - b)) | (a.hi << b));
|
||||
} else {
|
||||
return new Long(0, a.lo << (b - 32));
|
||||
}
|
||||
}
|
||||
Long_shr = function(a, b) {
|
||||
if (b < 32) {
|
||||
return new Long((a.lo >>> b) | (a.hi << (32 - b)), a.hi >> b);
|
||||
} else {
|
||||
return new Long((a.hi >> (b - 32)), -1);
|
||||
}
|
||||
}
|
||||
Long_shru = function(a, b) {
|
||||
if (b < 32) {
|
||||
return new Long((a.lo >>> b) | (a.hi << (32 - b)), a.hi >>> b);
|
||||
} else {
|
||||
return new Long((a.hi >>> (b - 32)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Represents a mutable 80-bit unsigned integer
|
||||
LongInt = function(lo, hi, sup) {
|
||||
this.lo = lo;
|
||||
this.hi = hi;
|
||||
this.sup = sup;
|
||||
}
|
||||
LongInt_mul = function(a, b) {
|
||||
var a_lolo = ((a.lo & 0xFFFF) * b) | 0;
|
||||
var a_lohi = ((a.lo >>> 16) * b) | 0;
|
||||
var a_hilo = ((a.hi & 0xFFFF) * b) | 0;
|
||||
var a_hihi = ((a.hi >>> 16) * b) | 0;
|
||||
var sup = (a.sup * b) | 0;
|
||||
|
||||
a_lohi = (a_lohi + (a_lolo >> 16)) | 0;
|
||||
a_hilo = (a_hilo + (a_lohi >> 16)) | 0;
|
||||
a_hihi = (a_hihi + (a_hilo >> 16)) | 0;
|
||||
sup = (sup + (a_hihi >> 16)) | 0;
|
||||
a.lo = (a_lolo & 0xFFFF) | (a_lohi << 16);
|
||||
a.hi = (a_hilo & 0xFFFF) | (a_hihi << 16);
|
||||
a.sup = sup & 0xFFFF;
|
||||
}
|
||||
LongInt_sub = function(a, b) {
|
||||
var a_lolo = a.lo & 0xFFFF;
|
||||
var a_lohi = a.lo >>> 16;
|
||||
var a_hilo = a.hi & 0xFFFF;
|
||||
var a_hihi = a.hi >>> 16;
|
||||
var b_lolo = b.lo & 0xFFFF;
|
||||
var b_lohi = b.lo >>> 16;
|
||||
var b_hilo = b.hi & 0xFFFF;
|
||||
var b_hihi = b.hi >>> 16;
|
||||
|
||||
a_lolo = (a_lolo - b_lolo) | 0;
|
||||
a_lohi = (a_lohi - b_lohi + (a_lolo >> 16)) | 0;
|
||||
a_hilo = (a_hilo - b_hilo + (a_lohi >> 16)) | 0;
|
||||
a_hihi = (a_hihi - b_hihi + (a_hilo >> 16)) | 0;
|
||||
sup = (a.sup - b.sup + (a_hihi >> 16)) | 0;
|
||||
a.lo = (a_lolo & 0xFFFF) | ((a_lohi & 0xFFFF) << 16);
|
||||
a.hi = (a_hilo & 0xFFFF) | ((a_hihi & 0xFFFF) << 16);
|
||||
a.sup = sup;
|
||||
}
|
||||
LongInt_add = function(a, b) {
|
||||
var a_lolo = a.lo & 0xFFFF;
|
||||
var a_lohi = a.lo >>> 16;
|
||||
var a_hilo = a.hi & 0xFFFF;
|
||||
var a_hihi = a.hi >>> 16;
|
||||
var b_lolo = b.lo & 0xFFFF;
|
||||
var b_lohi = b.lo >>> 16;
|
||||
var b_hilo = b.hi & 0xFFFF;
|
||||
var b_hihi = b.hi >>> 16;
|
||||
|
||||
a_lolo = (a_lolo + b_lolo) | 0;
|
||||
a_lohi = (a_lohi + b_lohi + (a_lolo >> 16)) | 0;
|
||||
a_hilo = (a_hilo + b_hilo + (a_lohi >> 16)) | 0;
|
||||
a_hihi = (a_hihi + b_hihi + (a_hilo >> 16)) | 0;
|
||||
sup = (a.sup + b.sup + (a_hihi >> 16)) | 0;
|
||||
a.lo = (a_lolo & 0xFFFF) | (a_lohi << 16);
|
||||
a.hi = (a_hilo & 0xFFFF) | (a_hihi << 16);
|
||||
a.sup = sup;
|
||||
}
|
||||
LongInt_ucompare = function(a, b) {
|
||||
var r = (a.sup - b.sup);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
var r = (a.hi >>> 1) - (b.hi >>> 1);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
var r = (a.hi & 1) - (b.hi & 1);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
var r = (a.lo >>> 1) - (b.lo >>> 1);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
return (a.lo & 1) - (b.lo & 1);
|
||||
}
|
||||
LongInt_numOfLeadingZeroBits = function(a) {
|
||||
var n = 0;
|
||||
var d = 16;
|
||||
while (d > 0) {
|
||||
if ((a >>> d) !== 0) {
|
||||
a >>>= d;
|
||||
n = (n + d) | 0;
|
||||
}
|
||||
d = (d / 2) | 0;
|
||||
}
|
||||
return 31 - n;
|
||||
}
|
||||
LongInt_shl = function(a, b) {
|
||||
if (b < 32) {
|
||||
a.sup = ((a.hi >>> (32 - b)) | (a.sup << b)) & 0xFFFF;
|
||||
a.hi = (a.lo >>> (32 - b)) | (a.hi << b);
|
||||
a.lo <<= b;
|
||||
} else if (b < 64) {
|
||||
a.sup = ((a.lo >>> (64 - b)) | (a.hi << (b - 32))) & 0xFFFF;
|
||||
a.hi = a.lo << b;
|
||||
a.lo = 0;
|
||||
} else {
|
||||
a.sup = (a.lo << (b - 64)) & 0xFFFF;
|
||||
a.hi = 0;
|
||||
a.lo = 0;
|
||||
}
|
||||
}
|
||||
LongInt_shr = function(a, b) {
|
||||
if (b < 32) {
|
||||
a.lo = (a.lo >>> b) | (a.hi << (32 - b));
|
||||
a.hi = (a.hi >>> b) | (a.sup << (32 - b));
|
||||
a.sup >>>= b;
|
||||
} else if (b < 64) {
|
||||
a.lo = (a.hi >>> (b - 32)) | (a.sup << (64 - b));
|
||||
a.hi = a.sup >>> (b - 32);
|
||||
a.sup = 0;
|
||||
} else {
|
||||
a.lo = a.sup >>> (b - 64);
|
||||
a.hi = 0;
|
||||
a.sup = 0;
|
||||
}
|
||||
}
|
||||
LongInt_copy = function(a) {
|
||||
return new LongInt(a.lo, a.hi, a.sup);
|
||||
}
|
||||
LongInt_div = function(a, b) {
|
||||
// Normalize divisor
|
||||
var bits = b.hi !== 0 ? LongInt_numOfLeadingZeroBits(b.hi) : LongInt_numOfLeadingZeroBits(b.lo) + 32;
|
||||
var sz = 1 + ((bits / 16) | 0);
|
||||
var dividentBits = bits % 16;
|
||||
LongInt_shl(b, bits);
|
||||
LongInt_shl(a, dividentBits);
|
||||
q = new LongInt(0, 0, 0);
|
||||
while (sz-- > 0) {
|
||||
LongInt_shl(q, 16);
|
||||
// Calculate approximate q
|
||||
var digitA = (a.hi >>> 16) + (0x10000 * a.sup);
|
||||
var digitB = b.hi >>> 16;
|
||||
var digit = (digitA / digitB) | 0;
|
||||
var t = LongInt_copy(b);
|
||||
LongInt_mul(t, digit);
|
||||
// Adjust q either down or up
|
||||
if (LongInt_ucompare(t, a) >= 0) {
|
||||
while (LongInt_ucompare(t, a) > 0) {
|
||||
LongInt_sub(t, b);
|
||||
q = (q - 1) | 0;
|
||||
}
|
||||
} else {
|
||||
while (true) {
|
||||
var nextT = LongInt_copy(t);
|
||||
LongInt_add(nextT, b);
|
||||
if (LongInt_ucompare(nextT, a) > 0) {
|
||||
break;
|
||||
}
|
||||
t = nextT;
|
||||
q = (q + 1) | 0;
|
||||
}
|
||||
}
|
||||
LongInt_sub(a, t);
|
||||
q.lo |= digit;
|
||||
LongInt_shl(a, 16);
|
||||
}
|
||||
LongInt_shr(a, bits + 16);
|
||||
return q;
|
||||
}
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 418 B |
After Width: | Height: | Size: 394 B |