These are chat archives for rust-lang/rust

25th
Sep 2017
Kunal Tyagi
@kunaltyagi
Sep 25 2017 02:52
cargo build is asking for 2 type arguments for Rc::Weak<T>. Any ideas why?
Code is simple
struct Node { ptr: std::rc::Weak<Node>,}
Michal 'vorner' Vaner
@vorner
Sep 25 2017 07:28
Hello. For some time I'm pondering an idea. I feel like I'm missing fixtures in my unit tests. Something that gets some code run before the test and something that cleans up after the code. It can be simulated a bit by having a struct Fixture that is created as the first thing in the test and the cleanup can go into its drop implementation. But I was thinking if it made sense to have somewhat more integrated support.
My idea was, if I have a type that is Default and possibly Drop (the fixture), I could annotate its methods with #[test]. In that case the compiler would first create an instance of the fixture with the Default implementation, run the test and then drop it. I think it feels somewhat natural, but does anyone see a problem? Or, if I wanted to make an RFC, should I first consult with somebody, or simply write it and create a merge request?
Aleksey Kladov
@matklad
Sep 25 2017 07:33
@vorner are you familiar how test.py handles fixtures? I think this is a super-nice approach, and, if you are going to write an RFC (which would be great), I urge you to consider its approach :)
Michal 'vorner' Vaner
@vorner
Sep 25 2017 07:35
I think it places def teardown(self) and def setup(self) into a class inheriting from unittest.TestCase. But it's a long time since I wrote something bigger in python and it may have changed.
Anyway, I was thinking about some very minimal and non-intrusive approach.
Aleksey Kladov
@matklad
Sep 25 2017 07:37
Hm, IIRC, it does not use unittest.TestCase at all
Michal 'vorner' Vaner
@vorner
Sep 25 2017 07:37
like:
struct TestFixture {
  test_data: usize,
}

impl Default for TextFixture {
  fn default() -> Self {
    Self { test_data: 42 }
  }
}

// impl Drop needed here...

impl TextFixture {
  #[test]
  fn test(&self) {
    assert_eq!(self.test_data, 42);
  }
}
Aleksey Kladov
@matklad
Sep 25 2017 07:37
Basically, a py.test fixture is a context manager/class with default and Drop
But the way you use it, is that you just pass a parameter with appropriate type to your test function, like this
struct TempDirFixture { ... }

#[test]
fn test_foo(tmpdir: TempDirFixture) {

}
This allows one to compose sevaral fixtures seamlessly, because it's easy to pass several parameters to a test function
As opposed to using setUp/tearDown style class hooks of JUnit, which couple your fixtures to single inheritance model.
Michal 'vorner' Vaner
@vorner
Sep 25 2017 07:40
Yes, that sounds interesting too. I liked the fact that I could also group the related tests together, but I guess using modules for that is enough.
Aleksey Kladov
@matklad
Sep 25 2017 07:46

@vorner I think you can even implement "fixtures as parameters" without too much magic.... Like, I can imaging something along the lines of impl<F1, F2> Test for FnOnce(F1, F2) where F1: TestFixture, F2: TestFixture.

The awkward thing about this approach though is that sometimes you need to parametrize your fixtures... That is, Default does not work, and it's not obvious how to pass arguments nicely.

Fra ns
@snarf95_twitter
Sep 25 2017 09:02
Hello rust :) another noob question regarding the joy of closures
I'm looking for a way to accomplish this
basically copying over a closure
Fra ns
@snarf95_twitter
Sep 25 2017 09:09
I really don't understand why the closures aren't compatible
Denis Lisov
@tanriol
Sep 25 2017 09:10
Different closures are never compatible, but you can try casting them to a function pointer.
Fra ns
@snarf95_twitter
Sep 25 2017 09:11
casting to a function pointer?
Jonas Platte
@jplatte
Sep 25 2017 09:18
Yup, your closures can actually be cast to fn(isize, isize) -> isize here instead of boxing them as Fn(isize, isize) -> isize trait objects
(because they don't capture anything from their environment)
Although after playing around a bit with your code, I also managed to tell the compiler to treat them as boxed trait objects here.
Jonas Platte
@jplatte
Sep 25 2017 09:20
Currently though, the four operator_* functions all have different types (box of that first closure, box of that second closure, ..)
Fra ns
@snarf95_twitter
Sep 25 2017 09:32
thanks a lot guys :)
David Harvey-Macaulay
@alteous
Sep 25 2017 11:35
Is there a way of documenting a re-exported enum that doesn't have any documentation of its own?
Michal 'vorner' Vaner
@vorner
Sep 25 2017 11:36
By a pull request? :innocent:
David Harvey-Macaulay
@alteous
Sep 25 2017 11:36
I'd like to re-export glutin::VirtualKeyCode without having a blank space in the docs.
@vorner Fair enough. :smile:
Maxwell Leisner
@CoffeeFrame
Sep 25 2017 12:02
Happy monday folks
Daan Rijks
@ijks
Sep 25 2017 14:30
@vorner You might want to look at this: https://github.com/reem/stainless. Part of the macro allows you to insert code for every test in a group of tests. So you could just create the fixture there.
Downside is that nightly is required though.
Michal 'vorner' Vaner
@vorner
Sep 25 2017 14:32
@ijks Thanks, I'll have a look soon. And I don't expect that any proposal that I'd make would not require nightly at first. Or is it expected the plugin interface stays unstable forever?
Aleksey Kladov
@matklad
Sep 25 2017 14:35
@vorner rust-lang/rfcs#816 might be relevant as well
Daan Rijks
@ijks
Sep 25 2017 15:03
@vorner The plugin interface, yes, I think. But procedural macros will be stabilized eventually IIRC. Custom derive is already stable, but that's not really useful in this case.