$print {
/**
Running hash table tests...
*/
}
const each = proc {k,v} {
//assert ! [this.mayIterate] // fixme: why does this _not_ fail?
$print ' ' this '\t' typename k k '\t=\t' typename v v
//$print 'this =' this this.search this.insert
if(!argv.callee.checked){
argv.callee.checked =
assert 'CWAL_RC_ACCESS' === [catch{$this.insert "MUST FAIL" true}.codeString]
$print "Modification during iteration properly failed."
}
}
0 && scope {
// check valgrind...
const h [api.Hash 10000]
assert 'hash' === typename h
}
1 && scope {
$print "Hashtable #1..."
const h = [api.Hash 19];
assert [h.mayIterate]
//$print 'h =' h h.insert h.search
[h.insert "foo" "bar"]
assert [h.containsEntry "foo"]
assert ![h.containsEntry "bar"]
[h.insert "foo" "baz"]
h.foo = "the other foo"
$print 'get foo =' [h.search "foo"]
assert "the other foo" === h.foo
assert "baz" === [h.search "foo"]
$print h "table entries:"
$h.eachEntry each
assert 'function' === typename h.prototype.entryKeys
assert 'function' === typename h.prototype.prototype.propertyKeys
assert h.prototype.prototype.propertyKeys !== h.entryKeys
var pk = h.prototype.prototype.propertyKeys
assert 'function' === typename pk.apply
var pkeys = [pk.apply h]
$print 'pk.apply... ' pkeys
assert "the other foo" === h.(pkeys.0)
$print "ending scope"
}
0 && scope {
$print "Hashtable #2..."
var h;
scope {
h = [api.Hash 400];
assert (400 < [h.hashSize]) && (600 > [h.hashSize])
[h.insert "foo" "bar"]
[h.insert "foot" "baz"]
$print h "table entries:"
[h.eachEntry each]
[h.remove "foo"]
[h.remove "foot"]
$print "hash =" h
}
$print "ending scope" h
}
1 && scope {
$print "Hashtable #N..."
const h = [api.Hash 19];
assert 1 === refcount h
if(false){
[[[h.insert "1" "one"].
insert 1 "!"].
insert h h] /* ugly, huh? */
}else{
[h.insert "1" "one"]
[h.insert 1 "!"]
[h.insert h h]
}
assert 3 === refcount h
assert 3 === [h.entryCount]
[h.eachEntry each]
var keys = [h.entryKeys], vals = [h.entryValues]
assert 'array' === typename keys
assert 3 === [keys.length]
assert 'array' === typename vals
assert 3 === [vals.length]
assert vals.1 === [h.search keys.1]
$print h "table entries:"
[h.eachEntry each]
assert "one" === [h.search "1"]
assert "!" === [h.search 1]
const oldRc = refcount h
[h.remove h]
assert (oldRc-2) === refcount h
assert 2 === [h.entryCount]
$print "Hash table properties again:"
[h.eachEntry each]
keys = [h.entryKeys]
vals = [h.entryValues]
$print 'keys =' keys
$print 'values =' vals
assert 2 === [keys.length]
assert 2 === [vals.length]
[h.clearEntries]
assert 0 === [h.entryCount]
//$print "Hash table properties after clearing:"
//[h.eachEntry each]
//$print "(should be empty)"
}
1 && scope {
const obj object { a: 3, b: 5 }
const h [api.Hash]
$print "Hashtable #X..." h
h.cpProp = proc{from}{
const self = this
$from.eachProperty proc{k,v}{
[self.insert k v]
}
}
[h.cpProp obj]
assert 2 === [h.entryCount]
assert [h.entryValues].1 === obj.([h.entryKeys].1)
//$print "Copied properties:"
//[h.eachEntry each]
[h.insert 'a' 7]
assert 2 === [h.entryCount]
//$print "Modified copied properties:"
//[h.eachEntry each]
assert [h.search 'a'] !== obj.a
var n = 0
h.eachEntry(proc(){
n += 1
return false
})
assert 1 === n
n = 0
h.eachProperty(proc(){ n+=1; return false})
assert 1 === n
}
scope {
const ar = array[1,2,3,4]
var n = 0
ar.eachIndex(proc(){ return !((n += 1)===2)})
assert 2===n
}
scope {
const obj = object{
c:3, a:1, b:2
}
$api.ob.push
$print obj
const v1 = $api.ob.takeBuffer
[obj.sortProperties]
[print obj]
const v2 = $api.ob.takeBuffer
$api.ob.pop
assert v2 !== v1 /* this ACTUALLY does not necessarily hold
because the original _might_ (but probably was not)
accidentally sorted. */
// And to prove that the above comparison in valid...
var b1 = api.Buffer(10), b2 = api.Buffer(10)
$b1.append "hi"
$b2.append "hi"
assert b1 === b2
$b2.append "!"
assert b1 !== b2
assert 'CWAL_RC_ACCESS' === [catch{
$obj.eachProperty proc(){ [obj.sortProperties] }
}.codeString /* cannot sort while traversing */]
}
0 && scope {
// check valgrind...
const h [api.Hash 1000]
assert 'hash' === typename h
assert 1000 <= [h.hashSize]
}
$print "done"
return "hoorah for hashes!"