Remacs: Writing tests with remacs-sys dependencies

Created on 31 Aug 2017  路  5Comments  路  Source: remacs/remacs

Hi, I jut discovered this project yesterday, and first would like to say this is a cool idea, even if just a chance to dig into the emacs internals. So I decided to get stuck in, first by writing a few tests in lisp.rs, just to get oriented. This issue is mostly to track my progress, gather input, and help future wayfarers.

I wrote this little test

#[test]
fn test_float_promotion_on_exceeding_max_int() {
    let x = LispObject::int_or_float_from_fixnum(MOST_POSITIVE_FIXNUM+1);
    assert!(x.as_fixnum() == None);
}

but on running cargo test I get a linker error

  = note: /home/richard/remacs/rust_src/target/debug/deps/remacs-c65f4237c5aa0389.0.o: In function `remacs::lisp::{{impl}}::from_float':
          /home/richard/remacs/rust_src/src/lisp.rs:78: undefined reference to `make_float'
          collect2: error: ld returned 1 exit status

(make check also fails with this test in place, cargo build works - to be expected since presumably on build we don't need to do any linking).

Tracing this through, I found make_float is declared as an C function in remacs-sys, and defined in src/alloc.c. I could work all the way down, and port all of the functions across to rust, but perhaps in general there is some merit to being able to pin these functions with tests before doing the port. This would also make it more viable for people to contribute tests to the project as a way to get started.

Searching around, I couldn't find an obvious way to make cargo test link against the C code - is it known if there is a way to do this? Presumably we want cargo build to ignore linking.

Most helpful comment

(Warning Shameless Plug):

Once I finish up my work on, https://github.com/Wilfred/remacs/pull/286, I plan on finishing the next milestone for my mocking library, mock_derive. The next milestone will allow us to mock the results of extern "C" calls for tests. While not a perfect solution in my mind, it will allow us to write tests and piece meal bring over functions without having to figure out linking our C code to the Rust tests.

All 5 comments

Great question! Yes, we don't have a solution yet: the few tests we have don't link against remacs-sys because of exactly this problem.

We've mostly been porting elisp functions, so you can test them by starting an Remacs instance and just calling the functions in ielm. This works, but of course it's not well-suited for other bits of code.

We would really benefit from a better solution, but we don't have one yet.

(Warning Shameless Plug):

Once I finish up my work on, https://github.com/Wilfred/remacs/pull/286, I plan on finishing the next milestone for my mocking library, mock_derive. The next milestone will allow us to mock the results of extern "C" calls for tests. While not a perfect solution in my mind, it will allow us to write tests and piece meal bring over functions without having to figure out linking our C code to the Rust tests.

Cool! That sounds like a good middle ground for the moment. Plausibly this is the kind of enhancement that might have some traction in the cargo community (namely being able to provide extra linking parameters for test vs. build). C ports must be a common use case for Rust. Probably wouldn't be too hard to implement either. If I find some time...

As promised, I have opened a PR using the aforementioned crate. https://github.com/Wilfred/remacs/pull/304

In related news, I added support for elisp tests targeting files in rust_src/src. These are functional rather than unit tests but they are better than nothing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gorakhargosh picture gorakhargosh  路  7Comments

brotzeit picture brotzeit  路  3Comments

MarcusE1W picture MarcusE1W  路  5Comments

haller33 picture haller33  路  4Comments

Wilfred picture Wilfred  路  9Comments