Commit ade58a75 authored by Hanspeter Portner's avatar Hanspeter Portner

add unit test for API.

parent 391e41c3
......@@ -13,6 +13,6 @@ install:
- sudo apt-get install -y libefl-dev libelementary-dev libsndfile1-dev cmake=2.8.12.2-3
- pushd lv2-1.10.0 && ./waf configure && ./waf build && sudo ./waf install && popd
before_script:
- mkdir build && pushd build && cmake -DCMAKE_C_FLAGS="-std=gnu99" .. && popd
- mkdir build && pushd build && cmake -DCMAKE_C_FLAGS="-std=gnu99" -DBUILD_TEST=1 .. && popd
script:
- pushd build && make && sudo make install; ./test_moony && popd
- pushd build && make && sudo make install; ./test_moony ../test_moony.lua && popd
......@@ -122,52 +122,59 @@ install(FILES ${PROJECT_BINARY_DIR}/manifest.ttl DESTINATION ${DEST})
install(FILES ${PROJECT_SOURCE_DIR}/moony.ttl DESTINATION ${DEST})
option(BUILD_TEST "Build test app" OFF)
add_executable(test_moony
test_moony.c
api.c
vm.c
tlsf-3.0/tlsf.c
lua-5.3/lapi.c
lua-5.3/lcode.c
lua-5.3/lctype.c
lua-5.3/ldebug.c
lua-5.3/ldo.c
lua-5.3/ldump.c
lua-5.3/lfunc.c
lua-5.3/lgc.c
lua-5.3/llex.c
lua-5.3/lmem.c
lua-5.3/lobject.c
lua-5.3/lopcodes.c
lua-5.3/lparser.c
lua-5.3/lstate.c
lua-5.3/lstring.c
lua-5.3/ltable.c
lua-5.3/ltm.c
lua-5.3/lundump.c
lua-5.3/lvm.c
lua-5.3/lzio.c
lua-5.3/lbaselib.c
lua-5.3/lauxlib.c
lua-5.3/lcorolib.c
lua-5.3/lmathlib.c
lua-5.3/lstrlib.c
lua-5.3/ltablib.c
lua-5.3/lutf8lib.c)
#lua-5.3/lbitlib.c
#lua-5.3/ldblib.c
#lua-5.3/liolib.c
#lua-5.3/loslib.c
#lua-5.3/loadlib.c
#lua-5.3/linit.c
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_compile_definitions(test_moony PUBLIC -DLUA_USE_LINUX)
elseif(WIN32)
target_compile_definitions(test_moony PUBLIC)
elseif(APPLE)
target_compile_definitions(test_moony PUBLIC -DLUA_USE_MACOSX)
if(${BUILD_TEST})
pkg_search_module(EINA REQUIRED eina>=1.8)
include_directories(${EINA_INCLUDE_DIRS})
add_executable(test_moony
test_moony.c
api.c
vm.c
ext_urid.c
tlsf-3.0/tlsf.c
lua-5.3/lapi.c
lua-5.3/lcode.c
lua-5.3/lctype.c
lua-5.3/ldebug.c
lua-5.3/ldo.c
lua-5.3/ldump.c
lua-5.3/lfunc.c
lua-5.3/lgc.c
lua-5.3/llex.c
lua-5.3/lmem.c
lua-5.3/lobject.c
lua-5.3/lopcodes.c
lua-5.3/lparser.c
lua-5.3/lstate.c
lua-5.3/lstring.c
lua-5.3/ltable.c
lua-5.3/ltm.c
lua-5.3/lundump.c
lua-5.3/lvm.c
lua-5.3/lzio.c
lua-5.3/lbaselib.c
lua-5.3/lauxlib.c
lua-5.3/lcorolib.c
lua-5.3/lmathlib.c
lua-5.3/lstrlib.c
lua-5.3/ltablib.c
lua-5.3/lutf8lib.c)
#lua-5.3/lbitlib.c
#lua-5.3/ldblib.c
#lua-5.3/liolib.c
#lua-5.3/loslib.c
#lua-5.3/loadlib.c
#lua-5.3/linit.c
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_compile_definitions(test_moony PUBLIC -DLUA_USE_LINUX)
elseif(WIN32)
target_compile_definitions(test_moony PUBLIC)
elseif(APPLE)
target_compile_definitions(test_moony PUBLIC -DLUA_USE_MACOSX)
endif()
target_link_libraries(test_moony ${EINA_LDFLAGS} "-lm")
endif()
target_link_libraries(test_moony ${LIBS} "-lm")
/*
* Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#include <ext_urid.h>
#include <Eina.h>
struct _ext_urid_t {
LV2_URID cnt;
Eina_Hash *uris;
Eina_Hash *urids;
LV2_URID_Map map;
LV2_URID_Unmap unmap;
};
static void
_uri_hash_uri_del(void *data)
{
LV2_URID *urid = data;
free(urid);
}
static void
_uri_hash_urid_del(void *data)
{
char *uri_dup = data;
free(uri_dup);
}
static LV2_URID
_urid_map(LV2_URID_Map_Handle handle, const char *uri)
{
ext_urid_t *uri_hash = handle;
LV2_URID *urid = NULL;
// uri already registered?
if((urid = eina_hash_find(uri_hash->uris, uri)))
return *urid;
// duplicate uri
char *uri_dup = strdup(uri);
if(!uri_dup)
return 0;
// create new urid for uri
urid = malloc(sizeof(LV2_URID));
if(!urid)
{
free(uri_dup);
return 0;
}
if(eina_hash_add(uri_hash->uris, uri_dup, urid))
{
*urid = uri_hash->cnt++;
if(eina_hash_add(uri_hash->urids, urid, uri_dup))
return *urid;
else
eina_hash_del(uri_hash->uris, uri_dup, urid);
}
free(urid);
free(uri_dup);
return 0;
}
static const char *
_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
{
ext_urid_t *uri_hash = handle;
const char *uri = NULL;
uri = eina_hash_find(uri_hash->urids, &urid);
return uri;
}
ext_urid_t *
ext_urid_new()
{
ext_urid_t *ext_urid = malloc(sizeof(ext_urid_t));
ext_urid->cnt = 1;
ext_urid->uris = eina_hash_string_superfast_new(_uri_hash_uri_del);
ext_urid->urids = eina_hash_int32_new(_uri_hash_urid_del);
ext_urid->map.handle = ext_urid;
ext_urid->map.map = _urid_map;
ext_urid->unmap.handle = ext_urid;
ext_urid->unmap.unmap = _urid_unmap;
return ext_urid;
}
void
ext_urid_free(ext_urid_t *ext_urid)
{
eina_hash_free(ext_urid->uris);
eina_hash_free(ext_urid->urids);
free(ext_urid);
}
LV2_URID_Map *
ext_urid_map_get(ext_urid_t *ext_urid)
{
return &ext_urid->map;
}
LV2_URID_Unmap *
ext_urid_unmap_get(ext_urid_t *ext_urid)
{
return &ext_urid->unmap;
}
LV2_URID
ext_urid_map(ext_urid_t *ext_urid, const char *uri)
{
return ext_urid->map.map(ext_urid->map.handle, uri);
}
const char *
ext_urid_unmap(ext_urid_t *ext_urid, const LV2_URID urid)
{
return ext_urid->unmap.unmap(ext_urid->unmap.handle, urid);
}
/*
* Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#ifndef _SYNTHPOD_EXT_URID_H
#define _SYNTHPOD_EXT_URID_H
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
typedef struct _ext_urid_t ext_urid_t;
ext_urid_t *
ext_urid_new();
void
ext_urid_free(ext_urid_t *ext_urid);
LV2_URID_Map *
ext_urid_map_get(ext_urid_t *ext_urid);
LV2_URID_Unmap *
ext_urid_unmap_get(ext_urid_t *ext_urid);
LV2_URID
ext_urid_map(ext_urid_t *ext_urid, const char *uri);
const char *
ext_urid_unmap(ext_urid_t *ext_urid, const LV2_URID urid);
#endif // _SYNTHPOD_EXT_URID_H
......@@ -17,41 +17,179 @@
#include <moony.h>
typedef struct _Handle Handle;
#include <Eina.h>
#include <ext_urid.h>
struct _Handle {
moony_t moony;
#include <lauxlib.h>
int max_val;
#define BUF_SIZE 8191
const LV2_Atom_Sequence *event_in;
LV2_Atom_Sequence *event_out;
const float *val_in [4];
float *val_out [4];
typedef struct _handle_t handle_t;
struct _handle_t {
moony_t moony;
ext_urid_t *ext_urid;
const LV2_Atom_Sequence *control;
LV2_Atom_Sequence *notify;
LV2_Atom_Forge forge;
uint8_t buf [8192];
};
static int
_test(lua_State *L)
{
handle_t *handle = lua_touserdata(L, lua_upvalueindex(1));
if(!lua_isfunction(L, 1) || !lua_isfunction(L, 2))
{
fprintf(stderr, "err: expected 2 function arguments\n");
exit(-1);
}
LV2_Atom_Forge *forge = &handle->forge;
LV2_Atom_Forge_Frame frame;
// produce events
lv2_atom_forge_set_buffer(forge, handle->buf, BUF_SIZE);
lv2_atom_forge_sequence_head(forge, &frame, 0);
{
lua_pushvalue(L, 1); // producer
lforge_t *lforge = lua_newuserdata(L, sizeof(lforge_t));
lforge->forge = forge;
luaL_getmetatable(L, "lforge");
lua_setmetatable(L, -2);
if(lua_pcall(L, 1, 0, 0))
{
fprintf(stderr, "err: %s\n", lua_tostring(L, -1));
exit(-1);
}
}
lv2_atom_forge_pop(forge, &frame);
// consume events
{
lua_pushvalue(L, 2); // consumer
lseq_t *lseq = lua_newuserdata(L, sizeof(lseq_t));
lseq->seq = (const LV2_Atom_Sequence *)handle->buf;
lseq->itr = NULL;
luaL_getmetatable(L, "lseq");
lua_setmetatable(L, -2);
if(lua_pcall(L, 1, 0, 0))
{
fprintf(stderr, "err: %s\n", lua_tostring(L, -1));
exit(-1);
}
}
return 0;
}
static LV2_URID
_map(LV2_URID_Map_Handle instance, const char *uri)
{
handle_t *handle = instance;
return ext_urid_map(handle->ext_urid, uri);
}
static const char *
_unmap(LV2_URID_Unmap_Handle instance, LV2_URID urid)
{
handle_t *handle = instance;
return ext_urid_unmap(handle->ext_urid, urid);
}
static LV2_Worker_Status
_sched(LV2_Worker_Schedule_Handle instance, uint32_t size, const void *data)
{
handle_t *handle = instance;
printf("_sched %u\n", size);
//TODO
return LV2_WORKER_SUCCESS;
}
int
main(int argc, char **argv)
{
Handle *producer = calloc(1, sizeof(Handle));
Handle *consumer = calloc(1, sizeof(Handle));
static handle_t handle;
eina_init();
if(!producer || !consumer)
{
if(producer)
free(producer);
if(consumer)
free(consumer);
handle.ext_urid = ext_urid_new();
LV2_URID_Map map = {
.handle = &handle,
.map = _map
};
LV2_URID_Unmap unmap = {
.handle = &handle,
.unmap = _unmap
};
LV2_Worker_Schedule sched = {
.handle = &handle,
.schedule_work = _sched
};
const LV2_Feature feat_map = {
.URI = LV2_URID__map,
.data = &map
};
const LV2_Feature feat_unmap = {
.URI = LV2_URID__unmap,
.data = &unmap
};
const LV2_Feature feat_sched = {
.URI = LV2_WORKER__schedule,
.data = &sched
};
const LV2_Feature *const features [] = {
&feat_map,
&feat_unmap,
&feat_sched,
NULL
};
if(moony_init(&handle.moony, features))
return -1;
lua_State *L = handle.moony.vm.L;
moony_open(&handle.moony, L);
lua_pushstring(L, "map");
lua_newtable(L);
lua_rawset(L, LUA_REGISTRYINDEX);
lua_pushstring(L, "unmap");
lua_newtable(L);
lua_rawset(L, LUA_REGISTRYINDEX);
lv2_atom_forge_init(&handle.forge, &map);
// register test function
lua_pushlightuserdata(L, &handle);
lua_pushcclosure(L, _test, 1);
lua_setglobal(L, "test");
if(luaL_dofile(L, argv[1]))
{
fprintf(stderr, "err: %s\n", lua_tostring(L, -1));
return -1;
}
//TODO write test cases
moony_deinit(&handle.moony);
ext_urid_free(handle.ext_urid);
eina_shutdown();
printf("sucess\n");
return 0;
}
--[[
Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
This is free software: you can redistribute it and/or modify
it under the terms of the Artistic License 2.0 as published by
The Perl Foundation.
This source is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Artistic License 2.0 for more details.
You should have received a copy of the Artistic License 2.0
along the source as a COPYING file. If not, obtain it from
http://www.perlfoundation.org/artistic_license_2_0.
--]]
-- map/unmap
do
local uri = 'http://test.org#foo'
assert(map[uri] == map[uri])
assert(map(uri) == map(uri))
local urid = map[uri]
assert(unmap[urid] == unmap[urid])
assert(unmap(urid) == unmap(urid))
end
-- Int
do
local function producer(forge)
forge:frame_time(0)
forge:int(0x7fffffff)
forge:frame_time(0)
forge:int(0xffffffff)
end
local function consumer(seq)
assert(#seq == 2)
local atom = seq[1]
assert(atom.type == map.Int)
assert(#atom == 4)
assert(type(atom.value) == 'number')
assert(atom.value == 0x7fffffff)
local atom = seq[2]
assert(atom.type == map.Int)
assert(#atom == 4)
assert(type(atom.value) == 'number')
assert(atom.value ~= 0xffffffff)
end
test(producer, consumer)
end
-- Long
do
local function producer(forge)
forge:frame_time(0)
forge:long(0x100000000)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.Long)
assert(#atom == 8)
assert(type(atom.value) == 'number')
assert(atom.value == 0x100000000)
end
test(producer, consumer)
end
-- Float
do
local function producer(forge)
forge:frame_time(0)
forge:float(2.0)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.Float)
assert(#atom == 4)
assert(type(atom.value) == 'number')
assert(atom.value == 2.0)
end
test(producer, consumer)
end
-- Double
do
local function producer(forge)
forge:frame_time(0)
forge:double(0.12)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.Double)
assert(#atom == 8)
assert(type(atom.value) == 'number')
assert(atom.value == 0.12)
end
test(producer, consumer)
end
-- Bool
do
local function producer(forge)
forge:frame_time(0)
forge:bool(true)
forge:frame_time(0)
forge:bool(false)
end
local function consumer(seq)
assert(#seq == 2)
local atom = seq[1]
assert(atom.type == map.Bool)
assert(#atom == 4)
assert(type(atom.value) == 'boolean')
assert(atom.value == true)
local atom = seq[2]
assert(atom.type == map.Bool)
assert(#atom == 4)
assert(type(atom.value) == 'boolean')
assert(type(atom.value) == 'boolean')
assert(atom.value == false)
end
test(producer, consumer)
end
-- String
do
local str = 'hello world'
local function producer(forge)
forge:frame_time(0)
forge:string(str)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.String)
assert(#atom == string.len(str) + 1)
assert(type(atom.value) == 'string')
assert(atom.value == str)
end
test(producer, consumer)
end
-- Literal
do
local str = 'hello world'
local datatype = map['http://test.org#datatype']
local lang = map['http://test.org#lang']
local function producer(forge)
forge:frame_time(0)
forge:literal(str, datatype, lang)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.Literal)
assert(type(atom.value) == 'string')
assert(#atom == string.len(str) + 1)
assert(atom.value == str)
assert(atom.datatype == datatype)
assert(atom.lang == lang)
end
test(producer, consumer)
end
-- URI
do
local uri = 'http://test.org'
local function producer(forge)
forge:frame_time(0)
forge:uri(uri)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.URI)
assert(#atom == string.len(uri) + 1)
assert(type(atom.value) == 'string')
assert(atom.value == uri)
end
test(producer, consumer)
end
-- Path
do
local path = '/tmp/lua.lua'
local function producer(forge)
forge:frame_time(0)
forge:path(path)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.Path)
assert(#atom == string.len(path) + 1)
assert(type(atom.value) == 'string')
assert(atom.value == path)
end
test(producer, consumer)
end
-- URID
do
local uri = 'http://test.org#uri'
local urid = map[uri]
local function producer(forge)
forge:frame_time(0)
forge:urid(urid)
end
local function consumer(seq)
assert(#seq == 1)
local atom = seq[1]
assert(atom.type == map.URID)
assert(#atom == 4)
assert(type(atom.value) == 'number')
assert(atom.value == urid)
assert(unmap[atom.value] == uri)
end