~jamesodhunt/ubuntu/raring/upstart/1.6

« back to all changes in this revision

Viewing changes to nih/tests/test_hash.c

  • Committer: Scott James Remnant
  • Date: 2010-02-04 23:39:59 UTC
  • mfrom: (1182.1.45 upstart)
  • mto: This revision was merged to the branch mainline in revision 1250.
  • Revision ID: scott@netsplit.com-20100204233959-7kajqjnaoh7208ob
Tags: upstream-0.6.5
ImportĀ upstreamĀ versionĀ 0.6.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* libnih
2
 
 *
3
 
 * test_hash.c - test suite for nih/hash.c
4
 
 *
5
 
 * Copyright Ā© 2009 Scott James Remnant <scott@netsplit.com>.
6
 
 * Copyright Ā© 2009 Canonical Ltd.
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License version 2, as
10
 
 * published by the Free Software Foundation.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License along
18
 
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 
 */
21
 
 
22
 
#include <nih/test.h>
23
 
 
24
 
#include <nih/macros.h>
25
 
#include <nih/alloc.h>
26
 
#include <nih/list.h>
27
 
#include <nih/hash.h>
28
 
 
29
 
 
30
 
typedef struct hash_entry {
31
 
        NihList     list;
32
 
        const char *key;
33
 
} HashEntry;
34
 
 
35
 
static NihList *
36
 
new_entry (void       *parent,
37
 
           const char *key)
38
 
{
39
 
        HashEntry *entry;
40
 
 
41
 
        entry = nih_new (parent, HashEntry);
42
 
 
43
 
        nih_list_init (&entry->list);
44
 
        entry->key = key;
45
 
 
46
 
        return (NihList *)entry;
47
 
}
48
 
 
49
 
static const void *
50
 
my_key_function (NihList *entry)
51
 
{
52
 
        return "foo";
53
 
}
54
 
 
55
 
static uint32_t
56
 
my_hash_function (const void *key)
57
 
{
58
 
        static uint32_t hash = 0;
59
 
 
60
 
        return hash++;
61
 
}
62
 
 
63
 
static int
64
 
my_cmp_function (const void *key1,
65
 
                 const void *key2)
66
 
{
67
 
        return 0;
68
 
}
69
 
 
70
 
 
71
 
void
72
 
test_new (void)
73
 
{
74
 
        NihHash *hash;
75
 
        size_t   i;
76
 
 
77
 
        TEST_FUNCTION ("nih_hash_new");
78
 
 
79
 
        /* Check that we can create a small hash table; a small prime number
80
 
         * should be selected for the actual size, and that number of empty
81
 
         * bins should be allocated as a child of the hash table.
82
 
         */
83
 
        TEST_FEATURE ("with zero size");
84
 
        TEST_ALLOC_FAIL {
85
 
                hash = nih_hash_new (NULL, 0,
86
 
                                     my_key_function,
87
 
                                     my_hash_function,
88
 
                                     my_cmp_function);
89
 
 
90
 
                if (test_alloc_failed) {
91
 
                        TEST_EQ_P (hash, NULL);
92
 
                        continue;
93
 
                }
94
 
 
95
 
                TEST_ALLOC_SIZE (hash, sizeof(NihHash));
96
 
                TEST_EQ_P (hash->key_function, my_key_function);
97
 
                TEST_EQ_P (hash->hash_function, my_hash_function);
98
 
                TEST_EQ_P (hash->cmp_function, my_cmp_function);
99
 
 
100
 
                TEST_EQ (hash->size, 17);
101
 
                TEST_NE_P (hash->bins, NULL);
102
 
                TEST_ALLOC_PARENT (hash->bins, hash);
103
 
 
104
 
                for (i = 0; i < hash->size; i++)
105
 
                        TEST_LIST_EMPTY (&hash->bins[i]);
106
 
 
107
 
                nih_free (hash);
108
 
        }
109
 
 
110
 
 
111
 
        /* Check again with a medium size, which should pick a medium prime
112
 
         * number.
113
 
         */
114
 
        TEST_FEATURE ("with medium size");
115
 
        TEST_ALLOC_FAIL {
116
 
                hash = nih_hash_new (NULL, 600,
117
 
                                     my_key_function,
118
 
                                     my_hash_function,
119
 
                                     my_cmp_function);
120
 
 
121
 
                if (test_alloc_failed) {
122
 
                        TEST_EQ_P (hash, NULL);
123
 
                        continue;
124
 
                }
125
 
 
126
 
                TEST_EQ (hash->size, 331);
127
 
                TEST_NE_P (hash->bins, NULL);
128
 
                TEST_ALLOC_PARENT (hash->bins, hash);
129
 
 
130
 
                for (i = 0; i < hash->size; i++)
131
 
                        TEST_LIST_EMPTY (&hash->bins[i]);
132
 
 
133
 
                nih_free (hash);
134
 
        }
135
 
 
136
 
 
137
 
        /* Check with a much larger size, which should pick the largest prime
138
 
         * that we know of.
139
 
         */
140
 
        TEST_FEATURE ("with large size");
141
 
        TEST_ALLOC_FAIL {
142
 
                hash = nih_hash_new (NULL, 40000000,
143
 
                                     my_key_function,
144
 
                                     my_hash_function,
145
 
                                     my_cmp_function);
146
 
 
147
 
                if (test_alloc_failed) {
148
 
                        TEST_EQ_P (hash, NULL);
149
 
                        continue;
150
 
                }
151
 
 
152
 
                TEST_EQ (hash->size, 10250323);
153
 
                TEST_NE_P (hash->bins, NULL);
154
 
                TEST_ALLOC_PARENT (hash->bins, hash);
155
 
 
156
 
                for (i = 0; i < hash->size; i++)
157
 
                        TEST_LIST_EMPTY (&hash->bins[i]);
158
 
 
159
 
                nih_free (hash);
160
 
        }
161
 
}
162
 
 
163
 
void
164
 
test_string_new (void)
165
 
{
166
 
        NihHash *hash;
167
 
        size_t   i;
168
 
 
169
 
        /* Check that we can create a small hash table; a small prime number
170
 
         * should be selected for the actual size, and that number of empty
171
 
         * bins should be allocated as a child of the hash table.
172
 
         */
173
 
        TEST_FUNCTION ("nih_hash_string_new");
174
 
        TEST_ALLOC_FAIL {
175
 
                hash = nih_hash_string_new (NULL, 0);
176
 
 
177
 
                if (test_alloc_failed) {
178
 
                        TEST_EQ_P (hash, NULL);
179
 
                        continue;
180
 
                }
181
 
 
182
 
                TEST_ALLOC_SIZE (hash, sizeof(NihHash));
183
 
                TEST_EQ_P (hash->key_function,
184
 
                           (NihKeyFunction)nih_hash_string_key);
185
 
                TEST_EQ_P (hash->hash_function,
186
 
                           (NihHashFunction)nih_hash_string_hash);
187
 
                TEST_EQ_P (hash->cmp_function,
188
 
                           (NihCmpFunction)nih_hash_string_cmp);
189
 
 
190
 
                TEST_EQ (hash->size, 17);
191
 
                TEST_NE_P (hash->bins, NULL);
192
 
                TEST_ALLOC_PARENT (hash->bins, hash);
193
 
 
194
 
                for (i = 0; i < hash->size; i++)
195
 
                        TEST_LIST_EMPTY (&hash->bins[i]);
196
 
 
197
 
                nih_free (hash);
198
 
        }
199
 
}
200
 
 
201
 
void
202
 
test_add (void)
203
 
{
204
 
        NihHash *hash;
205
 
        NihList *entry1, *entry2, *entry3, *entry4, *ptr;
206
 
 
207
 
        TEST_FUNCTION ("nih_hash_add");
208
 
        hash = nih_hash_string_new (NULL, 0);
209
 
        entry1 = new_entry (hash, "entry 1");
210
 
        entry2 = new_entry (hash, "entry 2");
211
 
        entry3 = new_entry (hash, "entry 1");
212
 
        entry4 = new_entry (hash, "entry 4");
213
 
 
214
 
        /* Check that we can add an entry to an empty hash table; it should
215
 
         * be returned and turn up in the appropriate bin.
216
 
         */
217
 
        TEST_FEATURE ("with empty hash");
218
 
        ptr = nih_hash_add (hash, entry1);
219
 
 
220
 
        TEST_EQ_P (ptr, entry1);
221
 
 
222
 
        TEST_EQ_P (hash->bins[15].next, entry1);
223
 
        TEST_EQ_P (entry1->next, &hash->bins[15]);
224
 
        TEST_EQ_P (hash->bins[15].prev, entry1);
225
 
        TEST_EQ_P (entry1->prev, &hash->bins[15]);
226
 
 
227
 
 
228
 
        /* Check that we can add an entry to a populated hash table. */
229
 
        TEST_FEATURE ("with non-empty hash");
230
 
        nih_hash_add (hash, entry2);
231
 
 
232
 
        TEST_EQ_P (hash->bins[14].next, entry2);
233
 
        TEST_EQ_P (entry2->next, &hash->bins[14]);
234
 
        TEST_EQ_P (hash->bins[14].prev, entry2);
235
 
        TEST_EQ_P (entry2->prev, &hash->bins[14]);
236
 
 
237
 
 
238
 
        /* Check that we can add an entry with a duplicate key, and it is
239
 
         * added to the end of the same bin as the previous entry with that
240
 
         * key.
241
 
         */
242
 
        TEST_FEATURE ("with duplicate key");
243
 
        nih_hash_add (hash, entry3);
244
 
 
245
 
        TEST_EQ_P (hash->bins[15].next, entry1);
246
 
        TEST_EQ_P (entry1->next, entry3);
247
 
        TEST_EQ_P (entry3->next, &hash->bins[15]);
248
 
        TEST_EQ_P (hash->bins[15].prev, entry3);
249
 
        TEST_EQ_P (entry3->prev, entry1);
250
 
        TEST_EQ_P (entry1->prev, &hash->bins[15]);
251
 
 
252
 
 
253
 
        /* Check that nih_hash_add can rip an entry out of an existing list
254
 
         * and place it in the hash table.
255
 
         */
256
 
        TEST_FEATURE ("with entry already in a list");
257
 
        ptr = nih_list_new (NULL);
258
 
        nih_list_add (ptr, entry4);
259
 
        nih_hash_add (hash, entry4);
260
 
 
261
 
        TEST_EQ_P (ptr->next, ptr);
262
 
        TEST_EQ_P (ptr->prev, ptr);
263
 
 
264
 
        TEST_EQ_P (hash->bins[3].next, entry4);
265
 
        TEST_EQ_P (entry4->next, &hash->bins[3]);
266
 
        TEST_EQ_P (hash->bins[3].prev, entry4);
267
 
        TEST_EQ_P (entry4->prev, &hash->bins[3]);
268
 
 
269
 
        nih_free (hash);
270
 
        nih_free (ptr);
271
 
}
272
 
 
273
 
void
274
 
test_add_unique (void)
275
 
{
276
 
        NihHash *hash;
277
 
        NihList *entry1, *entry2, *entry3, *entry4, *ptr;
278
 
 
279
 
        TEST_FUNCTION ("nih_hash_add_unique");
280
 
        hash = nih_hash_string_new (NULL, 0);
281
 
        entry1 = new_entry (hash, "entry 1");
282
 
        entry2 = new_entry (hash, "entry 2");
283
 
        entry3 = new_entry (hash, "entry 1");
284
 
        entry4 = new_entry (hash, "entry 4");
285
 
 
286
 
        /* Check that we can add an entry to an empty hash table; it should
287
 
         * be returned and turn up in the appropriate bin.
288
 
         */
289
 
        TEST_FEATURE ("with empty hash");
290
 
        ptr = nih_hash_add_unique (hash, entry1);
291
 
 
292
 
        TEST_EQ_P (ptr, entry1);
293
 
 
294
 
        TEST_EQ_P (hash->bins[15].next, entry1);
295
 
        TEST_EQ_P (entry1->next, &hash->bins[15]);
296
 
        TEST_EQ_P (hash->bins[15].prev, entry1);
297
 
        TEST_EQ_P (entry1->prev, &hash->bins[15]);
298
 
 
299
 
 
300
 
        /* Check that we can add an entry to a populated hash table. */
301
 
        TEST_FEATURE ("with non-empty hash");
302
 
        nih_hash_add_unique (hash, entry2);
303
 
 
304
 
        TEST_EQ_P (hash->bins[14].next, entry2);
305
 
        TEST_EQ_P (entry2->next, &hash->bins[14]);
306
 
        TEST_EQ_P (hash->bins[14].prev, entry2);
307
 
        TEST_EQ_P (entry2->prev, &hash->bins[14]);
308
 
 
309
 
 
310
 
        /* Check that we get NULL if we try and add an entry with a
311
 
         * duplicate key, and that the hash table is not altered.
312
 
         */
313
 
        TEST_FEATURE ("with duplicate key");
314
 
        ptr = nih_hash_add_unique (hash, entry3);
315
 
 
316
 
        TEST_EQ_P (ptr, NULL);
317
 
 
318
 
        TEST_EQ_P (hash->bins[15].next, entry1);
319
 
        TEST_EQ_P (entry1->next, &hash->bins[15]);
320
 
        TEST_EQ_P (hash->bins[15].prev, entry1);
321
 
        TEST_EQ_P (entry1->prev, &hash->bins[15]);
322
 
 
323
 
 
324
 
        /* Check that nih_hash_add can rip an entry out of an existing list
325
 
         * and place it in the hash table.
326
 
         */
327
 
        TEST_FEATURE ("with entry already in a list");
328
 
        ptr = nih_list_new (NULL);
329
 
        nih_list_add (ptr, entry4);
330
 
        nih_hash_add_unique (hash, entry4);
331
 
 
332
 
        TEST_EQ_P (ptr->next, ptr);
333
 
        TEST_EQ_P (ptr->prev, ptr);
334
 
 
335
 
        TEST_EQ_P (hash->bins[3].next, entry4);
336
 
        TEST_EQ_P (entry4->next, &hash->bins[3]);
337
 
        TEST_EQ_P (hash->bins[3].prev, entry4);
338
 
        TEST_EQ_P (entry4->prev, &hash->bins[3]);
339
 
 
340
 
        nih_free (hash);
341
 
        nih_free (ptr);
342
 
}
343
 
 
344
 
void
345
 
test_replace (void)
346
 
{
347
 
        NihHash *hash;
348
 
        NihList *entry1, *entry2, *entry3, *entry4, *ptr;
349
 
 
350
 
        TEST_FUNCTION ("nih_hash_replace");
351
 
        hash = nih_hash_string_new (NULL, 0);
352
 
        entry1 = new_entry (hash, "entry 1");
353
 
        entry2 = new_entry (hash, "entry 2");
354
 
        entry3 = new_entry (hash, "entry 1");
355
 
        entry4 = new_entry (hash, "entry 4");
356
 
 
357
 
        /* Check that we can add an entry to an empty hash table; NULL should
358
 
         * be returned (nothing replaced) and the entry should turn up in the
359
 
         * appropriate bin.
360
 
         */
361
 
        TEST_FEATURE ("with empty hash");
362
 
        ptr = nih_hash_replace (hash, entry1);
363
 
 
364
 
        TEST_EQ_P (ptr, NULL);
365
 
 
366
 
        TEST_EQ_P (hash->bins[15].next, entry1);
367
 
        TEST_EQ_P (entry1->next, &hash->bins[15]);
368
 
        TEST_EQ_P (hash->bins[15].prev, entry1);
369
 
        TEST_EQ_P (entry1->prev, &hash->bins[15]);
370
 
 
371
 
 
372
 
        /* Check that we can add an entry to a populated hash table. */
373
 
        TEST_FEATURE ("with non-empty hash");
374
 
        nih_hash_replace (hash, entry2);
375
 
 
376
 
        TEST_EQ_P (hash->bins[14].next, entry2);
377
 
        TEST_EQ_P (entry2->next, &hash->bins[14]);
378
 
        TEST_EQ_P (hash->bins[14].prev, entry2);
379
 
        TEST_EQ_P (entry2->prev, &hash->bins[14]);
380
 
 
381
 
 
382
 
        /* Check that we can add an entry with a duplicate key, replacing
383
 
         * the existing one in the hash.  The replaced entry should be
384
 
         * returned, and removed from the bin.
385
 
         */
386
 
        TEST_FEATURE ("with duplicate key");
387
 
        ptr = nih_hash_replace (hash, entry3);
388
 
 
389
 
        TEST_EQ_P (ptr, entry1);
390
 
 
391
 
        TEST_EQ_P (entry1->next, entry1);
392
 
        TEST_EQ_P (entry1->prev, entry1);
393
 
 
394
 
        TEST_EQ_P (hash->bins[15].next, entry3);
395
 
        TEST_EQ_P (entry3->next, &hash->bins[15]);
396
 
        TEST_EQ_P (hash->bins[15].prev, entry3);
397
 
        TEST_EQ_P (entry3->prev, &hash->bins[15]);
398
 
 
399
 
 
400
 
        /* Check that nih_hash_add can rip an entry out of an existing list
401
 
         * and place it in the hash table.
402
 
         */
403
 
        TEST_FEATURE ("with entry already in a list");
404
 
        ptr = nih_list_new (NULL);
405
 
        nih_list_add (ptr, entry4);
406
 
        nih_hash_replace (hash, entry4);
407
 
 
408
 
        TEST_EQ_P (ptr->next, ptr);
409
 
        TEST_EQ_P (ptr->prev, ptr);
410
 
 
411
 
        TEST_EQ_P (hash->bins[3].next, entry4);
412
 
        TEST_EQ_P (entry4->next, &hash->bins[3]);
413
 
        TEST_EQ_P (hash->bins[3].prev, entry4);
414
 
        TEST_EQ_P (entry4->prev, &hash->bins[3]);
415
 
 
416
 
        nih_free (hash);
417
 
        nih_free (ptr);
418
 
}
419
 
 
420
 
void
421
 
test_search (void)
422
 
{
423
 
        NihHash *hash;
424
 
        NihList *entry1, *entry2, *entry3, *ptr;
425
 
 
426
 
        TEST_FUNCTION ("nih_hash_search");
427
 
        hash = nih_hash_string_new (NULL, 0);
428
 
        entry1 = nih_hash_add (hash, new_entry (hash, "entry 1"));
429
 
        entry2 = nih_hash_add (hash, new_entry (hash, "entry 2"));
430
 
        entry3 = nih_hash_add (hash, new_entry (hash, "entry 2"));
431
 
 
432
 
        /* Check that we find the sole matching entry. */
433
 
        ptr = nih_hash_search (hash, "entry 1", NULL);
434
 
 
435
 
        TEST_EQ_P (ptr, entry1);
436
 
 
437
 
        /* Searching again should find nothing */
438
 
        ptr = nih_hash_search (hash, "entry 1", ptr);
439
 
 
440
 
        TEST_EQ_P (ptr, NULL);
441
 
 
442
 
 
443
 
        /* Check that where there's multiple matches, we find the first one. */
444
 
        TEST_FEATURE ("with multiple matches");
445
 
        ptr = nih_hash_search (hash, "entry 2", NULL);
446
 
 
447
 
        TEST_EQ_P (ptr, entry2);
448
 
 
449
 
        /* And that searching again finds the second one. */
450
 
        ptr = nih_hash_search (hash, "entry 2", ptr);
451
 
 
452
 
        TEST_EQ_P (ptr, entry3);
453
 
 
454
 
        /* And again finds nothing. */
455
 
        ptr = nih_hash_search (hash, "entry 2", ptr);
456
 
 
457
 
        TEST_EQ_P (ptr, NULL);
458
 
 
459
 
 
460
 
        /* Check that we get NULL if there are no matches. */
461
 
        TEST_FEATURE ("with no matches");
462
 
        ptr = nih_hash_search (hash, "entry 3", NULL);
463
 
 
464
 
        TEST_EQ_P (ptr, NULL);
465
 
 
466
 
        nih_free (hash);
467
 
}
468
 
 
469
 
void
470
 
test_lookup (void)
471
 
{
472
 
        NihHash *hash;
473
 
        NihList *entry1, *entry2, *entry3, *ptr;
474
 
 
475
 
        TEST_FUNCTION ("nih_hash_lookup");
476
 
        hash = nih_hash_string_new (NULL, 0);
477
 
        entry1 = nih_hash_add (hash, new_entry (hash, "entry 1"));
478
 
        entry2 = nih_hash_add (hash, new_entry (hash, "entry 2"));
479
 
        entry3 = new_entry (hash, "entry 3");
480
 
 
481
 
        /* Check that we find a single matching entry. */
482
 
        TEST_FEATURE ("with single match");
483
 
        ptr = nih_hash_lookup (hash, "entry 1");
484
 
 
485
 
        TEST_EQ_P (ptr, entry1);
486
 
 
487
 
 
488
 
        /* Check that we find the first matching entry. */
489
 
        TEST_FEATURE ("with multiple matches");
490
 
        ptr = nih_hash_lookup (hash, "entry 2");
491
 
 
492
 
        TEST_EQ_P (ptr, entry2);
493
 
 
494
 
 
495
 
        /* Check that we get NULL when there are no matching entries. */
496
 
        TEST_FEATURE ("with no matches");
497
 
        ptr = nih_hash_lookup (hash, "entry 3");
498
 
 
499
 
        TEST_EQ_P (ptr, NULL);
500
 
 
501
 
        nih_free (hash);
502
 
}
503
 
 
504
 
 
505
 
void
506
 
test_foreach (void)
507
 
{
508
 
        NihHash *hash;
509
 
        NihList *entry[4], *entry0, *entry1, *entry2, *entry3;
510
 
        int      i;
511
 
 
512
 
        /* Check that NIH_HASH_FOREACH iterates the hash correctly in order,
513
 
         * visiting each entry in each bin.  Note that we stage the entries
514
 
         * in the hash in the order we expect them to come out in, but add
515
 
         * them in a different order for sanity.
516
 
         */
517
 
        TEST_FUNCTION ("NIH_HASH_FOREACH");
518
 
        hash = nih_hash_string_new (NULL, 0);
519
 
        entry0 = entry[2] = new_entry (hash, "entry 1");
520
 
        entry1 = entry[1] = new_entry (hash, "entry 2");
521
 
        entry2 = entry[3] = new_entry (hash, "entry 1");
522
 
        entry3 = entry[0] = new_entry (hash, "entry 4");
523
 
 
524
 
        nih_hash_add (hash, entry0);
525
 
        nih_hash_add (hash, entry1);
526
 
        nih_hash_add (hash, entry2);
527
 
        nih_hash_add (hash, entry3);
528
 
 
529
 
        i = 0;
530
 
        NIH_HASH_FOREACH (hash, iter) {
531
 
                if (i > 3)
532
 
                        TEST_FAILED ("wrong number of iterations, expected %d got %d",
533
 
                                     4, i + 1);
534
 
 
535
 
                if (iter != entry[i])
536
 
                        TEST_FAILED ("wrong list entry, expected %p got %p",
537
 
                                     entry[i], iter);
538
 
 
539
 
                i++;
540
 
        }
541
 
 
542
 
        nih_free (hash);
543
 
}
544
 
 
545
 
void
546
 
test_foreach_safe (void)
547
 
{
548
 
        NihHash *hash;
549
 
        NihList *entry[4], *entry0, *entry1, *entry2, *entry3;
550
 
        int      i;
551
 
 
552
 
        /* Check that NIH_HASH_FOREACH_SAFE iterates the hash correctly in
553
 
         * order, visiting each entry in each bin; and that it's safe to
554
 
         * remove the entries while doing so.
555
 
         */
556
 
        TEST_FUNCTION ("NIH_HASH_FOREACH_SAFE");
557
 
        hash = nih_hash_string_new (NULL, 0);
558
 
        entry0 = entry[2] = new_entry (hash, "entry 1");
559
 
        entry1 = entry[1] = new_entry (hash, "entry 2");
560
 
        entry2 = entry[3] = new_entry (hash, "entry 1");
561
 
        entry3 = entry[0] = new_entry (hash, "entry 4");
562
 
 
563
 
        nih_hash_add (hash, entry0);
564
 
        nih_hash_add (hash, entry1);
565
 
        nih_hash_add (hash, entry2);
566
 
        nih_hash_add (hash, entry3);
567
 
 
568
 
        i = 0;
569
 
        NIH_HASH_FOREACH_SAFE (hash, iter) {
570
 
                if (i > 3)
571
 
                        TEST_FAILED ("wrong number of iterations, expected %d got %d",
572
 
                                     4, i + 1);
573
 
 
574
 
                if (iter != entry[i])
575
 
                        TEST_FAILED ("wrong list entry, expected %p got %p",
576
 
                                     entry[i], iter);
577
 
 
578
 
                nih_list_remove (entry[i]);
579
 
 
580
 
                i++;
581
 
        }
582
 
 
583
 
        nih_free (hash);
584
 
}
585
 
 
586
 
 
587
 
void
588
 
test_string_key (void)
589
 
{
590
 
        NihList    *entry;
591
 
        const char *key;
592
 
 
593
 
 
594
 
        /* Check that the string key function returns a pointer to the
595
 
         * key in our test structure.
596
 
         */
597
 
        TEST_FUNCTION ("nih_hash_string_key");
598
 
        entry = new_entry (NULL, "my entry");
599
 
 
600
 
        key = nih_hash_string_key (entry);
601
 
 
602
 
        TEST_EQ_P (key, ((HashEntry *)entry)->key);
603
 
        TEST_EQ_STR (key, "my entry");
604
 
 
605
 
        nih_free (entry);
606
 
}
607
 
 
608
 
 
609
 
int
610
 
main (int   argc,
611
 
      char *argv[])
612
 
{
613
 
        test_new ();
614
 
        test_string_new ();
615
 
        test_add ();
616
 
        test_add_unique ();
617
 
        test_replace ();
618
 
        test_search ();
619
 
        test_lookup ();
620
 
        test_foreach ();
621
 
        test_foreach_safe ();
622
 
        test_string_key ();
623
 
 
624
 
        return 0;
625
 
}