From 5c4cbee24927b2fb2a57c88f7236f4b77f568c1a Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Fri, 30 Jan 2015 12:15:20 -0500 Subject: [PATCH 1/2] Use Cargo to build and run tests html5ever-external-test.rs is now gone. Its custom test runner has moved into tokenizer.rs and tree_builder.rs. We're using the #[start] attribute to define our own entry point (#[main] isn't respected for tests) which generates the test cases and calls through to test::test_main. tests/util.rs now lives in its own test_util crate. It's the only way I could figure out to share this functionality between the tokenizer and tree builder integration tests. Makefile.in is now a little simpler because we can just use `cargo test` to handle building the tests and examples and and running the tests. Top-level make targets like `build`, `check`, and `examples` continue to work (though `make examples` also builds the tests now). --- Cargo.toml | 4 +- Makefile.in | 40 +++-------------- test_util/Cargo.toml | 5 +++ tests/util.rs => test_util/src/lib.rs | 6 ++- tests/html5ever-external-test.rs | 63 --------------------------- tests/tokenizer.rs | 30 ++++++++++--- tests/tree_builder.rs | 40 ++++++++++++++--- 7 files changed, 78 insertions(+), 110 deletions(-) create mode 100644 test_util/Cargo.toml rename tests/util.rs => test_util/src/lib.rs (90%) delete mode 100644 tests/html5ever-external-test.rs diff --git a/Cargo.toml b/Cargo.toml index 4729ec2f..6f2b8578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,5 +18,5 @@ git = "https://github.com/servo/string-cache" [dependencies.html5ever_macros] path = "macros" -[[test]] -name = "html5ever-external-test" +[dev-dependencies.test_util] +path = "test_util" diff --git a/Makefile.in b/Makefile.in index a5c9aa27..61b75d27 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,22 +17,17 @@ RUSTC_CMD := $(RUSTC) -D warnings -C rpath $(RUST_DIRS) --extern time=`find $(VP # We build the library itself using Cargo. CARGO_SOURCES := $(shell find $(VPATH)/src $(VPATH)/macros/src -type f -name '*.rs') -EXT_TEST_TOP_SRC := $(VPATH)/tests/html5ever-external-test.rs -EXT_TEST_ALL_SRC := $(shell find $(VPATH)/tests -type f -name '*.rs') - EXT_BENCH_TOP_SRC := $(VPATH)/bench/bin.rs EXT_BENCH_ALL_SRC := $(shell find $(VPATH)/bench -type f -name '*.rs') LIB := libhtml5ever.dummy -EXAMPLES := tokenize noop-tokenize print-tree-actions \ - print-rcdom html2html noop-tree-builder - .PHONY: all all: $(LIB) .PHONY: examples -examples: $(EXAMPLES) +examples: + (cd $(VPATH) && cargo test --no-run) $(LIB): $(CARGO_SOURCES) (cd $(VPATH) && cargo build) @@ -44,39 +39,16 @@ for_c: libhtml5ever_for_c.a libhtml5ever_for_c.a: $(LIB) $(CARGO_SOURCES) $(RUSTC_CMD) -o $@ --cfg for_c --crate-type staticlib $(VPATH)/src/lib.rs -define DEF_EXAMPLE -$(1): $$(VPATH)/examples/$(1).rs $$(LIB) - $$(RUSTC_CMD) $$< -endef - -$(foreach example,$(EXAMPLES),\ -$(eval $(call DEF_EXAMPLE,$(example)))) - -# Run #[test] functions -html5ever-test: $(LIB) - $(RUSTC_CMD) -o $@ --test $(VPATH)/src/lib.rs - -# Run external tests loaded from JSON -html5ever-external-test: $(EXT_TEST_ALL_SRC) $(LIB) - $(RUSTC_CMD) $(EXT_TEST_TOP_SRC) - # Run benchmarks html5ever-external-bench: $(EXT_BENCH_ALL_SRC) $(LIB) $(RUSTC_CMD) $(EXT_BENCH_TOP_SRC) .PHONY: check -check: check-build check-internal check-external +check: check-build + (cd $(VPATH) && cargo test) .PHONY: check-build -check-build: all examples html5ever-test html5ever-external-test html5ever-external-bench - -.PHONY: check-internal -check-internal: html5ever-test - ./html5ever-test - -.PHONY: check-external -check-external: html5ever-external-test - HTML5EVER_SRC_DIR=$(VPATH) ./html5ever-external-test +check-build: all examples html5ever-external-bench .PHONY: bench bench: html5ever-external-bench @@ -85,7 +57,7 @@ bench: html5ever-external-bench .PHONY: clean clean: (cd $(VPATH) && cargo clean) - rm -f *.o *.a *.so *.dylib *.dll *.dummy *-test *-bench $(EXAMPLES) + rm -f *.o *.a *.so *.dylib *.dll *.dummy *-bench .PHONY: docs docs: diff --git a/test_util/Cargo.toml b/test_util/Cargo.toml new file mode 100644 index 00000000..9b682e86 --- /dev/null +++ b/test_util/Cargo.toml @@ -0,0 +1,5 @@ +[package] + +name = "test_util" +version = "0.0.0" +authors = [ "The html5ever Project Developers" ] diff --git a/tests/util.rs b/test_util/src/lib.rs similarity index 90% rename from tests/util.rs rename to test_util/src/lib.rs index 903d40e0..3fc62879 100644 --- a/tests/util.rs +++ b/test_util/src/lib.rs @@ -7,8 +7,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(io, path)] + use std::old_io as io; -use std::old_path::Path; +use std::old_path::{GenericPath,Path}; +use std::ops::FnMut; +use std::str::StrExt; pub fn foreach_html5lib_test( src_dir: Path, diff --git a/tests/html5ever-external-test.rs b/tests/html5ever-external-test.rs deleted file mode 100644 index 22ac390e..00000000 --- a/tests/html5ever-external-test.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 The html5ever Project Developers. See the -// COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_name="html5ever-external-test"] -#![crate_type="bin"] - -#![feature(plugin)] -#![feature(rustc_private, core, env, io, path, std_misc, test)] -#![plugin(string_cache_plugin)] - -extern crate test; -extern crate serialize; - -#[macro_use] -extern crate string_cache; - -extern crate html5ever; - -use std::old_io as io; -use std::env; -use std::str::FromStr; -use std::collections::HashSet; -use test::test_main; - -mod tokenizer; -mod tree_builder; -mod util; - -// Needed to make `cargo test` run warning-free. -#[allow(dead_code)] -fn main() { - let src_dir: Path = FromStr::from_str( - env::var("HTML5EVER_SRC_DIR").unwrap().as_slice() - ).ok().expect("HTML5EVER_SRC_DIR invalid"); - - let mut ignores = HashSet::new(); - { - let f = io::File::open(&src_dir.join("data/test/ignore")).unwrap(); - let mut r = io::BufferedReader::new(f); - for ln in r.lines() { - ignores.insert(ln.unwrap().as_slice().trim_right().to_string()); - } - } - - let mut tests = vec!(); - - if env::var("HTML5EVER_NO_TOK_TEST").is_err() { - tests.extend(tokenizer::tests(src_dir.clone())); - } - - if env::var("HTML5EVER_NO_TB_TEST").is_err() { - tests.extend(tree_builder::tests(src_dir, &ignores)); - } - - let args: Vec = env::args().collect(); - test_main(&args, tests); -} diff --git a/tests/tokenizer.rs b/tests/tokenizer.rs index e15e9856..076498c6 100644 --- a/tests/tokenizer.rs +++ b/tests/tokenizer.rs @@ -7,9 +7,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use util::foreach_html5lib_test; +#![feature(core, env, int_uint, io, path, plugin, rustc_private, start, std_misc, test)] -use std::{num, char}; +#![plugin(string_cache_plugin)] + +extern crate test; +extern crate serialize; +extern crate string_cache; + +extern crate html5ever; +extern crate test_util; + +use test_util::foreach_html5lib_test; + +use std::{num, char, env, rt}; use std::mem::replace; use std::default::Default; use std::old_path::Path; @@ -20,7 +31,6 @@ use serialize::json; use serialize::json::Json; use std::collections::BTreeMap; use std::borrow::Cow::Borrowed; -use std::vec::IntoIter; use html5ever::tokenizer::{Doctype, Attribute, StartTag, EndTag, Tag}; use html5ever::tokenizer::{Token, DoctypeToken, TagToken, CommentToken}; @@ -378,7 +388,7 @@ fn mk_tests(tests: &mut Vec, path_str: &str, js: &Json) { } } -pub fn tests(src_dir: Path) -> IntoIter { +fn tests(src_dir: Path) -> Vec { let mut tests = vec!(); foreach_html5lib_test(src_dir, "tokenizer", ".test", |path_str, mut file| { @@ -397,5 +407,15 @@ pub fn tests(src_dir: Path) -> IntoIter { } }); - tests.into_iter() + tests +} + +#[start] +fn start(argc: int, argv: *const *const u8) -> int { + unsafe { + rt::args::init(argc, argv); + } + let args: Vec<_> = env::args().collect(); + test::test_main(args.as_slice(), tests(Path::new(env!("CARGO_MANIFEST_DIR")))); + 0 } diff --git a/tests/tree_builder.rs b/tests/tree_builder.rs index 8cbfd13a..54dcb359 100644 --- a/tests/tree_builder.rs +++ b/tests/tree_builder.rs @@ -7,15 +7,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use util::foreach_html5lib_test; +#![feature(core, env, int_uint, io, path, plugin, start, std_misc, test)] + +#![plugin(string_cache_plugin)] + +extern crate test; +extern crate string_cache; + +extern crate html5ever; +extern crate test_util; + +use test_util::foreach_html5lib_test; use std::old_io as io; +use std::{env, rt}; use std::iter::repeat; use std::mem::replace; use std::default::Default; use std::old_path::Path; use std::collections::{HashSet, HashMap}; -use std::vec::IntoIter; use std::thunk::Thunk; use test::{TestDesc, TestDescAndFn, DynTestName, DynTestFn}; use test::ShouldFail::No; @@ -47,7 +57,7 @@ fn parse_tests>(mut lines: It) -> Vec break, Some(line) => { - if line.as_slice().starts_with("#") { + if line.starts_with("#") { finish_val!(); if line.as_slice() == "#data\n" { finish_test!(); @@ -170,7 +180,7 @@ fn make_test( }); } -pub fn tests(src_dir: Path, ignores: &HashSet) -> IntoIter { +fn tests(src_dir: Path, ignores: &HashSet) -> Vec { let mut tests = vec!(); foreach_html5lib_test(src_dir, "tree-construction", ".dat", |path_str, file| { @@ -184,5 +194,25 @@ pub fn tests(src_dir: Path, ignores: &HashSet) -> IntoIter int { + unsafe { + rt::args::init(argc, argv); + } + let args: Vec<_> = env::args().collect(); + let src_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let mut ignores = HashSet::new(); + { + let f = io::File::open(&src_dir.join("data/test/ignore")).unwrap(); + let mut r = io::BufferedReader::new(f); + for ln in r.lines() { + ignores.insert(ln.unwrap().as_slice().trim_right().to_string()); + } + } + + test::test_main(args.as_slice(), tests(src_dir, &ignores)); + 0 } From b22741393e38c5f295936f5093111c98be260b50 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Tue, 3 Feb 2015 14:52:33 -0500 Subject: [PATCH 2/2] Use Cargo to build and run benchmarks This is quite similar to the cargoization of tests in the previous commit. html5ever-external-bench is now gone. benches/tokenizer.rs includes its own test harness that calls through to test::test_main. --- Makefile.in | 19 ++++++++----------- bench/bin.rs | 33 --------------------------------- {bench => benches}/tokenizer.rs | 26 ++++++++++++++++++++------ 3 files changed, 28 insertions(+), 50 deletions(-) delete mode 100644 bench/bin.rs rename {bench => benches}/tokenizer.rs (90%) diff --git a/Makefile.in b/Makefile.in index 61b75d27..5caff59b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,9 +17,6 @@ RUSTC_CMD := $(RUSTC) -D warnings -C rpath $(RUST_DIRS) --extern time=`find $(VP # We build the library itself using Cargo. CARGO_SOURCES := $(shell find $(VPATH)/src $(VPATH)/macros/src -type f -name '*.rs') -EXT_BENCH_TOP_SRC := $(VPATH)/bench/bin.rs -EXT_BENCH_ALL_SRC := $(shell find $(VPATH)/bench -type f -name '*.rs') - LIB := libhtml5ever.dummy .PHONY: all @@ -39,25 +36,25 @@ for_c: libhtml5ever_for_c.a libhtml5ever_for_c.a: $(LIB) $(CARGO_SOURCES) $(RUSTC_CMD) -o $@ --cfg for_c --crate-type staticlib $(VPATH)/src/lib.rs -# Run benchmarks -html5ever-external-bench: $(EXT_BENCH_ALL_SRC) $(LIB) - $(RUSTC_CMD) $(EXT_BENCH_TOP_SRC) - .PHONY: check check: check-build (cd $(VPATH) && cargo test) .PHONY: check-build -check-build: all examples html5ever-external-bench +check-build: all examples check-build-bench + +.PHONY: check-build-bench +check-build-bench: + (cd $(VPATH) && cargo bench --no-run) .PHONY: bench -bench: html5ever-external-bench - ./html5ever-external-bench --bench +bench: + (cd $(VPATH) && cargo bench) .PHONY: clean clean: (cd $(VPATH) && cargo clean) - rm -f *.o *.a *.so *.dylib *.dll *.dummy *-bench + rm -f *.o *.a *.so *.dylib *.dll *.dummy .PHONY: docs docs: diff --git a/bench/bin.rs b/bench/bin.rs deleted file mode 100644 index e57cee13..00000000 --- a/bench/bin.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2014 The html5ever Project Developers. See the -// COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_name="html5ever-external-bench"] -#![crate_type="bin"] - -#![feature(box_syntax)] -#![feature(core, io, env, path, test)] - -extern crate test; - -extern crate html5ever; - -use std::env; -use test::test_main; - -mod tokenizer; - -fn main() { - let mut tests = vec!(); - - tests.extend(tokenizer::tests()); - // more to follow - - let args: Vec<_> = env::args().collect(); - test_main(&args, tests); -} diff --git a/bench/tokenizer.rs b/benches/tokenizer.rs similarity index 90% rename from bench/tokenizer.rs rename to benches/tokenizer.rs index 55d4b89c..2f0a40e3 100644 --- a/bench/tokenizer.rs +++ b/benches/tokenizer.rs @@ -7,10 +7,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(box_syntax, core, env, int_uint, io, path, std_misc, start, test)] + +extern crate test; +extern crate html5ever; + use std::old_io as io; -use std::{env, cmp}; +use std::{env, cmp, rt}; use std::default::Default; -use std::vec::IntoIter; use test::{black_box, Bencher, TestDesc, TestDescAndFn}; use test::{DynTestName, DynBenchFn, TDynBenchFn}; @@ -39,8 +43,8 @@ struct Bench { impl Bench { fn new(name: &str, size: Option, clone_only: bool, opts: TokenizerOpts) -> Bench { - let mut path = env::current_exe().ok().expect("can't get exe path"); - path.push("../data/bench/"); + let mut path = Path::new(env!("CARGO_MANIFEST_DIR")); + path.push("data/bench/"); path.push(name); let mut file = io::File::open(&path).ok().expect("can't open file"); @@ -109,7 +113,7 @@ fn make_bench(name: &str, size: Option, clone_only: bool, } } -pub fn tests() -> IntoIter { +fn tests() -> Vec { let mut tests = vec!(make_bench("lipsum.html", Some(1024*1024), true, Default::default())); let mut opts_vec = vec!(Default::default()); @@ -140,5 +144,15 @@ pub fn tests() -> IntoIter { } } - tests.into_iter() + tests +} + +#[start] +fn start(argc: int, argv: *const *const u8) -> int { + unsafe { + rt::args::init(argc, argv); + } + let args: Vec<_> = env::args().collect(); + test::test_main(args.as_slice(), tests()); + 0 }