From a354e5b5cf433a8f1236c85f30cd19829a374f6d Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Fri, 3 Jul 2020 13:04:52 +1000 Subject: SSR: Update tests so that all paths in patterns can be resolved --- crates/ra_ssr/src/tests.rs | 164 +++++++++++++++++++++++++++------------------ 1 file changed, 97 insertions(+), 67 deletions(-) (limited to 'crates') diff --git a/crates/ra_ssr/src/tests.rs b/crates/ra_ssr/src/tests.rs index 9628dcbac..f20ae2cdf 100644 --- a/crates/ra_ssr/src/tests.rs +++ b/crates/ra_ssr/src/tests.rs @@ -148,8 +148,8 @@ fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expecte fn ssr_function_to_method() { assert_ssr_transform( "my_function($a, $b) ==>> ($a).my_method($b)", - "loop { my_function( other_func(x, y), z + w) }", - "loop { (other_func(x, y)).my_method(z + w) }", + "fn my_function() {} fn main() { loop { my_function( other_func(x, y), z + w) } }", + "fn my_function() {} fn main() { loop { (other_func(x, y)).my_method(z + w) } }", ) } @@ -157,8 +157,8 @@ fn ssr_function_to_method() { fn ssr_nested_function() { assert_ssr_transform( "foo($a, $b, $c) ==>> bar($c, baz($a, $b))", - "fn main { foo (x + value.method(b), x+y-z, true && false) }", - "fn main { bar(true && false, baz(x + value.method(b), x+y-z)) }", + "fn foo() {} fn main { foo (x + value.method(b), x+y-z, true && false) }", + "fn foo() {} fn main { bar(true && false, baz(x + value.method(b), x+y-z)) }", ) } @@ -166,8 +166,8 @@ fn ssr_nested_function() { fn ssr_expected_spacing() { assert_ssr_transform( "foo($x) + bar() ==>> bar($x)", - "fn main() { foo(5) + bar() }", - "fn main() { bar(5) }", + "fn foo() {} fn bar() {} fn main() { foo(5) + bar() }", + "fn foo() {} fn bar() {} fn main() { bar(5) }", ); } @@ -175,8 +175,8 @@ fn ssr_expected_spacing() { fn ssr_with_extra_space() { assert_ssr_transform( "foo($x ) + bar() ==>> bar($x)", - "fn main() { foo( 5 ) +bar( ) }", - "fn main() { bar(5) }", + "fn foo() {} fn bar() {} fn main() { foo( 5 ) +bar( ) }", + "fn foo() {} fn bar() {} fn main() { bar(5) }", ); } @@ -184,8 +184,8 @@ fn ssr_with_extra_space() { fn ssr_keeps_nested_comment() { assert_ssr_transform( "foo($x) ==>> bar($x)", - "fn main() { foo(other(5 /* using 5 */)) }", - "fn main() { bar(other(5 /* using 5 */)) }", + "fn foo() {} fn main() { foo(other(5 /* using 5 */)) }", + "fn foo() {} fn main() { bar(other(5 /* using 5 */)) }", ) } @@ -193,8 +193,8 @@ fn ssr_keeps_nested_comment() { fn ssr_keeps_comment() { assert_ssr_transform( "foo($x) ==>> bar($x)", - "fn main() { foo(5 /* using 5 */) }", - "fn main() { bar(5)/* using 5 */ }", + "fn foo() {} fn main() { foo(5 /* using 5 */) }", + "fn foo() {} fn main() { bar(5)/* using 5 */ }", ) } @@ -202,8 +202,8 @@ fn ssr_keeps_comment() { fn ssr_struct_lit() { assert_ssr_transform( "foo{a: $a, b: $b} ==>> foo::new($a, $b)", - "fn main() { foo{b:2, a:1} }", - "fn main() { foo::new(1, 2) }", + "fn foo() {} fn main() { foo{b:2, a:1} }", + "fn foo() {} fn main() { foo::new(1, 2) }", ) } @@ -225,16 +225,18 @@ fn match_fn_definition() { #[test] fn match_struct_definition() { - assert_matches( - "struct $n {$f: Option}", - "struct Bar {} struct Foo {name: Option}", - &["struct Foo {name: Option}"], - ); + let code = r#" + struct Option {} + struct Bar {} + struct Foo {name: Option}"#; + assert_matches("struct $n {$f: Option}", code, &["struct Foo {name: Option}"]); } #[test] fn match_expr() { - let code = "fn f() -> i32 {foo(40 + 2, 42)}"; + let code = r#" + fn foo() {} + fn f() -> i32 {foo(40 + 2, 42)}"#; assert_matches("foo($a, $b)", code, &["foo(40 + 2, 42)"]); assert_no_match("foo($a, $b, $c)", code); assert_no_match("foo($a)", code); @@ -263,7 +265,9 @@ fn match_nested_method_calls_with_macro_call() { #[test] fn match_complex_expr() { - let code = "fn f() -> i32 {foo(bar(40, 2), 42)}"; + let code = r#" + fn foo() {} fn bar() {} + fn f() -> i32 {foo(bar(40, 2), 42)}"#; assert_matches("foo($a, $b)", code, &["foo(bar(40, 2), 42)"]); assert_no_match("foo($a, $b, $c)", code); assert_no_match("foo($a)", code); @@ -274,53 +278,62 @@ fn match_complex_expr() { #[test] fn match_with_trailing_commas() { // Code has comma, pattern doesn't. - assert_matches("foo($a, $b)", "fn f() {foo(1, 2,);}", &["foo(1, 2,)"]); - assert_matches("Foo{$a, $b}", "fn f() {Foo{1, 2,};}", &["Foo{1, 2,}"]); + assert_matches("foo($a, $b)", "fn foo() {} fn f() {foo(1, 2,);}", &["foo(1, 2,)"]); + assert_matches("Foo{$a, $b}", "struct Foo {} fn f() {Foo{1, 2,};}", &["Foo{1, 2,}"]); // Pattern has comma, code doesn't. - assert_matches("foo($a, $b,)", "fn f() {foo(1, 2);}", &["foo(1, 2)"]); - assert_matches("Foo{$a, $b,}", "fn f() {Foo{1, 2};}", &["Foo{1, 2}"]); + assert_matches("foo($a, $b,)", "fn foo() {} fn f() {foo(1, 2);}", &["foo(1, 2)"]); + assert_matches("Foo{$a, $b,}", "struct Foo {} fn f() {Foo{1, 2};}", &["Foo{1, 2}"]); } #[test] fn match_type() { assert_matches("i32", "fn f() -> i32 {1 + 2}", &["i32"]); - assert_matches("Option<$a>", "fn f() -> Option {42}", &["Option"]); - assert_no_match("Option<$a>", "fn f() -> Result {42}"); + assert_matches( + "Option<$a>", + "struct Option {} fn f() -> Option {42}", + &["Option"], + ); + assert_no_match( + "Option<$a>", + "struct Option {} struct Result {} fn f() -> Result {42}", + ); } #[test] fn match_struct_instantiation() { - assert_matches( - "Foo {bar: 1, baz: 2}", - "fn f() {Foo {bar: 1, baz: 2}}", - &["Foo {bar: 1, baz: 2}"], - ); + let code = r#" + struct Foo {bar: i32, baz: i32} + fn f() {Foo {bar: 1, baz: 2}}"#; + assert_matches("Foo {bar: 1, baz: 2}", code, &["Foo {bar: 1, baz: 2}"]); // Now with placeholders for all parts of the struct. - assert_matches( - "Foo {$a: $b, $c: $d}", - "fn f() {Foo {bar: 1, baz: 2}}", - &["Foo {bar: 1, baz: 2}"], - ); - assert_matches("Foo {}", "fn f() {Foo {}}", &["Foo {}"]); + assert_matches("Foo {$a: $b, $c: $d}", code, &["Foo {bar: 1, baz: 2}"]); + assert_matches("Foo {}", "struct Foo {} fn f() {Foo {}}", &["Foo {}"]); } #[test] fn match_path() { - assert_matches("foo::bar", "fn f() {foo::bar(42)}", &["foo::bar"]); - assert_matches("$a::bar", "fn f() {foo::bar(42)}", &["foo::bar"]); - assert_matches("foo::$b", "fn f() {foo::bar(42)}", &["foo::bar"]); + let code = r#" + mod foo { + fn bar() {} + } + fn f() {foo::bar(42)}"#; + assert_matches("foo::bar", code, &["foo::bar"]); + assert_matches("$a::bar", code, &["foo::bar"]); + assert_matches("foo::$b", code, &["foo::bar"]); } #[test] fn match_pattern() { - assert_matches("Some($a)", "fn f() {if let Some(x) = foo() {}}", &["Some(x)"]); + assert_matches("Some($a)", "struct Some(); fn f() {if let Some(x) = foo() {}}", &["Some(x)"]); } #[test] fn literal_constraint() { mark::check!(literal_constraint); let code = r#" + enum Option { Some(T), None } + use Option::Some; fn f1() { let x1 = Some(42); let x2 = Some("foo"); @@ -337,24 +350,36 @@ fn literal_constraint() { fn match_reordered_struct_instantiation() { assert_matches( "Foo {aa: 1, b: 2, ccc: 3}", - "fn f() {Foo {b: 2, ccc: 3, aa: 1}}", + "struct Foo {} fn f() {Foo {b: 2, ccc: 3, aa: 1}}", &["Foo {b: 2, ccc: 3, aa: 1}"], ); - assert_no_match("Foo {a: 1}", "fn f() {Foo {b: 1}}"); - assert_no_match("Foo {a: 1}", "fn f() {Foo {a: 2}}"); - assert_no_match("Foo {a: 1, b: 2}", "fn f() {Foo {a: 1}}"); - assert_no_match("Foo {a: 1, b: 2}", "fn f() {Foo {b: 2}}"); - assert_no_match("Foo {a: 1, }", "fn f() {Foo {a: 1, b: 2}}"); - assert_no_match("Foo {a: 1, z: 9}", "fn f() {Foo {a: 1}}"); + assert_no_match("Foo {a: 1}", "struct Foo {} fn f() {Foo {b: 1}}"); + assert_no_match("Foo {a: 1}", "struct Foo {} fn f() {Foo {a: 2}}"); + assert_no_match("Foo {a: 1, b: 2}", "struct Foo {} fn f() {Foo {a: 1}}"); + assert_no_match("Foo {a: 1, b: 2}", "struct Foo {} fn f() {Foo {b: 2}}"); + assert_no_match("Foo {a: 1, }", "struct Foo {} fn f() {Foo {a: 1, b: 2}}"); + assert_no_match("Foo {a: 1, z: 9}", "struct Foo {} fn f() {Foo {a: 1}}"); } #[test] fn match_macro_invocation() { - assert_matches("foo!($a)", "fn() {foo(foo!(foo()))}", &["foo!(foo())"]); - assert_matches("foo!(41, $a, 43)", "fn() {foo!(41, 42, 43)}", &["foo!(41, 42, 43)"]); - assert_no_match("foo!(50, $a, 43)", "fn() {foo!(41, 42, 43}"); - assert_no_match("foo!(41, $a, 50)", "fn() {foo!(41, 42, 43}"); - assert_matches("foo!($a())", "fn() {foo!(bar())}", &["foo!(bar())"]); + assert_matches( + "foo!($a)", + "macro_rules! foo {() => {}} fn() {foo(foo!(foo()))}", + &["foo!(foo())"], + ); + assert_matches( + "foo!(41, $a, 43)", + "macro_rules! foo {() => {}} fn() {foo!(41, 42, 43)}", + &["foo!(41, 42, 43)"], + ); + assert_no_match("foo!(50, $a, 43)", "macro_rules! foo {() => {}} fn() {foo!(41, 42, 43}"); + assert_no_match("foo!(41, $a, 50)", "macro_rules! foo {() => {}} fn() {foo!(41, 42, 43}"); + assert_matches( + "foo!($a())", + "macro_rules! foo {() => {}} fn() {foo!(bar())}", + &["foo!(bar())"], + ); } // When matching within a macro expansion, we only allow matches of nodes that originated from @@ -389,15 +414,19 @@ fn no_match_split_expression() { #[test] fn replace_function_call() { - assert_ssr_transform("foo() ==>> bar()", "fn f1() {foo(); foo();}", "fn f1() {bar(); bar();}"); + assert_ssr_transform( + "foo() ==>> bar()", + "fn foo() {} fn f1() {foo(); foo();}", + "fn foo() {} fn f1() {bar(); bar();}", + ); } #[test] fn replace_function_call_with_placeholders() { assert_ssr_transform( "foo($a, $b) ==>> bar($b, $a)", - "fn f1() {foo(5, 42)}", - "fn f1() {bar(42, 5)}", + "fn foo() {} fn f1() {foo(5, 42)}", + "fn foo() {} fn f1() {bar(42, 5)}", ); } @@ -405,8 +434,8 @@ fn replace_function_call_with_placeholders() { fn replace_nested_function_calls() { assert_ssr_transform( "foo($a) ==>> bar($a)", - "fn f1() {foo(foo(42))}", - "fn f1() {bar(bar(42))}", + "fn foo() {} fn f1() {foo(foo(42))}", + "fn foo() {} fn f1() {bar(bar(42))}", ); } @@ -414,8 +443,8 @@ fn replace_nested_function_calls() { fn replace_type() { assert_ssr_transform( "Result<(), $a> ==>> Option<$a>", - "fn f1() -> Result<(), Vec> {foo()}", - "fn f1() -> Option> {foo()}", + "struct Result {} fn f1() -> Result<(), Vec> {foo()}", + "struct Result {} fn f1() -> Option> {foo()}", ); } @@ -423,8 +452,8 @@ fn replace_type() { fn replace_struct_init() { assert_ssr_transform( "Foo {a: $a, b: $b} ==>> Foo::new($a, $b)", - "fn f1() {Foo{b: 1, a: 2}}", - "fn f1() {Foo::new(2, 1)}", + "struct Foo {} fn f1() {Foo{b: 1, a: 2}}", + "struct Foo {} fn f1() {Foo::new(2, 1)}", ); } @@ -432,13 +461,13 @@ fn replace_struct_init() { fn replace_macro_invocations() { assert_ssr_transform( "try!($a) ==>> $a?", - "fn f1() -> Result<(), E> {bar(try!(foo()));}", - "fn f1() -> Result<(), E> {bar(foo()?);}", + "macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(try!(foo()));}", + "macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(foo()?);}", ); assert_ssr_transform( "foo!($a($b)) ==>> foo($b, $a)", - "fn f1() {foo!(abc(def() + 2));}", - "fn f1() {foo(def() + 2, abc);}", + "macro_rules! foo {() => {}} fn f1() {foo!(abc(def() + 2));}", + "macro_rules! foo {() => {}} fn f1() {foo(def() + 2, abc);}", ); } @@ -527,6 +556,7 @@ fn preserves_whitespace_within_macro_expansion() { #[test] fn match_failure_reasons() { let code = r#" + fn bar() {} macro_rules! foo { ($a:expr) => { 1 + $a + 2 -- cgit v1.2.3