summaryrefslogtreecommitdiffstats
path: root/test/test_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_state.c')
-rw-r--r--test/test_state.c1735
1 files changed, 930 insertions, 805 deletions
diff --git a/test/test_state.c b/test/test_state.c
index a9260b9..67325d2 100644
--- a/test/test_state.c
+++ b/test/test_state.c
@@ -1,38 +1,25 @@
-/*
- Copyright 2007-2020 David Robillard <http://drobilla.net>
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+// Copyright 2007-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#undef NDEBUG
#include "lilv_test_uri_map.h"
#include "lilv_test_utils.h"
-#include "../src/filesystem.h"
-#include "../src/lilv_internal.h"
-
#include "lilv/lilv.h"
#include "lv2/core/lv2.h"
#include "lv2/state/state.h"
#include "lv2/urid/urid.h"
#include "serd/serd.h"
+#include "zix/allocator.h"
+#include "zix/filesystem.h"
+#include "zix/path.h"
#ifdef _WIN32
-# include <direct.h>
-# define mkdir(path, flags) _mkdir(path)
+# include <direct.h>
+# define mkdir(path, flags) _mkdir(path)
#else
-# include <sys/stat.h>
+# include <sys/stat.h>
#endif
#include <assert.h>
@@ -44,143 +31,149 @@
#define TEST_PLUGIN_URI "http://example.org/lilv-test-plugin"
-typedef struct
-{
- LilvTestEnv* env;
- LilvTestUriMap uri_map;
- LV2_URID_Map map;
- LV2_Feature map_feature;
- LV2_URID_Unmap unmap;
- LV2_Feature unmap_feature;
- LV2_State_Free_Path free_path;
- LV2_Feature free_path_feature;
- const LV2_Feature* features[4];
- LV2_URID atom_Float;
- float in;
- float out;
- float control;
+typedef struct {
+ LilvTestEnv* env;
+ LilvTestUriMap uri_map;
+ LV2_URID_Map map;
+ LV2_Feature map_feature;
+ LV2_URID_Unmap unmap;
+ LV2_Feature unmap_feature;
+ LV2_State_Free_Path free_path;
+ LV2_Feature free_path_feature;
+ const LV2_Feature* features[4];
+ LV2_URID atom_Float;
+ float in;
+ float out;
+ float control;
} TestContext;
-typedef struct
-{
- char* top; ///< Temporary directory that contains everything
- char* shared; ///< Common parent for shared directoryes (top/shared)
- char* scratch; ///< Scratch file directory (top/shared/scratch)
- char* copy; ///< Copy directory (top/shared/scratch)
- char* link; ///< Link directory (top/shared/scratch)
+typedef struct {
+ char* top; ///< Temporary directory that contains everything
+ char* shared; ///< Common parent for shared directoryes (top/shared)
+ char* scratch; ///< Scratch file directory (top/shared/scratch)
+ char* copy; ///< Copy directory (top/shared/scratch)
+ char* link; ///< Link directory (top/shared/scratch)
} TestDirectories;
static void
lilv_free_path(LV2_State_Free_Path_Handle handle, char* path)
{
- (void)handle;
+ (void)handle;
- lilv_free(path);
+ lilv_free(path);
}
static TestContext*
test_context_new(void)
{
- TestContext* ctx = (TestContext*)calloc(1, sizeof(TestContext));
-
- lilv_test_uri_map_init(&ctx->uri_map);
-
- ctx->env = lilv_test_env_new();
- ctx->map.handle = &ctx->uri_map;
- ctx->map.map = map_uri;
- ctx->map_feature.URI = LV2_URID_MAP_URI;
- ctx->map_feature.data = &ctx->map;
- ctx->unmap.handle = &ctx->uri_map;
- ctx->unmap.unmap = unmap_uri;
- ctx->unmap_feature.URI = LV2_URID_UNMAP_URI;
- ctx->unmap_feature.data = &ctx->unmap;
- ctx->free_path.free_path = lilv_free_path;
- ctx->free_path_feature.URI = LV2_STATE__freePath;
- ctx->free_path_feature.data = &ctx->free_path;
- ctx->features[0] = &ctx->map_feature;
- ctx->features[1] = &ctx->unmap_feature;
- ctx->features[2] = &ctx->free_path_feature;
- ctx->features[3] = NULL;
-
- ctx->atom_Float =
- map_uri(&ctx->uri_map, "http://lv2plug.in/ns/ext/atom#Float");
-
- ctx->in = 1.0;
- ctx->out = 42.0;
- ctx->control = 1234.0;
-
- return ctx;
+ TestContext* ctx = (TestContext*)calloc(1, sizeof(TestContext));
+
+ lilv_test_uri_map_init(&ctx->uri_map);
+
+ ctx->env = lilv_test_env_new();
+ ctx->map.handle = &ctx->uri_map;
+ ctx->map.map = map_uri;
+ ctx->map_feature.URI = LV2_URID_MAP_URI;
+ ctx->map_feature.data = &ctx->map;
+ ctx->unmap.handle = &ctx->uri_map;
+ ctx->unmap.unmap = unmap_uri;
+ ctx->unmap_feature.URI = LV2_URID_UNMAP_URI;
+ ctx->unmap_feature.data = &ctx->unmap;
+ ctx->free_path.free_path = lilv_free_path;
+ ctx->free_path_feature.URI = LV2_STATE__freePath;
+ ctx->free_path_feature.data = &ctx->free_path;
+ ctx->features[0] = &ctx->map_feature;
+ ctx->features[1] = &ctx->unmap_feature;
+ ctx->features[2] = &ctx->free_path_feature;
+ ctx->features[3] = NULL;
+
+ ctx->atom_Float =
+ map_uri(&ctx->uri_map, "http://lv2plug.in/ns/ext/atom#Float");
+
+ ctx->in = 1.0;
+ ctx->out = 42.0;
+ ctx->control = 1234.0;
+
+ return ctx;
}
static void
test_context_free(TestContext* ctx)
{
- lilv_test_uri_map_clear(&ctx->uri_map);
- lilv_test_env_free(ctx->env);
- free(ctx);
+ lilv_test_uri_map_clear(&ctx->uri_map);
+ lilv_test_env_free(ctx->env);
+ free(ctx);
}
static TestDirectories
create_test_directories(void)
{
- TestDirectories dirs;
+ TestDirectories dirs;
- char* const top = lilv_create_temporary_directory("lilv_XXXXXX");
- assert(top);
+ char* const top = lilv_create_temporary_directory("lilv_XXXXXX");
+ assert(top);
- /* On MacOS, temporary directories from mkdtemp involve symlinks, so
- resolve it here so that path comparisons in tests work. */
+ /* On MacOS, temporary directories from mkdtemp involve symlinks, so
+ resolve it here so that path comparisons in tests work. */
- dirs.top = lilv_path_canonical(top);
- dirs.shared = lilv_path_join(dirs.top, "shared");
- dirs.scratch = lilv_path_join(dirs.shared, "scratch");
- dirs.copy = lilv_path_join(dirs.shared, "copy");
- dirs.link = lilv_path_join(dirs.shared, "link");
+ dirs.top = zix_canonical_path(NULL, top);
+ dirs.shared = zix_path_join(NULL, dirs.top, "shared");
+ dirs.scratch = zix_path_join(NULL, dirs.shared, "scratch");
+ dirs.copy = zix_path_join(NULL, dirs.shared, "copy");
+ dirs.link = zix_path_join(NULL, dirs.shared, "link");
- assert(!mkdir(dirs.shared, 0700));
- assert(!mkdir(dirs.scratch, 0700));
- assert(!mkdir(dirs.copy, 0700));
- assert(!mkdir(dirs.link, 0700));
+ assert(dirs.top);
+ assert(dirs.shared);
+ assert(dirs.scratch);
+ assert(dirs.copy);
+ assert(dirs.link);
- free(top);
+ assert(!mkdir(dirs.shared, 0700));
+ assert(!mkdir(dirs.scratch, 0700));
+ assert(!mkdir(dirs.copy, 0700));
+ assert(!mkdir(dirs.link, 0700));
- return dirs;
+ free(top);
+
+ return dirs;
}
static TestDirectories
no_test_directories(void)
{
- TestDirectories dirs = {NULL, NULL, NULL, NULL, NULL};
+ TestDirectories dirs = {NULL, NULL, NULL, NULL, NULL};
- return dirs;
+ return dirs;
}
static void
remove_file(const char* path, const char* name, void* data)
{
- char* const full_path = lilv_path_join(path, name);
- assert(!lilv_remove(full_path));
- free(full_path);
+ (void)data;
+
+ char* const full_path = zix_path_join(NULL, path, name);
+ assert(!zix_remove(full_path));
+ free(full_path);
}
static void
cleanup_test_directories(const TestDirectories dirs)
{
- lilv_dir_for_each(dirs.scratch, NULL, remove_file);
- lilv_dir_for_each(dirs.copy, NULL, remove_file);
- lilv_dir_for_each(dirs.link, NULL, remove_file);
-
- assert(!lilv_remove(dirs.link));
- assert(!lilv_remove(dirs.copy));
- assert(!lilv_remove(dirs.scratch));
- assert(!lilv_remove(dirs.shared));
- assert(!lilv_remove(dirs.top));
-
- free(dirs.link);
- free(dirs.copy);
- free(dirs.scratch);
- free(dirs.shared);
- free(dirs.top);
+ zix_dir_for_each(dirs.scratch, NULL, remove_file);
+ zix_dir_for_each(dirs.copy, NULL, remove_file);
+ zix_dir_for_each(dirs.link, NULL, remove_file);
+
+ assert(!zix_remove(dirs.link));
+ assert(!zix_remove(dirs.copy));
+ assert(!zix_remove(dirs.scratch));
+ assert(!zix_remove(dirs.shared));
+ assert(!zix_remove(dirs.top));
+
+ zix_free(NULL, dirs.link);
+ zix_free(NULL, dirs.copy);
+ zix_free(NULL, dirs.scratch);
+ zix_free(NULL, dirs.shared);
+ free(dirs.top);
}
static const void*
@@ -189,27 +182,30 @@ get_port_value(const char* port_symbol,
uint32_t* size,
uint32_t* type)
{
- TestContext* ctx = (TestContext*)user_data;
-
- if (!strcmp(port_symbol, "input")) {
- *size = sizeof(float);
- *type = ctx->atom_Float;
- return &ctx->in;
- } else if (!strcmp(port_symbol, "output")) {
- *size = sizeof(float);
- *type = ctx->atom_Float;
- return &ctx->out;
- } else if (!strcmp(port_symbol, "control")) {
- *size = sizeof(float);
- *type = ctx->atom_Float;
- return &ctx->control;
- } else {
- fprintf(stderr,
- "error: get_port_value for nonexistent port `%s'\n",
- port_symbol);
- *size = *type = 0;
- return NULL;
- }
+ TestContext* ctx = (TestContext*)user_data;
+
+ if (!strcmp(port_symbol, "input")) {
+ *size = sizeof(float);
+ *type = ctx->atom_Float;
+ return &ctx->in;
+ }
+
+ if (!strcmp(port_symbol, "output")) {
+ *size = sizeof(float);
+ *type = ctx->atom_Float;
+ return &ctx->out;
+ }
+
+ if (!strcmp(port_symbol, "control")) {
+ *size = sizeof(float);
+ *type = ctx->atom_Float;
+ return &ctx->control;
+ }
+
+ fprintf(
+ stderr, "error: get_port_value for nonexistent port `%s'\n", port_symbol);
+ *size = *type = 0;
+ return NULL;
}
static void
@@ -219,50 +215,48 @@ set_port_value(const char* port_symbol,
uint32_t size,
uint32_t type)
{
- TestContext* ctx = (TestContext*)user_data;
-
- if (!strcmp(port_symbol, "input")) {
- ctx->in = *(const float*)value;
- } else if (!strcmp(port_symbol, "output")) {
- ctx->out = *(const float*)value;
- } else if (!strcmp(port_symbol, "control")) {
- ctx->control = *(const float*)value;
- } else {
- fprintf(stderr,
- "error: set_port_value for nonexistent port `%s'\n",
- port_symbol);
- }
+ (void)size;
+ (void)type;
+
+ TestContext* ctx = (TestContext*)user_data;
+
+ if (!strcmp(port_symbol, "input")) {
+ ctx->in = *(const float*)value;
+ } else if (!strcmp(port_symbol, "output")) {
+ ctx->out = *(const float*)value;
+ } else if (!strcmp(port_symbol, "control")) {
+ ctx->control = *(const float*)value;
+ } else {
+ fprintf(
+ stderr, "error: set_port_value for nonexistent port `%s'\n", port_symbol);
+ }
}
static char*
make_scratch_path(LV2_State_Make_Path_Handle handle, const char* path)
{
- TestDirectories* dirs = (TestDirectories*)handle;
+ TestDirectories* dirs = (TestDirectories*)handle;
- return lilv_path_join(dirs->scratch, path);
+ return zix_path_join(NULL, dirs->scratch, path);
}
static const LilvPlugin*
load_test_plugin(const TestContext* const ctx)
{
- LilvWorld* world = ctx->env->world;
- uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(LILV_TEST_BUNDLE);
- SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true);
- LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf);
- LilvNode* plugin_uri = lilv_new_uri(world, TEST_PLUGIN_URI);
+ LilvWorld* world = ctx->env->world;
+ LilvNode* bundle_uri = lilv_new_file_uri(world, NULL, LILV_TEST_BUNDLE);
+ LilvNode* plugin_uri = lilv_new_uri(world, TEST_PLUGIN_URI);
- lilv_world_load_bundle(world, bundle_uri);
+ lilv_world_load_bundle(world, bundle_uri);
- const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
- const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri);
- lilv_node_free(plugin_uri);
- lilv_node_free(bundle_uri);
- serd_node_free(&bundle);
- free(abs_bundle);
+ lilv_node_free(plugin_uri);
+ lilv_node_free(bundle_uri);
- assert(plugin);
- return plugin;
+ assert(plugin);
+ return plugin;
}
static LilvState*
@@ -272,735 +266,866 @@ state_from_instance(const LilvPlugin* const plugin,
const TestDirectories* const dirs,
const char* const bundle_path)
{
- return lilv_state_new_from_instance(plugin,
- instance,
- &ctx->map,
- dirs->scratch,
- dirs->copy,
- dirs->link,
- bundle_path,
- get_port_value,
- ctx,
- 0,
- NULL);
+ return lilv_state_new_from_instance(plugin,
+ instance,
+ &ctx->map,
+ dirs->scratch,
+ dirs->copy,
+ dirs->link,
+ bundle_path,
+ get_port_value,
+ ctx,
+ 0,
+ NULL);
}
static void
test_instance_state(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
- assert(instance);
+ assert(instance);
- // Get instance state
- LilvState* const state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
+ // Get instance state
+ LilvState* const state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
- // Check that state contains properties saved by the plugin
- assert(lilv_state_get_num_properties(state) == 8);
+ // Check that state contains properties saved by the plugin
+ assert(lilv_state_get_num_properties(state) == 8);
- // Check that state has no URI
- assert(!lilv_state_get_uri(state));
+ // Check that state has no URI
+ assert(!lilv_state_get_uri(state));
- // Check that state can't be saved without a URI
- assert(!lilv_state_to_string(
- ctx->env->world, &ctx->map, &ctx->unmap, state, NULL, NULL));
+ // Check that state can't be saved without a URI
+ assert(!lilv_state_to_string(
+ ctx->env->world, &ctx->map, &ctx->unmap, state, NULL, NULL));
- // Check that we can't delete unsaved state
- assert(lilv_state_delete(ctx->env->world, state));
+ // Check that we can't delete unsaved state
+ assert(lilv_state_delete(ctx->env->world, state));
- lilv_state_free(state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ lilv_state_free(state);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
}
static void
test_equal(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
- assert(instance);
+ assert(instance);
- // Get instance state
- LilvState* const state_1 =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
+ // Get instance state
+ LilvState* const state_1 =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
- // Get another instance state
- LilvState* const state_2 =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
+ // Get another instance state
+ LilvState* const state_2 =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
- // Ensure they are equal
- assert(lilv_state_equals(state_1, state_2));
+ // Ensure they are equal
+ assert(lilv_state_equals(state_1, state_2));
- // Set a label on the second state
- assert(lilv_state_get_label(state_2) == NULL);
- lilv_state_set_label(state_2, "Test State Old Label");
+ // Set a label on the second state
+ assert(lilv_state_get_label(state_2) == NULL);
+ lilv_state_set_label(state_2, "Test State Old Label");
- // Ensure they are no longer equal
- assert(!lilv_state_equals(state_1, state_2));
+ // Ensure they are no longer equal
+ assert(!lilv_state_equals(state_1, state_2));
- lilv_state_free(state_2);
- lilv_state_free(state_1);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ lilv_state_free(state_2);
+ lilv_state_free(state_1);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
}
static void
test_changed_plugin_data(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
-
- assert(instance);
-
- // Get initial state
- LilvState* const initial_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Run plugin to change internal state
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Get a new instance state (which should now differ)
- LilvState* const changed_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Ensure state has changed
- assert(!lilv_state_equals(initial_state, changed_state));
-
- lilv_state_free(changed_state);
- lilv_state_free(initial_state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+
+ assert(instance);
+
+ // Get initial state
+ LilvState* const initial_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Run plugin to change internal state
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Get a new instance state (which should now differ)
+ LilvState* const changed_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Ensure state has changed
+ assert(!lilv_state_equals(initial_state, changed_state));
+
+ lilv_state_free(changed_state);
+ lilv_state_free(initial_state);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
}
static void
test_changed_metadata(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- LV2_URID_Map* const map = &ctx->map;
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
-
- assert(instance);
-
- // Get initial state
- LilvState* const initial_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Save initial state to a string
- char* const initial_string =
- lilv_state_to_string(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- initial_state,
- "http://example.org/initial",
- NULL);
-
- // Get another state
- LilvState* const changed_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Set a metadata property
- const LV2_URID key = map->map(map->handle, "http://example.org/extra");
- const int32_t value = 1;
- const LV2_URID type =
- map->map(map->handle, "http://lv2plug.in/ns/ext/atom#Int");
- lilv_state_set_metadata(changed_state,
- key,
- &value,
- sizeof(value),
- type,
- LV2_STATE_IS_PORTABLE | LV2_STATE_IS_POD);
-
- // Save changed state to a string
- char* const changed_string =
- lilv_state_to_string(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- changed_state,
- "http://example.org/changed",
- NULL);
-
- // Ensure that strings differ (metadata does not affect state equality)
- assert(strcmp(initial_string, changed_string));
-
- free(changed_string);
- lilv_state_free(changed_state);
- free(initial_string);
- lilv_state_free(initial_state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ LV2_URID_Map* const map = &ctx->map;
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+
+ assert(instance);
+
+ // Get initial state
+ LilvState* const initial_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Save initial state to a string
+ char* const initial_string =
+ lilv_state_to_string(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ initial_state,
+ "http://example.org/initial",
+ NULL);
+
+ // Get another state
+ LilvState* const changed_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Set a metadata property
+ const LV2_URID key = map->map(map->handle, "http://example.org/extra");
+ const int32_t value = 1;
+ const LV2_URID type =
+ map->map(map->handle, "http://lv2plug.in/ns/ext/atom#Int");
+ lilv_state_set_metadata(changed_state,
+ key,
+ &value,
+ sizeof(value),
+ type,
+ LV2_STATE_IS_PORTABLE | LV2_STATE_IS_POD);
+
+ // Save changed state to a string
+ char* const changed_string =
+ lilv_state_to_string(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ changed_state,
+ "http://example.org/changed",
+ NULL);
+
+ // Ensure that strings differ (metadata does not affect state equality)
+ assert(strcmp(initial_string, changed_string));
+
+ free(changed_string);
+ lilv_state_free(changed_state);
+ free(initial_string);
+ lilv_state_free(initial_state);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
}
static void
test_to_string(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
-
- assert(instance);
-
- // Get initial state
- LilvState* const initial_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Run plugin to change internal state
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Restore instance state to original state
- lilv_state_restore(initial_state, instance, set_port_value, ctx, 0, NULL);
-
- // Take a new snapshot of the state
- LilvState* const restored =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Check that new state matches the initial state
- assert(lilv_state_equals(initial_state, restored));
-
- lilv_state_free(restored);
- lilv_state_free(initial_state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+
+ assert(instance);
+
+ // Get initial state
+ LilvState* const initial_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Run plugin to change internal state
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Restore instance state to original state
+ lilv_state_restore(initial_state, instance, set_port_value, ctx, 0, NULL);
+
+ // Take a new snapshot of the state
+ LilvState* const restored =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Check that new state matches the initial state
+ assert(lilv_state_equals(initial_state, restored));
+
+ lilv_state_free(restored);
+ lilv_state_free(initial_state);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
}
static void
test_string_round_trip(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = no_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
-
- assert(instance);
-
- // Get initial state
- LilvState* const initial_state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Save state to a string
- char* const string = lilv_state_to_string(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- initial_state,
- "http://example.org/string",
- NULL);
-
- // Restore from string
- LilvState* const restored =
- lilv_state_new_from_string(ctx->env->world, &ctx->map, string);
-
- // Ensure they are equal
- assert(lilv_state_equals(initial_state, restored));
-
- // Check that the restored state refers to the correct plugin
- const LilvNode* state_plugin_uri = lilv_state_get_plugin_uri(restored);
- assert(!strcmp(lilv_node_as_string(state_plugin_uri), TEST_PLUGIN_URI));
-
- lilv_state_free(restored);
- free(string);
- lilv_state_free(initial_state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = no_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+
+ assert(instance);
+
+ // Get initial state
+ LilvState* const initial_state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Save state to a string
+ char* const string = lilv_state_to_string(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ initial_state,
+ "http://example.org/string",
+ NULL);
+
+ // Restore from string
+ LilvState* const restored =
+ lilv_state_new_from_string(ctx->env->world, &ctx->map, string);
+
+ // Ensure they are equal
+ assert(lilv_state_equals(initial_state, restored));
+
+ // Check that the restored state refers to the correct plugin
+ const LilvNode* state_plugin_uri = lilv_state_get_plugin_uri(restored);
+ assert(!strcmp(lilv_node_as_string(state_plugin_uri), TEST_PLUGIN_URI));
+
+ lilv_state_free(restored);
+ free(string);
+ lilv_state_free(initial_state);
+ lilv_instance_free(instance);
+ test_context_free(ctx);
+}
+
+static SerdStatus
+count_sink(void* const handle,
+ const SerdStatementFlags flags,
+ const SerdNode* const graph,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const object_datatype,
+ const SerdNode* const object_lang)
+{
+ (void)flags;
+ (void)graph;
+ (void)subject;
+ (void)predicate;
+ (void)object;
+ (void)object_datatype;
+ (void)object_lang;
+
+ size_t* const n_statements = (size_t*)handle;
+
+ ++(*n_statements);
+
+ return SERD_SUCCESS;
+}
+
+static size_t
+count_statements(const char* path)
+{
+ size_t n_statements = 0;
+
+ SerdReader* reader = serd_reader_new(
+ SERD_TURTLE, &n_statements, NULL, NULL, NULL, count_sink, NULL);
+
+ SerdNode uri = serd_node_new_file_uri((const uint8_t*)path, NULL, NULL, true);
+
+ assert(uri.buf);
+ assert(!serd_reader_read_file(reader, (const uint8_t*)uri.buf));
+
+ serd_node_free(&uri);
+ serd_reader_free(reader);
+
+ return n_statements;
}
static void
test_to_files(void)
{
- TestContext* const ctx = test_context_new();
- TestDirectories dirs = create_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
-
- LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
- LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
-
- const LV2_Feature* const instance_features[] = {&ctx->map_feature,
- &ctx->free_path_feature,
- &make_path_feature,
- NULL};
-
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, instance_features);
-
- assert(instance);
-
- // Run plugin to generate some recording file data
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- lilv_instance_run(instance, 2);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Check that the test plugin has made its recording scratch file
- char* const recfile_path = lilv_path_join(dirs.scratch, "recfile");
- assert(lilv_path_exists(recfile_path));
-
- // Get state
- char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2");
- LilvState* const state_1 =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path);
-
- // Check that state contains properties saved by the plugin (with files)
- assert(lilv_state_get_num_properties(state_1) == 10);
-
- // Check that a snapshop of the recfile was created
- char* const recfile_copy_1 = lilv_path_join(dirs.copy, "recfile");
- assert(lilv_path_exists(recfile_copy_1));
-
- // Set a label and save state to a bundle
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state_1,
- "http://example.org/state1",
- bundle_1_path,
- "state.ttl"));
-
- // Check that a link to the recfile exists in the saved bundle
- char* const recfile_link_1 = lilv_path_join(bundle_1_path, "recfile");
- assert(lilv_path_exists(recfile_link_1));
-
- // Check that link points to the corresponding copy
- char* const recfile_link_1_real = lilv_path_canonical(recfile_link_1);
- assert(!strcmp(recfile_link_1_real, recfile_copy_1));
-
- // Run plugin again to modify recording file data
- lilv_instance_run(instance, 2);
-
- // Get updated state
- char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2");
- LilvState* const state_2 =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
-
- // Save updated state to a bundle
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state_2,
- NULL,
- bundle_2_path,
- "state.ttl"));
-
- // Check that a new snapshop of the recfile was created
- char* const recfile_copy_2 = lilv_path_join(dirs.copy, "recfile.2");
- assert(lilv_path_exists(recfile_copy_2));
-
- // Check that a link to the recfile exists in the updated bundle
- char* const recfile_link_2 = lilv_path_join(bundle_2_path, "recfile");
- assert(lilv_path_exists(recfile_link_2));
-
- // Check that link points to the corresponding copy
- char* const recfile_link_2_real = lilv_path_canonical(recfile_link_2);
- assert(!strcmp(recfile_link_2_real, recfile_copy_2));
-
- lilv_dir_for_each(bundle_2_path, NULL, remove_file);
- lilv_dir_for_each(bundle_1_path, NULL, remove_file);
- lilv_remove(bundle_2_path);
- lilv_remove(bundle_1_path);
- cleanup_test_directories(dirs);
-
- free(recfile_link_2_real);
- free(recfile_link_2);
- free(recfile_copy_2);
- lilv_state_free(state_2);
- free(bundle_2_path);
- free(recfile_link_1_real);
- free(recfile_link_1);
- free(recfile_copy_1);
- lilv_state_free(state_1);
- free(bundle_1_path);
- free(recfile_path);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+
+ LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
+ LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
+
+ const LV2_Feature* const instance_features[] = {
+ &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL};
+
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, instance_features);
+
+ assert(instance);
+
+ // Run plugin to generate some recording file data
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ lilv_instance_run(instance, 2);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Check that the test plugin has made its recording scratch file
+ char* const recfile_path = zix_path_join(NULL, dirs.scratch, "recfile");
+ assert(zix_file_type(recfile_path) == ZIX_FILE_TYPE_REGULAR);
+
+ // Get state
+ char* const bundle_1_path = zix_path_join(NULL, dirs.top, "state1.lv2");
+ LilvState* const state_1 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path);
+
+ // Check that state contains properties saved by the plugin (with files)
+ assert(lilv_state_get_num_properties(state_1) == 10);
+
+ // Check that a snapshop of the recfile was created
+ char* const recfile_copy_1 = zix_path_join(NULL, dirs.copy, "recfile");
+ assert(zix_file_type(recfile_copy_1) == ZIX_FILE_TYPE_REGULAR);
+
+ // Save state to a bundle
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_1,
+ "http://example.org/state1",
+ bundle_1_path,
+ "state.ttl"));
+
+ // Check that a manifest exists
+ char* const manifest_path =
+ zix_path_join(NULL, bundle_1_path, "manifest.ttl");
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
+
+ // Check that the expected statements are in the manifest file
+ assert(count_statements(manifest_path) == 3);
+
+ // Check that a link to the recfile exists in the saved bundle
+ char* const recfile_link_1 = zix_path_join(NULL, bundle_1_path, "recfile");
+ assert(zix_file_type(recfile_link_1) == ZIX_FILE_TYPE_REGULAR);
+#ifndef _WIN32
+ assert(zix_symlink_type(recfile_link_1) == ZIX_FILE_TYPE_SYMLINK);
+#endif
+
+ // Check that link points to the corresponding copy
+ assert(zix_file_equals(NULL, recfile_link_1, recfile_copy_1));
+
+ // Run plugin again to modify recording file data
+ lilv_instance_run(instance, 2);
+
+ // Get updated state
+ char* const bundle_2_path = zix_path_join(NULL, dirs.top, "state2.lv2");
+ LilvState* const state_2 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
+
+ // Save updated state to a bundle
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_2,
+ NULL,
+ bundle_2_path,
+ "state.ttl"));
+
+ // Check that a new snapshop of the recfile was created
+ char* const recfile_copy_2 = zix_path_join(NULL, dirs.copy, "recfile.2");
+ assert(zix_file_type(recfile_copy_2) == ZIX_FILE_TYPE_REGULAR);
+
+ // Check that a link to the recfile exists in the updated bundle
+ char* const recfile_link_2 = zix_path_join(NULL, bundle_2_path, "recfile");
+ assert(zix_file_type(recfile_link_2) == ZIX_FILE_TYPE_REGULAR);
+#ifndef _WIN32
+ assert(zix_symlink_type(recfile_link_2) == ZIX_FILE_TYPE_SYMLINK);
+#endif
+
+ // Check that link points to the corresponding copy
+ assert(zix_file_equals(NULL, recfile_link_2, recfile_copy_2));
+
+ lilv_instance_free(instance);
+ zix_dir_for_each(bundle_2_path, NULL, remove_file);
+ zix_dir_for_each(bundle_1_path, NULL, remove_file);
+ assert(!zix_remove(bundle_2_path));
+ assert(!zix_remove(bundle_1_path));
+ cleanup_test_directories(dirs);
+
+ zix_free(NULL, recfile_link_2);
+ zix_free(NULL, recfile_copy_2);
+ lilv_state_free(state_2);
+ zix_free(NULL, bundle_2_path);
+ zix_free(NULL, recfile_link_1);
+ zix_free(NULL, manifest_path);
+ zix_free(NULL, recfile_copy_1);
+ lilv_state_free(state_1);
+ zix_free(NULL, bundle_1_path);
+ zix_free(NULL, recfile_path);
+ test_context_free(ctx);
+}
+
+static void
+test_multi_save(void)
+{
+ TestContext* const ctx = test_context_new();
+ TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+
+ LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
+ LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
+
+ const LV2_Feature* const instance_features[] = {
+ &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL};
+
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, instance_features);
+
+ assert(instance);
+
+ // Get state
+ char* const bundle_1_path = zix_path_join(NULL, dirs.top, "state1.lv2");
+ LilvState* const state_1 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path);
+
+ // Save state to a bundle
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_1,
+ "http://example.org/state1",
+ bundle_1_path,
+ "state.ttl"));
+
+ // Check that a manifest exists
+ char* const manifest_path =
+ zix_path_join(NULL, bundle_1_path, "manifest.ttl");
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
+
+ // Check that the state file exists
+ char* const state_path = zix_path_join(NULL, bundle_1_path, "state.ttl");
+ assert(zix_file_type(state_path) == ZIX_FILE_TYPE_REGULAR);
+
+ // Check that the expected statements are in the files
+ assert(count_statements(manifest_path) == 3);
+ assert(count_statements(state_path) == 21);
+
+ // Save state again to the same bundle
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_1,
+ "http://example.org/state1",
+ bundle_1_path,
+ "state.ttl"));
+
+ // Check that everything is the same
+ assert(zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR);
+ assert(zix_file_type(state_path) == ZIX_FILE_TYPE_REGULAR);
+ assert(count_statements(manifest_path) == 3);
+ assert(count_statements(state_path) == 21);
+
+ lilv_instance_free(instance);
+ zix_dir_for_each(bundle_1_path, NULL, remove_file);
+ zix_remove(bundle_1_path);
+ cleanup_test_directories(dirs);
+
+ free(state_path);
+ free(manifest_path);
+ lilv_state_free(state_1);
+ free(bundle_1_path);
+ test_context_free(ctx);
}
static void
test_files_round_trip(void)
{
- TestContext* const ctx = test_context_new();
- TestDirectories dirs = create_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
-
- LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
- LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
-
- const LV2_Feature* const instance_features[] = {&ctx->map_feature,
- &ctx->free_path_feature,
- &make_path_feature,
- NULL};
-
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, instance_features);
-
- assert(instance);
-
- // Run plugin to generate some recording file data
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- lilv_instance_run(instance, 2);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Save first state to a bundle
- char* const bundle_1_1_path = lilv_path_join(dirs.top, "state1_1.lv2");
- LilvState* const state_1_1 =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_1_1_path);
-
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state_1_1,
- NULL,
- bundle_1_1_path,
- "state.ttl"));
-
- // Save first state to another bundle
- char* const bundle_1_2_path = lilv_path_join(dirs.top, "state1_2.lv2");
- LilvState* const state_1_2 =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_1_2_path);
-
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state_1_2,
- NULL,
- bundle_1_2_path,
- "state.ttl"));
-
- // Load both first state bundles and check that the results are equal
- char* const state_1_1_path = lilv_path_join(bundle_1_1_path, "state.ttl");
- char* const state_1_2_path = lilv_path_join(bundle_1_2_path, "state.ttl");
-
- LilvState* state_1_1_loaded = lilv_state_new_from_file(ctx->env->world,
- &ctx->map,
- NULL,
- state_1_1_path);
-
- LilvState* state_1_2_loaded = lilv_state_new_from_file(ctx->env->world,
- &ctx->map,
- NULL,
- state_1_2_path);
-
- assert(state_1_1_loaded);
- assert(state_1_2_loaded);
- assert(lilv_state_equals(state_1_1_loaded, state_1_2_loaded));
-
- // Run plugin again to modify recording file data
- lilv_instance_run(instance, 2);
-
- // Save updated state to a bundle
- char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2");
- LilvState* const state_2 =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
-
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state_2,
- NULL,
- bundle_2_path,
- "state.ttl"));
-
- // Load updated state bundle and check that it differs from the others
- char* const state_2_path = lilv_path_join(bundle_2_path, "state.ttl");
-
- LilvState* state_2_loaded = lilv_state_new_from_file(ctx->env->world,
- &ctx->map,
- NULL,
- state_2_path);
-
- assert(state_2_loaded);
- assert(!lilv_state_equals(state_1_1_loaded, state_2_loaded));
-
- lilv_dir_for_each(bundle_1_1_path, NULL, remove_file);
- lilv_dir_for_each(bundle_1_2_path, NULL, remove_file);
- lilv_dir_for_each(bundle_2_path, NULL, remove_file);
- lilv_remove(bundle_1_1_path);
- lilv_remove(bundle_1_2_path);
- lilv_remove(bundle_2_path);
- cleanup_test_directories(dirs);
-
- lilv_state_free(state_2_loaded);
- free(state_2_path);
- lilv_state_free(state_2);
- free(bundle_2_path);
- lilv_state_free(state_1_2_loaded);
- lilv_state_free(state_1_1_loaded);
- free(state_1_2_path);
- free(state_1_1_path);
- lilv_state_free(state_1_2);
- free(bundle_1_2_path);
- lilv_state_free(state_1_1);
- free(bundle_1_1_path);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+
+ LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
+ LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
+
+ const LV2_Feature* const instance_features[] = {
+ &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL};
+
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, instance_features);
+
+ assert(instance);
+
+ // Run plugin to generate some recording file data
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ lilv_instance_run(instance, 2);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Save first state to a bundle
+ char* const bundle_1_1_path = zix_path_join(NULL, dirs.top, "state1_1.lv2");
+ LilvState* const state_1_1 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_1_1_path);
+
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_1_1,
+ NULL,
+ bundle_1_1_path,
+ "state.ttl"));
+
+ // Save first state to another bundle
+ char* const bundle_1_2_path = zix_path_join(NULL, dirs.top, "state1_2.lv2");
+ LilvState* const state_1_2 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_1_2_path);
+
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_1_2,
+ NULL,
+ bundle_1_2_path,
+ "state.ttl"));
+
+ // Load both first state bundles and check that the results are equal
+ char* const state_1_1_path =
+ zix_path_join(NULL, bundle_1_1_path, "state.ttl");
+ char* const state_1_2_path =
+ zix_path_join(NULL, bundle_1_2_path, "state.ttl");
+
+ LilvState* state_1_1_loaded =
+ lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_1_1_path);
+
+ LilvState* state_1_2_loaded =
+ lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_1_2_path);
+
+ assert(state_1_1_loaded);
+ assert(state_1_2_loaded);
+ assert(lilv_state_equals(state_1_1_loaded, state_1_2_loaded));
+
+ // Run plugin again to modify recording file data
+ lilv_instance_run(instance, 2);
+
+ // Save updated state to a bundle
+ char* const bundle_2_path = zix_path_join(NULL, dirs.top, "state2.lv2");
+ LilvState* const state_2 =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path);
+
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state_2,
+ NULL,
+ bundle_2_path,
+ "state.ttl"));
+
+ // Load updated state bundle and check that it differs from the others
+ char* const state_2_path = zix_path_join(NULL, bundle_2_path, "state.ttl");
+
+ LilvState* state_2_loaded =
+ lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_2_path);
+
+ assert(state_2_loaded);
+ assert(!lilv_state_equals(state_1_1_loaded, state_2_loaded));
+
+ lilv_instance_free(instance);
+ zix_dir_for_each(bundle_1_1_path, NULL, remove_file);
+ zix_dir_for_each(bundle_1_2_path, NULL, remove_file);
+ zix_dir_for_each(bundle_2_path, NULL, remove_file);
+ zix_remove(bundle_1_1_path);
+ zix_remove(bundle_1_2_path);
+ zix_remove(bundle_2_path);
+ cleanup_test_directories(dirs);
+
+ lilv_state_free(state_2_loaded);
+ free(state_2_path);
+ lilv_state_free(state_2);
+ free(bundle_2_path);
+ lilv_state_free(state_1_2_loaded);
+ lilv_state_free(state_1_1_loaded);
+ free(state_1_2_path);
+ free(state_1_1_path);
+ lilv_state_free(state_1_2);
+ free(bundle_1_2_path);
+ lilv_state_free(state_1_1);
+ free(bundle_1_1_path);
+ test_context_free(ctx);
}
static void
test_world_round_trip(void)
{
- TestContext* const ctx = test_context_new();
- LilvWorld* const world = ctx->env->world;
- TestDirectories dirs = create_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- static const char* const state_uri = "http://example.org/worldState";
-
- LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
- LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
-
- const LV2_Feature* const instance_features[] = {&ctx->map_feature,
- &ctx->free_path_feature,
- &make_path_feature,
- NULL};
-
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, instance_features);
-
- assert(instance);
-
- // Run plugin to generate some recording file data
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- lilv_instance_run(instance, 2);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Save state to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
- LilvState* const start_state =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
-
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- start_state,
- state_uri,
- bundle_path,
- "state.ttl"));
-
- // Load state bundle into world
- SerdNode bundle_uri =
- serd_node_new_file_uri((const uint8_t*)bundle_path, 0, 0, true);
- LilvNode* const bundle_node =
- lilv_new_uri(world, (const char*)bundle_uri.buf);
- LilvNode* const state_node = lilv_new_uri(world, state_uri);
- lilv_world_load_bundle(world, bundle_node);
- lilv_world_load_resource(world, state_node);
-
- // Ensure the state loaded from the world matches
- LilvState* const restored =
- lilv_state_new_from_world(world, &ctx->map, state_node);
- assert(lilv_state_equals(start_state, restored));
-
- // Unload state from world
- lilv_world_unload_resource(world, state_node);
- lilv_world_unload_bundle(world, bundle_node);
-
- // Ensure that it is no longer present
- assert(!lilv_state_new_from_world(world, &ctx->map, state_node));
-
- lilv_state_delete(world, restored);
- cleanup_test_directories(dirs);
-
- lilv_state_free(restored);
- lilv_node_free(state_node);
- lilv_node_free(bundle_node);
- serd_node_free(&bundle_uri);
- lilv_state_free(start_state);
- free(bundle_path);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ LilvWorld* const world = ctx->env->world;
+ TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ static const char* const state_uri = "http://example.org/worldState";
+
+ LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
+ LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
+
+ const LV2_Feature* const instance_features[] = {
+ &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL};
+
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, instance_features);
+
+ assert(instance);
+
+ // Run plugin to generate some recording file data
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ lilv_instance_run(instance, 2);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Save state to a bundle
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
+ LilvState* const start_state =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
+
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ start_state,
+ state_uri,
+ bundle_path,
+ "state.ttl"));
+
+ // Load state bundle into world
+ SerdNode bundle_uri =
+ serd_node_new_file_uri((const uint8_t*)bundle_path, 0, 0, true);
+ LilvNode* const bundle_node =
+ lilv_new_uri(world, (const char*)bundle_uri.buf);
+ LilvNode* const state_node = lilv_new_uri(world, state_uri);
+ lilv_world_load_bundle(world, bundle_node);
+ lilv_world_load_resource(world, state_node);
+
+ // Ensure the state loaded from the world matches
+ LilvState* const restored =
+ lilv_state_new_from_world(world, &ctx->map, state_node);
+ assert(lilv_state_equals(start_state, restored));
+
+ // Unload state from world
+ lilv_world_unload_resource(world, state_node);
+ lilv_world_unload_bundle(world, bundle_node);
+
+ // Ensure that it is no longer present
+ assert(!lilv_state_new_from_world(world, &ctx->map, state_node));
+
+ lilv_instance_free(instance);
+ lilv_state_delete(world, start_state);
+ cleanup_test_directories(dirs);
+
+ lilv_state_free(restored);
+ lilv_node_free(state_node);
+ lilv_node_free(bundle_node);
+ serd_node_free(&bundle_uri);
+ lilv_state_free(start_state);
+ free(bundle_path);
+ test_context_free(ctx);
}
static void
test_label_round_trip(void)
{
- TestContext* const ctx = test_context_new();
- const TestDirectories dirs = create_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
-
- assert(instance);
-
- // Get initial state
- LilvState* const state =
- state_from_instance(plugin, instance, ctx, &dirs, NULL);
-
- // Set a label
- lilv_state_set_label(state, "Monopoly on violence");
-
- // Save to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state,
- NULL,
- bundle_path,
- "state.ttl"));
-
- // Load bundle and check the label and that the states are equal
- char* const state_path = lilv_path_join(bundle_path, "state.ttl");
-
- LilvState* const loaded =
- lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_path);
-
- assert(loaded);
- assert(lilv_state_equals(state, loaded));
- assert(!strcmp(lilv_state_get_label(loaded), "Monopoly on violence"));
-
- lilv_state_delete(ctx->env->world, state);
- cleanup_test_directories(dirs);
-
- lilv_state_free(loaded);
- free(state_path);
- free(bundle_path);
- lilv_state_free(state);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ const TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, ctx->features);
+
+ assert(instance);
+
+ // Get initial state
+ LilvState* const state =
+ state_from_instance(plugin, instance, ctx, &dirs, NULL);
+
+ // Set a label
+ lilv_state_set_label(state, "Monopoly on violence");
+
+ // Save to a bundle
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state,
+ NULL,
+ bundle_path,
+ "state.ttl"));
+
+ // Load bundle and check the label and that the states are equal
+ char* const state_path = zix_path_join(NULL, bundle_path, "state.ttl");
+
+ LilvState* const loaded =
+ lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_path);
+
+ assert(loaded);
+ assert(lilv_state_equals(state, loaded));
+ assert(!strcmp(lilv_state_get_label(loaded), "Monopoly on violence"));
+
+ lilv_instance_free(instance);
+ lilv_state_delete(ctx->env->world, state);
+ cleanup_test_directories(dirs);
+
+ lilv_state_free(loaded);
+ free(state_path);
+ free(bundle_path);
+ lilv_state_free(state);
+ test_context_free(ctx);
}
static void
test_bad_subject(void)
{
- TestContext* const ctx = test_context_new();
- LilvNode* const string = lilv_new_string(ctx->env->world, "Not a URI");
+ TestContext* const ctx = test_context_new();
+ LilvNode* const string = lilv_new_string(ctx->env->world, "Not a URI");
+
+ LilvState* const file_state = lilv_state_new_from_file(
+ ctx->env->world, &ctx->map, string, "/I/do/not/matter");
+
+ assert(!file_state);
+
+ LilvState* const world_state =
+ lilv_state_new_from_world(ctx->env->world, &ctx->map, string);
- LilvState* const file_state = lilv_state_new_from_file(ctx->env->world,
- &ctx->map,
- string,
- "/I/do/not/matter");
+ assert(!world_state);
- assert(!file_state);
+ lilv_node_free(string);
+ test_context_free(ctx);
+}
- LilvState* const world_state =
- lilv_state_new_from_world(ctx->env->world, &ctx->map, string);
+static void
+test_missing_path(void)
+{
+ TestContext* const ctx = test_context_new();
+ LilvState* const state = lilv_state_new_from_file(
+ ctx->env->world, &ctx->map, NULL, "/does/not/exist");
- assert(!world_state);
+ assert(!state);
- lilv_node_free(string);
- test_context_free(ctx);
+ test_context_free(ctx);
}
static void
count_file(const char* path, const char* name, void* data)
{
- *(unsigned*)data += 1;
+ (void)path;
+ (void)name;
+
+ *(unsigned*)data += 1;
}
static void
test_delete(void)
{
- TestContext* const ctx = test_context_new();
- TestDirectories dirs = create_test_directories();
- const LilvPlugin* const plugin = load_test_plugin(ctx);
-
- LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
- LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
-
- const LV2_Feature* const instance_features[] = {&ctx->map_feature,
- &ctx->free_path_feature,
- &make_path_feature,
- NULL};
-
- LilvInstance* const instance =
- lilv_plugin_instantiate(plugin, 48000.0, instance_features);
-
- assert(instance);
-
- // Run plugin to generate some recording file data
- lilv_instance_activate(instance);
- lilv_instance_connect_port(instance, 0, &ctx->in);
- lilv_instance_connect_port(instance, 1, &ctx->out);
- lilv_instance_run(instance, 1);
- lilv_instance_run(instance, 2);
- assert(ctx->in == 1.0);
- assert(ctx->out == 1.0);
-
- // Save state to a bundle
- char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/");
- LilvState* const state =
- state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
-
- assert(!lilv_state_save(ctx->env->world,
- &ctx->map,
- &ctx->unmap,
- state,
- NULL,
- bundle_path,
- "state.ttl"));
-
- // Count the number of shared files before doing anything
- unsigned n_shared_files_before = 0;
- lilv_dir_for_each(dirs.shared, &n_shared_files_before, count_file);
-
- // Delete the state
- assert(!lilv_state_delete(ctx->env->world, state));
-
- // Ensure the number of shared files is the same after deletion
- unsigned n_shared_files_after = 0;
- lilv_dir_for_each(dirs.shared, &n_shared_files_after, count_file);
- assert(n_shared_files_before == n_shared_files_after);
-
- // Ensure the state directory has been deleted
- assert(!lilv_path_exists(bundle_path));
-
- cleanup_test_directories(dirs);
-
- lilv_state_free(state);
- free(bundle_path);
- lilv_instance_free(instance);
- test_context_free(ctx);
+ TestContext* const ctx = test_context_new();
+ TestDirectories dirs = create_test_directories();
+ const LilvPlugin* const plugin = load_test_plugin(ctx);
+
+ LV2_State_Make_Path make_path = {&dirs, make_scratch_path};
+ LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path};
+
+ const LV2_Feature* const instance_features[] = {
+ &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL};
+
+ LilvInstance* const instance =
+ lilv_plugin_instantiate(plugin, 48000.0, instance_features);
+
+ assert(instance);
+
+ // Run plugin to generate some recording file data
+ lilv_instance_activate(instance);
+ lilv_instance_connect_port(instance, 0, &ctx->in);
+ lilv_instance_connect_port(instance, 1, &ctx->out);
+ lilv_instance_run(instance, 1);
+ lilv_instance_run(instance, 2);
+ assert(ctx->in == 1.0);
+ assert(ctx->out == 1.0);
+
+ // Save state to a bundle
+ char* const bundle_path = zix_path_join(NULL, dirs.top, "state.lv2/");
+ LilvState* const state =
+ state_from_instance(plugin, instance, ctx, &dirs, bundle_path);
+
+ assert(!lilv_state_save(ctx->env->world,
+ &ctx->map,
+ &ctx->unmap,
+ state,
+ NULL,
+ bundle_path,
+ "state.ttl"));
+
+ // Count the number of shared files before doing anything
+ unsigned n_shared_files_before = 0;
+ zix_dir_for_each(dirs.shared, &n_shared_files_before, count_file);
+
+ lilv_instance_free(instance);
+
+ // Delete the state
+ assert(!lilv_state_delete(ctx->env->world, state));
+
+ // Ensure the number of shared files is the same after deletion
+ unsigned n_shared_files_after = 0;
+ zix_dir_for_each(dirs.shared, &n_shared_files_after, count_file);
+ assert(n_shared_files_before == n_shared_files_after);
+
+ // Ensure the state directory has been deleted
+ assert(zix_file_type(bundle_path) == ZIX_FILE_TYPE_NONE);
+
+ cleanup_test_directories(dirs);
+
+ lilv_state_free(state);
+ free(bundle_path);
+ test_context_free(ctx);
}
int
main(void)
{
- test_instance_state();
- test_equal();
- test_changed_plugin_data();
- test_changed_metadata();
- test_to_string();
- test_string_round_trip();
- test_to_files();
- test_files_round_trip();
- test_world_round_trip();
- test_label_round_trip();
- test_bad_subject();
- test_delete();
-
- return 0;
+ test_instance_state();
+ test_equal();
+ test_changed_plugin_data();
+ test_changed_metadata();
+ test_to_string();
+ test_string_round_trip();
+ test_to_files();
+ test_multi_save();
+ test_files_round_trip();
+ test_world_round_trip();
+ test_label_round_trip();
+ test_bad_subject();
+ test_missing_path();
+ test_delete();
+
+ return 0;
}