Skip to content

Commit 1da1e3a

Browse files
authored
test: add a few tests (#4)
1 parent ece8611 commit 1da1e3a

File tree

7 files changed

+385
-12
lines changed

7 files changed

+385
-12
lines changed

Cargo.lock

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ inquire = "0.7.5"
1313
log = { version = "0.4.21", features = ["std"] }
1414
regex = { version = "1.10.4", features = ["std"] }
1515
serde = { version = "1.0.202", features = ["derive"] }
16+
tempfile = "3.10.1"

src/commands/interactive.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::time::Duration;
2-
31
use clap::Args;
42

53
use crate::{
@@ -8,7 +6,7 @@ use crate::{
86
database,
97
maps::page_map::{PageMap, PageMapResult},
108
},
11-
indication::{spinner, ProgressBuilder},
9+
indication::ProgressBuilder,
1210
};
1311

1412
use super::ArgExecutor;

src/data/algorithm/bfs.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use log::debug;
55
use crate::data::maps::link_map::LinkMap;
66

77
pub fn find_shortest_path(start: i32, end: i32, links: &LinkMap) -> Option<Vec<i32>> {
8+
if start == end {
9+
return Some(vec![start]);
10+
}
11+
812
let mut queue = VecDeque::new();
913
let mut predecessor = HashMap::new();
1014
let mut visited = HashSet::new(); // note: having a set of visited nodes improves performance by a few percent while increasing memory usage
@@ -50,3 +54,88 @@ pub fn find_shortest_path(start: i32, end: i32, links: &LinkMap) -> Option<Vec<i
5054

5155
None
5256
}
57+
58+
mod test {
59+
#[allow(unused_imports)]
60+
use crate::{data::maps::link_map::LinkMap, indication::ProgressBuilder};
61+
62+
#[test]
63+
fn direct_link() {
64+
let link_map = LinkMap::new_with_progress(
65+
vec![(1, 2), (1, 3), (3, 2)].into_iter().collect(),
66+
ProgressBuilder::empty(),
67+
);
68+
69+
let path = super::find_shortest_path(1, 2, &link_map);
70+
71+
assert_eq!(path, Some(vec![1, 2]));
72+
}
73+
74+
#[test]
75+
fn start_is_end() {
76+
let link_map = LinkMap::new_with_progress(
77+
vec![(1, 2), (1, 3), (3, 2)].into_iter().collect(),
78+
ProgressBuilder::empty(),
79+
);
80+
81+
let path = super::find_shortest_path(1, 1, &link_map);
82+
83+
assert_eq!(path, Some(vec![1]));
84+
}
85+
86+
#[test]
87+
fn no_way() {
88+
let link_map = LinkMap::new_with_progress(
89+
vec![(1, 2), (1, 3), (3, 2)].into_iter().collect(),
90+
ProgressBuilder::empty(),
91+
);
92+
93+
let path = super::find_shortest_path(2, 1, &link_map);
94+
95+
assert_eq!(path, None);
96+
}
97+
98+
#[test]
99+
fn single_possibility() {
100+
let link_map = LinkMap::new_with_progress(
101+
vec![(1, 2), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5)]
102+
.into_iter()
103+
.collect(),
104+
ProgressBuilder::empty(),
105+
);
106+
107+
let path = super::find_shortest_path(1, 4, &link_map);
108+
109+
assert_eq!(path, Some(vec![1, 2, 3, 4]));
110+
}
111+
112+
#[test]
113+
fn multiple_possibilities_one_shortest() {
114+
// path over 1->2->3->4 and 1->5->4
115+
let link_map = LinkMap::new_with_progress(
116+
vec![(1, 2), (2, 3), (3, 4), (1, 5), (5, 4)]
117+
.into_iter()
118+
.collect(),
119+
ProgressBuilder::empty(),
120+
);
121+
122+
let path = super::find_shortest_path(1, 4, &link_map);
123+
124+
assert_eq!(path, Some(vec![1, 5, 4]));
125+
}
126+
127+
#[test]
128+
fn equal_length_uses_first_in_map() {
129+
// path over 1->2->3->4 and 1->5->6->4
130+
let link_map = LinkMap::new_with_progress(
131+
vec![(1, 2), (2, 3), (3, 4), (1, 5), (5, 6), (6, 4)]
132+
.into_iter()
133+
.collect(),
134+
ProgressBuilder::empty(),
135+
);
136+
137+
let path = super::find_shortest_path(1, 4, &link_map);
138+
139+
assert_eq!(path, Some(vec![1, 2, 3, 4]));
140+
}
141+
}

src/data/maps/link_map.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ impl LinkMap {
2121

2222
let (shrink_every, progress_every) = {
2323
let links_count = links.len();
24-
(links_count / 1000, links_count / 1000)
24+
if links_count < 1000 {
25+
(1, 1)
26+
} else {
27+
(links_count / 1000, links_count / 1000)
28+
}
2529
};
2630

2731
while let Some((from, to)) = links.pop_front() {
@@ -46,11 +50,18 @@ impl LinkMap {
4650
LinkMap { forward: map }
4751
}
4852

49-
pub fn new(links: VecDeque<LinkResolved>) -> LinkMap {
50-
LinkMap::new_with_progress(links, ProgressBuilder::empty())
51-
}
52-
5353
pub fn get(&self, from: i32) -> Option<&Vec<i32>> {
5454
self.forward.get(&from)
5555
}
5656
}
57+
58+
#[test]
59+
fn new_link_map() {
60+
let links = vec![(1, 2), (1, 3), (3, 2)].into_iter().collect();
61+
62+
let map = LinkMap::new_with_progress(links, ProgressBuilder::empty());
63+
64+
assert_eq!(map.get(1), Some(&vec![2, 3]));
65+
assert_eq!(map.get(2), None);
66+
assert_eq!(map.get(3), Some(&vec![2]));
67+
}

src/data/maps/page_map.rs

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct PageMap {
1515
id_to_redirect: HashMap<i32, i32>,
1616
}
1717

18+
#[derive(Debug, PartialEq)]
1819
pub struct PageMapResult {
1920
pub id: i32,
2021
pub title: String,
@@ -61,10 +62,6 @@ impl PageMap {
6162
}
6263
}
6364

64-
pub fn new(pages: VecDeque<Page>, redirect: VecDeque<Redirect>) -> Self {
65-
Self::new_internal(pages, redirect, ProgressBuilder::empty())
66-
}
67-
6865
pub fn new_with_progress(
6966
pages: VecDeque<Page>,
7067
redirect: VecDeque<Redirect>,
@@ -113,3 +110,126 @@ impl PageMap {
113110
Some(page)
114111
}
115112
}
113+
114+
#[test]
115+
fn new_page_map() {
116+
let pages = {
117+
let pages = vec![
118+
Page {
119+
id: 1,
120+
title: "Page 1".to_string(),
121+
redirect: false,
122+
},
123+
Page {
124+
id: 2,
125+
title: "Page 2".to_string(),
126+
redirect: false,
127+
},
128+
Page {
129+
id: 3,
130+
title: "Also Page 2".to_string(),
131+
redirect: true,
132+
},
133+
];
134+
VecDeque::from(pages)
135+
};
136+
137+
let redirects = {
138+
let redirects = vec![Redirect {
139+
id: 3,
140+
title: "Page 2".to_string(),
141+
}];
142+
VecDeque::from(redirects)
143+
};
144+
145+
let map = PageMap::new_with_progress(pages, redirects, ProgressBuilder::empty());
146+
147+
assert_eq!(map.name_to_id("Page 1"), Some(1));
148+
assert_eq!(map.name_to_id("Page 2"), Some(2));
149+
assert_eq!(map.name_to_id("Also Page 2"), Some(3));
150+
151+
assert_eq!(map.id_to_name(1), Some("Page 1"));
152+
assert_eq!(map.id_to_name(2), Some("Page 2"));
153+
assert_eq!(map.id_to_name(3), Some("Also Page 2"));
154+
155+
assert_eq!(map.id_to_redirect(1), None);
156+
assert_eq!(map.id_to_redirect(2), None);
157+
assert_eq!(map.id_to_redirect(3), Some(2));
158+
159+
assert_eq!(
160+
map.lookup_title("Page 1"),
161+
Some(PageMapResult {
162+
id: 1,
163+
title: "Page 1".to_string(),
164+
redirect: None
165+
})
166+
);
167+
assert_eq!(
168+
map.lookup_title("Page 2"),
169+
Some(PageMapResult {
170+
id: 2,
171+
title: "Page 2".to_string(),
172+
redirect: None
173+
})
174+
);
175+
assert_eq!(
176+
map.lookup_title("Also Page 2"),
177+
Some(PageMapResult {
178+
id: 3,
179+
title: "Also Page 2".to_string(),
180+
redirect: Some(2)
181+
})
182+
);
183+
184+
assert_eq!(
185+
map.lookup_id(1),
186+
Some(PageMapResult {
187+
id: 1,
188+
title: "Page 1".to_string(),
189+
redirect: None
190+
})
191+
);
192+
assert_eq!(
193+
map.lookup_id(2),
194+
Some(PageMapResult {
195+
id: 2,
196+
title: "Page 2".to_string(),
197+
redirect: None
198+
})
199+
);
200+
assert_eq!(
201+
map.lookup_id(3),
202+
Some(PageMapResult {
203+
id: 3,
204+
title: "Also Page 2".to_string(),
205+
redirect: Some(2)
206+
})
207+
);
208+
209+
assert_eq!(
210+
map.resolve_by_title("Page 1"),
211+
Some(PageMapResult {
212+
id: 1,
213+
title: "Page 1".to_string(),
214+
redirect: None
215+
})
216+
);
217+
218+
assert_eq!(
219+
map.resolve_by_title("Page 2"),
220+
Some(PageMapResult {
221+
id: 2,
222+
title: "Page 2".to_string(),
223+
redirect: None
224+
})
225+
);
226+
227+
assert_eq!(
228+
map.resolve_by_title("Also Page 2"),
229+
Some(PageMapResult {
230+
id: 2,
231+
title: "Page 2".to_string(),
232+
redirect: None
233+
})
234+
);
235+
}

0 commit comments

Comments
 (0)