Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lilv_test.c 74KB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276
  1. /*
  2. Copyright 2007-2016 David Robillard <http://drobilla.net>
  3. Copyright 2008 Krzysztof Foltman
  4. Permission to use, copy, modify, and/or distribute this software for any
  5. purpose with or without fee is hereby granted, provided that the above
  6. copyright notice and this permission notice appear in all copies.
  7. THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. */
  15. #define _POSIX_C_SOURCE 200809L /* for setenv */
  16. #define _XOPEN_SOURCE 600 /* for mkstemp */
  17. #include <assert.h>
  18. #include <ctype.h>
  19. #include <errno.h>
  20. #include <float.h>
  21. #include <limits.h>
  22. #include <math.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <sys/stat.h>
  27. #ifdef _WIN32
  28. # include <direct.h>
  29. # define mkdir(path, flags) _mkdir(path)
  30. # define setenv(n, v, r) SetEnvironmentVariable((n), (v))
  31. # define unsetenv(n) SetEnvironmentVariable((n), NULL)
  32. #else
  33. # include <dirent.h>
  34. # include <unistd.h>
  35. #endif
  36. #include "lilv/lilv.h"
  37. #include "../src/lilv_internal.h"
  38. #include "lv2/lv2plug.in/ns/ext/presets/presets.h"
  39. #include "lv2/lv2plug.in/ns/ext/state/state.h"
  40. #include "lv2/lv2plug.in/ns/ext/urid/urid.h"
  41. #define TEST_PATH_MAX 1024
  42. #if defined(__APPLE__)
  43. # define SHLIB_EXT ".dylib"
  44. #elif defined(_WIN32)
  45. # define SHLIB_EXT ".dll"
  46. #else
  47. # define SHLIB_EXT ".so"
  48. #endif
  49. static char bundle_dir_name[TEST_PATH_MAX];
  50. static char bundle_dir_uri[TEST_PATH_MAX];
  51. static char manifest_name[TEST_PATH_MAX];
  52. static char content_name[TEST_PATH_MAX];
  53. static LilvWorld* world;
  54. int test_count = 0;
  55. int error_count = 0;
  56. static void
  57. delete_bundle(void)
  58. {
  59. unlink(content_name);
  60. unlink(manifest_name);
  61. remove(bundle_dir_name);
  62. }
  63. static void
  64. init_tests(void)
  65. {
  66. strncpy(bundle_dir_name, getenv("HOME"), 900);
  67. strcat(bundle_dir_name, "/.lv2");
  68. mkdir(bundle_dir_name, 0700);
  69. strcat(bundle_dir_name, "/lilv-test.lv2");
  70. sprintf(bundle_dir_uri, "file://%s/", bundle_dir_name);
  71. sprintf(manifest_name, "%s/manifest.ttl", bundle_dir_name);
  72. sprintf(content_name, "%s/plugin.ttl", bundle_dir_name);
  73. delete_bundle();
  74. }
  75. static void
  76. fatal_error(const char* err, const char* arg)
  77. {
  78. /* TODO: possibly change to vfprintf later */
  79. fprintf(stderr, err, arg);
  80. /* IMHO, the bundle should be left in place after an error, for possible investigation */
  81. /* delete_bundle(); */
  82. exit(1);
  83. }
  84. static void
  85. write_file(const char* name, const char* content)
  86. {
  87. FILE* f = fopen(name, "w");
  88. size_t len = strlen(content);
  89. if (fwrite(content, 1, len, f) != len)
  90. fatal_error("Cannot write file %s\n", name);
  91. fclose(f);
  92. }
  93. static int
  94. init_world(void)
  95. {
  96. world = lilv_world_new();
  97. return world != NULL;
  98. }
  99. static int
  100. load_all_bundles(void)
  101. {
  102. if (!init_world())
  103. return 0;
  104. lilv_world_load_all(world);
  105. return 1;
  106. }
  107. static void
  108. create_bundle(const char* manifest, const char* content)
  109. {
  110. if (mkdir(bundle_dir_name, 0700) && errno != EEXIST)
  111. fatal_error("Cannot create directory %s\n", bundle_dir_name);
  112. write_file(manifest_name, manifest);
  113. write_file(content_name, content);
  114. }
  115. static int
  116. start_bundle(const char* manifest, const char* content)
  117. {
  118. create_bundle(manifest, content);
  119. return load_all_bundles();
  120. }
  121. static void
  122. unload_bundle(void)
  123. {
  124. if (world)
  125. lilv_world_free(world);
  126. world = NULL;
  127. }
  128. static void
  129. cleanup(void)
  130. {
  131. delete_bundle();
  132. }
  133. /*****************************************************************************/
  134. #define TEST_CASE(name) { #name, test_##name }
  135. #define TEST_ASSERT(check) do {\
  136. test_count++;\
  137. if (!(check)) {\
  138. error_count++;\
  139. fprintf(stderr, "lilv_test.c:%d: error: test `%s' failed\n", __LINE__, #check);\
  140. assert(check);\
  141. }\
  142. } while (0)
  143. typedef int (*TestFunc)(void);
  144. struct TestCase {
  145. const char* title;
  146. TestFunc func;
  147. };
  148. #define PREFIX_ATOM "@prefix atom: <http://lv2plug.in/ns/ext/atom#> . \n"
  149. #define PREFIX_LINE "@prefix : <http://example.org/> .\n"
  150. #define PREFIX_LV2 "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n"
  151. #define PREFIX_LV2EV "@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> . \n"
  152. #define PREFIX_LV2UI "@prefix lv2ui: <http://lv2plug.in/ns/extensions/ui#> .\n"
  153. #define PREFIX_RDF "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n"
  154. #define PREFIX_RDFS "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"
  155. #define PREFIX_FOAF "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"
  156. #define PREFIX_DOAP "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"
  157. #define PREFIX_PSET "@prefix pset: <http://lv2plug.in/ns/ext/presets#> .\n"
  158. #define MANIFEST_PREFIXES PREFIX_LINE PREFIX_LV2 PREFIX_RDFS
  159. #define BUNDLE_PREFIXES PREFIX_ATOM PREFIX_LINE PREFIX_LV2 PREFIX_RDF PREFIX_RDFS PREFIX_FOAF PREFIX_DOAP PREFIX_PSET
  160. #define PLUGIN_NAME(name) "doap:name \"" name "\""
  161. #define LICENSE_GPL "doap:license <http://usefulinc.com/doap/licenses/gpl>"
  162. static const char* uris_plugin = "http://example.org/plug";
  163. static LilvNode* plugin_uri_value;
  164. static LilvNode* plugin2_uri_value;
  165. /*****************************************************************************/
  166. static void
  167. init_uris(void)
  168. {
  169. plugin_uri_value = lilv_new_uri(world, uris_plugin);
  170. plugin2_uri_value = lilv_new_uri(world, "http://example.org/foobar");
  171. TEST_ASSERT(plugin_uri_value);
  172. TEST_ASSERT(plugin2_uri_value);
  173. }
  174. static void
  175. cleanup_uris(void)
  176. {
  177. lilv_node_free(plugin2_uri_value);
  178. lilv_node_free(plugin_uri_value);
  179. plugin2_uri_value = NULL;
  180. plugin_uri_value = NULL;
  181. }
  182. /*****************************************************************************/
  183. static int
  184. test_value(void)
  185. {
  186. if (!start_bundle(MANIFEST_PREFIXES
  187. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  188. BUNDLE_PREFIXES
  189. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  190. PLUGIN_NAME("Test plugin") " ; "
  191. LICENSE_GPL " ; "
  192. "lv2:port [ "
  193. " a lv2:ControlPort ; a lv2:InputPort ; "
  194. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"Foo\" ; "
  195. "] ."))
  196. return 0;
  197. init_uris();
  198. LilvNode* uval = lilv_new_uri(world, "http://example.org");
  199. LilvNode* sval = lilv_new_string(world, "Foo");
  200. LilvNode* ival = lilv_new_int(world, 42);
  201. LilvNode* fval = lilv_new_float(world, 1.6180);
  202. TEST_ASSERT(lilv_node_is_uri(uval));
  203. TEST_ASSERT(lilv_node_is_string(sval));
  204. TEST_ASSERT(lilv_node_is_int(ival));
  205. TEST_ASSERT(lilv_node_is_float(fval));
  206. TEST_ASSERT(!lilv_node_is_literal(NULL));
  207. TEST_ASSERT(!lilv_node_is_literal(uval));
  208. TEST_ASSERT(lilv_node_is_literal(sval));
  209. TEST_ASSERT(lilv_node_is_literal(ival));
  210. TEST_ASSERT(lilv_node_is_literal(fval));
  211. TEST_ASSERT(!lilv_node_get_path(fval, NULL));
  212. TEST_ASSERT(!strcmp(lilv_node_as_uri(uval), "http://example.org"));
  213. TEST_ASSERT(!strcmp(lilv_node_as_string(sval), "Foo"));
  214. TEST_ASSERT(lilv_node_as_int(ival) == 42);
  215. TEST_ASSERT(fabs(lilv_node_as_float(fval) - 1.6180) < FLT_EPSILON);
  216. TEST_ASSERT(isnan(lilv_node_as_float(sval)));
  217. #if defined(__clang__)
  218. # pragma clang diagnostic push
  219. # pragma clang diagnostic ignored "-Wdeprecated-declarations"
  220. #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  221. # pragma GCC diagnostic push
  222. # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  223. #endif
  224. TEST_ASSERT(!strcmp(lilv_uri_to_path("file:///foo"), "/foo"));
  225. #if defined(__clang__)
  226. # pragma clang diagnostic pop
  227. #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  228. # pragma GCC diagnostic pop
  229. #endif
  230. LilvNode* loc_abs = lilv_new_file_uri(world, NULL, "/foo/bar");
  231. LilvNode* loc_rel = lilv_new_file_uri(world, NULL, "foo");
  232. LilvNode* host_abs = lilv_new_file_uri(world, "host", "/foo/bar");
  233. LilvNode* host_rel = lilv_new_file_uri(world, "host", "foo");
  234. TEST_ASSERT(!strcmp(lilv_node_as_uri(loc_abs), "file:///foo/bar"));
  235. TEST_ASSERT(!strncmp(lilv_node_as_uri(loc_rel), "file:///", 8));
  236. TEST_ASSERT(!strcmp(lilv_node_as_uri(host_abs), "file://host/foo/bar"));
  237. TEST_ASSERT(!strncmp(lilv_node_as_uri(host_rel), "file://host/", 12));
  238. lilv_node_free(host_rel);
  239. lilv_node_free(host_abs);
  240. lilv_node_free(loc_rel);
  241. lilv_node_free(loc_abs);
  242. char* tok = lilv_node_get_turtle_token(uval);
  243. TEST_ASSERT(!strcmp(tok, "<http://example.org>"));
  244. lilv_free(tok);
  245. tok = lilv_node_get_turtle_token(sval);
  246. TEST_ASSERT(!strcmp(tok, "Foo"));
  247. lilv_free(tok);
  248. tok = lilv_node_get_turtle_token(ival);
  249. TEST_ASSERT(!strcmp(tok, "42"));
  250. lilv_free(tok);
  251. tok = lilv_node_get_turtle_token(fval);
  252. TEST_ASSERT(!strncmp(tok, "1.6180", 6));
  253. lilv_free(tok);
  254. LilvNode* uval_e = lilv_new_uri(world, "http://example.org");
  255. LilvNode* sval_e = lilv_new_string(world, "Foo");
  256. LilvNode* ival_e = lilv_new_int(world, 42);
  257. LilvNode* fval_e = lilv_new_float(world, 1.6180);
  258. LilvNode* uval_ne = lilv_new_uri(world, "http://no-example.org");
  259. LilvNode* sval_ne = lilv_new_string(world, "Bar");
  260. LilvNode* ival_ne = lilv_new_int(world, 24);
  261. LilvNode* fval_ne = lilv_new_float(world, 3.14159);
  262. TEST_ASSERT(lilv_node_equals(uval, uval_e));
  263. TEST_ASSERT(lilv_node_equals(sval, sval_e));
  264. TEST_ASSERT(lilv_node_equals(ival, ival_e));
  265. TEST_ASSERT(lilv_node_equals(fval, fval_e));
  266. TEST_ASSERT(!lilv_node_equals(uval, uval_ne));
  267. TEST_ASSERT(!lilv_node_equals(sval, sval_ne));
  268. TEST_ASSERT(!lilv_node_equals(ival, ival_ne));
  269. TEST_ASSERT(!lilv_node_equals(fval, fval_ne));
  270. TEST_ASSERT(!lilv_node_equals(uval, sval));
  271. TEST_ASSERT(!lilv_node_equals(sval, ival));
  272. TEST_ASSERT(!lilv_node_equals(ival, fval));
  273. LilvNode* uval_dup = lilv_node_duplicate(uval);
  274. TEST_ASSERT(lilv_node_equals(uval, uval_dup));
  275. LilvNode* ifval = lilv_new_float(world, 42.0);
  276. TEST_ASSERT(!lilv_node_equals(ival, ifval));
  277. lilv_node_free(ifval);
  278. LilvNode* nil = NULL;
  279. TEST_ASSERT(!lilv_node_equals(uval, nil));
  280. TEST_ASSERT(!lilv_node_equals(nil, uval));
  281. TEST_ASSERT(lilv_node_equals(nil, nil));
  282. LilvNode* nil2 = lilv_node_duplicate(nil);
  283. TEST_ASSERT(lilv_node_equals(nil, nil2));
  284. lilv_node_free(uval);
  285. lilv_node_free(sval);
  286. lilv_node_free(ival);
  287. lilv_node_free(fval);
  288. lilv_node_free(uval_e);
  289. lilv_node_free(sval_e);
  290. lilv_node_free(ival_e);
  291. lilv_node_free(fval_e);
  292. lilv_node_free(uval_ne);
  293. lilv_node_free(sval_ne);
  294. lilv_node_free(ival_ne);
  295. lilv_node_free(fval_ne);
  296. lilv_node_free(uval_dup);
  297. lilv_node_free(nil2);
  298. cleanup_uris();
  299. return 1;
  300. }
  301. /*****************************************************************************/
  302. static int
  303. test_util(void)
  304. {
  305. TEST_ASSERT(!lilv_realpath(NULL));
  306. char a_path[16];
  307. char b_path[16];
  308. strcpy(a_path, "copy_a_XXXXXX");
  309. strcpy(b_path, "copy_b_XXXXXX");
  310. mkstemp(a_path);
  311. mkstemp(b_path);
  312. FILE* fa = fopen(a_path, "w");
  313. FILE* fb = fopen(b_path, "w");
  314. fprintf(fa, "AA\n");
  315. fprintf(fb, "AB\n");
  316. fclose(fa);
  317. fclose(fb);
  318. TEST_ASSERT(lilv_copy_file("does/not/exist", "copy"));
  319. TEST_ASSERT(lilv_copy_file(a_path, "not/a/dir/copy"));
  320. TEST_ASSERT(!lilv_copy_file(a_path, "copy_c"));
  321. TEST_ASSERT(!lilv_file_equals(a_path, b_path));
  322. TEST_ASSERT(lilv_file_equals(a_path, a_path));
  323. TEST_ASSERT(lilv_file_equals(a_path, "copy_c"));
  324. TEST_ASSERT(!lilv_file_equals("does/not/exist", b_path));
  325. TEST_ASSERT(!lilv_file_equals(a_path, "does/not/exist"));
  326. TEST_ASSERT(!lilv_file_equals("does/not/exist", "/does/not/either"));
  327. return 1;
  328. }
  329. /*****************************************************************************/
  330. static int discovery_plugin_found = 0;
  331. static void
  332. discovery_verify_plugin(const LilvPlugin* plugin)
  333. {
  334. const LilvNode* value = lilv_plugin_get_uri(plugin);
  335. if (lilv_node_equals(value, plugin_uri_value)) {
  336. const LilvNode* lib_uri = NULL;
  337. TEST_ASSERT(!lilv_node_equals(value, plugin2_uri_value));
  338. discovery_plugin_found = 1;
  339. lib_uri = lilv_plugin_get_library_uri(plugin);
  340. TEST_ASSERT(lib_uri);
  341. TEST_ASSERT(lilv_node_is_uri(lib_uri));
  342. TEST_ASSERT(lilv_node_as_uri(lib_uri));
  343. TEST_ASSERT(strstr(lilv_node_as_uri(lib_uri), "foo" SHLIB_EXT));
  344. TEST_ASSERT(lilv_plugin_verify(plugin));
  345. }
  346. }
  347. static int
  348. test_discovery(void)
  349. {
  350. if (!start_bundle(MANIFEST_PREFIXES
  351. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  352. BUNDLE_PREFIXES
  353. ":plug a lv2:Plugin ;"
  354. PLUGIN_NAME("Test plugin") " ; "
  355. LICENSE_GPL " ; "
  356. "lv2:port [ a lv2:ControlPort ; a lv2:InputPort ;"
  357. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; ] ."))
  358. return 0;
  359. init_uris();
  360. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  361. TEST_ASSERT(lilv_plugins_size(plugins) > 0);
  362. const LilvPlugin* explug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  363. TEST_ASSERT(explug != NULL);
  364. const LilvPlugin* explug2 = lilv_plugins_get_by_uri(plugins, plugin2_uri_value);
  365. TEST_ASSERT(explug2 == NULL);
  366. if (explug) {
  367. LilvNode* name = lilv_plugin_get_name(explug);
  368. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "Test plugin"));
  369. lilv_node_free(name);
  370. }
  371. discovery_plugin_found = 0;
  372. LILV_FOREACH(plugins, i, plugins)
  373. discovery_verify_plugin(lilv_plugins_get(plugins, i));
  374. TEST_ASSERT(discovery_plugin_found);
  375. plugins = NULL;
  376. cleanup_uris();
  377. return 1;
  378. }
  379. /*****************************************************************************/
  380. static int
  381. test_lv2_path(void)
  382. {
  383. #ifndef _WIN32
  384. char* orig_lv2_path = lilv_strdup(getenv("LV2_PATH"));
  385. setenv("LV2_PATH", "~/.lv2:/usr/local/lib/lv2:/usr/lib/lv2", 1);
  386. world = lilv_world_new();
  387. lilv_world_load_all(world);
  388. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  389. const size_t n_plugins = lilv_plugins_size(plugins);
  390. lilv_world_free(world);
  391. setenv("LV2_PATH", "$HOME/.lv2:/usr/local/lib/lv2:/usr/lib/lv2", 1);
  392. world = lilv_world_new();
  393. lilv_world_load_all(world);
  394. plugins = lilv_world_get_all_plugins(world);
  395. TEST_ASSERT(lilv_plugins_size(plugins) == n_plugins);
  396. lilv_world_free(world);
  397. world = NULL;
  398. if (orig_lv2_path) {
  399. setenv("LV2_PATH", orig_lv2_path, 1);
  400. } else {
  401. unsetenv("LV2_PATH");
  402. }
  403. free(orig_lv2_path);
  404. #endif
  405. return 1;
  406. }
  407. /*****************************************************************************/
  408. static int
  409. test_verify(void)
  410. {
  411. if (!start_bundle(MANIFEST_PREFIXES
  412. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  413. BUNDLE_PREFIXES
  414. ":plug a lv2:Plugin ; "
  415. PLUGIN_NAME("Test plugin") " ; "
  416. LICENSE_GPL " ; "
  417. "lv2:port [ a lv2:ControlPort ; a lv2:InputPort ;"
  418. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ] ."))
  419. return 0;
  420. init_uris();
  421. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  422. const LilvPlugin* explug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  423. TEST_ASSERT(explug);
  424. TEST_ASSERT(lilv_plugin_verify(explug));
  425. cleanup_uris();
  426. return 1;
  427. }
  428. /*****************************************************************************/
  429. static int
  430. test_no_verify(void)
  431. {
  432. if (!start_bundle(MANIFEST_PREFIXES
  433. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  434. BUNDLE_PREFIXES
  435. ":plug a lv2:Plugin . "))
  436. return 0;
  437. init_uris();
  438. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  439. const LilvPlugin* explug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  440. TEST_ASSERT(explug);
  441. TEST_ASSERT(!lilv_plugin_verify(explug));
  442. cleanup_uris();
  443. return 1;
  444. }
  445. /*****************************************************************************/
  446. static int
  447. test_classes(void)
  448. {
  449. if (!start_bundle(MANIFEST_PREFIXES
  450. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  451. BUNDLE_PREFIXES
  452. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  453. PLUGIN_NAME("Test plugin") " ; "
  454. LICENSE_GPL " ; "
  455. "lv2:port [ "
  456. " a lv2:ControlPort ; a lv2:InputPort ; "
  457. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"Foo\" ; "
  458. "] ."))
  459. return 0;
  460. init_uris();
  461. const LilvPluginClass* plugin = lilv_world_get_plugin_class(world);
  462. const LilvPluginClasses* classes = lilv_world_get_plugin_classes(world);
  463. LilvPluginClasses* children = lilv_plugin_class_get_children(plugin);
  464. TEST_ASSERT(lilv_plugin_class_get_parent_uri(plugin) == NULL);
  465. TEST_ASSERT(lilv_plugin_classes_size(classes) > lilv_plugin_classes_size(children));
  466. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_plugin_class_get_label(plugin)), "Plugin"));
  467. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_plugin_class_get_uri(plugin)),
  468. "http://lv2plug.in/ns/lv2core#Plugin"));
  469. LILV_FOREACH(plugin_classes, i, children) {
  470. TEST_ASSERT(lilv_node_equals(
  471. lilv_plugin_class_get_parent_uri(lilv_plugin_classes_get(children, i)),
  472. lilv_plugin_class_get_uri(plugin)));
  473. }
  474. LilvNode* some_uri = lilv_new_uri(world, "http://example.org/whatever");
  475. TEST_ASSERT(lilv_plugin_classes_get_by_uri(classes, some_uri) == NULL);
  476. lilv_node_free(some_uri);
  477. lilv_plugin_classes_free(children);
  478. cleanup_uris();
  479. return 1;
  480. }
  481. /*****************************************************************************/
  482. static int
  483. test_plugin(void)
  484. {
  485. if (!start_bundle(MANIFEST_PREFIXES
  486. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  487. BUNDLE_PREFIXES
  488. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  489. PLUGIN_NAME("Test plugin") " ; "
  490. LICENSE_GPL " ; "
  491. "lv2:optionalFeature lv2:hardRTCapable ; "
  492. "lv2:requiredFeature <http://lv2plug.in/ns/ext/event> ; "
  493. "lv2:extensionData <http://example.org/extdata> ;"
  494. ":foo 1.6180 ; "
  495. ":bar true ; "
  496. ":baz false ; "
  497. ":blank [ a <http://example.org/blank> ] ; "
  498. "doap:maintainer [ foaf:name \"David Robillard\" ; "
  499. " foaf:homepage <http://drobilla.net> ; foaf:mbox <mailto:d@drobilla.net> ] ; "
  500. "lv2:port [ "
  501. " a lv2:ControlPort ; a lv2:InputPort ; "
  502. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  503. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  504. "] , [ "
  505. " a lv2:ControlPort ; a lv2:InputPort ; "
  506. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  507. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  508. "] , [ "
  509. " a lv2:ControlPort ; a lv2:OutputPort ; "
  510. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  511. " lv2:portProperty lv2:reportsLatency ; "
  512. " lv2:designation lv2:latency "
  513. "] . \n"
  514. ":thing doap:name \"Something else\" .\n"))
  515. return 0;
  516. init_uris();
  517. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  518. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  519. TEST_ASSERT(plug);
  520. const LilvPluginClass* klass = lilv_plugin_get_class(plug);
  521. const LilvNode* klass_uri = lilv_plugin_class_get_uri(klass);
  522. TEST_ASSERT(!strcmp(lilv_node_as_string(klass_uri),
  523. "http://lv2plug.in/ns/lv2core#CompressorPlugin"));
  524. LilvNode* rdf_type = lilv_new_uri(
  525. world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
  526. TEST_ASSERT(lilv_world_ask(world,
  527. lilv_plugin_get_uri(plug),
  528. rdf_type,
  529. klass_uri));
  530. lilv_node_free(rdf_type);
  531. TEST_ASSERT(!lilv_plugin_is_replaced(plug));
  532. TEST_ASSERT(!lilv_plugin_get_related(plug, NULL));
  533. const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug);
  534. TEST_ASSERT(!strcmp(lilv_node_as_string(plug_bundle_uri), bundle_dir_uri));
  535. const LilvNodes* data_uris = lilv_plugin_get_data_uris(plug);
  536. TEST_ASSERT(lilv_nodes_size(data_uris) == 2);
  537. LilvNode* project = lilv_plugin_get_project(plug);
  538. TEST_ASSERT(!project);
  539. char* manifest_uri = (char*)malloc(TEST_PATH_MAX);
  540. char* data_uri = (char*)malloc(TEST_PATH_MAX);
  541. snprintf(manifest_uri, TEST_PATH_MAX, "%s%s",
  542. lilv_node_as_string(plug_bundle_uri), "manifest.ttl");
  543. snprintf(data_uri, TEST_PATH_MAX, "%s%s",
  544. lilv_node_as_string(plug_bundle_uri), "plugin.ttl");
  545. LilvNode* manifest_uri_val = lilv_new_uri(world, manifest_uri);
  546. TEST_ASSERT(lilv_nodes_contains(data_uris, manifest_uri_val));
  547. lilv_node_free(manifest_uri_val);
  548. LilvNode* data_uri_val = lilv_new_uri(world, data_uri);
  549. TEST_ASSERT(lilv_nodes_contains(data_uris, data_uri_val));
  550. lilv_node_free(data_uri_val);
  551. LilvNode* unknown_uri_val = lilv_new_uri(world, "http://example.org/unknown");
  552. TEST_ASSERT(!lilv_nodes_contains(data_uris, unknown_uri_val));
  553. lilv_node_free(unknown_uri_val);
  554. free(manifest_uri);
  555. free(data_uri);
  556. float mins[3];
  557. float maxs[3];
  558. float defs[3];
  559. lilv_plugin_get_port_ranges_float(plug, mins, maxs, defs);
  560. TEST_ASSERT(mins[0] == -1.0f);
  561. TEST_ASSERT(maxs[0] == 1.0f);
  562. TEST_ASSERT(defs[0] == 0.5f);
  563. LilvNode* audio_class = lilv_new_uri(world,
  564. "http://lv2plug.in/ns/lv2core#AudioPort");
  565. LilvNode* control_class = lilv_new_uri(world,
  566. "http://lv2plug.in/ns/lv2core#ControlPort");
  567. LilvNode* in_class = lilv_new_uri(world,
  568. "http://lv2plug.in/ns/lv2core#InputPort");
  569. LilvNode* out_class = lilv_new_uri(world,
  570. "http://lv2plug.in/ns/lv2core#OutputPort");
  571. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, control_class, NULL) == 3);
  572. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, audio_class, NULL) == 0);
  573. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, in_class, NULL) == 2);
  574. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, out_class, NULL) == 1);
  575. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, control_class, in_class, NULL) == 2);
  576. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, control_class, out_class, NULL) == 1);
  577. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == 0);
  578. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, audio_class, out_class, NULL) == 0);
  579. TEST_ASSERT(lilv_plugin_has_latency(plug));
  580. TEST_ASSERT(lilv_plugin_get_latency_port_index(plug) == 2);
  581. LilvNode* lv2_latency = lilv_new_uri(world,
  582. "http://lv2plug.in/ns/lv2core#latency");
  583. const LilvPort* latency_port = lilv_plugin_get_port_by_designation(
  584. plug, out_class, lv2_latency);
  585. lilv_node_free(lv2_latency);
  586. TEST_ASSERT(latency_port);
  587. TEST_ASSERT(lilv_port_get_index(plug, latency_port) == 2);
  588. TEST_ASSERT(lilv_node_is_blank(lilv_port_get_node(plug, latency_port)));
  589. LilvNode* rt_feature = lilv_new_uri(world,
  590. "http://lv2plug.in/ns/lv2core#hardRTCapable");
  591. LilvNode* event_feature = lilv_new_uri(world,
  592. "http://lv2plug.in/ns/ext/event");
  593. LilvNode* pretend_feature = lilv_new_uri(world,
  594. "http://example.org/solvesWorldHunger");
  595. TEST_ASSERT(lilv_plugin_has_feature(plug, rt_feature));
  596. TEST_ASSERT(lilv_plugin_has_feature(plug, event_feature));
  597. TEST_ASSERT(!lilv_plugin_has_feature(plug, pretend_feature));
  598. lilv_node_free(rt_feature);
  599. lilv_node_free(event_feature);
  600. lilv_node_free(pretend_feature);
  601. LilvNodes* supported = lilv_plugin_get_supported_features(plug);
  602. LilvNodes* required = lilv_plugin_get_required_features(plug);
  603. LilvNodes* optional = lilv_plugin_get_optional_features(plug);
  604. TEST_ASSERT(lilv_nodes_size(supported) == 2);
  605. TEST_ASSERT(lilv_nodes_size(required) == 1);
  606. TEST_ASSERT(lilv_nodes_size(optional) == 1);
  607. lilv_nodes_free(supported);
  608. lilv_nodes_free(required);
  609. lilv_nodes_free(optional);
  610. LilvNode* foo_p = lilv_new_uri(world, "http://example.org/foo");
  611. LilvNodes* foos = lilv_plugin_get_value(plug, foo_p);
  612. TEST_ASSERT(lilv_nodes_size(foos) == 1);
  613. TEST_ASSERT(fabs(lilv_node_as_float(lilv_nodes_get_first(foos)) - 1.6180) < FLT_EPSILON);
  614. lilv_node_free(foo_p);
  615. lilv_nodes_free(foos);
  616. LilvNode* bar_p = lilv_new_uri(world, "http://example.org/bar");
  617. LilvNodes* bars = lilv_plugin_get_value(plug, bar_p);
  618. TEST_ASSERT(lilv_nodes_size(bars) == 1);
  619. TEST_ASSERT(lilv_node_as_bool(lilv_nodes_get_first(bars)) == true);
  620. lilv_node_free(bar_p);
  621. lilv_nodes_free(bars);
  622. LilvNode* baz_p = lilv_new_uri(world, "http://example.org/baz");
  623. LilvNodes* bazs = lilv_plugin_get_value(plug, baz_p);
  624. TEST_ASSERT(lilv_nodes_size(bazs) == 1);
  625. TEST_ASSERT(lilv_node_as_bool(lilv_nodes_get_first(bazs)) == false);
  626. lilv_node_free(baz_p);
  627. lilv_nodes_free(bazs);
  628. LilvNode* blank_p = lilv_new_uri(world, "http://example.org/blank");
  629. LilvNodes* blanks = lilv_plugin_get_value(plug, blank_p);
  630. TEST_ASSERT(lilv_nodes_size(blanks) == 1);
  631. LilvNode* blank = lilv_nodes_get_first(blanks);
  632. TEST_ASSERT(lilv_node_is_blank(blank));
  633. const char* blank_str = lilv_node_as_blank(blank);
  634. char* blank_tok = lilv_node_get_turtle_token(blank);
  635. TEST_ASSERT(!strncmp(blank_tok, "_:", 2));
  636. TEST_ASSERT(!strcmp(blank_tok + 2, blank_str));
  637. lilv_free(blank_tok);
  638. lilv_node_free(blank_p);
  639. lilv_nodes_free(blanks);
  640. LilvNode* author_name = lilv_plugin_get_author_name(plug);
  641. TEST_ASSERT(!strcmp(lilv_node_as_string(author_name), "David Robillard"));
  642. lilv_node_free(author_name);
  643. LilvNode* author_email = lilv_plugin_get_author_email(plug);
  644. TEST_ASSERT(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net"));
  645. lilv_node_free(author_email);
  646. LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
  647. TEST_ASSERT(!strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net"));
  648. lilv_node_free(author_homepage);
  649. LilvNode* thing_uri = lilv_new_uri(world, "http://example.org/thing");
  650. LilvNode* name_p = lilv_new_uri(world, "http://usefulinc.com/ns/doap#name");
  651. LilvNodes* thing_names = lilv_world_find_nodes(world, thing_uri, name_p, NULL);
  652. TEST_ASSERT(lilv_nodes_size(thing_names) == 1);
  653. LilvNode* thing_name = lilv_nodes_get_first(thing_names);
  654. TEST_ASSERT(thing_name);
  655. TEST_ASSERT(lilv_node_is_string(thing_name));
  656. TEST_ASSERT(!strcmp(lilv_node_as_string(thing_name), "Something else"));
  657. LilvNode* thing_name2 = lilv_world_get(world, thing_uri, name_p, NULL);
  658. TEST_ASSERT(lilv_node_equals(thing_name, thing_name2));
  659. LilvUIs* uis = lilv_plugin_get_uis(plug);
  660. TEST_ASSERT(lilv_uis_size(uis) == 0);
  661. lilv_uis_free(uis);
  662. LilvNode* extdata = lilv_new_uri(world, "http://example.org/extdata");
  663. LilvNode* noextdata = lilv_new_uri(world, "http://example.org/noextdata");
  664. LilvNodes* extdatas = lilv_plugin_get_extension_data(plug);
  665. TEST_ASSERT(lilv_plugin_has_extension_data(plug, extdata));
  666. TEST_ASSERT(!lilv_plugin_has_extension_data(plug, noextdata));
  667. TEST_ASSERT(lilv_nodes_size(extdatas) == 1);
  668. TEST_ASSERT(lilv_node_equals(lilv_nodes_get_first(extdatas), extdata));
  669. lilv_node_free(noextdata);
  670. lilv_node_free(extdata);
  671. lilv_nodes_free(extdatas);
  672. lilv_nodes_free(thing_names);
  673. lilv_node_free(thing_uri);
  674. lilv_node_free(thing_name2);
  675. lilv_node_free(name_p);
  676. lilv_node_free(control_class);
  677. lilv_node_free(audio_class);
  678. lilv_node_free(in_class);
  679. lilv_node_free(out_class);
  680. cleanup_uris();
  681. return 1;
  682. }
  683. /*****************************************************************************/
  684. static int
  685. test_project(void)
  686. {
  687. if (!start_bundle(MANIFEST_PREFIXES
  688. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  689. BUNDLE_PREFIXES
  690. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  691. PLUGIN_NAME("Test plugin with project") " ; "
  692. LICENSE_GPL " ; "
  693. "lv2:project [ "
  694. " doap:maintainer [ "
  695. " foaf:name \"David Robillard\" ; "
  696. " foaf:homepage <http://drobilla.net> ; foaf:mbox <mailto:d@drobilla.net> ] ; "
  697. "] ; "
  698. "lv2:port [ "
  699. " a lv2:ControlPort ; a lv2:InputPort ; "
  700. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  701. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  702. "] , [ "
  703. " a lv2:ControlPort ; a lv2:InputPort ; "
  704. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  705. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  706. "] , [ "
  707. " a lv2:ControlPort ; a lv2:OutputPort ; "
  708. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  709. " lv2:portProperty lv2:reportsLatency ; "
  710. " lv2:designation lv2:latency "
  711. "] . \n"
  712. ":thing doap:name \"Something else\" .\n"))
  713. return 0;
  714. init_uris();
  715. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  716. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  717. TEST_ASSERT(plug);
  718. LilvNode* author_name = lilv_plugin_get_author_name(plug);
  719. TEST_ASSERT(!strcmp(lilv_node_as_string(author_name), "David Robillard"));
  720. lilv_node_free(author_name);
  721. LilvNode* author_email = lilv_plugin_get_author_email(plug);
  722. TEST_ASSERT(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net"));
  723. lilv_node_free(author_email);
  724. LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
  725. TEST_ASSERT(!strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net"));
  726. lilv_node_free(author_homepage);
  727. cleanup_uris();
  728. return 1;
  729. }
  730. /*****************************************************************************/
  731. static int
  732. test_no_author(void)
  733. {
  734. if (!start_bundle(MANIFEST_PREFIXES
  735. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  736. BUNDLE_PREFIXES
  737. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  738. PLUGIN_NAME("Test plugin with project") " ; "
  739. LICENSE_GPL " ; "
  740. "lv2:port [ "
  741. " a lv2:ControlPort ; a lv2:InputPort ; "
  742. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  743. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  744. "] , [ "
  745. " a lv2:ControlPort ; a lv2:InputPort ; "
  746. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  747. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  748. "] , [ "
  749. " a lv2:ControlPort ; a lv2:OutputPort ; "
  750. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  751. " lv2:portProperty lv2:reportsLatency ; "
  752. " lv2:designation lv2:latency "
  753. "] . \n"
  754. ":thing doap:name \"Something else\" .\n"))
  755. return 0;
  756. init_uris();
  757. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  758. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  759. TEST_ASSERT(plug);
  760. LilvNode* author_name = lilv_plugin_get_author_name(plug);
  761. TEST_ASSERT(!author_name);
  762. LilvNode* author_email = lilv_plugin_get_author_email(plug);
  763. TEST_ASSERT(!author_email);
  764. LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
  765. TEST_ASSERT(!author_homepage);
  766. cleanup_uris();
  767. return 1;
  768. }
  769. /*****************************************************************************/
  770. static int
  771. test_project_no_author(void)
  772. {
  773. if (!start_bundle(MANIFEST_PREFIXES
  774. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  775. BUNDLE_PREFIXES
  776. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  777. PLUGIN_NAME("Test plugin with project") " ; "
  778. LICENSE_GPL " ; "
  779. "lv2:project [ "
  780. " doap:name \"Fake project\" ;"
  781. "] ; "
  782. "lv2:port [ "
  783. " a lv2:ControlPort ; a lv2:InputPort ; "
  784. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  785. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  786. "] , [ "
  787. " a lv2:ControlPort ; a lv2:InputPort ; "
  788. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  789. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  790. "] , [ "
  791. " a lv2:ControlPort ; a lv2:OutputPort ; "
  792. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  793. " lv2:portProperty lv2:reportsLatency ; "
  794. " lv2:designation lv2:latency "
  795. "] . \n"
  796. ":thing doap:name \"Something else\" .\n"))
  797. return 0;
  798. init_uris();
  799. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  800. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  801. TEST_ASSERT(plug);
  802. LilvNode* author_name = lilv_plugin_get_author_name(plug);
  803. TEST_ASSERT(!author_name);
  804. LilvNode* author_email = lilv_plugin_get_author_email(plug);
  805. TEST_ASSERT(!author_email);
  806. LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
  807. TEST_ASSERT(!author_homepage);
  808. cleanup_uris();
  809. return 1;
  810. }
  811. /*****************************************************************************/
  812. static int
  813. test_preset(void)
  814. {
  815. if (!start_bundle(MANIFEST_PREFIXES
  816. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  817. BUNDLE_PREFIXES
  818. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  819. PLUGIN_NAME("Test plugin with project") " ; "
  820. LICENSE_GPL " ; "
  821. "lv2:project [ "
  822. " doap:name \"Fake project\" ;"
  823. "] ; "
  824. "lv2:port [ "
  825. " a lv2:ControlPort ; a lv2:InputPort ; "
  826. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  827. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  828. "] , [ "
  829. " a lv2:ControlPort ; a lv2:InputPort ; "
  830. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  831. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  832. "] , [ "
  833. " a lv2:ControlPort ; a lv2:OutputPort ; "
  834. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  835. " lv2:portProperty lv2:reportsLatency ; "
  836. " lv2:designation lv2:latency "
  837. "] . \n"
  838. "<http://example.org/preset> a pset:Preset ;"
  839. " lv2:appliesTo :plug ;"
  840. " rdfs:label \"some preset\" .\n"))
  841. return 0;
  842. init_uris();
  843. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  844. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  845. TEST_ASSERT(plug);
  846. LilvNode* pset_Preset = lilv_new_uri(world, LV2_PRESETS__Preset);
  847. LilvNodes* related = lilv_plugin_get_related(plug, pset_Preset);
  848. TEST_ASSERT(lilv_nodes_size(related) == 1);
  849. lilv_node_free(pset_Preset);
  850. lilv_nodes_free(related);
  851. cleanup_uris();
  852. return 1;
  853. }
  854. /*****************************************************************************/
  855. static int
  856. test_prototype(void)
  857. {
  858. if (!start_bundle(MANIFEST_PREFIXES
  859. ":prot a lv2:PluginBase ; rdfs:seeAlso <plugin.ttl> .\n"
  860. ":plug a lv2:Plugin ; lv2:binary <inst" SHLIB_EXT "> ; lv2:prototype :prot .\n",
  861. BUNDLE_PREFIXES
  862. ":prot a lv2:Plugin ; a lv2:CompressorPlugin ; "
  863. LICENSE_GPL " ; "
  864. "lv2:project [ "
  865. " doap:name \"Fake project\" ;"
  866. "] ; "
  867. "lv2:port [ "
  868. " a lv2:ControlPort ; a lv2:InputPort ; "
  869. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  870. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  871. "] , [ "
  872. " a lv2:ControlPort ; a lv2:InputPort ; "
  873. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  874. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  875. "] , [ "
  876. " a lv2:ControlPort ; a lv2:OutputPort ; "
  877. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  878. " lv2:portProperty lv2:reportsLatency ; "
  879. " lv2:designation lv2:latency "
  880. "] . \n"
  881. ":plug doap:name \"Instance\" .\n"))
  882. return 0;
  883. init_uris();
  884. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  885. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  886. TEST_ASSERT(plug);
  887. // Test non-inherited property
  888. LilvNode* name = lilv_plugin_get_name(plug);
  889. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "Instance"));
  890. lilv_node_free(name);
  891. // Test inherited property
  892. const LilvNode* binary = lilv_plugin_get_library_uri(plug);
  893. TEST_ASSERT(strstr(lilv_node_as_string(binary), "inst" SHLIB_EXT));
  894. cleanup_uris();
  895. return 1;
  896. }
  897. /*****************************************************************************/
  898. static int
  899. test_port(void)
  900. {
  901. if (!start_bundle(MANIFEST_PREFIXES
  902. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  903. BUNDLE_PREFIXES PREFIX_LV2EV
  904. ":plug a lv2:Plugin ; "
  905. PLUGIN_NAME("Test plugin") " ; "
  906. LICENSE_GPL " ; "
  907. "doap:homepage <http://example.org/someplug> ; "
  908. "lv2:port [ "
  909. " a lv2:ControlPort ; a lv2:InputPort ; "
  910. " lv2:index 0 ; lv2:symbol \"foo\" ; "
  911. " lv2:name \"store\" ; "
  912. " lv2:name \"dépanneur\"@fr-ca ; lv2:name \"épicerie\"@fr-fr ; "
  913. " lv2:name \"tienda\"@es ; "
  914. " rdfs:comment \"comment\"@en , \"commentaires\"@fr ; "
  915. " lv2:portProperty lv2:integer ; "
  916. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 ; "
  917. " lv2:scalePoint [ rdfs:label \"Sin\"; rdf:value 3 ] ; "
  918. " lv2:scalePoint [ rdfs:label \"Cos\"; rdf:value 4 ] "
  919. "] , [\n"
  920. " a lv2:EventPort ; a lv2:InputPort ; "
  921. " lv2:index 1 ; lv2:symbol \"event_in\" ; "
  922. " lv2:name \"Event Input\" ; "
  923. " lv2ev:supportsEvent <http://example.org/event> ;"
  924. " atom:supports <http://example.org/atomEvent> "
  925. "] , [\n"
  926. " a lv2:AudioPort ; a lv2:InputPort ; "
  927. " lv2:index 2 ; lv2:symbol \"audio_in\" ; "
  928. " lv2:name \"Audio Input\" ; "
  929. "] , [\n"
  930. " a lv2:AudioPort ; a lv2:OutputPort ; "
  931. " lv2:index 3 ; lv2:symbol \"audio_out\" ; "
  932. " lv2:name \"Audio Output\" ; "
  933. "] ."))
  934. return 0;
  935. init_uris();
  936. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  937. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  938. TEST_ASSERT(plug);
  939. LilvNode* psym = lilv_new_string(world, "foo");
  940. const LilvPort* p = lilv_plugin_get_port_by_index(plug, 0);
  941. const LilvPort* p2 = lilv_plugin_get_port_by_symbol(plug, psym);
  942. lilv_node_free(psym);
  943. TEST_ASSERT(p != NULL);
  944. TEST_ASSERT(p2 != NULL);
  945. TEST_ASSERT(p == p2);
  946. LilvNode* nopsym = lilv_new_string(world, "thisaintnoportfoo");
  947. const LilvPort* p3 = lilv_plugin_get_port_by_symbol(plug, nopsym);
  948. TEST_ASSERT(p3 == NULL);
  949. lilv_node_free(nopsym);
  950. // Try getting an invalid property
  951. LilvNode* num = lilv_new_int(world, 1);
  952. LilvNodes* nothing = lilv_port_get_value(plug, p, num);
  953. TEST_ASSERT(!nothing);
  954. lilv_node_free(num);
  955. LilvNode* audio_class = lilv_new_uri(world,
  956. "http://lv2plug.in/ns/lv2core#AudioPort");
  957. LilvNode* control_class = lilv_new_uri(world,
  958. "http://lv2plug.in/ns/lv2core#ControlPort");
  959. LilvNode* in_class = lilv_new_uri(world,
  960. "http://lv2plug.in/ns/lv2core#InputPort");
  961. LilvNode* out_class = lilv_new_uri(world,
  962. "http://lv2plug.in/ns/lv2core#OutputPort");
  963. TEST_ASSERT(lilv_nodes_size(lilv_port_get_classes(plug, p)) == 2);
  964. TEST_ASSERT(lilv_plugin_get_num_ports(plug) == 4);
  965. TEST_ASSERT(lilv_port_is_a(plug, p, control_class));
  966. TEST_ASSERT(lilv_port_is_a(plug, p, in_class));
  967. TEST_ASSERT(!lilv_port_is_a(plug, p, audio_class));
  968. LilvNodes* port_properties = lilv_port_get_properties(plug, p);
  969. TEST_ASSERT(lilv_nodes_size(port_properties) == 1);
  970. lilv_nodes_free(port_properties);
  971. // Untranslated name (current locale is set to "C" in main)
  972. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_port_get_symbol(plug, p)), "foo"));
  973. LilvNode* name = lilv_port_get_name(plug, p);
  974. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "store"));
  975. lilv_node_free(name);
  976. // Exact language match
  977. setenv("LANG", "fr_FR", 1);
  978. name = lilv_port_get_name(plug, p);
  979. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "épicerie"));
  980. lilv_node_free(name);
  981. // Exact language match (with charset suffix)
  982. setenv("LANG", "fr_CA.utf8", 1);
  983. name = lilv_port_get_name(plug, p);
  984. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "dépanneur"));
  985. lilv_node_free(name);
  986. // Partial language match (choose value translated for different country)
  987. setenv("LANG", "fr_BE", 1);
  988. name = lilv_port_get_name(plug, p);
  989. TEST_ASSERT((!strcmp(lilv_node_as_string(name), "dépanneur"))
  990. ||(!strcmp(lilv_node_as_string(name), "épicerie")));
  991. lilv_node_free(name);
  992. // Partial language match (choose country-less language tagged value)
  993. setenv("LANG", "es_MX", 1);
  994. name = lilv_port_get_name(plug, p);
  995. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "tienda"));
  996. lilv_node_free(name);
  997. // No language match (choose untranslated value)
  998. setenv("LANG", "cn", 1);
  999. name = lilv_port_get_name(plug, p);
  1000. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "store"));
  1001. lilv_node_free(name);
  1002. // Invalid language
  1003. setenv("LANG", "1!", 1);
  1004. name = lilv_port_get_name(plug, p);
  1005. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "store"));
  1006. lilv_node_free(name);
  1007. setenv("LANG", "en_CA.utf-8", 1);
  1008. // Language tagged value with no untranslated values
  1009. LilvNode* rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
  1010. LilvNodes* comments = lilv_port_get_value(plug, p, rdfs_comment);
  1011. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)),
  1012. "comment"));
  1013. LilvNode* comment = lilv_port_get(plug, p, rdfs_comment);
  1014. TEST_ASSERT(!strcmp(lilv_node_as_string(comment), "comment"));
  1015. lilv_node_free(comment);
  1016. lilv_nodes_free(comments);
  1017. setenv("LANG", "fr", 1);
  1018. comments = lilv_port_get_value(plug, p, rdfs_comment);
  1019. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)),
  1020. "commentaires"));
  1021. lilv_nodes_free(comments);
  1022. setenv("LANG", "cn", 1);
  1023. comments = lilv_port_get_value(plug, p, rdfs_comment);
  1024. TEST_ASSERT(!comments);
  1025. lilv_nodes_free(comments);
  1026. lilv_node_free(rdfs_comment);
  1027. setenv("LANG", "C", 1); // Reset locale
  1028. LilvScalePoints* points = lilv_port_get_scale_points(plug, p);
  1029. TEST_ASSERT(lilv_scale_points_size(points) == 2);
  1030. LilvIter* sp_iter = lilv_scale_points_begin(points);
  1031. const LilvScalePoint* sp0 = lilv_scale_points_get(points, sp_iter);
  1032. TEST_ASSERT(sp0);
  1033. sp_iter = lilv_scale_points_next(points, sp_iter);
  1034. const LilvScalePoint* sp1 = lilv_scale_points_get(points, sp_iter);
  1035. TEST_ASSERT(sp1);
  1036. TEST_ASSERT(
  1037. ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), "Sin")
  1038. && lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 3)
  1039. &&
  1040. (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), "Cos")
  1041. && lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 4))
  1042. ||
  1043. ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), "Cos")
  1044. && lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 4)
  1045. &&
  1046. (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), "Sin")
  1047. && lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 3)));
  1048. LilvNode* homepage_p = lilv_new_uri(world, "http://usefulinc.com/ns/doap#homepage");
  1049. LilvNodes* homepages = lilv_plugin_get_value(plug, homepage_p);
  1050. TEST_ASSERT(lilv_nodes_size(homepages) == 1);
  1051. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_nodes_get_first(homepages)),
  1052. "http://example.org/someplug"));
  1053. LilvNode *min, *max, *def;
  1054. lilv_port_get_range(plug, p, &def, &min, &max);
  1055. TEST_ASSERT(def);
  1056. TEST_ASSERT(min);
  1057. TEST_ASSERT(max);
  1058. TEST_ASSERT(lilv_node_as_float(def) == 0.5);
  1059. TEST_ASSERT(lilv_node_as_float(min) == -1.0);
  1060. TEST_ASSERT(lilv_node_as_float(max) == 1.0);
  1061. LilvNode* integer_prop = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#integer");
  1062. LilvNode* toggled_prop = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#toggled");
  1063. TEST_ASSERT(lilv_port_has_property(plug, p, integer_prop));
  1064. TEST_ASSERT(!lilv_port_has_property(plug, p, toggled_prop));
  1065. const LilvPort* ep = lilv_plugin_get_port_by_index(plug, 1);
  1066. LilvNode* event_type = lilv_new_uri(world, "http://example.org/event");
  1067. LilvNode* event_type_2 = lilv_new_uri(world, "http://example.org/otherEvent");
  1068. LilvNode* atom_event = lilv_new_uri(world, "http://example.org/atomEvent");
  1069. TEST_ASSERT(lilv_port_supports_event(plug, ep, event_type));
  1070. TEST_ASSERT(!lilv_port_supports_event(plug, ep, event_type_2));
  1071. TEST_ASSERT(lilv_port_supports_event(plug, ep, atom_event));
  1072. LilvNode* name_p = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#name");
  1073. LilvNodes* names = lilv_port_get_value(plug, p, name_p);
  1074. TEST_ASSERT(lilv_nodes_size(names) == 1);
  1075. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)),
  1076. "store"));
  1077. lilv_nodes_free(names);
  1078. LilvNode* true_val = lilv_new_bool(world, true);
  1079. LilvNode* false_val = lilv_new_bool(world, false);
  1080. TEST_ASSERT(!lilv_node_equals(true_val, false_val));
  1081. lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, false_val);
  1082. names = lilv_port_get_value(plug, p, name_p);
  1083. TEST_ASSERT(lilv_nodes_size(names) == 4);
  1084. lilv_nodes_free(names);
  1085. lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, true_val);
  1086. lilv_node_free(false_val);
  1087. lilv_node_free(true_val);
  1088. names = lilv_port_get_value(plug, ep, name_p);
  1089. TEST_ASSERT(lilv_nodes_size(names) == 1);
  1090. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)),
  1091. "Event Input"));
  1092. const LilvPort* ap_in = lilv_plugin_get_port_by_index(plug, 2);
  1093. TEST_ASSERT(lilv_port_is_a(plug, ap_in, in_class));
  1094. TEST_ASSERT(!lilv_port_is_a(plug, ap_in, out_class));
  1095. TEST_ASSERT(lilv_port_is_a(plug, ap_in, audio_class));
  1096. TEST_ASSERT(!lilv_port_is_a(plug, ap_in, control_class));
  1097. const LilvPort* ap_out = lilv_plugin_get_port_by_index(plug, 3);
  1098. TEST_ASSERT(lilv_port_is_a(plug, ap_out, out_class));
  1099. TEST_ASSERT(!lilv_port_is_a(plug, ap_out, in_class));
  1100. TEST_ASSERT(lilv_port_is_a(plug, ap_out, audio_class));
  1101. TEST_ASSERT(!lilv_port_is_a(plug, ap_out, control_class));
  1102. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, control_class, in_class , NULL) == 1);
  1103. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, audio_class , in_class , NULL) == 1);
  1104. TEST_ASSERT(lilv_plugin_get_num_ports_of_class(plug, audio_class , out_class, NULL) == 1);
  1105. lilv_nodes_free(names);
  1106. lilv_node_free(name_p);
  1107. lilv_node_free(integer_prop);
  1108. lilv_node_free(toggled_prop);
  1109. lilv_node_free(event_type);
  1110. lilv_node_free(event_type_2);
  1111. lilv_node_free(atom_event);
  1112. lilv_node_free(min);
  1113. lilv_node_free(max);
  1114. lilv_node_free(def);
  1115. lilv_node_free(homepage_p);
  1116. lilv_nodes_free(homepages);
  1117. lilv_scale_points_free(points);
  1118. lilv_node_free(control_class);
  1119. lilv_node_free(audio_class);
  1120. lilv_node_free(out_class);
  1121. lilv_node_free(in_class);
  1122. cleanup_uris();
  1123. return 1;
  1124. }
  1125. /*****************************************************************************/
  1126. static unsigned
  1127. ui_supported(const char* container_type_uri,
  1128. const char* ui_type_uri)
  1129. {
  1130. return !strcmp(container_type_uri, ui_type_uri);
  1131. }
  1132. static int
  1133. test_ui(void)
  1134. {
  1135. if (!start_bundle(MANIFEST_PREFIXES
  1136. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1137. BUNDLE_PREFIXES PREFIX_LV2UI
  1138. ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
  1139. PLUGIN_NAME("Test plugin") " ; "
  1140. LICENSE_GPL " ; "
  1141. "lv2:optionalFeature lv2:hardRTCapable ; "
  1142. "lv2:requiredFeature <http://lv2plug.in/ns/ext/event> ; "
  1143. "lv2ui:ui :ui , :ui2 , :ui3 , :ui4 ; "
  1144. "doap:maintainer [ foaf:name \"David Robillard\" ; "
  1145. " foaf:homepage <http://drobilla.net> ; foaf:mbox <mailto:d@drobilla.net> ] ; "
  1146. "lv2:port [ "
  1147. " a lv2:ControlPort ; a lv2:InputPort ; "
  1148. " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
  1149. " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
  1150. "] , [ "
  1151. " a lv2:ControlPort ; a lv2:InputPort ; "
  1152. " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
  1153. " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
  1154. "] , [ "
  1155. " a lv2:ControlPort ; a lv2:OutputPort ; "
  1156. " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
  1157. " lv2:portProperty lv2:reportsLatency "
  1158. "] .\n"
  1159. ":ui a lv2ui:GtkUI ; "
  1160. " lv2ui:requiredFeature lv2ui:makeResident ; "
  1161. " lv2ui:binary <ui" SHLIB_EXT "> ; "
  1162. " lv2ui:optionalFeature lv2ui:ext_presets . "
  1163. ":ui2 a lv2ui:GtkUI ; lv2ui:binary <ui2" SHLIB_EXT "> . "
  1164. ":ui3 a lv2ui:GtkUI ; lv2ui:binary <ui3" SHLIB_EXT "> . "
  1165. ":ui4 a lv2ui:GtkUI ; lv2ui:binary <ui4" SHLIB_EXT "> . "))
  1166. return 0;
  1167. init_uris();
  1168. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1169. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  1170. TEST_ASSERT(plug);
  1171. LilvUIs* uis = lilv_plugin_get_uis(plug);
  1172. TEST_ASSERT(lilv_uis_size(uis) == 4);
  1173. const LilvUI* ui0 = lilv_uis_get(uis, lilv_uis_begin(uis));
  1174. TEST_ASSERT(ui0);
  1175. LilvNode* ui_uri = lilv_new_uri(world, "http://example.org/ui");
  1176. LilvNode* ui2_uri = lilv_new_uri(world, "http://example.org/ui3");
  1177. LilvNode* ui3_uri = lilv_new_uri(world, "http://example.org/ui4");
  1178. LilvNode* noui_uri = lilv_new_uri(world, "http://example.org/notaui");
  1179. const LilvUI* ui0_2 = lilv_uis_get_by_uri(uis, ui_uri);
  1180. TEST_ASSERT(ui0 == ui0_2);
  1181. TEST_ASSERT(lilv_node_equals(lilv_ui_get_uri(ui0_2), ui_uri));
  1182. const LilvUI* ui2 = lilv_uis_get_by_uri(uis, ui2_uri);
  1183. TEST_ASSERT(ui2 != ui0);
  1184. const LilvUI* ui3 = lilv_uis_get_by_uri(uis, ui3_uri);
  1185. TEST_ASSERT(ui3 != ui0);
  1186. const LilvUI* noui = lilv_uis_get_by_uri(uis, noui_uri);
  1187. TEST_ASSERT(noui == NULL);
  1188. const LilvNodes* classes = lilv_ui_get_classes(ui0);
  1189. TEST_ASSERT(lilv_nodes_size(classes) == 1);
  1190. LilvNode* ui_class_uri = lilv_new_uri(world,
  1191. "http://lv2plug.in/ns/extensions/ui#GtkUI");
  1192. LilvNode* unknown_ui_class_uri = lilv_new_uri(world,
  1193. "http://example.org/mysteryUI");
  1194. TEST_ASSERT(lilv_node_equals(lilv_nodes_get_first(classes), ui_class_uri));
  1195. TEST_ASSERT(lilv_ui_is_a(ui0, ui_class_uri));
  1196. const LilvNode* ui_type = NULL;
  1197. TEST_ASSERT(lilv_ui_is_supported(ui0, ui_supported, ui_class_uri, &ui_type));
  1198. TEST_ASSERT(!lilv_ui_is_supported(ui0, ui_supported, unknown_ui_class_uri, &ui_type));
  1199. TEST_ASSERT(lilv_node_equals(ui_type, ui_class_uri));
  1200. const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug);
  1201. const LilvNode* ui_bundle_uri = lilv_ui_get_bundle_uri(ui0);
  1202. TEST_ASSERT(lilv_node_equals(plug_bundle_uri, ui_bundle_uri));
  1203. char* ui_binary_uri_str = (char*)malloc(TEST_PATH_MAX);
  1204. snprintf(ui_binary_uri_str, TEST_PATH_MAX, "%s%s",
  1205. lilv_node_as_string(plug_bundle_uri), "ui" SHLIB_EXT);
  1206. const LilvNode* ui_binary_uri = lilv_ui_get_binary_uri(ui0);
  1207. LilvNode* expected_uri = lilv_new_uri(world, ui_binary_uri_str);
  1208. TEST_ASSERT(lilv_node_equals(expected_uri, ui_binary_uri));
  1209. free(ui_binary_uri_str);
  1210. lilv_node_free(unknown_ui_class_uri);
  1211. lilv_node_free(ui_class_uri);
  1212. lilv_node_free(ui_uri);
  1213. lilv_node_free(ui2_uri);
  1214. lilv_node_free(ui3_uri);
  1215. lilv_node_free(noui_uri);
  1216. lilv_node_free(expected_uri);
  1217. lilv_uis_free(uis);
  1218. cleanup_uris();
  1219. return 1;
  1220. }
  1221. /*****************************************************************************/
  1222. uint32_t atom_Float = 0;
  1223. float in = 1.0;
  1224. float out = 42.0;
  1225. float control = 1234.0;
  1226. static const void*
  1227. get_port_value(const char* port_symbol,
  1228. void* user_data,
  1229. uint32_t* size,
  1230. uint32_t* type)
  1231. {
  1232. if (!strcmp(port_symbol, "input")) {
  1233. *size = sizeof(float);
  1234. *type = atom_Float;
  1235. return &in;
  1236. } else if (!strcmp(port_symbol, "output")) {
  1237. *size = sizeof(float);
  1238. *type = atom_Float;
  1239. return &out;
  1240. } else if (!strcmp(port_symbol, "control")) {
  1241. *size = sizeof(float);
  1242. *type = atom_Float;
  1243. return &control;
  1244. } else {
  1245. fprintf(stderr, "error: get_port_value for nonexistent port `%s'\n",
  1246. port_symbol);
  1247. *size = *type = 0;
  1248. return NULL;
  1249. }
  1250. }
  1251. static void
  1252. set_port_value(const char* port_symbol,
  1253. void* user_data,
  1254. const void* value,
  1255. uint32_t size,
  1256. uint32_t type)
  1257. {
  1258. if (!strcmp(port_symbol, "input")) {
  1259. in = *(const float*)value;
  1260. } else if (!strcmp(port_symbol, "output")) {
  1261. out = *(const float*)value;
  1262. } else if (!strcmp(port_symbol, "control")) {
  1263. control = *(const float*)value;
  1264. } else {
  1265. fprintf(stderr, "error: set_port_value for nonexistent port `%s'\n",
  1266. port_symbol);
  1267. }
  1268. }
  1269. char** uris = NULL;
  1270. size_t n_uris = 0;
  1271. static LV2_URID
  1272. map_uri(LV2_URID_Map_Handle handle,
  1273. const char* uri)
  1274. {
  1275. for (size_t i = 0; i < n_uris; ++i) {
  1276. if (!strcmp(uris[i], uri)) {
  1277. return i + 1;
  1278. }
  1279. }
  1280. assert(serd_uri_string_has_scheme((const uint8_t*)uri));
  1281. uris = (char**)realloc(uris, ++n_uris * sizeof(char*));
  1282. uris[n_uris - 1] = lilv_strdup(uri);
  1283. return n_uris;
  1284. }
  1285. static const char*
  1286. unmap_uri(LV2_URID_Map_Handle handle,
  1287. LV2_URID urid)
  1288. {
  1289. if (urid > 0 && urid <= n_uris) {
  1290. return uris[urid - 1];
  1291. }
  1292. return NULL;
  1293. }
  1294. static char* temp_dir = NULL;
  1295. static char*
  1296. lilv_make_path(LV2_State_Make_Path_Handle handle,
  1297. const char* path)
  1298. {
  1299. return lilv_path_join(temp_dir, path);
  1300. }
  1301. static int
  1302. test_state(void)
  1303. {
  1304. init_world();
  1305. uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(LILV_TEST_BUNDLE);
  1306. SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
  1307. LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
  1308. LilvNode* plugin_uri = lilv_new_uri(world,
  1309. "http://example.org/lilv-test-plugin");
  1310. lilv_world_load_bundle(world, bundle_uri);
  1311. free(abs_bundle);
  1312. serd_node_free(&bundle);
  1313. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1314. const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
  1315. TEST_ASSERT(plugin);
  1316. LV2_URID_Map map = { NULL, map_uri };
  1317. LV2_Feature map_feature = { LV2_URID_MAP_URI, &map };
  1318. LV2_URID_Unmap unmap = { NULL, unmap_uri };
  1319. LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap };
  1320. const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL };
  1321. atom_Float = map.map(map.handle, "http://lv2plug.in/ns/ext/atom#Float");
  1322. LilvNode* num = lilv_new_int(world, 5);
  1323. LilvState* nostate = lilv_state_new_from_file(world, &map, num, "/junk");
  1324. TEST_ASSERT(!nostate);
  1325. LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, features);
  1326. TEST_ASSERT(instance);
  1327. lilv_instance_activate(instance);
  1328. lilv_instance_connect_port(instance, 0, &in);
  1329. lilv_instance_connect_port(instance, 1, &out);
  1330. lilv_instance_run(instance, 1);
  1331. TEST_ASSERT(in == 1.0);
  1332. TEST_ASSERT(out == 1.0);
  1333. temp_dir = lilv_realpath("temp");
  1334. const char* file_dir = NULL;
  1335. char* copy_dir = NULL;
  1336. char* link_dir = NULL;
  1337. char* save_dir = NULL;
  1338. // Get instance state state
  1339. LilvState* state = lilv_state_new_from_instance(
  1340. plugin, instance, &map,
  1341. file_dir, copy_dir, link_dir, save_dir,
  1342. get_port_value, world, 0, NULL);
  1343. // Get another instance state
  1344. LilvState* state2 = lilv_state_new_from_instance(
  1345. plugin, instance, &map,
  1346. file_dir, copy_dir, link_dir, save_dir,
  1347. get_port_value, world, 0, NULL);
  1348. // Ensure they are equal
  1349. TEST_ASSERT(lilv_state_equals(state, state2));
  1350. // Check that we can't delete unsaved state
  1351. TEST_ASSERT(lilv_state_delete(world, state));
  1352. // Check that state has no URI
  1353. TEST_ASSERT(!lilv_state_get_uri(state));
  1354. // Check that we can't save a state with no URI
  1355. char* bad_state_str = lilv_state_to_string(
  1356. world, &map, &unmap, state, NULL, NULL);
  1357. TEST_ASSERT(!bad_state_str);
  1358. // Check that we can't restore the NULL string (and it doesn't crash)
  1359. LilvState* bad_state = lilv_state_new_from_string(world, &map, NULL);
  1360. TEST_ASSERT(!bad_state);
  1361. // Save state to a string
  1362. char* state1_str = lilv_state_to_string(
  1363. world, &map, &unmap, state, "http://example.org/state1", NULL);
  1364. // Restore from string
  1365. LilvState* from_str = lilv_state_new_from_string(world, &map, state1_str);
  1366. // Ensure they are equal
  1367. TEST_ASSERT(lilv_state_equals(state, from_str));
  1368. free(state1_str);
  1369. const LilvNode* state_plugin_uri = lilv_state_get_plugin_uri(state);
  1370. TEST_ASSERT(lilv_node_equals(state_plugin_uri, plugin_uri));
  1371. // Tinker with the label of the first state
  1372. TEST_ASSERT(lilv_state_get_label(state) == NULL);
  1373. lilv_state_set_label(state, "Test State Old Label");
  1374. TEST_ASSERT(!strcmp(lilv_state_get_label(state), "Test State Old Label"));
  1375. lilv_state_set_label(state, "Test State");
  1376. TEST_ASSERT(!strcmp(lilv_state_get_label(state), "Test State"));
  1377. TEST_ASSERT(!lilv_state_equals(state, state2)); // Label changed
  1378. // Run and get a new instance state (which should now differ)
  1379. lilv_instance_run(instance, 1);
  1380. LilvState* state3 = lilv_state_new_from_instance(
  1381. plugin, instance, &map,
  1382. file_dir, copy_dir, link_dir, save_dir,
  1383. get_port_value, world, 0, NULL);
  1384. TEST_ASSERT(!lilv_state_equals(state2, state3)); // num_runs changed
  1385. // Restore instance state to original state
  1386. lilv_state_restore(state2, instance, set_port_value, NULL, 0, NULL);
  1387. // Take a new snapshot and ensure it matches the set state
  1388. LilvState* state4 = lilv_state_new_from_instance(
  1389. plugin, instance, &map,
  1390. file_dir, copy_dir, link_dir, save_dir,
  1391. get_port_value, world, 0, NULL);
  1392. TEST_ASSERT(lilv_state_equals(state2, state4));
  1393. // Set some metadata properties
  1394. lilv_state_set_metadata(state, map.map(map.handle, LILV_NS_RDFS "comment"),
  1395. "This is a comment",
  1396. strlen("This is a comment") + 1,
  1397. map.map(map.handle, "http://lv2plug.in/ns/ext/atom#Literal"),
  1398. LV2_STATE_IS_POD);
  1399. lilv_state_set_metadata(state, map.map(map.handle, "http://example.org/metablob"),
  1400. "LIVEBEEF",
  1401. strlen("LIVEBEEF") + 1,
  1402. map.map(map.handle, "http://example.org/MetaBlob"),
  1403. 0);
  1404. // Save state to a directory
  1405. int ret = lilv_state_save(world, &map, &unmap, state, NULL,
  1406. "state/state.lv2", "state.ttl");
  1407. TEST_ASSERT(!ret);
  1408. // Load state from directory
  1409. LilvState* state5 = lilv_state_new_from_file(world, &map, NULL,
  1410. "state/state.lv2/state.ttl");
  1411. TEST_ASSERT(lilv_state_equals(state, state5)); // Round trip accuracy
  1412. TEST_ASSERT(lilv_state_get_num_properties(state) == 8);
  1413. // Attempt to save state to nowhere (error)
  1414. ret = lilv_state_save(world, &map, &unmap, state, NULL, NULL, NULL);
  1415. TEST_ASSERT(ret);
  1416. // Save another state to the same directory (update manifest)
  1417. ret = lilv_state_save(world, &map, &unmap, state, NULL,
  1418. "state/state.lv2", "state2.ttl");
  1419. TEST_ASSERT(!ret);
  1420. // Save state with URI to a directory
  1421. const char* state_uri = "http://example.org/state";
  1422. ret = lilv_state_save(world, &map, &unmap, state, state_uri,
  1423. "state/state6.lv2", "state6.ttl");
  1424. TEST_ASSERT(!ret);
  1425. // Load default bundle into world and load state from it
  1426. uint8_t* state6_path = (uint8_t*)lilv_path_absolute("state/state6.lv2/");
  1427. SerdNode state6_uri = serd_node_new_file_uri(state6_path, 0, 0, true);
  1428. LilvNode* test_state_bundle = lilv_new_uri(world, (const char*)state6_uri.buf);
  1429. LilvNode* test_state_node = lilv_new_uri(world, state_uri);
  1430. lilv_world_load_bundle(world, test_state_bundle);
  1431. lilv_world_load_resource(world, test_state_node);
  1432. serd_node_free(&state6_uri);
  1433. free(state6_path);
  1434. LilvState* state6 = lilv_state_new_from_world(world, &map, test_state_node);
  1435. TEST_ASSERT(lilv_state_equals(state, state6)); // Round trip accuracy
  1436. // Check that loaded state has correct URI
  1437. TEST_ASSERT(lilv_state_get_uri(state6));
  1438. TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_state_get_uri(state6)),
  1439. state_uri));
  1440. lilv_world_unload_resource(world, test_state_node);
  1441. lilv_world_unload_bundle(world, test_state_bundle);
  1442. LilvState* state6_2 = lilv_state_new_from_world(world, &map, test_state_node);
  1443. TEST_ASSERT(!state6_2); // No longer present
  1444. lilv_state_free(state6_2);
  1445. lilv_node_free(test_state_bundle);
  1446. lilv_node_free(test_state_node);
  1447. unsetenv("LV2_STATE_BUNDLE");
  1448. // Make directories and test files support
  1449. mkdir("temp", 0700);
  1450. file_dir = temp_dir;
  1451. mkdir("files", 0700);
  1452. copy_dir = lilv_realpath("files");
  1453. mkdir("links", 0700);
  1454. link_dir = lilv_realpath("links");
  1455. LV2_State_Make_Path make_path = { NULL, lilv_make_path };
  1456. LV2_Feature make_path_feature = { LV2_STATE__makePath, &make_path };
  1457. const LV2_Feature* ffeatures[] = { &make_path_feature, &map_feature, NULL };
  1458. lilv_instance_deactivate(instance);
  1459. lilv_instance_free(instance);
  1460. instance = lilv_plugin_instantiate(plugin, 48000.0, ffeatures);
  1461. lilv_instance_activate(instance);
  1462. lilv_instance_connect_port(instance, 0, &in);
  1463. lilv_instance_connect_port(instance, 1, &out);
  1464. lilv_instance_run(instance, 1);
  1465. // Test instantiating twice
  1466. LilvInstance* instance2 = lilv_plugin_instantiate(plugin, 48000.0, ffeatures);
  1467. if (!instance2) {
  1468. fatal_error("Failed to create multiple instances of <%s>\n",
  1469. lilv_node_as_uri(state_plugin_uri));
  1470. return 0;
  1471. }
  1472. lilv_instance_free(instance2);
  1473. // Get instance state state
  1474. LilvState* fstate = lilv_state_new_from_instance(
  1475. plugin, instance, &map,
  1476. file_dir, copy_dir, link_dir, "state/fstate.lv2",
  1477. get_port_value, world, 0, ffeatures);
  1478. // Get another instance state
  1479. LilvState* fstate2 = lilv_state_new_from_instance(
  1480. plugin, instance, &map,
  1481. file_dir, copy_dir, link_dir, "state/fstate2.lv2",
  1482. get_port_value, world, 0, ffeatures);
  1483. // Should be identical
  1484. TEST_ASSERT(lilv_state_equals(fstate, fstate2));
  1485. // Run, writing more to rec file
  1486. lilv_instance_run(instance, 2);
  1487. // Get yet another instance state
  1488. LilvState* fstate3 = lilv_state_new_from_instance(
  1489. plugin, instance, &map, file_dir, copy_dir, link_dir, "state/fstate3.lv2",
  1490. get_port_value, world, 0, ffeatures);
  1491. // Should be different
  1492. TEST_ASSERT(!lilv_state_equals(fstate, fstate3));
  1493. // Save state to a directory
  1494. ret = lilv_state_save(world, &map, &unmap, fstate, NULL,
  1495. "state/fstate.lv2", "fstate.ttl");
  1496. TEST_ASSERT(!ret);
  1497. // Load state from directory
  1498. LilvState* fstate4 = lilv_state_new_from_file(world, &map, NULL,
  1499. "state/fstate.lv2/fstate.ttl");
  1500. TEST_ASSERT(lilv_state_equals(fstate, fstate4)); // Round trip accuracy
  1501. // Restore instance state to loaded state
  1502. lilv_state_restore(fstate4, instance, set_port_value, NULL, 0, ffeatures);
  1503. // Take a new snapshot and ensure it matches
  1504. LilvState* fstate5 = lilv_state_new_from_instance(
  1505. plugin, instance, &map,
  1506. file_dir, copy_dir, link_dir, "state/fstate5.lv2",
  1507. get_port_value, world, 0, ffeatures);
  1508. TEST_ASSERT(lilv_state_equals(fstate3, fstate5));
  1509. // Save state to a (different) directory again
  1510. ret = lilv_state_save(world, &map, &unmap, fstate, NULL,
  1511. "state/fstate6.lv2", "fstate6.ttl");
  1512. TEST_ASSERT(!ret);
  1513. // Reload it and ensure it's identical to the other loaded version
  1514. LilvState* fstate6 = lilv_state_new_from_file(world, &map, NULL,
  1515. "state/fstate6.lv2/fstate6.ttl");
  1516. TEST_ASSERT(lilv_state_equals(fstate4, fstate6));
  1517. // Run, changing rec file (without changing size)
  1518. lilv_instance_run(instance, 3);
  1519. // Take a new snapshot
  1520. LilvState* fstate7 = lilv_state_new_from_instance(
  1521. plugin, instance, &map,
  1522. file_dir, copy_dir, link_dir, "state/fstate7.lv2",
  1523. get_port_value, world, 0, ffeatures);
  1524. TEST_ASSERT(!lilv_state_equals(fstate6, fstate7));
  1525. // Save the changed state to a (different) directory again
  1526. ret = lilv_state_save(world, &map, &unmap, fstate7, NULL,
  1527. "state/fstate7.lv2", "fstate7.ttl");
  1528. TEST_ASSERT(!ret);
  1529. // Reload it and ensure it's changed
  1530. LilvState* fstate72 = lilv_state_new_from_file(world, &map, NULL,
  1531. "state/fstate7.lv2/fstate7.ttl");
  1532. TEST_ASSERT(lilv_state_equals(fstate72, fstate7));
  1533. TEST_ASSERT(!lilv_state_equals(fstate6, fstate72));
  1534. // Delete saved state
  1535. lilv_state_delete(world, fstate7);
  1536. lilv_instance_deactivate(instance);
  1537. lilv_instance_free(instance);
  1538. lilv_node_free(num);
  1539. lilv_state_free(state);
  1540. lilv_state_free(from_str);
  1541. lilv_state_free(state2);
  1542. lilv_state_free(state3);
  1543. lilv_state_free(state4);
  1544. lilv_state_free(state5);
  1545. lilv_state_free(state6);
  1546. lilv_state_free(fstate);
  1547. lilv_state_free(fstate2);
  1548. lilv_state_free(fstate3);
  1549. lilv_state_free(fstate4);
  1550. lilv_state_free(fstate5);
  1551. lilv_state_free(fstate6);
  1552. lilv_state_free(fstate7);
  1553. lilv_state_free(fstate72);
  1554. // Free URI map
  1555. for (size_t i = 0; i < n_uris; ++i) {
  1556. free(uris[i]);
  1557. }
  1558. free(uris);
  1559. n_uris = 0;
  1560. lilv_node_free(plugin_uri);
  1561. lilv_node_free(bundle_uri);
  1562. free(link_dir);
  1563. free(copy_dir);
  1564. free(temp_dir);
  1565. cleanup_uris();
  1566. return 1;
  1567. }
  1568. /*****************************************************************************/
  1569. static int
  1570. test_bad_port_symbol(void)
  1571. {
  1572. if (!start_bundle(MANIFEST_PREFIXES
  1573. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1574. BUNDLE_PREFIXES PREFIX_LV2EV
  1575. ":plug a lv2:Plugin ; "
  1576. PLUGIN_NAME("Test plugin") " ; "
  1577. LICENSE_GPL " ; "
  1578. "doap:homepage <http://example.org/someplug> ; "
  1579. "lv2:port [ "
  1580. " a lv2:ControlPort ; a lv2:InputPort ; "
  1581. " lv2:index 0 ; lv2:symbol \"0invalid\" ;"
  1582. " lv2:name \"Invalid\" ; "
  1583. "] ."))
  1584. return 0;
  1585. init_uris();
  1586. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1587. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  1588. uint32_t n_ports = lilv_plugin_get_num_ports(plug);
  1589. TEST_ASSERT(n_ports == 0);
  1590. cleanup_uris();
  1591. return 1;
  1592. }
  1593. /*****************************************************************************/
  1594. static int
  1595. test_bad_port_index(void)
  1596. {
  1597. if (!start_bundle(MANIFEST_PREFIXES
  1598. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1599. BUNDLE_PREFIXES PREFIX_LV2EV
  1600. ":plug a lv2:Plugin ; "
  1601. PLUGIN_NAME("Test plugin") " ; "
  1602. LICENSE_GPL " ; "
  1603. "doap:homepage <http://example.org/someplug> ; "
  1604. "lv2:port [ "
  1605. " a lv2:ControlPort ; a lv2:InputPort ; "
  1606. " lv2:index \"notaninteger\" ; lv2:symbol \"invalid\" ;"
  1607. " lv2:name \"Invalid\" ; "
  1608. "] ."))
  1609. return 0;
  1610. init_uris();
  1611. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1612. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  1613. uint32_t n_ports = lilv_plugin_get_num_ports(plug);
  1614. TEST_ASSERT(n_ports == 0);
  1615. cleanup_uris();
  1616. return 1;
  1617. }
  1618. /*****************************************************************************/
  1619. static int
  1620. test_string(void)
  1621. {
  1622. char* s = NULL;
  1623. TEST_ASSERT(!strcmp((s = lilv_dirname("/foo/bar")), "/foo")); free(s);
  1624. TEST_ASSERT(!strcmp((s = lilv_dirname("/foo/bar/")), "/foo")); free(s);
  1625. TEST_ASSERT(!strcmp((s = lilv_dirname("/foo///bar/")), "/foo")); free(s);
  1626. TEST_ASSERT(!strcmp((s = lilv_dirname("/foo///bar//")), "/foo")); free(s);
  1627. TEST_ASSERT(!strcmp((s = lilv_dirname("foo")), ".")); free(s);
  1628. TEST_ASSERT(!strcmp((s = lilv_dirname("/foo")), "/")); free(s);
  1629. TEST_ASSERT(!strcmp((s = lilv_dirname("/")), "/")); free(s);
  1630. TEST_ASSERT(!strcmp((s = lilv_dirname("//")), "/")); free(s);
  1631. TEST_ASSERT(!strcmp((s = lilv_path_relative_to("/a/b", "/a/")), "b")); free(s);
  1632. TEST_ASSERT(!strcmp((s = lilv_path_relative_to("/a", "/b/c/")), "/a")); free(s);
  1633. TEST_ASSERT(!strcmp((s = lilv_path_relative_to("/a/b/c", "/a/b/d/")), "../c")); free(s);
  1634. TEST_ASSERT(!strcmp((s = lilv_path_relative_to("/a/b/c", "/a/b/d/e/")), "../../c")); free(s);
  1635. TEST_ASSERT(!strcmp((s = lilv_path_join("/a", "b")), "/a/b")); free(s);
  1636. TEST_ASSERT(!strcmp((s = lilv_path_join("/a", "/b")), "/a/b")); free(s);
  1637. TEST_ASSERT(!strcmp((s = lilv_path_join("/a/", "/b")), "/a/b")); free(s);
  1638. TEST_ASSERT(!strcmp((s = lilv_path_join("/a/", "b")), "/a/b")); free(s);
  1639. TEST_ASSERT(!strcmp((s = lilv_path_join("/a", NULL)), "/a/")); free(s);
  1640. TEST_ASSERT(!strcmp((s = lilv_path_join(NULL, "/b")), "/b")); free(s);
  1641. #ifndef _WIN32
  1642. setenv("LILV_TEST_1", "test", 1);
  1643. char* home_foo = lilv_strjoin(getenv("HOME"), "/foo", NULL);
  1644. TEST_ASSERT(!strcmp((s = lilv_expand("$LILV_TEST_1")), "test")); free(s);
  1645. TEST_ASSERT(!strcmp((s = lilv_expand("~")), getenv("HOME"))); free(s);
  1646. TEST_ASSERT(!strcmp((s = lilv_expand("~foo")), "~foo")); free(s);
  1647. TEST_ASSERT(!strcmp((s = lilv_expand("~/foo")), home_foo)); free(s);
  1648. TEST_ASSERT(!strcmp((s = lilv_expand("$NOT_A_VAR")), "$NOT_A_VAR")); free(s);
  1649. free(home_foo);
  1650. unsetenv("LILV_TEST_1");
  1651. #endif
  1652. return 1;
  1653. }
  1654. /*****************************************************************************/
  1655. static int
  1656. test_world(void)
  1657. {
  1658. if (!init_world()) {
  1659. return 0;
  1660. }
  1661. LilvNode* num = lilv_new_int(world, 4);
  1662. LilvNode* uri = lilv_new_uri(world, "http://example.org/object");
  1663. LilvNodes* matches = lilv_world_find_nodes(world, num, NULL, NULL);
  1664. TEST_ASSERT(!matches);
  1665. matches = lilv_world_find_nodes(world, NULL, num, NULL);
  1666. TEST_ASSERT(!matches);
  1667. matches = lilv_world_find_nodes(world, NULL, uri, NULL);
  1668. TEST_ASSERT(!matches);
  1669. lilv_node_free(uri);
  1670. lilv_node_free(num);
  1671. lilv_world_unload_bundle(world, NULL);
  1672. return 1;
  1673. }
  1674. /*****************************************************************************/
  1675. static int
  1676. test_reload_bundle(void)
  1677. {
  1678. // Create a simple plugin bundle
  1679. create_bundle(MANIFEST_PREFIXES
  1680. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1681. BUNDLE_PREFIXES
  1682. ":plug a lv2:Plugin ; "
  1683. PLUGIN_NAME("First name") " .");
  1684. if (!init_world()) {
  1685. return 0;
  1686. }
  1687. init_uris();
  1688. lilv_world_load_specifications(world);
  1689. // Load bundle
  1690. LilvNode* bundle_uri = lilv_new_uri(world, bundle_dir_uri);
  1691. lilv_world_load_bundle(world, bundle_uri);
  1692. // Check that plugin is present
  1693. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1694. const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  1695. TEST_ASSERT(plug);
  1696. // Check that plugin name is correct
  1697. LilvNode* name = lilv_plugin_get_name(plug);
  1698. TEST_ASSERT(!strcmp(lilv_node_as_string(name), "First name"));
  1699. lilv_node_free(name);
  1700. // Unload bundle from world and delete it
  1701. lilv_world_unload_bundle(world, bundle_uri);
  1702. delete_bundle();
  1703. // Create a new version of the same bundle, but with a different name
  1704. create_bundle(MANIFEST_PREFIXES
  1705. ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1706. BUNDLE_PREFIXES
  1707. ":plug a lv2:Plugin ; "
  1708. PLUGIN_NAME("Second name") " .");
  1709. // Check that plugin is no longer in the world's plugin list
  1710. TEST_ASSERT(lilv_plugins_size(plugins) == 0);
  1711. // Load new bundle
  1712. lilv_world_load_bundle(world, bundle_uri);
  1713. // Check that plugin is present again and is the same LilvPlugin
  1714. const LilvPlugin* plug2 = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
  1715. TEST_ASSERT(plug2);
  1716. TEST_ASSERT(plug2 == plug);
  1717. // Check that plugin now has new name
  1718. LilvNode* name2 = lilv_plugin_get_name(plug2);
  1719. TEST_ASSERT(name2);
  1720. TEST_ASSERT(!strcmp(lilv_node_as_string(name2), "Second name"));
  1721. lilv_node_free(name2);
  1722. // Load new bundle again (noop)
  1723. lilv_world_load_bundle(world, bundle_uri);
  1724. cleanup_uris();
  1725. lilv_node_free(bundle_uri);
  1726. lilv_world_free(world);
  1727. world = NULL;
  1728. return 1;
  1729. }
  1730. /*****************************************************************************/
  1731. static int
  1732. test_replace_version(void)
  1733. {
  1734. if (!init_world()) {
  1735. return 0;
  1736. }
  1737. LilvNode* plug_uri = lilv_new_uri(world, "http://example.org/versioned");
  1738. LilvNode* lv2_minorVersion = lilv_new_uri(world, LV2_CORE__minorVersion);
  1739. LilvNode* lv2_microVersion = lilv_new_uri(world, LV2_CORE__microVersion);
  1740. LilvNode* minor = NULL;
  1741. LilvNode* micro = NULL;
  1742. char* old_bundle_path = (char*)malloc(strlen(LILV_TEST_DIR) + 32);
  1743. strcpy(old_bundle_path, LILV_TEST_DIR);
  1744. strcat(old_bundle_path, "old_version.lv2/");
  1745. // Load plugin from old bundle
  1746. LilvNode* old_bundle = lilv_new_file_uri(world, NULL, old_bundle_path);
  1747. lilv_world_load_bundle(world, old_bundle);
  1748. lilv_world_load_resource(world, plug_uri);
  1749. // Check version
  1750. const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
  1751. const LilvPlugin* old_plug = lilv_plugins_get_by_uri(plugins, plug_uri);
  1752. TEST_ASSERT(old_plug);
  1753. minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0);
  1754. micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0);
  1755. TEST_ASSERT(!strcmp(lilv_node_as_string(minor), "1"));
  1756. TEST_ASSERT(!strcmp(lilv_node_as_string(micro), "0"));
  1757. lilv_node_free(micro);
  1758. lilv_node_free(minor);
  1759. char* new_bundle_path = (char*)malloc(strlen(LILV_TEST_DIR) + 32);
  1760. strcpy(new_bundle_path, LILV_TEST_DIR);
  1761. strcat(new_bundle_path, "new_version.lv2/");
  1762. // Load plugin from new bundle
  1763. LilvNode* new_bundle = lilv_new_file_uri(world, NULL, new_bundle_path);
  1764. lilv_world_load_bundle(world, new_bundle);
  1765. lilv_world_load_resource(world, plug_uri);
  1766. // Check that version in the world model has changed
  1767. plugins = lilv_world_get_all_plugins(world);
  1768. const LilvPlugin* new_plug = lilv_plugins_get_by_uri(plugins, plug_uri);
  1769. TEST_ASSERT(new_plug);
  1770. TEST_ASSERT(lilv_node_equals(lilv_plugin_get_bundle_uri(new_plug), new_bundle));
  1771. minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0);
  1772. micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0);
  1773. TEST_ASSERT(!strcmp(lilv_node_as_string(minor), "2"));
  1774. TEST_ASSERT(!strcmp(lilv_node_as_string(micro), "1"));
  1775. lilv_node_free(micro);
  1776. lilv_node_free(minor);
  1777. // Try to load the old version again
  1778. lilv_world_load_bundle(world, old_bundle);
  1779. lilv_world_load_resource(world, plug_uri);
  1780. // Check that version in the world model has not changed
  1781. plugins = lilv_world_get_all_plugins(world);
  1782. new_plug = lilv_plugins_get_by_uri(plugins, plug_uri);
  1783. TEST_ASSERT(new_plug);
  1784. minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0);
  1785. micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0);
  1786. TEST_ASSERT(!strcmp(lilv_node_as_string(minor), "2"));
  1787. TEST_ASSERT(!strcmp(lilv_node_as_string(micro), "1"));
  1788. lilv_node_free(micro);
  1789. lilv_node_free(minor);
  1790. lilv_node_free(new_bundle);
  1791. lilv_node_free(old_bundle);
  1792. free(new_bundle_path);
  1793. free(old_bundle_path);
  1794. lilv_node_free(plug_uri);
  1795. lilv_node_free(lv2_minorVersion);
  1796. lilv_node_free(lv2_microVersion);
  1797. return 1;
  1798. }
  1799. /*****************************************************************************/
  1800. static int
  1801. test_get_symbol(void)
  1802. {
  1803. if (!start_bundle(
  1804. MANIFEST_PREFIXES
  1805. ":plug a lv2:Plugin ; lv2:symbol \"plugsym\" ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
  1806. BUNDLE_PREFIXES PREFIX_LV2EV
  1807. ":plug a lv2:Plugin ; "
  1808. PLUGIN_NAME("Test plugin") " ; "
  1809. "lv2:symbol \"plugsym\" .")) {
  1810. return 0;
  1811. }
  1812. init_uris();
  1813. LilvNode* plug_sym = lilv_world_get_symbol(world, plugin_uri_value);
  1814. LilvNode* path = lilv_new_uri(world, "http://example.org/foo");
  1815. LilvNode* path_sym = lilv_world_get_symbol(world, path);
  1816. LilvNode* query = lilv_new_uri(world, "http://example.org/foo?bar=baz");
  1817. LilvNode* query_sym = lilv_world_get_symbol(world, query);
  1818. LilvNode* frag = lilv_new_uri(world, "http://example.org/foo#bar");
  1819. LilvNode* frag_sym = lilv_world_get_symbol(world, frag);
  1820. LilvNode* queryfrag = lilv_new_uri(world, "http://example.org/foo?bar=baz#quux");
  1821. LilvNode* queryfrag_sym = lilv_world_get_symbol(world, queryfrag);
  1822. LilvNode* nonuri = lilv_new_int(world, 42);
  1823. TEST_ASSERT(lilv_world_get_symbol(world, nonuri) == NULL);
  1824. TEST_ASSERT(!strcmp(lilv_node_as_string(plug_sym), "plugsym"));
  1825. TEST_ASSERT(!strcmp(lilv_node_as_string(path_sym), "foo"));
  1826. TEST_ASSERT(!strcmp(lilv_node_as_string(query_sym), "bar_baz"));
  1827. TEST_ASSERT(!strcmp(lilv_node_as_string(frag_sym), "bar"));
  1828. TEST_ASSERT(!strcmp(lilv_node_as_string(queryfrag_sym), "quux"));
  1829. lilv_node_free(nonuri);
  1830. lilv_node_free(queryfrag_sym);
  1831. lilv_node_free(queryfrag);
  1832. lilv_node_free(frag_sym);
  1833. lilv_node_free(frag);
  1834. lilv_node_free(query_sym);
  1835. lilv_node_free(query);
  1836. lilv_node_free(path_sym);
  1837. lilv_node_free(path);
  1838. lilv_node_free(plug_sym);
  1839. cleanup_uris();
  1840. return 1;
  1841. }
  1842. /*****************************************************************************/
  1843. /* add tests here */
  1844. static struct TestCase tests[] = {
  1845. TEST_CASE(util),
  1846. TEST_CASE(value),
  1847. TEST_CASE(verify),
  1848. TEST_CASE(no_verify),
  1849. TEST_CASE(discovery),
  1850. TEST_CASE(lv2_path),
  1851. TEST_CASE(classes),
  1852. TEST_CASE(plugin),
  1853. TEST_CASE(project),
  1854. TEST_CASE(no_author),
  1855. TEST_CASE(project_no_author),
  1856. TEST_CASE(preset),
  1857. TEST_CASE(prototype),
  1858. TEST_CASE(port),
  1859. TEST_CASE(ui),
  1860. TEST_CASE(bad_port_symbol),
  1861. TEST_CASE(bad_port_index),
  1862. TEST_CASE(bad_port_index),
  1863. TEST_CASE(string),
  1864. TEST_CASE(world),
  1865. TEST_CASE(state),
  1866. TEST_CASE(reload_bundle),
  1867. TEST_CASE(replace_version),
  1868. TEST_CASE(get_symbol),
  1869. { NULL, NULL }
  1870. };
  1871. static void
  1872. run_tests(void)
  1873. {
  1874. int i;
  1875. for (i = 0; tests[i].title; i++) {
  1876. printf("*** Test %s\n", tests[i].title);
  1877. if (!tests[i].func()) {
  1878. printf("\nTest failed\n");
  1879. /* test case that wasn't able to be executed at all counts as 1 test + 1 error */
  1880. error_count++;
  1881. test_count++;
  1882. }
  1883. unload_bundle();
  1884. cleanup();
  1885. }
  1886. }
  1887. int
  1888. main(int argc, char* argv[])
  1889. {
  1890. if (argc != 1) {
  1891. printf("Syntax: %s\n", argv[0]);
  1892. return 0;
  1893. }
  1894. setenv("LANG", "C", 1);
  1895. init_tests();
  1896. run_tests();
  1897. cleanup();
  1898. printf("\n*** Test Results: %d tests, %d errors\n\n", test_count, error_count);
  1899. return error_count ? 1 : 0;
  1900. }