Skip to content

Commit

Permalink
Rewrite qInstallMsgHandler test in C++
Browse files Browse the repository at this point in the history
* Allows tests independent of debug settings for Qt
* Allows testing behavior unreachable from Ruby
  • Loading branch information
jferris authored and youpy committed Jul 22, 2014
1 parent 3263cd7 commit a6f59f8
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 96 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,5 +1,6 @@
*.swp
bin/webkit_server*
test/testwebkitserver
*.swo
*~
*.o
Expand Down
17 changes: 13 additions & 4 deletions Rakefile
Expand Up @@ -20,6 +20,18 @@ task :build => :qmake do
CapybaraWebkitBuilder.build or exit(1)
end

task :makefile_test do
CapybaraWebkitBuilder.makefile('CONFIG+=test') or exit(1)
end

desc "Build the webkit server for running tests"
task :build_test => [:makefile_test, :build]

desc "Run QtTest unit tests for webkit server"
task :check => :build_test do
sh("make check") or exit(1)
end

file 'bin/webkit_server' => :build

RSpec::Core::RakeTask.new do |t|
Expand All @@ -28,15 +40,12 @@ RSpec::Core::RakeTask.new do |t|
end

desc "Default: build and run all specs"
task :default => [:build, :spec]
task :default => [:check, :spec]

desc "Generate a new command called NAME"
task :generate_command do
name = ENV['NAME'] or raise "Provide a name with NAME="

header = "src/#{name}.h"
source = "src/#{name}.cpp"

%w(h cpp).each do |extension|
File.open("templates/Command.#{extension}", "r") do |source_file|
contents = source_file.read
Expand Down
4 changes: 2 additions & 2 deletions lib/capybara_webkit_builder.rb
Expand Up @@ -52,8 +52,8 @@ def sh(command)
success
end

def makefile
sh("#{qmake_bin} -spec #{spec}")
def makefile(config = '')
sh("#{qmake_bin} -spec #{spec} #{config}")
end

def qmake
Expand Down
57 changes: 0 additions & 57 deletions spec/driver_spec.rb
Expand Up @@ -2350,63 +2350,6 @@ def log
end
end

context 'Qt debug error app' do
let(:app) do
Class.new(Sinatra::Base) do
get '/' do
<<-HTML
<html>
<body>
<div id="target">Loading</div>
<script type="text/javascript">
function causeMissingContentTypeWarning() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var target = document.getElementById('target');
target.innerHTML = this.responseText;
}
xhr.open('post', '/ajax', false);
xhr.send();
}
causeMissingContentTypeWarning();
</script>
</body>
</html>
HTML
end

post '/ajax' do
'Complete'
end
end
end

it 'silences Qt debug messages' do
visit '/'
wait_for_ajax_request
log.should eq('')
end

def wait_for_ajax_request
driver.find_css('#target').first.text.should eq('Complete')
end

let(:driver) do
run_application app
connection = Capybara::Webkit::Connection.new(:stderr => output)
browser = Capybara::Webkit::Browser.new(connection)
Capybara::Webkit::Driver.new(AppRunner.app, :browser => browser)
end

let(:output) { StringIO.new }

def log
output.rewind
output.read
end
end

def driver_url(driver, path)
URI.parse(driver.current_url).merge(path).to_s
end
Expand Down
36 changes: 36 additions & 0 deletions src/IgnoreDebugOutput.cpp
@@ -0,0 +1,36 @@
#include "IgnoreDebugOutput.h"

#include <QtGlobal>
#include <QString>

void debugIgnoringMessageHandler(QtMsgType type, const char *msg);

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
void debugIgnoringMessageHandlerQt5(QtMsgType type, const QMessageLogContext &context, const QString &message);
#endif

void debugIgnoringMessageHandler(QtMsgType type, const char *msg) {
switch (type) {
case QtDebugMsg:
case QtWarningMsg:
break;
default:
fprintf(stderr, "%s\n", msg);
break;
}
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
void debugIgnoringMessageHandlerQt5(QtMsgType type, const QMessageLogContext &context, const QString &message) {
Q_UNUSED(context);
debugIgnoringMessageHandler(type, message.toLocal8Bit().data());
}
#endif

void ignoreDebugOutput(void) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
qInstallMessageHandler(debugIgnoringMessageHandlerQt5);
#else
qInstallMsgHandler(debugIgnoringMessageHandler);
#endif
}
1 change: 1 addition & 0 deletions src/IgnoreDebugOutput.h
@@ -0,0 +1 @@
void ignoreDebugOutput(void);
32 changes: 2 additions & 30 deletions src/main.cpp
@@ -1,16 +1,11 @@
#include "Server.h"
#include "IgnoreDebugOutput.h"
#include <QApplication>
#include <iostream>
#ifdef Q_OS_UNIX
#include <unistd.h>
#endif

void ignoreDebugOutput(QtMsgType type, const char *msg);

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
void ignoreDebugOutputQt5(QtMsgType type, const QMessageLogContext &context, const QString &message);
#endif

int main(int argc, char **argv) {
#ifdef Q_OS_UNIX
if (setpgid(0, 0) < 0) {
Expand All @@ -24,12 +19,7 @@ int main(int argc, char **argv) {
app.setOrganizationName("thoughtbot, inc");
app.setOrganizationDomain("thoughtbot.com");

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
qInstallMessageHandler(ignoreDebugOutputQt5);
#else
qInstallMsgHandler(ignoreDebugOutput);
#endif

ignoreDebugOutput();
Server server(0);

if (server.start()) {
Expand All @@ -40,21 +30,3 @@ int main(int argc, char **argv) {
return 1;
}
}

void ignoreDebugOutput(QtMsgType type, const char *msg) {
switch (type) {
case QtDebugMsg:
case QtWarningMsg:
break;
default:
fprintf(stderr, "%s\n", msg);
break;
}
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
void ignoreDebugOutputQt5(QtMsgType type, const QMessageLogContext &context, const QString &message) {
Q_UNUSED(context);
ignoreDebugOutput(type, message.toLocal8Bit().data());
}
#endif
6 changes: 4 additions & 2 deletions src/webkit_server.pro
Expand Up @@ -62,7 +62,8 @@ HEADERS = \
FindCss.h \
JavascriptCommand.h \
FindXpath.h \
NetworkReplyProxy.h
NetworkReplyProxy.h \
IgnoreDebugOutput.h

SOURCES = \
Version.cpp \
Expand Down Expand Up @@ -126,7 +127,8 @@ SOURCES = \
FindCss.cpp \
JavascriptCommand.cpp \
FindXpath.cpp \
NetworkReplyProxy.cpp
NetworkReplyProxy.cpp \
IgnoreDebugOutput.cpp

RESOURCES = webkit_server.qrc
QT += network
Expand Down
45 changes: 45 additions & 0 deletions test/testignoredebugoutput.cpp
@@ -0,0 +1,45 @@
#include <QtTest/QtTest>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "../src/IgnoreDebugOutput.h"

#define MAX_LEN 40

class TestIgnoreDebugOutput: public QObject {
Q_OBJECT

private slots:
void testIgnoreDebugOutput();
};

void TestIgnoreDebugOutput::testIgnoreDebugOutput() {
char buffer[MAX_LEN+1] = {0};
int out_pipe[2];
int saved_stdout;

saved_stdout = dup(STDOUT_FILENO);

QVERIFY(pipe(out_pipe) == 0);

dup2(out_pipe[1], STDOUT_FILENO);
close(out_pipe[1]);

long flags = fcntl(out_pipe[0], F_GETFL);
flags |= O_NONBLOCK;
fcntl(out_pipe[0], F_SETFL, flags);

ignoreDebugOutput();

qDebug() << "Message";
fflush(stdout);

read(out_pipe[0], buffer, MAX_LEN);

dup2(saved_stdout, STDOUT_FILENO);

QCOMPARE(QString(buffer), QString(""));
}

QTEST_MAIN(TestIgnoreDebugOutput)
#include "testignoredebugoutput.moc"
5 changes: 5 additions & 0 deletions test/testwebkitserver.pro
@@ -0,0 +1,5 @@
SOURCES = testignoredebugoutput.cpp
OBJECTS += ../src/IgnoreDebugOutput.o
QT += testlib
CONFIG += testcase console
CONFIG -= app_bundle
4 changes: 3 additions & 1 deletion webkit_server.pro
@@ -1,4 +1,6 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += src/webkit_server.pro

test {
SUBDIRS += test/testwebkitserver.pro
}

0 comments on commit a6f59f8

Please sign in to comment.