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.
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.
11 #include <gtest/gtest.h>
12 #include "TestUtils.h"
14 #include "Dictionary.h"
19 using namespace Mooseyard;
21 static const HashDictionary& getDict() {
22 static HashDictionary *sDict;
24 printf("Building large HashDictionary...\n");
25 sDict = new HashDictionary();
27 for( int i=0; i<sNWords; i++) {
29 sDict->put(Key(kv),kv);
35 TEST(Dictionary,AddRemove) {
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"));
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"));
55 TEST(Dictionary,GetAll) {
56 const Dictionary &dict = getDict();
57 EXPECT_EQ( sNWords , dict.count() );
58 for( int i=0; i<sNWords; i++) {
60 Blob value = dict.get(key);
62 EXPECT_TRUE( value.equals(key) );
66 TEST(Dictionary,Iterate) {
67 const HashDictionary &dict = getDict();
68 Timer t("Iterating Dictionary", sNWords);
70 for( HashDictionary::Iterator it(dict); it; ++it) {
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
76 EXPECT_EQ(sNWords, n);
79 TEST(Dictionary,Overlay) {
80 const Dictionary &dict = getDict();
81 OverlayDictionary overlay(&dict);
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"));
88 overlay.put("animal", "AMINAL");
89 overlay.put("growf", "growf");
90 EXPECT_TRUE(overlay.remove("asparagus"));
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"));
100 for( OverlayDictionary::Iterator it(overlay); it; ++it) {
102 EXPECT_TRUE(!it.key().equals("asparagus"));
104 EXPECT_EQ(sNWords, n);
106 printf("Testing ChangeIterator...\n");
108 int foundAsparagus=0, foundAnimal=0, foundGrowf=0;
109 for( Dictionary::ChangeIterator it(&overlay); it; ++it) {
111 if (it.key().equals("animal")) {
113 EXPECT_TRUE(it.value().equals("AMINAL"));
114 EXPECT_TRUE(it.otherValue().equals("animal"));
115 } else if (it.key().equals("asparagus")) {
117 EXPECT_FALSE(it.value());
118 EXPECT_TRUE(it.otherValue().equals("asparagus"));
119 } else if (it.key().equals("growf")) {
121 EXPECT_TRUE(it.value().equals("growf"));
122 EXPECT_FALSE(it.otherValue());
127 EXPECT_EQ(1, foundAnimal);
128 EXPECT_EQ(1, foundAsparagus);
129 EXPECT_EQ(1, foundGrowf);