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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
#include <QObject> #include <QObject>
#include <QStringList>
class QTcpSocket; class QTcpSocket;
class WebPage; class WebPage;
@ -16,10 +17,15 @@ class Connection : public QObject {
private: private:
void readNext(); 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; QTcpSocket *m_socket;
Command *m_command; Command *m_command;
QStringList m_arguments;
int m_argumentsExpected;
WebPage *m_page; WebPage *m_page;
}; };

View File

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

View File

@ -7,7 +7,7 @@ class Find : public Command {
public: public:
Find(WebPage *page, QObject *parent = 0); 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) { 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()->triggerAction(QWebPage::Stop);
page()->mainFrame()->setHtml("<html><body></body></html>"); page()->mainFrame()->setHtml("<html><body></body></html>");
QString response = ""; QString response = "";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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