Skip to content

Commit

Permalink
Merge pull request #494 from marcusnaslund/missing-collections-tests-v2
Browse files Browse the repository at this point in the history
Reworked HashDictionary
  • Loading branch information
davidhesselbom committed Oct 28, 2015
2 parents ceef6b4 + 3dfbccd commit e78108f
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 118 deletions.
103 changes: 47 additions & 56 deletions source/collections/HashDictionary.ooc
@@ -1,97 +1,88 @@
import structs/[HashBag, HashMap, ArrayList]

HashDictionary: class {
_myHashBag: HashBag
_capacity: Int
_hashBag: HashBag
count ::= this _hashBag size()
empty ::= this _hashBag empty?()
init: func { init ~withCapacity(10) }
init: func ~withCapacity (=_capacity) {
_myHashBag = HashBag new(this _capacity)
init: func ~withCapacity (capacity: Int) {
this _hashBag = HashBag new(capacity)
}
init: func ~copy (other: This) {
hashMapClone := other _myHashBag myMap clone()
_myHashBag = HashBag new(other _capacity)
this _myHashBag myMap = hashMapClone
hashMapClone := other _hashBag myMap clone()
this _hashBag = HashBag new(other _hashBag myMap capacity)
this _hashBag myMap = hashMapClone
}
free: override func {
free(this _hashBag myMap keys data)
free(this _hashBag myMap keys)
for (i in 0 .. (this _hashBag myMap capacity)) {
next := (this _hashBag myMap buckets[i])
next dispose()
}
free(this _hashBag myMap buckets data)
free(this _hashBag myMap)
free(this _hashBag)
super()
}
clone: func -> This {
result := This new()
hashMapClone := this _myHashBag myMap clone()
result _myHashBag myMap = hashMapClone
hashMapClone := this _hashBag myMap clone()
result _hashBag myMap = hashMapClone
result
}
merge: func (other: This) -> This {
result := this clone()
result _myHashBag myMap merge!(other _myHashBag myMap)
result _hashBag myMap merge!(other _hashBag myMap)
result
}
/* WARNING: The defaultValue parameter for Covers must be new Cell(cover) */
get: func <T> (key: String, defaultValue: T) -> T {
result := defaultValue
if (_myHashBag contains?(key)) {
storedType := _myHashBag getClass(key)
// is `T` a derived type or the same type as the stored type?
if (T inheritsFrom?(storedType)) {
result = _myHashBag getEntry(key, T) value as T
if (_hashBag contains?(key)) {
storedType := this _hashBag getClass(key)
entryValue := this _hashBag getEntry(key, storedType) value
if (storedType inheritsFrom?(Cell)) {
entryValueCell := (entryValue as Cell<T>*)@
if (T inheritsFrom?(entryValueCell T))
result = entryValueCell get()
}
}
result
}
/* WARNING: The Class parameter for Covers must be Cell<Cover> */
getAsType: func <T>(key: String, T: Class) -> T {
result := null
if (_myHashBag contains?(key)) {
storedType := _myHashBag getClass(key)
// is `T` a derived type or the same type as the stored type?
if (T inheritsFrom?(storedType))
result = _myHashBag getEntry(key, T) value as T
else if (T inheritsFrom?(storedType))
result = this _hashBag getEntry(key, T) value as T
}
result
}
getClass: func (key: String) -> Class {
return _myHashBag getClass(key)
this _hashBag getClass(key)
}
getEntry: func <V> (key: String, V: Class) -> HashEntry<String, Pointer> {
return _myHashBag getEntry(key, V)
}
put: func <T> (key: String, value: T) -> Bool {
if (_myHashBag contains?(key))
this remove(key)
return _myHashBag put(key, value)
this _hashBag getEntry(key, V)
}
/* WARNING: Covers must be wrapped into a Cell before adding to the dictionary */
add: func <T> (key: String, value: T) -> Bool {
return this put(key, value)
if (_hashBag contains?(key))
this remove(key)
if (T inheritsFrom?(Object))
this _hashBag put(key, value)
else {
cellValue := Cell<T> new(value)
this _hashBag put(key, cellValue)
}
}
empty?: func -> Bool { return _myHashBag empty?() }
remove: func (key: String) -> Bool {
return _myHashBag remove(key)
this _hashBag remove(key)
}
size: func -> Int { _myHashBag size() }
contains?: func (key: String) -> Bool {
return _myHashBag contains?(key)
contains: func (key: String) -> Bool {
this _hashBag contains?(key)
}
getKeys: func -> ArrayList<String> {
return _myHashBag getKeys()
this _hashBag getKeys()
}
getPath: func <T> (path: String, T: Class) -> T {
return _myHashBag getPath(path, T)
}
dispose: func {
free(this _myHashBag myMap keys data)
free(this _myHashBag myMap keys)
for (i in 0 .. (this _myHashBag myMap capacity)) {
next := (this _myHashBag myMap buckets[i])
next dispose()
}
free(this _myHashBag myMap buckets data)
free(this _myHashBag myMap)
free(this _myHashBag)
free(this)
this _hashBag getPath(path, T)
}
}

extend HashEntry {
dispose: func {
// free(this key as String _buffer)
free(this key)
free(this value)
if (this next != null) {
Expand Down
133 changes: 74 additions & 59 deletions test/collections/HashDictionaryTest.ooc
@@ -1,6 +1,6 @@
use ooc-base
use ooc-collections
use ooc-unit
import structs/ArrayList

TestClass: class {
intVal: Int
Expand All @@ -24,13 +24,16 @@ TestCover: cover {
}

HashDictionaryTest: class extends Fixture {
defaultCover := TestCover new()
defaultClass := TestClass new()

init: func {
super("HashDictionary")
this add("Int", func {
dictionary := HashDictionary new()
dictionary add("IntegerValue", 1)
expect(dictionary get("IntegerValue", 0) == 1, is true)
expect(dictionary get("Nonexistent", 0) == 0, is true)
expect(dictionary get("IntegerValue", 0), is equal to(1))
expect(dictionary get("Nonexistent", 0), is equal to(0))
})
this add("String", func {
dictionary := HashDictionary new()
Expand All @@ -40,41 +43,37 @@ HashDictionaryTest: class extends Fixture {
expect(dictionary get("IntegerValue", "Default") == "Default", is true)
expect(dictionary get("Nonexistent", "Default") == "Default", is true)
})

this add("Cover", func {
dictionary := HashDictionary new()
defaultCover := TestCover new()
testCover := TestCover new(1, "String")
dictionary add("TestClassValue", Cell new(testCover))
expect(dictionary get("TestClassValue", Cell new(defaultCover)) get() stringVal == "String", is true)
expect(dictionary get("Nonexistent", Cell new(defaultCover)) get() stringVal == "Default", is true)
expect(dictionary get("TestClassValue", Cell new(defaultCover)) get() intVal == 1, is true)
expect(dictionary get("Nonexistent", Cell new(defaultCover)) get() intVal == 0, is true)
dictionary add("TestClassValue", testCover)
expect(dictionary get("TestClassValue", this defaultCover) stringVal == "String", is true)
expect(dictionary get("Nonexistent", this defaultCover) stringVal == "Default", is true)
expect(dictionary get("TestClassValue", this defaultCover) intVal, is equal to(1))
expect(dictionary get("Nonexistent", this defaultCover) intVal, is equal to(0))
})

this add("Class", func {
dictionary := HashDictionary new()
defaultClass := TestClass new()
testClass := TestClass new(1, "String")
dictionary add("TestClassValue", testClass)
expect(dictionary get("TestClassValue", defaultClass) stringVal == "String", is true)
expect(dictionary get("Nonexistent", defaultClass) stringVal == "Default", is true)
expect(dictionary get("TestClassValue", defaultClass) intVal == 1, is true)
expect(dictionary get("Nonexistent", defaultClass) intVal == 0, is true)
expect(dictionary get("TestClassValue", this defaultClass) stringVal == "String", is true)
expect(dictionary get("Nonexistent", this defaultClass) stringVal == "Default", is true)
expect(dictionary get("TestClassValue", this defaultClass) intVal, is equal to(1))
expect(dictionary get("Nonexistent", this defaultClass) intVal, is equal to(0))
})
this add("ArrayList", func {
this add("VectorList", func {
dictionary := HashDictionary new()
arrayListDefault := ArrayList<String> new()
arrayListDefault add("zero")
arrayList := ArrayList<String> new()
arrayList add("one")
arrayList add("two")
arrayList add("three")
dictionary add("ArrayList", arrayList)
expect(dictionary get("ArrayList", arrayListDefault)[0] == "one", is true)
expect(dictionary get("ArrayList", arrayListDefault)[1] == "two", is true)
expect(dictionary get("ArrayList", arrayListDefault)[2] == "three", is true)
expect(dictionary get("Nonexistent", arrayListDefault)[0] == "zero", is true)
VectorListDefault := VectorList<String> new()
VectorListDefault add("zero")
vectorList := VectorList<String> new()
vectorList add("one")
vectorList add("two")
vectorList add("three")
dictionary add("VectorList", vectorList)
expect(dictionary get("VectorList", VectorListDefault)[0] == "one", is true)
expect(dictionary get("VectorList", VectorListDefault)[1] == "two", is true)
expect(dictionary get("VectorList", VectorListDefault)[2] == "three", is true)
expect(dictionary get("Nonexistent", VectorListDefault)[0] == "zero", is true)
})
this add("Copy constructor", func {
dictionary := HashDictionary new()
Expand All @@ -98,65 +97,81 @@ HashDictionaryTest: class extends Fixture {
expect(dictionary2 get("First", "Default") == "First", is true)
expect(dictionary2 get("Int", 0) == 1, is true)
})

this add("Get from primitive", func {
dictionary := HashDictionary new()
dictionary add("First", 1337)
expect(dictionary getAsType("First", Int) == 1337)
expect(dictionary getAsType("First", String) == null)
expect(dictionary getAsType("Second", Int) == null)
expect(dictionary getAsType("First", Cell<TestCover>) == null)
expect(dictionary getAsType("First", TestClass) == null)
dictionary add("Second", TestClass new(1337, "String"))
expect(dictionary get("First", 0), is equal to(1337))
expect(dictionary get("First", t"null") == t"null")
expect(dictionary get("Second", 0), is equal to(0))
expect(dictionary get("First", defaultCover) intVal, is equal to(0))
expect(dictionary get("First", null) == null)
expect(dictionary get("Second", defaultClass) intVal, is equal to(1337))
})

this add("Get from cover", func {
dictionary := HashDictionary new()
testCover := TestCover new(1337, "String")
dictionary add("First", Cell new(testCover))
expect(dictionary getAsType("First", Cell<TestCover>) get() intVal == 1337)
expect(dictionary getAsType("First", Cell<TestCover>) get() stringVal == "String")
expect(dictionary getAsType("Second", Cell<TestCover>) == null)
expect(dictionary getAsType("First", Int) == null)
expect(dictionary getAsType("First", TestClass) == null)
dictionary add("First", testCover)
expect(dictionary get("First", defaultCover) intVal, is equal to(1337))
expect(dictionary get("First", defaultCover) stringVal == "String")
expect(dictionary get("Second", defaultCover) intVal, is equal to(0))
expect(dictionary get("First", 0), is equal to(0))
expect(dictionary get("First", null) == null)
})

this add("Get from class", func {
dictionary := HashDictionary new()
dictionary add("First", TestClass new(1337, "String"))

expect(dictionary getAsType("First", TestClass) intVal == 1337)
expect(dictionary getAsType("First", TestClass) stringVal == "String")
expect(dictionary getAsType("Second", TestClass) == null)
expect(dictionary getAsType("First", Int) == null)
expect(dictionary getAsType("First", Cell<TestCover>) == null)
expect(dictionary get("First", defaultClass) intVal, is equal to(1337))
expect(dictionary get("First", defaultClass) stringVal == "String")
expect(dictionary get("Second", null) == null)
expect(dictionary get("First", 0), is equal to(0))
expect(dictionary get("First", defaultCover) intVal, is equal to(0))
})
this add("Merge", func {
dictionary := HashDictionary new()
dictionary add("First", 1337)
dictionary add("Second", "Foo")
dictionary add("Third", Cell new(TestCover new(42, "Hello")))
dictionary add("Third", TestCover new(42, "Hello"))
dictionary add("Fourth", TestClass new(101, "Darth"))
dictionary add("Fifth", "Almost")
dictionary add("Sixth", "Done")

dictionary2 := HashDictionary new()
dictionary2 add("First", 1338)
dictionary2 add("Second", "Bar")
dictionary2 add("Third", Cell new(TestCover new(43, "World")))
dictionary2 add("Third", TestCover new(43, "World"))
dictionary2 add("Fourth", TestClass new(102, "Vader"))
dictionary2 add("Sixth", 1002)

dictionary3 := dictionary merge(dictionary2)
expect(dictionary3 getAsType("First", Int) == 1338)
expect(dictionary3 getAsType("Second", String) == "Bar")
expect(dictionary3 getAsType("Third", Cell<TestCover>) get() intVal == 43)
expect(dictionary3 getAsType("Third", Cell<TestCover>) get() stringVal == "World")
expect(dictionary3 getAsType("Fourth", TestClass) intVal == 102)
expect(dictionary3 getAsType("Fourth", TestClass) stringVal == "Vader")
expect(dictionary3 getAsType("Fifth", String) == "Almost")
expect(dictionary3 getAsType("Sixth", Int) == 1002)
expect(dictionary3 getAsType("Sixth", String) == null)
expect(dictionary3 get("First", 0), is equal to(1338))
expect(dictionary3 get("Second", "null") == "Bar")
expect(dictionary3 get("Third", defaultCover) intVal, is equal to(43))
expect(dictionary3 get("Third", defaultCover) stringVal == "World")
expect(dictionary3 get("Fourth", defaultClass) intVal, is equal to(102))
expect(dictionary3 get("Fourth", defaultClass) stringVal == "Vader")
expect(dictionary3 get("Fifth", "null") == "Almost")
expect(dictionary3 get("Sixth", 0), is equal to(1002))
expect(dictionary3 get("Sixth", "null") == "null")
})
this add("Sizes", func {
dictionary := HashDictionary new()
dictionary add("First", 1)
dictionary add("Second", 2)
dictionary add("Third", 3)
expect(dictionary count, is equal to(3))
expect(dictionary empty, is false)
expect(dictionary contains("Second"), is true)
dictionary remove("Second")
expect(dictionary count, is equal to(2))
expect(dictionary empty, is false)
expect(dictionary contains("Second"), is false)
dictionary remove("Third")
dictionary remove("First")
expect(dictionary count, is equal to(0))
expect(dictionary empty, is true)
})
}
}

HashDictionaryTest new() run()
5 changes: 2 additions & 3 deletions test/collections/VectorListTest.ooc
Expand Up @@ -140,7 +140,7 @@ VectorListTest: class extends Fixture {
list add(3.0f)
list add(4.0f)
slice := list getSlice(1, 2)
expect(slice count == 2)
expect(slice count, is equal to(2))
expect(slice[0], is equal to(2.0f) within(tolerance))
expect(slice[1], is equal to(3.0f) within(tolerance))
sliceInto := VectorList<Float> new()
Expand Down Expand Up @@ -208,9 +208,8 @@ VectorListTest: class extends Fixture {
list add(32)
list add(64)
expect(list empty, is false)
while (!list empty) {
while (!list empty)
list removeAt(0)
}
expect(list empty, is true)
list free()
})
Expand Down

0 comments on commit e78108f

Please sign in to comment.