1 // ===========================================================================
2 //
3 // PUBLIC DOMAIN NOTICE
4 // National Center for Biotechnology Information
5 //
6 // This software/database is a "United States Government Work" under the
7 // terms of the United States Copyright Act. It was written as part of
8 // the author's official duties as a United States Government employee and
9 // thus cannot be copyrighted. This software/database is freely available
10 // to the public for use. The National Library of Medicine and the U.S.
11 // Government have not placed any restriction on its use or reproduction.
12 //
13 // Although all reasonable efforts have been taken to ensure the accuracy
14 // and reliability of the software and data, the NLM and the U.S.
15 // Government do not and cannot warrant the performance or results that
16 // may be obtained by using this software or data. The NLM and the U.S.
17 // Government disclaim all warranties, express or implied, including
18 // warranties of performance, merchantability or fitness for any particular
19 // purpose.
20 //
21 // Please cite the author in any work or product based on this material.
22 //
23 // ===========================================================================
24
25 #include <vdb/manager.h> // VDBManager
26 #include <vdb/vdb-priv.h>
27
28 #include <ktst/unit_test.hpp> // TEST_CASE
29 #include <klib/text.h>
30 #include <klib/out.h>
31 #include <klib/namelist.h>
32
33 #include <sysalloc.h>
34 #include <cstdlib>
35 #include <stdexcept>
36
37 using namespace std;
38
39 TEST_SUITE( T_VNamelist )
40
41
TEST_CASE(VNamelist_1)42 TEST_CASE( VNamelist_1 )
43 {
44 VNamelist * list;
45 rc_t rc = VNamelistMake ( &list, 10 );
46 if ( rc != 0 )
47 FAIL( "FAIL: VNamelistMake( 10 ) failed" );
48
49 rc = VNamelistRelease ( list );
50 if ( rc != 0 )
51 FAIL( "FAIL: VNamelistRelease() failed" );
52 }
53
54 struct on_part_ctx
55 {
56 const char ** v;
57 int idx;
58 };
59
on_part(const String * part,void * data)60 static rc_t CC on_part( const String * part, void * data )
61 {
62 rc_t rc = 0;
63 struct on_part_ctx * ctx = ( struct on_part_ctx * ) data;
64 std::string p = std::string( part->addr, part->size );
65 std::string c = std::string( ctx->v[ ctx->idx ] );
66 if ( p != c ) rc = -1;
67 ctx->idx++;
68 return rc;
69 }
70
71
test_String(const char * to_test,const char ** v,int count)72 rc_t test_String( const char * to_test, const char ** v, int count )
73 {
74 String s;
75 struct on_part_ctx ctx;
76 ctx.v = v;
77 ctx.idx = 0;
78
79 StringInitCString( &s, to_test );
80 rc_t rc = foreach_String_part( &s, ':', on_part, &ctx );
81 if ( rc == 0 && ctx.idx != count ) rc = -1;
82 return rc;
83 }
84
85
test_pchar(const char * to_test,const char ** v,int count)86 rc_t test_pchar( const char * to_test, const char ** v, int count )
87 {
88 struct on_part_ctx ctx;
89 ctx.v = v;
90 ctx.idx = 0;
91
92 rc_t rc = foreach_Str_part( to_test, ':', on_part, &ctx );
93 if ( rc == 0 && ctx.idx != count ) rc = -1;
94 return rc;
95 }
96
97 static const char * s1 = "string:with:colons";
98 static const char * t1[] = { "string", "with", "colons" };
99 static const int n1 = 3;
100
101 static const char * s2 = "just a string";
102 static const char * t2[] = { "just a string" };
103 static const int n2 = 1;
104
105 static const char * s3 = "with::multiple::colons";
106 static const char * t3[] = { "with", "", "multiple", "", "colons" };
107 static const int n3 = 5;
108
109 static const char * s4 = "::leading:colons";
110 static const char * t4[] = { "", "", "leading", "colons" };
111 static const int n4 = 4;
112
113 static const char * s5 = "trailing:colons::";
114 static const char * t5[] = { "trailing", "colons", "", "" };
115 static const int n5 = 4;
116
TEST_CASE(StringSplit)117 TEST_CASE( StringSplit )
118 {
119 std::cout << "testing String-splitting by callback" << std::endl;
120
121 rc_t rc = test_String( s1, t1, n1 );
122 if ( rc != 0 )
123 FAIL( "FAIL: foreach_String_part( #1 ) failed" );
124 rc = test_pchar( s1, t1, n1 );
125 if ( rc != 0 )
126 FAIL( "FAIL: foreach_Str_part( #1 ) failed" );
127
128 rc = test_String( s2, t2, n2 );
129 if ( rc != 0 )
130 FAIL( "FAIL: foreach_String_part( #2 ) failed" );
131 rc = test_pchar( s2, t2, n2 );
132 if ( rc != 0 )
133 FAIL( "FAIL: foreach_Str_part( #2 ) failed" );
134
135 rc = test_String( s3, t3, n3 );
136 if ( rc != 0 )
137 FAIL( "FAIL: foreach_String_part( #3) failed" );
138 rc = test_pchar( s3, t3, n3 );
139 if ( rc != 0 )
140 FAIL( "FAIL: foreach_Str_part( #3 ) failed" );
141
142 rc = test_String( s4, t4, n4 );
143 if ( rc != 0 )
144 FAIL( "FAIL: foreach_String_part( #4 ) failed" );
145 rc = test_pchar( s4, t4, n4 );
146 if ( rc != 0 )
147 FAIL( "FAIL: foreach_Str_part( #4 ) failed" );
148
149 rc = test_String( s5, t5, n5 );
150 if ( rc != 0 )
151 FAIL( "FAIL: foreach_String_part( #5 ) failed" );
152 rc = test_pchar( s5, t5, n5 );
153 if ( rc != 0 )
154 FAIL( "FAIL: foreach_Str_part( #5 ) failed" );
155 }
156
157
insert_String(VNamelist * list,const char * to_test)158 rc_t insert_String( VNamelist * list, const char * to_test )
159 {
160 String s;
161 StringInitCString( &s, to_test );
162 return VNamelistSplitString ( list, &s, ':' );
163 }
164
165
insert_pchar(VNamelist * list,const char * to_test)166 rc_t insert_pchar( VNamelist * list, const char * to_test )
167 {
168 return VNamelistSplitStr ( list, to_test, ':' );
169 }
170
171
check_list(const VNamelist * list,const char ** v,uint32_t count)172 rc_t check_list( const VNamelist * list, const char ** v, uint32_t count )
173 {
174 rc_t rc = 0;
175 uint32_t idx;
176 for ( idx = 0; rc == 0 && idx < count; ++idx )
177 {
178 const char * item;
179 rc = VNameListGet ( list, idx, &item );
180 if ( rc == 0 )
181 {
182 std::string s_item = std::string( item );
183 std::string s_cmp = std::string( v[ idx ] );
184 if ( s_item.compare( s_cmp ) != 0 )
185 rc = -1;
186 }
187 if ( rc == 0 )
188 {
189 uint32_t lc;
190 rc = VNameListCount ( list, &lc );
191 if ( rc == 0 && lc != count )
192 rc = -1;
193 }
194 }
195 return rc;
196 }
197
198
test_split_string(const char * to_test,const char ** v,uint32_t count)199 rc_t test_split_string( const char * to_test, const char ** v, uint32_t count )
200 {
201 VNamelist * list;
202 rc_t rc = VNamelistMake ( &list, 10 );
203 if ( rc == 0 )
204 {
205 rc = insert_String( list, to_test );
206 if ( rc == 0 )
207 rc = check_list( list, v, count );
208 if ( rc == 0 )
209 rc = VNamelistRemoveAll( list );
210
211 if ( rc == 0 )
212 rc = insert_pchar( list, to_test );
213 if ( rc == 0 )
214 rc = check_list( list, v, count );
215
216 VNamelistRelease ( list );
217 }
218 return rc;
219 }
220
TEST_CASE(SplitIntoVNamelist)221 TEST_CASE( SplitIntoVNamelist )
222 {
223 std::cout << "testing String-splitting into existing VNamelist " << std::endl;
224
225 rc_t rc = test_split_string( s1, t1, n1 );
226 if ( rc != 0 )
227 FAIL( "FAIL: test_split_string( #1 )" );
228
229 rc = test_split_string( s2, t2, n2 );
230 if ( rc != 0 )
231 FAIL( "FAIL: test_split_string( #2 )" );
232
233 rc = test_split_string( s3, t3, n3 );
234 if ( rc != 0 )
235 FAIL( "FAIL: test_split_string( #3 )" );
236
237 rc = test_split_string( s4, t4, n4 );
238 if ( rc != 0 )
239 FAIL( "FAIL: test_split_string( #4 )" );
240
241 rc = test_split_string( s5, t5, n5 );
242 if ( rc != 0 )
243 FAIL( "FAIL: test_split_string( #5 )" );
244
245 }
246
247
test_make_from_string(const char * to_test,const char ** v,uint32_t count)248 rc_t test_make_from_string( const char * to_test, const char ** v, uint32_t count )
249 {
250 String s;
251 StringInitCString( &s, to_test );
252
253 VNamelist * list;
254 rc_t rc = VNamelistFromString( &list, &s, ':' );
255 if ( rc == 0 )
256 {
257 rc = check_list( list, v, count );
258 VNamelistRelease ( list );
259 }
260
261 if ( rc == 0 )
262 {
263 rc = VNamelistFromStr( &list, to_test, ':' );
264 if ( rc == 0 )
265 {
266 rc = check_list( list, v, count );
267 VNamelistRelease ( list );
268 }
269 }
270 return rc;
271 }
272
273
TEST_CASE(MakeVNamelistFromString)274 TEST_CASE( MakeVNamelistFromString )
275 {
276 std::cout << "testing String-splitting into new VNamelist " << std::endl;
277
278 rc_t rc = test_make_from_string( s1, t1, n1 );
279 if ( rc != 0 )
280 FAIL( "FAIL: test_make_from_string( #1 )" );
281
282 rc = test_make_from_string( s2, t2, n2 );
283 if ( rc != 0 )
284 FAIL( "FAIL: test_make_from_string( #2 )" );
285
286 rc = test_make_from_string( s3, t3, n3 );
287 if ( rc != 0 )
288 FAIL( "FAIL: test_make_from_string( #3 )" );
289
290 rc = test_make_from_string( s4, t4, n4 );
291 if ( rc != 0 )
292 FAIL( "FAIL: test_make_from_string( #4 )" );
293
294 rc = test_make_from_string( s5, t5, n5 );
295 if ( rc != 0 )
296 FAIL( "FAIL: test_make_from_string( #5 )" );
297 }
298
split_join_and_check(const char * to_test)299 rc_t split_join_and_check( const char * to_test )
300 {
301 VNamelist * list;
302 rc_t rc = VNamelistFromStr( &list, to_test, ':' );
303 if ( rc == 0 )
304 {
305 const String * joined;
306 rc = VNamelistJoin( list, ':', &joined );
307 if ( rc != 0 )
308 FAIL( "FAIL: VNamelistJoin()" );
309 else
310 {
311 String S2;
312 StringInitCString( &S2, to_test );
313 if ( !StringEqual( joined, &S2 ) )
314 rc = -1;
315 StringWhack ( joined );
316 }
317 VNamelistRelease ( list );
318 }
319 return rc;
320 }
321
TEST_CASE(VNamelistJoining)322 TEST_CASE( VNamelistJoining )
323 {
324 std::cout << "testing joining VNamelist into one String" << std::endl;
325
326 rc_t rc = split_join_and_check( s1 );
327 if ( rc != 0 )
328 FAIL( "FAIL: split_join_and_check( #1 )" );
329
330 rc = split_join_and_check( s2 );
331 if ( rc != 0 )
332 FAIL( "FAIL: split_join_and_check( #2 )" );
333
334 rc = split_join_and_check( s3 );
335 if ( rc != 0 )
336 FAIL( "FAIL: split_join_and_check( #3 )" );
337
338 rc = split_join_and_check( s4 );
339 if ( rc != 0 )
340 FAIL( "FAIL: split_join_and_check( #4 )" );
341
342 rc = split_join_and_check( s5 );
343 if ( rc != 0 )
344 FAIL( "FAIL: split_join_and_check( #5 )" );
345 }
346
347 //////////////////////////////////////////// Main
348 extern "C"
349 {
350
351 #include <kapp/args.h>
352
KAppVersion(void)353 ver_t CC KAppVersion ( void ) { return 0x1000000; }
UsageSummary(const char * progname)354 rc_t CC UsageSummary ( const char * progname ) { return 0; }
Usage(const Args * args)355 rc_t CC Usage ( const Args * args ) { return 0; }
356 const char UsageDefaultName[] = "test-VDB-3060";
357
KMain(int argc,char * argv[])358 rc_t CC KMain ( int argc, char *argv [] )
359 {
360 rc_t rc = T_VNamelist( argc, argv );
361 return rc;
362 }
363
364 }
365