summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-07-14 15:48:58 -0400
committerDavid Robillard <d@drobilla.net>2016-07-14 15:48:58 -0400
commitd92e316db4d5e28a05400d834e9f43c592f764fb (patch)
treeac071034fc96d97cd096c24e0a5d72f4d8b7f2d1 /test
parent84ec2ee47279f87b4ed9ee44c9153f52a97732da (diff)
downloadlilv-d92e316db4d5e28a05400d834e9f43c592f764fb.tar.gz
lilv-d92e316db4d5e28a05400d834e9f43c592f764fb.tar.bz2
lilv-d92e316db4d5e28a05400d834e9f43c592f764fb.zip
Improve test coverage
Diffstat (limited to 'test')
-rw-r--r--test/bad_syntax.lv2/bad_syntax.c93
-rw-r--r--test/bad_syntax.lv2/bad_syntax.ttl.in22
-rw-r--r--test/bad_syntax.lv2/manifest.ttl.in7
-rw-r--r--test/bad_syntax.lv2/test_bad_syntax.c45
-rw-r--r--test/failed_instantiation.lv2/failed_instantiation.c70
-rw-r--r--test/failed_instantiation.lv2/failed_instantiation.ttl.in40
-rw-r--r--test/failed_instantiation.lv2/manifest.ttl.in7
-rw-r--r--test/failed_instantiation.lv2/test_failed_instantiation.c45
-rw-r--r--test/lilv_test.c40
-rw-r--r--test/missing_name.lv2/missing_name.c2
-rw-r--r--test/missing_plugin.lv2/missing_plugin.c15
-rw-r--r--test/missing_port.lv2/manifest.ttl.in7
-rw-r--r--test/missing_port.lv2/missing_port.c93
-rw-r--r--test/missing_port.lv2/missing_port.ttl.in31
-rw-r--r--test/missing_port.lv2/test_missing_port.c45
15 files changed, 561 insertions, 1 deletions
diff --git a/test/bad_syntax.lv2/bad_syntax.c b/test/bad_syntax.lv2/bad_syntax.c
new file mode 100644
index 0000000..52620bd
--- /dev/null
+++ b/test/bad_syntax.lv2/bad_syntax.c
@@ -0,0 +1,93 @@
+/*
+ Lilv Test Plugin - Bad syntax in plugin data file
+ Copyright 2011-2016 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define PLUGIN_URI "http://example.org/bad-syntax"
+
+enum {
+ TEST_INPUT = 0,
+ TEST_OUTPUT = 1
+};
+
+typedef struct {
+ float* input;
+ float* output;
+} Test;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free((Test*)instance);
+}
+
+static void
+connect_port(LV2_Handle instance, uint32_t port, void* data)
+{
+ Test* test = (Test*)instance;
+ switch (port) {
+ case TEST_INPUT:
+ test->input = (float*)data;
+ break;
+ case TEST_OUTPUT:
+ test->output = (float*)data;
+ break;
+ default:
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* path,
+ const LV2_Feature* const* features)
+{
+ Test* test = (Test*)calloc(1, sizeof(Test));
+ if (!test) {
+ return NULL;
+ }
+
+ return (LV2_Handle)test;
+}
+
+static void
+run(LV2_Handle instance, uint32_t sample_count)
+{
+ Test* test = (Test*)instance;
+
+ *test->output = *test->input;
+}
+
+static const LV2_Descriptor descriptor = {
+ PLUGIN_URI,
+ instantiate,
+ connect_port,
+ NULL, // activate,
+ run,
+ NULL, // deactivate,
+ cleanup,
+ NULL // extension_data
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor* lv2_descriptor(uint32_t index)
+{
+ return (index == 0) ? &descriptor : NULL;
+}
diff --git a/test/bad_syntax.lv2/bad_syntax.ttl.in b/test/bad_syntax.lv2/bad_syntax.ttl.in
new file mode 100644
index 0000000..a96d1fc
--- /dev/null
+++ b/test/bad_syntax.lv2/bad_syntax.ttl.in
@@ -0,0 +1,22 @@
+# Lilv Test Plugin - Bad syntax in plugin data file
+# Copyright 2011-2016 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+
+<http://example.org/bad-syntax>
+ a plugin with a clearly broken data file \ No newline at end of file
diff --git a/test/bad_syntax.lv2/manifest.ttl.in b/test/bad_syntax.lv2/manifest.ttl.in
new file mode 100644
index 0000000..6350d8d
--- /dev/null
+++ b/test/bad_syntax.lv2/manifest.ttl.in
@@ -0,0 +1,7 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://example.org/bad-syntax>
+ a lv2:Plugin ;
+ lv2:binary <bad_syntax@SHLIB_EXT@> ;
+ rdfs:seeAlso <bad_syntax.ttl> .
diff --git a/test/bad_syntax.lv2/test_bad_syntax.c b/test/bad_syntax.lv2/test_bad_syntax.c
new file mode 100644
index 0000000..d20b8b7
--- /dev/null
+++ b/test/bad_syntax.lv2/test_bad_syntax.c
@@ -0,0 +1,45 @@
+#include "lilv/lilv.h"
+#include "../src/lilv_internal.h"
+
+#define PLUGIN_URI "http://example.org/bad-syntax"
+
+#define TEST_ASSERT(check) do {\
+ if (!(check)) {\
+ fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
+ return 1;\
+ }\
+} while (0)
+
+int
+main(int argc, char** argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
+ return 1;
+ }
+
+ const char* bundle_path = argv[1];
+ LilvWorld* world = lilv_world_new();
+
+ // Load test plugin bundle
+ uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
+ SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
+ LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ lilv_world_load_bundle(world, bundle_uri);
+ free(abs_bundle);
+ serd_node_free(&bundle);
+ lilv_node_free(bundle_uri);
+
+ LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
+
+ TEST_ASSERT(!lilv_plugin_get_name(plugin));
+ TEST_ASSERT(!lilv_plugin_instantiate(plugin, 48000, NULL));
+
+ lilv_node_free(plugin_uri);
+ lilv_world_free(world);
+
+ return 0;
+}
+
diff --git a/test/failed_instantiation.lv2/failed_instantiation.c b/test/failed_instantiation.lv2/failed_instantiation.c
new file mode 100644
index 0000000..aa90532
--- /dev/null
+++ b/test/failed_instantiation.lv2/failed_instantiation.c
@@ -0,0 +1,70 @@
+/*
+ Lilv Test Plugin - Failed instantiation
+ Copyright 2011-2016 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define PLUGIN_URI "http://example.org/failed-instantiation"
+
+enum {
+ TEST_INPUT = 0,
+ TEST_OUTPUT = 1
+};
+
+typedef struct {
+ float* input;
+ float* output;
+} Test;
+
+static void
+cleanup(LV2_Handle instance)
+{}
+
+static void
+connect_port(LV2_Handle instance, uint32_t port, void* data)
+{}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* path,
+ const LV2_Feature* const* features)
+{
+ return NULL;
+}
+
+static void
+run(LV2_Handle instance, uint32_t sample_count)
+{}
+
+static const LV2_Descriptor descriptor = {
+ PLUGIN_URI,
+ instantiate,
+ connect_port,
+ NULL, // activate,
+ run,
+ NULL, // deactivate,
+ cleanup,
+ NULL // extension_data
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor* lv2_descriptor(uint32_t index)
+{
+ return (index == 0) ? &descriptor : NULL;
+}
diff --git a/test/failed_instantiation.lv2/failed_instantiation.ttl.in b/test/failed_instantiation.lv2/failed_instantiation.ttl.in
new file mode 100644
index 0000000..8c7f678
--- /dev/null
+++ b/test/failed_instantiation.lv2/failed_instantiation.ttl.in
@@ -0,0 +1,40 @@
+# Lilv Test Plugin - Failed instantiation
+# Copyright 2011-2016 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+
+<http://example.org/failed-instantiation>
+ a lv2:Plugin ;
+ doap:license <http://opensource.org/licenses/isc> ;
+ doap:name "New version" ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:minorVersion 2 ;
+ lv2:microVersion 1 ;
+ lv2:port [
+ a lv2:InputPort ,
+ lv2:ControlPort ;
+ lv2:index 0 ;
+ lv2:symbol "input" ;
+ lv2:name "Input"
+ ] , [
+ a lv2:OutputPort ,
+ lv2:ControlPort ;
+ lv2:index 1 ;
+ lv2:symbol "output" ;
+ lv2:name "Output"
+ ] .
diff --git a/test/failed_instantiation.lv2/manifest.ttl.in b/test/failed_instantiation.lv2/manifest.ttl.in
new file mode 100644
index 0000000..d55a573
--- /dev/null
+++ b/test/failed_instantiation.lv2/manifest.ttl.in
@@ -0,0 +1,7 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://example.org/failed-instantiation>
+ a lv2:Plugin ;
+ lv2:binary <failed_instantiation@SHLIB_EXT@> ;
+ rdfs:seeAlso <failed_instantiation.ttl> .
diff --git a/test/failed_instantiation.lv2/test_failed_instantiation.c b/test/failed_instantiation.lv2/test_failed_instantiation.c
new file mode 100644
index 0000000..6efa0ae
--- /dev/null
+++ b/test/failed_instantiation.lv2/test_failed_instantiation.c
@@ -0,0 +1,45 @@
+#include "lilv/lilv.h"
+#include "../src/lilv_internal.h"
+
+#define PLUGIN_URI "http://example.org/failed-instantiation"
+
+#define TEST_ASSERT(check) do {\
+ if (!(check)) {\
+ fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
+ return 1;\
+ }\
+} while (0)
+
+int
+main(int argc, char** argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
+ return 1;
+ }
+
+ const char* bundle_path = argv[1];
+ LilvWorld* world = lilv_world_new();
+
+ // Load test plugin bundle
+ uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
+ SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
+ LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ lilv_world_load_bundle(world, bundle_uri);
+ free(abs_bundle);
+ serd_node_free(&bundle);
+ lilv_node_free(bundle_uri);
+
+ LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
+ TEST_ASSERT(plugin);
+
+ TEST_ASSERT(!lilv_plugin_instantiate(plugin, 48000, NULL));
+
+ lilv_node_free(plugin_uri);
+ lilv_world_free(world);
+
+ return 0;
+}
+
diff --git a/test/lilv_test.c b/test/lilv_test.c
index ebdef23..ca73b42 100644
--- a/test/lilv_test.c
+++ b/test/lilv_test.c
@@ -16,6 +16,7 @@
*/
#define _POSIX_C_SOURCE 200112L /* for setenv */
+#define _XOPEN_SOURCE 500 /* for mkstemp */
#include <assert.h>
#include <ctype.h>
@@ -254,6 +255,22 @@ test_value(void)
TEST_ASSERT(fabs(lilv_node_as_float(fval) - 1.6180) < FLT_EPSILON);
TEST_ASSERT(isnan(lilv_node_as_float(sval)));
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+ TEST_ASSERT(!strcmp(lilv_uri_to_path("file:///foo"), "/foo"));
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+# pragma GCC diagnostic pop
+#endif
+
LilvNode* loc_abs = lilv_new_file_uri(world, NULL, "/foo/bar");
LilvNode* loc_rel = lilv_new_file_uri(world, NULL, "foo");
LilvNode* host_abs = lilv_new_file_uri(world, "host", "/foo/bar");
@@ -346,6 +363,29 @@ test_util(void)
{
TEST_ASSERT(!lilv_realpath(NULL));
+ char a_path[16];
+ char b_path[16];
+ strcpy(a_path, "copy_a_XXXXXX");
+ strcpy(b_path, "copy_b_XXXXXX");
+ mkstemp(a_path);
+ mkstemp(b_path);
+
+ FILE* fa = fopen(a_path, "w");
+ FILE* fb = fopen(b_path, "w");
+ fprintf(fa, "AA\n");
+ fprintf(fb, "AB\n");
+ fclose(fa);
+ fclose(fb);
+
+ TEST_ASSERT(lilv_copy_file("does/not/exist", "copy"));
+ TEST_ASSERT(lilv_copy_file(a_path, "not/a/dir/copy"));
+ TEST_ASSERT(!lilv_copy_file(a_path, "copy_c"));
+ TEST_ASSERT(!lilv_file_equals(a_path, b_path));
+ TEST_ASSERT(lilv_file_equals(a_path, a_path));
+ TEST_ASSERT(lilv_file_equals(a_path, "copy_c"));
+ TEST_ASSERT(!lilv_file_equals("does/not/exist", b_path));
+ TEST_ASSERT(!lilv_file_equals(a_path, "does/not/exist"));
+ TEST_ASSERT(!lilv_file_equals("does/not/exist", "/does/not/either"));
return 1;
}
diff --git a/test/missing_name.lv2/missing_name.c b/test/missing_name.lv2/missing_name.c
index 8a198b9..6b86e09 100644
--- a/test/missing_name.lv2/missing_name.c
+++ b/test/missing_name.lv2/missing_name.c
@@ -1,5 +1,5 @@
/*
- Lilv Test Plugin - Missing descriptor
+ Lilv Test Plugin - Missing name
Copyright 2011-2015 David Robillard <d@drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
diff --git a/test/missing_plugin.lv2/missing_plugin.c b/test/missing_plugin.lv2/missing_plugin.c
index 577d42a..4d21226 100644
--- a/test/missing_plugin.lv2/missing_plugin.c
+++ b/test/missing_plugin.lv2/missing_plugin.c
@@ -21,8 +21,23 @@
#define PLUGIN_URI "http://example.org/missing-plugin"
+static const LV2_Descriptor descriptor = {
+ "http://example.org/not-the-plugin-you-are-looking-for",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
LV2_SYMBOL_EXPORT
const LV2_Descriptor* lv2_descriptor(uint32_t index)
{
+ if (index == 0) {
+ return &descriptor;
+ }
+
return NULL;
}
diff --git a/test/missing_port.lv2/manifest.ttl.in b/test/missing_port.lv2/manifest.ttl.in
new file mode 100644
index 0000000..c090042
--- /dev/null
+++ b/test/missing_port.lv2/manifest.ttl.in
@@ -0,0 +1,7 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://example.org/missing-port>
+ a lv2:Plugin ;
+ lv2:binary <missing_port@SHLIB_EXT@> ;
+ rdfs:seeAlso <missing_port.ttl> .
diff --git a/test/missing_port.lv2/missing_port.c b/test/missing_port.lv2/missing_port.c
new file mode 100644
index 0000000..dd7e9ff
--- /dev/null
+++ b/test/missing_port.lv2/missing_port.c
@@ -0,0 +1,93 @@
+/*
+ Lilv Test Plugin - Missing port
+ Copyright 2011-2016 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define PLUGIN_URI "http://example.org/missing-port"
+
+enum {
+ TEST_INPUT = 0,
+ TEST_OUTPUT = 1
+};
+
+typedef struct {
+ float* input;
+ float* output;
+} Test;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free((Test*)instance);
+}
+
+static void
+connect_port(LV2_Handle instance, uint32_t port, void* data)
+{
+ Test* test = (Test*)instance;
+ switch (port) {
+ case TEST_INPUT:
+ test->input = (float*)data;
+ break;
+ case TEST_OUTPUT:
+ test->output = (float*)data;
+ break;
+ default:
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* path,
+ const LV2_Feature* const* features)
+{
+ Test* test = (Test*)calloc(1, sizeof(Test));
+ if (!test) {
+ return NULL;
+ }
+
+ return (LV2_Handle)test;
+}
+
+static void
+run(LV2_Handle instance, uint32_t sample_count)
+{
+ Test* test = (Test*)instance;
+
+ *test->output = *test->input;
+}
+
+static const LV2_Descriptor descriptor = {
+ PLUGIN_URI,
+ instantiate,
+ connect_port,
+ NULL, // activate,
+ run,
+ NULL, // deactivate,
+ cleanup,
+ NULL // extension_data
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor* lv2_descriptor(uint32_t index)
+{
+ return (index == 0) ? &descriptor : NULL;
+}
diff --git a/test/missing_port.lv2/missing_port.ttl.in b/test/missing_port.lv2/missing_port.ttl.in
new file mode 100644
index 0000000..0dec1cf
--- /dev/null
+++ b/test/missing_port.lv2/missing_port.ttl.in
@@ -0,0 +1,31 @@
+# Lilv Test Plugin - Missing plugin port
+# Copyright 2011-2016 David Robillard <d@drobilla.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+
+<http://example.org/missing-port>
+ a lv2:Plugin ;
+ doap:license <http://opensource.org/licenses/isc> ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:OutputPort ,
+ lv2:ControlPort ;
+ lv2:index 1 ;
+ lv2:symbol "output" ;
+ lv2:name "Output"
+ ] .
diff --git a/test/missing_port.lv2/test_missing_port.c b/test/missing_port.lv2/test_missing_port.c
new file mode 100644
index 0000000..c67a1b8
--- /dev/null
+++ b/test/missing_port.lv2/test_missing_port.c
@@ -0,0 +1,45 @@
+#include "lilv/lilv.h"
+#include "../src/lilv_internal.h"
+
+#define PLUGIN_URI "http://example.org/missing-port"
+
+#define TEST_ASSERT(check) do {\
+ if (!(check)) {\
+ fprintf(stderr, "%s:%d: failed test: %s\n", __FILE__, __LINE__, #check);\
+ return 1;\
+ }\
+} while (0)
+
+int
+main(int argc, char** argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]);
+ return 1;
+ }
+
+ const char* bundle_path = argv[1];
+ LilvWorld* world = lilv_world_new();
+
+ // Load test plugin bundle
+ uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path);
+ SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
+ LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
+ lilv_world_load_bundle(world, bundle_uri);
+ free(abs_bundle);
+ serd_node_free(&bundle);
+ lilv_node_free(bundle_uri);
+
+ LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI);
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
+
+ // Check that all ports are ignored
+ TEST_ASSERT(lilv_plugin_get_num_ports(plugin) == 0);
+
+ lilv_node_free(plugin_uri);
+ lilv_world_free(world);
+
+ return 0;
+}
+