summaryrefslogtreecommitdiff
path: root/rust-mode-tests.el
diff options
context:
space:
mode:
Diffstat (limited to 'rust-mode-tests.el')
-rw-r--r--rust-mode-tests.el649
1 files changed, 648 insertions, 1 deletions
diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index a846a27..4a6cf20 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -710,6 +710,7 @@ INIT-POS, FINAL-POS are position symbols found in `rust-test-positions-alist'."
(with-temp-buffer
(rust-mode)
(insert source-code)
+ (font-lock-fontify-buffer)
(goto-char (rust-get-buffer-pos init-pos))
(apply manip-func args)
(should (equal (point) (rust-get-buffer-pos final-pos)))))
@@ -723,6 +724,7 @@ All positions are position symbols found in `rust-test-positions-alist'."
(with-temp-buffer
(rust-mode)
(insert source-code)
+ (font-lock-fontify-buffer)
(goto-char (rust-get-buffer-pos init-pos))
(apply manip-func args)
(should (equal (list (region-beginning) (region-end))
@@ -1303,7 +1305,7 @@ fn indented_already() {
\n // The previous line already has its spaces
}
")
-
+ (font-lock-fontify-buffer)
(goto-line 11)
(move-to-column 0)
(indent-for-tab-command)
@@ -1483,6 +1485,14 @@ la la\");
;; Needs to leave 1 space before "world"
"\"hello \\\n world\""))
+(ert-deftest indent-multi-line-type-param-list ()
+ (test-indent
+ "
+pub fn foo<T,
+ V>() {
+ hello();
+}"))
+
(defun rust-test-matching-parens (content pairs &optional nonparen-positions)
"Assert that in rust-mode, given a buffer with the given `content',
emacs's paren matching will find all of the pairs of positions
@@ -1562,3 +1572,640 @@ la la\");
"r#\"\"\"#;\n'q'"
'("r#\"\"\"#" font-lock-string-face
"'q'" font-lock-string-face)))
+
+(ert-deftest rust-test-basic-paren-matching ()
+ (rust-test-matching-parens
+ "
+fn foo() {
+ let a = [1, 2, 3];
+}"
+ '((8 9) ;; Parens of foo()
+ (11 36) ;; Curly braces
+ (25 33) ;; Square brackets
+ )))
+
+(ert-deftest rust-test-paren-matching-generic-fn ()
+ (rust-test-matching-parens
+ "
+fn foo<A>() {
+}"
+ '((8 10) ;; Angle brackets <A>
+ (11 12) ;; Parens
+ (14 16) ;; Curly braces
+ )))
+
+(ert-deftest rust-test-paren-matching-generic-fn-with-return-value ()
+ (rust-test-matching-parens
+ "
+fn foo<A>() -> bool {
+ false
+}"
+ '((8 10) ;; Angle brackets <A>
+ (11 12) ;; Parens
+ (22 34) ;; Curly braces
+ )
+
+ '(15 ;; The ">" in "->" is not an angle bracket
+ )))
+
+(ert-deftest rust-test-paren-matching-match-stmt ()
+ (rust-test-matching-parens
+ "
+fn foo() {
+ something_str(match <Type as Trait>::method() {
+ Some(_) => \"Got some\",
+ None => \"Nada\"
+ });
+}"
+ '((8 9) ;; parens of fn foo
+ (11 127) ;; curly braces of foo
+ (30 124) ;; parens of something_str
+ (37 51) ;; angle brackets of <Type as Trait>
+ (60 61) ;; parens of method()
+ (63 123) ;; curly braces of match
+ (77 79) ;; parens of Some(_)
+ )
+
+ '(82 ;; > in first =>
+ 112 ;; > in second =>
+ )))
+
+(ert-deftest rust-test-paren-matching-bitshift-operators ()
+ (rust-test-matching-parens
+ "
+fn foo(z:i32) {
+ let a:Option<Result<i32,i32>> = Some(Ok(4 >> 1));
+ let b = a.map(|x| x.map(|y| y << 3));
+ let trick_question = z<<<Type as Trait>::method(); // First two <s are not brackets, third is
+}"
+ '((34 50) ;; angle brackets of Option
+ (41 49) ;; angle brackets of Result
+ (142 156) ;; angle brackets of <Type as Trait>
+ )
+ '(64 ;; The >> inside Some(Ok()) are not angle brackets
+ 65 ;; The >> inside Some(Ok()) are not angle brackets
+ 106 ;; The << inside map() are not angle brackets
+ 107 ;; The << inside map() are not angle brackets
+ 140 ;; The << before <Type as Trait> are not angle brackets
+ 141 ;; The << before <Type as Trait> are not angle brackets
+ 183 ;; The < inside the comment
+ )))
+
+(ert-deftest rust-test-paren-matching-angle-bracket-after-colon-ident ()
+ (rust-test-matching-parens
+ "
+struct Bla<T> {
+ a:Option<(i32,Option<bool>)>,
+ b:Option<T>,
+ c:bool
+}
+
+fn f(x:i32,y:Option<i32>) {
+ let z:Option<i32> = None;
+ let b:Bla<i8> = Bla{
+ a:None,
+ b:None,
+ c:x<y.unwrap();
+ }
+}"
+ '((12 14) ;; Angle brackets of Bla<T>
+ (30 49) ;; Outer angle brackets of a:Option<...>
+ (42 47) ;; Inner angle brackets of Option<bool>
+ (64 66) ;; Angle brackets of Option<T>
+ (102 106) ;; Angle brackets of y:Option<i32>
+ (127 131) ;; Angle brackets of z:Option<i32>
+ (154 157) ;; Angle brackets of b:Bla<i8>
+ )
+ '(209 ;; less than operator in c:x<y.unwrap...
+ )))
+
+(ert-deftest rust-test-paren-matching-struct-literals ()
+ (rust-test-matching-parens
+ "
+fn foo(x:i32) -> Bar {
+ Bar {
+ b:x<3
+ }
+}"
+ '()
+ '(17 ;; the -> is not a brace
+ 46 ;; x<3 the < is a less than sign
+ ))
+ )
+
+(ert-deftest rust-test-paren-matching-nested-struct-literals ()
+ (rust-test-matching-parens
+ "
+fn f(x:i32,y:i32) -> Foo<Bar> {
+ Foo{
+ bar:Bar{
+ a:3,
+ b:x<y
+ }
+ }
+}
+"
+ '((26 30)) ;; Angle brackets of Foo<Bar>
+ )
+ '(92 ;; less than operator x<y
+ ))
+
+(ert-deftest rust-test-paren-matching-fn-types-in-type-params ()
+ (rust-test-matching-parens
+ "
+fn foo<T:Fn() -> X<Y>>() -> Z {
+}
+"
+ '((8 23) ;; The angle brackets of foo<T...>
+ (20 22 ;; The angle brackets of X<Y>
+ ))
+ '(17 ;; The first ->
+ 28 ;; The second ->
+ )
+ ))
+
+(ert-deftest rust-test-paren-matching-lt-ops-in-fn-params ()
+ (rust-test-matching-parens
+ "
+fn foo(x:i32) {
+ f(x < 3);
+}
+"
+ '()
+ '(26 ;; The < inside f is a less than operator
+ )
+ ))
+
+(ert-deftest rust-test-paren-matching-lt-ops-in-fn-params ()
+ (rust-test-matching-parens
+ "
+fn foo(x:i32) -> bool {
+ return x < 3;
+}
+"
+ '()
+ '(17 ;; The ->
+ 39 ;; The < after return is a less than operator
+ )
+ ))
+
+(ert-deftest rust-test-type-paren-matching-angle-brackets-in-type-items ()
+ (rust-test-matching-parens
+ "
+type Foo = Blah<Z,Y>;
+type Bar<X> = (Foo, Bletch<X>);
+type ThisThing<Z,A,D,F> = HereYouGo<Z,Y<Fn(A) -> B<C<D>>,E<F>>>;"
+ '((17 21) ;; Angle brackets of Blah<Z,Y>
+ (32 34) ;; Angle brackets of Bar<X>
+ (50 52) ;; Angle brackets of Bletch<X>
+ (70 78) ;; Angle brackets of ThisThing<Z,A,D,F>
+ (91 118) ;; Angle brackets of HereYouGo<...>
+ (95 117) ;; Angle brackets of Y<Fn...>
+ (106 111) ;; Angle brackets of B<C<D>>
+ (108 110) ;; Angle brackets of C<D>
+ (114 116) ;; Angle brackets of E<F>
+ )))
+
+(ert-deftest rust-test-paren-matching-tuple-like-struct ()
+ (rust-test-matching-parens
+ "
+struct A(Option<B>);
+struct C<Q>(Result<Q,i32>);"
+ '((17 19) ;; The angle brackets <B>
+ (10 20) ;; The parens of A();
+ (31 33) ;; The angle brackets of C<Q>
+ (41 47) ;; The angle brackets of Result<Q,i32>
+ )
+ '()))
+
+(ert-deftest rust-test-paren-matching-in-enum ()
+ (rust-test-matching-parens
+ "
+enum Boo<A> {
+ TupleLike(Option<A>),
+ StructLike{foo: Result<A,i32>}
+}"
+ '((10 12) ;; Angle brackets of Boo<A>
+ (36 38) ;; Angle brackets of Option<A>
+ (68 74) ;; Angle brackets of Result<A,i32>
+ )))
+
+(ert-deftest rust-test-paren-matching-assoc-type-bounds ()
+ (rust-test-matching-parens
+ "impl <A:B<AssocType = C<A> >> Thing<A> {}"
+ '((6 29) ;; Outer angle brackets of impl
+ (10 28) ;; Outer angle brackets of B<AssocType = C<A>>
+ (24 26) ;; Inner angle brackets of C<A>
+ (36 38) ;; Angle brackets of Thing<A>
+ )
+ ))
+
+(ert-deftest rust-test-paren-matching-plus-signs-in-expressions-and-bounds ()
+ ;; Note that as I write this, the function "bluh" below does not compile, but
+ ;; it warns that the equality constraint in a where clause is "not yet
+ ;; supported." It seems that the compiler will support this eventually, so
+ ;; the emacs mode needs to support it.
+ (rust-test-matching-parens
+ "fn foo<A:Trait1+Trait2<i32>,B>(a:A,b:B) -> bool where B:Trait3<Foo>+Trait4<Bar> {
+ 2 + a < 3 && 3 + b > 11
+}
+
+fn bluh<A>() where A:Fn()+MyTrait<i32>, MyTrait<A>::AssocType = Option<bool> {
+}
+
+fn fluh<C>() where C:Fn(i32) -> (i32, i32) + SomeTrait<i32>, C::AssocType = OtherThing<bool> {
+}"
+ '((7 30) ;; Angle brackets of foo<...>
+ (23 27) ;; Angle brackets of Trait2<i32>
+ (63 67) ;; Angle brackets of Trait3<Foo>
+ (75 79) ;; Angle brackets of Trait4<Bar>
+
+ (121 123) ;; Angle brackets of bluh<A>
+ (147 151) ;; Angle brackets of MyTrait<i32>
+
+ (161 163) ;; Angle brackets of MyTrait<A>
+ (184 189) ;; Angle brackets of Option<bool>
+
+ (203 205) ;; Angle brackets of <C>
+ (250 254) ;; Angle brackets of SomeTrait<i32>
+ (282 287) ;; Angle brackets of Option<bool>
+ )
+ '(93 ;; Less-than sign of a < 3
+ 106 ;; Greater than sign of b > 11
+ )))
+
+(ert-deftest rust-test-paren-matching-generic-type-in-tuple-return-type ()
+ (rust-test-matching-parens
+ "pub fn take(mut self) -> (EmptyBucket<K, V, M>, K, V) {}"
+ '((38 46))
+ ))
+
+(ert-deftest rust-test-paren-matching-references-and-logical-and ()
+ (rust-test-matching-parens
+ "
+fn ampersand_check(a: &Option<i32>, b:bool) -> &Option<u32> {
+ a.map(|x| {
+ b && x < 32
+ })
+}"
+ '((31 35) ;; Option<i32>
+ (56 60) ;; Option<u32>
+ )
+ '(95 ;; x < 32
+ )
+ )
+ )
+
+(ert-deftest rust-test-paren-matching-lt-sign-in-if-statement ()
+ (rust-test-matching-parens
+ "
+fn if_check(a:i32,b:i32,c:i32) {
+ if a + b < c {
+
+ }
+ if a < b {
+
+ }
+ if (c < a) {
+
+ }
+}
+
+fn while_check(x:i32,y:i32) -> bool {
+ while x < y {
+ }
+ for x in y < x {
+ }
+ match y < z {
+ true => (), _ => ()
+ }
+ return z < y;
+}"
+ '()
+ '(48 ;; b < c
+ 78 ;; a < b
+ 109 ;; (c < a)
+
+ 184 ;; x < y
+ 211 ;; y < x
+ 235 ;; y < z
+ 288 ;; z < y
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-expr-with-field ()
+ (rust-test-matching-parens
+ "fn foo() { x.y < 3 }"
+ '()
+ '(16 ;; x.y < 3
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-expr-with-quote ()
+ (rust-test-matching-parens
+ "
+fn quote_check() {
+ 'x' < y;
+ \"y\" < x;
+ r##\"z\"## < q;
+ a <= 3 && b < '2'
+}"
+ '()
+ '(29 ;; 'x' < y
+ 42 ;; "y" < x
+ 60 ;; r##"z"## < q
+ 71 ;; a <= '3'
+ 81 ;; b < '2'
+ )))
+
+(ert-deftest rust-test-paren-matching-keywords-capitalized-are-ok-type-names ()
+ (rust-test-matching-parens
+ "
+fn foo() -> Box<i32> {
+ let z:If<bool> = If(a < 3);
+}"
+ '((17 21) ;; Box<i32>
+ (37 42) ;; If<bool>
+ )
+ '(51 ;; If(a < 3)
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-expression-inside-macro ()
+ (rust-test-matching-parens
+ "fn bla() { assert!(x < y); }"
+ '()
+ '(22 ;; x < y
+ )))
+
+(ert-deftest rust-test-paren-matching-array-types-with-generics ()
+ (rust-test-matching-parens
+ "fn boo () -> [Option<i32>] {}"
+ '((21 25))))
+
+(ert-deftest rust-test-paren-matching-angle-bracket-inner-reference ()
+ (rust-test-matching-parens
+ "fn x() -> Option<&Node<T>> {}"
+ '((17 26) ;; Option
+ (23 25) ;; Node
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-operator-after-semicolon ()
+ (rust-test-matching-parens
+ "fn f(x:i32) -> bool { (); x < 3 }"
+ '()
+ '(29
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-operator-after-comma ()
+ (rust-test-matching-parens
+ "fn foo() {
+ (e, a < b)
+}"
+ '((16 25) ;; The parens ()
+ )
+ '(22 ;; The < operator
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-operator-after-let ()
+ (rust-test-matching-parens
+ "fn main() {
+ let x = a < b;
+}"
+ '((11 32) ;; The { }
+ )
+ '(27 ;; The < operator
+ )))
+
+(ert-deftest rust-test-paren-matching-two-lt-ops-in-a-row ()
+ (rust-test-matching-parens
+ "fn next(&mut self) -> Option<<I as Iterator>::Item>"
+ '((29 51) ;; Outer Option<>
+ (30 44) ;; Inner <I as Iterator>
+ )
+ '(21
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-after-caret ()
+ (rust-test-matching-parens
+ "fn foo() { x^2 < 3 }"
+ '((10 20) ;; The { }
+ )
+ '(16 ;; The < operator
+ )))
+
+(ert-deftest rust-test-paren-matching-lt-operator-after-special-type ()
+ (rust-test-matching-parens
+ "fn foo() { low as uint <= c }"
+ '((10 29))
+ '(24)))
+
+(ert-deftest rust-test-paren-matching-lt-operator-after-closing-curly-brace ()
+ (rust-test-matching-parens
+ "fn main() { if true {} a < 3 }"
+ '((11 30)
+ )
+ '(26)))
+
+(ert-deftest rust-test-paren-matching-const ()
+ (rust-test-matching-parens
+ "
+const BLA = 1 << 3;
+const BLUB = 2 < 4;"
+ '()
+ '(16
+ 17 ;; Both chars of the << in 1 << 3
+ 37 ;; The < in 2 < 4
+ )))
+
+(ert-deftest rust-test-paren-matching-c-like-enum ()
+ (rust-test-matching-parens
+ "
+enum CLikeEnum {
+ Two = 1 << 1,
+ Four = 1 << 2
+}"
+ '((17 56 ;; The { } of the enum
+ ))
+ '(31
+ 32 ;; The first <<
+ 50
+ 51 ;; The second <<
+ )))
+
+(ert-deftest rust-test-paren-matching-no-angle-brackets-in-macros ()
+ (rust-test-matching-parens
+ "
+fn foo<A>(a:A) {
+ macro_a!( foo::<ignore the bracets> );
+ macro_b![ foo as Option<B> ];
+}
+
+macro_c!{
+ struct Boo<D> {}
+}"
+ '((8 10))
+ ;; Inside macros, it should not find any angle brackets, even if it normally
+ ;; would
+ '(38 ;; macro_a <
+ 57 ;; macro_a >
+ 89 ;; macro_b <
+ 91 ;; macro_b >
+ 123 ;; macro_c <
+ 125 ;; macro_d >
+ )))
+
+(ert-deftest rust-test-paren-matching-type-with-module-name ()
+ (rust-test-matching-parens
+ "
+const X: libc::c_int = 1 << 2;
+fn main() {
+ let z: libc::c_uint = 1 << 4;
+}
+"
+ '((43 79)) ;; The curly braces
+ '(27
+ 28 ;; The first <<
+ 73
+ 74 ;; The second <<
+ )))
+
+(ert-deftest rust-test-paren-matching-qualififed-struct-literal ()
+ (rust-test-matching-parens
+ "
+fn foo() -> Fn(asd) -> F<V> {
+ let z = foo::Struct{ b: 1 << 4, c: 2 < 4 }
+}"
+ '((30 80) ;; Outer curly brackets
+ )
+ '(62
+ 63 ;; The shift operator
+ 73 ;; The less than operator
+ )))
+
+(ert-deftest rust-test-paren-matching-let-mut ()
+ (rust-test-matching-parens
+ "
+fn f() {
+ let mut b = 1 < 3;
+ let mut i = 1 << 3;
+}
+"
+ '()
+ '(28 ;; 1 < 3
+ 51
+ 52 ;; 1 << 3
+ )))
+
+(ert-deftest rust-test-paren-matching-as-ref-type ()
+ (rust-test-matching-parens
+ "fn f() {
+ let a = b as &Foo<Bar>;
+}"
+ '((31 35) ;; Angle brackets Foo<Bar>
+ )))
+
+(ert-deftest rust-test-paren-matching-type-ascription ()
+ (rust-test-matching-parens
+ "
+fn rfc803() {
+ let z = a < b:FunnkyThing<int>;
+ let s = Foo {
+ a: b < 3,
+ b: d:CrazyStuff<int> < 3,
+ c: 2 < x:CrazyStuff<uint>
+ }
+}"
+ '((45 49) ;; FunkyThing<int>
+ (111 115) ;; CrazyStuff<int>
+ (149 154) ;; CrazyStuff<uint>
+ )
+ '(30 ;; a < b
+ 83 ;; b < 3
+ 117 ;; d... < 3
+ 135 ;; 2 < x
+ )))
+
+(ert-deftest rust-test-paren-matching-angle-brackets-in-enum-with-where-claause ()
+ (rust-test-matching-parens
+ "
+enum MyEnum<T> where T:std::fmt::Debug {
+ Thing(Option<T>)
+}"
+ '((13 15) ;; MyEnum<T>
+ (59 61) ;; Option<T>
+ )))
+
+(ert-deftest rust-test-paren-matching-where-clauses-with-closure-types ()
+ (rust-test-matching-parens
+ "
+enum Boo<'a,T> where T:Fn() -> Option<&'a str> + 'a {
+ Thingy(Option<&'a T>)
+}
+
+fn foo<'a>() -> Result<B,C> where C::X: D<A>, B:FnMut() -> Option<Q>+'a {
+ Foo(a < b)
+}
+
+type Foo<T> where T: Copy = Box<T>;
+"
+ '((10 15) ;; Boo<'a,T>
+ (39 47) ;; Option<&'a str>
+ (72 78) ;; Option<&'a T>
+
+ (106 110) ;; Result<B,C>
+ (125 127) ;; D<A>
+ (149 151) ;; Option<Q>
+ (184 186) ;; Foo<T>
+ (207 209) ;; Box<T>
+ )
+
+ '(168 ;; Foo(a < b)
+ )
+ ))
+
+(ert-deftest rust-test-angle-bracket-matching-turned-off ()
+ (let ((rust-match-angle-brackets nil))
+ (rust-test-matching-parens
+ "fn foo<a>() {}"
+ '((10 11))
+ '(7 9))))
+
+;; If electric-pair-mode is available, load it and run the tests that use it. If not,
+;; no error--the tests will be skipped.
+(require 'elec-pair nil t)
+
+;; The emacs 23 version of ERT does not have test skipping functionality. So
+;; don't even define these tests if elec-pair is not available.
+(when (featurep 'elec-pair)
+ (defun test-electric-pair-insert (original point-pos char closer)
+ (let ((old-electric-pair-mode electric-pair-mode))
+ (electric-pair-mode 1)
+ (unwind-protect
+ (with-temp-buffer
+ (rust-mode)
+ (insert original)
+ (font-lock-fontify-buffer)
+
+ (goto-char point-pos)
+ (deactivate-mark)
+ (let ((last-command-event char)) (self-insert-command 1))
+ (should (equal (char-after)
+ (or closer (aref original point-pos)))))
+ (electric-pair-mode (or old-electric-pair-mode 1)))))
+
+ (ert-deftest rust-test-electric-pair-generic-fn ()
+ (test-electric-pair-insert "fn foo() { }" 7 ?< ?>))
+
+ (ert-deftest rust-test-electric-pair-impl-param ()
+ (test-electric-pair-insert "impl Foo<T> for Bar<T>" 5 ?< ?>))
+
+ (ert-deftest rust-test-electric-pair-impl-for-type-param ()
+ (test-electric-pair-insert "impl<T> Foo<T> for Bar" 22 ?< ?>))
+
+ (ert-deftest rust-test-electric-pair-lt-expression ()
+ (test-electric-pair-insert "fn foo(bar:i32) -> bool { bar }" 30 ?< nil))
+
+ (ert-deftest rust-test-electric-pair-lt-expression-in-struct-literal ()
+ (test-electric-pair-insert "fn foo(x:i32) -> Bar { Bar { a:(bleh() + whatever::<X>()), b:x } }" 63 ?< nil))
+
+ (ert-deftest rust-test-electric-pair-lt-expression-capitalized-keyword ()
+ (test-electric-pair-insert "fn foo() -> Box" 16 ?< ?>))
+ )