Skip to content

Commit 0c62d9d

Browse files
committed
auto merge of #12298 : alexcrichton/rust/rustdoc-testing, r=sfackler
It's too easy to forget the `rust` tag to test something. Closes #11698
2 parents d98668a + e72ddbd commit 0c62d9d

File tree

21 files changed

+133
-102
lines changed

21 files changed

+133
-102
lines changed

src/doc/rustdoc.md

+12-20
Original file line numberDiff line numberDiff line change
@@ -100,34 +100,29 @@ rustdoc --test crate.rs
100100

101101
## Defining tests
102102

103-
Rust documentation currently uses the markdown format, and code blocks can refer
104-
to any piece of code-related documentation, which isn't always rust. Because of
105-
this, only code blocks with the language of "rust" will be considered for
106-
testing.
103+
Rust documentation currently uses the markdown format, and rustdoc treats all
104+
code blocks as testable-by-default. In order to not run a test over a block of
105+
code, the `ignore` string can be added to the three-backtick form of markdown
106+
code block.
107107

108108
~~~
109-
```rust
109+
```
110110
// This is a testable code block
111111
```
112112
113-
```
113+
```ignore
114114
// This is not a testable code block
115115
```
116116
117-
// This is not a testable code block (4-space indent)
117+
// This is a testable code block (4-space indent)
118118
~~~
119119

120-
In addition to only testing "rust"-language code blocks, there are additional
121-
specifiers that can be used to dictate how a code block is tested:
120+
In addition to the `ignore` directive, you can specify that the test's execution
121+
should fail with the `should_fail` directive.
122122

123123
~~~
124-
```rust,ignore
125-
// This code block is ignored by rustdoc, but is passed through to the test
126-
// harness
127-
```
128-
129-
```rust,should_fail
130-
// This code block is expected to generate a failure
124+
```should_fail
125+
// This code block is expected to generate a failure when run
131126
```
132127
~~~
133128

@@ -143,7 +138,7 @@ that one can still write things like `#[deriving(Eq)]`).
143138
# the doc-generating tool. In order to display them anyway in this particular
144139
# case, the character following the leading '#' is not a usual space like in
145140
# these first five lines but a non breakable one.
146-
#
141+
#
147142
# // showing 'fib' in this documentation would just be tedious and detracts from
148143
# // what's actualy being documented.
149144
# fn fib(n: int) { n + 2 }
@@ -169,9 +164,6 @@ rustdoc --test lib.rs --test-args 'foo'
169164
170165
// See what's possible when running tests
171166
rustdoc --test lib.rs --test-args '--help'
172-
173-
// Run all ignored tests
174-
rustdoc --test lib.rs --test-args '--ignored'
175167
~~~
176168

177169
When testing a library, code examples will often show how functions are used,

src/libextra/json.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ An object is a series of string keys mapping to values, in `"key": value` format
3030
Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).
3131
A simple JSON document encoding a person, his/her age, address and phone numbers could look like:
3232
33-
```
33+
```ignore
3434
{
3535
"FirstName": "John",
3636
"LastName": "Doe",

src/libextra/stats.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ pub fn write_5_number_summary(w: &mut io::Writer,
341341
/// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might
342342
/// display as:
343343
///
344-
/// ~~~~
344+
/// ~~~~ignore
345345
/// 10 | [--****#******----------] | 40
346346
/// ~~~~
347347

src/libglob/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub struct Paths {
6767
///
6868
/// The above code will print:
6969
///
70-
/// ```
70+
/// ```ignore
7171
/// /media/pictures/kittens.jpg
7272
/// /media/pictures/puppies.jpg
7373
/// ```

src/librustdoc/html/markdown.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -172,21 +172,23 @@ pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result {
172172
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
173173
extern fn block(_ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
174174
unsafe {
175-
if text.is_null() || lang.is_null() { return }
176-
let (test, shouldfail, ignore) =
175+
if text.is_null() { return }
176+
let (shouldfail, ignore) = if lang.is_null() {
177+
(false, false)
178+
} else {
177179
vec::raw::buf_as_slice((*lang).data,
178180
(*lang).size as uint, |lang| {
179181
let s = str::from_utf8(lang).unwrap();
180-
(s.contains("rust"), s.contains("should_fail"),
181-
s.contains("ignore"))
182-
});
183-
if !test { return }
182+
(s.contains("should_fail"), s.contains("ignore"))
183+
})
184+
};
185+
if ignore { return }
184186
vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
185187
let tests: &mut ::test::Collector = intrinsics::transmute(opaque);
186188
let text = str::from_utf8(text).unwrap();
187189
let mut lines = text.lines().map(|l| stripped_filtered_line(l).unwrap_or(l));
188190
let text = lines.to_owned_vec().connect("\n");
189-
tests.add_test(text, ignore, shouldfail);
191+
tests.add_test(text, shouldfail);
190192
})
191193
}
192194
}

src/librustdoc/test.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
9494
0
9595
}
9696

97-
fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
97+
fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool) {
9898
let test = maketest(test, cratename);
9999
let parsesess = parse::new_parse_sess();
100100
let input = driver::StrInput(test);
@@ -130,9 +130,10 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
130130
match out {
131131
Err(e) => fail!("couldn't run the test: {}", e),
132132
Ok(out) => {
133-
if !out.status.success() {
134-
fail!("test executable failed:\n{}",
135-
str::from_utf8(out.error));
133+
if should_fail && out.status.success() {
134+
fail!("test executable succeeded when it should have failed");
135+
} else if !should_fail && !out.status.success() {
136+
fail!("test executable failed:\n{}", str::from_utf8(out.error));
136137
}
137138
}
138139
}
@@ -169,7 +170,7 @@ pub struct Collector {
169170
}
170171

171172
impl Collector {
172-
pub fn add_test(&mut self, test: &str, ignore: bool, should_fail: bool) {
173+
pub fn add_test(&mut self, test: &str, should_fail: bool) {
173174
let test = test.to_owned();
174175
let name = format!("{}_{}", self.names.connect("::"), self.cnt);
175176
self.cnt += 1;
@@ -180,11 +181,11 @@ impl Collector {
180181
self.tests.push(test::TestDescAndFn {
181182
desc: test::TestDesc {
182183
name: test::DynTestName(name),
183-
ignore: ignore,
184-
should_fail: should_fail,
184+
ignore: false,
185+
should_fail: false, // compiler failures are test failures
185186
},
186187
testfn: test::DynTestFn(proc() {
187-
runtest(test, cratename, libs);
188+
runtest(test, cratename, libs, should_fail);
188189
}),
189190
});
190191
}

src/libstd/comm/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
//! let (port, chan) = Chan::new();
6262
//! spawn(proc() {
6363
//! chan.send(10);
64-
//! })
64+
//! });
6565
//! assert_eq!(port.recv(), 10);
6666
//!
6767
//! // Create a shared channel which can be sent along from many tasks

src/libstd/fmt/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ function, but the `format!` macro is a syntax extension which allows it to
8282
leverage named parameters. Named parameters are listed at the end of the
8383
argument list and have the syntax:
8484
85-
```
85+
```ignore
8686
identifier '=' expression
8787
```
8888
@@ -107,7 +107,7 @@ and if all references to one argument do not provide a type, then the format `?`
107107
is used (the type's rust-representation is printed). For example, this is an
108108
invalid format string:
109109
110-
```
110+
```ignore
111111
{0:d} {0:s}
112112
```
113113
@@ -123,7 +123,7 @@ must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
123123
illegal to reference an argument as such. For example, this is another invalid
124124
format string:
125125
126-
```
126+
```ignore
127127
{:.*s} {0:u}
128128
```
129129
@@ -334,7 +334,7 @@ This example is the equivalent of `{0:s}` essentially.
334334
The select method is a switch over a `&str` parameter, and the parameter *must*
335335
be of the type `&str`. An example of the syntax is:
336336
337-
```
337+
```ignore
338338
{0, select, male{...} female{...} other{...}}
339339
```
340340
@@ -353,7 +353,7 @@ The plural method is a switch statement over a `uint` parameter, and the
353353
parameter *must* be a `uint`. A plural method in its full glory can be specified
354354
as:
355355
356-
```
356+
```ignore
357357
{0, plural, offset=1 =1{...} two{...} many{...} other{...}}
358358
```
359359
@@ -381,7 +381,7 @@ should not be too alien. Arguments are formatted with python-like syntax,
381381
meaning that arguments are surrounded by `{}` instead of the C-like `%`. The
382382
actual grammar for the formatting syntax is:
383383
384-
```
384+
```ignore
385385
format_string := <text> [ format <text> ] *
386386
format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}'
387387
argument := integer | identifier

src/libstd/io/comm_adapters.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@ use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
2222
/// # Example
2323
///
2424
/// ```
25-
/// let reader = PortReader::new(port);
25+
/// use std::io::PortReader;
26+
///
27+
/// let (port, chan) = Chan::new();
28+
/// # drop(chan);
29+
/// let mut reader = PortReader::new(port);
2630
///
2731
/// let mut buf = ~[0u8, ..100];
2832
/// match reader.read(buf) {
29-
/// Some(nread) => println!("Read {} bytes", nread),
30-
/// None => println!("At the end of the stream!")
33+
/// Ok(nread) => println!("Read {} bytes", nread),
34+
/// Err(e) => println!("read error: {}", e),
3135
/// }
3236
/// ```
3337
pub struct PortReader {
@@ -83,7 +87,12 @@ impl Reader for PortReader {
8387
/// # Example
8488
///
8589
/// ```
86-
/// let writer = ChanWriter::new(chan);
90+
/// # #[allow(unused_must_use)];
91+
/// use std::io::ChanWriter;
92+
///
93+
/// let (port, chan) = Chan::new();
94+
/// # drop(port);
95+
/// let mut writer = ChanWriter::new(chan);
8796
/// writer.write("hello, world".as_bytes());
8897
/// ```
8998
pub struct ChanWriter {

src/libstd/io/net/unix.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ impl UnixListener {
9191
/// # Example
9292
///
9393
/// ```
94+
/// # fn main() {}
95+
/// # fn foo() {
96+
/// # #[allow(unused_must_use)];
9497
/// use std::io::net::unix::UnixListener;
95-
/// use std::io::Listener;
98+
/// use std::io::{Listener, Acceptor};
9699
///
97-
/// let server = Path::new("path/to/my/socket");
98-
/// let mut stream = UnixListener::bind(&server);
99-
/// for client in stream.incoming() {
100-
/// let mut client = client;
100+
/// let server = Path::new("/path/to/my/socket");
101+
/// let stream = UnixListener::bind(&server);
102+
/// for mut client in stream.listen().incoming() {
101103
/// client.write([1, 2, 3, 4]);
102104
/// }
105+
/// # }
103106
/// ```
104107
pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> {
105108
LocalIo::maybe_raise(|io| {

src/libstd/kinds.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ pub mod marker {
6969
/// Given a struct `S` that includes a type parameter `T`
7070
/// but does not actually *reference* that type parameter:
7171
///
72-
/// ```
72+
/// ```ignore
73+
/// use std::cast;
74+
///
7375
/// struct S<T> { x: *() }
7476
/// fn get<T>(s: &S<T>) -> T {
7577
/// unsafe {
@@ -109,6 +111,8 @@ pub mod marker {
109111
/// but does not actually *reference* that type parameter:
110112
///
111113
/// ```
114+
/// use std::cast;
115+
///
112116
/// struct S<T> { x: *() }
113117
/// fn get<T>(s: &S<T>, v: T) {
114118
/// unsafe {
@@ -147,7 +151,8 @@ pub mod marker {
147151
/// "interior" mutability:
148152
///
149153
/// ```
150-
/// struct Cell<T> { priv value: T }
154+
/// pub struct Cell<T> { priv value: T }
155+
/// # fn main() {}
151156
/// ```
152157
///
153158
/// The type system would infer that `value` is only read here and

src/libstd/logging.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ disabled except for `error!` (a log level of 1). Logging is controlled via the
4242
`RUST_LOG` environment variable. The value of this environment variable is a
4343
comma-separated list of logging directives. A logging directive is of the form:
4444
45-
```
45+
```ignore
4646
path::to::module=log_level
4747
```
4848
@@ -65,7 +65,7 @@ all modules is set to this value.
6565
6666
Some examples of valid values of `RUST_LOG` are:
6767
68-
```
68+
```ignore
6969
hello // turns on all logging for the 'hello' module
7070
info // turns on all info logging
7171
hello=debug // turns on debug logging for 'hello'

0 commit comments

Comments
 (0)