Auto merge of #96622 - JohnTitor:rollup-8hckgaj, r=JohnTitor
Rollup of 7 pull requests Successful merges: - #94126 (Classify BinaryHeap & LinkedList unit tests as such) - #96222 (Clarify docs for `from_raw_parts` on `Vec` and `String`) - #96499 (Make it possible to write doctests for bootstrap) - #96567 (Fix docs for u32 and i32 logs func) - #96568 (std::fmt: Various fixes and improvements to documentation) - #96571 (Add a bathroom stall to weird expressions test) - #96610 (Update browser-ui-test version to 0.9.0) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f6cbc92e2a
14 changed files with 756 additions and 723 deletions
|
@ -155,6 +155,9 @@ use crate::vec::{self, AsVecIntoIter, Vec};
|
|||
|
||||
use super::SpecExtend;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// A priority queue implemented with a binary heap.
|
||||
///
|
||||
/// This will be a max-heap.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::collections::binary_heap::{Drain, PeekMut};
|
||||
use std::collections::BinaryHeap;
|
||||
use super::*;
|
||||
use crate::boxed::Box;
|
||||
use std::iter::TrustedLen;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
|
@ -1,10 +1,55 @@
|
|||
use super::*;
|
||||
use crate::vec::Vec;
|
||||
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::thread;
|
||||
use std::vec::Vec;
|
||||
|
||||
use rand::{thread_rng, RngCore};
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let mut m = LinkedList::<Box<_>>::new();
|
||||
assert_eq!(m.pop_front(), None);
|
||||
assert_eq!(m.pop_back(), None);
|
||||
assert_eq!(m.pop_front(), None);
|
||||
m.push_front(box 1);
|
||||
assert_eq!(m.pop_front(), Some(box 1));
|
||||
m.push_back(box 2);
|
||||
m.push_back(box 3);
|
||||
assert_eq!(m.len(), 2);
|
||||
assert_eq!(m.pop_front(), Some(box 2));
|
||||
assert_eq!(m.pop_front(), Some(box 3));
|
||||
assert_eq!(m.len(), 0);
|
||||
assert_eq!(m.pop_front(), None);
|
||||
m.push_back(box 1);
|
||||
m.push_back(box 3);
|
||||
m.push_back(box 5);
|
||||
m.push_back(box 7);
|
||||
assert_eq!(m.pop_front(), Some(box 1));
|
||||
|
||||
let mut n = LinkedList::new();
|
||||
n.push_front(2);
|
||||
n.push_front(3);
|
||||
{
|
||||
assert_eq!(n.front().unwrap(), &3);
|
||||
let x = n.front_mut().unwrap();
|
||||
assert_eq!(*x, 3);
|
||||
*x = 0;
|
||||
}
|
||||
{
|
||||
assert_eq!(n.back().unwrap(), &2);
|
||||
let y = n.back_mut().unwrap();
|
||||
assert_eq!(*y, 2);
|
||||
*y = 1;
|
||||
}
|
||||
assert_eq!(n.pop_front(), Some(0));
|
||||
assert_eq!(n.pop_front(), Some(1));
|
||||
}
|
||||
|
||||
fn generate_test() -> LinkedList<i32> {
|
||||
list_from(&[0, 1, 2, 3, 4, 5, 6])
|
||||
}
|
||||
|
||||
fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
|
||||
v.iter().cloned().collect()
|
||||
}
|
||||
|
@ -110,6 +155,123 @@ fn test_append() {
|
|||
check_links(&n);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let m = generate_test();
|
||||
for (i, elt) in m.iter().enumerate() {
|
||||
assert_eq!(i as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().next(), None);
|
||||
n.push_front(4);
|
||||
let mut it = n.iter();
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_clone() {
|
||||
let mut n = LinkedList::new();
|
||||
n.push_back(2);
|
||||
n.push_back(3);
|
||||
n.push_back(4);
|
||||
let mut it = n.iter();
|
||||
it.next();
|
||||
let mut jt = it.clone();
|
||||
assert_eq!(it.next(), jt.next());
|
||||
assert_eq!(it.next_back(), jt.next_back());
|
||||
assert_eq!(it.next(), jt.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_double_end() {
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().next(), None);
|
||||
n.push_front(4);
|
||||
n.push_front(5);
|
||||
n.push_front(6);
|
||||
let mut it = n.iter();
|
||||
assert_eq!(it.size_hint(), (3, Some(3)));
|
||||
assert_eq!(it.next().unwrap(), &6);
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next_back().unwrap(), &5);
|
||||
assert_eq!(it.next_back(), None);
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_iter() {
|
||||
let m = generate_test();
|
||||
for (i, elt) in m.iter().rev().enumerate() {
|
||||
assert_eq!((6 - i) as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().rev().next(), None);
|
||||
n.push_front(4);
|
||||
let mut it = n.iter().rev();
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_iter() {
|
||||
let mut m = generate_test();
|
||||
let mut len = m.len();
|
||||
for (i, elt) in m.iter_mut().enumerate() {
|
||||
assert_eq!(i as i32, *elt);
|
||||
len -= 1;
|
||||
}
|
||||
assert_eq!(len, 0);
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().next().is_none());
|
||||
n.push_front(4);
|
||||
n.push_back(5);
|
||||
let mut it = n.iter_mut();
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert!(it.next().is_some());
|
||||
assert!(it.next().is_some());
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_mut_double_end() {
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().next_back().is_none());
|
||||
n.push_front(4);
|
||||
n.push_front(5);
|
||||
n.push_front(6);
|
||||
let mut it = n.iter_mut();
|
||||
assert_eq!(it.size_hint(), (3, Some(3)));
|
||||
assert_eq!(*it.next().unwrap(), 6);
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert_eq!(*it.next_back().unwrap(), 4);
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(*it.next_back().unwrap(), 5);
|
||||
assert!(it.next_back().is_none());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rev_iter() {
|
||||
let mut m = generate_test();
|
||||
for (i, elt) in m.iter_mut().rev().enumerate() {
|
||||
assert_eq!((6 - i) as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().rev().next().is_none());
|
||||
n.push_front(4);
|
||||
let mut it = n.iter_mut().rev();
|
||||
assert!(it.next().is_some());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone_from() {
|
||||
// Short cloned from long
|
||||
|
@ -168,13 +330,60 @@ fn test_send() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_fuzz() {
|
||||
for _ in 0..25 {
|
||||
fuzz_test(3);
|
||||
fuzz_test(16);
|
||||
#[cfg(not(miri))] // Miri is too slow
|
||||
fuzz_test(189);
|
||||
}
|
||||
fn test_eq() {
|
||||
let mut n = list_from(&[]);
|
||||
let mut m = list_from(&[]);
|
||||
assert!(n == m);
|
||||
n.push_front(1);
|
||||
assert!(n != m);
|
||||
m.push_back(1);
|
||||
assert!(n == m);
|
||||
|
||||
let n = list_from(&[2, 3, 4]);
|
||||
let m = list_from(&[1, 2, 3]);
|
||||
assert!(n != m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let n = list_from(&[]);
|
||||
let m = list_from(&[1, 2, 3]);
|
||||
assert!(n < m);
|
||||
assert!(m > n);
|
||||
assert!(n <= n);
|
||||
assert!(n >= n);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_nan() {
|
||||
let nan = 0.0f64 / 0.0;
|
||||
let n = list_from(&[nan]);
|
||||
let m = list_from(&[nan]);
|
||||
assert!(!(n < m));
|
||||
assert!(!(n > m));
|
||||
assert!(!(n <= m));
|
||||
assert!(!(n >= m));
|
||||
|
||||
let n = list_from(&[nan]);
|
||||
let one = list_from(&[1.0f64]);
|
||||
assert!(!(n < one));
|
||||
assert!(!(n > one));
|
||||
assert!(!(n <= one));
|
||||
assert!(!(n >= one));
|
||||
|
||||
let u = list_from(&[1.0f64, 2.0, nan]);
|
||||
let v = list_from(&[1.0f64, 2.0, 3.0]);
|
||||
assert!(!(u < v));
|
||||
assert!(!(u > v));
|
||||
assert!(!(u <= v));
|
||||
assert!(!(u >= v));
|
||||
|
||||
let s = list_from(&[1.0f64, 2.0, 4.0, 2.0]);
|
||||
let t = list_from(&[1.0f64, 2.0, 3.0, 2.0]);
|
||||
assert!(!(s < t));
|
||||
assert!(s > one);
|
||||
assert!(!(s <= one));
|
||||
assert!(s >= one);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -215,6 +424,62 @@ fn test_split_off() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_off_2() {
|
||||
// singleton
|
||||
{
|
||||
let mut m = LinkedList::new();
|
||||
m.push_back(1);
|
||||
|
||||
let p = m.split_off(0);
|
||||
assert_eq!(m.len(), 0);
|
||||
assert_eq!(p.len(), 1);
|
||||
assert_eq!(p.back(), Some(&1));
|
||||
assert_eq!(p.front(), Some(&1));
|
||||
}
|
||||
|
||||
// not singleton, forwards
|
||||
{
|
||||
let u = vec![1, 2, 3, 4, 5];
|
||||
let mut m = list_from(&u);
|
||||
let mut n = m.split_off(2);
|
||||
assert_eq!(m.len(), 2);
|
||||
assert_eq!(n.len(), 3);
|
||||
for elt in 1..3 {
|
||||
assert_eq!(m.pop_front(), Some(elt));
|
||||
}
|
||||
for elt in 3..6 {
|
||||
assert_eq!(n.pop_front(), Some(elt));
|
||||
}
|
||||
}
|
||||
// not singleton, backwards
|
||||
{
|
||||
let u = vec![1, 2, 3, 4, 5];
|
||||
let mut m = list_from(&u);
|
||||
let mut n = m.split_off(4);
|
||||
assert_eq!(m.len(), 4);
|
||||
assert_eq!(n.len(), 1);
|
||||
for elt in 1..5 {
|
||||
assert_eq!(m.pop_front(), Some(elt));
|
||||
}
|
||||
for elt in 5..6 {
|
||||
assert_eq!(n.pop_front(), Some(elt));
|
||||
}
|
||||
}
|
||||
|
||||
// no-op on the last index
|
||||
{
|
||||
let mut m = LinkedList::new();
|
||||
m.push_back(1);
|
||||
|
||||
let p = m.split_off(1);
|
||||
assert_eq!(m.len(), 1);
|
||||
assert_eq!(p.len(), 0);
|
||||
assert_eq!(m.back(), Some(&1));
|
||||
assert_eq!(m.front(), Some(&1));
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzz_test(sz: i32) {
|
||||
let mut m: LinkedList<_> = LinkedList::new();
|
||||
let mut v = vec![];
|
||||
|
@ -253,6 +518,25 @@ fn fuzz_test(sz: i32) {
|
|||
assert_eq!(i, v.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fuzz() {
|
||||
for _ in 0..25 {
|
||||
fuzz_test(3);
|
||||
fuzz_test(16);
|
||||
#[cfg(not(miri))] // Miri is too slow
|
||||
fuzz_test(189);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let list: LinkedList<_> = (0..10).collect();
|
||||
assert_eq!(format!("{list:?}"), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
||||
|
||||
let list: LinkedList<_> = ["just", "one", "test", "more"].into_iter().collect();
|
||||
assert_eq!(format!("{list:?}"), "[\"just\", \"one\", \"test\", \"more\"]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_test() {
|
||||
let mut m: LinkedList<u32> = LinkedList::new();
|
||||
|
@ -475,3 +759,398 @@ fn test_cursor_pop_front_back() {
|
|||
assert_eq!(c.current(), None);
|
||||
assert_eq!(c.index, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_ref() {
|
||||
let mut a = LinkedList::new();
|
||||
a.push_back(1);
|
||||
|
||||
a.extend(&[2, 3, 4]);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(a, list_from(&[1, 2, 3, 4]));
|
||||
|
||||
let mut b = LinkedList::new();
|
||||
b.push_back(5);
|
||||
b.push_back(6);
|
||||
a.extend(&b);
|
||||
|
||||
assert_eq!(a.len(), 6);
|
||||
assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend() {
|
||||
let mut a = LinkedList::new();
|
||||
a.push_back(1);
|
||||
a.extend(vec![2, 3, 4]); // uses iterator
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert!(a.iter().eq(&[1, 2, 3, 4]));
|
||||
|
||||
let b: LinkedList<_> = [5, 6, 7].into_iter().collect();
|
||||
a.extend(b); // specializes to `append`
|
||||
|
||||
assert_eq!(a.len(), 7);
|
||||
assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains() {
|
||||
let mut l = LinkedList::new();
|
||||
l.extend(&[2, 3, 4]);
|
||||
|
||||
assert!(l.contains(&3));
|
||||
assert!(!l.contains(&1));
|
||||
|
||||
l.clear();
|
||||
|
||||
assert!(!l.contains(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_empty() {
|
||||
let mut list: LinkedList<i32> = LinkedList::new();
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_zst() {
|
||||
let mut list: LinkedList<_> = [(), (), (), (), ()].into_iter().collect();
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
while let Some(_) = iter.next() {
|
||||
count += 1;
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, initial_len);
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_false() {
|
||||
let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| false);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
for _ in iter.by_ref() {
|
||||
count += 1;
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, 0);
|
||||
assert_eq!(list.len(), initial_len);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_true() {
|
||||
let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
while let Some(_) = iter.next() {
|
||||
count += 1;
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, initial_len);
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_complex() {
|
||||
{
|
||||
// [+xxx++++++xxxxx++++x+x++]
|
||||
let mut list = [
|
||||
1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37,
|
||||
39,
|
||||
]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 14);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxx++++++xxxxx++++x+x++]
|
||||
let mut list =
|
||||
[2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 13);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxx++++++xxxxx++++x+x]
|
||||
let mut list =
|
||||
[2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 11);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxxxxxxxxx+++++++++++]
|
||||
let mut list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
|
||||
|
||||
assert_eq!(list.len(), 10);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||
}
|
||||
|
||||
{
|
||||
// [+++++++++++xxxxxxxxxx]
|
||||
let mut list = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
|
||||
|
||||
assert_eq!(list.len(), 10);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_drop_panic_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(true));
|
||||
q.push_front(D(false));
|
||||
|
||||
catch_unwind(AssertUnwindSafe(|| drop(q.drain_filter(|_| true)))).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 8);
|
||||
assert!(q.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_pred_panic_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct D(u32);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(3));
|
||||
q.push_back(D(4));
|
||||
q.push_back(D(5));
|
||||
q.push_back(D(6));
|
||||
q.push_back(D(7));
|
||||
q.push_front(D(2));
|
||||
q.push_front(D(1));
|
||||
q.push_front(D(0));
|
||||
|
||||
catch_unwind(AssertUnwindSafe(|| {
|
||||
drop(q.drain_filter(|item| if item.0 >= 2 { panic!() } else { true }))
|
||||
}))
|
||||
.ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 2); // 0 and 1
|
||||
assert_eq!(q.len(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
drop(ring);
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_with_pop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
|
||||
drop(ring.pop_back());
|
||||
drop(ring.pop_front());
|
||||
assert_eq!(unsafe { DROPS }, 2);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_clear() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.clear();
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_panic() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(true));
|
||||
|
||||
catch_unwind(move || drop(q)).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 8);
|
||||
}
|
||||
|
|
|
@ -221,10 +221,12 @@
|
|||
//!
|
||||
//! 3. An asterisk `.*`:
|
||||
//!
|
||||
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
|
||||
//! first input holds the `usize` precision, and the second holds the value to print. Note that
|
||||
//! in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
|
||||
//! to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
|
||||
//! `.*` means that this `{...}` is associated with *two* format inputs rather than one:
|
||||
//! - If a format string in the fashion of `{:<spec>.*}` is used, then the first input holds
|
||||
//! the `usize` precision, and the second holds the value to print.
|
||||
//! - If a format string in the fashion of `{<arg>:<spec>.*}` is used, then the `<arg>` part
|
||||
//! refers to the value to print, and the `precision` is taken like it was specified with an
|
||||
//! omitted positional parameter (`{}` instead of `{<arg>:}`).
|
||||
//!
|
||||
//! For example, the following calls all print the same thing `Hello x is 0.01000`:
|
||||
//!
|
||||
|
@ -238,15 +240,19 @@
|
|||
//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)}
|
||||
//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
|
||||
//!
|
||||
//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision
|
||||
//! // specified in first of next two args (5)}
|
||||
//! // Hello {next arg -> arg 0 ("x")} is {second of next two args -> arg 2 (0.01) with precision
|
||||
//! // specified in first of next two args -> arg 1 (5)}
|
||||
//! println!("Hello {} is {:.*}", "x", 5, 0.01);
|
||||
//!
|
||||
//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision
|
||||
//! // specified in its predecessor (5)}
|
||||
//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision
|
||||
//! // specified in next arg -> arg 0 (5)}
|
||||
//! println!("Hello {1} is {2:.*}", 5, "x", 0.01);
|
||||
//!
|
||||
//! // Hello {next arg -> arg 0 ("x")} is {arg 2 (0.01) with precision
|
||||
//! // specified in next arg -> arg 1 (5)}
|
||||
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
|
||||
//!
|
||||
//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified
|
||||
//! // Hello {next arg -> arg 0 ("x")} is {arg "number" (0.01) with precision specified
|
||||
//! // in arg "prec" (5)}
|
||||
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
|
||||
//! ```
|
||||
|
@ -304,7 +310,7 @@
|
|||
//! ```text
|
||||
//! format_string := text [ maybe_format text ] *
|
||||
//! maybe_format := '{' '{' | '}' '}' | format
|
||||
//! format := '{' [ argument ] [ ':' format_spec ] '}'
|
||||
//! format := '{' [ argument ] [ ':' format_spec ] [ ws ] * '}'
|
||||
//! argument := integer | identifier
|
||||
//!
|
||||
//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision]type
|
||||
|
@ -317,7 +323,12 @@
|
|||
//! count := parameter | integer
|
||||
//! parameter := argument '$'
|
||||
//! ```
|
||||
//! In the above grammar, `text` must not contain any `'{'` or `'}'` characters.
|
||||
//! In the above grammar,
|
||||
//! - `text` must not contain any `'{'` or `'}'` characters,
|
||||
//! - `ws` is any character for which [`char::is_whitespace`] returns `true`, has no semantic
|
||||
//! meaning and is completely optional,
|
||||
//! - `integer` is a decimal integer that may contain leading zeroes and
|
||||
//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as defined by the [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html).
|
||||
//!
|
||||
//! # Formatting traits
|
||||
//!
|
||||
|
@ -358,9 +369,9 @@
|
|||
//! ```
|
||||
//!
|
||||
//! Your type will be passed as `self` by-reference, and then the function
|
||||
//! should emit output into the `f.buf` stream. It is up to each format trait
|
||||
//! implementation to correctly adhere to the requested formatting parameters.
|
||||
//! The values of these parameters will be listed in the fields of the
|
||||
//! should emit output into the Formatter `f` which implements `fmt::Write`. It is up to each
|
||||
//! format trait implementation to correctly adhere to the requested formatting parameters.
|
||||
//! The values of these parameters can be accessed with methods of the
|
||||
//! [`Formatter`] struct. In order to help with this, the [`Formatter`] struct also
|
||||
//! provides some helper methods.
|
||||
//!
|
||||
|
@ -449,7 +460,7 @@
|
|||
//!
|
||||
//! ```ignore (only-for-syntax-highlight)
|
||||
//! format! // described above
|
||||
//! write! // first argument is a &mut io::Write, the destination
|
||||
//! write! // first argument is either a &mut io::Write or a &mut fmt::Write, the destination
|
||||
//! writeln! // same as write but appends a newline
|
||||
//! print! // the format string is printed to the standard output
|
||||
//! println! // same as print but appends a newline
|
||||
|
@ -460,11 +471,11 @@
|
|||
//!
|
||||
//! ### `write!`
|
||||
//!
|
||||
//! This and [`writeln!`] are two macros which are used to emit the format string
|
||||
//! [`write!`] and [`writeln!`] are two macros which are used to emit the format string
|
||||
//! to a specified stream. This is used to prevent intermediate allocations of
|
||||
//! format strings and instead directly write the output. Under the hood, this
|
||||
//! function is actually invoking the [`write_fmt`] function defined on the
|
||||
//! [`std::io::Write`] trait. Example usage is:
|
||||
//! [`std::io::Write`] and the [`std::fmt::Write`] trait. Example usage is:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![allow(unused_must_use)]
|
||||
|
@ -491,7 +502,7 @@
|
|||
//!
|
||||
//! ### `format_args!`
|
||||
//!
|
||||
//! This is a curious macro used to safely pass around
|
||||
//! [`format_args!`] is a curious macro used to safely pass around
|
||||
//! an opaque object describing the format string. This object
|
||||
//! does not require any heap allocations to create, and it only
|
||||
//! references information on the stack. Under the hood, all of
|
||||
|
@ -529,10 +540,12 @@
|
|||
//! [`to_string`]: crate::string::ToString::to_string "ToString::to_string"
|
||||
//! [`write_fmt`]: ../../std/io/trait.Write.html#method.write_fmt
|
||||
//! [`std::io::Write`]: ../../std/io/trait.Write.html
|
||||
//! [`std::fmt::Write`]: ../../std/fmt/trait.Write.html
|
||||
//! [`print!`]: ../../std/macro.print.html "print!"
|
||||
//! [`println!`]: ../../std/macro.println.html "println!"
|
||||
//! [`eprint!`]: ../../std/macro.eprint.html "eprint!"
|
||||
//! [`eprintln!`]: ../../std/macro.eprintln.html "eprintln!"
|
||||
//! [`format_args!`]: ../../std/macro.format_args.html "format_args!"
|
||||
//! [`fmt::Arguments`]: Arguments "fmt::Arguments"
|
||||
//! [`format`]: format() "fmt::format"
|
||||
|
||||
|
|
|
@ -770,7 +770,10 @@ impl String {
|
|||
/// * The first `length` bytes at `buf` need to be valid UTF-8.
|
||||
///
|
||||
/// Violating these may cause problems like corrupting the allocator's
|
||||
/// internal data structures.
|
||||
/// internal data structures. For example, it is normally **not** safe to
|
||||
/// build a `String` from a pointer to a C `char` array containing UTF-8
|
||||
/// _unless_ you are certain that array was originally allocated by the
|
||||
/// Rust standard library's allocator.
|
||||
///
|
||||
/// The ownership of `buf` is effectively transferred to the
|
||||
/// `String` which may then deallocate, reallocate or change the
|
||||
|
|
|
@ -489,8 +489,10 @@ impl<T> Vec<T> {
|
|||
/// * `length` needs to be less than or equal to `capacity`.
|
||||
///
|
||||
/// Violating these may cause problems like corrupting the allocator's
|
||||
/// internal data structures. For example it is **not** safe
|
||||
/// to build a `Vec<u8>` from a pointer to a C `char` array with length `size_t`.
|
||||
/// internal data structures. For example it is normally **not** safe
|
||||
/// to build a `Vec<u8>` from a pointer to a C `char` array with length
|
||||
/// `size_t`, doing so is only safe if the array was initially allocated by
|
||||
/// a `Vec` or `String`.
|
||||
/// It's also not safe to build one from a `Vec<u16>` and its length, because
|
||||
/// the allocator cares about the alignment, and these two types have different
|
||||
/// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
|
||||
|
|
|
@ -47,7 +47,6 @@ use std::collections::hash_map::DefaultHasher;
|
|||
use std::hash::{Hash, Hasher};
|
||||
|
||||
mod arc;
|
||||
mod binary_heap;
|
||||
mod borrow;
|
||||
mod boxed;
|
||||
mod btree_set_hash;
|
||||
|
|
|
@ -1,241 +1,4 @@
|
|||
use std::collections::LinkedList;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let mut m = LinkedList::<Box<_>>::new();
|
||||
assert_eq!(m.pop_front(), None);
|
||||
assert_eq!(m.pop_back(), None);
|
||||
assert_eq!(m.pop_front(), None);
|
||||
m.push_front(box 1);
|
||||
assert_eq!(m.pop_front(), Some(box 1));
|
||||
m.push_back(box 2);
|
||||
m.push_back(box 3);
|
||||
assert_eq!(m.len(), 2);
|
||||
assert_eq!(m.pop_front(), Some(box 2));
|
||||
assert_eq!(m.pop_front(), Some(box 3));
|
||||
assert_eq!(m.len(), 0);
|
||||
assert_eq!(m.pop_front(), None);
|
||||
m.push_back(box 1);
|
||||
m.push_back(box 3);
|
||||
m.push_back(box 5);
|
||||
m.push_back(box 7);
|
||||
assert_eq!(m.pop_front(), Some(box 1));
|
||||
|
||||
let mut n = LinkedList::new();
|
||||
n.push_front(2);
|
||||
n.push_front(3);
|
||||
{
|
||||
assert_eq!(n.front().unwrap(), &3);
|
||||
let x = n.front_mut().unwrap();
|
||||
assert_eq!(*x, 3);
|
||||
*x = 0;
|
||||
}
|
||||
{
|
||||
assert_eq!(n.back().unwrap(), &2);
|
||||
let y = n.back_mut().unwrap();
|
||||
assert_eq!(*y, 2);
|
||||
*y = 1;
|
||||
}
|
||||
assert_eq!(n.pop_front(), Some(0));
|
||||
assert_eq!(n.pop_front(), Some(1));
|
||||
}
|
||||
|
||||
fn generate_test() -> LinkedList<i32> {
|
||||
list_from(&[0, 1, 2, 3, 4, 5, 6])
|
||||
}
|
||||
|
||||
fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
|
||||
v.iter().cloned().collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_off() {
|
||||
// singleton
|
||||
{
|
||||
let mut m = LinkedList::new();
|
||||
m.push_back(1);
|
||||
|
||||
let p = m.split_off(0);
|
||||
assert_eq!(m.len(), 0);
|
||||
assert_eq!(p.len(), 1);
|
||||
assert_eq!(p.back(), Some(&1));
|
||||
assert_eq!(p.front(), Some(&1));
|
||||
}
|
||||
|
||||
// not singleton, forwards
|
||||
{
|
||||
let u = vec![1, 2, 3, 4, 5];
|
||||
let mut m = list_from(&u);
|
||||
let mut n = m.split_off(2);
|
||||
assert_eq!(m.len(), 2);
|
||||
assert_eq!(n.len(), 3);
|
||||
for elt in 1..3 {
|
||||
assert_eq!(m.pop_front(), Some(elt));
|
||||
}
|
||||
for elt in 3..6 {
|
||||
assert_eq!(n.pop_front(), Some(elt));
|
||||
}
|
||||
}
|
||||
// not singleton, backwards
|
||||
{
|
||||
let u = vec![1, 2, 3, 4, 5];
|
||||
let mut m = list_from(&u);
|
||||
let mut n = m.split_off(4);
|
||||
assert_eq!(m.len(), 4);
|
||||
assert_eq!(n.len(), 1);
|
||||
for elt in 1..5 {
|
||||
assert_eq!(m.pop_front(), Some(elt));
|
||||
}
|
||||
for elt in 5..6 {
|
||||
assert_eq!(n.pop_front(), Some(elt));
|
||||
}
|
||||
}
|
||||
|
||||
// no-op on the last index
|
||||
{
|
||||
let mut m = LinkedList::new();
|
||||
m.push_back(1);
|
||||
|
||||
let p = m.split_off(1);
|
||||
assert_eq!(m.len(), 1);
|
||||
assert_eq!(p.len(), 0);
|
||||
assert_eq!(m.back(), Some(&1));
|
||||
assert_eq!(m.front(), Some(&1));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let m = generate_test();
|
||||
for (i, elt) in m.iter().enumerate() {
|
||||
assert_eq!(i as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().next(), None);
|
||||
n.push_front(4);
|
||||
let mut it = n.iter();
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_clone() {
|
||||
let mut n = LinkedList::new();
|
||||
n.push_back(2);
|
||||
n.push_back(3);
|
||||
n.push_back(4);
|
||||
let mut it = n.iter();
|
||||
it.next();
|
||||
let mut jt = it.clone();
|
||||
assert_eq!(it.next(), jt.next());
|
||||
assert_eq!(it.next_back(), jt.next_back());
|
||||
assert_eq!(it.next(), jt.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_double_end() {
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().next(), None);
|
||||
n.push_front(4);
|
||||
n.push_front(5);
|
||||
n.push_front(6);
|
||||
let mut it = n.iter();
|
||||
assert_eq!(it.size_hint(), (3, Some(3)));
|
||||
assert_eq!(it.next().unwrap(), &6);
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next_back().unwrap(), &5);
|
||||
assert_eq!(it.next_back(), None);
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_iter() {
|
||||
let m = generate_test();
|
||||
for (i, elt) in m.iter().rev().enumerate() {
|
||||
assert_eq!((6 - i) as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert_eq!(n.iter().rev().next(), None);
|
||||
n.push_front(4);
|
||||
let mut it = n.iter().rev();
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next().unwrap(), &4);
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_iter() {
|
||||
let mut m = generate_test();
|
||||
let mut len = m.len();
|
||||
for (i, elt) in m.iter_mut().enumerate() {
|
||||
assert_eq!(i as i32, *elt);
|
||||
len -= 1;
|
||||
}
|
||||
assert_eq!(len, 0);
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().next().is_none());
|
||||
n.push_front(4);
|
||||
n.push_back(5);
|
||||
let mut it = n.iter_mut();
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert!(it.next().is_some());
|
||||
assert!(it.next().is_some());
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_mut_double_end() {
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().next_back().is_none());
|
||||
n.push_front(4);
|
||||
n.push_front(5);
|
||||
n.push_front(6);
|
||||
let mut it = n.iter_mut();
|
||||
assert_eq!(it.size_hint(), (3, Some(3)));
|
||||
assert_eq!(*it.next().unwrap(), 6);
|
||||
assert_eq!(it.size_hint(), (2, Some(2)));
|
||||
assert_eq!(*it.next_back().unwrap(), 4);
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(*it.next_back().unwrap(), 5);
|
||||
assert!(it.next_back().is_none());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rev_iter() {
|
||||
let mut m = generate_test();
|
||||
for (i, elt) in m.iter_mut().rev().enumerate() {
|
||||
assert_eq!((6 - i) as i32, *elt);
|
||||
}
|
||||
let mut n = LinkedList::new();
|
||||
assert!(n.iter_mut().rev().next().is_none());
|
||||
n.push_front(4);
|
||||
let mut it = n.iter_mut().rev();
|
||||
assert!(it.next().is_some());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let mut n = list_from(&[]);
|
||||
let mut m = list_from(&[]);
|
||||
assert!(n == m);
|
||||
n.push_front(1);
|
||||
assert!(n != m);
|
||||
m.push_back(1);
|
||||
assert!(n == m);
|
||||
|
||||
let n = list_from(&[2, 3, 4]);
|
||||
let m = list_from(&[1, 2, 3]);
|
||||
assert!(n != m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
|
@ -256,449 +19,3 @@ fn test_hash() {
|
|||
|
||||
assert!(hash(&x) == hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let n = list_from(&[]);
|
||||
let m = list_from(&[1, 2, 3]);
|
||||
assert!(n < m);
|
||||
assert!(m > n);
|
||||
assert!(n <= n);
|
||||
assert!(n >= n);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_nan() {
|
||||
let nan = 0.0f64 / 0.0;
|
||||
let n = list_from(&[nan]);
|
||||
let m = list_from(&[nan]);
|
||||
assert!(!(n < m));
|
||||
assert!(!(n > m));
|
||||
assert!(!(n <= m));
|
||||
assert!(!(n >= m));
|
||||
|
||||
let n = list_from(&[nan]);
|
||||
let one = list_from(&[1.0f64]);
|
||||
assert!(!(n < one));
|
||||
assert!(!(n > one));
|
||||
assert!(!(n <= one));
|
||||
assert!(!(n >= one));
|
||||
|
||||
let u = list_from(&[1.0f64, 2.0, nan]);
|
||||
let v = list_from(&[1.0f64, 2.0, 3.0]);
|
||||
assert!(!(u < v));
|
||||
assert!(!(u > v));
|
||||
assert!(!(u <= v));
|
||||
assert!(!(u >= v));
|
||||
|
||||
let s = list_from(&[1.0f64, 2.0, 4.0, 2.0]);
|
||||
let t = list_from(&[1.0f64, 2.0, 3.0, 2.0]);
|
||||
assert!(!(s < t));
|
||||
assert!(s > one);
|
||||
assert!(!(s <= one));
|
||||
assert!(s >= one);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let list: LinkedList<_> = (0..10).collect();
|
||||
assert_eq!(format!("{list:?}"), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
|
||||
|
||||
let list: LinkedList<_> = ["just", "one", "test", "more"].into_iter().collect();
|
||||
assert_eq!(format!("{list:?}"), "[\"just\", \"one\", \"test\", \"more\"]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_ref() {
|
||||
let mut a = LinkedList::new();
|
||||
a.push_back(1);
|
||||
|
||||
a.extend(&[2, 3, 4]);
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert_eq!(a, list_from(&[1, 2, 3, 4]));
|
||||
|
||||
let mut b = LinkedList::new();
|
||||
b.push_back(5);
|
||||
b.push_back(6);
|
||||
a.extend(&b);
|
||||
|
||||
assert_eq!(a.len(), 6);
|
||||
assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend() {
|
||||
let mut a = LinkedList::new();
|
||||
a.push_back(1);
|
||||
a.extend(vec![2, 3, 4]); // uses iterator
|
||||
|
||||
assert_eq!(a.len(), 4);
|
||||
assert!(a.iter().eq(&[1, 2, 3, 4]));
|
||||
|
||||
let b: LinkedList<_> = [5, 6, 7].into_iter().collect();
|
||||
a.extend(b); // specializes to `append`
|
||||
|
||||
assert_eq!(a.len(), 7);
|
||||
assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains() {
|
||||
let mut l = LinkedList::new();
|
||||
l.extend(&[2, 3, 4]);
|
||||
|
||||
assert!(l.contains(&3));
|
||||
assert!(!l.contains(&1));
|
||||
|
||||
l.clear();
|
||||
|
||||
assert!(!l.contains(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_empty() {
|
||||
let mut list: LinkedList<i32> = LinkedList::new();
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_zst() {
|
||||
let mut list: LinkedList<_> = [(), (), (), (), ()].into_iter().collect();
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
while let Some(_) = iter.next() {
|
||||
count += 1;
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, initial_len);
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_false() {
|
||||
let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| false);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
for _ in iter.by_ref() {
|
||||
count += 1;
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, 0);
|
||||
assert_eq!(list.len(), initial_len);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_true() {
|
||||
let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
|
||||
|
||||
let initial_len = list.len();
|
||||
let mut count = 0;
|
||||
|
||||
{
|
||||
let mut iter = list.drain_filter(|_| true);
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len)));
|
||||
while let Some(_) = iter.next() {
|
||||
count += 1;
|
||||
assert_eq!(iter.size_hint(), (0, Some(initial_len - count)));
|
||||
}
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
assert_eq!(count, initial_len);
|
||||
assert_eq!(list.len(), 0);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_complex() {
|
||||
{
|
||||
// [+xxx++++++xxxxx++++x+x++]
|
||||
let mut list = [
|
||||
1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37,
|
||||
39,
|
||||
]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 14);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxx++++++xxxxx++++x+x++]
|
||||
let mut list =
|
||||
[2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 13);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxx++++++xxxxx++++x+x]
|
||||
let mut list =
|
||||
[2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]);
|
||||
|
||||
assert_eq!(list.len(), 11);
|
||||
assert_eq!(
|
||||
list.into_iter().collect::<Vec<_>>(),
|
||||
vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
// [xxxxxxxxxx+++++++++++]
|
||||
let mut list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
|
||||
|
||||
assert_eq!(list.len(), 10);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||
}
|
||||
|
||||
{
|
||||
// [+++++++++++xxxxxxxxxx]
|
||||
let mut list = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
|
||||
.into_iter()
|
||||
.collect::<LinkedList<_>>();
|
||||
|
||||
let removed = list.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();
|
||||
assert_eq!(removed.len(), 10);
|
||||
assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]);
|
||||
|
||||
assert_eq!(list.len(), 10);
|
||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_drop_panic_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(true));
|
||||
q.push_front(D(false));
|
||||
|
||||
catch_unwind(AssertUnwindSafe(|| drop(q.drain_filter(|_| true)))).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 8);
|
||||
assert!(q.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_filter_pred_panic_leak() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct D(u32);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(3));
|
||||
q.push_back(D(4));
|
||||
q.push_back(D(5));
|
||||
q.push_back(D(6));
|
||||
q.push_back(D(7));
|
||||
q.push_front(D(2));
|
||||
q.push_front(D(1));
|
||||
q.push_front(D(0));
|
||||
|
||||
catch_unwind(AssertUnwindSafe(|| {
|
||||
drop(q.drain_filter(|item| if item.0 >= 2 { panic!() } else { true }))
|
||||
}))
|
||||
.ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 2); // 0 and 1
|
||||
assert_eq!(q.len(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
drop(ring);
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_with_pop() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
|
||||
drop(ring.pop_back());
|
||||
drop(ring.pop_front());
|
||||
assert_eq!(unsafe { DROPS }, 2);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_clear() {
|
||||
static mut DROPS: i32 = 0;
|
||||
struct Elem;
|
||||
impl Drop for Elem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ring = LinkedList::new();
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.push_back(Elem);
|
||||
ring.push_front(Elem);
|
||||
ring.clear();
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
|
||||
drop(ring);
|
||||
assert_eq!(unsafe { DROPS }, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_panic() {
|
||||
static mut DROPS: i32 = 0;
|
||||
|
||||
struct D(bool);
|
||||
|
||||
impl Drop for D {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DROPS += 1;
|
||||
}
|
||||
|
||||
if self.0 {
|
||||
panic!("panic in `drop`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = LinkedList::new();
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_back(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(false));
|
||||
q.push_front(D(true));
|
||||
|
||||
catch_unwind(move || drop(q)).ok();
|
||||
|
||||
assert_eq!(unsafe { DROPS }, 8);
|
||||
}
|
||||
|
|
|
@ -2189,7 +2189,7 @@ macro_rules! int_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is zero, or if the base is not at least 2; it
|
||||
/// When the number is negative, zero, or if the base is not at least 2; it
|
||||
/// panics in debug mode and the return value is 0 in release
|
||||
/// mode.
|
||||
///
|
||||
|
@ -2223,7 +2223,7 @@ macro_rules! int_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is zero it panics in debug mode and the return value
|
||||
/// When the number is negative or zero it panics in debug mode and the return value
|
||||
/// is 0 in release mode.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -2256,7 +2256,7 @@ macro_rules! int_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is zero it panics in debug mode and the return value
|
||||
/// When the number is negative or zero it panics in debug mode and the return value
|
||||
/// is 0 in release mode.
|
||||
///
|
||||
/// # Example
|
||||
|
|
|
@ -689,7 +689,7 @@ macro_rules! uint_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is negative, zero, or if the base is not at least 2;
|
||||
/// When the number is zero, or if the base is not at least 2;
|
||||
/// it panics in debug mode and the return value is 0 in release mode.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -722,7 +722,7 @@ macro_rules! uint_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is negative or zero it panics in debug mode and
|
||||
/// When the number is zero it panics in debug mode and
|
||||
/// the return value is 0 in release mode.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -755,7 +755,7 @@ macro_rules! uint_impl {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the number is negative or zero it panics in debug mode and the
|
||||
/// When the number is zero it panics in debug mode and the
|
||||
/// return value is 0 in release mode.
|
||||
///
|
||||
/// # Example
|
||||
|
|
|
@ -2359,6 +2359,7 @@ impl Step for Bootstrap {
|
|||
.env("RUSTFLAGS", "-Cdebuginfo=2")
|
||||
.env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.env("RUSTDOC", builder.rustdoc(builder.compiler(0, builder.build.build)))
|
||||
.env("RUSTC", &builder.initial_rustc);
|
||||
if let Some(flags) = option_env!("RUSTFLAGS") {
|
||||
// Use the same rustc flags for testing as for "normal" compilation,
|
||||
|
@ -2369,6 +2370,16 @@ impl Step for Bootstrap {
|
|||
if !builder.fail_fast {
|
||||
cmd.arg("--no-fail-fast");
|
||||
}
|
||||
match builder.doc_tests {
|
||||
DocTests::Only => {
|
||||
cmd.arg("--doc");
|
||||
}
|
||||
DocTests::No => {
|
||||
cmd.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
|
||||
}
|
||||
DocTests::Yes => {}
|
||||
}
|
||||
|
||||
cmd.arg("--").args(&builder.config.cmd.test_args());
|
||||
// rustbuild tests are racy on directory creation so just run them one at a time.
|
||||
// Since there's not many this shouldn't be a problem.
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.8.5
|
||||
0.9.0
|
|
@ -164,6 +164,12 @@ fn monkey_barrel() {
|
|||
assert_eq!(val, ());
|
||||
}
|
||||
|
||||
fn bathroom_stall() {
|
||||
let mut i = 1;
|
||||
matches!(2, _|_|_|_|_|_ if (i+=1) != (i+=1));
|
||||
assert_eq!(i, 13);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
strange();
|
||||
funny();
|
||||
|
@ -183,4 +189,5 @@ pub fn main() {
|
|||
i_yield();
|
||||
match_nested_if();
|
||||
monkey_barrel();
|
||||
bathroom_stall();
|
||||
}
|
||||
|
|
|
@ -138,7 +138,6 @@ async function main(argv) {
|
|||
try {
|
||||
// This is more convenient that setting fields one by one.
|
||||
let args = [
|
||||
"--no-screenshot-comparison",
|
||||
"--variable", "DOC_PATH", opts["doc_folder"],
|
||||
];
|
||||
if (opts["debug"]) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue