Skip to content

Commit

Permalink
Tests and test-related fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
arkpar committed Apr 6, 2015
1 parent a9d8fe5 commit 6985984
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 114 deletions.
18 changes: 11 additions & 7 deletions ClientModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,13 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
codeMaps.push_back(move(codeMap));
//try to resolve contract for source level debugging
auto nameIter = m_contractNames.find(code.address);
if (nameIter != m_contractNames.end())
CompiledContract const* compilerRes = nullptr;
if (nameIter != m_contractNames.end() && (compilerRes = m_codeModel->tryGetContract(nameIter->second)))
{
CompiledContract const& compilerRes = m_codeModel->contract(nameIter->second);
eth::AssemblyItems assemblyItems = !_t.isConstructor() ? compilerRes.assemblyItems() : compilerRes.constructorAssemblyItems();
codes.back()->setDocument(compilerRes.documentId());
eth::AssemblyItems assemblyItems = !_t.isConstructor() ? compilerRes->assemblyItems() : compilerRes->constructorAssemblyItems();
codes.back()->setDocument(compilerRes->documentId());
codeItems.push_back(move(assemblyItems));
contracts.push_back(&compilerRes);
contracts.push_back(compilerRes);
}
else
{
Expand Down Expand Up @@ -432,7 +432,12 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
storage["values"] = storageValues;

prevInstructionIndex = instructionIndex;
solState = new QSolState(debugData, move(storage), move(solCallStack), move(locals), instruction.getLocation().start, instruction.getLocation().end, QString::fromUtf8(instruction.getLocation().sourceName->c_str()));

SourceLocation location = instruction.getLocation();
if (contract->contract()->location() == location || contract->functions().contains(LocationPair(location.start, location.end)))
location = dev::SourceLocation(-1, -1, location.sourceName);

solState = new QSolState(debugData, move(storage), move(solCallStack), move(locals), location.start, location.end, QString::fromUtf8(location.sourceName->c_str()));
}

states.append(QVariant::fromValue(new QMachineState(debugData, instructionIndex, s, codes[s.codeIndex], data[s.dataIndex], solState)));
Expand Down Expand Up @@ -460,7 +465,6 @@ QVariant ClientModel::formatStorageValue(SolidityType const& _type, map<u256, u2
{
count = _storage.at(slot);
slot = fromBigEndian<u256>(sha3(toBigEndian(slot)).asBytes());
cout << std::hex << slot;
}
else if (_type.array)
count = _type.count;
Expand Down
26 changes: 9 additions & 17 deletions CodeModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,6 @@ class CollectDeclarationsVisitor: public ASTConstVisitor
bool m_functionScope;
};

dev::eth::AssemblyItems filterLocations(dev::eth::AssemblyItems const& _locations, dev::solidity::ContractDefinition const& _contract, QHash<LocationPair, QString> _functions)
{
dev::eth::AssemblyItems result;
result.reserve(_locations.size());
for (dev::eth::AssemblyItem item : _locations)
{
dev::SourceLocation const& l = item.getLocation();
if (_contract.getLocation() == l || _functions.contains(LocationPair(l.start, l.end)))
item.setLocation(dev::SourceLocation(-1, -1, l.sourceName));
result.push_back(item);
}
return result;
}

QHash<unsigned, SolidityDeclarations> collectStorage(dev::solidity::ContractDefinition const& _contract)
{
QHash<unsigned, SolidityDeclarations> result;
Expand All @@ -121,7 +107,6 @@ QHash<unsigned, SolidityDeclarations> collectStorage(dev::solidity::ContractDefi
return result;
}


} //namespace

void BackgroundWorker::queueCodeChange(int _jobId)
Expand Down Expand Up @@ -150,8 +135,8 @@ CompiledContract::CompiledContract(const dev::solidity::CompilerStack& _compiler
CollectDeclarationsVisitor visitor(&m_functions, &m_locals);
m_storage = collectStorage(contractDefinition);
contractDefinition.accept(visitor);
m_assemblyItems = filterLocations(_compiler.getRuntimeAssemblyItems(name), contractDefinition, m_functions);
m_constructorAssemblyItems = filterLocations(_compiler.getAssemblyItems(name), contractDefinition, m_functions);
m_assemblyItems = _compiler.getRuntimeAssemblyItems(name);
m_constructorAssemblyItems = _compiler.getAssemblyItems(name);
}

QString CompiledContract::codeHex() const
Expand Down Expand Up @@ -253,6 +238,13 @@ CompiledContract const& CodeModel::contract(QString _name) const
return *res;
}

CompiledContract const* CodeModel::tryGetContract(QString _name) const
{
Guard l(x_contractMap);
CompiledContract* res = m_contractMap.value(_name);
return res;
}

void CodeModel::releaseContracts()
{
for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); ++c)
Expand Down
4 changes: 4 additions & 0 deletions CodeModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ class CodeModel: public QObject
/// Get contract code by url. Contract is compiled on first access and cached
dev::bytes const& getStdContractCode(QString const& _contractName, QString const& _url);
/// Get contract by name
/// Throws if not found
CompiledContract const& contract(QString _name) const;
/// Get contract by name
/// @returns nullptr if not found
CompiledContract const* tryGetContract(QString _name) const;
/// Find a contract by document id
/// @returns CompiledContract object or null if not found
Q_INVOKABLE CompiledContract* contractByDocumentId(QString _documentId) const;
Expand Down
2 changes: 1 addition & 1 deletion QBasicNodeDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace mix
{

QBasicNodeDefinition::QBasicNodeDefinition(QObject* _parent, solidity::Declaration const* _d):
QObject(_parent), m_name(QString::fromStdString(_d->getName()))
QObject(_parent), m_name(QString::fromStdString(_d->getName())), m_location(_d->getLocation())
{
}

Expand Down
3 changes: 3 additions & 0 deletions QBasicNodeDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <string>
#include <QObject>
#include <libevmcore/SourceLocation.h>

namespace dev
{
Expand All @@ -47,9 +48,11 @@ class QBasicNodeDefinition: public QObject
QBasicNodeDefinition(QObject* _parent, std::string const& _name);
/// Get the name of the node.
QString name() const { return m_name; }
dev::SourceLocation const& location() { return m_location; }

private:
QString m_name;
dev::SourceLocation m_location;
};

}
Expand Down
4 changes: 4 additions & 0 deletions qml/Debugger.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Rectangle {
id: debugPanel

property alias transactionLog: transactionLog
property alias debugSlider: statesSlider
property alias solLocals: solLocals
property alias solStorage: solStorage
property alias solCallStack: solCallStack
signal debugExecuteLocation(string documentId, var location)
property string compilationErrorMessage
property bool assemblyMode: false
Expand Down
1 change: 0 additions & 1 deletion qml/VariablesView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import "."

DebugInfoList
{
Expand Down
10 changes: 10 additions & 0 deletions qml/WebPreview.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ Item {
property string pendingPageUrl: ""
property bool initialized: false
property alias urlInput: urlInput
property alias webView: webView
property string webContent; //for testing
signal javaScriptMessage(var _level, string _sourceId, var _lineNb, string _content)
signal webContentReady

function setPreviewUrl(url) {
if (!initialized)
Expand Down Expand Up @@ -57,6 +60,13 @@ Item {
action(i);
}

function getContent() {
webView.runJavaScript("getContent()", function(result) {
webContent = result;
webContentReady();
});
}

function changePage() {
setPreviewUrl(urlInput.text);
}
Expand Down
7 changes: 7 additions & 0 deletions qml/html/WebContainer.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
return JSON.stringify(obj, null, 2);
}

getContent = function() {
var preview = document.getElementById('preview');
var doc = preview.contentDocument? preview.contentDocument: preview.contentWindow.document;
var body = doc.getElementsByTagName('body')[0];
return body.innerHTML;
}

</script>

<style>
Expand Down
6 changes: 6 additions & 0 deletions test/TestService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ bool TestService::waitForSignal(QObject* _item, QString _signalName, int _timeou
return spy.size();
}

bool TestService::waitForRendering(QObject* _item, int timeout)
{
QWindow* window = eventWindow(_item);
return waitForSignal(window, "frameSwapped()", timeout);
}

bool TestService::keyPress(QObject* _item, int _key, int _modifiers, int _delay)
{
QWindow* window = eventWindow(_item);
Expand Down
1 change: 1 addition & 0 deletions test/TestService.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class TestService: public QObject

public slots:
bool waitForSignal(QObject* _item, QString _signalName, int _timeout);
bool waitForRendering(QObject* _item, int timeout);
bool keyPress(QObject* _item, int _key, int _modifiers, int _delay);
bool keyRelease(QObject* _item, int _key, int _modifiers, int _delay);
bool keyClick(QObject* _item, int _key, int _modifiers, int _delay);
Expand Down
106 changes: 18 additions & 88 deletions test/qml/TestMain.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import QtQuick 2.2
import QtTest 1.1
import org.ethereum.qml.TestService 1.0
import "../../qml"
import "js/TestDebugger.js" as TestDebugger
import "js/TestTutorial.js" as TestTutorial

TestCase
{
Expand All @@ -23,6 +25,11 @@ TestCase
}
}

Application
{
id: mainApplication
}

function newProject()
{
waitForRendering(mainApplication.mainContent, 10000);
Expand All @@ -43,100 +50,23 @@ TestCase
fail("not compiled");
}

function clickElement(el, x, y)
function editHtml(c)
{
ts.mouseClick(el, x, y, Qt.LeftButton, Qt.NoModifier, 10)
}

function test_defaultTransactionSequence()
{
newProject();
editContract(
"contract Contract {\r" +
" function Contract() {\r" +
" uint x = 69;\r" +
" uint y = 5;\r" +
" for (uint i = 0; i < y; ++i) {\r" +
" x += 42;\r" +
" z += x;\r" +
" }\r" +
" }\r" +
" uint z;\r" +
"}\r"
);
if (!ts.waitForSignal(mainApplication.clientModel, "runComplete()", 5000))
fail("not run");
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel, "count", 3);
}

function test_transactionWithParameter()
{
newProject();
editContract(
"contract Contract {\r" +
" function setZ(uint256 x) {\r" +
" z = x;\r" +
" }\r" +
" function getZ() returns(uint256) {\r" +
" return z;\r" +
" }\r" +
" uint z;\r" +
"}\r"
);
mainApplication.projectModel.stateListModel.editState(0);
mainApplication.projectModel.stateDialog.model.addTransaction();
var transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog;
transactionDialog.selectFunction("setZ");
clickElement(transactionDialog, 140, 300);
ts.typeString("442", transactionDialog);
transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.model.addTransaction();
transactionDialog.selectFunction("getZ");
transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.acceptAndClose();
mainApplication.mainContent.startQuickDebugging();
mainApplication.projectModel.openDocument("index.html");
wait(1);
if (!ts.waitForSignal(mainApplication.clientModel, "runComplete()", 5000))
fail("not run");
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel, "count", 5);
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(4), "returned", "(442)");
mainApplication.mainContent.codeEditor.getEditor("index.html").setText(c);
ts.keyPressChar(mainApplication, "S", Qt.ControlModifier, 200); //Ctrl+S
}

function test_constructorParameters()
function clickElement(el, x, y)
{
newProject();
editContract(
"contract Contract {\r" +
" function Contract(uint256 x) {\r" +
" z = x;\r" +
" }\r" +
" function getZ() returns(uint256) {\r" +
" return z;\r" +
" }\r" +
" uint z;\r" +
"}\r"
);
mainApplication.projectModel.stateListModel.editState(0);
mainApplication.projectModel.stateDialog.model.editTransaction(2);
var transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog;
clickElement(transactionDialog, 140, 300);
ts.typeString("442", transactionDialog);
transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.model.addTransaction();
transactionDialog.selectFunction("getZ");
transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.acceptAndClose();
wait(1);
mainApplication.mainContent.startQuickDebugging();
if (!ts.waitForSignal(mainApplication.clientModel, "runComplete()", 5000))
fail("not run");
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel, "count", 4);
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(3), "returned", "(442)");
ts.mouseClick(el, x, y, Qt.LeftButton, Qt.NoModifier, 10)
}

Application
{
id: mainApplication
}
function test_tutorial() { TestTutorial.test_tutorial(); }
function test_dbg_defaultTransactionSequence() { TestDebugger.test_defaultTransactionSequence(); }
function test_dbg_transactionWithParameter() { TestDebugger.test_transactionWithParameter(); }
function test_dbg_constructorParameters() { TestDebugger.test_constructorParameters(); }
function test_dbg_arrayParametersAndStorage() { TestDebugger.test_arrayParametersAndStorage(); }
}

Loading

0 comments on commit 6985984

Please sign in to comment.