aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2017-11-30 16:04:11 +0100
committerSimon Sapin <simon.sapin@exyr.org>2017-12-07 13:50:09 +0100
commit05a364c7b8d5787fdd25f42a874c949ebaca1e56 (patch)
tree1fb1a196747bbbc38344319a869d6bd819d0ff96 /ports
parent1a950d263a631c59534eb2c97e92348321e42d63 (diff)
downloadservo-05a364c7b8d5787fdd25f42a874c949ebaca1e56.tar.gz
servo-05a364c7b8d5787fdd25f42a874c949ebaca1e56.zip
Move Stylo unit tests out of tests/unit
This will allow writing `tests/unit/*` in the root `Cargo.toml` file to designate Servo unit tests.
Diffstat (limited to 'ports')
-rw-r--r--ports/geckolib/Cargo.toml2
-rw-r--r--ports/geckolib/tests/Cargo.toml30
-rw-r--r--ports/geckolib/tests/build.rs75
-rw-r--r--ports/geckolib/tests/lib.rs37
-rw-r--r--ports/geckolib/tests/servo_function_signatures.rs26
-rw-r--r--ports/geckolib/tests/size_of.rs63
-rw-r--r--ports/geckolib/tests/specified_values.rs50
7 files changed, 282 insertions, 1 deletions
diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml
index 70ffc615d9b..5f370937b68 100644
--- a/ports/geckolib/Cargo.toml
+++ b/ports/geckolib/Cargo.toml
@@ -33,4 +33,4 @@ style = {path = "../../components/style", features = ["gecko"]}
style_traits = {path = "../../components/style_traits"}
[dev-dependencies]
-stylo_tests = {path = "../../tests/unit/stylo"}
+stylo_tests = {path = "./tests"}
diff --git a/ports/geckolib/tests/Cargo.toml b/ports/geckolib/tests/Cargo.toml
new file mode 100644
index 00000000000..7747fff2da9
--- /dev/null
+++ b/ports/geckolib/tests/Cargo.toml
@@ -0,0 +1,30 @@
+[package]
+name = "stylo_tests"
+version = "0.0.1"
+authors = ["The Servo Project Developers"]
+license = "MPL-2.0"
+
+build = "build.rs"
+
+[lib]
+name = "stylo_tests"
+path = "lib.rs"
+doctest = false
+
+[dependencies]
+atomic_refcell = "0.1"
+cssparser = "0.23.0"
+env_logger = "0.4"
+euclid = "0.15"
+geckoservo = {path = "../../../ports/geckolib"}
+libc = "0.2"
+log = {version = "0.3.5", features = ["release_max_level_info"]}
+malloc_size_of = {path = "../../../components/malloc_size_of"}
+selectors = {path = "../../../components/selectors", features = ["gecko_like_types"]}
+size_of_test = {path = "../../../components/size_of_test"}
+smallvec = "0.6"
+style_traits = {path = "../../../components/style_traits"}
+style = {path = "../../../components/style", features = ["gecko"]}
+
+[build-dependencies]
+regex = "0.2"
diff --git a/ports/geckolib/tests/build.rs b/ports/geckolib/tests/build.rs
new file mode 100644
index 00000000000..7712698c4b8
--- /dev/null
+++ b/ports/geckolib/tests/build.rs
@@ -0,0 +1,75 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+extern crate regex;
+
+use regex::Regex;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::Path;
+
+fn main() {
+ if std::mem::size_of::<Option<bool>>() == 1 {
+ // https://github.com/rust-lang/rust/pull/45225
+ println!("cargo:rustc-cfg=rustc_has_pr45225")
+ }
+
+ let root_path = Path::new("../../../");
+ let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs");
+ let glue_file = root_path.join("ports/geckolib/glue.rs");
+
+ println!("cargo:rerun-if-changed=build.rs");
+ println!("cargo:rerun-if-changed={}", glue_file.display());
+ println!("cargo:rerun-if-changed={}", bindings_file.display());
+
+ let env_out_dir = env::var("OUT_DIR").unwrap();
+ let out_dir = Path::new(&env_out_dir);
+
+ {
+ let output = out_dir.join("check_bindings.rs");
+ let r = BufReader::new(File::open(bindings_file).unwrap());
+ let mut w = File::create(output).unwrap();
+
+ w.write_all(b"fn assert_types() {\n").unwrap();
+
+ let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap();
+
+ for line in r.lines() {
+ let s = line.unwrap();
+ for cap in matcher.captures_iter(&s) {
+ w.write_all(format!(" [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap();
+ }
+ }
+
+ w.write_all(b"}\n").unwrap();
+ }
+
+ {
+ let output = out_dir.join("glue.rs");
+ let r = BufReader::new(File::open(glue_file).unwrap());
+ let mut w = File::create(output).unwrap();
+
+ w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap();
+
+ for line in r.lines() {
+ let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn");
+ w.write_all(s.as_bytes()).unwrap();
+ w.write_all(b"\n").unwrap();
+ }
+ }
+
+ // https://github.com/rust-lang/cargo/issues/3544
+ let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \
+ TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap();
+ File::create(out_dir.join("bindings.rs"))
+ .unwrap()
+ .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));",
+ style_out_dir).as_bytes())
+ .unwrap();
+
+ if env::var_os("MOZ_SRC").is_some() {
+ println!("cargo:rustc-cfg=linking_with_gecko")
+ }
+}
diff --git a/ports/geckolib/tests/lib.rs b/ports/geckolib/tests/lib.rs
new file mode 100644
index 00000000000..62fd455239d
--- /dev/null
+++ b/ports/geckolib/tests/lib.rs
@@ -0,0 +1,37 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Disable this entire crate on Windows when Gecko symbols are not available
+// as linking would fail:
+// https://github.com/rust-lang/rust/pull/44603#issuecomment-338807312
+//
+// On Linux and OS X linking succeeds anyway.
+// Presumably these symbol declarations don’t need to be resolved
+// as they’re not used in any code called from this crate.
+#![cfg(any(linking_with_gecko, not(windows)))]
+
+extern crate atomic_refcell;
+extern crate cssparser;
+extern crate env_logger;
+extern crate geckoservo;
+#[macro_use] extern crate log;
+extern crate malloc_size_of;
+extern crate selectors;
+extern crate smallvec;
+#[macro_use] extern crate size_of_test;
+#[macro_use] extern crate style;
+extern crate style_traits;
+
+#[cfg(target_pointer_width = "64")]
+mod size_of;
+mod specified_values;
+
+mod servo_function_signatures;
+
+use style::*;
+
+#[allow(dead_code, improper_ctypes)]
+mod bindings {
+ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+}
diff --git a/ports/geckolib/tests/servo_function_signatures.rs b/ports/geckolib/tests/servo_function_signatures.rs
new file mode 100644
index 00000000000..90d925fb1e1
--- /dev/null
+++ b/ports/geckolib/tests/servo_function_signatures.rs
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#![allow(unused)]
+
+use self::glue::*;
+use style::gecko_bindings::bindings;
+use style::gecko_properties::*;
+
+include!(concat!(env!("OUT_DIR"), "/check_bindings.rs"));
+
+#[path = "../../../ports/geckolib/error_reporter.rs"]
+mod error_reporter;
+
+#[path = "../../../ports/geckolib/stylesheet_loader.rs"]
+mod stylesheet_loader;
+
+#[allow(non_snake_case, unused_unsafe, private_no_mangle_fns)]
+mod glue {
+ // this module pretends to be glue.rs, with the safe functions swapped for unsafe ones. This is
+ // a hack to compensate for the fact that `fn` types cannot coerce to `unsafe fn` types. The
+ // imports are populated with the same things so the type assertion should be equivalent
+ use geckoservo::*;
+ include!(concat!(env!("OUT_DIR"), "/glue.rs"));
+}
diff --git a/ports/geckolib/tests/size_of.rs b/ports/geckolib/tests/size_of.rs
new file mode 100644
index 00000000000..9c2f6cbba1c
--- /dev/null
+++ b/ports/geckolib/tests/size_of.rs
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use selectors::gecko_like_types as dummies;
+use servo_arc::Arc;
+use std::mem::{size_of, align_of};
+use style;
+use style::applicable_declarations::ApplicableDeclarationBlock;
+use style::data::{ElementData, ElementStyles};
+use style::gecko::selector_parser as real;
+use style::properties::ComputedValues;
+use style::rule_tree::{RuleNode, StrongRuleNode};
+use style::values::computed;
+use style::values::specified;
+
+#[test]
+fn size_of_selectors_dummy_types() {
+ assert_eq!(size_of::<dummies::PseudoClass>(), size_of::<real::NonTSPseudoClass>());
+ assert_eq!(align_of::<dummies::PseudoClass>(), align_of::<real::NonTSPseudoClass>());
+
+ assert_eq!(size_of::<dummies::PseudoElement>(), size_of::<real::PseudoElement>());
+ assert_eq!(align_of::<dummies::PseudoElement>(), align_of::<real::PseudoElement>());
+
+ assert_eq!(size_of::<dummies::Atom>(), size_of::<style::Atom>());
+ assert_eq!(align_of::<dummies::Atom>(), align_of::<style::Atom>());
+}
+
+// The size of this is critical to performance on the bloom-basic microbenchmark.
+// When iterating over a large Rule array, we want to be able to fast-reject
+// selectors (with the inline hashes) with as few cache misses as possible.
+size_of_test!(test_size_of_rule, style::stylist::Rule, 32);
+
+// Large pages generate tens of thousands of ComputedValues.
+size_of_test!(test_size_of_cv, ComputedValues, 256);
+
+size_of_test!(test_size_of_option_arc_cv, Option<Arc<ComputedValues>>, 8);
+size_of_test!(test_size_of_option_rule_node, Option<StrongRuleNode>, 8);
+
+size_of_test!(test_size_of_element_styles, ElementStyles, 16);
+size_of_test!(test_size_of_element_data, ElementData, 24);
+
+size_of_test!(test_size_of_property_declaration, style::properties::PropertyDeclaration, 32);
+
+size_of_test!(test_size_of_application_declaration_block, ApplicableDeclarationBlock, 24);
+
+// FIXME(bholley): This can shrink with a little bit of work.
+// See https://github.com/servo/servo/issues/17280
+size_of_test!(test_size_of_rule_node, RuleNode, 80);
+
+// This is huge, but we allocate it on the stack and then never move it,
+// we only pass `&mut SourcePropertyDeclaration` references around.
+size_of_test!(test_size_of_parsed_declaration, style::properties::SourcePropertyDeclaration, 576);
+
+size_of_test!(test_size_of_computed_image, computed::image::Image, 40);
+size_of_test!(test_size_of_specified_image, specified::image::Image, 40);
+
+// FIXME(bz): These can shrink if we move the None_ value inside the
+// enum instead of paying an extra word for the Either discriminant.
+size_of_test!(test_size_of_computed_image_layer, computed::image::ImageLayer,
+ if cfg!(rustc_has_pr45225) { 40 } else { 48 });
+size_of_test!(test_size_of_specified_image_layer, specified::image::ImageLayer,
+ if cfg!(rustc_has_pr45225) { 40 } else { 48 });
diff --git a/ports/geckolib/tests/specified_values.rs b/ports/geckolib/tests/specified_values.rs
new file mode 100644
index 00000000000..6bc01a97a46
--- /dev/null
+++ b/ports/geckolib/tests/specified_values.rs
@@ -0,0 +1,50 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use style;
+
+#[cfg(all(test, target_pointer_width = "64"))]
+#[test]
+fn size_of_specified_values() {
+ use std::mem::size_of;
+ let threshold = 24;
+
+ let mut bad_properties = vec![];
+
+ macro_rules! check_property {
+ ( $( { $name: ident, $boxed: expr } )+ ) => {
+ $(
+ let size = size_of::<style::properties::longhands::$name::SpecifiedValue>();
+ let is_boxed = $boxed;
+ if (!is_boxed && size > threshold) || (is_boxed && size <= threshold) {
+ bad_properties.push((stringify!($name), size, is_boxed));
+ }
+ )+
+ }
+ }
+
+ longhand_properties_idents!(check_property);
+
+ let mut failing_messages = vec![];
+
+ for bad_prop in bad_properties {
+ if !bad_prop.2 {
+ failing_messages.push(
+ format!("Your changes have increased the size of {} SpecifiedValue to {}. The threshold is \
+ currently {}. SpecifiedValues affect size of PropertyDeclaration enum and \
+ increasing the size may negative affect style system performance. Please consider \
+ using `boxed=\"True\"` in this longhand.",
+ bad_prop.0, bad_prop.1, threshold));
+ } else if bad_prop.2 {
+ failing_messages.push(
+ format!("Your changes have decreased the size of {} SpecifiedValue to {}. Good work! \
+ The threshold is currently {}. Please consider removing `boxed=\"True\"` from this longhand.",
+ bad_prop.0, bad_prop.1, threshold));
+ }
+ }
+
+ if !failing_messages.is_empty() {
+ panic!("{}", failing_messages.join("\n\n"));
+ }
+}