Skip to content

Commit 4f71bc0

Browse files
committed
Add tests for graph.add_module
1 parent b8ee7f0 commit 4f71bc0

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

rust/src/graph.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::hierarchy::ModuleHierarchy;
1+
use crate::hierarchy::{ModuleHierarchy, ModuleIterator};
22
use crate::imports::{ImportDetails, ModuleImports};
33
use anyhow::Result;
44
use std::collections::HashSet;
@@ -46,7 +46,11 @@ impl Graph {
4646
}
4747

4848
pub fn get_modules(&self) -> HashSet<&str> {
49-
todo!()
49+
self.hierarchy
50+
.all()
51+
.visible()
52+
.names()
53+
.collect()
5054
}
5155

5256
pub fn count_imports(&self) -> usize {
@@ -150,3 +154,45 @@ impl Graph {
150154
todo!()
151155
}
152156
}
157+
158+
#[cfg(test)]
159+
mod tests {
160+
use super::*;
161+
162+
#[test]
163+
fn add_module() -> Result<()> {
164+
let mut graph = Graph::default();
165+
166+
graph.add_module("mypackage")?;
167+
168+
let result = graph.get_modules();
169+
170+
assert_eq!(result, HashSet::from(["mypackage"]));
171+
Ok(())
172+
}
173+
174+
#[test]
175+
fn add_module_doesnt_add_parent() -> Result<()> {
176+
let mut graph = Graph::default();
177+
178+
graph.add_module("mypackage.foo")?;
179+
180+
let result = graph.get_modules();
181+
182+
assert_eq!(result, HashSet::from(["mypackage.foo"]));
183+
Ok(())
184+
}
185+
186+
#[test]
187+
fn add_modules() -> Result<()> {
188+
let mut graph = Graph::default();
189+
190+
graph.add_module("mypackage")?;
191+
graph.add_module("mypackage.foo")?;
192+
193+
let result = graph.get_modules();
194+
195+
assert_eq!(result, HashSet::from(["mypackage", "mypackage.foo"]));
196+
Ok(())
197+
}
198+
}

rust/src/hierarchy.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ impl ModuleHierarchy {
118118
}
119119
}
120120

121+
// TODO(peter) Do we want this?
122+
// `add_module` already has "get or insert" semantics. The difference here is just that
123+
// `get_by_name_or_add` is not making the module visible.
121124
pub fn get_by_name_or_add(&mut self, name: &str) -> Result<&Module> {
122125
let token = match self.get_by_name(name) {
123126
Some(module) => module.token,
@@ -131,6 +134,11 @@ impl ModuleHierarchy {
131134
self.modules.get(module)
132135
}
133136

137+
// TODO(peter) Guarantee order?
138+
pub fn all(&self) -> impl Iterator<Item = &Module> {
139+
self.modules.values()
140+
}
141+
134142
pub fn get_parent(&self, module: ModuleToken) -> Option<&Module> {
135143
match self.module_parents.get(module) {
136144
Some(parent) => parent.map(|parent| self.get(parent).unwrap()),
@@ -196,6 +204,22 @@ impl<T: Sized + Clone + IntoIterator<Item = ModuleToken> + Extend<ModuleToken>>
196204
{
197205
}
198206

207+
pub trait ModuleIterator<'a>: Iterator<Item = &'a Module> + Sized {
208+
fn tokens(self) -> impl Iterator<Item = ModuleToken> {
209+
self.map(|m| m.token)
210+
}
211+
212+
fn names(self) -> impl Iterator<Item = &'a str> {
213+
self.map(|m| m.name.as_str())
214+
}
215+
216+
fn visible(self) -> impl Iterator<Item = &'a Module> {
217+
self.filter(|m| !m.is_invisible)
218+
}
219+
}
220+
221+
impl<'a, T: Iterator<Item = &'a Module>> ModuleIterator<'a> for T {}
222+
199223
fn parent_name(name: &str) -> Option<String> {
200224
match name.rsplit_once(".") {
201225
Some((base, _)) => Some(base.to_owned()),

0 commit comments

Comments
 (0)