Skip to content

Commit

Permalink
100% LinkedListMap coverage (moonbitlang#585)
Browse files Browse the repository at this point in the history
* 100% coverage for linklistmap

* patch hash collision

* patch format
  • Loading branch information
Lampese authored Jun 20, 2024
1 parent e72597a commit 08de0b4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 41 deletions.
23 changes: 12 additions & 11 deletions builtin/linkedhashmap.mbt → builtin/linked_hash_map.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ struct Map[K, V] {

// Implementations

fn unwrap[X](self : X?) -> X {
match self {
None => panic()
Some(x) => x
}
}

fn power_2_above(x : Int, n : Int) -> Int {
for i = x {
if i >= n {
Expand Down Expand Up @@ -119,10 +126,7 @@ pub fn set[K : Hash + Eq, V](self : Map[K, V], key : K, value : V) -> Unit {
hash.land(self.capacity_mask),
insert_entry,
{ prev: None, next: None } {
i, idx, entry, node => {
if i == self.capacity {
panic()
}
i, idx, entry, node =>
match self.entries[idx] {
None => {
self.entries[idx] = Some(entry)
Expand Down Expand Up @@ -153,7 +157,6 @@ pub fn set[K : Hash + Eq, V](self : Map[K, V], key : K, value : V) -> Unit {
}
}
}
}
}
}

Expand Down Expand Up @@ -248,13 +251,11 @@ fn remove_entry[K : Eq, V](self : Map[K, V], entry : Entry[K, V]) -> Unit {
self.head = None
self.tail = None
} else {
match self.head {
Some(head) => if head == entry { self.head = node.next }
None => ()
if self.head.unwrap() == entry {
self.head = node.next
}
match self.tail {
Some(tail) => if tail == entry { self.tail = node.prev }
None => ()
if self.tail.unwrap() == entry {
self.tail = node.prev
}
match node.prev {
Some(prev) => self.list[prev.idx].next = node.next
Expand Down
76 changes: 46 additions & 30 deletions builtin/linkedhashmap_test.mbt → builtin/linked_hash_map_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -102,35 +102,6 @@ test "from_array" {
@assertion.assert_eq(m.get("c"), Some(3))?
}

test "remove" {
let m : Map[MyString, Int] = Map::new()
m.set("a", 1)
m.set("ab", 2)
m.set("bc", 2)
m.set("cd", 2)
m.set("abc", 3)
m.set("abcdef", 6)
m.remove("ab")
@assertion.assert_eq(m.size(), 5)?
@assertion.assert_eq(
m.debug_entries(),
"_,(0,a,1),(0,bc,2),(1,cd,2),(1,abc,3),_,(0,abcdef,6),_",
)?
}

test "remove_unexist_key" {
let m : Map[MyString, Int] = Map::new()
m.set("a", 1)
m.set("ab", 2)
m.set("abc", 3)
m.remove("d")
@assertion.assert_eq(m.size(), 3)?
@assertion.assert_eq(
m.debug_entries(),
"_,(0,a,1),(0,ab,2),(0,abc,3),_,_,_,_",
)?
}

test "size" {
let m : Map[String, Int] = Map::new()
@assertion.assert_eq(m.size(), 0)?
Expand All @@ -145,6 +116,8 @@ test "is_empty" {
@assertion.assert_eq(m.is_empty(), false)?
m.remove("a")
@assertion.assert_eq(m.is_empty(), true)?
m.remove("a")
@assertion.assert_eq(m.is_empty(), true)?
}

test "iter" {
Expand Down Expand Up @@ -668,7 +641,9 @@ test "op_equal" {
m1.set("b", 2)
m1.set("c", 3)
let m2 = { "a": 1, "b": 2, "c": 3 }
@assertion.assert_eq(m1 == m2, true)?
inspect(m1 == m2, content="true")?
inspect({ "a": 1 } == { }, content="false")?
inspect({ 1: 2, 2: 3 } == { 1: 3, 2: 4 }, content="false")?
}

test "to_string" {
Expand All @@ -679,3 +654,44 @@ test "to_string" {
m.set("c", 3)
inspect(m.to_string(), content="{a:1, b:2, c:3}")?
}

test "hash collision" {
let m : Map[MyString, Int] = Map::new()
m.set("a", 1)
m.set("ab", 2)
m.set("abc", 3)
inspect(m["d"], content="None")?
}

test "panic unwrap" {
(None : Unit?).unwrap()
}

test "remove" {
let m : Map[MyString, Int] = Map::new()
m.set("a", 1)
m.set("ab", 2)
m.set("bc", 2)
m.set("cd", 2)
m.set("abc", 3)
m.set("abcdef", 6)
m.remove("ab")
@assertion.assert_eq(m.size(), 5)?
@assertion.assert_eq(
m.debug_entries(),
"_,(0,a,1),(0,bc,2),(1,cd,2),(1,abc,3),_,(0,abcdef,6),_",
)?
}

test "remove_unexist_key" {
let m : Map[MyString, Int] = Map::new()
m.set("a", 1)
m.set("ab", 2)
m.set("abc", 3)
m.remove("d")
@assertion.assert_eq(m.size(), 3)?
@assertion.assert_eq(
m.debug_entries(),
"_,(0,a,1),(0,ab,2),(0,abc,3),_,_,_,_",
)?
}

0 comments on commit 08de0b4

Please sign in to comment.