Skip to content

Commit b277420

Browse files
committedMar 7, 2025
tests: Add tests for clip store

File tree

4 files changed

+622
-2
lines changed

4 files changed

+622
-2
lines changed
 

‎.github/workflows/ci.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ jobs:
1717
- run: gcc --version
1818

1919
- run: make clean analyse
20-
- run: tests/x_integration_tests
20+
- run: make tests
21+
- run: make integration_tests
22+
env:
23+
NO_PID_NAMESPACE: 1
2124

2225
on:
2326
push:

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ src/clipdel
44
src/clipmenu
55
src/clipserve
66
tests/test
7+
tests/test_store
78
*.o

‎Makefile

+10-1
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,13 @@ $(h_analyse_targets): %-analyse:
9292
clang-tidy $< --quiet -checks=-clang-analyzer-unix.Malloc -- -std=gnu99
9393
clang-format --dry-run --Werror $<
9494

95-
.PHONY: all debug install uninstall clean analyse
95+
tests: tests/test_store
96+
tests/test_store
97+
98+
integration_tests:
99+
tests/x_integration_tests
100+
101+
tests/test_store: tests/test_store.c src/store.o src/util.o
102+
$(CC) $(CFLAGS) $(CPPFLAGS) -I./src -o $@ $^ $(LDLIBS)
103+
104+
.PHONY: all debug install uninstall clean analyse tests integration_tests

‎tests/test_store.c

+607
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,607 @@
1+
#include <assert.h>
2+
#include <dirent.h>
3+
#include <errno.h>
4+
#include <fcntl.h>
5+
#include <limits.h>
6+
#include <stdbool.h>
7+
#include <stdint.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
#include <sys/mman.h>
12+
#include <sys/stat.h>
13+
#include <unistd.h>
14+
15+
#include "../src/store.h"
16+
#include "../src/util.h"
17+
18+
#define COL_NORMAL "\x1B[0m"
19+
#define COL_GREEN "\x1B[32m"
20+
#define COL_RED "\x1B[31m"
21+
22+
#define t_assert(test) \
23+
do { \
24+
if (!(test)) { \
25+
printf(" %s[FAIL:%d] %s%s\n", COL_RED, __LINE__, #test, \
26+
COL_NORMAL); \
27+
return false; \
28+
} \
29+
printf(" %s[PASS:%d] %s%s\n", COL_GREEN, __LINE__, #test, \
30+
COL_NORMAL); \
31+
} while (0)
32+
33+
#define t_run(test) \
34+
do { \
35+
printf("%s:\n", #test); \
36+
bool ret = test(); \
37+
printf("\n"); \
38+
if (!ret) { \
39+
return ret; \
40+
} \
41+
} while (0)
42+
43+
#define TEST_SNIP_FILE "/clip_store_snip_test"
44+
#define TEST_CONTENT_DIR "/dev/shm/clip_store_content_dir_test"
45+
46+
static int create_test_snip_fd(void) {
47+
shm_unlink(TEST_SNIP_FILE);
48+
int snip_fd = shm_open(TEST_SNIP_FILE, O_RDWR | O_CREAT | O_EXCL, 0600);
49+
assert(snip_fd >= 0);
50+
return snip_fd;
51+
}
52+
53+
static void drop_remove_test_snip_fd(int *snip_fd) {
54+
close(*snip_fd);
55+
int ret = shm_unlink(TEST_SNIP_FILE);
56+
assert(ret == 0);
57+
}
58+
59+
static void _drop_remove_test_content_dir_fd(int *dir_fd_ptr) {
60+
int dir_fd = *dir_fd_ptr;
61+
DIR *dir = fdopendir(dir_fd);
62+
if (dir == NULL) {
63+
close(dir_fd);
64+
return;
65+
}
66+
67+
struct dirent *entry;
68+
while ((entry = readdir(dir)) != NULL) {
69+
if (streq(entry->d_name, ".") || streq(entry->d_name, "..")) {
70+
continue;
71+
}
72+
73+
if (entry->d_type == DT_REG) {
74+
int ret = unlinkat(dir_fd, entry->d_name, 0);
75+
assert(ret == 0);
76+
} else if (entry->d_type == DT_DIR) {
77+
int subdir_fd =
78+
openat(dir_fd, entry->d_name, O_RDONLY | O_DIRECTORY);
79+
assert(subdir_fd >= 0);
80+
_drop_remove_test_content_dir_fd(&subdir_fd);
81+
int ret = unlinkat(dir_fd, entry->d_name, AT_REMOVEDIR);
82+
assert(ret == 0);
83+
}
84+
}
85+
86+
closedir(dir);
87+
}
88+
89+
static void drop_remove_test_content_dir_fd(int *dir_fd_ptr) {
90+
_drop_remove_test_content_dir_fd(dir_fd_ptr);
91+
int ret = rmdir(TEST_CONTENT_DIR);
92+
assert(ret == 0);
93+
}
94+
95+
static void remove_test_content_dir(const char *path) {
96+
int dir_fd = open(path, O_RDONLY);
97+
if (dir_fd < 0) {
98+
assert(errno == ENOENT);
99+
return;
100+
}
101+
drop_remove_test_content_dir_fd(&dir_fd);
102+
}
103+
104+
static int create_test_content_dir_fd(void) {
105+
remove_test_content_dir(TEST_CONTENT_DIR);
106+
int ret = mkdir(TEST_CONTENT_DIR, 0700);
107+
assert(ret == 0);
108+
int dir_fd = open(TEST_CONTENT_DIR, O_RDONLY);
109+
assert(dir_fd >= 0);
110+
return dir_fd;
111+
}
112+
113+
/* Test callables */
114+
static enum cs_remove_action remove_if_five(uint64_t hash, const char *line,
115+
void *private) {
116+
(void)hash;
117+
size_t *count = private;
118+
enum cs_remove_action ret = 0;
119+
120+
if (*count == 0) {
121+
ret |= CS_ACTION_STOP;
122+
}
123+
(*count)--;
124+
125+
if (line[0] == '5') {
126+
ret |= CS_ACTION_REMOVE;
127+
}
128+
129+
return ret;
130+
}
131+
132+
static struct clip_store setup_test(void) {
133+
struct clip_store cs;
134+
int snip_fd = create_test_snip_fd();
135+
int content_dir_fd = create_test_content_dir_fd();
136+
int ret = cs_init(&cs, snip_fd, content_dir_fd);
137+
assert(ret == 0);
138+
return cs;
139+
}
140+
141+
static void drop_teardown_test(struct clip_store *cs) {
142+
int snip_fd = cs->snip_fd;
143+
int content_dir_fd = cs->content_dir_fd;
144+
int ret = cs_destroy(cs);
145+
assert(ret == 0);
146+
close(snip_fd);
147+
close(content_dir_fd);
148+
}
149+
150+
static void add_ten_snips(struct clip_store *cs) {
151+
for (char i = 0; i < 10; i++) {
152+
char num[8];
153+
snprintf(num, sizeof(num), "%d", i);
154+
int ret = cs_add(cs, num, NULL);
155+
assert(ret == 0);
156+
}
157+
}
158+
159+
/* Tests */
160+
161+
static bool test__cs_init(void) {
162+
_drop_(teardown_test) struct clip_store cs = setup_test();
163+
164+
t_assert(cs.snip_fd >= 0);
165+
t_assert(cs.content_dir_fd >= 0);
166+
167+
/* Check header fields were set up and are correct */
168+
struct stat st;
169+
t_assert(fstat(cs.snip_fd, &st) == 0);
170+
t_assert(st.st_size == CS_SNIP_SIZE);
171+
t_assert(cs.header->nr_snips_alloc == 0);
172+
173+
return true;
174+
}
175+
176+
static bool test__cs_init__bad_size(void) {
177+
_drop_(remove_test_snip_fd) int snip_fd = create_test_snip_fd();
178+
_drop_(remove_test_content_dir_fd) int content_dir_fd =
179+
create_test_content_dir_fd();
180+
t_assert(ftruncate(snip_fd, CS_SNIP_SIZE - 1) == 0);
181+
struct clip_store cs;
182+
t_assert(cs_init(&cs, snip_fd, content_dir_fd) == -EINVAL);
183+
184+
return true;
185+
}
186+
187+
static bool test__cs_init__bad_size_aligned(void) {
188+
_drop_(remove_test_snip_fd) int snip_fd = create_test_snip_fd();
189+
_drop_(remove_test_content_dir_fd) int content_dir_fd =
190+
create_test_content_dir_fd();
191+
t_assert(ftruncate(snip_fd, CS_SNIP_SIZE * 2) == 0);
192+
struct clip_store cs;
193+
t_assert(cs_init(&cs, snip_fd, content_dir_fd) == -EINVAL);
194+
195+
return true;
196+
}
197+
198+
static bool test__cs_add(void) {
199+
_drop_(teardown_test) struct clip_store cs = setup_test();
200+
201+
for (char i = 0; i < 10; i++) {
202+
char num[8];
203+
snprintf(num, sizeof(num), "%d", i);
204+
205+
uint64_t hash;
206+
int ret = cs_add(&cs, num, &hash);
207+
t_assert(ret == 0);
208+
209+
_drop_(cs_content_unmap) struct cs_content content;
210+
ret = cs_content_get(&cs, hash, &content);
211+
t_assert(ret == 0);
212+
t_assert(strncmp(content.data, num, content.size) == 0);
213+
}
214+
215+
t_assert(cs.header->nr_snips == 10);
216+
217+
return true;
218+
}
219+
220+
static bool test__cs_snip_iter(void) {
221+
_drop_(teardown_test) struct clip_store cs = setup_test();
222+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
223+
224+
add_ten_snips(&cs);
225+
226+
struct cs_snip *snip = NULL;
227+
int last_num = 9;
228+
while (cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip)) {
229+
_drop_(cs_content_unmap) struct cs_content content;
230+
int ret = cs_content_get(&cs, snip->hash, &content);
231+
t_assert(ret == 0);
232+
233+
/* add_ten_snips adds from 0-9, we should get the last one first */
234+
int num = content.data[0] - '0';
235+
t_assert(num == last_num--);
236+
}
237+
238+
snip = NULL;
239+
last_num = 0;
240+
while (cs_snip_iter(&guard, CS_ITER_OLDEST_FIRST, &snip)) {
241+
_drop_(cs_content_unmap) struct cs_content content;
242+
int ret = cs_content_get(&cs, snip->hash, &content);
243+
t_assert(ret == 0);
244+
245+
int num = content.data[0] - '0';
246+
t_assert(num == last_num++);
247+
}
248+
249+
return true;
250+
}
251+
252+
static bool test__cs_remove(void) {
253+
_drop_(teardown_test) struct clip_store cs = setup_test();
254+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
255+
256+
add_ten_snips(&cs);
257+
258+
size_t nr_iter = 1;
259+
t_assert(cs_remove(&cs, CS_ITER_NEWEST_FIRST, remove_if_five, &nr_iter) ==
260+
0);
261+
t_assert(cs.header->nr_snips == 10);
262+
nr_iter = SIZE_MAX;
263+
t_assert(cs_remove(&cs, CS_ITER_NEWEST_FIRST, remove_if_five, &nr_iter) ==
264+
0);
265+
t_assert(cs.header->nr_snips == 9);
266+
267+
return true;
268+
}
269+
270+
static bool test__cs_trim(void) {
271+
_drop_(teardown_test) struct clip_store cs = setup_test();
272+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
273+
274+
add_ten_snips(&cs);
275+
276+
struct cs_snip *snip = NULL;
277+
while (cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip))
278+
;
279+
uint64_t oldest_hash = snip->hash;
280+
281+
t_assert(cs_trim(&cs, CS_ITER_NEWEST_FIRST, 3) == 0);
282+
t_assert(cs.header->nr_snips == 3);
283+
284+
/* Check we kept the most recently added ones */
285+
int last_num = 9;
286+
snip = NULL;
287+
while (cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip)) {
288+
_drop_(cs_content_unmap) struct cs_content content;
289+
int ret = cs_content_get(&cs, snip->hash, &content);
290+
t_assert(ret == 0);
291+
292+
int num = content.data[0] - '0';
293+
t_assert(num == last_num--);
294+
}
295+
296+
/* Check the oldest snip hash is gone */
297+
_drop_(cs_content_unmap) struct cs_content content;
298+
t_assert(cs_content_get(&cs, oldest_hash, &content) == -ENOENT);
299+
300+
return true;
301+
}
302+
303+
static bool test__cs_replace(void) {
304+
_drop_(teardown_test) struct clip_store cs = setup_test();
305+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
306+
307+
add_ten_snips(&cs);
308+
309+
const char *new = "new";
310+
311+
int ret = cs_replace(&cs, CS_ITER_NEWEST_FIRST, 1, new, NULL);
312+
t_assert(ret == 0);
313+
314+
struct cs_snip *snip = NULL;
315+
bool i_ret = cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip);
316+
t_assert(i_ret == true);
317+
t_assert(streq(snip->line, "9"));
318+
i_ret = cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip);
319+
t_assert(i_ret == true);
320+
t_assert(streq(snip->line, new));
321+
322+
_drop_(cs_content_unmap) struct cs_content first_content;
323+
ret = cs_content_get(&cs, snip->hash, &first_content);
324+
t_assert(ret == 0);
325+
t_assert(strncmp(first_content.data, new, first_content.size) == 0);
326+
327+
/* No other clips should be affected */
328+
int last_num = 7;
329+
while (cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip)) {
330+
_drop_(cs_content_unmap) struct cs_content content;
331+
ret = cs_content_get(&cs, snip->hash, &content);
332+
t_assert(ret == 0);
333+
334+
int num = content.data[0] - '0';
335+
t_assert(num == last_num--);
336+
}
337+
338+
return true;
339+
}
340+
341+
static bool test__reuse_cs(void) {
342+
_drop_(teardown_test) struct clip_store cs = setup_test();
343+
344+
add_ten_snips(&cs);
345+
t_assert(cs_destroy(&cs) == 0);
346+
347+
t_assert(cs_init(&cs, cs.snip_fd, cs.content_dir_fd) == 0);
348+
t_assert(cs.header->nr_snips == 10);
349+
350+
return true;
351+
}
352+
353+
static bool test__cs_add__exceeds_snip_line_size(void) {
354+
_drop_(teardown_test) struct clip_store cs = setup_test();
355+
356+
/* Construct a string that exceeds CS_SNIP_LINE_SIZE */
357+
char long_content[CS_SNIP_LINE_SIZE + 100];
358+
memset(long_content, 'A', sizeof(long_content));
359+
long_content[sizeof(long_content) - 1] = '\0';
360+
361+
int ret = cs_add(&cs, long_content, NULL);
362+
t_assert(ret == 0);
363+
364+
struct cs_snip *snip = NULL;
365+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
366+
bool found = cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip);
367+
t_assert(found);
368+
t_assert(strlen(snip->line) == CS_SNIP_LINE_SIZE - 1);
369+
370+
return true;
371+
}
372+
373+
static bool test__cs_trim__when_empty(void) {
374+
_drop_(teardown_test) struct clip_store cs = setup_test();
375+
376+
int ret = cs_trim(&cs, CS_ITER_NEWEST_FIRST, 0);
377+
t_assert(ret == 0);
378+
t_assert(cs.header->nr_snips == 0);
379+
380+
return true;
381+
}
382+
383+
static bool test__cs_remove___empty(void) {
384+
_drop_(teardown_test) struct clip_store cs = setup_test();
385+
386+
/* Attempt to remove any entry, if present */
387+
size_t dummy = 0;
388+
int ret = cs_remove(&cs, CS_ITER_NEWEST_FIRST, remove_if_five, &dummy);
389+
t_assert(ret == 0);
390+
t_assert(cs.header->nr_snips == 0);
391+
392+
return true;
393+
}
394+
395+
static bool test__cs_add__around_alloc_batch_threshold(void) {
396+
_drop_(teardown_test) struct clip_store cs = setup_test();
397+
398+
for (size_t i = 0; i < CS_SNIP_ALLOC_BATCH - 1; i++) {
399+
int ret = cs_add(&cs, "test content", NULL);
400+
assert(ret == 0);
401+
}
402+
t_assert(cs.header->nr_snips == CS_SNIP_ALLOC_BATCH - 1);
403+
404+
/* Add one more entry to exceed the batch threshold */
405+
t_assert(cs_add(&cs, "test content", NULL) == 0);
406+
t_assert(cs.header->nr_snips == CS_SNIP_ALLOC_BATCH);
407+
t_assert(cs.header->nr_snips_alloc >= CS_SNIP_ALLOC_BATCH);
408+
409+
return true;
410+
}
411+
412+
static bool test__cs_trim__no_remove_when_still_referenced(void) {
413+
_drop_(teardown_test) struct clip_store cs = setup_test();
414+
415+
uint64_t hash;
416+
for (size_t i = 0; i < 2; i++) {
417+
int ret = cs_add(&cs, "test content", &hash);
418+
t_assert(ret == 0);
419+
}
420+
421+
_drop_(cs_content_unmap) struct cs_content content;
422+
423+
t_assert(cs.header->nr_snips == 2);
424+
t_assert(cs_content_get(&cs, hash, &content) == 0);
425+
426+
t_assert(cs_trim(&cs, CS_ITER_NEWEST_FIRST, 1) == 0);
427+
t_assert(cs.header->nr_snips == 1);
428+
t_assert(cs_content_get(&cs, hash, &content) == 0);
429+
430+
t_assert(cs_trim(&cs, CS_ITER_NEWEST_FIRST, 0) == 0);
431+
t_assert(cs.header->nr_snips == 0);
432+
t_assert(cs_content_get(&cs, hash, &content) == -ENOENT);
433+
434+
return true;
435+
}
436+
437+
static bool test__cs_replace__out_of_bounds(void) {
438+
_drop_(teardown_test) struct clip_store cs = setup_test();
439+
440+
add_ten_snips(&cs);
441+
442+
int ret = cs_replace(&cs, CS_ITER_NEWEST_FIRST, 10, "test content", NULL);
443+
t_assert(ret == -ERANGE);
444+
445+
return true;
446+
}
447+
448+
static bool test__cs_snip__correct_nr_lines(void) {
449+
_drop_(teardown_test) struct clip_store cs = setup_test();
450+
451+
add_ten_snips(&cs);
452+
453+
/* No need to do exhaustive ones, they're done in test__first_line_* */
454+
uint64_t hash;
455+
struct cs_snip *snip = NULL;
456+
int ret =
457+
cs_replace(&cs, CS_ITER_NEWEST_FIRST, 0, "one\ntwo\nthree", &hash);
458+
459+
t_assert(ret == 0);
460+
_drop_(cs_unref) struct ref_guard guard = cs_ref(&cs);
461+
t_assert(cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip));
462+
t_assert(snip->hash == hash);
463+
t_assert(snip->nr_lines == 3);
464+
465+
return true;
466+
}
467+
468+
static bool test__first_line__empty(void) {
469+
char line[CS_SNIP_LINE_SIZE];
470+
size_t num_lines = first_line("", line);
471+
printf("%s\n", line);
472+
t_assert(streq(line, ""));
473+
t_assert(num_lines == 0);
474+
num_lines = first_line("\n", line);
475+
t_assert(streq(line, ""));
476+
t_assert(num_lines == 1);
477+
478+
num_lines = first_line("\n\n\n", line);
479+
t_assert(streq(line, ""));
480+
t_assert(num_lines == 3);
481+
return true;
482+
}
483+
484+
static bool test__first_line__only_one(void) {
485+
char line[CS_SNIP_LINE_SIZE];
486+
size_t num_lines = first_line("Foo bar\n", line);
487+
t_assert(streq(line, "Foo bar"));
488+
t_assert(num_lines == 1);
489+
return true;
490+
}
491+
492+
static bool test__first_line__multiple(void) {
493+
char line[CS_SNIP_LINE_SIZE];
494+
size_t num_lines = first_line("Foo bar\nbaz\nqux\n", line);
495+
t_assert(streq(line, "Foo bar"));
496+
t_assert(num_lines == 3);
497+
return true;
498+
}
499+
500+
static bool test__first_line__no_final_newline(void) {
501+
/* If the last line didn't end with a newline, still count it */
502+
char line[CS_SNIP_LINE_SIZE];
503+
size_t num_lines = first_line("Foo bar", line);
504+
t_assert(streq(line, "Foo bar"));
505+
t_assert(num_lines == 1);
506+
num_lines = first_line("Foo bar\nbaz", line);
507+
t_assert(streq(line, "Foo bar"));
508+
t_assert(num_lines == 2);
509+
return true;
510+
}
511+
512+
static bool test__first_line__ignore_blank_lines(void) {
513+
char line[CS_SNIP_LINE_SIZE];
514+
size_t num_lines = first_line("\n\n\nFoo bar\n\n\n", line);
515+
t_assert(streq(line, "Foo bar"));
516+
t_assert(num_lines == 6);
517+
return true;
518+
}
519+
520+
static bool test__first_line__unicode(void) {
521+
char line[CS_SNIP_LINE_SIZE];
522+
size_t num_lines = first_line("道", line);
523+
t_assert(streq(line, "道"));
524+
t_assert(num_lines == 1);
525+
num_lines = first_line("道\n", line);
526+
t_assert(streq(line, "道"));
527+
t_assert(num_lines == 1);
528+
num_lines = first_line("道\n非", line);
529+
t_assert(streq(line, "道"));
530+
t_assert(num_lines == 2);
531+
return true;
532+
}
533+
534+
static bool test__synchronisation(void) {
535+
_drop_(remove_test_snip_fd) int snip_fd1 = create_test_snip_fd();
536+
_drop_(remove_test_content_dir_fd) int content_dir_fd1 =
537+
create_test_content_dir_fd();
538+
_drop_(close) int snip_fd2 = dup(snip_fd1);
539+
_drop_(close) int content_dir_fd2 = dup(content_dir_fd1);
540+
541+
assert(snip_fd2 >= 0 && content_dir_fd2 >= 0);
542+
543+
struct clip_store cs1, cs2;
544+
int ret = cs_init(&cs1, snip_fd1, content_dir_fd1);
545+
t_assert(ret == 0);
546+
ret = cs_init(&cs2, snip_fd2, content_dir_fd2);
547+
t_assert(ret == 0);
548+
549+
uint64_t hash;
550+
ret = cs_add(&cs1, "test content", &hash);
551+
t_assert(ret == 0);
552+
553+
bool found = false;
554+
struct cs_snip *snip = NULL;
555+
_drop_(cs_unref) struct ref_guard guard_cs2 = cs_ref(&cs2);
556+
while (cs_snip_iter(&guard_cs2, CS_ITER_NEWEST_FIRST, &snip)) {
557+
if (snip->hash == hash) {
558+
found = true;
559+
break;
560+
}
561+
}
562+
t_assert(found);
563+
564+
ret = cs_trim(&cs2, CS_ITER_NEWEST_FIRST, 0);
565+
t_assert(ret == 0);
566+
567+
found = false;
568+
snip = NULL;
569+
_drop_(cs_unref) struct ref_guard guard_cs1 = cs_ref(&cs1);
570+
while (cs_snip_iter(&guard_cs1, CS_ITER_NEWEST_FIRST, &snip)) {
571+
found = true;
572+
}
573+
t_assert(!found);
574+
575+
t_assert(cs_destroy(&cs1) == 0);
576+
t_assert(cs_destroy(&cs2) == 0);
577+
578+
return true;
579+
}
580+
581+
int main(void) {
582+
t_run(test__cs_init);
583+
t_run(test__cs_init__bad_size);
584+
t_run(test__cs_init__bad_size_aligned);
585+
t_run(test__cs_add);
586+
t_run(test__cs_snip_iter);
587+
t_run(test__cs_remove);
588+
t_run(test__cs_trim);
589+
t_run(test__cs_replace);
590+
t_run(test__reuse_cs);
591+
t_run(test__cs_add__exceeds_snip_line_size);
592+
t_run(test__cs_trim__when_empty);
593+
t_run(test__cs_remove___empty);
594+
t_run(test__cs_add__around_alloc_batch_threshold);
595+
t_run(test__cs_replace__out_of_bounds);
596+
t_run(test__synchronisation);
597+
t_run(test__cs_trim__no_remove_when_still_referenced);
598+
t_run(test__cs_snip__correct_nr_lines);
599+
t_run(test__first_line__empty);
600+
t_run(test__first_line__only_one);
601+
t_run(test__first_line__multiple);
602+
t_run(test__first_line__no_final_newline);
603+
t_run(test__first_line__ignore_blank_lines);
604+
t_run(test__first_line__unicode);
605+
606+
return 0;
607+
}

0 commit comments

Comments
 (0)
Please sign in to comment.