aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-29 09:39:51 +0100
committerGitHub <[email protected]>2020-07-29 09:39:51 +0100
commit82e390ff8687038740b3d3bcfa6c69441ad0be0c (patch)
treedbe2f77a15554846b9a053d59b517acea77e75d4 /crates/ra_ide
parent5a8124273dd663f7f1ed43b53defc4a2c52dbc12 (diff)
parentbb1ae85ed0bdd854029435ac5a9f175e3f33e2e7 (diff)
Merge #5561
5561: Allow running more tests at once via the module runners r=matklad a=SomeoneToIgnore Sometimes I group tests into submodules located in the root `#[cfg(test)]` crate and want to (re)run them all at once. This PR adds more test runnables to allow running all tests in the file via a module runner. Not all possible module runners are added, to avoid displaying too many code lens. before: <img width="306" alt="before" src="https://user-images.githubusercontent.com/2690773/88724886-e4c6ea00-d133-11ea-9d80-082bb610d422.png"> after (`nested_tests_0` got the runnable, `root_tests` had not): <img width="300" alt="after" src="https://user-images.githubusercontent.com/2690773/88724896-e85a7100-d133-11ea-99ee-689126679cbc.png"> Co-authored-by: Kirill Bulatov <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/runnables.rs164
1 files changed, 110 insertions, 54 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 95a35a28d..45e0a7d85 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -220,15 +220,7 @@ fn runnable_mod(
220 module: ast::Module, 220 module: ast::Module,
221 file_id: FileId, 221 file_id: FileId,
222) -> Option<Runnable> { 222) -> Option<Runnable> {
223 let has_test_function = module 223 if !has_test_function_or_multiple_test_submodules(&module) {
224 .item_list()?
225 .items()
226 .filter_map(|it| match it {
227 ast::ModuleItem::FnDef(it) => Some(it),
228 _ => None,
229 })
230 .any(|f| has_test_related_attribute(&f));
231 if !has_test_function {
232 return None; 224 return None;
233 } 225 }
234 let module_def = sema.to_def(&module)?; 226 let module_def = sema.to_def(&module)?;
@@ -246,6 +238,34 @@ fn runnable_mod(
246 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg_exprs }) 238 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg_exprs })
247} 239}
248 240
241// We could create runnables for modules with number_of_test_submodules > 0,
242// but that bloats the runnables for no real benefit, since all tests can be run by the submodule already
243fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool {
244 if let Some(item_list) = module.item_list() {
245 let mut number_of_test_submodules = 0;
246
247 for item in item_list.items() {
248 match item {
249 ast::ModuleItem::FnDef(f) => {
250 if has_test_related_attribute(&f) {
251 return true;
252 }
253 }
254 ast::ModuleItem::Module(submodule) => {
255 if has_test_function_or_multiple_test_submodules(&submodule) {
256 number_of_test_submodules += 1;
257 }
258 }
259 _ => (),
260 }
261 }
262
263 number_of_test_submodules > 1
264 } else {
265 false
266 }
267}
268
249#[cfg(test)] 269#[cfg(test)]
250mod tests { 270mod tests {
251 use expect::{expect, Expect}; 271 use expect::{expect, Expect};
@@ -571,19 +591,33 @@ mod test_mod {
571 } 591 }
572 592
573 #[test] 593 #[test]
574 fn test_runnables_one_depth_layer_module() { 594 fn only_modules_with_test_functions_or_more_than_one_test_submodule_have_runners() {
575 check( 595 check(
576 r#" 596 r#"
577//- /lib.rs 597//- /lib.rs
578<|> 598<|>
579mod foo { 599mod root_tests {
580 mod test_mod { 600 mod nested_tests_0 {
581 #[test] 601 mod nested_tests_1 {
582 fn test_foo1() {} 602 #[test]
603 fn nested_test_11() {}
604
605 #[test]
606 fn nested_test_12() {}
607 }
608
609 mod nested_tests_2 {
610 #[test]
611 fn nested_test_2() {}
612 }
613
614 mod nested_tests_3 {}
583 } 615 }
616
617 mod nested_tests_4 {}
584} 618}
585"#, 619"#,
586 &[&TEST, &TEST], 620 &[&TEST, &TEST, &TEST, &TEST, &TEST, &TEST],
587 expect![[r#" 621 expect![[r#"
588 [ 622 [
589 Runnable { 623 Runnable {
@@ -591,18 +625,18 @@ mod foo {
591 file_id: FileId( 625 file_id: FileId(
592 1, 626 1,
593 ), 627 ),
594 full_range: 15..77, 628 full_range: 22..323,
595 focus_range: Some( 629 focus_range: Some(
596 19..27, 630 26..40,
597 ), 631 ),
598 name: "test_mod", 632 name: "nested_tests_0",
599 kind: MODULE, 633 kind: MODULE,
600 container_name: None, 634 container_name: None,
601 description: None, 635 description: None,
602 docs: None, 636 docs: None,
603 }, 637 },
604 kind: TestMod { 638 kind: TestMod {
605 path: "foo::test_mod", 639 path: "root_tests::nested_tests_0",
606 }, 640 },
607 cfg_exprs: [], 641 cfg_exprs: [],
608 }, 642 },
@@ -611,11 +645,31 @@ mod foo {
611 file_id: FileId( 645 file_id: FileId(
612 1, 646 1,
613 ), 647 ),
614 full_range: 38..71, 648 full_range: 51..192,
615 focus_range: Some( 649 focus_range: Some(
616 57..66, 650 55..69,
617 ), 651 ),
618 name: "test_foo1", 652 name: "nested_tests_1",
653 kind: MODULE,
654 container_name: None,
655 description: None,
656 docs: None,
657 },
658 kind: TestMod {
659 path: "root_tests::nested_tests_0::nested_tests_1",
660 },
661 cfg_exprs: [],
662 },
663 Runnable {
664 nav: NavigationTarget {
665 file_id: FileId(
666 1,
667 ),
668 full_range: 84..126,
669 focus_range: Some(
670 107..121,
671 ),
672 name: "nested_test_11",
619 kind: FN_DEF, 673 kind: FN_DEF,
620 container_name: None, 674 container_name: None,
621 description: None, 675 description: None,
@@ -623,7 +677,7 @@ mod foo {
623 }, 677 },
624 kind: Test { 678 kind: Test {
625 test_id: Path( 679 test_id: Path(
626 "foo::test_mod::test_foo1", 680 "root_tests::nested_tests_0::nested_tests_1::nested_test_11",
627 ), 681 ),
628 attr: TestAttr { 682 attr: TestAttr {
629 ignore: false, 683 ignore: false,
@@ -631,46 +685,48 @@ mod foo {
631 }, 685 },
632 cfg_exprs: [], 686 cfg_exprs: [],
633 }, 687 },
634 ]
635 "#]],
636 );
637 }
638
639 #[test]
640 fn test_runnables_multiple_depth_module() {
641 check(
642 r#"
643//- /lib.rs
644<|>
645mod foo {
646 mod bar {
647 mod test_mod {
648 #[test]
649 fn test_foo1() {}
650 }
651 }
652}
653"#,
654 &[&TEST, &TEST],
655 expect![[r#"
656 [
657 Runnable { 688 Runnable {
658 nav: NavigationTarget { 689 nav: NavigationTarget {
659 file_id: FileId( 690 file_id: FileId(
660 1, 691 1,
661 ), 692 ),
662 full_range: 33..107, 693 full_range: 140..182,
663 focus_range: Some( 694 focus_range: Some(
664 37..45, 695 163..177,
665 ), 696 ),
666 name: "test_mod", 697 name: "nested_test_12",
698 kind: FN_DEF,
699 container_name: None,
700 description: None,
701 docs: None,
702 },
703 kind: Test {
704 test_id: Path(
705 "root_tests::nested_tests_0::nested_tests_1::nested_test_12",
706 ),
707 attr: TestAttr {
708 ignore: false,
709 },
710 },
711 cfg_exprs: [],
712 },
713 Runnable {
714 nav: NavigationTarget {
715 file_id: FileId(
716 1,
717 ),
718 full_range: 202..286,
719 focus_range: Some(
720 206..220,
721 ),
722 name: "nested_tests_2",
667 kind: MODULE, 723 kind: MODULE,
668 container_name: None, 724 container_name: None,
669 description: None, 725 description: None,
670 docs: None, 726 docs: None,
671 }, 727 },
672 kind: TestMod { 728 kind: TestMod {
673 path: "foo::bar::test_mod", 729 path: "root_tests::nested_tests_0::nested_tests_2",
674 }, 730 },
675 cfg_exprs: [], 731 cfg_exprs: [],
676 }, 732 },
@@ -679,11 +735,11 @@ mod foo {
679 file_id: FileId( 735 file_id: FileId(
680 1, 736 1,
681 ), 737 ),
682 full_range: 60..97, 738 full_range: 235..276,
683 focus_range: Some( 739 focus_range: Some(
684 83..92, 740 258..271,
685 ), 741 ),
686 name: "test_foo1", 742 name: "nested_test_2",
687 kind: FN_DEF, 743 kind: FN_DEF,
688 container_name: None, 744 container_name: None,
689 description: None, 745 description: None,
@@ -691,7 +747,7 @@ mod foo {
691 }, 747 },
692 kind: Test { 748 kind: Test {
693 test_id: Path( 749 test_id: Path(
694 "foo::bar::test_mod::test_foo1", 750 "root_tests::nested_tests_0::nested_tests_2::nested_test_2",
695 ), 751 ),
696 attr: TestAttr { 752 attr: TestAttr {
697 ignore: false, 753 ignore: false,