blob: ebf2d174ac4431bd1869168324a58731ca166bc0 [file] [log] [blame]
/* nih-dbus-tool
*
* test_interface.c - test suite for nih-dbus-tool/interface.c
*
* Copyright © 2009 Scott James Remnant <scott@netsplit.com>.
* Copyright © 2009 Canonical Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <nih/test.h>
#include <expat.h>
#include <errno.h>
#include <assert.h>
#include <nih/macros.h>
#include <nih/alloc.h>
#include <nih/list.h>
#include <nih/string.h>
#include <nih/main.h>
#include <nih/error.h>
#include "type.h"
#include "node.h"
#include "interface.h"
#include "method.h"
#include "signal.h"
#include "property.h"
#include "parse.h"
#include "errors.h"
void
test_name_valid (void)
{
TEST_FUNCTION ("interface_name_valid");
/* Check that a typical interface name is valid. */
TEST_FEATURE ("with typical interface name");
TEST_TRUE (interface_name_valid ("com.netsplit.Nih.Test"));
/* Check that an interface name is not valid if it is has an
* initial period.
*/
TEST_FEATURE ("with initial period");
TEST_FALSE (interface_name_valid (".com.netsplit.Nih.Test"));
/* Check that an interface name is not valid if it has multiple
* consecutive periods.
*/
TEST_FEATURE ("with consecutive periods");
TEST_FALSE (interface_name_valid ("com..netsplit.Nih.Test"));
/* Check that an interface name is not valid if it ends in a period */
TEST_FEATURE ("with final period");
TEST_FALSE (interface_name_valid ("com.netsplit.Nih.Test."));
/* Check that an interface name is not valid if it only has one
* component
*/
TEST_FEATURE ("with only one component");
TEST_FALSE (interface_name_valid ("com"));
/* Check that an interface name is valid if it has two components.
*/
TEST_FEATURE ("with two components");
TEST_TRUE (interface_name_valid ("com.netsplit"));
/* Check that a interface name elements may contain numbers */
TEST_FEATURE ("with numbers in interface name");
TEST_TRUE (interface_name_valid ("com.netsplit.a43b.Test"));
/* Check that a interface name elements may not begin with numbers */
TEST_FEATURE ("with numbers starting interface name element");
TEST_FALSE (interface_name_valid ("com.netsplit.43b.Test"));
/* Check that the first interface name element may not begin
* with numbers
*/
TEST_FEATURE ("with numbers starting first interface name element");
TEST_FALSE (interface_name_valid ("32com.netsplit.Nih.Test"));
/* Check that a interface name elements may contain underscores */
TEST_FEATURE ("with underscore in interface name");
TEST_TRUE (interface_name_valid ("com.netsplit.Nih_Test"));
/* Check that a interface name elements may begin with underscores */
TEST_FEATURE ("with underscore starting interface name element");
TEST_TRUE (interface_name_valid ("com.netsplit._Nih.Test"));
/* Check that other characters are not permitted */
TEST_FEATURE ("with non-permitted characters");
TEST_FALSE (interface_name_valid ("com.netsplit/Nih.Test-Thing"));
/* Check that an empty interface name is invalid */
TEST_FEATURE ("with empty string");
TEST_FALSE (interface_name_valid (""));
/* Check that an interface name may not exceed 255 characters */
TEST_FEATURE ("with overly long name");
TEST_FALSE (interface_name_valid ("com.netsplit.Nih.ReallyLongInt"
"erfaceNameThatNobodyInTheirRig"
"htMindWouldEverUseButStillWeNe"
"edToTestThisKindOfShitSeriousl"
"yLookHowLongThisIs.IMeanYoureJ"
"ustNeverGoingToGetAnywhereNear"
"ThisLimitInFactIfTheLimitIsThi"
"sLongWhyHaveOneAtAllStupidSoft"
"ware.YayThereNow"));
}
void
test_new (void)
{
Interface *interface;
/* Check that an Interface object is allocated with the structure
* filled in properly, but not placed in a list.
*/
TEST_FUNCTION ("interface_new");
TEST_ALLOC_FAIL {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
if (test_alloc_failed) {
TEST_EQ_P (interface, NULL);
continue;
}
TEST_ALLOC_SIZE (interface, sizeof (Interface));
TEST_LIST_EMPTY (&interface->entry);
TEST_EQ_STR (interface->name, "com.netsplit.Nih.Test");
TEST_ALLOC_PARENT (interface->name, interface);
TEST_EQ_P (interface->symbol, NULL);
TEST_FALSE (interface->deprecated);
TEST_LIST_EMPTY (&interface->methods);
TEST_LIST_EMPTY (&interface->signals);
TEST_LIST_EMPTY (&interface->properties);
nih_free (interface);
}
}
void
test_start_tag (void)
{
ParseContext context;
ParseStack * parent = NULL;
ParseStack * entry = NULL;
XML_Parser xmlp;
Node * node = NULL;
Interface * interface;
char * attr[5];
int ret = 0;
NihError * err;
FILE * output;
TEST_FUNCTION ("interface_start_tag");
context.parent = NULL;
nih_list_init (&context.stack);
context.filename = "foo";
context.node = NULL;
assert (xmlp = XML_ParserCreate ("UTF-8"));
XML_SetUserData (xmlp, &context);
output = tmpfile ();
/* Check that an interface tag for an node with the usual name
* attribute results in an Interface member being created and pushed
* onto the stack with that attribute filled in correctly.
*/
TEST_FEATURE ("with interface");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
}
attr[0] = "name";
attr[1] = "com.netsplit.Nih.Test";
attr[2] = NULL;
ret = interface_start_tag (xmlp, "interface", attr);
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_EQ_P (parse_stack_top (&context.stack),
parent);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
entry = parse_stack_top (&context.stack);
TEST_NE_P (entry, parent);
TEST_ALLOC_SIZE (entry, sizeof (ParseStack));
TEST_EQ (entry->type, PARSE_INTERFACE);
interface = entry->interface;
TEST_ALLOC_SIZE (interface, sizeof (Interface));
TEST_ALLOC_PARENT (interface, entry);
TEST_EQ_STR (interface->name, "com.netsplit.Nih.Test");
TEST_ALLOC_PARENT (interface->name, interface);
TEST_EQ_P (interface->symbol, NULL);
TEST_LIST_EMPTY (&interface->methods);
TEST_LIST_EMPTY (&interface->signals);
TEST_LIST_EMPTY (&interface->properties);
TEST_LIST_EMPTY (&node->interfaces);
nih_free (entry);
nih_free (parent);
}
/* Check that a interface with a missing name attribute results
* in an error being raised.
*/
TEST_FEATURE ("with missing name");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
attr[0] = NULL;
}
ret = interface_start_tag (xmlp, "interface", attr);
TEST_LT (ret, 0);
TEST_EQ_P (parse_stack_top (&context.stack), parent);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, INTERFACE_MISSING_NAME);
nih_free (err);
nih_free (parent);
}
/* Check that a interface with an invalid name results in an
* error being raised.
*/
TEST_FEATURE ("with invalid name");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
attr[0] = "name";
attr[1] = "Test Interface";
attr[2] = NULL;
}
ret = interface_start_tag (xmlp, "interface", attr);
TEST_LT (ret, 0);
TEST_EQ_P (parse_stack_top (&context.stack), parent);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, INTERFACE_INVALID_NAME);
nih_free (err);
nih_free (parent);
}
/* Check that an unknown interface attribute results in a warning
* being printed to standard error, but is otherwise ignored
* and the normal processing finished.
*/
TEST_FEATURE ("with unknown attribute");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
attr[0] = "name";
attr[1] = "com.netsplit.Nih.Test";
attr[2] = "frodo";
attr[3] = "baggins";
attr[4] = NULL;
}
TEST_DIVERT_STDERR (output) {
ret = interface_start_tag (xmlp, "interface", attr);
}
rewind (output);
if (test_alloc_failed
&& (ret < 0)) {
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
TEST_EQ_P (parse_stack_top (&context.stack), parent);
TEST_FILE_RESET (output);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
entry = parse_stack_top (&context.stack);
TEST_NE_P (entry, parent);
TEST_ALLOC_SIZE (entry, sizeof (ParseStack));
TEST_EQ (entry->type, PARSE_INTERFACE);
interface = entry->interface;
TEST_ALLOC_SIZE (interface, sizeof (Interface));
TEST_ALLOC_PARENT (interface, entry);
TEST_EQ_STR (interface->name, "com.netsplit.Nih.Test");
TEST_ALLOC_PARENT (interface->name, interface);
TEST_EQ_P (interface->symbol, NULL);
TEST_LIST_EMPTY (&interface->methods);
TEST_LIST_EMPTY (&interface->signals);
TEST_LIST_EMPTY (&interface->properties);
TEST_LIST_EMPTY (&node->interfaces);
TEST_FILE_EQ (output, ("test:foo:1:0: Ignored unknown <interface> attribute: "
"frodo\n"));
TEST_FILE_END (output);
TEST_FILE_RESET (output);
nih_free (entry);
nih_free (parent);
}
/* Check that a interface on an empty stack (ie. a top-level
* interface element) results in a warning being printed on
* standard error and an ignored element being pushed onto the
* stack.
*/
TEST_FEATURE ("with empty stack");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
attr[0] = "name";
attr[1] = "com.netsplit.Nih.Test";
attr[2] = NULL;
}
TEST_DIVERT_STDERR (output) {
ret = interface_start_tag (xmlp, "interface", attr);
}
rewind (output);
if (test_alloc_failed
&& (ret < 0)) {
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
TEST_EQ_P (parse_stack_top (&context.stack), NULL);
TEST_FILE_RESET (output);
continue;
}
TEST_EQ (ret, 0);
entry = parse_stack_top (&context.stack);
TEST_ALLOC_SIZE (entry, sizeof (ParseStack));
TEST_EQ (entry->type, PARSE_IGNORED);
TEST_EQ_P (entry->data, NULL);
TEST_FILE_EQ (output, "test:foo:1:0: Ignored unexpected <interface> tag\n");
TEST_FILE_END (output);
TEST_FILE_RESET (output);
nih_free (entry);
}
/* Check that a interface on top of a stack entry that's not an
* node results in a warning being printed on
* standard error and an ignored element being pushed onto the
* stack.
*/
TEST_FEATURE ("with non-node on stack");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
parent = parse_stack_push (NULL, &context.stack,
PARSE_METHOD, method_new (NULL, "Test"));
attr[0] = "name";
attr[1] = "com.netsplit.Nih.Test";
attr[2] = NULL;
}
TEST_DIVERT_STDERR (output) {
ret = interface_start_tag (xmlp, "interface", attr);
}
rewind (output);
if (test_alloc_failed
&& (ret < 0)) {
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
TEST_EQ_P (parse_stack_top (&context.stack), parent);
TEST_FILE_RESET (output);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
entry = parse_stack_top (&context.stack);
TEST_NE_P (entry, parent);
TEST_ALLOC_SIZE (entry, sizeof (ParseStack));
TEST_EQ (entry->type, PARSE_IGNORED);
TEST_EQ_P (entry->data, NULL);
TEST_FILE_EQ (output, "test:foo:1:0: Ignored unexpected <interface> tag\n");
TEST_FILE_END (output);
TEST_FILE_RESET (output);
nih_free (entry);
nih_free (parent);
}
XML_ParserFree (xmlp);
fclose (output);
}
void
test_end_tag (void)
{
ParseContext context;
ParseStack * parent = NULL;
ParseStack * entry = NULL;
XML_Parser xmlp;
Node * node = NULL;
Interface * interface = NULL;
Interface * other = NULL;
int ret;
NihError * err;
char * symbol;
TEST_FUNCTION ("interface_end_tag");
context.parent = NULL;
nih_list_init (&context.stack);
context.filename = "foo";
context.node = NULL;
assert (xmlp = XML_ParserCreate ("UTF-8"));
XML_SetUserData (xmlp, &context);
/* Check that when we parse the end tag for a interface, we pop
* the Interface object off the stack (freeing and removing it)
* and append it to the parent node's interfaces list, adding a
* reference to the node as well. A symbol should be generated
* for the interface by taking the last part of the Interface
* name and convering it to C style.
*/
TEST_FEATURE ("with no assigned symbol");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
interface = interface_new (NULL, "com.netsplit.Nih.TestInterface");
entry = parse_stack_push (NULL, &context.stack,
PARSE_INTERFACE, interface);
}
TEST_FREE_TAG (entry);
ret = interface_end_tag (xmlp, "interface");
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_NOT_FREE (entry);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (entry);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
TEST_FREE (entry);
TEST_ALLOC_PARENT (interface, node);
TEST_LIST_NOT_EMPTY (&node->interfaces);
TEST_EQ_P (node->interfaces.next, &interface->entry);
TEST_EQ_STR (interface->symbol, "test_interface");
TEST_ALLOC_PARENT (interface->symbol, interface);
nih_free (parent);
}
/* Check that when the symbol has been pre-assigned by the data,
* it's not overriden and is used even if different.
*/
TEST_FEATURE ("with assigned symbol");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = nih_strdup (interface, "foo");
entry = parse_stack_push (NULL, &context.stack,
PARSE_INTERFACE, interface);
}
TEST_FREE_TAG (entry);
ret = interface_end_tag (xmlp, "interface");
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_NOT_FREE (entry);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (entry);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
TEST_FREE (entry);
TEST_ALLOC_PARENT (interface, node);
TEST_LIST_NOT_EMPTY (&node->interfaces);
TEST_EQ_P (node->interfaces.next, &interface->entry);
TEST_EQ_STR (interface->symbol, "foo");
TEST_ALLOC_PARENT (interface->symbol, interface);
nih_free (parent);
}
/* Check that the symbol may be set to the empty string, in which
* case it's set to NULL after the call to this function.
*/
TEST_FEATURE ("with empty string for symbol");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = nih_strdup (interface, "");
entry = parse_stack_push (NULL, &context.stack,
PARSE_INTERFACE, interface);
}
symbol = interface->symbol;
TEST_FREE_TAG (symbol);
TEST_FREE_TAG (entry);
ret = interface_end_tag (xmlp, "interface");
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_NOT_FREE (symbol);
TEST_NOT_FREE (entry);
TEST_LIST_EMPTY (&node->interfaces);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (entry);
nih_free (parent);
continue;
}
TEST_EQ (ret, 0);
TEST_FREE (entry);
TEST_ALLOC_PARENT (interface, node);
TEST_LIST_NOT_EMPTY (&node->interfaces);
TEST_EQ_P (node->interfaces.next, &interface->entry);
TEST_FREE (symbol);
TEST_EQ_P (interface->symbol, NULL);
nih_free (parent);
}
/* Check that we don't generate a duplicate symbol, and instead
* raise an error and allow the user to deal with it using
* the Symbol annotation. The reason we don't work around this
* with a counter or similar is that the function names then
* become unpredictable (introspection data isn't ordered).
*/
TEST_FEATURE ("with conflicting symbol");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
node = node_new (NULL, "/com/netsplit/Nih/Test");
parent = parse_stack_push (NULL, &context.stack,
PARSE_NODE, node);
other = interface_new (node, "com.netsplit.Foo.Test");
other->symbol = nih_strdup (other, "test");
nih_list_add (&node->interfaces, &other->entry);
interface = interface_new (NULL, "com.netsplit.Nih.Test");
entry = parse_stack_push (NULL, &context.stack,
PARSE_INTERFACE, interface);
}
ret = interface_end_tag (xmlp, "interface");
TEST_LT (ret, 0);
err = nih_error_get ();
if ((! test_alloc_failed)
|| (err->number != ENOMEM))
TEST_EQ (err->number, INTERFACE_DUPLICATE_SYMBOL);
nih_free (err);
nih_free (entry);
nih_free (parent);
}
XML_ParserFree (xmlp);
}
void
test_annotation (void)
{
Interface *interface = NULL;
char * symbol;
int ret;
NihError * err;
TEST_FUNCTION ("interface_annotation");
/* Check that the annotation to mark a interface as deprecated is
* handled, and the Interface is marked deprecated.
*/
TEST_FEATURE ("with deprecated annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"org.freedesktop.DBus.Deprecated",
"true");
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_FALSE (interface->deprecated);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (interface);
continue;
}
TEST_EQ (ret, 0);
TEST_TRUE (interface->deprecated);
nih_free (interface);
}
/* Check that the annotation to mark a interface as deprecated can be
* given a false value to explicitly mark the Interface non-deprecated.
*/
TEST_FEATURE ("with explicitly non-deprecated annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->deprecated = TRUE;
}
ret = interface_annotation (interface,
"org.freedesktop.DBus.Deprecated",
"false");
if (test_alloc_failed) {
TEST_LT (ret, 0);
TEST_TRUE (interface->deprecated);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (interface);
continue;
}
TEST_EQ (ret, 0);
TEST_FALSE (interface->deprecated);
nih_free (interface);
}
/* Check that an annotation to add a symbol to the interface is
* handled, and the new symbol is stored in the interface.
*/
TEST_FEATURE ("with symbol annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"com.netsplit.Nih.Symbol",
"foo");
if (test_alloc_failed) {
TEST_LT (ret, 0);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (interface);
continue;
}
TEST_EQ (ret, 0);
TEST_EQ_STR (interface->symbol, "foo");
TEST_ALLOC_PARENT (interface->symbol, interface);
nih_free (interface);
}
/* Check that an annotation to add a symbol to the interface
* replaces any previous symbol applied (e.g. by a previous
* annotation).
*/
TEST_FEATURE ("with symbol annotation and existing symbol");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = nih_strdup (interface, "test_arg");
}
symbol = interface->symbol;
TEST_FREE_TAG (symbol);
ret = interface_annotation (interface,
"com.netsplit.Nih.Symbol",
"foo");
if (test_alloc_failed) {
TEST_LT (ret, 0);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (interface);
continue;
}
TEST_EQ (ret, 0);
TEST_FREE (symbol);
TEST_EQ_STR (interface->symbol, "foo");
TEST_ALLOC_PARENT (interface->symbol, interface);
nih_free (interface);
}
/* Check that an annotation to request no symbol for the interface
* is handled.
*/
TEST_FEATURE ("with empty symbol annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"com.netsplit.Nih.Symbol",
"");
if (test_alloc_failed) {
TEST_LT (ret, 0);
err = nih_error_get ();
TEST_EQ (err->number, ENOMEM);
nih_free (err);
nih_free (interface);
continue;
}
TEST_EQ (ret, 0);
TEST_EQ_STR (interface->symbol, "");
TEST_ALLOC_PARENT (interface->symbol, interface);
nih_free (interface);
}
/* Check that an invalid value for the deprecated annotation results
* in an error being raised.
*/
TEST_FEATURE ("with invalid value for deprecated annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"org.freedesktop.DBus.Deprecated",
"foo");
TEST_LT (ret, 0);
TEST_EQ_P (interface->symbol, NULL);
err = nih_error_get ();
TEST_EQ (err->number, INTERFACE_ILLEGAL_DEPRECATED);
nih_free (err);
nih_free (interface);
}
/* Check that an invalid symbol in an annotation results in an
* error being raised.
*/
TEST_FEATURE ("with invalid symbol in annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"com.netsplit.Nih.Symbol",
"foo bar");
TEST_LT (ret, 0);
TEST_EQ_P (interface->symbol, NULL);
err = nih_error_get ();
TEST_EQ (err->number, INTERFACE_INVALID_SYMBOL);
nih_free (err);
nih_free (interface);
}
/* Check that an unknown annotation results in an error being
* raised.
*/
TEST_FEATURE ("with unknown annotation");
TEST_ALLOC_FAIL {
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
}
ret = interface_annotation (interface,
"com.netsplit.Nih.Unknown",
"true");
TEST_LT (ret, 0);
err = nih_error_get ();
TEST_EQ (err->number, INTERFACE_UNKNOWN_ANNOTATION);
nih_free (err);
nih_free (interface);
}
}
void
test_methods_array (void)
{
NihList prototypes;
Interface *interface = NULL;
Method * method = NULL;
Argument * arg = NULL;
char * str;
TypeVar * var;
TEST_FUNCTION ("interface_methods_array");
/* Check that we can generate an array of interface methods with
* their handler functions. The C code returned should be lined up
* nicely and include the argument variable definitions as well.
*/
TEST_FEATURE ("with handlers");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
}
str = interface_methods_array (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, my_com_netsplit_Nih_Test_Poke_method },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, my_com_netsplit_Nih_Test_Peek_method },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, my_com_netsplit_Nih_Test_IsValidAddress_method },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusMethod");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_methods");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that we can generate an array of interface methods without
* their handler functions. The C code returned should be lined up
* nicely, but should include NULL in the place of the handler
* function.
*/
TEST_FEATURE ("without handlers");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
}
str = interface_methods_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, NULL },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, NULL },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, NULL },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusMethod");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_methods");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that the array is returned empty if the interface has
* no methods.
*/
TEST_FEATURE ("with no methods");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
}
str = interface_methods_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusMethod");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_methods");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
}
void
test_signals_array (void)
{
NihList prototypes;
Interface *interface = NULL;
Signal * signal = NULL;
Argument * arg = NULL;
char * str;
TypeVar * var;
TEST_FUNCTION ("interface_signals_array");
/* Check that we can generate an array of interface signals with
* their filter functions. The C code returned should be lined up
* nicely and include the argument variable definitions as well.
*/
TEST_FEATURE ("with filters");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
}
str = interface_signals_array (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, my_com_netsplit_Nih_Test_Bounce_signal },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, my_com_netsplit_Nih_Test_Exploded_signal },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusSignal");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_signals");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that we can generate an array of interface signals without
* their filter functions. The C code returned should be lined up
* nicely, but should include NULL in the place of the filter
* function.
*/
TEST_FEATURE ("without filters");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
}
str = interface_signals_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, NULL },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, NULL },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusSignal");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_signals");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that the array is returned empty if the interface has
* no signals.
*/
TEST_FEATURE ("with no signals");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
}
str = interface_signals_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusSignal");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_signals");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
}
void
test_properties_array (void)
{
NihList prototypes;
Interface *interface = NULL;
Property * property = NULL;
char * str;
TypeVar * var;
TEST_FUNCTION ("interface_properties_array");
/* Check that we can create an array of an interface's properties,
* with getter and setter functions filled in where appropriate.
* Each of the columns should be lined up nicely.
*/
TEST_FEATURE ("with handler functions");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_properties_array (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, my_com_netsplit_Nih_Test_colour_get, my_com_netsplit_Nih_Test_colour_set },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, my_com_netsplit_Nih_Test_size_get, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, my_com_netsplit_Nih_Test_touch_set },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusProperty");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_properties");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that we can create an array of an interface's properties
* without getter and setter functions filled in. Each of the
* columns should still be lined up.
*/
TEST_FEATURE ("without handler functions");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_properties_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, NULL, NULL },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, NULL, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, NULL },\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusProperty");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_properties");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that we return an empty array when the interface has no
* properties.
*/
TEST_FEATURE ("with no properties");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
}
str = interface_properties_array (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ NULL }\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusProperty");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test_properties");
TEST_ALLOC_PARENT (var->name, var);
TEST_TRUE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
}
void
test_struct (void)
{
NihList prototypes;
Interface *interface = NULL;
Method * method = NULL;
Signal * signal = NULL;
Argument * arg = NULL;
Property * property = NULL;
char * str;
TypeVar * var;
TEST_FUNCTION ("interface_struct");
/* Check that we can generate the structure variable code for an
* interface with many methods, signals and properties. We want
* the members set up for an object implementation, so the method
* and property function pointers should be set and not the signal
* filter pointer.
*/
TEST_FEATURE ("with object");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_struct (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, my_com_netsplit_Nih_Test_Poke_method },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, my_com_netsplit_Nih_Test_Peek_method },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, my_com_netsplit_Nih_Test_IsValidAddress_method },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, NULL },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, NULL },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, my_com_netsplit_Nih_Test_colour_get, my_com_netsplit_Nih_Test_colour_set },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, my_com_netsplit_Nih_Test_size_get, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, my_com_netsplit_Nih_Test_touch_set },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that we can generate the structure variable code for an
* interface with many methods, signals and properties. We want
* the members set up for a proxy implementation, so the signal
* filter pointer should be set but not the method or property
* function pointers.
*/
TEST_FEATURE ("with proxy");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_struct (NULL, "my", interface, FALSE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, NULL },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, NULL },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, NULL },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, my_com_netsplit_Nih_Test_Bounce_signal },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, my_com_netsplit_Nih_Test_Exploded_signal },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, NULL, NULL },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, NULL, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, NULL },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that valid code is still returned when there are no
* methods.
*/
TEST_FEATURE ("with no methods");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_struct (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, NULL },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, NULL },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, my_com_netsplit_Nih_Test_colour_get, my_com_netsplit_Nih_Test_colour_set },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, my_com_netsplit_Nih_Test_size_get, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, my_com_netsplit_Nih_Test_touch_set },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that valid code is still returned when there are no
* signals.
*/
TEST_FEATURE ("with no signals");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
property = property_new (interface, "colour",
"s", NIH_DBUS_READWRITE);
property->symbol = "colour";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "size",
"u", NIH_DBUS_READ);
property->symbol = "size";
nih_list_add (&interface->properties, &property->entry);
property = property_new (interface, "touch",
"b", NIH_DBUS_WRITE);
property->symbol = "touch";
nih_list_add (&interface->properties, &property->entry);
}
str = interface_struct (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, my_com_netsplit_Nih_Test_Poke_method },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, my_com_netsplit_Nih_Test_Peek_method },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, my_com_netsplit_Nih_Test_IsValidAddress_method },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ \"colour\", \"s\", NIH_DBUS_READWRITE, my_com_netsplit_Nih_Test_colour_get, my_com_netsplit_Nih_Test_colour_set },\n"
"\t{ \"size\", \"u\", NIH_DBUS_READ, my_com_netsplit_Nih_Test_size_get, NULL },\n"
"\t{ \"touch\", \"b\", NIH_DBUS_WRITE, NULL, my_com_netsplit_Nih_Test_touch_set },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that valid code is still returned when there are no
* properties.
*/
TEST_FEATURE ("with no properties");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
method = method_new (interface, "Poke");
method->symbol = "poke";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_IN);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "Peek");
method->symbol = "peek";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
arg = argument_new (method, "value",
"s", NIH_DBUS_ARG_OUT);
arg->symbol = "value";
nih_list_add (&method->arguments, &arg->entry);
method = method_new (interface, "IsValidAddress");
method->symbol = "is_valid_address";
nih_list_add (&interface->methods, &method->entry);
arg = argument_new (method, "address",
"u", NIH_DBUS_ARG_IN);
arg->symbol = "address";
nih_list_add (&method->arguments, &arg->entry);
signal = signal_new (interface, "Bounce");
signal->symbol = "bounce";
nih_list_add (&interface->signals, &signal->entry);
arg = argument_new (signal, "height",
"u", NIH_DBUS_ARG_OUT);
arg->symbol = "height";
nih_list_add (&signal->arguments, &arg->entry);
arg = argument_new (signal, "velocity",
"i", NIH_DBUS_ARG_OUT);
arg->symbol = "velocity";
nih_list_add (&signal->arguments, &arg->entry);
signal = signal_new (interface, "Exploded");
signal->symbol = "exploded";
nih_list_add (&interface->signals, &signal->entry);
}
str = interface_struct (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusArg my_com_netsplit_Nih_Test_Poke_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Peek_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ \"value\", \"s\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_IsValidAddress_method_args[] = {\n"
"\t{ \"address\", \"u\", NIH_DBUS_ARG_IN },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ \"Poke\", my_com_netsplit_Nih_Test_Poke_method_args, my_com_netsplit_Nih_Test_Poke_method },\n"
"\t{ \"Peek\", my_com_netsplit_Nih_Test_Peek_method_args, my_com_netsplit_Nih_Test_Peek_method },\n"
"\t{ \"IsValidAddress\", my_com_netsplit_Nih_Test_IsValidAddress_method_args, my_com_netsplit_Nih_Test_IsValidAddress_method },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Bounce_signal_args[] = {\n"
"\t{ \"height\", \"u\", NIH_DBUS_ARG_OUT },\n"
"\t{ \"velocity\", \"i\", NIH_DBUS_ARG_OUT },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusArg my_com_netsplit_Nih_Test_Exploded_signal_args[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ \"Bounce\", my_com_netsplit_Nih_Test_Bounce_signal_args, NULL },\n"
"\t{ \"Exploded\", my_com_netsplit_Nih_Test_Exploded_signal_args, NULL },\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
/* Check that valid code is still returned when there are no
* methods, signals or properties.
*/
TEST_FEATURE ("with no members");
TEST_ALLOC_FAIL {
nih_list_init (&prototypes);
TEST_ALLOC_SAFE {
interface = interface_new (NULL, "com.netsplit.Nih.Test");
interface->symbol = "test";
}
str = interface_struct (NULL, "my", interface, TRUE,
&prototypes);
if (test_alloc_failed) {
TEST_EQ_P (str, NULL);
TEST_LIST_EMPTY (&prototypes);
nih_free (interface);
continue;
}
TEST_EQ_STR (str,
"static const NihDBusMethod my_com_netsplit_Nih_Test_methods[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusSignal my_com_netsplit_Nih_Test_signals[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"static const NihDBusProperty my_com_netsplit_Nih_Test_properties[] = {\n"
"\t{ NULL }\n"
"};\n"
"\n"
"const NihDBusInterface my_com_netsplit_Nih_Test = {\n"
"\t\"com.netsplit.Nih.Test\",\n"
"\tmy_com_netsplit_Nih_Test_methods,\n"
"\tmy_com_netsplit_Nih_Test_signals,\n"
"\tmy_com_netsplit_Nih_Test_properties\n"
"};\n");
TEST_LIST_NOT_EMPTY (&prototypes);
var = (TypeVar *)prototypes.next;
TEST_ALLOC_SIZE (var, sizeof (TypeVar));
TEST_ALLOC_PARENT (var, str);
TEST_EQ_STR (var->type, "const NihDBusInterface");
TEST_ALLOC_PARENT (var->type, var);
TEST_EQ_STR (var->name, "my_com_netsplit_Nih_Test");
TEST_ALLOC_PARENT (var->name, var);
TEST_FALSE (var->array);
nih_free (var);
TEST_LIST_EMPTY (&prototypes);
nih_free (str);
nih_free (interface);
}
}
int
main (int argc,
char *argv[])
{
program_name = "test";
nih_error_init ();
test_name_valid ();
test_new ();
test_start_tag ();
test_end_tag ();
test_annotation ();
test_methods_array ();
test_signals_array ();
test_properties_array ();
test_struct ();
return 0;
}