Skip to content

Commit

Permalink
Add ERT tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MicahChalmer committed Sep 6, 2013
1 parent 377b2c7 commit fcf1878
Show file tree
Hide file tree
Showing 3 changed files with 389 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/etc/emacs/README.md
Expand Up @@ -68,6 +68,12 @@ marking, press x, and ELPA will install the packages for you (under

* or using <kbd>M-x package-install rust-mode

### Tests via ERT

The file `rust-mode-tests.el` contains tests that can be run via ERT. You can
use `run_rust_emacs_tests.sh` to run them in batch mode, if emacs is somewhere
in your `$PATH`.

### Known bugs

* Combining `global-whitespace-mode` and `rust-mode` is generally glitchy.
Expand Down
3 changes: 3 additions & 0 deletions src/etc/emacs/run_rust_emacs_tests.sh
@@ -0,0 +1,3 @@
# This runs the test for emacs rust-mode.
# It must be possible to find emacs via PATH.
emacs -batch -l rust-mode.el -l rust-mode-tests.el -f ert-run-tests-batch-and-exit
380 changes: 380 additions & 0 deletions src/etc/emacs/rust-mode-tests.el
@@ -0,0 +1,380 @@
;;; rust-mode-tests.el --- ERT tests for rust-mode.el

(require 'rust-mode)
(require 'ert)
(require 'cl)

(setq rust-test-fill-column 32)

(defun rust-compare-code-after-manip (original point-pos manip-func expected got)
(equal expected got))

(defun rust-test-explain-bad-manip (original point-pos manip-func expected got)
(if (equal expected got)
nil
(list
;; The (goto-char) and (insert) business here is just for
;; convenience--after an error, you can copy-paste that into emacs eval to
;; insert the bare strings into a buffer
"Rust code was manipulated wrong after:"
`(insert ,original)
`(goto-char ,point-pos)
'expected `(insert ,expected)
'got `(insert ,got)
(loop for i from 0 to (max (length original) (length expected))
for oi = (if (< i (length got)) (elt got i))
for ei = (if (< i (length expected)) (elt expected i))
while (equal oi ei)
finally return `(first-difference-at
(goto-char ,(+ 1 i))
expected ,(char-to-string ei)
got ,(char-to-string oi))))))
(put 'rust-compare-code-after-manip 'ert-explainer
'rust-test-explain-bad-manip)

(defun rust-test-manip-code (original point-pos manip-func expected)
(with-temp-buffer
(rust-mode)
(insert original)
(goto-char point-pos)
(funcall manip-func)
(should (rust-compare-code-after-manip
original point-pos manip-func expected (buffer-string)))))

(defun test-fill-paragraph (unfilled expected &optional start-pos end-pos)
"We're going to run through many scenarios here--the point should be able to be anywhere from the start-pos (defaults to 1) through end-pos (defaults to the length of what was passed in) and (fill-paragraph) should return the same result.
Also, the result should be the same regardless of whether the code is at the beginning or end of the file. (If you're not careful, that can make a difference.) So we test each position given above with the passed code at the beginning, the end, neither and both. So we do this a total of (end-pos - start-pos)*4 times. Oy."
(let* ((start-pos (or start-pos 1))
(end-pos (or end-pos (length unfilled)))
(padding "\n \n")
(padding-len (length padding)))
(loop
for pad-at-beginning from 0 to 1
for pad-at-end from 0 to 1
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
with padding-end = (if (= 0 pad-at-end) "" padding)
with padding-adjust = (* padding-len pad-at-beginning)
with padding-beginning = (if (= 0 pad-at-beginning) "" padding)
with padding-end = (if (= 0 pad-at-end) "" padding)
for pos from (if (= 1 start-pos) 1 (+ padding-adjust start-pos)) to (+ end-pos padding-adjust)
do (rust-test-manip-code
(concat padding-beginning unfilled padding-end)
pos
(lambda ()
(let ((fill-column rust-test-fill-column))
(fill-paragraph)))
(concat padding-beginning expected padding-end)))))

(ert-deftest fill-paragraph-top-level-multi-line-style-doc-comment-second-line ()
(test-fill-paragraph
"/**
* This is a very very very very very very very long string
*/"
"/**
* This is a very very very very
* very very very long string
*/"))


(ert-deftest fill-paragraph-top-level-multi-line-style-doc-comment-first-line ()
(test-fill-paragraph
"/** This is a very very very very very very very long string
*/"
"/** This is a very very very
* very very very very long
* string
*/"))

(ert-deftest fill-paragraph-multi-paragraph-multi-line-style-doc-comment ()
(let
((multi-paragraph-unfilled
"/**
* This is the first really really really really really really really long paragraph
*
* This is the second really really really really really really long paragraph
*/"))
(test-fill-paragraph
multi-paragraph-unfilled
"/**
* This is the first really
* really really really really
* really really long paragraph
*
* This is the second really really really really really really long paragraph
*/"
1 89)
(test-fill-paragraph
multi-paragraph-unfilled
"/**
* This is the first really really really really really really really long paragraph
*
* This is the second really
* really really really really
* really long paragraph
*/"
90)))

(ert-deftest fill-paragraph-multi-paragraph-single-line-style-doc-comment ()
(let
((multi-paragraph-unfilled
"/// This is the first really really really really really really really long paragraph
///
/// This is the second really really really really really really long paragraph"))
(test-fill-paragraph
multi-paragraph-unfilled
"/// This is the first really
/// really really really really
/// really really long paragraph
///
/// This is the second really really really really really really long paragraph"
1 86)
(test-fill-paragraph
multi-paragraph-unfilled
"/// This is the first really really really really really really really long paragraph
///
/// This is the second really
/// really really really really
/// really long paragraph"
87)))

(ert-deftest fill-paragraph-multi-paragraph-single-line-style-indented ()
(test-fill-paragraph
" // This is the first really really really really really really really long paragraph
//
// This is the second really really really really really really long paragraph"
" // This is the first really
// really really really
// really really really
// long paragraph
//
// This is the second really really really really really really long paragraph" 1 89))

(ert-deftest fill-paragraph-multi-line-style-inner-doc-comment ()
(test-fill-paragraph
"/*! This is a very very very very very very very long string
*/"
"/*! This is a very very very
* very very very very long
* string
*/"))

(ert-deftest fill-paragraph-single-line-style-inner-doc-comment ()
(test-fill-paragraph
"//! This is a very very very very very very very long string"
"//! This is a very very very
//! very very very very long
//! string"))

(ert-deftest fill-paragraph-prefixless-multi-line-doc-comment ()
(test-fill-paragraph
"/**
This is my summary. Blah blah blah blah blah. Dilly dally dilly dally dilly dally doo.
This is some more text. Fee fie fo fum. Humpty dumpty sat on a wall.
*/"
"/**
This is my summary. Blah blah
blah blah blah. Dilly dally
dilly dally dilly dally doo.
This is some more text. Fee fie fo fum. Humpty dumpty sat on a wall.
*/" 4 90))

(ert-deftest fill-paragraph-with-no-space-after-star-prefix ()
(test-fill-paragraph
"/**
*This is a very very very very very very very long string
*/"
"/**
*This is a very very very very
*very very very long string
*/"))

(defun test-auto-fill (initial position inserted expected)
(rust-test-manip-code
initial
position
(lambda ()
(unwind-protect
(progn
(let ((fill-column rust-test-fill-column))
(auto-fill-mode)
(goto-char position)
(insert inserted)
(syntax-ppss-flush-cache 1)
(funcall auto-fill-function)))
(auto-fill-mode t)))
expected))

(ert-deftest auto-fill-multi-line-doc-comment ()
(test-auto-fill
"/**
*
*/"
8
"This is a very very very very very very very long string"
"/**
* This is a very very very very
* very very very long string
*/"))

(ert-deftest auto-fill-single-line-doc-comment ()
(test-auto-fill
"/// This is the first really
/// really really really really
/// really really long paragraph
///
/// "
103
"This is the second really really really really really really long paragraph"
"/// This is the first really
/// really really really really
/// really really long paragraph
///
/// This is the second really
/// really really really really
/// really long paragraph"
))

(ert-deftest auto-fill-multi-line-prefixless ()
(test-auto-fill
"/*
*/"
4
"This is a very very very very very very very long string"
"/*
This is a very very very very
very very very long string
*/"
))

(defun test-indent (indented)
(let ((deindented (replace-regexp-in-string "^[[:blank:]]*" " " indented)))
(rust-test-manip-code
deindented
1
(lambda () (indent-region 1 (buffer-size)))
indented)))


(ert-deftest indent-struct-fields-aligned ()
(test-indent
"
struct Foo { bar: int,
baz: int }
struct Blah {x:int,
y:int,
z:~str}"))

(ert-deftest indent-doc-comments ()
(test-indent
"
/**
* This is a doc comment
*
*/
/// So is this
fn foo() {
/*!
* this is a nested doc comment
*/
//! And so is this
}"))

(ert-deftest indent-inside-braces ()
(test-indent
"
// struct fields out one level:
struct foo {
a:int,
// comments too
b:char
}
fn bar(x:~int) { // comment here should not affect the next indent
bla();
bla();
}"))

(ert-deftest indent-top-level ()
(test-indent
"
// Everything here is at the top level and should not be indented
#[attrib]
mod foo;
pub static bar = Quux{a: b()}
use foo::bar::baz;
fn foo() { }
"))

(ert-deftest indent-params-no-align ()
(test-indent
"
// Indent out one level because no params appear on the first line
fn xyzzy(
a:int,
b:char) { }
fn abcdef(
a:int,
b:char)
-> char
{ }"))

(ert-deftest indent-params-align ()
(test-indent
"
// Align the second line of params to the first
fn foo(a:int,
b:char) { }
fn bar( a:int,
b:char)
-> int
{ }
fn baz( a:int, // shoudl work with a comment here
b:char)
-> int
{ }
"))

(ert-deftest indent-square-bracket-alignment ()
(test-indent
"
fn args_on_the_next_line( // with a comment
a:int,
b:~str) {
let aaaaaa = [
1,
2,
3];
let bbbbbbb = [1, 2, 3,
4, 5, 6];
let ccc = [ 10, 9, 8,
7, 6, 5];
}
"))

(ert-deftest indent-nested-fns ()
(test-indent
"
fn nexted_fns(a: fn(b:int,
c:char)
-> int,
d: int)
-> uint
{
0
}
"
))

0 comments on commit fcf1878

Please sign in to comment.