Shorten line length
This commit is contained in:
parent
c13c5a019f
commit
61adf4cb4b
|
|
@ -1,6 +1,6 @@
|
||||||
### The `#[test]` attribute
|
### The `#[test]` attribute
|
||||||
Today, rust programmers rely on a built in attribute called `#[test]`.
|
Today, rust programmers rely on a built in attribute called `#[test]`. All
|
||||||
All you have to do is mark a function as a test and include some asserts like so:
|
you have to do is mark a function as a test and include some asserts like so:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -36,10 +36,11 @@ rewrites the crate in 3 steps:
|
||||||
|
|
||||||
#### Step 1: Re-Exporting
|
#### Step 1: Re-Exporting
|
||||||
|
|
||||||
As mentioned earlier, tests can exist inside private modules, so we need a way of
|
As mentioned earlier, tests can exist inside private modules, so we need a
|
||||||
exposing them to the main function, without breaking any existing code. To that end,
|
way of exposing them to the main function, without breaking any existing
|
||||||
`libsyntax` will create local modules called `__test_reexports` that recursively reexport tests.
|
code. To that end, `libsyntax` will create local modules called
|
||||||
This expansion translates the above example into:
|
`__test_reexports` that recursively reexport tests. This expansion translates
|
||||||
|
the above example into:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
mod my_priv_mod {
|
mod my_priv_mod {
|
||||||
|
|
@ -76,8 +77,8 @@ collision during code generation and is the foundation of Rust's macro
|
||||||
hygiene.
|
hygiene.
|
||||||
|
|
||||||
#### Step 2: Harness Generation
|
#### Step 2: Harness Generation
|
||||||
Now that our tests are accessible from the root of our crate, we need to do something with them.
|
Now that our tests are accessible from the root of our crate, we need to do
|
||||||
`libsyntax` generates a module like so:
|
something with them. `libsyntax` generates a module like so:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
pub mod __test {
|
pub mod __test {
|
||||||
|
|
@ -91,15 +92,19 @@ pub mod __test {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
While this transformation is simple, it gives us a lot of insight into how tests are actually run.
|
While this transformation is simple, it gives us a lot of insight into how
|
||||||
The tests are aggregated into an array and passed to a test runner called `test_static_main`.
|
tests are actually run. The tests are aggregated into an array and passed to
|
||||||
We'll come back to exactly what `TestDescAndFn` is, but for now, the key takeaway is that there is a crate
|
a test runner called `test_static_main`. We'll come back to exactly what
|
||||||
called [`test`][test] that is part of Rust core, that implements all of the runtime for testing. `test`'s interface is unstable,
|
`TestDescAndFn` is, but for now, the key takeaway is that there is a crate
|
||||||
so the only stable way to interact with it is through the `#[test]` macro.
|
called [`test`][test] that is part of Rust core, that implements all of the
|
||||||
|
runtime for testing. `test`'s interface is unstable, so the only stable way
|
||||||
|
to interact with it is through the `#[test]` macro.
|
||||||
|
|
||||||
#### Step 3: Test Object Generation
|
#### Step 3: Test Object Generation
|
||||||
If you've written tests in Rust before, you may be familiar with some of the optional attributes available on test functions.
|
If you've written tests in Rust before, you may be familiar with some of the
|
||||||
For example, a test can be annotated with `#[should_panic]` if we expect the test to cause a panic. It looks something like this:
|
optional attributes available on test functions. For example, a test can be
|
||||||
|
annotated with `#[should_panic]` if we expect the test to cause a panic. It
|
||||||
|
looks something like this:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -109,10 +114,13 @@ fn foo() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This means our tests are more than just simple functions, they have configuration information as well. `test` encodes this configuration
|
This means our tests are more than just simple functions, they have
|
||||||
data into a struct called [`TestDesc`][TestDesc]. For each test function in a crate, `libsyntax` will parse its attributes and generate a `TestDesc` instance.
|
configuration information as well. `test` encodes this configuration data
|
||||||
It then combines the `TestDesc` and test function into the predictably named `TestDescAndFn` struct, that `test_static_main` operates on.
|
into a struct called [`TestDesc`][TestDesc]. For each test function in a
|
||||||
For a given test, the generated `TestDescAndFn` instance looks like so:
|
crate, `libsyntax` will parse its attributes and generate a `TestDesc`
|
||||||
|
instance. It then combines the `TestDesc` and test function into the
|
||||||
|
predictably named `TestDescAndFn` struct, that `test_static_main` operates
|
||||||
|
on. For a given test, the generated `TestDescAndFn` instance looks like so:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
self::test::TestDescAndFn{
|
self::test::TestDescAndFn{
|
||||||
|
|
@ -131,7 +139,8 @@ Once we've constructed an array of these test objects, they're passed to the
|
||||||
test runner via the harness generated in step 2.
|
test runner via the harness generated in step 2.
|
||||||
|
|
||||||
### Inspecting the generated code
|
### Inspecting the generated code
|
||||||
On nightly rust, there's an unstable flag called `unpretty` that you can use to print out the module source after macro expansion:
|
On nightly rust, there's an unstable flag called `unpretty` that you can use
|
||||||
|
to print out the module source after macro expansion:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rustc my_mod.rs -Z unpretty=hir
|
$ rustc my_mod.rs -Z unpretty=hir
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue