From 77973a47ae4f34c58e2f8b6ea121838cc6f9a421 Mon Sep 17 00:00:00 2001 From: Andrey Chernih Date: Tue, 21 May 2013 15:58:46 +0400 Subject: [PATCH] Instantiate errors in capybara-webkit --- lib/capybara/webkit/browser.rb | 2 +- lib/capybara/webkit/errors.rb | 28 +++++++++++++++++++--------- spec/browser_spec.rb | 17 ++++++++++++++++- spec/errors_spec.rb | 11 +++++++++++ src/ErrorMessage.cpp | 4 ++-- src/InvocationResult.cpp | 2 +- src/TimeoutCommand.cpp | 2 +- 7 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 spec/errors_spec.rb diff --git a/lib/capybara/webkit/browser.rb b/lib/capybara/webkit/browser.rb index 9513f33..81c528e 100644 --- a/lib/capybara/webkit/browser.rb +++ b/lib/capybara/webkit/browser.rb @@ -212,7 +212,7 @@ module Capybara::Webkit if result.nil? raise NoResponseError, "No response received from the server." elsif result != 'ok' - raise JSON.load(read_response) + raise JsonError.new(read_response) end result diff --git a/lib/capybara/webkit/errors.rb b/lib/capybara/webkit/errors.rb index 12efa25..621e966 100644 --- a/lib/capybara/webkit/errors.rb +++ b/lib/capybara/webkit/errors.rb @@ -1,12 +1,5 @@ module Capybara::Webkit - module JsonError - def json_create(attributes) - new(attributes["message"]) - end - end - class InvalidResponseError < StandardError - extend JsonError end class NoResponseError < StandardError @@ -16,10 +9,27 @@ module Capybara::Webkit end class ClickFailed < StandardError - extend JsonError end class TimeoutError < Timeout::Error - extend JsonError + end + + class JsonError + def initialize(response) + error = JSON.parse response + + @class_name = error['class'] + @message = error['message'] + end + + def exception + error_class.new @message + end + + private + + def error_class + Capybara::Webkit.const_get @class_name + end end end diff --git a/spec/browser_spec.rb b/spec/browser_spec.rb index 3bedf26..20a5c87 100644 --- a/spec/browser_spec.rb +++ b/spec/browser_spec.rb @@ -7,7 +7,8 @@ require 'base64' describe Capybara::Webkit::Browser do - let(:browser) { Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new) } + let(:connection) { Capybara::Webkit::Connection.new } + let(:browser) { Capybara::Webkit::Browser.new(connection) } let(:browser_ignore_ssl_err) do Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser| browser.ignore_ssl_errors @@ -258,4 +259,18 @@ describe Capybara::Webkit::Browser do expect { browser.visit("/") }.not_to raise_error(/empty response/) end + + describe '#command' do + context 'non-ok response' do + it 'raises an error of given class' do + error_json = '{"class": "ClickFailed"}' + + connection.should_receive(:gets).ordered.and_return 'error' + connection.should_receive(:gets).ordered.and_return error_json.bytesize + connection.stub read: error_json + + expect { browser.command 'blah', 'meh' }.to raise_error(Capybara::Webkit::ClickFailed) + end + end + end end diff --git a/spec/errors_spec.rb b/spec/errors_spec.rb new file mode 100644 index 0000000..c090e09 --- /dev/null +++ b/spec/errors_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Capybara::Webkit::JsonError do + let(:error) { described_class.new '{"class": "ClickFailed", "message": "Error clicking this element"}' } + + subject { error.exception } + + it { should be_an_instance_of Capybara::Webkit::ClickFailed } + + its(:message) { should == 'Error clicking this element' } +end diff --git a/src/ErrorMessage.cpp b/src/ErrorMessage.cpp index d3254f8..297523c 100644 --- a/src/ErrorMessage.cpp +++ b/src/ErrorMessage.cpp @@ -16,9 +16,9 @@ QByteArray ErrorMessage::toString() { QVariantMap map; if (m_type.isNull()) - map["json_class"] = "Capybara::Webkit::InvalidResponseError"; + map["class"] = "InvalidResponseError"; else - map["json_class"] = m_type; + map["class"] = m_type; map["message"] = m_message; diff --git a/src/InvocationResult.cpp b/src/InvocationResult.cpp index 6b6d8ff..948731a 100644 --- a/src/InvocationResult.cpp +++ b/src/InvocationResult.cpp @@ -23,7 +23,7 @@ ErrorMessage *InvocationResult::errorMessage() { QString message = error["message"].toString(); if (error["name"] == "Capybara.ClickFailed") - return new ErrorMessage("Capybara::Webkit::ClickFailed", message); + return new ErrorMessage("ClickFailed", message); else return new ErrorMessage(message); } diff --git a/src/TimeoutCommand.cpp b/src/TimeoutCommand.cpp index 6bbe8fd..bbb4ef6 100644 --- a/src/TimeoutCommand.cpp +++ b/src/TimeoutCommand.cpp @@ -60,7 +60,7 @@ void TimeoutCommand::commandTimeout() { disconnect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *))); m_manager->currentPage()->triggerAction(QWebPage::Stop); QString message = QString("Request timed out after %1 second(s)").arg(m_manager->getTimeout()); - finish(false, new ErrorMessage("Capybara::Webkit::TimeoutError", message)); + finish(false, new ErrorMessage("TimeoutError", message)); } void TimeoutCommand::commandFinished(Response *response) {