cargo.el icon indicating copy to clipboard operation
cargo.el copied to clipboard

cargo-process-current-*test* for functional tests

Open Dushistov opened this issue 6 years ago • 5 comments

If create dummy crate with cargo new foo, and create subdirectory foo/tests

cargo new foo && cd foo && mkdir tests && touch tests/dummy.rs

with such dummy context: $ cat tests/dummy.rs

#[test]
fn test_dummy() {
   println!("do nothing");
}

then M-x cargo-process-current-test can not run test (I placed cursor at println!), because of it run cargo test ::test_dummy, while it should not use ::, so it runs 0 tests. Plus M-x cargo-process-current-file-tests run cargo test nil command, which one obviously not run any tests.

Dushistov avatar Jul 31 '17 20:07 Dushistov

Hi, thanks for reporting.

I fixed the current test issue in the latest commit: https://github.com/kwrooijen/cargo.el/commit/486d9a6aa6aac64a9c53555ec69980be5f3ad366

I also made sure that cargo test nil doesn't happen, and instead simply runs cargo test

We discussed briefly about running tests in a specific file https://github.com/kwrooijen/cargo.el/issues/39 but I haven't been able to come up with a good solution yet. Using something like RLS (like you mentioned) would probably be the best option, but I don't know when I'll have to time to actually tackle a project like that.

kwrooijen avatar Aug 01 '17 08:08 kwrooijen

@kwrooijen

Great, I will try it as soon as melpa update arrive.

We discussed briefly about running tests in a specific file #39 but I haven't been able to come up with a good solution yet.

Funny that recently after you fixed of #39 I met corner case:

    #[test]
    fn test_foreign_type_map_parsing() {
        let parse_sess = ParseSess::new();
        let types_map = parse_types_map(
            &parse_sess,
            "test",
            r#"
mod foreign_types_map {
    #![foreigner_type="boolean"]
    #![rust_type="jboolean"]
    #![foreigner_type="int"]
    #![rust_type="jint"]
}

impl SwigInto<bool> for jboolean {
    fn swig_into(self, _: *mut JNIEnv) -> bool {
        self != 0
    }
}

impl SwigFrom<bool> for jboolean {
    fn swig_from(x: bool, _: *mut JNIEnv) -> Self {
        if x { 1 as jboolean } else { 0 as jboolean }
    }
}

impl SwigFrom<i32> for jint {
    fn swig_from(x: i32, _: *mut JNIEnv) -> Self {
        x
    }
}
"#,
        );
        assert_eq!(types_map
                       .to_foreign_type_name(Symbol::intern("bool"))
                       .unwrap()
                       .0,
                   Symbol::intern("boolean"));

cargo-process-current-test = Unable to find test if put cursor into assert_eq!,

But if install imenu-list I get right information that I am inside test_foreign_type_map_parsing function, and imenu-list allow me to jump to function by it's name.

I suppose emacs-racer gives this information to imenu and imenu-list get from imenu, but I may be wrong here,

may be cargo.el also can get this information from imenu emacs's subsystem? imenu-list just visualize information as I understand, while imenu is part of emacs.

Dushistov avatar Aug 01 '17 08:08 Dushistov

So the reason this case is breaking is because we use rust-mode's rust-beginning-of-defun function. This allows us to figure out which function is at the current point. The problem is that it doesn't filter fns inside strings. So rust-beginning-of-defun jumps to the swig_from function (inside the string) instead of test_foreign_type_map_parsing.

So technically speaking this is an issue on rust-mode's side, but quite an edge-case. We could try to hack our way around this but it would be better to fix it at the source.

As for imenu, it could be used for finding all functions, but it doesn't distinguish if they have the [test] tag or not. Also AFAIK I don't think there's a way to find the function at point using imenu.

One simple way of finding all file tests would be to parse the file for [test] tags, but it would be nice to have a better structure of course.

kwrooijen avatar Aug 01 '17 09:08 kwrooijen

Seems fixed at now, thanks.

Dushistov avatar Aug 05 '17 18:08 Dushistov

Funny, that every time I thought that now were covered all cases, on the next day I use #[test] in some other way, and cargo-process-current-test not run test.

    #[test]
    fn it_works() {
        fn helper(a: i32) -> i32 {
            a * 2
        }
        assert_eq!(helper(1), 2);
    }

If put cursor at assert_eq! and run M-x cargo-process-current-test then cargo.el run wrong test: cargo test tests::helper, instead of cargo test tests::it_works

P.S.

This code of course is senseless, but in real code analog of helper function is used as argument for function that really tested by unit test.

Dushistov avatar Aug 09 '17 01:08 Dushistov