mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 06:16:06 +00:00
Add tests for themes
This commit is contained in:
parent
63ee1cd846
commit
51580d46f9
@ -258,7 +258,7 @@ impl<'a> Builder<'a> {
|
||||
test::HostCompiletest, test::Crate, test::CrateLibrustc, test::Rustdoc,
|
||||
test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::Docs,
|
||||
test::ErrorIndex, test::Distcheck, test::Rustfmt, test::Miri, test::Clippy,
|
||||
test::RustdocJS),
|
||||
test::RustdocJS, test::RustdocTheme),
|
||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
||||
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
|
||||
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
|
||||
|
@ -160,4 +160,3 @@ pub fn libtest_stamp(build: &Build, compiler: Compiler, target: Interned<String>
|
||||
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
|
||||
}
|
||||
|
||||
|
@ -424,6 +424,48 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
|
||||
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RustdocTheme {
|
||||
pub compiler: Compiler,
|
||||
pub host: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for RustdocTheme {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/tools/rustdoc-themes")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
||||
|
||||
run.builder.ensure(RustdocTheme {
|
||||
compiler: compiler,
|
||||
host: run.builder.build.build,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
let rustdoc = builder.rustdoc(self.compiler.host);
|
||||
let mut cmd = Command::new(builder.config.python.clone().expect("python not defined"));
|
||||
cmd.args(&["src/tools/rustdoc-themes/test-themes.py", rustdoc.to_str().unwrap()]);
|
||||
cmd.env("RUSTC_STAGE", self.compiler.stage.to_string())
|
||||
.env("RUSTC_SYSROOT", builder.sysroot(self.compiler))
|
||||
.env("RUSTDOC_LIBDIR", builder.sysroot_libdir(self.compiler, self.compiler.host))
|
||||
.env("CFG_RELEASE_CHANNEL", &builder.build.config.channel)
|
||||
.env("RUSTDOC_REAL", builder.rustdoc(self.host))
|
||||
.env("RUSTDOC_CRATE_VERSION", builder.build.rust_version())
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
if let Some(linker) = builder.build.linker(self.host) {
|
||||
cmd.env("RUSTC_TARGET_LINKER", linker);
|
||||
}
|
||||
builder.run(&mut cmd);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RustdocJS {
|
||||
pub host: Interned<String>,
|
||||
|
@ -324,13 +324,13 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
|
||||
let to_check = matches.opt_strs("theme-checker");
|
||||
if !to_check.is_empty() {
|
||||
let pathes = theme::load_css_pathes(include_bytes!("html/static/themes/main.css"));
|
||||
let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css"));
|
||||
let mut errors = 0;
|
||||
|
||||
println!("rustdoc: [theme-checker] Starting tests!");
|
||||
for theme_file in to_check.iter() {
|
||||
print!(" - Checking \"{}\"...", theme_file);
|
||||
let (success, differences) = theme::test_theme_against(theme_file, &pathes);
|
||||
let (success, differences) = theme::test_theme_against(theme_file, &paths);
|
||||
if !differences.is_empty() || !success {
|
||||
eprintln!(" FAILED");
|
||||
errors += 1;
|
||||
@ -401,7 +401,7 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
|
||||
let mut themes = Vec::new();
|
||||
if matches.opt_present("themes") {
|
||||
let pathes = theme::load_css_pathes(include_bytes!("html/static/themes/main.css"));
|
||||
let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css"));
|
||||
|
||||
for (theme_file, theme_s) in matches.opt_strs("themes")
|
||||
.iter()
|
||||
@ -410,7 +410,7 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
eprintln!("rustdoc: option --themes arguments must all be files");
|
||||
return 1;
|
||||
}
|
||||
let (success, ret) = theme::test_theme_against(&theme_file, &pathes);
|
||||
let (success, ret) = theme::test_theme_against(&theme_file, &paths);
|
||||
if !success || !ret.is_empty() {
|
||||
eprintln!("rustdoc: invalid theme: \"{}\"", theme_s);
|
||||
eprintln!(" Check what's wrong with the \"theme-checker\" option");
|
||||
|
@ -170,18 +170,24 @@ fn get_useful_next(events: &[Events], pos: &mut usize) -> Option<Events> {
|
||||
fn get_previous_positions(events: &[Events], mut pos: usize) -> Vec<usize> {
|
||||
let mut ret = Vec::with_capacity(3);
|
||||
|
||||
ret.push(events[pos].get_pos() - 1);
|
||||
ret.push(events[pos].get_pos());
|
||||
if pos > 0 {
|
||||
pos -= 1;
|
||||
}
|
||||
loop {
|
||||
ret.push(events[pos].get_pos());
|
||||
if pos < 1 || !events[pos].is_comment() {
|
||||
let x = events[pos].get_pos();
|
||||
if *ret.last().unwrap() != x {
|
||||
ret.push(x);
|
||||
} else {
|
||||
ret.push(0);
|
||||
}
|
||||
break
|
||||
}
|
||||
ret.push(events[pos].get_pos());
|
||||
pos -= 1;
|
||||
}
|
||||
if events[pos].is_comment() {
|
||||
if ret.len() & 1 != 0 && events[pos].is_comment() {
|
||||
ret.push(0);
|
||||
}
|
||||
ret.iter().rev().cloned().collect()
|
||||
@ -189,14 +195,22 @@ fn get_previous_positions(events: &[Events], mut pos: usize) -> Vec<usize> {
|
||||
|
||||
fn build_rule(v: &[u8], positions: &[usize]) -> String {
|
||||
positions.chunks(2)
|
||||
.map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or("").to_owned())
|
||||
.map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or(""))
|
||||
.collect::<String>()
|
||||
.trim()
|
||||
.replace("\n", " ")
|
||||
.replace("/", "")
|
||||
.replace("\t", " ")
|
||||
.replace("{", "")
|
||||
.replace("}", "")
|
||||
.split(" ")
|
||||
.filter(|s| s.len() > 0)
|
||||
.collect::<Vec<&str>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> HashSet<CssPath> {
|
||||
let mut pathes = Vec::with_capacity(50);
|
||||
let mut paths = Vec::with_capacity(50);
|
||||
|
||||
while *pos < events.len() {
|
||||
if let Some(Events::OutBlock(_)) = get_useful_next(events, pos) {
|
||||
@ -204,11 +218,11 @@ fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> HashSet<CssPath> {
|
||||
break
|
||||
}
|
||||
if let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
|
||||
pathes.push(CssPath::new(build_rule(v, &get_previous_positions(events, *pos))));
|
||||
paths.push(CssPath::new(build_rule(v, &get_previous_positions(events, *pos))));
|
||||
*pos += 1;
|
||||
}
|
||||
while let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
|
||||
if let Some(ref mut path) = pathes.last_mut() {
|
||||
if let Some(ref mut path) = paths.last_mut() {
|
||||
for entry in inner(v, events, pos).iter() {
|
||||
path.children.insert(entry.clone());
|
||||
}
|
||||
@ -218,10 +232,10 @@ fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> HashSet<CssPath> {
|
||||
*pos += 1;
|
||||
}
|
||||
}
|
||||
pathes.iter().cloned().collect()
|
||||
paths.iter().cloned().collect()
|
||||
}
|
||||
|
||||
pub fn load_css_pathes(v: &[u8]) -> CssPath {
|
||||
pub fn load_css_paths(v: &[u8]) -> CssPath {
|
||||
let events = load_css_events(v);
|
||||
let mut pos = 0;
|
||||
|
||||
@ -264,9 +278,9 @@ pub fn test_theme_against<P: AsRef<Path>>(f: &P, against: &CssPath) -> (bool, Ve
|
||||
let mut data = Vec::with_capacity(1000);
|
||||
|
||||
try_something!(file.read_to_end(&mut data), (false, Vec::new()));
|
||||
let pathes = load_css_pathes(&data);
|
||||
let paths = load_css_paths(&data);
|
||||
let mut ret = Vec::new();
|
||||
get_differences(against, &pathes, &mut ret);
|
||||
get_differences(against, &paths, &mut ret);
|
||||
(true, ret)
|
||||
}
|
||||
|
||||
@ -317,8 +331,11 @@ rule gh i {}
|
||||
rule j end {}
|
||||
"#;
|
||||
|
||||
assert!(get_differences(&load_css_pathes(against.as_bytes()),
|
||||
&load_css_pathes(text.as_bytes())).is_empty());
|
||||
let mut ret = Vec::new();
|
||||
get_differences(&load_css_paths(against.as_bytes()),
|
||||
&load_css_paths(text.as_bytes()),
|
||||
&mut ret);
|
||||
assert!(ret.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -330,8 +347,8 @@ a
|
||||
c // sdf
|
||||
d {}
|
||||
"#;
|
||||
let pathes = load_css_pathes(text.as_bytes());
|
||||
assert!(pathes.children.get("a b c d").is_some());
|
||||
let paths = load_css_paths(text.as_bytes());
|
||||
assert!(paths.children.get(&CssPath::new("a b c d".to_owned())).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -350,10 +367,13 @@ a {
|
||||
}
|
||||
"#;
|
||||
|
||||
let against = load_css_pathes(y.as_bytes());
|
||||
let other = load_css_pathes(x.as_bytes());
|
||||
let against = load_css_paths(y.as_bytes());
|
||||
let other = load_css_paths(x.as_bytes());
|
||||
|
||||
assert!(get_differences(&against, &other).is_empty());
|
||||
assert_eq!(get_differences(&other, &against), vec![" Missing \"c\" rule".to_owned()])
|
||||
let mut ret = Vec::new();
|
||||
get_differences(&against, &other, &mut ret);
|
||||
assert!(ret.is_empty());
|
||||
get_differences(&other, &against, &mut ret);
|
||||
assert_eq!(ret, vec![" Missing \"c\" rule".to_owned()]);
|
||||
}
|
||||
}
|
||||
|
52
src/tools/rustdoc-themes/test-themes.py
Normal file
52
src/tools/rustdoc-themes/test-themes.py
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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.
|
||||
|
||||
from os import listdir
|
||||
from os.path import isfile, join
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
FILES_TO_IGNORE = ['main.css']
|
||||
THEME_DIR_PATH = "src/librustdoc/html/static/themes"
|
||||
|
||||
|
||||
def print_err(msg):
|
||||
sys.stderr.write('{}\n'.format(msg))
|
||||
|
||||
|
||||
def exec_command(command):
|
||||
child = subprocess.Popen(command)
|
||||
stdout, stderr = child.communicate()
|
||||
return child.returncode
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 1:
|
||||
print_err("Needs rustdoc binary path")
|
||||
return 1
|
||||
rustdoc_bin = argv[0]
|
||||
themes = [join(THEME_DIR_PATH, f) for f in listdir(THEME_DIR_PATH)
|
||||
if isfile(join(THEME_DIR_PATH, f)) and f not in FILES_TO_IGNORE]
|
||||
if len(themes) < 1:
|
||||
print_err('No theme found in "{}"...'.format(THEME_DIR_PATH))
|
||||
return 1
|
||||
args = [rustdoc_bin, '-Z', 'unstable-options', '--theme-checker']
|
||||
args.extend(themes)
|
||||
return exec_command(args)
|
||||
|
||||
|
||||
if __name__ != '__main__':
|
||||
print_err("Needs to be run as main")
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(main(sys.argv[1:]))
|
Loading…
Reference in New Issue
Block a user