Refactor Connection/Command so that arguments are passed in as a single QStringList instead of in consecutive calls to argumentReceived

This commit is contained in:
Joe Ferris 2011-02-25 23:29:36 -05:00
parent 18d424803d
commit 3e32892e2b
18 changed files with 62 additions and 75 deletions

View File

@ -20,8 +20,8 @@ class Capybara::Driver::Webkit
end
def command(name, *args)
puts ">> Sending #{name}"
@socket.puts name
@socket.puts args.size.to_s
args.each { |arg| @socket.puts arg }
check
read_response
@ -35,12 +35,10 @@ class Capybara::Driver::Webkit
end
def connect
puts ">> Connecting"
Capybara.timeout(5) do
attempt_connect
!@socket.nil?
end
puts ">> Connected"
end
def attempt_connect
@ -50,7 +48,6 @@ class Capybara::Driver::Webkit
def check
result = @socket.gets.strip
puts ">> #{result}"
unless result == 'ok'
raise WebkitError, read_response
end

View File

@ -4,15 +4,9 @@
Attribute::Attribute(WebPage *page, QObject *parent) : Command(page, parent) {
}
void Attribute::receivedArgument(const char *argument) {
m_args.append(argument);
if (m_args.length() == 2) {
QString nodeIndex = m_args[0];
QString attributeName = m_args[1];
QString javascript = QString("Capybara.attribute(" + nodeIndex + ", \"" + attributeName + "\")");
QVariant result = page()->mainFrame()->evaluateJavaScript(javascript);
QString attributeValue = result.toString();
emit finished(true, attributeValue);
}
void Attribute::start(QStringList &arguments) {
QVariant result = page()->invokeCapybaraFunction("attribute", arguments);
QString attributeValue = result.toString();
emit finished(true, attributeValue);
}

View File

@ -8,9 +8,6 @@ class Attribute : public Command {
public:
Attribute(WebPage *page, QObject *parent = 0);
virtual void receivedArgument(const char *argument);
private:
QStringList m_args;
virtual void start(QStringList &arguments);
};

View File

@ -5,11 +5,8 @@ Command::Command(WebPage *page, QObject *parent) : QObject(parent) {
m_page = page;
}
void Command::receivedArgument(const char *argument) {
Q_UNUSED(argument);
}
void Command::start() {
void Command::start(QStringList &arguments) {
Q_UNUSED(arguments);
}
WebPage *Command::page() {

View File

@ -2,6 +2,7 @@
#define COMMAND_H
#include <QObject>
#include <QStringList>
class WebPage;
@ -10,8 +11,7 @@ class Command : public QObject {
public:
Command(WebPage *page, QObject *parent = 0);
virtual void start();
virtual void receivedArgument(const char *argument);
virtual void start(QStringList &arguments);
signals:
void finished(bool success, QString &response);

View File

@ -6,7 +6,6 @@
#include "Attribute.h"
#include <QTcpSocket>
#include <iostream>
Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
QObject(parent) {
@ -17,46 +16,62 @@ Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
}
void Connection::checkNext() {
std::cout << "<< Data ready to read" << std::endl;
while (m_socket->canReadLine()) {
readNext();
}
}
void Connection::readNext() {
std::cout << "<< Reading line" << std::endl;
char buffer[1024];
qint64 lineLength = m_socket->readLine(buffer, 1024);
if (lineLength != -1) {
buffer[lineLength - 1] = 0;
std::cout << "<< Got line: " << buffer << std::endl;
processLine(buffer);
}
}
void Connection::processLine(const char *line) {
if (m_command) {
continueCommand(line);
} else {
m_command = createCommand(line);
if (m_command) {
m_command->receivedArgument(buffer);
startCommand();
} else {
m_command = startCommand(buffer);
if (m_command) {
connect(m_command,
SIGNAL(finished(bool, QString &)),
this,
SLOT(finishCommand(bool, QString &)));
m_command->start();
} else {
m_socket->write("bad command\n");
}
m_socket->write("bad command\n");
}
}
}
Command *Connection::startCommand(const char *name) {
Command *Connection::createCommand(const char *name) {
#include "find_command.h"
std::cout << ">> Unknown command" << std::endl;
return NULL;
}
void Connection::startCommand() {
m_argumentsExpected = -1;
connect(m_command,
SIGNAL(finished(bool, QString &)),
this,
SLOT(finishCommand(bool, QString &)));
}
void Connection::continueCommand(const char *line) {
if (m_argumentsExpected == -1) {
m_argumentsExpected = QString(line).toInt();
} else {
m_arguments.append(line);
}
if (m_arguments.length() == m_argumentsExpected) {
m_command->start(m_arguments);
}
}
void Connection::finishCommand(bool success, QString &response) {
m_command->deleteLater();
m_command = NULL;
m_arguments.clear();
if (success) {
m_socket->write("ok\n");
} else {

View File

@ -1,4 +1,5 @@
#include <QObject>
#include <QStringList>
class QTcpSocket;
class WebPage;
@ -16,10 +17,15 @@ class Connection : public QObject {
private:
void readNext();
Command *startCommand(const char *name);
void processLine(const char *line);
Command *createCommand(const char *name);
void startCommand();
void continueCommand(const char *line);
QTcpSocket *m_socket;
Command *m_command;
QStringList m_arguments;
int m_argumentsExpected;
WebPage *m_page;
};

View File

@ -1,23 +1,16 @@
#include "Find.h"
#include "Command.h"
#include "WebPage.h"
#include <iostream>
Find::Find(WebPage *page, QObject *parent) : Command(page, parent) {
}
void Find::receivedArgument(const char *xpath) {
QStringList arguments;
void Find::start(QStringList &arguments) {
QString response;
arguments.append(QString(xpath));
QVariant result = page()->invokeCapybaraFunction("find", arguments);
if (result.isValid()) {
response = result.toString();
std::cout << "<< Got result:" << std::endl;
std::cout << response.toAscii().data() << std::endl;
emit finished(true, response);
} else {
response = "Invalid XPath expression";

View File

@ -7,7 +7,7 @@ class Find : public Command {
public:
Find(WebPage *page, QObject *parent = 0);
virtual void receivedArgument(const char *argument);
virtual void start(QStringList &arguments);
};

View File

@ -4,7 +4,9 @@
Reset::Reset(WebPage *page, QObject *parent) : Command(page, parent) {
}
void Reset::start() {
void Reset::start(QStringList &arguments) {
Q_UNUSED(arguments);
page()->triggerAction(QWebPage::Stop);
page()->mainFrame()->setHtml("<html><body></body></html>");
QString response = "";

View File

@ -7,6 +7,6 @@ class Reset : public Command {
public:
Reset(WebPage *page, QObject *parent = 0);
virtual void start();
virtual void start(QStringList &arguments);
};

View File

@ -3,7 +3,6 @@
#include "Connection.h"
#include <QTcpServer>
#include <iostream>
Server::Server(QObject *parent) : QObject(parent) {
m_tcp_server = new QTcpServer(this);
@ -16,7 +15,6 @@ bool Server::start() {
}
void Server::handleConnection() {
std::cout << "<< Got connection" << std::endl;
QTcpSocket *socket = m_tcp_server->nextPendingConnection();
new Connection(socket, m_page, this);
}

View File

@ -1,21 +1,17 @@
#include "Visit.h"
#include "Command.h"
#include "WebPage.h"
#include <iostream>
Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) {
connect(page, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
}
void Visit::receivedArgument(const char *url) {
std::cout << ">> Loading page: " << url << std::endl;
page()->mainFrame()->setUrl(QUrl(url));
void Visit::start(QStringList &arguments) {
page()->mainFrame()->setUrl(QUrl(arguments[0]));
}
void Visit::loadFinished(bool success) {
std::cout << ">> Page loaded" << std::endl;
QString response;
std::cout << page()->mainFrame()->toHtml().toAscii().constData() << std::endl;
emit finished(success, response);
}

View File

@ -7,7 +7,7 @@ class Visit : public Command {
public:
Visit(WebPage *page, QObject *parent = 0);
virtual void receivedArgument(const char *argument);
virtual void start(QStringList &arguments);
private slots:
void loadFinished(bool success);

View File

@ -1,5 +1,4 @@
#include <QtWebKit>
#include <iostream>
class WebPage : public QWebPage {
Q_OBJECT

View File

@ -1,6 +1,5 @@
#include "Server.h"
#include <QtGui>
#include <iostream>
int main(int argc, char **argv) {
@ -11,8 +10,6 @@ int main(int argc, char **argv) {
Server server;
if (server.start()) {
std::cout << "<< Started server" << std::endl;
return app.exec();
} else {
std::cerr << "Couldn't start server" << std::endl;

View File

@ -4,10 +4,7 @@
NAME::NAME(WebPage *page, QObject *parent) : Command(page, parent) {
}
void NAME::start() {
}
void NAME::receivedArgument(const char *argument) {
Q_UNUSED(argument);
void NAME::start(QStringList &arguments) {
Q_UNUSED(arguments);
}

View File

@ -7,7 +7,6 @@ class NAME : public Command {
public:
NAME(WebPage *page, QObject *parent = 0);
virtual void start();
virtual void receivedArgument(const char *argument);
virtual void start(QStringList &arguments);
};