Skip to content

Commit 51580d4

Browse files
Add tests for themes
1 parent 63ee1cd commit 51580d4

File tree

6 files changed

+138
-25
lines changed

6 files changed

+138
-25
lines changed

src/bootstrap/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ impl<'a> Builder<'a> {
258258
test::HostCompiletest, test::Crate, test::CrateLibrustc, test::Rustdoc,
259259
test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::Docs,
260260
test::ErrorIndex, test::Distcheck, test::Rustfmt, test::Miri, test::Clippy,
261-
test::RustdocJS),
261+
test::RustdocJS, test::RustdocTheme),
262262
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
263263
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
264264
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,

src/bootstrap/check.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,3 @@ pub fn libtest_stamp(build: &Build, compiler: Compiler, target: Interned<String>
160160
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
161161
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
162162
}
163-

src/bootstrap/test.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,48 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
424424
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
425425
}
426426

427+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
428+
pub struct RustdocTheme {
429+
pub compiler: Compiler,
430+
pub host: Interned<String>,
431+
}
432+
433+
impl Step for RustdocTheme {
434+
type Output = ();
435+
const DEFAULT: bool = true;
436+
const ONLY_HOSTS: bool = true;
437+
438+
fn should_run(run: ShouldRun) -> ShouldRun {
439+
run.path("src/tools/rustdoc-themes")
440+
}
441+
442+
fn make_run(run: RunConfig) {
443+
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
444+
445+
run.builder.ensure(RustdocTheme {
446+
compiler: compiler,
447+
host: run.builder.build.build,
448+
});
449+
}
450+
451+
fn run(self, builder: &Builder) {
452+
let rustdoc = builder.rustdoc(self.compiler.host);
453+
let mut cmd = Command::new(builder.config.python.clone().expect("python not defined"));
454+
cmd.args(&["src/tools/rustdoc-themes/test-themes.py", rustdoc.to_str().unwrap()]);
455+
cmd.env("RUSTC_STAGE", self.compiler.stage.to_string())
456+
.env("RUSTC_SYSROOT", builder.sysroot(self.compiler))
457+
.env("RUSTDOC_LIBDIR", builder.sysroot_libdir(self.compiler, self.compiler.host))
458+
.env("CFG_RELEASE_CHANNEL", &builder.build.config.channel)
459+
.env("RUSTDOC_REAL", builder.rustdoc(self.host))
460+
.env("RUSTDOC_CRATE_VERSION", builder.build.rust_version())
461+
.env("RUSTC_BOOTSTRAP", "1");
462+
if let Some(linker) = builder.build.linker(self.host) {
463+
cmd.env("RUSTC_TARGET_LINKER", linker);
464+
}
465+
builder.run(&mut cmd);
466+
}
467+
}
468+
427469
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
428470
pub struct RustdocJS {
429471
pub host: Interned<String>,

src/librustdoc/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,13 @@ pub fn main_args(args: &[String]) -> isize {
324324

325325
let to_check = matches.opt_strs("theme-checker");
326326
if !to_check.is_empty() {
327-
let pathes = theme::load_css_pathes(include_bytes!("html/static/themes/main.css"));
327+
let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css"));
328328
let mut errors = 0;
329329

330330
println!("rustdoc: [theme-checker] Starting tests!");
331331
for theme_file in to_check.iter() {
332332
print!(" - Checking \"{}\"...", theme_file);
333-
let (success, differences) = theme::test_theme_against(theme_file, &pathes);
333+
let (success, differences) = theme::test_theme_against(theme_file, &paths);
334334
if !differences.is_empty() || !success {
335335
eprintln!(" FAILED");
336336
errors += 1;
@@ -401,7 +401,7 @@ pub fn main_args(args: &[String]) -> isize {
401401

402402
let mut themes = Vec::new();
403403
if matches.opt_present("themes") {
404-
let pathes = theme::load_css_pathes(include_bytes!("html/static/themes/main.css"));
404+
let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css"));
405405

406406
for (theme_file, theme_s) in matches.opt_strs("themes")
407407
.iter()
@@ -410,7 +410,7 @@ pub fn main_args(args: &[String]) -> isize {
410410
eprintln!("rustdoc: option --themes arguments must all be files");
411411
return 1;
412412
}
413-
let (success, ret) = theme::test_theme_against(&theme_file, &pathes);
413+
let (success, ret) = theme::test_theme_against(&theme_file, &paths);
414414
if !success || !ret.is_empty() {
415415
eprintln!("rustdoc: invalid theme: \"{}\"", theme_s);
416416
eprintln!(" Check what's wrong with the \"theme-checker\" option");

src/librustdoc/theme.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -170,45 +170,59 @@ fn get_useful_next(events: &[Events], pos: &mut usize) -> Option<Events> {
170170
fn get_previous_positions(events: &[Events], mut pos: usize) -> Vec<usize> {
171171
let mut ret = Vec::with_capacity(3);
172172

173-
ret.push(events[pos].get_pos() - 1);
173+
ret.push(events[pos].get_pos());
174174
if pos > 0 {
175175
pos -= 1;
176176
}
177177
loop {
178-
ret.push(events[pos].get_pos());
179178
if pos < 1 || !events[pos].is_comment() {
179+
let x = events[pos].get_pos();
180+
if *ret.last().unwrap() != x {
181+
ret.push(x);
182+
} else {
183+
ret.push(0);
184+
}
180185
break
181186
}
187+
ret.push(events[pos].get_pos());
182188
pos -= 1;
183189
}
184-
if events[pos].is_comment() {
190+
if ret.len() & 1 != 0 && events[pos].is_comment() {
185191
ret.push(0);
186192
}
187193
ret.iter().rev().cloned().collect()
188194
}
189195

190196
fn build_rule(v: &[u8], positions: &[usize]) -> String {
191197
positions.chunks(2)
192-
.map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or("").to_owned())
198+
.map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or(""))
193199
.collect::<String>()
194200
.trim()
195201
.replace("\n", " ")
202+
.replace("/", "")
203+
.replace("\t", " ")
204+
.replace("{", "")
205+
.replace("}", "")
206+
.split(" ")
207+
.filter(|s| s.len() > 0)
208+
.collect::<Vec<&str>>()
209+
.join(" ")
196210
}
197211

198212
fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> HashSet<CssPath> {
199-
let mut pathes = Vec::with_capacity(50);
213+
let mut paths = Vec::with_capacity(50);
200214

201215
while *pos < events.len() {
202216
if let Some(Events::OutBlock(_)) = get_useful_next(events, pos) {
203217
*pos += 1;
204218
break
205219
}
206220
if let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
207-
pathes.push(CssPath::new(build_rule(v, &get_previous_positions(events, *pos))));
221+
paths.push(CssPath::new(build_rule(v, &get_previous_positions(events, *pos))));
208222
*pos += 1;
209223
}
210224
while let Some(Events::InBlock(_)) = get_useful_next(events, pos) {
211-
if let Some(ref mut path) = pathes.last_mut() {
225+
if let Some(ref mut path) = paths.last_mut() {
212226
for entry in inner(v, events, pos).iter() {
213227
path.children.insert(entry.clone());
214228
}
@@ -218,10 +232,10 @@ fn inner(v: &[u8], events: &[Events], pos: &mut usize) -> HashSet<CssPath> {
218232
*pos += 1;
219233
}
220234
}
221-
pathes.iter().cloned().collect()
235+
paths.iter().cloned().collect()
222236
}
223237

224-
pub fn load_css_pathes(v: &[u8]) -> CssPath {
238+
pub fn load_css_paths(v: &[u8]) -> CssPath {
225239
let events = load_css_events(v);
226240
let mut pos = 0;
227241

@@ -264,9 +278,9 @@ pub fn test_theme_against<P: AsRef<Path>>(f: &P, against: &CssPath) -> (bool, Ve
264278
let mut data = Vec::with_capacity(1000);
265279

266280
try_something!(file.read_to_end(&mut data), (false, Vec::new()));
267-
let pathes = load_css_pathes(&data);
281+
let paths = load_css_paths(&data);
268282
let mut ret = Vec::new();
269-
get_differences(against, &pathes, &mut ret);
283+
get_differences(against, &paths, &mut ret);
270284
(true, ret)
271285
}
272286

@@ -317,8 +331,11 @@ rule gh i {}
317331
rule j end {}
318332
"#;
319333

320-
assert!(get_differences(&load_css_pathes(against.as_bytes()),
321-
&load_css_pathes(text.as_bytes())).is_empty());
334+
let mut ret = Vec::new();
335+
get_differences(&load_css_paths(against.as_bytes()),
336+
&load_css_paths(text.as_bytes()),
337+
&mut ret);
338+
assert!(ret.is_empty());
322339
}
323340

324341
#[test]
@@ -330,8 +347,8 @@ a
330347
c // sdf
331348
d {}
332349
"#;
333-
let pathes = load_css_pathes(text.as_bytes());
334-
assert!(pathes.children.get("a b c d").is_some());
350+
let paths = load_css_paths(text.as_bytes());
351+
assert!(paths.children.get(&CssPath::new("a b c d".to_owned())).is_some());
335352
}
336353

337354
#[test]
@@ -350,10 +367,13 @@ a {
350367
}
351368
"#;
352369

353-
let against = load_css_pathes(y.as_bytes());
354-
let other = load_css_pathes(x.as_bytes());
370+
let against = load_css_paths(y.as_bytes());
371+
let other = load_css_paths(x.as_bytes());
355372

356-
assert!(get_differences(&against, &other).is_empty());
357-
assert_eq!(get_differences(&other, &against), vec![" Missing \"c\" rule".to_owned()])
373+
let mut ret = Vec::new();
374+
get_differences(&against, &other, &mut ret);
375+
assert!(ret.is_empty());
376+
get_differences(&other, &against, &mut ret);
377+
assert_eq!(ret, vec![" Missing \"c\" rule".to_owned()]);
358378
}
359379
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright 2018 The Rust Project Developers. See the COPYRIGHT
5+
# file at the top-level directory of this distribution and at
6+
# http://rust-lang.org/COPYRIGHT.
7+
#
8+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
11+
# option. This file may not be copied, modified, or distributed
12+
# except according to those terms.
13+
14+
from os import listdir
15+
from os.path import isfile, join
16+
import subprocess
17+
import sys
18+
19+
FILES_TO_IGNORE = ['main.css']
20+
THEME_DIR_PATH = "src/librustdoc/html/static/themes"
21+
22+
23+
def print_err(msg):
24+
sys.stderr.write('{}\n'.format(msg))
25+
26+
27+
def exec_command(command):
28+
child = subprocess.Popen(command)
29+
stdout, stderr = child.communicate()
30+
return child.returncode
31+
32+
33+
def main(argv):
34+
if len(argv) < 1:
35+
print_err("Needs rustdoc binary path")
36+
return 1
37+
rustdoc_bin = argv[0]
38+
themes = [join(THEME_DIR_PATH, f) for f in listdir(THEME_DIR_PATH)
39+
if isfile(join(THEME_DIR_PATH, f)) and f not in FILES_TO_IGNORE]
40+
if len(themes) < 1:
41+
print_err('No theme found in "{}"...'.format(THEME_DIR_PATH))
42+
return 1
43+
args = [rustdoc_bin, '-Z', 'unstable-options', '--theme-checker']
44+
args.extend(themes)
45+
return exec_command(args)
46+
47+
48+
if __name__ != '__main__':
49+
print_err("Needs to be run as main")
50+
sys.exit(1)
51+
else:
52+
sys.exit(main(sys.argv[1:]))

0 commit comments

Comments
 (0)