Compare commits

...

2 commits

4 changed files with 204 additions and 3 deletions

View file

@ -129,8 +129,10 @@ void list_insert_before(listnode_t *pos, listnode_t *new_node);
* @param member: Name of the `listnode_t` member embedded within `cursor` * @param member: Name of the `listnode_t` member embedded within `cursor`
*/ */
#define list_foreach_reverse(cursor, list, member) \ #define list_foreach_reverse(cursor, list, member) \
for (cursor = _neo_list_last( list, typeof(*(cursor)), member ), \ for (typeof(cursor) __tmp = _neo_list_prev( \
__tmp = _neo_list_prev(cursor, member); \ cursor = _neo_list_last( list, typeof(*(cursor)), member ), \
member \
); \
!_neo_list_is_root(cursor, list, member); \ !_neo_list_is_root(cursor, list, member); \
cursor = __tmp, __tmp = _neo_list_prev(__tmp, member)) cursor = __tmp, __tmp = _neo_list_prev(__tmp, member))

View file

@ -19,6 +19,7 @@ add_executable(neo_test neo_test.cpp)
include(string/string.cmake) include(string/string.cmake)
target_sources(neo_test PRIVATE target_sources(neo_test PRIVATE
list.cpp
nref.cpp nref.cpp
) )

197
test/list.cpp Normal file
View file

@ -0,0 +1,197 @@
/** See the end of this file for copyright and license terms. */
#include <catch2/catch.hpp>
#include <errno.h>
#include <neo.h>
#include <neo/list.h>
extern "C" struct list_test {
int number;
/* link is not at the beginning to ensure offsets are subtracted */
listnode_t link;
};
SCENARIO( "list: items can be added and removed", "[src/list.c]" )
{
GIVEN( "list is initialized" )
{
list_t list = {
._len = 0,
};
list_init(&list);
REQUIRE( nlen(&list) == 0 );
WHEN( "one item is added" )
{
struct list_test item1 = {
.number = 1,
};
list_add(&list, &item1.link);
THEN( "item is in the list" )
{
REQUIRE( nlen(&list) == 1 );
struct list_test *cursor;
int iterations = 0;
list_foreach(cursor, &list, link) {
iterations++;
REQUIRE( cursor == &item1 );
REQUIRE( cursor->number == 1 );
}
REQUIRE( iterations == 1 );
}
WHEN( "item is removed again" )
{
list_del(&item1.link);
THEN( "list is empty" )
{
REQUIRE( nlen(&list) == 0 );
struct list_test *cursor;
int iterations = 0;
list_foreach(cursor, &list, link) {
iterations++;
}
REQUIRE( iterations == 0 );
}
}
WHEN( "another item is added" )
{
struct list_test item2 = {
.number = 2,
};
list_add(&list, &item2.link);
THEN( "new item is in position 2")
{
REQUIRE( nlen(&list) == 2 );
struct list_test *cursor;
int iterations = 0;
list_foreach(cursor, &list, link) {
iterations++;
REQUIRE( cursor->number == iterations );
}
REQUIRE( iterations == 2 );
}
}
}
}
}
SCENARIO( "list: items are inserted at the right position", "[src/list.c]" )
{
GIVEN( "list is initialized and populated" )
{
list_t list = {
/* required because C++ i think */
._len = 0,
};
list_init(&list);
REQUIRE( nlen(&list) == 0 );
struct list_test item1 = {
.number = 1,
};
list_add(&list, &item1.link);
struct list_test item2 = {
.number = 2,
};
list_add(&list, &item2.link);
WHEN( "item is added at the end" )
{
struct list_test item3 = {
.number = 3,
};
list_add(&list, &item3.link);
THEN( "item is at the end" )
{
struct list_test *cursor;
int number = 0;
list_foreach(cursor, &list, link) {
number++;
REQUIRE( cursor->number == number );
}
REQUIRE( number == 3 );
}
}
WHEN( "item is added at the beginning" )
{
struct list_test item0 = {
.number = 0,
};
list_add_first(&list, &item0.link);
THEN( "item is at the beginning" )
{
struct list_test *cursor;
int number = -1;
list_foreach(cursor, &list, link) {
number++;
REQUIRE( cursor->number == number );
}
REQUIRE( number == 2 );
}
}
WHEN( "item is inserted after position 1" )
{
struct list_test item11 = {
.number = 11,
};
list_insert(&item1.link, &item11.link);
THEN( "item is at position 2" )
{
struct list_test *cursor;
int i = 0;
static const int numbers[] = { 1, 11, 2 };
list_foreach(cursor, &list, link) {
REQUIRE( cursor->number == numbers[i] );
i++;
}
REQUIRE( i == 3 );
}
}
WHEN( "item is inserted before position 2" )
{
struct list_test item11 = {
.number = 11,
};
list_insert_before(&item2.link, &item11.link);
THEN( "item is at position 2" )
{
struct list_test *cursor;
int i = 0;
static const int numbers[] = { 1, 11, 2 };
list_foreach(cursor, &list, link) {
REQUIRE( cursor->number == numbers[i] );
i++;
}
REQUIRE( i == 3 );
}
}
}
}
/*
* This file is part of libneo.
* Copyright (c) 2021 Fefie <owo@fef.moe>.
*
* libneo is non-violent software: you may only use, redistribute,
* and/or modify it under the terms of the CNPLv6+ as found in
* the LICENSE file in the source code root directory or at
* <https://git.pixie.town/thufie/CNPL>.
*
* libneo comes with ABSOLUTELY NO WARRANTY, to the extent
* permitted by applicable law. See the CNPLv6+ for details.
*/

View file

@ -15,8 +15,9 @@
* code rather than the fun quirks C++ is infamous for. * code rather than the fun quirks C++ is infamous for.
*/ */
extern "C" struct nref_test { extern "C" struct nref_test {
NREF_FIELD;
bool *called; bool *called;
/* NREF_FIELD is not at the beginning to ensure offsets are subtracted */
NREF_FIELD;
}; };
void test_destroy(struct nref_test *ptr) void test_destroy(struct nref_test *ptr)