aboutsummaryrefslogtreecommitdiffstats
path: root/tests/contenttest.rs
blob: 67e24187b965cd03254d13692f1a0a7d96713f44 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

#![feature(collections)]
#![feature(exit_status)]
#![feature(path)]
#![feature(rustc_private)]
#![feature(std_misc)]
#![feature(test)]

extern crate getopts;
extern crate test;

use test::{AutoColor, TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use test::ShouldPanic;
use getopts::{getopts, reqopt};
use std::{str, env};
use std::ffi::OsStr;
use std::fs::read_dir;
use std::process::{Command, Stdio};
use std::thunk::Thunk;

#[derive(Clone)]
struct Config {
    source_dir: String,
    filter: Option<String>
}

fn main() {
    let args = env::args();
    let config = parse_config(args.collect());
    let opts = test_options(config.clone());
    let tests = find_tests(config);
    match run_tests_console(&opts, tests) {
        Ok(false) => env::set_exit_status(1), // tests failed
        Err(_) => env::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

fn parse_config(args: Vec<String>) -> Config {
    let args = args.tail();
    let opts = vec!(reqopt("s", "source-dir", "source-dir", "source-dir"));
    let matches = match getopts(args, &opts) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };

    Config {
        source_dir: matches.opt_str("source-dir").unwrap(),
        filter: matches.free.first().map(|s| s.clone())
    }
}

fn test_options(config: Config) -> TestOpts {
    TestOpts {
        filter: config.filter,
        run_ignored: false,
        run_tests: true,
        run_benchmarks: false,
        logfile: None,
        nocapture: false,
        color: AutoColor,
    }
}

fn find_tests(config: Config) -> Vec<TestDescAndFn> {
    read_dir(&config.source_dir)
        .ok()
        .expect("Error reading directory.")
        .filter_map(Result::ok)
        .map(|e| e.path())
        .filter(|file| file.extension().map_or(false, |e| e == OsStr::from_str("html")))
        .map(|file| make_test(file.display().to_string()))
        .collect()
}

fn make_test(file: String) -> TestDescAndFn {
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(file.clone()),
            ignore: false,
            should_panic: ShouldPanic::No,
        },
        testfn: DynTestFn(Thunk::new(move || { run_test(file) }))
    }
}

fn run_test(file: String) {
    let path = env::current_dir().unwrap().join(&file);
    // FIXME (#1094): not the right way to transform a path
    let infile = format!("file://{}", path.display());
    let args = ["-z", "-f", &*infile];

    let mut prc_arg = env::current_exe().unwrap();
    let prc_arg = match prc_arg.pop() {
        true => prc_arg.join("servo"),
        _ => panic!("could not pop directory"),
    };
    let output = match Command::new(prc_arg.to_str().unwrap())
        .args(&args)
        .stdin(Stdio::null())
        .stderr(Stdio::inherit())
        .output()
    {
        Ok(p) => p,
        _ => panic!("Unable to spawn process."),
    };

    print!("{}", str::from_utf8(&output.stdout).unwrap());

    let out = str::from_utf8(&output.stderr);
    let lines: Vec<&str> = out.unwrap().split('\n').collect();
    for &line in lines.iter() {
        if line.contains("TEST-UNEXPECTED-FAIL") {
            panic!(line.to_string());
        }
    }

    if !output.status.success() {
        panic!("Servo exited with non-zero status {:?}", output.status);
    }
}