internal: cleanup tests

This commit is contained in:
Aleksey Kladov 2021-06-16 23:27:04 +03:00
parent ee7b649d44
commit 35772256f8
2 changed files with 140 additions and 72 deletions

View File

@ -85,7 +85,9 @@ fn is_ref_and_impls_iter_method(
let krate = scope.module()?.krate(); let krate = scope.module()?.krate();
let traits_in_scope = scope.traits_in_scope(); let traits_in_scope = scope.traits_in_scope();
let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?; let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
let has_wanted_method = typ.iterate_method_candidates(
let has_wanted_method = typ
.iterate_method_candidates(
sema.db, sema.db,
krate, krate,
&traits_in_scope, &traits_in_scope,
@ -96,27 +98,35 @@ fn is_ref_and_impls_iter_method(
} }
None None
}, },
); )
has_wanted_method.and(Some((expr_behind_ref, wanted_method))) .is_some();
if !has_wanted_method {
return None;
}
Some((expr_behind_ref, wanted_method))
} }
/// Whether iterable implements core::Iterator /// Whether iterable implements core::Iterator
fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool { fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
let it_typ = if let Some(i) = sema.type_of_expr(iterable) { let it_typ = match sema.type_of_expr(iterable) {
i Some(it) => it,
} else { None => return false,
return false;
}; };
let module = if let Some(m) = sema.scope(iterable.syntax()).module() {
m let module = match sema.scope(iterable.syntax()).module() {
} else { Some(it) => it,
return false; None => return false,
}; };
let krate = module.krate(); let krate = module.krate();
if let Some(iter_trait) = FamousDefs(sema, Some(krate)).core_iter_Iterator() { match FamousDefs(sema, Some(krate)).core_iter_Iterator() {
return it_typ.impls_trait(sema.db, iter_trait, &[]); Some(iter_trait) => {
cov_mark::hit!(test_already_impls_iterator);
it_typ.impls_trait(sema.db, iter_trait, &[])
}
None => false,
} }
false
} }
#[cfg(test)] #[cfg(test)]
@ -125,33 +135,6 @@ mod tests {
use super::*; use super::*;
const EMPTY_ITER_FIXTURE: &'static str = r"
//- /lib.rs deps:core crate:empty_iter
pub struct EmptyIter;
impl Iterator for EmptyIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
pub struct Empty;
impl Empty {
pub fn iter(&self) -> EmptyIter { EmptyIter }
pub fn iter_mut(&self) -> EmptyIter { EmptyIter }
}
pub struct NoIterMethod;
";
fn check_assist_with_fixtures(before: &str, after: &str) {
let before = &format!(
"//- /main.rs crate:main deps:core,empty_iter{}{}{}",
before,
FamousDefs::FIXTURE,
EMPTY_ITER_FIXTURE
);
check_assist(replace_for_loop_with_for_each, before, after);
}
#[test] #[test]
fn test_not_for() { fn test_not_for() {
check_assist_not_applicable( check_assist_not_applicable(
@ -201,20 +184,44 @@ fn main() {
#[test] #[test]
fn test_for_borrowed() { fn test_for_borrowed() {
check_assist_with_fixtures( check_assist(
replace_for_loop_with_for_each,
r" r"
use empty_iter::*; //- minicore: iterator
struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
struct S;
impl S {
fn iter(&self) -> Iter { Iter }
fn iter_mut(&mut self) -> Iter { Iter }
}
fn main() { fn main() {
let x = Empty; let x = S;
for $0v in &x { for $0v in &x {
let a = v * 2; let a = v * 2;
} }
} }
", ",
r" r"
use empty_iter::*; struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
struct S;
impl S {
fn iter(&self) -> Iter { Iter }
fn iter_mut(&mut self) -> Iter { Iter }
}
fn main() { fn main() {
let x = Empty; let x = S;
x.iter().for_each(|v| { x.iter().for_each(|v| {
let a = v * 2; let a = v * 2;
}); });
@ -225,9 +232,10 @@ fn main() {
#[test] #[test]
fn test_for_borrowed_no_iter_method() { fn test_for_borrowed_no_iter_method() {
check_assist_with_fixtures( check_assist(
replace_for_loop_with_for_each,
r" r"
use empty_iter::*; struct NoIterMethod;
fn main() { fn main() {
let x = NoIterMethod; let x = NoIterMethod;
for $0v in &x { for $0v in &x {
@ -236,7 +244,7 @@ fn main() {
} }
", ",
r" r"
use empty_iter::*; struct NoIterMethod;
fn main() { fn main() {
let x = NoIterMethod; let x = NoIterMethod;
(&x).into_iter().for_each(|v| { (&x).into_iter().for_each(|v| {
@ -249,20 +257,44 @@ fn main() {
#[test] #[test]
fn test_for_borrowed_mut() { fn test_for_borrowed_mut() {
check_assist_with_fixtures( check_assist(
replace_for_loop_with_for_each,
r" r"
use empty_iter::*; //- minicore: iterator
struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
struct S;
impl S {
fn iter(&self) -> Iter { Iter }
fn iter_mut(&mut self) -> Iter { Iter }
}
fn main() { fn main() {
let x = Empty; let x = S;
for $0v in &mut x { for $0v in &mut x {
let a = v * 2; let a = v * 2;
} }
} }
", ",
r" r"
use empty_iter::*; struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
struct S;
impl S {
fn iter(&self) -> Iter { Iter }
fn iter_mut(&mut self) -> Iter { Iter }
}
fn main() { fn main() {
let x = Empty; let x = S;
x.iter_mut().for_each(|v| { x.iter_mut().for_each(|v| {
let a = v * 2; let a = v * 2;
}); });
@ -296,21 +328,32 @@ fn main() {
#[test] #[test]
fn test_already_impls_iterator() { fn test_already_impls_iterator() {
check_assist_with_fixtures( cov_mark::check!(test_already_impls_iterator);
check_assist(
replace_for_loop_with_for_each,
r#" r#"
use empty_iter::*; //- minicore: iterator
struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
fn main() { fn main() {
let x = Empty; for$0 a in Iter.take(1) {
for$0 a in x.iter().take(1) {
println!("{}", a); println!("{}", a);
} }
} }
"#, "#,
r#" r#"
use empty_iter::*; struct Iter;
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> { None }
}
fn main() { fn main() {
let x = Empty; Iter.take(1).for_each(|a| {
x.iter().take(1).for_each(|a| {
println!("{}", a); println!("{}", a);
}); });
} }

View File

@ -209,8 +209,29 @@ pub mod task {
// region:iterator // region:iterator
pub mod iter { pub mod iter {
mod adapters {
pub struct Take<I> {
iter: I,
n: usize,
}
impl<I> Iterator for Take<I>
where
I: Iterator,
{
type Item = <I as Iterator>::Item;
fn next(&mut self) -> Option<<I as Iterator>::Item> {
loop {}
}
}
}
pub use self::adapters::Take;
mod traits { mod traits {
mod iterator { mod iterator {
use super::super::Take;
pub trait Iterator { pub trait Iterator {
type Item; type Item;
#[lang = "next"] #[lang = "next"]
@ -218,8 +239,13 @@ pub mod iter {
fn nth(&mut self, n: usize) -> Option<Self::Item> { fn nth(&mut self, n: usize) -> Option<Self::Item> {
loop {} loop {}
} }
fn take(self, n: usize) -> crate::iter::Take<Self> {
loop {}
} }
} }
}
pub use self::iterator::Iterator;
mod collect { mod collect {
pub trait IntoIterator { pub trait IntoIterator {
type Item; type Item;
@ -236,7 +262,6 @@ pub mod iter {
} }
} }
pub use self::collect::IntoIterator; pub use self::collect::IntoIterator;
pub use self::iterator::Iterator;
} }
pub use self::traits::{IntoIterator, Iterator}; pub use self::traits::{IntoIterator, Iterator};
} }