iPXE
editstring_test.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26/** @file
27 *
28 * Editable string tests
29 *
30 */
31
32/* Forcibly enable assertions */
33#undef NDEBUG
34
35#include <stdlib.h>
36#include <string.h>
37#include <ctype.h>
38#include <ipxe/keys.h>
39#include <ipxe/editstring.h>
40#include <ipxe/test.h>
41
42/** An editable string test */
44 /** Initial string, or NULL */
45 const char *start;
46 /** Key sequence */
47 const int *keys;
48 /** Length of key sequence */
49 unsigned int count;
50 /** Expected result */
51 const char *expected;
52};
53
54/** Define an inline key sequence */
55#define KEYS(...) { __VA_ARGS__ }
56
57/** Define an editable string test */
58#define EDITSTRING_TEST( name, START, EXPECTED, KEYS ) \
59 static const int name ## _keys[] = KEYS; \
60 static struct editstring_test name = { \
61 .start = START, \
62 .keys = name ## _keys, \
63 .count = ( sizeof ( name ## _keys ) / \
64 sizeof ( name ## _keys[0] ) ), \
65 .expected = EXPECTED, \
66 };
67
68/* Simple typing */
69EDITSTRING_TEST ( simple, "", "hello world!",
70 KEYS ( 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l',
71 'd', '!' ) );
72
73/* Simple typing from a NULL starting value */
74EDITSTRING_TEST ( simple_null, NULL, "hi there",
75 KEYS ( 'h', 'i', ' ', 't', 'h', 'e', 'r', 'e' ) );
76
77/* Insertion */
78EDITSTRING_TEST ( insert, "in middle", "in the middle",
80 KEY_LEFT, 't', 'h', 'e', ' ' ) );
81
82/* Backspace at end */
83EDITSTRING_TEST ( backspace_end, "byebye", "bye",
85
86/* Backspace of whole string */
87EDITSTRING_TEST ( backspace_all, "abc", "",
89
90/* Backspace of empty string */
91EDITSTRING_TEST ( backspace_empty, NULL, "", KEYS ( KEY_BACKSPACE ) );
92
93/* Backspace beyond start of string */
94EDITSTRING_TEST ( backspace_beyond, "too far", "",
98
99/* Deletion of character at cursor via DEL */
100EDITSTRING_TEST ( delete_dc, "go away", "goaway",
102
103/* Deletion of character at cursor via Ctrl-D */
104EDITSTRING_TEST ( delete_ctrl_d, "not here", "nohere",
106 KEY_LEFT, CTRL_D, CTRL_D ) );
107
108/* Deletion of word at end of string */
109EDITSTRING_TEST ( word_end, "remove these two words", "remove these ",
110 KEYS ( CTRL_W, CTRL_W ) );
111
112/* Deletion of word at start of string */
113EDITSTRING_TEST ( word_start, "no word", "word",
115
116/* Deletion of word mid-string */
117EDITSTRING_TEST ( word_mid, "delete this word", "delete word",
119
120/* Deletion to start of line */
121EDITSTRING_TEST ( sol, "everything must go", "go",
123
124/* Delete to end of line */
125EDITSTRING_TEST ( eol, "all is lost", "all",
127
128/**
129 * Report an editable string test result
130 *
131 * @v test Editable string test
132 * @v file Test code file
133 * @v line Test code line
134 */
135static void editstring_okx ( struct editstring_test *test, const char *file,
136 unsigned int line ) {
137 struct edit_string string;
138 unsigned int i;
139 char *actual;
140 int key;
141
142 /* Initialise editable string */
143 memset ( &string, 0, sizeof ( string ) );
144 actual = NULL;
145 init_editstring ( &string, &actual );
146
147 /* Set initial string content */
148 okx ( replace_string ( &string, test->start ) == 0, file, line );
149 okx ( actual != NULL, file, line );
150 okx ( string.cursor == ( test->start ? strlen ( test->start ) : 0 ),
151 file, line );
152 DBGC ( test, "Initial string: \"%s\"\n", actual );
153
154 /* Inject keypresses */
155 for ( i = 0 ; i < test->count ; i++ ) {
156 key = test->keys[i];
157 okx ( edit_string ( &string, key ) == 0, file, line );
158 okx ( actual != NULL, file, line );
159 okx ( string.cursor <= strlen ( actual ), file, line );
160 DBGC ( test, "After key %#02x (%c): \"%s\"\n",
161 key, ( isprint ( key ) ? key : '.' ), actual );
162 }
163
164 /* Verify result string */
165 okx ( strcmp ( actual, test->expected ) == 0, file, line );
166
167 /* Free result string */
168 free ( actual );
169}
170#define editstring_ok( test ) editstring_okx ( test, __FILE__, __LINE__ )
171
172/**
173 * Perform editable string self-tests
174 *
175 */
176static void editstring_test_exec ( void ) {
177
178 editstring_ok ( &simple );
179 editstring_ok ( &simple_null );
180 editstring_ok ( &insert );
181 editstring_ok ( &backspace_end );
182 editstring_ok ( &backspace_all );
183 editstring_ok ( &backspace_empty );
184 editstring_ok ( &backspace_beyond );
185 editstring_ok ( &delete_dc );
186 editstring_ok ( &delete_ctrl_d );
187 editstring_ok ( &word_end );
188 editstring_ok ( &word_start );
189 editstring_ok ( &word_mid );
190 editstring_ok ( &sol );
191 editstring_ok ( &eol );
192}
193
194/** Editable string self-test */
196 .name = "editstring",
197 .exec = editstring_test_exec,
198};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
Character types.
static int isprint(int character)
Check if character is printable.
Definition ctype.h:98
int replace_string(struct edit_string *string, const char *replacement)
Replace editable string.
Definition editstring.c:229
Editable strings.
static __nonnull void init_editstring(struct edit_string *string, char **buf)
Initialise editable string.
Definition editstring.h:47
#define EDITSTRING_TEST(name, START, EXPECTED, KEYS)
Define an editable string test.
static void editstring_okx(struct editstring_test *test, const char *file, unsigned int line)
Report an editable string test result.
#define editstring_ok(test)
static void editstring_test_exec(void)
Perform editable string self-tests.
#define KEYS(...)
Define an inline key sequence.
static int test
Definition epic100.c:73
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
Key definitions.
#define KEY_RIGHT
Right arrow.
Definition keys.h:108
#define KEY_DC
Delete.
Definition keys.h:113
#define KEY_BACKSPACE
Definition keys.h:128
#define CTRL_W
Definition keys.h:41
#define CTRL_D
Definition keys.h:22
#define CTRL_U
Definition keys.h:39
#define CTRL_K
Definition keys.h:29
#define CTRL_A
Definition keys.h:19
#define KEY_LEFT
Left arrow.
Definition keys.h:109
#define KEY_HOME
Home.
Definition keys.h:111
uint32_t string
Definition multiboot.h:2
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An editable string.
Definition editstring.h:14
unsigned int cursor
Cursor position.
Definition editstring.h:18
An editable string test.
const char * start
Initial string, or NULL.
const int * keys
Key sequence.
const char * expected
Expected result.
unsigned int count
Length of key sequence.
A self-test set.
Definition test.h:15
Self-test infrastructure.
#define okx(success, file, line)
Report test result.
Definition test.h:44
#define __self_test
Declare a self-test.
Definition test.h:32