Auto merge of #50466 - kennytm:rustbuild-stage0-lib-test, r=Mark-Simulacrum
rustbuild: Allow quick testing of libstd and libcore at stage0 This PR implemented two features: 1. Added a `--no-doc` flag to allow testing a crate *without* doc tests. In this mode, we don't need to build rustdoc, and thus we can skip building the stage2 compiler. (Ideally stage0 test should use the bootstrap rustdoc, but I don't want to mess up the core builder logic here) 2. Moved all libcore tests externally and added a tidy test to ensure we don't accidentally add `#[test]` into libcore. After this PR, one could run `./x.py test --stage 0 --no-doc src/libstd` to test `libstd` without building the compiler, thus enables us to quickly test new library features.
This commit is contained in:
@@ -64,6 +64,10 @@ The script accepts commands, flags, and arguments to determine what to do:
|
||||
# execute tests in the standard library in stage0
|
||||
./x.py test --stage 0 src/libstd
|
||||
|
||||
# execute tests in the core and standard library in stage0,
|
||||
# without running doc tests (thus avoid depending on building the compiler)
|
||||
./x.py test --stage 0 --no-doc src/libcore src/libstd
|
||||
|
||||
# execute all doc tests
|
||||
./x.py test src/doc
|
||||
```
|
||||
|
||||
@@ -25,7 +25,7 @@ use compile;
|
||||
use install;
|
||||
use dist;
|
||||
use util::{exe, libdir, add_lib_path};
|
||||
use {Build, Mode};
|
||||
use {Build, Mode, DocTests};
|
||||
use cache::{INTERNER, Interned, Cache};
|
||||
use check;
|
||||
use test;
|
||||
@@ -591,6 +591,8 @@ impl<'a> Builder<'a> {
|
||||
format!("{} {}", env::var("RUSTFLAGS").unwrap_or_default(), extra_args));
|
||||
}
|
||||
|
||||
let want_rustdoc = self.doc_tests != DocTests::No;
|
||||
|
||||
// Customize the compiler we're running. Specify the compiler to cargo
|
||||
// as our shim and then pass it some various options used to configure
|
||||
// how the actual compiler itself is called.
|
||||
@@ -607,7 +609,7 @@ impl<'a> Builder<'a> {
|
||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
||||
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
||||
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
||||
.env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" {
|
||||
.env("RUSTDOC_REAL", if cmd == "doc" || (cmd == "test" && want_rustdoc) {
|
||||
self.rustdoc(compiler.host)
|
||||
} else {
|
||||
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
||||
@@ -624,7 +626,7 @@ impl<'a> Builder<'a> {
|
||||
if let Some(ref error_format) = self.config.rustc_error_format {
|
||||
cargo.env("RUSTC_ERROR_FORMAT", error_format);
|
||||
}
|
||||
if cmd != "build" && cmd != "check" {
|
||||
if cmd != "build" && cmd != "check" && want_rustdoc {
|
||||
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.config.build)));
|
||||
}
|
||||
|
||||
@@ -1407,4 +1409,39 @@ mod __test {
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_no_doc_stage0() {
|
||||
let mut config = configure(&[], &[]);
|
||||
config.stage = Some(0);
|
||||
config.cmd = Subcommand::Test {
|
||||
paths: vec!["src/libstd".into()],
|
||||
test_args: vec![],
|
||||
rustc_args: vec![],
|
||||
fail_fast: true,
|
||||
doc_tests: DocTests::No,
|
||||
};
|
||||
|
||||
let build = Build::new(config);
|
||||
let mut builder = Builder::new(&build);
|
||||
|
||||
let host = INTERNER.intern_str("A");
|
||||
|
||||
builder.run_step_descriptions(
|
||||
&[StepDescription::from::<test::Crate>()],
|
||||
&["src/libstd".into()],
|
||||
);
|
||||
|
||||
// Ensure we don't build any compiler artifacts.
|
||||
assert!(builder.cache.all::<compile::Rustc>().is_empty());
|
||||
assert_eq!(first(builder.cache.all::<test::Crate>()), &[
|
||||
test::Crate {
|
||||
compiler: Compiler { host, stage: 0 },
|
||||
target: host,
|
||||
mode: Mode::Libstd,
|
||||
test_kind: test::TestKind::Test,
|
||||
krate: INTERNER.intern_str("std"),
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use std::process;
|
||||
|
||||
use getopts::Options;
|
||||
|
||||
use Build;
|
||||
use {Build, DocTests};
|
||||
use config::Config;
|
||||
use metadata;
|
||||
use builder::Builder;
|
||||
@@ -62,7 +62,7 @@ pub enum Subcommand {
|
||||
test_args: Vec<String>,
|
||||
rustc_args: Vec<String>,
|
||||
fail_fast: bool,
|
||||
doc_tests: bool,
|
||||
doc_tests: DocTests,
|
||||
},
|
||||
Bench {
|
||||
paths: Vec<PathBuf>,
|
||||
@@ -171,7 +171,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
||||
"extra options to pass the compiler when running tests",
|
||||
"ARGS",
|
||||
);
|
||||
opts.optflag("", "doc", "run doc tests");
|
||||
opts.optflag("", "no-doc", "do not run doc tests");
|
||||
opts.optflag("", "doc", "only run doc tests");
|
||||
},
|
||||
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
||||
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
||||
@@ -324,7 +325,13 @@ Arguments:
|
||||
test_args: matches.opt_strs("test-args"),
|
||||
rustc_args: matches.opt_strs("rustc-args"),
|
||||
fail_fast: !matches.opt_present("no-fail-fast"),
|
||||
doc_tests: matches.opt_present("doc"),
|
||||
doc_tests: if matches.opt_present("doc") {
|
||||
DocTests::Only
|
||||
} else if matches.opt_present("no-doc") {
|
||||
DocTests::No
|
||||
} else {
|
||||
DocTests::Yes
|
||||
}
|
||||
}
|
||||
}
|
||||
"bench" => {
|
||||
@@ -411,10 +418,10 @@ impl Subcommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn doc_tests(&self) -> bool {
|
||||
pub fn doc_tests(&self) -> DocTests {
|
||||
match *self {
|
||||
Subcommand::Test { doc_tests, .. } => doc_tests,
|
||||
_ => false,
|
||||
_ => DocTests::Yes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,16 @@ pub struct Compiler {
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub enum DocTests {
|
||||
// Default, run normal tests and doc tests.
|
||||
Yes,
|
||||
// Do not run any doc tests.
|
||||
No,
|
||||
// Only run doc tests.
|
||||
Only,
|
||||
}
|
||||
|
||||
/// Global configuration for the build system.
|
||||
///
|
||||
/// This structure transitively contains all configuration for the build system.
|
||||
@@ -233,7 +243,7 @@ pub struct Build {
|
||||
rustfmt_info: channel::GitInfo,
|
||||
local_rebuild: bool,
|
||||
fail_fast: bool,
|
||||
doc_tests: bool,
|
||||
doc_tests: DocTests,
|
||||
verbosity: usize,
|
||||
|
||||
// Targets for which to build.
|
||||
@@ -294,7 +304,7 @@ impl Crate {
|
||||
///
|
||||
/// These entries currently correspond to the various output directories of the
|
||||
/// build system, with each mod generating output in a different directory.
|
||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Mode {
|
||||
/// Build the standard library, placing output in the "stageN-std" directory.
|
||||
Libstd,
|
||||
|
||||
@@ -32,13 +32,13 @@ use dist;
|
||||
use native;
|
||||
use tool::{self, Tool};
|
||||
use util::{self, dylib_path, dylib_path_var};
|
||||
use Mode;
|
||||
use {Mode, DocTests};
|
||||
use toolstate::ToolState;
|
||||
|
||||
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
||||
|
||||
/// The two modes of the test runner; tests or benchmarks.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord)]
|
||||
pub enum TestKind {
|
||||
/// Run `cargo test`
|
||||
Test,
|
||||
@@ -1407,13 +1407,13 @@ impl Step for CrateNotDefault {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Crate {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: Mode,
|
||||
test_kind: TestKind,
|
||||
krate: Interned<String>,
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
pub mode: Mode,
|
||||
pub test_kind: TestKind,
|
||||
pub krate: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Crate {
|
||||
@@ -1519,9 +1519,15 @@ impl Step for Crate {
|
||||
if test_kind.subcommand() == "test" && !builder.fail_fast {
|
||||
cargo.arg("--no-fail-fast");
|
||||
}
|
||||
if builder.doc_tests {
|
||||
match builder.doc_tests {
|
||||
DocTests::Only => {
|
||||
cargo.arg("--doc");
|
||||
}
|
||||
DocTests::No => {
|
||||
cargo.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
|
||||
}
|
||||
DocTests::Yes => {}
|
||||
}
|
||||
|
||||
cargo.arg("-p").arg(krate);
|
||||
|
||||
|
||||
@@ -50,6 +50,15 @@
|
||||
|
||||
// Since libcore defines many fundamental lang items, all tests live in a
|
||||
// separate crate, libcoretest, to avoid bizarre issues.
|
||||
//
|
||||
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
|
||||
// this, both the generated test artifact and the linked libtest (which
|
||||
// transitively includes libcore) will both define the same set of lang items,
|
||||
// and this will cause the E0152 "duplicate lang item found" error. See
|
||||
// discussion in #50466 for details.
|
||||
//
|
||||
// This cfg won't affect doc tests.
|
||||
#![cfg(not(test))]
|
||||
|
||||
#![stable(feature = "core", since = "1.6.0")]
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
|
||||
@@ -135,85 +135,3 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
|
||||
// find the byte before the point the body loop stopped
|
||||
text[..offset].iter().rposition(|elt| *elt == x)
|
||||
}
|
||||
|
||||
// test fallback implementations on all platforms
|
||||
#[test]
|
||||
fn matches_one() {
|
||||
assert_eq!(Some(0), memchr(b'a', b"a"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_begin() {
|
||||
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_end() {
|
||||
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_nul() {
|
||||
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_past_nul() {
|
||||
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_empty() {
|
||||
assert_eq!(None, memchr(b'a', b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match() {
|
||||
assert_eq!(None, memchr(b'a', b"xyz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_one_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'a', b"a"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_begin_reversed() {
|
||||
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_end_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_nul_reversed() {
|
||||
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_past_nul_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_empty_reversed() {
|
||||
assert_eq!(None, memrchr(b'a', b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_reversed() {
|
||||
assert_eq!(None, memrchr(b'a', b"xyz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_alignment_reversed() {
|
||||
let mut data = [1u8; 64];
|
||||
let needle = 2;
|
||||
let pos = 40;
|
||||
data[pos] = needle;
|
||||
for start in 0..16 {
|
||||
assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#![feature(reverse_bits)]
|
||||
#![feature(inclusive_range_methods)]
|
||||
#![feature(iterator_find_map)]
|
||||
#![feature(slice_internals)]
|
||||
|
||||
extern crate core;
|
||||
extern crate test;
|
||||
@@ -74,4 +75,5 @@ mod result;
|
||||
mod slice;
|
||||
mod str;
|
||||
mod str_lossy;
|
||||
mod time;
|
||||
mod tuple;
|
||||
|
||||
@@ -98,6 +98,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(stage0))]
|
||||
fn test_reverse_bits() {
|
||||
assert_eq!(A.reverse_bits().reverse_bits(), A);
|
||||
assert_eq!(B.reverse_bits().reverse_bits(), B);
|
||||
|
||||
@@ -550,3 +550,89 @@ fn sort_unstable() {
|
||||
v.sort_unstable();
|
||||
assert!(v == [0xDEADBEEF]);
|
||||
}
|
||||
|
||||
pub mod memchr {
|
||||
use core::slice::memchr::{memchr, memrchr};
|
||||
|
||||
// test fallback implementations on all platforms
|
||||
#[test]
|
||||
fn matches_one() {
|
||||
assert_eq!(Some(0), memchr(b'a', b"a"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_begin() {
|
||||
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_end() {
|
||||
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_nul() {
|
||||
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_past_nul() {
|
||||
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_empty() {
|
||||
assert_eq!(None, memchr(b'a', b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match() {
|
||||
assert_eq!(None, memchr(b'a', b"xyz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_one_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'a', b"a"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_begin_reversed() {
|
||||
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_end_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_nul_reversed() {
|
||||
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_past_nul_reversed() {
|
||||
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_empty_reversed() {
|
||||
assert_eq!(None, memrchr(b'a', b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_reversed() {
|
||||
assert_eq!(None, memrchr(b'a', b"xyz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_alignment_reversed() {
|
||||
let mut data = [1u8; 64];
|
||||
let needle = 2;
|
||||
let pos = 40;
|
||||
data[pos] = needle;
|
||||
for start in 0..16 {
|
||||
assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
124
src/libcore/tests/time.rs
Normal file
124
src/libcore/tests/time.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn creation() {
|
||||
assert!(Duration::from_secs(1) != Duration::from_secs(0));
|
||||
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
|
||||
Duration::from_secs(3));
|
||||
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
|
||||
Duration::new(4, 10 * 1_000_000));
|
||||
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn secs() {
|
||||
assert_eq!(Duration::new(0, 0).as_secs(), 0);
|
||||
assert_eq!(Duration::from_secs(1).as_secs(), 1);
|
||||
assert_eq!(Duration::from_millis(999).as_secs(), 0);
|
||||
assert_eq!(Duration::from_millis(1001).as_secs(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nanos() {
|
||||
assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
|
||||
assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
|
||||
assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
|
||||
assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
|
||||
assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
|
||||
assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
|
||||
Duration::new(1, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_add() {
|
||||
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
|
||||
Some(Duration::new(0, 1)));
|
||||
assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
|
||||
Some(Duration::new(1, 1)));
|
||||
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::core::u64::MAX, 0)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub() {
|
||||
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
|
||||
Duration::new(0, 999_999_999));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_sub() {
|
||||
let zero = Duration::new(0, 0);
|
||||
let one_nano = Duration::new(0, 1);
|
||||
let one_sec = Duration::new(1, 0);
|
||||
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
|
||||
assert_eq!(one_sec.checked_sub(one_nano),
|
||||
Some(Duration::new(0, 999_999_999)));
|
||||
assert_eq!(zero.checked_sub(one_nano), None);
|
||||
assert_eq!(zero.checked_sub(one_sec), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn sub_bad1() {
|
||||
let _ = Duration::new(0, 0) - Duration::new(0, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn sub_bad2() {
|
||||
let _ = Duration::new(0, 0) - Duration::new(1, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul() {
|
||||
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
|
||||
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
|
||||
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
|
||||
assert_eq!(Duration::new(0, 500_000_001) * 4000,
|
||||
Duration::new(2000, 4000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_mul() {
|
||||
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
|
||||
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
|
||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
|
||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
|
||||
Some(Duration::new(2000, 4000)));
|
||||
assert_eq!(Duration::new(::core::u64::MAX - 1, 0).checked_mul(2), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div() {
|
||||
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
|
||||
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
|
||||
assert_eq!(Duration::new(99, 999_999_000) / 100,
|
||||
Duration::new(0, 999_999_990));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_div() {
|
||||
assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
|
||||
assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
|
||||
assert_eq!(Duration::new(2, 0).checked_div(0), None);
|
||||
}
|
||||
@@ -481,119 +481,3 @@ impl<'a> Sum<&'a Duration> for Duration {
|
||||
iter.fold(Duration::new(0, 0), |a, b| a + *b)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Duration;
|
||||
|
||||
#[test]
|
||||
fn creation() {
|
||||
assert!(Duration::from_secs(1) != Duration::from_secs(0));
|
||||
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
|
||||
Duration::from_secs(3));
|
||||
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
|
||||
Duration::new(4, 10 * 1_000_000));
|
||||
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn secs() {
|
||||
assert_eq!(Duration::new(0, 0).as_secs(), 0);
|
||||
assert_eq!(Duration::from_secs(1).as_secs(), 1);
|
||||
assert_eq!(Duration::from_millis(999).as_secs(), 0);
|
||||
assert_eq!(Duration::from_millis(1001).as_secs(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nanos() {
|
||||
assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
|
||||
assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
|
||||
assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
|
||||
assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
|
||||
assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
|
||||
assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
|
||||
Duration::new(1, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_add() {
|
||||
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
|
||||
Some(Duration::new(0, 1)));
|
||||
assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
|
||||
Some(Duration::new(1, 1)));
|
||||
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::u64::MAX, 0)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub() {
|
||||
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
|
||||
Duration::new(0, 1));
|
||||
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
|
||||
Duration::new(0, 999_999_999));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_sub() {
|
||||
let zero = Duration::new(0, 0);
|
||||
let one_nano = Duration::new(0, 1);
|
||||
let one_sec = Duration::new(1, 0);
|
||||
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
|
||||
assert_eq!(one_sec.checked_sub(one_nano),
|
||||
Some(Duration::new(0, 999_999_999)));
|
||||
assert_eq!(zero.checked_sub(one_nano), None);
|
||||
assert_eq!(zero.checked_sub(one_sec), None);
|
||||
}
|
||||
|
||||
#[test] #[should_panic]
|
||||
fn sub_bad1() {
|
||||
Duration::new(0, 0) - Duration::new(0, 1);
|
||||
}
|
||||
|
||||
#[test] #[should_panic]
|
||||
fn sub_bad2() {
|
||||
Duration::new(0, 0) - Duration::new(1, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul() {
|
||||
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
|
||||
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
|
||||
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
|
||||
assert_eq!(Duration::new(0, 500_000_001) * 4000,
|
||||
Duration::new(2000, 4000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_mul() {
|
||||
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
|
||||
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
|
||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
|
||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
|
||||
Some(Duration::new(2000, 4000)));
|
||||
assert_eq!(Duration::new(::u64::MAX - 1, 0).checked_mul(2), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div() {
|
||||
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
|
||||
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
|
||||
assert_eq!(Duration::new(99, 999_999_000) / 100,
|
||||
Duration::new(0, 999_999_990));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checked_div() {
|
||||
assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
|
||||
assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
|
||||
assert_eq!(Duration::new(2, 0).checked_div(0), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,10 +330,10 @@
|
||||
// with a rustc without jemalloc.
|
||||
// FIXME(#44236) shouldn't need MSVC logic
|
||||
#![cfg_attr(all(not(target_env = "msvc"),
|
||||
any(stage0, feature = "force_alloc_system")),
|
||||
any(all(stage0, not(test)), feature = "force_alloc_system")),
|
||||
feature(global_allocator))]
|
||||
#[cfg(all(not(target_env = "msvc"),
|
||||
any(stage0, feature = "force_alloc_system")))]
|
||||
any(all(stage0, not(test)), feature = "force_alloc_system")))]
|
||||
#[global_allocator]
|
||||
static ALLOC: alloc_system::System = alloc_system::System;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ pub mod pal;
|
||||
pub mod deps;
|
||||
pub mod ui_tests;
|
||||
pub mod unstable_book;
|
||||
pub mod libcoretest;
|
||||
|
||||
fn filter_dirs(path: &Path) -> bool {
|
||||
let skip = [
|
||||
|
||||
34
src/tools/tidy/src/libcoretest.rs
Normal file
34
src/tools/tidy/src/libcoretest.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Tidy check to ensure `#[test]` is not used directly inside `libcore`.
|
||||
//!
|
||||
//! `#![no_core]` libraries cannot be tested directly due to duplicating lang
|
||||
//! item. All tests must be written externally in `libcore/tests`.
|
||||
|
||||
use std::path::Path;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
let libcore_path = path.join("libcore");
|
||||
super::walk(
|
||||
&libcore_path,
|
||||
&mut |subpath| t!(subpath.strip_prefix(&libcore_path)).starts_with("tests"),
|
||||
&mut |subpath| {
|
||||
if t!(read_to_string(subpath)).contains("#[test]") {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"{} contains #[test]; libcore tests must be placed inside `src/libcore/tests/`",
|
||||
subpath.display()
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -41,6 +41,7 @@ fn main() {
|
||||
features::check(&path, &mut bad, quiet);
|
||||
pal::check(&path, &mut bad);
|
||||
unstable_book::check(&path, &mut bad);
|
||||
libcoretest::check(&path, &mut bad);
|
||||
if !args.iter().any(|s| *s == "--no-vendor") {
|
||||
deps::check(&path, &mut bad);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user