about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2018-01-26 00:44:52 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2018-02-08 10:53:09 +0100
commit51580d46f919c1f97d82aeca1ea1086c545c7484 (patch)
tree9c14eccb3366b76e988077a9d12bc1724c612a47
parent63ee1cd846b92eb3a124ec345d4889bdb5bca8e3 (diff)
downloadrust-51580d46f919c1f97d82aeca1ea1086c545c7484.tar.gz
rust-51580d46f919c1f97d82aeca1ea1086c545c7484.zip
Add tests for themes
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/check.rs1
-rw-r--r--src/bootstrap/test.rs42
-rw-r--r--src/librustdoc/lib.rs8
-rw-r--r--src/librustdoc/theme.rs58
-rw-r--r--src/tools/rustdoc-themes/test-themes.py52
6 files changed, 138 insertions, 25 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index bf7b1015a49..6c68ee18506 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -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,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index e6871764b2c..ede403491d7 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -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")
 }
-
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index e4c1cdb79fd..1c6cd066ad9 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -425,6 +425,48 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
 }
 
 #[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>,
     pub target: Interned<String>,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index c08cff98892..17cf2b7349b 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -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");
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index fe753878041..39c9a6e2aa4 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -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()]);
     }
 }
diff --git a/src/tools/rustdoc-themes/test-themes.py b/src/tools/rustdoc-themes/test-themes.py
new file mode 100644
index 00000000000..27756e3bef6
--- /dev/null
+++ b/src/tools/rustdoc-themes/test-themes.py
@@ -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:]))