Skip to content

Commit fd75b52

Browse files
committed
Move integration tests
The remaining tests in the lib.rs file appear to be integration tests for example files. According to [the book](https://doc.rust-lang.org/stable/book/ch11-03-test-organization.html#integration-tests) these should go into `tests/` and use the crate externally. This commit makes this change and necessary exposure of public methods.
1 parent 5c9abb1 commit fd75b52

File tree

4 files changed

+155
-157
lines changed

4 files changed

+155
-157
lines changed

src/ideal.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,27 +92,27 @@ impl Ideal {
9292
Ideal(vec![val; dimension])
9393
}
9494

95-
pub(crate) fn from_vec(vec: Vec<Coef>) -> Ideal {
95+
pub fn from_vec(vec: Vec<Coef>) -> Ideal {
9696
Ideal(vec)
9797
}
9898

9999
pub fn is_below(&self, other: &Self) -> bool {
100100
self.0.iter().enumerate().all(|(i, &x)| x <= other.0[i])
101101
}
102102

103-
pub(crate) fn len(&self) -> usize {
103+
pub fn len(&self) -> usize {
104104
self.0.len()
105105
}
106106

107-
pub(crate) fn get(&self, i: usize) -> Coef {
107+
pub fn get(&self, i: usize) -> Coef {
108108
self.0[i]
109109
}
110110

111-
pub(crate) fn set(&mut self, state: usize, val: Coef) {
111+
pub fn set(&mut self, state: usize, val: Coef) {
112112
self.0[state] = val;
113113
}
114114

115-
pub(crate) fn intersection(x: &Ideal, ideal: &Ideal) -> Ideal {
115+
pub fn intersection(x: &Ideal, ideal: &Ideal) -> Ideal {
116116
debug_assert_eq!(x.len(), ideal.len());
117117
Ideal(
118118
x.0.iter()
@@ -124,7 +124,7 @@ impl Ideal {
124124
}
125125

126126
#[allow(dead_code)]
127-
pub(crate) fn from_non_zero_coefs(
127+
pub fn from_non_zero_coefs(
128128
dim: usize,
129129
partition: &[coef],
130130
predecessors: &[usize],
@@ -137,11 +137,11 @@ impl Ideal {
137137
Ideal(result)
138138
}
139139

140-
pub(crate) fn all_omega(&self, succ: &[usize]) -> bool {
140+
pub fn all_omega(&self, succ: &[usize]) -> bool {
141141
succ.iter().all(|&i| self.get(i) == OMEGA)
142142
}
143143

144-
pub(crate) fn round_up(&mut self, max_finite_value: coef) -> Ideal {
144+
pub fn round_up(&mut self, max_finite_value: coef) -> Ideal {
145145
Ideal(
146146
self.0
147147
.iter()
@@ -150,7 +150,7 @@ impl Ideal {
150150
)
151151
}
152152

153-
pub(crate) fn round_down(&mut self, upper_bound: coef, dim: usize) {
153+
pub fn round_down(&mut self, upper_bound: coef, dim: usize) {
154154
for i in 0..dim {
155155
if let Coef::Value(x) = self.get(i) {
156156
if x > upper_bound {
@@ -160,7 +160,7 @@ impl Ideal {
160160
}
161161
}
162162

163-
pub(crate) fn some_finite_coordinate_is_larger_than(&self, upper_bound: coef) -> bool {
163+
pub fn some_finite_coordinate_is_larger_than(&self, upper_bound: coef) -> bool {
164164
self.0
165165
.iter()
166166
.any(|&x| x < OMEGA && x > Coef::Value(upper_bound))
@@ -178,7 +178,7 @@ impl Ideal {
178178
content
179179
}
180180

181-
pub(crate) fn iter(&self) -> impl Iterator<Item = &Coef> {
181+
pub fn iter(&self) -> impl Iterator<Item = &Coef> {
182182
self.0.iter()
183183
}
184184

@@ -190,7 +190,7 @@ impl Ideal {
190190
}
191191
}
192192

193-
pub(crate) fn clone_and_decrease(&self, i: usize, maximal_finite_value: coef) -> Ideal {
193+
pub fn clone_and_decrease(&self, i: usize, maximal_finite_value: coef) -> Ideal {
194194
let mut result: Ideal = self.clone();
195195
let c = result.0[i];
196196
debug_assert!(c != Coef::Value(0));

src/lib.rs

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -12,146 +12,3 @@ pub mod solver;
1212
pub mod strategy;
1313

1414

15-
#[cfg(test)]
16-
mod tests {
17-
use super::*;
18-
use crate::coef::{C0, C1, C2, OMEGA};
19-
use crate::downset::DownSet;
20-
use crate::ideal::Ideal;
21-
22-
const EXAMPLE1: &str = include_str!("../examples/bottleneck-1-ab.tikz");
23-
const EXAMPLE1_COMPLETE: &str = include_str!("../examples/bottleneck-1-ab-complete.tikz");
24-
const EXAMPLE2: &str = include_str!("../examples/bottleneck-2.tikz");
25-
const EXAMPLE_BUG12: &str = include_str!("../examples/bug12.tikz");
26-
27-
#[test]
28-
fn test_example_1() {
29-
let nfa = nfa::Nfa::from_tikz(EXAMPLE1);
30-
let solution = solver::solve(&nfa, &solver::SolverOutput::YesNo);
31-
print!("{}", solution);
32-
assert!(!solution.is_controllable);
33-
assert_eq!(solution.winning_strategy.iter().count(), 2);
34-
let downseta = solution
35-
.winning_strategy
36-
.iter()
37-
.filter(|x| x.0 == "a")
38-
.map(|x| x.1)
39-
.next()
40-
.unwrap();
41-
let downsetb = solution
42-
.winning_strategy
43-
.iter()
44-
.filter(|x| x.0 == "b")
45-
.map(|x| x.1)
46-
.next()
47-
.unwrap();
48-
49-
assert_eq!(
50-
*downseta,
51-
DownSet::from_vecs(&[&[C1, C0, C0, C0, C0], &[C0, OMEGA, C0, C0, C0]])
52-
);
53-
assert_eq!(*downsetb, DownSet::from_vecs(&[&[C0, C0, OMEGA, C0, C0]]));
54-
}
55-
56-
#[test]
57-
fn test_example_1bis() {
58-
let nfa = nfa::Nfa::from_tikz(EXAMPLE1_COMPLETE);
59-
let solution = solver::solve(&nfa, &solver::SolverOutput::YesNo);
60-
print!("{}", solution);
61-
assert!(!solution.is_controllable);
62-
assert_eq!(solution.winning_strategy.iter().count(), 2);
63-
let downseta = solution
64-
.winning_strategy
65-
.iter()
66-
.filter(|x| x.0 == "a")
67-
.map(|x| x.1)
68-
.next()
69-
.unwrap();
70-
let downsetb = solution
71-
.winning_strategy
72-
.iter()
73-
.filter(|x| x.0 == "b")
74-
.map(|x| x.1)
75-
.next()
76-
.unwrap();
77-
78-
assert_eq!(
79-
*downseta,
80-
DownSet::from_vecs(&[&[C1, OMEGA, C0, OMEGA, C0]])
81-
);
82-
assert_eq!(
83-
*downsetb,
84-
DownSet::from_vecs(&[&[C0, C0, OMEGA, OMEGA, C0]])
85-
);
86-
}
87-
88-
#[test]
89-
fn test_example_2() {
90-
let nfa = nfa::Nfa::from_tikz(EXAMPLE2);
91-
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
92-
print!("{}", solution);
93-
assert!(!solution.is_controllable);
94-
assert_eq!(solution.winning_strategy.iter().count(), 4);
95-
let downseta = solution
96-
.winning_strategy
97-
.iter()
98-
.filter(|x| x.0 == "a")
99-
.map(|x| x.1)
100-
.next()
101-
.unwrap();
102-
103-
assert_eq!(*downseta, DownSet::from_vecs(&[&[C2, C0, C0, C0, C0]]));
104-
}
105-
106-
#[test]
107-
fn test_example_2_sorted_alpha() {
108-
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE2);
109-
nfa.sort(&nfa::StateOrdering::Alphabetical);
110-
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
111-
assert!(!solution.is_controllable);
112-
assert_eq!(solution.winning_strategy.iter().count(), 4);
113-
let downseta = solution
114-
.winning_strategy
115-
.iter()
116-
.filter(|x| x.0 == "a")
117-
.map(|x| x.1)
118-
.next()
119-
.unwrap();
120-
121-
assert_eq!(*downseta, DownSet::from_vecs(&[&[C0, C0, C0, C0, C2]]));
122-
}
123-
124-
#[test]
125-
fn test_example_2_sorted_topo() {
126-
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE2);
127-
nfa.sort(&nfa::StateOrdering::Topological);
128-
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
129-
assert!(!solution.is_controllable);
130-
assert_eq!(solution.winning_strategy.iter().count(), 4);
131-
let downseta = solution
132-
.winning_strategy
133-
.iter()
134-
.filter(|x| x.0 == "a")
135-
.map(|x| x.1)
136-
.next()
137-
.unwrap();
138-
139-
assert_eq!(*downseta, DownSet::from_vecs(&[&[C2, C0, C0, C0, C0]]));
140-
}
141-
142-
#[test]
143-
fn test_bug12() {
144-
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE_BUG12);
145-
nfa.sort(&nfa::StateOrdering::Topological);
146-
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
147-
let downsetb = solution
148-
.winning_strategy
149-
.iter()
150-
.filter(|x| x.0 == "b")
151-
.map(|x| x.1)
152-
.next()
153-
.unwrap();
154-
println!("{}", downsetb);
155-
assert!(downsetb.contains(&Ideal::from_vec(vec![C2, C0, C0, C0, C0, C0, C0, C0])));
156-
}
157-
}

src/strategy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl Strategy {
2929
self.0.values().any(|downset| downset.contains(source))
3030
}
3131

32-
pub(crate) fn restrict_to(
32+
pub fn restrict_to(
3333
&mut self,
3434
safe: DownSet,
3535
edges_per_letter: &HashMap<nfa::Letter, Graph>,
@@ -46,7 +46,7 @@ impl Strategy {
4646
result
4747
}
4848

49-
pub(crate) fn iter(&self) -> impl Iterator<Item = (&nfa::Letter, &DownSet)> {
49+
pub fn iter(&self) -> impl Iterator<Item = (&nfa::Letter, &DownSet)> {
5050
self.0.iter()
5151
}
5252

tests/integration_test.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use shepherd::nfa;
2+
use shepherd::solver;
3+
use shepherd::coef::{C0, C1, C2, OMEGA};
4+
use shepherd::downset::DownSet;
5+
use shepherd::ideal::Ideal;
6+
7+
const EXAMPLE1: &str = include_str!("../examples/bottleneck-1-ab.tikz");
8+
const EXAMPLE1_COMPLETE: &str = include_str!("../examples/bottleneck-1-ab-complete.tikz");
9+
const EXAMPLE2: &str = include_str!("../examples/bottleneck-2.tikz");
10+
const EXAMPLE_BUG12: &str = include_str!("../examples/bug12.tikz");
11+
12+
#[test]
13+
fn test_example_1() {
14+
let nfa = nfa::Nfa::from_tikz(EXAMPLE1);
15+
let solution = solver::solve(&nfa, &solver::SolverOutput::YesNo);
16+
print!("{}", solution);
17+
assert!(!solution.is_controllable);
18+
assert_eq!(solution.winning_strategy.iter().count(), 2);
19+
let downseta = solution
20+
.winning_strategy
21+
.iter()
22+
.filter(|x| x.0 == "a")
23+
.map(|x| x.1)
24+
.next()
25+
.unwrap();
26+
let downsetb = solution
27+
.winning_strategy
28+
.iter()
29+
.filter(|x| x.0 == "b")
30+
.map(|x| x.1)
31+
.next()
32+
.unwrap();
33+
34+
assert_eq!(
35+
*downseta,
36+
DownSet::from_vecs(&[&[C1, C0, C0, C0, C0], &[C0, OMEGA, C0, C0, C0]])
37+
);
38+
assert_eq!(*downsetb, DownSet::from_vecs(&[&[C0, C0, OMEGA, C0, C0]]));
39+
}
40+
41+
#[test]
42+
fn test_example_1bis() {
43+
let nfa = nfa::Nfa::from_tikz(EXAMPLE1_COMPLETE);
44+
let solution = solver::solve(&nfa, &solver::SolverOutput::YesNo);
45+
print!("{}", solution);
46+
assert!(!solution.is_controllable);
47+
assert_eq!(solution.winning_strategy.iter().count(), 2);
48+
let downseta = solution
49+
.winning_strategy
50+
.iter()
51+
.filter(|x| x.0 == "a")
52+
.map(|x| x.1)
53+
.next()
54+
.unwrap();
55+
let downsetb = solution
56+
.winning_strategy
57+
.iter()
58+
.filter(|x| x.0 == "b")
59+
.map(|x| x.1)
60+
.next()
61+
.unwrap();
62+
63+
assert_eq!(
64+
*downseta,
65+
DownSet::from_vecs(&[&[C1, OMEGA, C0, OMEGA, C0]])
66+
);
67+
assert_eq!(
68+
*downsetb,
69+
DownSet::from_vecs(&[&[C0, C0, OMEGA, OMEGA, C0]])
70+
);
71+
}
72+
73+
#[test]
74+
fn test_example_2() {
75+
let nfa = nfa::Nfa::from_tikz(EXAMPLE2);
76+
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
77+
print!("{}", solution);
78+
assert!(!solution.is_controllable);
79+
assert_eq!(solution.winning_strategy.iter().count(), 4);
80+
let downseta = solution
81+
.winning_strategy
82+
.iter()
83+
.filter(|x| x.0 == "a")
84+
.map(|x| x.1)
85+
.next()
86+
.unwrap();
87+
88+
assert_eq!(*downseta, DownSet::from_vecs(&[&[C2, C0, C0, C0, C0]]));
89+
}
90+
91+
#[test]
92+
fn test_example_2_sorted_alpha() {
93+
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE2);
94+
nfa.sort(&nfa::StateOrdering::Alphabetical);
95+
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
96+
assert!(!solution.is_controllable);
97+
assert_eq!(solution.winning_strategy.iter().count(), 4);
98+
let downseta = solution
99+
.winning_strategy
100+
.iter()
101+
.filter(|x| x.0 == "a")
102+
.map(|x| x.1)
103+
.next()
104+
.unwrap();
105+
106+
assert_eq!(*downseta, DownSet::from_vecs(&[&[C0, C0, C0, C0, C2]]));
107+
}
108+
109+
#[test]
110+
fn test_example_2_sorted_topo() {
111+
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE2);
112+
nfa.sort(&nfa::StateOrdering::Topological);
113+
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
114+
assert!(!solution.is_controllable);
115+
assert_eq!(solution.winning_strategy.iter().count(), 4);
116+
let downseta = solution
117+
.winning_strategy
118+
.iter()
119+
.filter(|x| x.0 == "a")
120+
.map(|x| x.1)
121+
.next()
122+
.unwrap();
123+
124+
assert_eq!(*downseta, DownSet::from_vecs(&[&[C2, C0, C0, C0, C0]]));
125+
}
126+
127+
#[test]
128+
fn test_bug12() {
129+
let mut nfa = nfa::Nfa::from_tikz(EXAMPLE_BUG12);
130+
nfa.sort(&nfa::StateOrdering::Topological);
131+
let solution = solver::solve(&nfa, &solver::SolverOutput::Strategy);
132+
let downsetb = solution
133+
.winning_strategy
134+
.iter()
135+
.filter(|x| x.0 == "b")
136+
.map(|x| x.1)
137+
.next()
138+
.unwrap();
139+
println!("{}", downsetb);
140+
assert!(downsetb.contains(&Ideal::from_vec(vec![C2, C0, C0, C0, C0, C0, C0, C0])));
141+
}

0 commit comments

Comments
 (0)