Skip to content

Commit 3e0f7d5

Browse files
Merge pull request #1039 from tgnottingham/interp-and-average
Fix `Interpolate` iterator indicating incorrect interpolation and add some tests
2 parents b5ca7de + af8df13 commit 3e0f7d5

File tree

2 files changed

+143
-2
lines changed

2 files changed

+143
-2
lines changed

site/src/average.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ where
4343
}
4444
Some(point) => {
4545
count += 1;
46-
sum += point.value().expect("present");
46+
sum += point
47+
.value()
48+
.expect("Uninterpolated iterators are not supported");
4749
i += 1;
4850
if let Some(t) = &mut first {
4951
if point.interpolated() {
@@ -75,3 +77,77 @@ where
7577
}
7678
}
7779
}
80+
81+
#[cfg(test)]
82+
mod tests {
83+
use super::average;
84+
85+
#[test]
86+
fn test_no_interpolation_average() {
87+
// Test that averaging works without interpolation.
88+
use crate::db::Point;
89+
90+
let v = vec![
91+
vec![("a", 0.0), ("b", 200.0)],
92+
vec![("a", 100.0), ("b", 300.0)],
93+
];
94+
95+
let iterators: Vec<_> = v.into_iter().map(|v| v.into_iter()).collect();
96+
let mut average = average(iterators);
97+
98+
let a = average.next().unwrap();
99+
assert_eq!(a, ("a", 50.0));
100+
assert_eq!(a.interpolated(), false);
101+
102+
let b = average.next().unwrap();
103+
assert_eq!(b, ("b", 250.0));
104+
assert_eq!(b.interpolated(), false);
105+
106+
assert!(average.next().is_none());
107+
}
108+
109+
#[test]
110+
fn test_interpolation_average() {
111+
// Test that averaging works with interpolation.
112+
use crate::db::Point;
113+
use crate::interpolate::{Interpolate, Interpolated};
114+
115+
let v = vec![
116+
vec![("a", Some(0.0)), ("b", Some(200.0))],
117+
vec![("a", Some(100.0)), ("b", None)],
118+
];
119+
120+
let iterators: Vec<_> = v
121+
.into_iter()
122+
.map(|v| Interpolate::new(v.into_iter()))
123+
.collect();
124+
125+
let mut average = average(iterators);
126+
127+
let a = average.next().unwrap();
128+
assert_eq!(a, (("a", Some(50.0)), Interpolated::No));
129+
assert_eq!(a.interpolated(), false);
130+
131+
let b = average.next().unwrap();
132+
assert_eq!(b, (("b", Some(150.0)), Interpolated::Yes));
133+
assert_eq!(b.interpolated(), true);
134+
135+
assert!(average.next().is_none());
136+
}
137+
138+
#[test]
139+
#[should_panic(expected = "Uninterpolated iterators are not supported")]
140+
fn test_uninterpolated_iterator() {
141+
let v = vec![vec![("a", Some(1.0)), ("b", Some(2.0))], vec![("a", None)]];
142+
let iterators: Vec<_> = v.into_iter().map(|v| v.into_iter()).collect();
143+
let _ = average(iterators).next();
144+
}
145+
146+
#[test]
147+
#[should_panic(expected = "Not all iterators of the same length")]
148+
fn test_unequal_length_iterators() {
149+
let v = vec![vec![("a", 1.0), ("b", 2.0)], vec![("a", 3.0)]];
150+
let iterators: Vec<_> = v.into_iter().map(|v| v.into_iter()).collect();
151+
for _ in average(iterators) {}
152+
}
153+
}

site/src/interpolate.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ where
8181
fn next(&mut self) -> Option<Self::Item> {
8282
if let Some(mut item) = self.consumed.pop() {
8383
item.set_value(self.last_seen.unwrap());
84-
return Some((item, Interpolated::Yes));
84+
let interpolation = if self.consumed.is_empty() {
85+
Interpolated::No
86+
} else {
87+
Interpolated::Yes
88+
};
89+
return Some((item, interpolation));
8590
}
8691

8792
let mut item = self.iterator.next()?;
@@ -131,3 +136,63 @@ where
131136
}
132137
}
133138
}
139+
140+
#[cfg(test)]
141+
mod tests {
142+
use super::{Interpolate, Interpolated};
143+
144+
#[test]
145+
fn test_no_interpolation() {
146+
let v = vec![("a", 1.0), ("b", 2.0)];
147+
let mut iter = Interpolate::new(v.into_iter());
148+
149+
assert_eq!(iter.next().unwrap(), (("a", 1.0), Interpolated::No));
150+
assert_eq!(iter.next().unwrap(), (("b", 2.0), Interpolated::No));
151+
assert!(iter.next().is_none());
152+
}
153+
154+
#[test]
155+
fn test_leading_interpolation() {
156+
let v = vec![("a", None), ("b", None), ("c", Some(3.0)), ("d", Some(4.0))];
157+
let mut iter = Interpolate::new(v.into_iter());
158+
159+
assert_eq!(iter.next().unwrap(), (("a", Some(3.0)), Interpolated::Yes));
160+
assert_eq!(iter.next().unwrap(), (("b", Some(3.0)), Interpolated::Yes));
161+
assert_eq!(iter.next().unwrap(), (("c", Some(3.0)), Interpolated::No));
162+
assert_eq!(iter.next().unwrap(), (("d", Some(4.0)), Interpolated::No));
163+
assert!(iter.next().is_none());
164+
}
165+
166+
#[test]
167+
fn test_inner_interpolation() {
168+
let v = vec![
169+
("a", Some(1.0)),
170+
("b", Some(2.0)),
171+
("c", None),
172+
("d", None),
173+
("e", Some(5.0)),
174+
("f", Some(6.0)),
175+
];
176+
let mut iter = Interpolate::new(v.into_iter());
177+
178+
assert_eq!(iter.next().unwrap(), (("a", Some(1.0)), Interpolated::No));
179+
assert_eq!(iter.next().unwrap(), (("b", Some(2.0)), Interpolated::No));
180+
assert_eq!(iter.next().unwrap(), (("c", Some(2.0)), Interpolated::Yes));
181+
assert_eq!(iter.next().unwrap(), (("d", Some(2.0)), Interpolated::Yes));
182+
assert_eq!(iter.next().unwrap(), (("e", Some(5.0)), Interpolated::No));
183+
assert_eq!(iter.next().unwrap(), (("f", Some(6.0)), Interpolated::No));
184+
assert!(iter.next().is_none());
185+
}
186+
187+
#[test]
188+
fn test_trailing_interpolation() {
189+
let v = vec![("a", Some(1.0)), ("b", Some(2.0)), ("c", None), ("d", None)];
190+
let mut iter = Interpolate::new(v.into_iter());
191+
192+
assert_eq!(iter.next().unwrap(), (("a", Some(1.0)), Interpolated::No));
193+
assert_eq!(iter.next().unwrap(), (("b", Some(2.0)), Interpolated::No));
194+
assert_eq!(iter.next().unwrap(), (("c", Some(2.0)), Interpolated::Yes));
195+
assert_eq!(iter.next().unwrap(), (("d", Some(2.0)), Interpolated::Yes));
196+
assert!(iter.next().is_none());
197+
}
198+
}

0 commit comments

Comments
 (0)