Skip to content

Commit cb5e429

Browse files
author
Jorge Aparicio
committed
move some tests back to libcollections
1 parent e09bf82 commit cb5e429

File tree

12 files changed

+565
-511
lines changed

12 files changed

+565
-511
lines changed

mk/tests.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ $(eval $(call RUST_CRATE,coretest))
2222
DEPS_collectionstest :=
2323
$(eval $(call RUST_CRATE,collectionstest))
2424

25-
TEST_TARGET_CRATES = $(filter-out collections core unicode,$(TARGET_CRATES)) \
25+
TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) \
2626
collectionstest coretest
2727
TEST_DOC_CRATES = $(DOC_CRATES)
2828
TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans rustc_lint,\

src/libcollections/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ extern crate core;
4747
extern crate unicode;
4848
extern crate alloc;
4949

50+
#[cfg(test)] #[macro_use] extern crate std;
51+
#[cfg(test)] extern crate test;
52+
5053
pub use binary_heap::BinaryHeap;
5154
pub use bit_vec::BitVec;
5255
pub use bit_set::BitSet;
@@ -131,6 +134,7 @@ pub mod btree_set {
131134
#[doc(hidden)]
132135
pub fn fixme_14344_be_sure_to_link_to_collections() {}
133136

137+
#[cfg(not(test))]
134138
mod std {
135139
pub use core::ops; // RangeFull
136140
}

src/libcollections/linked_list.rs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,3 +938,194 @@ impl<A: Hash> Hash for LinkedList<A> {
938938
}
939939
}
940940
}
941+
942+
#[cfg(test)]
943+
mod test {
944+
use std::clone::Clone;
945+
use std::iter::{Iterator, IteratorExt};
946+
use std::option::Option::{Some, None, self};
947+
use std::rand;
948+
use std::thread;
949+
use std::vec::Vec;
950+
951+
use super::{LinkedList, Node};
952+
953+
#[cfg(test)]
954+
fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
955+
v.iter().cloned().collect()
956+
}
957+
958+
pub fn check_links<T>(list: &LinkedList<T>) {
959+
let mut len = 0;
960+
let mut last_ptr: Option<&Node<T>> = None;
961+
let mut node_ptr: &Node<T>;
962+
match list.list_head {
963+
None => { assert_eq!(0, list.length); return }
964+
Some(ref node) => node_ptr = &**node,
965+
}
966+
loop {
967+
match (last_ptr, node_ptr.prev.resolve_immut()) {
968+
(None , None ) => {}
969+
(None , _ ) => panic!("prev link for list_head"),
970+
(Some(p), Some(pptr)) => {
971+
assert_eq!(p as *const Node<T>, pptr as *const Node<T>);
972+
}
973+
_ => panic!("prev link is none, not good"),
974+
}
975+
match node_ptr.next {
976+
Some(ref next) => {
977+
last_ptr = Some(node_ptr);
978+
node_ptr = &**next;
979+
len += 1;
980+
}
981+
None => {
982+
len += 1;
983+
break;
984+
}
985+
}
986+
}
987+
assert_eq!(len, list.length);
988+
}
989+
990+
#[test]
991+
fn test_append() {
992+
// Empty to empty
993+
{
994+
let mut m = LinkedList::<i32>::new();
995+
let mut n = LinkedList::new();
996+
m.append(&mut n);
997+
check_links(&m);
998+
assert_eq!(m.len(), 0);
999+
assert_eq!(n.len(), 0);
1000+
}
1001+
// Non-empty to empty
1002+
{
1003+
let mut m = LinkedList::new();
1004+
let mut n = LinkedList::new();
1005+
n.push_back(2);
1006+
m.append(&mut n);
1007+
check_links(&m);
1008+
assert_eq!(m.len(), 1);
1009+
assert_eq!(m.pop_back(), Some(2));
1010+
assert_eq!(n.len(), 0);
1011+
check_links(&m);
1012+
}
1013+
// Empty to non-empty
1014+
{
1015+
let mut m = LinkedList::new();
1016+
let mut n = LinkedList::new();
1017+
m.push_back(2);
1018+
m.append(&mut n);
1019+
check_links(&m);
1020+
assert_eq!(m.len(), 1);
1021+
assert_eq!(m.pop_back(), Some(2));
1022+
check_links(&m);
1023+
}
1024+
1025+
// Non-empty to non-empty
1026+
let v = vec![1,2,3,4,5];
1027+
let u = vec![9,8,1,2,3,4,5];
1028+
let mut m = list_from(&v);
1029+
let mut n = list_from(&u);
1030+
m.append(&mut n);
1031+
check_links(&m);
1032+
let mut sum = v;
1033+
sum.push_all(&u);
1034+
assert_eq!(sum.len(), m.len());
1035+
for elt in sum {
1036+
assert_eq!(m.pop_front(), Some(elt))
1037+
}
1038+
assert_eq!(n.len(), 0);
1039+
// let's make sure it's working properly, since we
1040+
// did some direct changes to private members
1041+
n.push_back(3);
1042+
assert_eq!(n.len(), 1);
1043+
assert_eq!(n.pop_front(), Some(3));
1044+
check_links(&n);
1045+
}
1046+
1047+
#[test]
1048+
fn test_insert_prev() {
1049+
let mut m = list_from(&[0,2,4,6,8]);
1050+
let len = m.len();
1051+
{
1052+
let mut it = m.iter_mut();
1053+
it.insert_next(-2);
1054+
loop {
1055+
match it.next() {
1056+
None => break,
1057+
Some(elt) => {
1058+
it.insert_next(*elt + 1);
1059+
match it.peek_next() {
1060+
Some(x) => assert_eq!(*x, *elt + 2),
1061+
None => assert_eq!(8, *elt),
1062+
}
1063+
}
1064+
}
1065+
}
1066+
it.insert_next(0);
1067+
it.insert_next(1);
1068+
}
1069+
check_links(&m);
1070+
assert_eq!(m.len(), 3 + len * 2);
1071+
assert_eq!(m.into_iter().collect::<Vec<_>>(), [-2,0,1,2,3,4,5,6,7,8,9,0,1]);
1072+
}
1073+
1074+
#[test]
1075+
fn test_send() {
1076+
let n = list_from(&[1,2,3]);
1077+
thread::spawn(move || {
1078+
check_links(&n);
1079+
let a: &[_] = &[&1,&2,&3];
1080+
assert_eq!(a, n.iter().collect::<Vec<_>>());
1081+
}).join().ok().unwrap();
1082+
}
1083+
1084+
#[test]
1085+
fn test_fuzz() {
1086+
for _ in 0..25 {
1087+
fuzz_test(3);
1088+
fuzz_test(16);
1089+
fuzz_test(189);
1090+
}
1091+
}
1092+
1093+
#[cfg(test)]
1094+
fn fuzz_test(sz: i32) {
1095+
let mut m: LinkedList<_> = LinkedList::new();
1096+
let mut v = vec![];
1097+
for i in 0..sz {
1098+
check_links(&m);
1099+
let r: u8 = rand::random();
1100+
match r % 6 {
1101+
0 => {
1102+
m.pop_back();
1103+
v.pop();
1104+
}
1105+
1 => {
1106+
if !v.is_empty() {
1107+
m.pop_front();
1108+
v.remove(0);
1109+
}
1110+
}
1111+
2 | 4 => {
1112+
m.push_front(-i);
1113+
v.insert(0, -i);
1114+
}
1115+
3 | 5 | _ => {
1116+
m.push_back(i);
1117+
v.push(i);
1118+
}
1119+
}
1120+
}
1121+
1122+
check_links(&m);
1123+
1124+
let mut i = 0;
1125+
for (a, &b) in m.into_iter().zip(v.iter()) {
1126+
i += 1;
1127+
assert_eq!(a, b);
1128+
}
1129+
assert_eq!(i, v.len());
1130+
}
1131+
}

src/libcollections/macros.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ macro_rules! vec {
7171
/// Note that unlike array expressions this syntax supports all elements
7272
/// which implement `Clone` and the number of elements doesn't have to be
7373
/// a constant.
74+
#[cfg(not(test))]
7475
#[macro_export]
7576
#[stable(feature = "rust1", since = "1.0.0")]
7677
macro_rules! vec {
@@ -83,6 +84,20 @@ macro_rules! vec {
8384
($($x:expr,)*) => (vec![$($x),*])
8485
}
8586

87+
// HACK: `impl [T]` is not available in cfg(test), use `::slice::into_vec`, instead of
88+
// `<[T]>::to_vec`
89+
#[cfg(not(stage0))]
90+
#[cfg(test)]
91+
macro_rules! vec {
92+
($elem:expr; $n:expr) => (
93+
$crate::vec::from_elem($elem, $n)
94+
);
95+
($($x:expr),*) => (
96+
$crate::slice::into_vec($crate::boxed::Box::new([$($x),*]))
97+
);
98+
($($x:expr,)*) => (vec![$($x),*])
99+
}
100+
86101
/// Use the syntax described in `std::fmt` to create a value of type `String`.
87102
/// See `std::fmt` for more information.
88103
///

src/libcollections/slice.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,9 +1083,36 @@ impl<T> SliceExt for [T] {
10831083
}
10841084
}
10851085

1086+
// HACK: With cfg(test) `impl [T]` is not available, these three functions are actually methods
1087+
// that are in `impl [T]` but not in `core::slice::SliceExt` - this is only need for testing
1088+
#[cfg(test)]
1089+
pub fn into_vec<T>(mut b: Box<[T]>) -> Vec<T> {
1090+
unsafe {
1091+
let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len());
1092+
mem::forget(b);
1093+
xs
1094+
}
1095+
}
1096+
1097+
#[cfg(test)]
1098+
pub fn permutations<T>(s: &[T]) -> Permutations<T> where T: Clone {
1099+
Permutations{
1100+
swaps: ElementSwaps::new(s.len()),
1101+
v: ::slice::to_vec(s),
1102+
}
1103+
}
1104+
1105+
#[cfg(test)]
1106+
pub fn to_vec<T>(s: &[T]) -> Vec<T> where T: Clone {
1107+
let mut vector = Vec::with_capacity(s.len());
1108+
vector.push_all(s);
1109+
vector
1110+
}
1111+
10861112
#[cfg(not(stage0))]
10871113
/// Allocating extension methods for slices.
10881114
#[lang = "slice"]
1115+
#[cfg(not(test))]
10891116
#[stable(feature = "rust1", since = "1.0.0")]
10901117
impl<T> [T] {
10911118
/// Sorts the slice, in place, using `compare` to compare
@@ -2022,7 +2049,13 @@ impl<T> BorrowMut<[T]> for Vec<T> {
20222049
#[stable(feature = "rust1", since = "1.0.0")]
20232050
impl<T: Clone> ToOwned for [T] {
20242051
type Owned = Vec<T>;
2052+
#[cfg(not(test))]
20252053
fn to_owned(&self) -> Vec<T> { self.to_vec() }
2054+
2055+
// HACK: `impl [T]` is not available in cfg(test), use `::slice::to_vec` instead of
2056+
// `<[T]>::to_vec`
2057+
#[cfg(test)]
2058+
fn to_owned(&self) -> Vec<T> { ::slice::to_vec(self) }
20262059
}
20272060

20282061
////////////////////////////////////////////////////////////////////////////////
@@ -2339,3 +2372,63 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
23392372
old
23402373
}
23412374
}
2375+
2376+
#[cfg(test)]
2377+
mod test {
2378+
use core::iter::{Iterator, IteratorExt};
2379+
use core::option::Option::{None, Some};
2380+
use string::ToString;
2381+
2382+
#[test]
2383+
fn test_permutations() {
2384+
{
2385+
let v: [i32; 0] = [];
2386+
let mut it = ::slice::permutations(&v);
2387+
let (min_size, max_opt) = it.size_hint();
2388+
assert_eq!(min_size, 1);
2389+
assert_eq!(max_opt.unwrap(), 1);
2390+
assert_eq!(it.next(), Some(::slice::to_vec(&v)));
2391+
assert_eq!(it.next(), None);
2392+
}
2393+
{
2394+
let v = ["Hello".to_string()];
2395+
let mut it = ::slice::permutations(&v);
2396+
let (min_size, max_opt) = it.size_hint();
2397+
assert_eq!(min_size, 1);
2398+
assert_eq!(max_opt.unwrap(), 1);
2399+
assert_eq!(it.next(), Some(::slice::to_vec(&v)));
2400+
assert_eq!(it.next(), None);
2401+
}
2402+
{
2403+
let v = [1, 2, 3];
2404+
let mut it = ::slice::permutations(&v);
2405+
let (min_size, max_opt) = it.size_hint();
2406+
assert_eq!(min_size, 3*2);
2407+
assert_eq!(max_opt.unwrap(), 3*2);
2408+
assert_eq!(it.next().unwrap(), [1,2,3]);
2409+
assert_eq!(it.next().unwrap(), [1,3,2]);
2410+
assert_eq!(it.next().unwrap(), [3,1,2]);
2411+
let (min_size, max_opt) = it.size_hint();
2412+
assert_eq!(min_size, 3);
2413+
assert_eq!(max_opt.unwrap(), 3);
2414+
assert_eq!(it.next().unwrap(), [3,2,1]);
2415+
assert_eq!(it.next().unwrap(), [2,3,1]);
2416+
assert_eq!(it.next().unwrap(), [2,1,3]);
2417+
assert_eq!(it.next(), None);
2418+
}
2419+
{
2420+
// check that we have N! permutations
2421+
let v = ['A', 'B', 'C', 'D', 'E', 'F'];
2422+
let mut amt = 0;
2423+
let mut it = ::slice::permutations(&v);
2424+
let (min_size, max_opt) = it.size_hint();
2425+
for _perm in it.by_ref() {
2426+
amt += 1;
2427+
}
2428+
assert_eq!(amt, it.swaps.swaps_made);
2429+
assert_eq!(amt, min_size);
2430+
assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
2431+
assert_eq!(amt, max_opt.unwrap());
2432+
}
2433+
}
2434+
}

src/libcollections/str.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,7 @@ impl StrExt for str {
15621562
#[cfg(not(stage0))]
15631563
/// Any string that can be represented as a slice.
15641564
#[lang = "str"]
1565+
#[cfg(not(test))]
15651566
#[stable(feature = "rust1", since = "1.0.0")]
15661567
impl str {
15671568
/// Escapes each char in `s` with `char::escape_default`.

src/libcollections/string.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,19 @@ impl String {
113113
#[inline]
114114
#[unstable(feature = "collections",
115115
reason = "needs investigation to see if to_string() can match perf")]
116+
#[cfg(not(test))]
116117
pub fn from_str(string: &str) -> String {
117118
String { vec: <[_]>::to_vec(string.as_bytes()) }
118119
}
119120

121+
// HACK: `impl [T]` is not available in cfg(test), use `::slice::to_vec` instead of
122+
// `<[T]>::to_vec`
123+
#[inline]
124+
#[cfg(test)]
125+
pub fn from_str(string: &str) -> String {
126+
String { vec: ::slice::to_vec(string.as_bytes()) }
127+
}
128+
120129
/// Returns the vector as a string buffer, if possible, taking care not to
121130
/// copy it.
122131
///

0 commit comments

Comments
 (0)