summaryrefslogtreecommitdiffstats
path: root/test/test_port.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_port.c')
-rw-r--r--test/test_port.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/test/test_port.c b/test/test_port.c
new file mode 100644
index 0000000..63f8bd0
--- /dev/null
+++ b/test/test_port.c
@@ -0,0 +1,331 @@
+/*
+ Copyright 2007-2020 David Robillard <http://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.
+*/
+
+#undef NDEBUG
+
+#include "lilv_test_utils.h"
+
+#include "lilv/lilv.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+
+static const char* const plugin_ttl = "\
+@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> . \n\
+:plug\n\
+ a lv2:Plugin ;\n\
+ doap:name \"Test plugin\" ;\n\
+ doap:homepage <http://example.org/someplug> ;\n\
+ lv2:port [\n\
+ a lv2:ControlPort ;\n\
+ a lv2:InputPort ;\n\
+ lv2:index 0 ;\n\
+ lv2:symbol \"foo\" ;\n\
+ lv2:name \"store\" ;\n\
+ lv2:name \"Laden\"@de-de ;\n\
+ lv2:name \"Geschaeft\"@de-at ;\n\
+ lv2:name \"tienda\"@es ;\n\
+ rdfs:comment \"comment\"@en , \"commentaires\"@fr ;\n\
+ lv2:portProperty lv2:integer ;\n\
+ lv2:minimum -1.0 ;\n\
+ lv2:maximum 1.0 ;\n\
+ lv2:default 0.5 ;\n\
+ lv2:scalePoint [\n\
+ rdfs:label \"Sin\";\n\
+ rdf:value 3\n\
+ ] ;\n\
+ lv2:scalePoint [\n\
+ rdfs:label \"Cos\";\n\
+ rdf:value 4\n\
+ ]\n\
+ ] , [\n\
+ a lv2:EventPort ;\n\
+ a lv2:InputPort ;\n\
+ lv2:index 1 ;\n\
+ lv2:symbol \"event_in\" ;\n\
+ lv2:name \"Event Input\" ;\n\
+ lv2ev:supportsEvent <http://example.org/event> ;\n\
+ atom:supports <http://example.org/atomEvent>\n\
+ ] , [\n\
+ a lv2:AudioPort ;\n\
+ a lv2:InputPort ;\n\
+ lv2:index 2 ;\n\
+ lv2:symbol \"audio_in\" ;\n\
+ lv2:name \"Audio Input\" ;\n\
+ ] , [\n\
+ a lv2:AudioPort ;\n\
+ a lv2:OutputPort ;\n\
+ lv2:index 3 ;\n\
+ lv2:symbol \"audio_out\" ;\n\
+ lv2:name \"Audio Output\" ;\n\
+ ] .\n";
+
+int
+main(void)
+{
+ LilvTestEnv* const env = lilv_test_env_new();
+ LilvWorld* const world = env->world;
+
+ if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) {
+ return 1;
+ }
+
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri);
+ assert(plug);
+
+ LilvNode* psym = lilv_new_string(world, "foo");
+ const LilvPort* p = lilv_plugin_get_port_by_index(plug, 0);
+ const LilvPort* p2 = lilv_plugin_get_port_by_symbol(plug, psym);
+ lilv_node_free(psym);
+ assert(p != NULL);
+ assert(p2 != NULL);
+ assert(p == p2);
+
+ LilvNode* nopsym = lilv_new_string(world, "thisaintnoportfoo");
+ const LilvPort* p3 = lilv_plugin_get_port_by_symbol(plug, nopsym);
+ assert(p3 == NULL);
+ lilv_node_free(nopsym);
+
+ // Try getting an invalid property
+ LilvNode* num = lilv_new_int(world, 1);
+ LilvNodes* nothing = lilv_port_get_value(plug, p, num);
+ assert(!nothing);
+ lilv_node_free(num);
+
+ LilvNode* audio_class =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort");
+ LilvNode* control_class =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort");
+ LilvNode* in_class =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort");
+ LilvNode* out_class =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort");
+
+ assert(lilv_nodes_size(lilv_port_get_classes(plug, p)) == 2);
+ assert(lilv_plugin_get_num_ports(plug) == 4);
+ assert(lilv_port_is_a(plug, p, control_class));
+ assert(lilv_port_is_a(plug, p, in_class));
+ assert(!lilv_port_is_a(plug, p, audio_class));
+
+ LilvNodes* port_properties = lilv_port_get_properties(plug, p);
+ assert(lilv_nodes_size(port_properties) == 1);
+ lilv_nodes_free(port_properties);
+
+ // Untranslated name (current locale is set to "C" in main)
+ assert(!strcmp(lilv_node_as_string(lilv_port_get_symbol(plug, p)), "foo"));
+ LilvNode* name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "store"));
+ lilv_node_free(name);
+
+ // Exact language match
+ set_env("LANG", "de_DE");
+ name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "Laden"));
+ lilv_node_free(name);
+
+ // Exact language match (with charset suffix)
+ set_env("LANG", "de_AT.utf8");
+ name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "Geschaeft"));
+ lilv_node_free(name);
+
+ // Partial language match (choose value translated for different country)
+ set_env("LANG", "de_CH");
+ name = lilv_port_get_name(plug, p);
+ assert((!strcmp(lilv_node_as_string(name), "Laden")) ||
+ (!strcmp(lilv_node_as_string(name), "Geschaeft")));
+ lilv_node_free(name);
+
+ // Partial language match (choose country-less language tagged value)
+ set_env("LANG", "es_MX");
+ name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "tienda"));
+ lilv_node_free(name);
+
+ // No language match (choose untranslated value)
+ set_env("LANG", "cn");
+ name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "store"));
+ lilv_node_free(name);
+
+ // Invalid language
+ set_env("LANG", "1!");
+ name = lilv_port_get_name(plug, p);
+ assert(!strcmp(lilv_node_as_string(name), "store"));
+ lilv_node_free(name);
+
+ set_env("LANG", "en_CA.utf-8");
+
+ // Language tagged value with no untranslated values
+ LilvNode* rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
+ LilvNodes* comments = lilv_port_get_value(plug, p, rdfs_comment);
+ assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)),
+ "comment"));
+ LilvNode* comment = lilv_port_get(plug, p, rdfs_comment);
+ assert(!strcmp(lilv_node_as_string(comment), "comment"));
+ lilv_node_free(comment);
+ lilv_nodes_free(comments);
+
+ set_env("LANG", "fr");
+
+ comments = lilv_port_get_value(plug, p, rdfs_comment);
+ assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)),
+ "commentaires"));
+ lilv_nodes_free(comments);
+
+ set_env("LANG", "cn");
+
+ comments = lilv_port_get_value(plug, p, rdfs_comment);
+ assert(!comments);
+ lilv_nodes_free(comments);
+
+ lilv_node_free(rdfs_comment);
+
+ set_env("LANG", "C"); // Reset locale
+
+ LilvScalePoints* points = lilv_port_get_scale_points(plug, p);
+ assert(lilv_scale_points_size(points) == 2);
+
+ LilvIter* sp_iter = lilv_scale_points_begin(points);
+ const LilvScalePoint* sp0 = lilv_scale_points_get(points, sp_iter);
+ assert(sp0);
+ sp_iter = lilv_scale_points_next(points, sp_iter);
+ const LilvScalePoint* sp1 = lilv_scale_points_get(points, sp_iter);
+ assert(sp1);
+
+ assert(((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)),
+ "Sin") &&
+ lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 3) &&
+ (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)),
+ "Cos") &&
+ lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 4)) ||
+ ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)),
+ "Cos") &&
+ lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 4) &&
+ (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)),
+ "Sin") &&
+ lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 3)));
+
+ LilvNode* homepage_p =
+ lilv_new_uri(world, "http://usefulinc.com/ns/doap#homepage");
+ LilvNodes* homepages = lilv_plugin_get_value(plug, homepage_p);
+ assert(lilv_nodes_size(homepages) == 1);
+ assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(homepages)),
+ "http://example.org/someplug"));
+
+ LilvNode *min, *max, *def;
+ lilv_port_get_range(plug, p, &def, &min, &max);
+ assert(def);
+ assert(min);
+ assert(max);
+ assert(lilv_node_as_float(def) == 0.5);
+ assert(lilv_node_as_float(min) == -1.0);
+ assert(lilv_node_as_float(max) == 1.0);
+
+ LilvNode* integer_prop =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#integer");
+ LilvNode* toggled_prop =
+ lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#toggled");
+
+ assert(lilv_port_has_property(plug, p, integer_prop));
+ assert(!lilv_port_has_property(plug, p, toggled_prop));
+
+ const LilvPort* ep = lilv_plugin_get_port_by_index(plug, 1);
+
+ LilvNode* event_type = lilv_new_uri(world, "http://example.org/event");
+ LilvNode* event_type_2 =
+ lilv_new_uri(world, "http://example.org/otherEvent");
+ LilvNode* atom_event = lilv_new_uri(world, "http://example.org/atomEvent");
+ assert(lilv_port_supports_event(plug, ep, event_type));
+ assert(!lilv_port_supports_event(plug, ep, event_type_2));
+ assert(lilv_port_supports_event(plug, ep, atom_event));
+
+ LilvNode* name_p = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#name");
+ LilvNodes* names = lilv_port_get_value(plug, p, name_p);
+ assert(lilv_nodes_size(names) == 1);
+ assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)), "store"));
+ lilv_nodes_free(names);
+
+ LilvNode* true_val = lilv_new_bool(world, true);
+ LilvNode* false_val = lilv_new_bool(world, false);
+
+ assert(!lilv_node_equals(true_val, false_val));
+
+ lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, false_val);
+ names = lilv_port_get_value(plug, p, name_p);
+ assert(lilv_nodes_size(names) == 4);
+ lilv_nodes_free(names);
+ lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, true_val);
+
+ lilv_node_free(false_val);
+ lilv_node_free(true_val);
+
+ names = lilv_port_get_value(plug, ep, name_p);
+ assert(lilv_nodes_size(names) == 1);
+ assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)),
+ "Event Input"));
+
+ const LilvPort* ap_in = lilv_plugin_get_port_by_index(plug, 2);
+
+ assert(lilv_port_is_a(plug, ap_in, in_class));
+ assert(!lilv_port_is_a(plug, ap_in, out_class));
+ assert(lilv_port_is_a(plug, ap_in, audio_class));
+ assert(!lilv_port_is_a(plug, ap_in, control_class));
+
+ const LilvPort* ap_out = lilv_plugin_get_port_by_index(plug, 3);
+
+ assert(lilv_port_is_a(plug, ap_out, out_class));
+ assert(!lilv_port_is_a(plug, ap_out, in_class));
+ assert(lilv_port_is_a(plug, ap_out, audio_class));
+ assert(!lilv_port_is_a(plug, ap_out, control_class));
+
+ assert(lilv_plugin_get_num_ports_of_class(
+ plug, control_class, in_class, NULL) == 1);
+ assert(
+ lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) ==
+ 1);
+ assert(lilv_plugin_get_num_ports_of_class(
+ plug, audio_class, out_class, NULL) == 1);
+
+ lilv_nodes_free(names);
+ lilv_node_free(name_p);
+
+ lilv_node_free(integer_prop);
+ lilv_node_free(toggled_prop);
+ lilv_node_free(event_type);
+ lilv_node_free(event_type_2);
+ lilv_node_free(atom_event);
+
+ lilv_node_free(min);
+ lilv_node_free(max);
+ lilv_node_free(def);
+
+ lilv_node_free(homepage_p);
+ lilv_nodes_free(homepages);
+
+ lilv_scale_points_free(points);
+ lilv_node_free(control_class);
+ lilv_node_free(audio_class);
+ lilv_node_free(out_class);
+ lilv_node_free(in_class);
+
+ delete_bundle(env);
+ lilv_test_env_free(env);
+
+ return 0;
+}