summaryrefslogtreecommitdiffstats
path: root/dcop/tests
diff options
context:
space:
mode:
Diffstat (limited to 'dcop/tests')
-rw-r--r--dcop/tests/Makefile.am35
-rw-r--r--dcop/tests/README37
-rw-r--r--dcop/tests/driver.cpp65
-rw-r--r--dcop/tests/driver.h21
-rwxr-xr-xdcop/tests/generate.pl221
-rw-r--r--dcop/tests/run-tests.sh44
-rw-r--r--dcop/tests/test.cpp44
-rw-r--r--dcop/tests/testcases105
8 files changed, 572 insertions, 0 deletions
diff --git a/dcop/tests/Makefile.am b/dcop/tests/Makefile.am
new file mode 100644
index 000000000..16d8ac7e0
--- /dev/null
+++ b/dcop/tests/Makefile.am
@@ -0,0 +1,35 @@
+
+nothing:
+ @echo -e "dcop tests not run.\nRun make tests in the tests directory to make them"
+
+INCLUDES = $(all_includes)
+AM_LDFLAGS = $(all_libraries)
+
+METASOURCES = AUTO
+
+####### Files
+
+check_PROGRAMS = dcop_test driver
+
+dcop_test_SOURCES = test.cpp test.skel
+dcop_test_LDADD = $(LIB_KDECORE)
+dcop_test_LDFLAGS = $(KDE_RPATH)
+
+driver_SOURCES = driver.cpp test.stub
+driver_LDADD = $(LIB_KDECORE)
+driver_LDFLAGS = $(KDE_RPATH)
+
+CLEANFILES = batch.generated definitions.generated driver.generated shell.generated test.h
+
+BUILT_SOURCES = test.h
+
+test-clean:
+ rm batch.returns driver.returns shell.returns batch.stdout driver.stdout shell.stdout
+
+test.h: shell.generated
+
+shell.generated: $(srcdir)/testcases $(srcdir)/generate.pl
+ perl $(srcdir)/generate.pl < $(srcdir)/testcases
+
+check-local:
+ sh $(srcdir)/run-tests.sh
diff --git a/dcop/tests/README b/dcop/tests/README
new file mode 100644
index 000000000..3dec62986
--- /dev/null
+++ b/dcop/tests/README
@@ -0,0 +1,37 @@
+WHAT IS IT
+==========
+
+This is a test case for the dcop family of utils.
+
+
+HOW TO USE IT
+=============
+
+testcases is the important file, the rest is build system.
+It details what functions we should generate and with what arguments to call them
+
+'make'ing will generate a small dcop app which runs in two modes: the batch mode and the
+interactive mode. The batch mode simply runs all the tests inside the app, while in the interactive
+mode, the app goes to sleep and exactly the same tests are called from the outside. Should the results
+differ, we probably have a bug.
+
+
+HOW IT WORKS
+============
+
+Six files get generated:
+
+ local external shell
+ +-------------------+-----------------+-----------------+
+ | | | |
+ stdout | batch.stdout | dcop.stdout | shell.stdoud |
+ | | | |
+ +-------------------+-----------------+-----------------+
+ | | | |
+ return values | batch.returns | dcop.returns | shell.returns |
+ | | | |
+ +-------------------+-----------------+-----------------+
+
+The local column are the files generated in batch mode where the calls are made locally, the external and shell columns lists files made using dcop calls, "external" calls were made through an external program and shell call were made using the dcop shell client. The stdout row is what got printed to stdout and the returns row is what return values the various functions support. These are kept separate to simplify things.
+
+
diff --git a/dcop/tests/driver.cpp b/dcop/tests/driver.cpp
new file mode 100644
index 000000000..ac06d2873
--- /dev/null
+++ b/dcop/tests/driver.cpp
@@ -0,0 +1,65 @@
+#include "driver.h"
+#include <kapplication.h>
+#include <iostream>
+#include <dcopclient.h>
+#include <kcmdlineargs.h>
+#include <qtimer.h>
+#include <qtimer.h>
+
+using namespace std;
+
+#ifdef _MSC_VER
+#define __PRETTY_FUNCTION__ __FUNCTION__
+#endif
+
+Driver::Driver(const char* app)
+ :Test_stub( app, "TestInterface" ),
+ DCOPStub( app, "TestInterface" ), // DCOPStub is *virtual* inherited
+ count( 0 )
+{
+
+}
+
+QTextStream output( fopen( "driver.returns", "w" ) , IO_WriteOnly );
+#include <iostream>
+void Driver::test()
+{
+ // This is written like this to allow the potentially ASYNC calls to be syncronized
+ // Just sleeping would mean that no errors were reported until much later
+ // I could improve it, so that we don't sleep after a synchronous call, but I will
+ // leave it for later
+
+ std::cerr << __PRETTY_FUNCTION__ << " count: " << count << '\n';
+
+ Driver* object = this;
+ switch ( count ) {
+#include "driver.generated"
+ default:
+ exit( 0 );
+ }
+
+ ++count;
+ QTimer::singleShot( 100, this, SLOT( test() ) );
+}
+
+#include "driver.moc"
+
+#ifdef Q_OS_WIN
+# define main kdemain
+#endif
+
+int main(int argc, char** argv)
+{
+ if ( argc < 2 ) { qWarning("Usage: driver <appid>"); return 1; }
+ const char* appname = strdup( argv[ 1 ] );
+ argv[ 1 ] = 0; // sue me
+ KCmdLineArgs::init( argc, argv, "TestAppDriver", "Tests the dcop familly of tools + libraries", "1.0" ); // FIXME
+ KApplication app;
+ app.dcopClient()->attach( );
+ app.dcopClient()->registerAs( "TestAppDriver" );
+ Driver * object = new Driver( appname );
+ QTimer::singleShot( 10, object, SLOT( test() ) );
+ return app.exec();
+}
+
+
diff --git a/dcop/tests/driver.h b/dcop/tests/driver.h
new file mode 100644
index 000000000..ee4d5df57
--- /dev/null
+++ b/dcop/tests/driver.h
@@ -0,0 +1,21 @@
+#ifndef _OPT_KDECVS_SRC_KDELIBS_DCOP_TEST_TESTER_H
+#define _OPT_KDECVS_SRC_KDELIBS_DCOP_TEST_TESTER_H
+#include "test_stub.h"
+#include <qobject.h>
+
+
+
+class Driver : public QObject, public Test_stub
+{
+ Q_OBJECT
+
+ public:
+ Driver(const char*);
+ public slots:
+ void test();
+
+ private:
+ int count;
+};
+
+#endif // _OPT_KDE-CVS_SRC_KDELIBS_DCOP_TEST_TESTER_H
diff --git a/dcop/tests/generate.pl b/dcop/tests/generate.pl
new file mode 100755
index 000000000..cd4697d3f
--- /dev/null
+++ b/dcop/tests/generate.pl
@@ -0,0 +1,221 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+
+my $DERIVED_CLASS = 'Test';
+my $BASE_CLASS = 'Test';
+my $DCOP = '../client/dcop';
+my $TEST_APP = '$TEST_APP';
+my $OBJECT_NAME = 'TestInterface';
+
+
+sub shell_header {
+ print SHELL "TEST_APP=\`$DCOP 'TestApp-*'\`\n";
+}
+sub shell_footer {
+ print SHELL "$DCOP $TEST_APP 'MainApplication-Interface' quit";
+}
+
+sub test_h_header {
+print HEADER <<END;
+
+#ifndef MY_INTERFACE_H
+#define MY_INTERFACE_H
+
+/* This is combined with test.cpp and run_test a test case for dcop
+ * family of programms
+ */
+
+// some comment
+#include <dcopobject.h>
+#include <dcopref.h>
+
+class Test2;
+
+// this has to work too
+#include <qstring.h>
+
+
+
+namespace MyNamespace {
+ struct MyParentClass {
+ int x;
+ };
+}
+
+class Test : public MyNamespace::MyParentClass, virtual public DCOPObject
+{
+ K_DCOP
+
+public:
+ Test() : DCOPObject("TestInterface") {}
+ ~Test();
+k_dcop:
+
+END
+
+}
+
+sub test_h_footer {
+print HEADER <<END;
+
+};
+
+#endif // end
+
+END
+}
+
+
+
+sub getline {
+ local $_;
+ until (eof()) {
+ last unless defined($_ = <>);
+ chomp;
+ next if /^\s*#/;
+ return $_;
+ }
+ return '';
+}
+
+#sub getline {
+# print STDERR "HERE2\n";
+# my $res = &getlinereal;
+# print STDERR "G->" . $res . "<-\n";
+# return $res;
+#}
+
+
+# main();
+
+open(HEADER,'>test.h');
+open(IMPLEMENTATION,'>definitions.generated');
+open(BATCH, '>batch.generated');
+open(SHELL,'>shell.generated');
+open(DRIVER,'>driver.generated');
+
+&test_h_header;
+&shell_header;
+my $previous_comment;
+my $i = 0;
+my $i_1 = 1;
+until (eof()) {
+ my $comment = &getline;
+ next if $comment eq '';
+ my $return_type = $comment;
+ $previous_comment = $comment;
+ if ($comment =~ m#\s*//#) { $return_type = &getline; }
+ else { $comment = $previous_comment; }
+ my $function_name = &getline;
+ my $argument_types = &getline;
+ my $function_body = '';
+ my $line;
+ do {
+ $line = &getline;
+ $function_body .= $line;
+ } until ($line =~ /^}/);
+ my @shell_args = ();
+ my @cpp_args = ();
+ print STDERR "Working on function $function_name$argument_types\n";
+ while (1) {
+ local $_ = &getline;
+ chomp;
+ print STDERR "Looking at -$_-\n";
+ die 'I/O Error' if eof();
+ die 'I/O Error' unless defined($_); # should catch all previous IO errors as well
+
+ if (/^\s*$/ || /^-$/ ) {
+ if (scalar(@shell_args) == 0) {
+ @shell_args = ('');
+ @cpp_args = ('');
+ print STDERR "Function $function_name$argument_types: No arguments\n";
+ }
+ last;
+ }
+ /^(.*);(.*)$/ or last;
+ push @shell_args, ($1);
+ push @cpp_args, ($2);
+ print STDERR "Function $function_name$argument_types: args {-$1-} {-$2-}\n";
+ print STDERR "Function $function_name$argument_types: so far ", scalar(@shell_args), "\n";
+ }
+
+
+ $comment =~ s#^\s*//##;
+
+ print HEADER <<END;
+ // $comment
+ virtual $return_type ${function_name}_virtual $argument_types;
+ $return_type ${function_name} $argument_types;
+END
+
+ print IMPLEMENTATION <<END;
+ $return_type $DERIVED_CLASS :: ${function_name}_virtual $argument_types
+ $function_body
+
+ $return_type $BASE_CLASS :: ${function_name} $argument_types
+ $function_body
+END
+
+ my $cpp_cur = scalar(shift @cpp_args or '');
+ my $shell_cur = scalar(shift @shell_args or '');
+
+ if ($return_type ne 'void') {
+ print BATCH <<END;
+ output << "$return_type $function_name($argument_types)\\n{\\n";
+ output << "// $comment\\n";
+ output << object->$function_name($cpp_cur) << "\\n}\\n";
+ output << "$return_type ${function_name}_virtual($argument_types)\\n{\\n";
+ output << "// $comment\\n";
+ output << object->${function_name}_virtual($cpp_cur) << "\\n}\\n";
+END
+ } else {
+ print BATCH <<END;
+ // Void Functions:
+ object->$function_name();
+ object->${function_name}_virtual();
+END
+ }
+
+ print SHELL <<END;
+ echo "$return_type $function_name($argument_types)"
+ echo "{"
+ echo "// $comment";
+ $DCOP $TEST_APP $OBJECT_NAME $function_name $shell_cur
+ echo "}"
+ echo "$return_type ${function_name}_virtual($argument_types)"
+ echo "{"
+ echo "// $comment";
+ $DCOP $TEST_APP $OBJECT_NAME ${function_name}_virtual $shell_cur
+ echo "}"
+END
+
+ print DRIVER <<END;
+ case $i:
+ output << "$return_type $function_name($argument_types)\\n{\\n";
+ output << "// $comment\\n";
+ output << object->$function_name($cpp_cur) << '\\n';
+ output << "}\\n";
+ break;
+ case $i_1:
+ output << "$return_type ${function_name}_virtual($argument_types)\\n{\\n";
+ output << "// $comment\\n";
+ output << object->${function_name}_virtual($cpp_cur) << '\\n';
+ output << "}\\n";
+ break;
+END
+ $i += 2;
+ $i_1 = $i + 1;
+}
+
+&test_h_footer;
+&shell_footer;
+
+close HEADER;
+close IMPLEMENTATION;
+close BATCH;
+close SHELL;
+close DRIVER;
+
+1;
diff --git a/dcop/tests/run-tests.sh b/dcop/tests/run-tests.sh
new file mode 100644
index 000000000..216c29aef
--- /dev/null
+++ b/dcop/tests/run-tests.sh
@@ -0,0 +1,44 @@
+
+clean_up() {
+ rm -f batch.stdout shell.stdout shell.returns batch.returns
+}
+
+clean_up
+
+echo '* Running batch mode'
+./dcop_test --batch >batch.stdout
+
+echo -n '* Starting test app '
+./dcop_test >shell.stdout &
+
+while ! dcop | grep -q TestApp; do echo -n '.'; sleep 2; done
+
+echo ' started'
+
+echo '* Running driver mode'
+./driver `dcop 'TestApp-*'` >driver.stdout
+
+echo '* Running shell mode'
+source shell.generated >shell.returns
+
+echo -n '* Comparing ... '
+
+compare()
+{
+if ! diff -q --strip-trailing-cr $1 $2; then
+ echo "FAILED:"
+ diff -u $1 $2
+ exit 1;
+fi
+}
+
+compare batch.stdout shell.stdout
+compare batch.stdout driver.stdout
+compare batch.returns shell.returns
+compare batch.returns driver.returns
+
+clean_up
+
+echo "Passed"
+exit 0;
+
diff --git a/dcop/tests/test.cpp b/dcop/tests/test.cpp
new file mode 100644
index 000000000..025230547
--- /dev/null
+++ b/dcop/tests/test.cpp
@@ -0,0 +1,44 @@
+#include "test.h"
+#include <kapplication.h>
+#include <iostream>
+#include <dcopclient.h>
+#include <kcmdlineargs.h>
+
+
+
+Test::~Test()
+{
+}
+
+#include "definitions.generated"
+
+using namespace std;
+
+void batch()
+{
+ QTextStream output( fopen( "batch.returns", "w" ) , IO_WriteOnly );
+ Test* object = new Test;
+#include "batch.generated"
+}
+
+#ifdef Q_OS_WIN
+# define main kdemain
+#endif
+
+int main(int argc, char** argv)
+{
+ if ( argc > 1 ) {
+ batch();
+ return 0;
+ }
+ KCmdLineArgs::init( argc, argv, "TestApp", "Tests the dcop familly of tools + libraries", "1.0" ); // FIXME
+ KApplication app;
+ if(!app.dcopClient()->attach( ))
+ return 1;
+
+ app.dcopClient()->registerAs( "TestApp" );
+ new Test;
+ return app.exec();
+}
+
+
diff --git a/dcop/tests/testcases b/dcop/tests/testcases
new file mode 100644
index 000000000..0f16bdbe3
--- /dev/null
+++ b/dcop/tests/testcases
@@ -0,0 +1,105 @@
+# Format of this file:
+#
+# Lines beginning with '#' are comments
+# The file consists of a repetion of the following pattern
+# (\n means newline and + means you can repeat the line):
+#
+# // comment \n+
+# return_type \n
+# function_name \n
+# (argument_list) \n
+# { \n
+# body \n
+# } \n
+# arguments_to_use_in_shell;arguments_to_use_in_c++ \n+
+#
+# The last line has a few nuances:
+# 1. to call a void function you can use '-' or leave it out.
+#
+# 2. First you put shell like argument:
+# "string with spaces" 4 string_without_spaces
+# Then you should put c++ style arguments:
+# QString::fromLatin1("string with spaces"),4,"string_with_spaces"
+#
+# Note that the first argument has type QString and the last type const char*
+# (adapt accordingly)
+#
+// 1. easy case
+QString
+url
+()
+{
+return QString::fromLatin1( "http://www.kde.org/");
+}
+-
+
+// 2.1 overloading on number of args
+unsigned
+getObject
+( int num )
+{
+ return num;
+}
+42;42
+1;1
+
+
+
+unsigned int
+getObject
+( int x, int y)
+{
+ return x + y;
+}
+2 3;2,3
+
+
+
+
+// 2.2 overloading on type of args
+QString
+identity
+( QString x)
+{
+ return x;
+}
+"test";QString::fromLatin1("test")
+
+// 2.3 unsigned long int
+unsigned long int
+getObject23
+( int x, int y)
+{
+ return x + y;
+}
+2 3;2,3
+
+
+
+// 2.4 unsigned long int
+unsigned long int
+getObject24
+( unsigned long int x, int y)
+{
+ return x + y;
+}
+5 7;5,7
+
+
+
+#virtual QString identity( QCString );
+#
+#// 4. simple template argument:
+#virtual
+#
+#// 3. simple template return type:
+#virtual QValueList<DCOPRef> getWindows();
+#
+#
+#// spaces in the return value
+#virtual unsigned long int srvv();
+#unsigned long int srv();
+#
+#// spaces in the return value's template
+#QValueList< DCOPRef > srvtv();
+#QValueList< DCOPRef > srvt();