test/Dictionary_test.cpp
author Jens Alfke <jens@mooseyard.com>
Thu Sep 24 10:28:50 2009 -0700 (2009-09-24)
changeset 3 8e3ae153e2c9
parent 0 31a43d94cc26
permissions -rw-r--r--
Fixed a nasty bug in HashDictionary that could cause heap corruption after removing a value. Added a test case to catch that bug. A few tweaks to Hash.
     1 /*
     2  *  Dictionary_test.cpp
     3  *  Ottoman
     4  *
     5  *  Created by Jens Alfke on 9/4/09.
     6  *  Copyright 2009 Jens Alfke. All rights reserved.
     7  *  BSD-Licensed: See the file "LICENSE.txt" for details.
     8  */
     9 
    10 
    11 #include <gtest/gtest.h>
    12 #include "TestUtils.h"
    13 #include "File.h"
    14 #include "Dictionary.h"
    15 #include "Hash.h"
    16 #include <fcntl.h>
    17 #include <stdio.h>
    18 
    19 using namespace Mooseyard;
    20 
    21 static const HashDictionary& getDict() {
    22     static HashDictionary *sDict;
    23     if (!sDict) {
    24         printf("Building large HashDictionary...\n");
    25         sDict = new HashDictionary();
    26         readWords();
    27         for( int i=0; i<sNWords; i++) {
    28             Blob kv(sWords[i]);
    29             sDict->put(Key(kv),kv);
    30         }
    31     }
    32     return *sDict;
    33 }
    34 
    35 TEST(Dictionary,AddRemove) {
    36     HashDictionary dict;
    37     EXPECT_EQ(0, dict.count());
    38     dict.put("key 1", "value 1");
    39     EXPECT_EQ(1, dict.count());
    40     dict.put("key 2", "value 2");
    41     EXPECT_EQ(2, dict.count());
    42     dict.put("key 3", "value 3");
    43     EXPECT_TRUE(dict.get("key 1").equals("value 1"));
    44     EXPECT_TRUE(dict.get("key 2").equals("value 2"));
    45     EXPECT_TRUE(dict.get("key 3").equals("value 3"));
    46     EXPECT_TRUE(!dict.get("key 4"));
    47 
    48     EXPECT_TRUE(dict.remove("key 2"));
    49     EXPECT_EQ(2, dict.count());
    50     EXPECT_TRUE(dict.get("key 1").equals("value 1"));
    51     EXPECT_TRUE(!dict.get("key 2"));
    52     EXPECT_TRUE(dict.get("key 3").equals("value 3"));
    53 }
    54 
    55 TEST(Dictionary,GetAll) {
    56     const Dictionary &dict = getDict();
    57     EXPECT_EQ( sNWords ,  dict.count() );
    58     for( int i=0; i<sNWords; i++) {
    59         Key key(sWords[i]);
    60         Blob value = dict.get(key);
    61         EXPECT_TRUE(value);
    62         EXPECT_TRUE( value.equals(key) );
    63     }
    64 }
    65 
    66 TEST(Dictionary,Iterate) {
    67     const HashDictionary &dict = getDict();
    68     Timer t("Iterating Dictionary", sNWords);
    69     int n=0;
    70     for( HashDictionary::Iterator it(dict); it; ++it) {
    71         n++;
    72         EXPECT_TRUE(it.key().length > 0 && it.key().length < 50);
    73         EXPECT_TRUE(it.key().equals(it.value()));
    74         EXPECT_EQ( 0, ((size_t)it.value().bytes & 0x3) );  // 4-byte aligned
    75     }
    76     EXPECT_EQ(sNWords, n);
    77 }
    78 
    79 TEST(Dictionary,Overlay) {
    80     const Dictionary &dict = getDict();
    81     OverlayDictionary overlay(&dict);
    82     
    83     EXPECT_EQ( sNWords ,  overlay.count() );
    84     EXPECT_TRUE(overlay.get("animal").equals("animal"));
    85     EXPECT_TRUE(overlay.get("asparagus").equals("asparagus"));
    86     EXPECT_FALSE(overlay.get("growf"));
    87     
    88     overlay.put("animal", "AMINAL");
    89     overlay.put("growf", "growf");
    90     EXPECT_TRUE(overlay.remove("asparagus"));
    91     
    92     EXPECT_EQ( sNWords, overlay.count() );
    93     EXPECT_TRUE(overlay.get("animal").equals("AMINAL"));
    94     EXPECT_TRUE(overlay.get("growf").equals("growf"));
    95     EXPECT_TRUE(overlay.contains("growf"));
    96     EXPECT_FALSE(overlay.get("asparagus"));
    97     EXPECT_FALSE(overlay.contains("asparagus"));
    98     
    99     int n=0;
   100     for( OverlayDictionary::Iterator it(overlay); it; ++it) {
   101         n++;
   102         EXPECT_TRUE(!it.key().equals("asparagus"));
   103     }
   104     EXPECT_EQ(sNWords, n);
   105     
   106     printf("Testing ChangeIterator...\n");
   107     n=0;
   108     int foundAsparagus=0, foundAnimal=0, foundGrowf=0;
   109     for( Dictionary::ChangeIterator it(&overlay); it; ++it) {
   110         n++;
   111         if (it.key().equals("animal")) {
   112             foundAnimal++;
   113             EXPECT_TRUE(it.value().equals("AMINAL"));
   114             EXPECT_TRUE(it.otherValue().equals("animal"));
   115         } else if (it.key().equals("asparagus")) {
   116             foundAsparagus++;
   117             EXPECT_FALSE(it.value());
   118             EXPECT_TRUE(it.otherValue().equals("asparagus"));
   119         } else if (it.key().equals("growf")) {
   120             foundGrowf++;
   121             EXPECT_TRUE(it.value().equals("growf"));
   122             EXPECT_FALSE(it.otherValue());
   123         } else {
   124             EXPECT_TRUE(false);
   125         }
   126     }
   127     EXPECT_EQ(1, foundAnimal);
   128     EXPECT_EQ(1, foundAsparagus);
   129     EXPECT_EQ(1, foundGrowf);
   130     EXPECT_EQ(3, n);
   131 }