зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #17984 - Remove style/testing feature (from Manishearth:rm-testing); r=SimonSapin
We added this because a year ago we had no reliable Gecko CI. This meant that Gecko-only properties needed to be tested *somehow*, and we solved that by making it so that for unit tests we compile all properties, not just the servo ones. This was useful back then, but I don't think we need this anymore. We have reliable Gecko CI, and all the gecko-only stuff we tested is adequately handled by the properties-database parsing mochitests. It's a bit of annoying cruft that just complicates things; we probably should remove it. r? @emilio or @SimonSapin Source-Repo: https://github.com/servo/servo Source-Revision: 32f835260cd3ea03a881f7a344a01f401c4db621 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 2b280c0e8d9940b424b893e18a46cdad65fa40ca
This commit is contained in:
Родитель
7fd76cec03
Коммит
1cedde3ab8
|
@ -16,7 +16,6 @@ default = ["webdriver", "max_log_level"]
|
|||
max_log_level = ["log/release_max_level_info"]
|
||||
webdriver = ["webdriver_server"]
|
||||
energy-profiling = ["profile_traits/energy-profiling"]
|
||||
testing = ["style/testing"]
|
||||
debugmozjs = ["script/debugmozjs"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -26,7 +26,6 @@ servo = ["serde", "heapsize", "heapsize_derive",
|
|||
#"arrayvec/use_union"
|
||||
|
||||
"servo_url"]
|
||||
testing = []
|
||||
gecko_debug = ["nsstring_vendor/gecko_debug"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -75,7 +75,6 @@ fn generate_properties() {
|
|||
.arg(&script)
|
||||
.arg(product)
|
||||
.arg("style-crate")
|
||||
.arg(if cfg!(feature = "testing") { "testing" } else { "regular" })
|
||||
.status()
|
||||
.unwrap();
|
||||
if !status.success() {
|
||||
|
|
|
@ -21,17 +21,16 @@ RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>')
|
|||
|
||||
|
||||
def main():
|
||||
usage = "Usage: %s [ servo | gecko ] [ style-crate | html ] [ testing | regular ]" % sys.argv[0]
|
||||
if len(sys.argv) < 4:
|
||||
usage = "Usage: %s [ servo | gecko ] [ style-crate | html ]" % sys.argv[0]
|
||||
if len(sys.argv) < 3:
|
||||
abort(usage)
|
||||
product = sys.argv[1]
|
||||
output = sys.argv[2]
|
||||
testing = sys.argv[3] == "testing"
|
||||
|
||||
if product not in ["servo", "gecko"] or output not in ["style-crate", "geckolib", "html"]:
|
||||
abort(usage)
|
||||
|
||||
properties = data.PropertiesData(product=product, testing=testing)
|
||||
properties = data.PropertiesData(product=product)
|
||||
template = os.path.join(BASE, "properties.mako.rs")
|
||||
rust = render(template, product=product, data=properties, __file__=template)
|
||||
if output == "style-crate":
|
||||
|
|
|
@ -304,18 +304,8 @@ class StyleStruct(object):
|
|||
|
||||
|
||||
class PropertiesData(object):
|
||||
"""
|
||||
The `testing` parameter means that we're running tests.
|
||||
|
||||
In this situation, the `product` value is ignored while choosing
|
||||
which shorthands and longhands to generate; and instead all properties for
|
||||
which code exists for either servo or stylo are generated. Note that we skip
|
||||
this behavior when the style crate is being built in gecko mode, because we
|
||||
need manual glue for such properties and we don't have it.
|
||||
"""
|
||||
def __init__(self, product, testing):
|
||||
def __init__(self, product):
|
||||
self.product = product
|
||||
self.testing = testing and product != "gecko"
|
||||
self.style_structs = []
|
||||
self.current_style_struct = None
|
||||
self.longhands = []
|
||||
|
@ -338,9 +328,9 @@ class PropertiesData(object):
|
|||
for prefix in property.extra_prefixes:
|
||||
property.alias.append('-%s-%s' % (prefix, property.name))
|
||||
|
||||
def declare_longhand(self, name, products="gecko servo", disable_when_testing=False, **kwargs):
|
||||
def declare_longhand(self, name, products="gecko servo", **kwargs):
|
||||
products = products.split()
|
||||
if self.product not in products and not (self.testing and not disable_when_testing):
|
||||
if self.product not in products:
|
||||
return
|
||||
|
||||
longhand = Longhand(self.current_style_struct, name, **kwargs)
|
||||
|
@ -354,10 +344,9 @@ class PropertiesData(object):
|
|||
|
||||
return longhand
|
||||
|
||||
def declare_shorthand(self, name, sub_properties, products="gecko servo",
|
||||
disable_when_testing=False, *args, **kwargs):
|
||||
def declare_shorthand(self, name, sub_properties, products="gecko servo", *args, **kwargs):
|
||||
products = products.split()
|
||||
if self.product not in products and not (self.testing and not disable_when_testing):
|
||||
if self.product not in products:
|
||||
return
|
||||
|
||||
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
|
||||
|
|
|
@ -34,7 +34,7 @@ use std::cmp;
|
|||
#[cfg(feature = "gecko")] use fnv::FnvHashMap;
|
||||
use style_traits::ParseError;
|
||||
use super::ComputedValues;
|
||||
#[cfg(any(feature = "gecko", feature = "testing"))]
|
||||
#[cfg(feature = "gecko")]
|
||||
use values::Auto;
|
||||
use values::{CSSFloat, CustomIdent, Either};
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
|
|
|
@ -711,7 +711,6 @@ ${helpers.predefined_type("animation-delay",
|
|||
"computed::ScrollSnapPoint::none()",
|
||||
animation_value_type="discrete",
|
||||
products="gecko",
|
||||
disable_when_testing=True,
|
||||
spec="Nonstandard (https://www.w3.org/TR/2015/WD-css-snappoints-1-20150326/#scroll-snap-points)",
|
||||
)}
|
||||
% endfor
|
||||
|
@ -1832,8 +1831,7 @@ ${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)",
|
|||
boxed="True" if product == "gecko" else "False",
|
||||
animation_value_type="none",
|
||||
gecko_ffi_name="mBinding",
|
||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)",
|
||||
disable_when_testing="True")}
|
||||
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)")}
|
||||
|
||||
${helpers.single_keyword("-moz-orient",
|
||||
"inline block horizontal vertical",
|
||||
|
@ -1915,7 +1913,6 @@ ${helpers.predefined_type("shape-outside", "basic_shape::FloatAreaShape",
|
|||
<%helpers:longhand name="touch-action"
|
||||
products="gecko"
|
||||
animation_value_type="discrete"
|
||||
disable_when_testing="True"
|
||||
spec="https://compat.spec.whatwg.org/#touch-action">
|
||||
use gecko_bindings::structs;
|
||||
use std::fmt;
|
||||
|
|
|
@ -1507,7 +1507,7 @@ ${helpers.single_keyword_system("font-kerning",
|
|||
}
|
||||
</%helpers:longhand>
|
||||
|
||||
#[cfg(any(feature = "gecko", feature = "testing"))]
|
||||
#[cfg(feature = "gecko")]
|
||||
macro_rules! exclusive_value {
|
||||
(($value:ident, $set:expr) => $ident:ident) => {
|
||||
if $value.intersects($set) {
|
||||
|
@ -2256,7 +2256,7 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
|
|||
<%helpers:longhand name="-moz-script-size-multiplier" products="gecko" animation_value_type="none"
|
||||
predefined_type="Number" gecko_ffi_name="mScriptSizeMultiplier"
|
||||
spec="Internal (not web-exposed)"
|
||||
internal="True" disable_when_testing="True">
|
||||
internal="True">
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
pub use self::computed_value::T as SpecifiedValue;
|
||||
|
||||
|
@ -2281,7 +2281,7 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-
|
|||
<%helpers:longhand name="-moz-script-level" products="gecko" animation_value_type="none"
|
||||
predefined_type="Integer" gecko_ffi_name="mScriptLevel"
|
||||
spec="Internal (not web-exposed)"
|
||||
internal="True" disable_when_testing="True" need_clone="True">
|
||||
internal="True" need_clone="True">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
|
@ -2380,7 +2380,7 @@ ${helpers.single_keyword("-moz-math-variant",
|
|||
<%helpers:longhand name="-moz-script-min-size" products="gecko" animation_value_type="none"
|
||||
predefined_type="Length" gecko_ffi_name="mScriptMinSize"
|
||||
spec="Internal (not web-exposed)"
|
||||
internal="True" disable_when_testing="True">
|
||||
internal="True">
|
||||
use app_units::Au;
|
||||
use gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT;
|
||||
use values::specified::length::{AU_PER_PT, FontBaseSize, NoCalcLength};
|
||||
|
|
|
@ -416,7 +416,6 @@ ${helpers.predefined_type("object-position",
|
|||
spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas"
|
||||
products="gecko"
|
||||
animation_value_type="discrete"
|
||||
disable_when_testing="True"
|
||||
boxed="True">
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
<%helpers:shorthand name="font"
|
||||
sub_properties="font-style font-variant-caps font-weight font-stretch
|
||||
font-size line-height font-family
|
||||
${'font-size-adjust' if product == 'gecko' or data.testing else ''}
|
||||
${'font-kerning' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-alternates' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-east-asian' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-ligatures' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-numeric' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-position' if product == 'gecko' or data.testing else ''}
|
||||
${'font-language-override' if product == 'gecko' or data.testing else ''}
|
||||
${'font-feature-settings' if product == 'gecko' or data.testing else ''}"
|
||||
${'font-size-adjust' if product == 'gecko' else ''}
|
||||
${'font-kerning' if product == 'gecko' else ''}
|
||||
${'font-variant-alternates' if product == 'gecko' else ''}
|
||||
${'font-variant-east-asian' if product == 'gecko' else ''}
|
||||
${'font-variant-ligatures' if product == 'gecko' else ''}
|
||||
${'font-variant-numeric' if product == 'gecko' else ''}
|
||||
${'font-variant-position' if product == 'gecko' else ''}
|
||||
${'font-language-override' if product == 'gecko' else ''}
|
||||
${'font-feature-settings' if product == 'gecko' else ''}"
|
||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
||||
use parser::Parse;
|
||||
use properties::longhands::{font_family, font_style, font_weight, font_stretch};
|
||||
|
@ -31,7 +31,7 @@
|
|||
variant_ligatures variant_numeric \
|
||||
variant_position feature_settings".split()
|
||||
%>
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
% for prop in gecko_sub_properties:
|
||||
use properties::longhands::font_${prop};
|
||||
% endfor
|
||||
|
@ -112,7 +112,7 @@
|
|||
% endfor
|
||||
line_height: line_height.unwrap_or(LineHeight::normal()),
|
||||
font_family: family,
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
% for name in gecko_sub_properties:
|
||||
font_${name}: font_${name}::get_initial_specified_value(),
|
||||
% endfor
|
||||
|
@ -146,7 +146,7 @@
|
|||
}
|
||||
% endif
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
% for name in gecko_sub_properties:
|
||||
if self.font_${name} != &font_${name}::get_initial_specified_value() {
|
||||
return Ok(());
|
||||
|
@ -226,16 +226,16 @@
|
|||
|
||||
<%helpers:shorthand name="font-variant"
|
||||
sub_properties="font-variant-caps
|
||||
${'font-variant-alternates' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-east-asian' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-ligatures' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-numeric' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-position' if product == 'gecko' or data.testing else ''}"
|
||||
${'font-variant-alternates' if product == 'gecko' else ''}
|
||||
${'font-variant-east-asian' if product == 'gecko' else ''}
|
||||
${'font-variant-ligatures' if product == 'gecko' else ''}
|
||||
${'font-variant-numeric' if product == 'gecko' else ''}
|
||||
${'font-variant-position' if product == 'gecko' else ''}"
|
||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-variant">
|
||||
<% gecko_sub_properties = "alternates east_asian ligatures numeric position".split() %>
|
||||
<%
|
||||
sub_properties = ["caps"]
|
||||
if product == "gecko" or data.testing:
|
||||
if product == "gecko":
|
||||
sub_properties += gecko_sub_properties
|
||||
%>
|
||||
|
||||
|
@ -254,7 +254,7 @@
|
|||
} else if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
// The 'none' value sets 'font-variant-ligatures' to 'none' and resets all other sub properties
|
||||
// to their initial value.
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
ligatures = Some(font_variant_ligatures::get_none_specified_value());
|
||||
% endif
|
||||
} else {
|
||||
|
@ -294,7 +294,7 @@
|
|||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
|
||||
let has_none_ligatures =
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
self.font_variant_ligatures == &font_variant_ligatures::get_none_specified_value();
|
||||
% else:
|
||||
false;
|
||||
|
|
|
@ -239,7 +239,6 @@
|
|||
<%helpers:shorthand name="grid-template"
|
||||
sub_properties="grid-template-rows grid-template-columns grid-template-areas"
|
||||
spec="https://drafts.csswg.org/css-grid/#propdef-grid-template"
|
||||
disable_when_testing="True"
|
||||
products="gecko">
|
||||
use parser::Parse;
|
||||
use properties::longhands::grid_template_areas::TemplateAreas;
|
||||
|
@ -452,7 +451,6 @@
|
|||
grid-auto-rows grid-auto-columns grid-row-gap grid-column-gap
|
||||
grid-auto-flow"
|
||||
spec="https://drafts.csswg.org/css-grid/#propdef-grid"
|
||||
disable_when_testing="True"
|
||||
products="gecko">
|
||||
use parser::Parse;
|
||||
use properties::longhands::{grid_auto_columns, grid_auto_rows, grid_auto_flow};
|
||||
|
@ -612,7 +610,7 @@
|
|||
|
||||
<%helpers:shorthand name="place-content" sub_properties="align-content justify-content"
|
||||
spec="https://drafts.csswg.org/css-align/#propdef-place-content"
|
||||
products="gecko" disable_when_testing="True">
|
||||
products="gecko">
|
||||
use properties::longhands::align_content;
|
||||
use properties::longhands::justify_content;
|
||||
|
||||
|
@ -648,7 +646,7 @@
|
|||
|
||||
<%helpers:shorthand name="place-self" sub_properties="align-self justify-self"
|
||||
spec="https://drafts.csswg.org/css-align/#place-self-property"
|
||||
products="gecko" disable_when_testing="True">
|
||||
products="gecko">
|
||||
use values::specified::align::AlignJustifySelf;
|
||||
use parser::Parse;
|
||||
|
||||
|
@ -684,7 +682,7 @@
|
|||
|
||||
<%helpers:shorthand name="place-items" sub_properties="align-items justify-items"
|
||||
spec="https://drafts.csswg.org/css-align/#place-items-property"
|
||||
products="gecko" disable_when_testing="True">
|
||||
products="gecko">
|
||||
use values::specified::align::{AlignItems, JustifyItems};
|
||||
use parser::Parse;
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
<%helpers:shorthand name="text-decoration"
|
||||
sub_properties="text-decoration-line
|
||||
${' text-decoration-style text-decoration-color' if product == 'gecko' or data.testing else ''}"
|
||||
${' text-decoration-style text-decoration-color' if product == 'gecko' else ''}"
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration">
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
use values::specified;
|
||||
use properties::longhands::{text_decoration_line, text_decoration_style, text_decoration_color};
|
||||
% else:
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Longhands, ParseError<'i>> {
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
let (mut line, mut style, mut color, mut any) = (None, None, None, false);
|
||||
% else:
|
||||
let (mut line, mut any) = (None, false);
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
parse_component!(line, text_decoration_line);
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
parse_component!(style, text_decoration_style);
|
||||
parse_component!(color, text_decoration_color);
|
||||
% endif
|
||||
|
@ -54,7 +54,7 @@
|
|||
Ok(expanded! {
|
||||
text_decoration_line: unwrap_or_initial!(text_decoration_line, line),
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
text_decoration_style: unwrap_or_initial!(text_decoration_style, style),
|
||||
text_decoration_color: unwrap_or_initial!(text_decoration_color, color),
|
||||
% endif
|
||||
|
@ -65,7 +65,7 @@
|
|||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
self.text_decoration_line.to_css(dest)?;
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% if product == "gecko":
|
||||
if self.text_decoration_style != &text_decoration_style::SpecifiedValue::solid {
|
||||
dest.write_str(" ")?;
|
||||
self.text_decoration_style.to_css(dest)?;
|
||||
|
|
|
@ -953,11 +953,10 @@ impl StrongRuleNode {
|
|||
// That's... suspicious, but it's fine if it happens for the rule tree
|
||||
// case, so just don't crash in the case we're doing the final GC in
|
||||
// script.
|
||||
if !cfg!(feature = "testing") {
|
||||
debug_assert!(!thread_state::get().is_worker() &&
|
||||
(thread_state::get().is_layout() ||
|
||||
thread_state::get().is_script()));
|
||||
}
|
||||
|
||||
debug_assert!(!thread_state::get().is_worker() &&
|
||||
(thread_state::get().is_layout() ||
|
||||
thread_state::get().is_script()));
|
||||
|
||||
let current = me.next_free.load(Ordering::Relaxed);
|
||||
if current == FREE_LIST_SENTINEL {
|
||||
|
|
|
@ -359,7 +359,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
|||
Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace(location)))
|
||||
},
|
||||
"font-feature-values" => {
|
||||
if !cfg!(feature = "gecko") && !cfg!(feature = "testing") {
|
||||
if !cfg!(feature = "gecko") {
|
||||
// Support for this rule is not fully implemented in Servo yet.
|
||||
return Err(StyleParseError::UnsupportedAtRule(name.clone()).into())
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ crate-type = ["staticlib", "rlib"]
|
|||
|
||||
[features]
|
||||
bindgen = ["style/use_bindgen"]
|
||||
testing = ["style/testing"]
|
||||
gecko_debug = ["style/gecko_debug"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -32,7 +32,6 @@ default = ["webdriver", "max_log_level"]
|
|||
max_log_level = ["log/release_max_level_info"]
|
||||
webdriver = ["libservo/webdriver_server"]
|
||||
energy-profiling = ["libservo/energy-profiling"]
|
||||
testing = ["libservo/testing"]
|
||||
debugmozjs = ["libservo/debugmozjs"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -257,12 +257,6 @@ class MachCommands(CommandBase):
|
|||
|
||||
packages.discard('stylo')
|
||||
|
||||
has_style = True
|
||||
try:
|
||||
packages.remove('style')
|
||||
except KeyError:
|
||||
has_style = False
|
||||
|
||||
env = self.build_env()
|
||||
env["RUST_BACKTRACE"] = "1"
|
||||
|
||||
|
@ -290,20 +284,6 @@ class MachCommands(CommandBase):
|
|||
if err is not 0:
|
||||
return err
|
||||
|
||||
# Run style tests with the testing feature
|
||||
if has_style:
|
||||
args = ["cargo", "bench" if bench else "test", "-p", "style_tests", "--features"]
|
||||
if features:
|
||||
args += ["%s" % ' '.join(features + ["testing"])]
|
||||
else:
|
||||
args += ["testing"]
|
||||
|
||||
args += test_patterns
|
||||
|
||||
if nocapture:
|
||||
args += ["--", "--nocapture"]
|
||||
return call(args, env=env, cwd=self.servo_crate())
|
||||
|
||||
@Command('test-stylo',
|
||||
description='Run stylo unit tests',
|
||||
category='testing')
|
||||
|
@ -319,7 +299,7 @@ class MachCommands(CommandBase):
|
|||
env["RUST_BACKTRACE"] = "1"
|
||||
env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
|
||||
|
||||
args = (["cargo", "test", "-p", "stylo_tests", "--features", "testing"] +
|
||||
args = (["cargo", "test", "-p", "stylo_tests"] +
|
||||
(["--release"] if release else []) + (test_name or []))
|
||||
with cd(path.join("ports", "geckolib")):
|
||||
return call(args, env=env)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#![feature(plugin, test)]
|
||||
|
||||
extern crate app_units;
|
||||
extern crate byteorder;
|
||||
extern crate cssparser;
|
||||
extern crate euclid;
|
||||
#[macro_use] extern crate html5ever;
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
/* 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 parsing::parse;
|
||||
use style::parser::Parse;
|
||||
use style::values::specified::basic_shape::*;
|
||||
use style_traits::ToCss;
|
||||
|
||||
// Ensure that basic-shape sub-functions parse as both basic shapes
|
||||
// and their individual components
|
||||
macro_rules! assert_roundtrip_basicshape {
|
||||
($fun:expr, $input:expr, $output:expr) => {
|
||||
assert_roundtrip_with_context!($fun, $input, $output);
|
||||
assert_roundtrip_with_context!(BasicShape::parse, $input, $output);
|
||||
};
|
||||
($fun:expr, $input:expr) => {
|
||||
assert_roundtrip_basicshape!($fun, $input, $input);
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inset() {
|
||||
assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px)");
|
||||
assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px 20%)");
|
||||
|
||||
assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px round 10px)");
|
||||
assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px round 10px 20px 30px 40px)");
|
||||
assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px round 10px 20px 30px 40px / 1px 2px 3px 4px)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circle() {
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at center)", "circle(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle()", "circle(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at left bottom)", "circle(at 0% 100%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at bottom left)", "circle(at 0% 100%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at top left)", "circle(at 0% 0%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at center left)", "circle(at 0% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at left center)", "circle(at 0% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at top center)", "circle(at 50% 0%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at center top)", "circle(at 50% 0%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at 40% top)", "circle(at 40% 0%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at 10px 100px)", "circle(at 10px 100px)");
|
||||
// closest-side is omitted, because it is the default
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(closest-side at center)", "circle(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(farthest-side at center)",
|
||||
"circle(farthest-side at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(10px)",
|
||||
"circle(10px at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(20px at center)", "circle(20px at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(calc(1px + 50%) at center)",
|
||||
"circle(calc(1px + 50%) at 50% 50%)");
|
||||
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at right 5px bottom 10px)",
|
||||
"circle(at right 5px bottom 10px)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at bottom 5px right 10px)",
|
||||
"circle(at right 10px bottom 5px)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at right 5% top 0px)",
|
||||
"circle(at 95% 0%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at right 5% bottom 0px)",
|
||||
"circle(at 95% 100%)");
|
||||
assert_roundtrip_basicshape!(Circle::parse, "circle(at right 5% bottom 1px)",
|
||||
"circle(at left 95% bottom 1px)");
|
||||
|
||||
assert!(parse(Circle::parse, "circle(at 5% bottom 1px)").is_err());
|
||||
assert!(parse(Circle::parse, "circle(at top 40%)").is_err());
|
||||
assert!(parse(Circle::parse, "circle(-10px)").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipse() {
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(at center)", "ellipse(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse()", "ellipse(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(at left bottom)", "ellipse(at 0% 100%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(at bottom left)", "ellipse(at 0% 100%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(at 10px 100px)", "ellipse(at 10px 100px)");
|
||||
// closest-side is omitted, because it is the default
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(closest-side closest-side at center)",
|
||||
"ellipse(at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(farthest-side closest-side at center)",
|
||||
"ellipse(farthest-side closest-side at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(20px 10% at center)", "ellipse(20px 10% at 50% 50%)");
|
||||
assert_roundtrip_basicshape!(Ellipse::parse, "ellipse(calc(1px + 50%) 10px at center)",
|
||||
"ellipse(calc(1px + 50%) 10px at 50% 50%)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_polygon() {
|
||||
// surprisingly, polygons are only required to have at least one vertex,
|
||||
// not at least 3
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(10px 10px)", "polygon(10px 10px)");
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(10px 10px, 10px 10px)", "polygon(10px 10px, 10px 10px)");
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(nonzero, 10px 10px, 10px 10px)",
|
||||
"polygon(10px 10px, 10px 10px)");
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(evenodd, 10px 10px, 10px 10px)",
|
||||
"polygon(evenodd, 10px 10px, 10px 10px)");
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(evenodd, 10px 10px, 10px calc(10px + 50%))",
|
||||
"polygon(evenodd, 10px 10px, 10px calc(10px + 50%))");
|
||||
assert_roundtrip_basicshape!(Polygon::parse, "polygon(evenodd, 10px 10px, 10px 10px, 10px 10px, 10px 10px, 10px \
|
||||
10px, 10px 10px, 10px 10px, 10px 10px, 10px 10px, 10px 10px, \
|
||||
10px 10px, 10px 10px, 10px 10px)",
|
||||
"polygon(evenodd, 10px 10px, 10px 10px, 10px 10px, 10px 10px, 10px \
|
||||
10px, 10px 10px, 10px 10px, 10px 10px, 10px 10px, 10px 10px, \
|
||||
10px 10px, 10px 10px, 10px 10px)");
|
||||
|
||||
assert!(parse(Polygon::parse, "polygon()").is_err());
|
||||
}
|
|
@ -5,24 +5,6 @@
|
|||
use parsing::parse;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn test_will_change() {
|
||||
use style::properties::longhands::will_change;
|
||||
|
||||
assert_roundtrip_with_context!(will_change::parse, "auto");
|
||||
assert_roundtrip_with_context!(will_change::parse, "scroll-position");
|
||||
assert_roundtrip_with_context!(will_change::parse, "contents");
|
||||
assert_roundtrip_with_context!(will_change::parse, "transition");
|
||||
assert_roundtrip_with_context!(will_change::parse, "opacity, transform");
|
||||
|
||||
assert!(parse(will_change::parse, "will-change").is_err());
|
||||
assert!(parse(will_change::parse, "all").is_err());
|
||||
assert!(parse(will_change::parse, "none").is_err());
|
||||
assert!(parse(will_change::parse, "contents, auto").is_err());
|
||||
assert!(parse(will_change::parse, "contents, inherit, initial").is_err());
|
||||
assert!(parse(will_change::parse, "transform scroll-position").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transform_translate() {
|
||||
use style::properties::longhands::transform;
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 parsing::parse;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn contain_longhand_should_parse_correctly() {
|
||||
use style::properties::longhands::contain;
|
||||
use style::properties::longhands::contain::SpecifiedValue;
|
||||
|
||||
let none = parse_longhand!(contain, "none");
|
||||
assert_eq!(none, SpecifiedValue::empty());
|
||||
|
||||
let strict = parse_longhand!(contain, "strict");
|
||||
assert_eq!(strict, contain::STRICT | contain::STRICT_BITS);
|
||||
|
||||
let style_paint = parse_longhand!(contain, "style paint");
|
||||
assert_eq!(style_paint, contain::STYLE | contain::PAINT);
|
||||
|
||||
assert_roundtrip_with_context!(contain::parse, "strict");
|
||||
assert_roundtrip_with_context!(contain::parse, "layout style paint");
|
||||
|
||||
// Assert that the `2px` is not consumed, which would trigger parsing failure in real use
|
||||
assert_parser_exhausted!(contain::parse, "layout 2px", false);
|
||||
}
|
|
@ -3,95 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use parsing::parse;
|
||||
use style::properties::longhands::{font_feature_settings, font_weight};
|
||||
use style::properties::longhands::font_feature_settings::SpecifiedValue;
|
||||
use style::values::generics::{FontSettings, FontSettingTag, FontSettingTagInt};
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn font_feature_settings_should_parse_properly() {
|
||||
use byteorder::{ReadBytesExt, BigEndian};
|
||||
use std::io::Cursor;
|
||||
|
||||
let normal = parse_longhand!(font_feature_settings, "normal");
|
||||
let normal_computed = SpecifiedValue::Value(FontSettings::Normal);
|
||||
assert_eq!(normal, normal_computed);
|
||||
|
||||
let mut a_d_bytes = Cursor::new(b"abcd");
|
||||
let mut e_h_bytes = Cursor::new(b"efgh");
|
||||
|
||||
let abcd = a_d_bytes.read_u32::<BigEndian>().unwrap();
|
||||
let efgh = e_h_bytes.read_u32::<BigEndian>().unwrap();
|
||||
|
||||
let on = parse_longhand!(font_feature_settings, "\"abcd\" on");
|
||||
let on_computed = SpecifiedValue::Value(FontSettings::Tag(vec![
|
||||
FontSettingTag { tag: abcd, value: FontSettingTagInt(1) }
|
||||
]));
|
||||
assert_eq!(on, on_computed);
|
||||
|
||||
let off = parse_longhand!(font_feature_settings, "\"abcd\" off");
|
||||
let off_computed = SpecifiedValue::Value(FontSettings::Tag(vec![
|
||||
FontSettingTag { tag: abcd, value: FontSettingTagInt(0) }
|
||||
]));
|
||||
assert_eq!(off, off_computed);
|
||||
|
||||
let no_value = parse_longhand!(font_feature_settings, "\"abcd\"");
|
||||
let no_value_computed = SpecifiedValue::Value(FontSettings::Tag(vec![
|
||||
FontSettingTag { tag: abcd, value: FontSettingTagInt(1) }
|
||||
]));
|
||||
assert_eq!(no_value, no_value_computed);
|
||||
|
||||
let pos_integer = parse_longhand!(font_feature_settings, "\"abcd\" 100");
|
||||
let pos_integer_computed = SpecifiedValue::Value(FontSettings::Tag(vec![
|
||||
FontSettingTag { tag: abcd, value: FontSettingTagInt(100) }
|
||||
]));
|
||||
assert_eq!(pos_integer, pos_integer_computed);
|
||||
|
||||
let multiple = parse_longhand!(font_feature_settings, "\"abcd\" off, \"efgh\"");
|
||||
let multiple_computed = SpecifiedValue::Value(FontSettings::Tag(vec![
|
||||
FontSettingTag { tag: abcd, value: FontSettingTagInt(0) },
|
||||
FontSettingTag { tag: efgh, value: FontSettingTagInt(1) }
|
||||
]));
|
||||
assert_eq!(multiple, multiple_computed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_feature_settings_should_throw_on_bad_input() {
|
||||
assert!(parse(font_feature_settings::parse, "").is_err());
|
||||
assert!(parse(font_feature_settings::parse, "\"abcd\" -1").is_err());
|
||||
assert!(parse(font_feature_settings::parse, "\"abc\"").is_err());
|
||||
assert!(parse(font_feature_settings::parse, "\"abcó\"").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_feature_settings_to_css() {
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "normal");
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "\"abcd\"");
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "\"abcd\" on", "\"abcd\"");
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "\"abcd\" off");
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "\"abcd\" 4");
|
||||
assert_roundtrip_with_context!(font_feature_settings::parse, "\"abcd\", \"efgh\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_language_override_should_parse_properly() {
|
||||
use style::properties::longhands::font_language_override::{self, SpecifiedValue};
|
||||
|
||||
let normal = parse_longhand!(font_language_override, "normal");
|
||||
assert_eq!(normal, SpecifiedValue::Normal);
|
||||
|
||||
let empty_str = parse_longhand!(font_language_override, "\"\"");
|
||||
assert_eq!(empty_str, SpecifiedValue::Override("".to_string()));
|
||||
|
||||
let normal_str = parse_longhand!(font_language_override, "\"normal\"");
|
||||
assert_eq!(normal_str, SpecifiedValue::Override("normal".to_string()));
|
||||
|
||||
let turkic = parse_longhand!(font_language_override, "\"TRK\"");
|
||||
assert_eq!(turkic, SpecifiedValue::Override("TRK".to_string()));
|
||||
|
||||
let danish = parse_longhand!(font_language_override, "\"DAN\"");
|
||||
assert_eq!(danish, SpecifiedValue::Override("DAN".to_string()));
|
||||
}
|
||||
use style::properties::longhands::font_weight;
|
||||
|
||||
#[test]
|
||||
fn font_weight_keyword_should_preserve_keyword() {
|
||||
|
@ -103,11 +15,3 @@ fn font_weight_keyword_should_preserve_keyword() {
|
|||
let result = parse(font_weight::parse, "bold").unwrap();
|
||||
assert_eq!(result, SpecifiedValue::Bold);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn font_language_override_should_fail_on_empty_str() {
|
||||
use style::properties::longhands::font_language_override;
|
||||
|
||||
parse_longhand!(font_language_override, "");
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 parsing::parse;
|
||||
|
||||
#[test]
|
||||
fn image_orientation_longhand_should_parse_properly() {
|
||||
use style::properties::longhands::image_orientation;
|
||||
use style::properties::longhands::image_orientation::SpecifiedValue;
|
||||
use style::values::specified::Angle;
|
||||
|
||||
let from_image = parse_longhand!(image_orientation, "from-image");
|
||||
assert_eq!(from_image, SpecifiedValue { angle: None, flipped: false });
|
||||
|
||||
let flip = parse_longhand!(image_orientation, "flip");
|
||||
assert_eq!(flip, SpecifiedValue { angle: Some(Angle::zero()), flipped: true });
|
||||
|
||||
let zero = parse_longhand!(image_orientation, "0deg");
|
||||
assert_eq!(zero, SpecifiedValue { angle: Some(Angle::zero()), flipped: false });
|
||||
|
||||
let negative_rad = parse_longhand!(image_orientation, "-1rad");
|
||||
assert_eq!(negative_rad, SpecifiedValue { angle: Some(Angle::from_radians(-1.0, false)), flipped: false });
|
||||
|
||||
let flip_with_180 = parse_longhand!(image_orientation, "180deg flip");
|
||||
assert_eq!(flip_with_180, SpecifiedValue { angle: Some(Angle::from_degrees(180.0, false)), flipped: true });
|
||||
}
|
|
@ -27,94 +27,6 @@ fn negative_word_spacing_should_parse_properly() {
|
|||
assert_eq!(negative_value, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_emphasis_style_longhand_should_parse_properly() {
|
||||
use style::properties::longhands::text_emphasis_style;
|
||||
use style::properties::longhands::text_emphasis_style::{ShapeKeyword, SpecifiedValue, KeywordValue};
|
||||
|
||||
let none = parse_longhand!(text_emphasis_style, "none");
|
||||
assert_eq!(none, SpecifiedValue::None);
|
||||
|
||||
let fill = parse_longhand!(text_emphasis_style, "open");
|
||||
let fill_struct = SpecifiedValue::Keyword(KeywordValue::Fill(false));
|
||||
assert_eq!(fill, fill_struct);
|
||||
|
||||
let shape = parse_longhand!(text_emphasis_style, "triangle");
|
||||
let shape_struct = SpecifiedValue::Keyword(KeywordValue::Shape(ShapeKeyword::Triangle));
|
||||
assert_eq!(shape, shape_struct);
|
||||
|
||||
let fill_shape = parse_longhand!(text_emphasis_style, "filled dot");
|
||||
let fill_shape_struct = SpecifiedValue::Keyword(KeywordValue::FillAndShape(true, ShapeKeyword::Dot));
|
||||
assert_eq!(fill_shape, fill_shape_struct);
|
||||
|
||||
let shape_fill = parse_longhand!(text_emphasis_style, "dot filled");
|
||||
let shape_fill_struct = SpecifiedValue::Keyword(KeywordValue::FillAndShape(true, ShapeKeyword::Dot));
|
||||
assert_eq!(shape_fill, shape_fill_struct);
|
||||
|
||||
let a_string = parse_longhand!(text_emphasis_style, "\"a\"");
|
||||
let a_string_struct = SpecifiedValue::String("a".to_string());
|
||||
assert_eq!(a_string, a_string_struct);
|
||||
|
||||
let chinese_string = parse_longhand!(text_emphasis_style, "\"点\"");
|
||||
let chinese_string_struct = SpecifiedValue::String("点".to_string());
|
||||
assert_eq!(chinese_string, chinese_string_struct);
|
||||
|
||||
let unicode_string = parse_longhand!(text_emphasis_style, "\"\\25B2\"");
|
||||
let unicode_string_struct = SpecifiedValue::String("▲".to_string());
|
||||
assert_eq!(unicode_string, unicode_string_struct);
|
||||
|
||||
let devanagari_string = parse_longhand!(text_emphasis_style, "\"षि\"");
|
||||
let devanagari_string_struct = SpecifiedValue::String("षि".to_string());
|
||||
assert_eq!(devanagari_string, devanagari_string_struct);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_text_emphasis_position() {
|
||||
use style::properties::longhands::text_emphasis_position;
|
||||
use style::properties::longhands::text_emphasis_position::{HorizontalWritingModeValue, VerticalWritingModeValue};
|
||||
use style::properties::longhands::text_emphasis_position::SpecifiedValue;
|
||||
|
||||
let over_right = parse_longhand!(text_emphasis_position, "over right");
|
||||
assert_eq!(over_right, SpecifiedValue(HorizontalWritingModeValue::Over, VerticalWritingModeValue::Right));
|
||||
|
||||
let over_left = parse_longhand!(text_emphasis_position, "over left");
|
||||
assert_eq!(over_left, SpecifiedValue(HorizontalWritingModeValue::Over, VerticalWritingModeValue::Left));
|
||||
|
||||
let under_right = parse_longhand!(text_emphasis_position, "under right");
|
||||
assert_eq!(under_right, SpecifiedValue(HorizontalWritingModeValue::Under, VerticalWritingModeValue::Right));
|
||||
|
||||
let under_left = parse_longhand!(text_emphasis_position, "under left");
|
||||
assert_eq!(under_left, SpecifiedValue(HorizontalWritingModeValue::Under, VerticalWritingModeValue::Left));
|
||||
|
||||
let right_over = parse_longhand!(text_emphasis_position, "right over");
|
||||
assert_eq!(right_over, SpecifiedValue(HorizontalWritingModeValue::Over, VerticalWritingModeValue::Right));
|
||||
|
||||
let left_over = parse_longhand!(text_emphasis_position, "left over");
|
||||
assert_eq!(left_over, SpecifiedValue(HorizontalWritingModeValue::Over, VerticalWritingModeValue::Left));
|
||||
|
||||
let right_under = parse_longhand!(text_emphasis_position, "right under");
|
||||
assert_eq!(right_under, SpecifiedValue(HorizontalWritingModeValue::Under, VerticalWritingModeValue::Right));
|
||||
|
||||
let left_under = parse_longhand!(text_emphasis_position, "left under");
|
||||
assert_eq!(left_under, SpecifiedValue(HorizontalWritingModeValue::Under, VerticalWritingModeValue::Left));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn webkit_text_stroke_shorthand_should_parse_properly() {
|
||||
use style::properties::longhands::_webkit_text_stroke_color;
|
||||
use style::properties::longhands::_webkit_text_stroke_width;
|
||||
use style::properties::shorthands::_webkit_text_stroke;
|
||||
|
||||
let result = parse(_webkit_text_stroke::parse_value, "thin red").unwrap();
|
||||
assert_eq!(result._webkit_text_stroke_color, parse_longhand!(_webkit_text_stroke_color, "red"));
|
||||
assert_eq!(result._webkit_text_stroke_width, parse_longhand!(_webkit_text_stroke_width, "thin"));
|
||||
|
||||
// ensure its no longer sensitive to order
|
||||
let result = parse(_webkit_text_stroke::parse_value, "red thin").unwrap();
|
||||
assert_eq!(result._webkit_text_stroke_color, parse_longhand!(_webkit_text_stroke_color, "red"));
|
||||
assert_eq!(result._webkit_text_stroke_width, parse_longhand!(_webkit_text_stroke_width, "thin"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_height_should_return_number_on_plain_zero() {
|
||||
use style::properties::longhands::line_height;
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
/* 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 parsing::parse;
|
||||
use style::properties::longhands::{mask_clip, mask_composite, mask_image, mask_mode};
|
||||
use style::properties::longhands::{mask_origin, mask_position_x, mask_position_y, mask_repeat, mask_size};
|
||||
use style::properties::shorthands::mask;
|
||||
|
||||
#[test]
|
||||
fn mask_shorthand_should_parse_all_available_properties_when_specified() {
|
||||
let input = "url(\"http://servo/test.png\") luminance 7px 4px / 70px 50px repeat-x padding-box border-box subtract";
|
||||
let result = parse(mask::parse_value, input).unwrap();
|
||||
|
||||
assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")"));
|
||||
assert_eq!(result.mask_mode, parse_longhand!(mask_mode, "luminance"));
|
||||
assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px"));
|
||||
assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px"));
|
||||
assert_eq!(result.mask_size, parse_longhand!(mask_size, "70px 50px"));
|
||||
assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat-x"));
|
||||
assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box"));
|
||||
assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "border-box"));
|
||||
assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "subtract"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_shorthand_should_parse_when_some_fields_set() {
|
||||
let result = parse(mask::parse_value, "14px 40px repeat-y").unwrap();
|
||||
|
||||
assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "14px"));
|
||||
assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "40px"));
|
||||
assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat-y"));
|
||||
|
||||
let result = parse(mask::parse_value, "url(\"http://servo/test.png\") repeat add").unwrap();
|
||||
|
||||
assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")"));
|
||||
assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat"));
|
||||
assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "add"));
|
||||
|
||||
let result = parse(mask::parse_value, "intersect").unwrap();
|
||||
|
||||
assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "intersect"));
|
||||
|
||||
let result = parse(mask::parse_value, "url(\"http://servo/test.png\")").unwrap();
|
||||
|
||||
assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_shorthand_should_parse_position_and_size_correctly() {
|
||||
let result = parse(mask::parse_value, "7px 4px").unwrap();
|
||||
|
||||
assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px"));
|
||||
assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px"));
|
||||
|
||||
let result = parse(mask::parse_value, "7px 4px / 30px 20px").unwrap();
|
||||
|
||||
assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px"));
|
||||
assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px"));
|
||||
assert_eq!(result.mask_size, parse_longhand!(mask_size, "30px 20px"));
|
||||
|
||||
assert!(parse(mask::parse_value, "/ 30px 20px").is_err());
|
||||
|
||||
assert!(parse(mask::parse_value, "match-source repeat-x / 30px 20px").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_shorthand_should_parse_origin_and_clip_correctly() {
|
||||
let result = parse(mask::parse_value, "padding-box content-box").unwrap();
|
||||
|
||||
assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box"));
|
||||
assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "content-box"));
|
||||
|
||||
let result = parse(mask::parse_value, "padding-box padding-box").unwrap();
|
||||
|
||||
assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box"));
|
||||
assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "padding-box"));
|
||||
|
||||
let result = parse(mask::parse_value, "padding-box").unwrap();
|
||||
|
||||
assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box"));
|
||||
assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "padding-box"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_shorthand_should_parse_mode_everywhere() {
|
||||
assert!(parse(mask::parse_value, "luminance 7px 4px repeat-x padding-box").is_ok());
|
||||
assert!(parse(mask::parse_value, "alpha").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_repeat_should_parse_shorthand_correctly() {
|
||||
use style::properties::longhands::mask_repeat::single_value::{RepeatKeyword, SpecifiedValue};
|
||||
|
||||
let repeat_x = parse_longhand!(mask_repeat, "repeat-x");
|
||||
assert_eq!(repeat_x, mask_repeat::SpecifiedValue(vec![SpecifiedValue::RepeatX]));
|
||||
|
||||
let repeat_y = parse_longhand!(mask_repeat, "repeat-y");
|
||||
assert_eq!(repeat_y, mask_repeat::SpecifiedValue(vec![SpecifiedValue::RepeatY]));
|
||||
|
||||
let repeat = parse_longhand!(mask_repeat, "repeat");
|
||||
assert_eq!(repeat,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::Repeat, None)]));
|
||||
|
||||
let space = parse_longhand!(mask_repeat, "space");
|
||||
assert_eq!(space,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::Space, None)]));
|
||||
|
||||
let round = parse_longhand!(mask_repeat, "round");
|
||||
assert_eq!(round,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::Round, None)]));
|
||||
|
||||
let no_repeat = parse_longhand!(mask_repeat, "no-repeat");
|
||||
assert_eq!(no_repeat,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::NoRepeat, None)]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_repeat_should_parse_longhand_correctly() {
|
||||
use style::properties::longhands::mask_repeat::single_value::{RepeatKeyword, SpecifiedValue};
|
||||
|
||||
// repeat-x is not available in longhand form.
|
||||
assert!(parse(mask_repeat::parse, "repeat-x no-repeat").is_err());
|
||||
assert!(parse(mask_repeat::parse, "no-repeat repeat-x").is_err());
|
||||
|
||||
// repeat-y is not available in longhand form.
|
||||
assert!(parse(mask_repeat::parse, "repeat-y no-repeat").is_err());
|
||||
assert!(parse(mask_repeat::parse, "no-repeat repeat-y").is_err());
|
||||
|
||||
// Longhand form supports two directions.
|
||||
let no_repeat_and_round = parse_longhand!(mask_repeat, "no-repeat round");
|
||||
assert_eq!(no_repeat_and_round,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::NoRepeat,
|
||||
Some(RepeatKeyword::Round))]));
|
||||
|
||||
// Not three directions.
|
||||
assert!(parse(mask_repeat::parse, "repeat no-repeat round").is_err());
|
||||
|
||||
// Multiple values with mixed shortform and longform should parse.
|
||||
let multiple = parse_longhand!(mask_repeat, "repeat, no-repeat round");
|
||||
assert_eq!(multiple,
|
||||
mask_repeat::SpecifiedValue(vec![SpecifiedValue::Other(RepeatKeyword::Repeat, None),
|
||||
SpecifiedValue::Other(RepeatKeyword::NoRepeat,
|
||||
Some(RepeatKeyword::Round))]));
|
||||
}
|
|
@ -5,17 +5,11 @@
|
|||
//! Tests for parsing and serialization of values/properties
|
||||
|
||||
use cssparser::{Parser, ParserInput};
|
||||
use euclid::ScaleFactor;
|
||||
use euclid::TypedSize2D;
|
||||
use media_queries::CSSErrorReporterTest;
|
||||
use style::context::QuirksMode;
|
||||
use style::font_metrics::ServoMetricsProvider;
|
||||
use style::media_queries::{Device, MediaType};
|
||||
use style::parser::ParserContext;
|
||||
use style::properties::{ComputedValues, StyleBuilder};
|
||||
use style::stylesheets::{CssRuleType, Origin};
|
||||
use style::values::computed::{Context, ToComputedValue};
|
||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError};
|
||||
use style_traits::{PARSING_MODE_DEFAULT, ParseError};
|
||||
|
||||
fn parse<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>>
|
||||
where F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>> {
|
||||
|
@ -45,30 +39,6 @@ where F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>> {
|
|||
parse_input(|context, parser| parser.parse_entirely(|p| f(context, p)), input)
|
||||
}
|
||||
|
||||
fn assert_computed_serialization<C, F, T>(f: F, input: &'static str, output: &str)
|
||||
where F: for<'t> Fn(&ParserContext, &mut Parser<'static, 't>) -> Result<T, ParseError<'static>>,
|
||||
T: ToComputedValue<ComputedValue=C>, C: ToCss
|
||||
{
|
||||
let viewport_size = TypedSize2D::new(0., 0.);
|
||||
let initial_style = ComputedValues::initial_values();
|
||||
let device = Device::new(MediaType::Screen, viewport_size, ScaleFactor::new(1.0));
|
||||
|
||||
let context = Context {
|
||||
is_root_element: true,
|
||||
builder: StyleBuilder::for_derived_style(&device, initial_style, None, None),
|
||||
cached_system_font: None,
|
||||
font_metrics_provider: &ServoMetricsProvider,
|
||||
in_media_query: false,
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
for_smil_animation: false,
|
||||
};
|
||||
|
||||
let parsed = parse(f, input).unwrap();
|
||||
let computed = parsed.to_computed_value(&context);
|
||||
let serialized = ToCss::to_css_string(&computed);
|
||||
assert_eq!(serialized, output);
|
||||
}
|
||||
|
||||
// This is a macro so that the file/line information
|
||||
// is preserved in the panic
|
||||
macro_rules! assert_roundtrip_with_context {
|
||||
|
@ -137,26 +107,20 @@ macro_rules! parse_longhand {
|
|||
|
||||
mod animation;
|
||||
mod background;
|
||||
mod basic_shape;
|
||||
mod border;
|
||||
mod box_;
|
||||
mod column;
|
||||
mod containment;
|
||||
mod effects;
|
||||
mod font;
|
||||
mod image;
|
||||
mod inherited_box;
|
||||
mod inherited_text;
|
||||
mod length;
|
||||
mod mask;
|
||||
mod outline;
|
||||
mod position;
|
||||
mod selectors;
|
||||
mod supports;
|
||||
mod text;
|
||||
mod text_overflow;
|
||||
mod transition_duration;
|
||||
mod transition_property;
|
||||
mod transition_timing_function;
|
||||
mod ui;
|
||||
mod value;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 parsing::{assert_computed_serialization, parse, parse_entirely};
|
||||
use parsing::{parse, parse_entirely};
|
||||
use style::parser::Parse;
|
||||
use style::values::specified::position::*;
|
||||
use style_traits::ToCss;
|
||||
|
@ -144,105 +144,3 @@ fn test_vertical_position() {
|
|||
assert!(parse(VerticalPosition::parse, "y-end").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grid_auto_flow() {
|
||||
use style::properties::longhands::grid_auto_flow;
|
||||
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "row dense", "row dense");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "dense row", "row dense");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "column dense", "column dense");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "dense column", "column dense");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "dense", "row dense");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "row", "row");
|
||||
assert_roundtrip_with_context!(grid_auto_flow::parse, "column", "column");
|
||||
|
||||
// Neither row, column or dense can be repeated
|
||||
assert!(parse(grid_auto_flow::parse, "dense dense").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "row row").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "column column").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "row dense dense").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "column dense dense").is_err());
|
||||
|
||||
// Only row, column, dense idents are allowed
|
||||
assert!(parse(grid_auto_flow::parse, "dense 1").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "column 'dense'").is_err());
|
||||
assert!(parse(grid_auto_flow::parse, "column 2px dense").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grid_auto_rows_columns() {
|
||||
use style::properties::longhands::grid_auto_rows;
|
||||
|
||||
// the grammar is <track-size>+ but gecko supports only a single value, so we've clamped ourselves
|
||||
assert_roundtrip_with_context!(grid_auto_rows::parse, "55%");
|
||||
assert_roundtrip_with_context!(grid_auto_rows::parse, "0.5fr");
|
||||
assert_roundtrip_with_context!(grid_auto_rows::parse, "fit-content(11%)");
|
||||
// only <inflexible-breadth> is allowed in first arg of minmax
|
||||
assert!(parse(grid_auto_rows::parse, "minmax(1fr, max-content)").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grid_template_rows_columns() {
|
||||
use style::properties::longhands::grid_template_rows;
|
||||
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse, "none"); // none keyword
|
||||
// <track-size>{2} with `<track-breadth> minmax(<inflexible-breadth>, <track-breadth>)`
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse, "1fr minmax(min-content, 1fr)");
|
||||
// <track-size> with <track-breadth> as <length-percentage>
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse, "calc(4em + 5px)");
|
||||
// <track-size> with <length> followed by <track-repeat> with `<track-size>{3}` (<flex>, auto, minmax)
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse,
|
||||
"10px repeat(2, 1fr auto minmax(200px, 1fr))",
|
||||
"10px 1fr auto minmax(200px, 1fr) 1fr auto minmax(200px, 1fr)");
|
||||
// <track-repeat> with `<track-size> <line-names>` followed by <track-size>
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse,
|
||||
"repeat(2, 10px [col-start] 250px [col-end]) 10px",
|
||||
"10px [col-start] 250px [col-end] 10px [col-start] 250px [col-end] 10px");
|
||||
// mixture of <track-size>, <track-repeat> and <line-names>
|
||||
assert_roundtrip_with_context!(grid_template_rows::parse,
|
||||
"[a] auto [b] minmax(min-content, 1fr) [b c d] repeat(2, 40px [e] 30px) [i]",
|
||||
"[a] auto [b] minmax(min-content, 1fr) [b c d] 40px [e] 30px 40px [e] 30px [i]");
|
||||
assert!(parse(grid_template_rows::parse, "subgrid").is_ok());
|
||||
|
||||
// no span allowed in <line-names>
|
||||
assert!(parse(grid_template_rows::parse, "[a span] 10px").is_err());
|
||||
// <track-list> needs at least one <track-size> | <track-repeat>
|
||||
assert!(parse(grid_template_rows::parse, "[a b c]").is_err());
|
||||
// at least one argument of <fixed-size> should be a <fixed-breadth> (i.e., <length-percentage>)
|
||||
assert!(parse(grid_template_rows::parse, "[a b] repeat(auto-fill, 50px) minmax(auto, 1fr)").is_err());
|
||||
// fit-content is not a <fixed-size>
|
||||
assert!(parse(grid_template_rows::parse, "[a b] repeat(auto-fill, fit-content(20%))").is_err());
|
||||
// <auto-track-list> only allows <fixed-size> | <fixed-repeat>
|
||||
assert!(parse(grid_template_rows::parse, "[a] repeat(2, auto) repeat(auto-fill, 10px)").is_err());
|
||||
// only <inflexible-breadth> allowed in <auto-track-repeat>
|
||||
assert!(parse(grid_template_rows::parse, "[a] repeat(auto-fill, 1fr)").is_err());
|
||||
// <auto-track-repeat> is allowed only once
|
||||
assert!(parse(grid_template_rows::parse, "[a] repeat(auto-fit, [b] 8px) [c] repeat(auto-fill, [c] 8px)").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_computed_grid_template_rows_colums() {
|
||||
use style::properties::longhands::grid_template_rows;
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"[a] repeat(calc(1 + 1), [b] auto)", "[a b] auto [b] auto");
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"[a] repeat(2, [b c] auto [e] auto [d])",
|
||||
"[a b c] auto [e] auto [d b c] auto [e] auto [d]");
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"[a] 50px [b] 10% [b c d] repeat(2, [e] 40px [f]) [g] repeat(auto-fill, [h i] 20px [j]) [k] 10px [l]",
|
||||
"[a] 50px [b] 10% [b c d e] 40px [f e] 40px [f g] repeat(auto-fill, [h i] 20px [j]) [k] 10px [l]");
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"10px repeat(2, 1fr auto minmax(200px, 1fr))",
|
||||
"10px 1fr auto minmax(200px, 1fr) 1fr auto minmax(200px, 1fr)");
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"subgrid [a] [] repeat(auto-fill, [])", "subgrid [a] [] repeat(auto-fill, [])");
|
||||
|
||||
assert_computed_serialization(grid_template_rows::parse,
|
||||
"subgrid [a] [b] repeat(2, [c d] [] [e]) [] repeat(auto-fill, [])",
|
||||
"subgrid [a] [b] [c d] [] [e] [c d] [] [e] [] repeat(auto-fill, [])");
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/* 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 parsing::parse;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn initial_letter_should_be_parsed_correctly() {
|
||||
use style::properties::longhands::initial_letter;
|
||||
|
||||
assert_roundtrip_with_context!(initial_letter::parse, "1.5");
|
||||
assert_roundtrip_with_context!(initial_letter::parse, "1.5 3");
|
||||
assert_roundtrip_with_context!(initial_letter::parse, "normal");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initial_letter_doesnt_parse_invalid_input() {
|
||||
use style::properties::longhands::initial_letter;
|
||||
|
||||
assert!(parse(initial_letter::parse, "1.5x 5").is_err());
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 cssparser::RGBA;
|
||||
use parsing::parse;
|
||||
use style::values::{Auto, Either};
|
||||
use style::values::specified::Color;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[test]
|
||||
fn test_moz_user_select() {
|
||||
use style::properties::longhands::_moz_user_select;
|
||||
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "auto");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "text");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "none");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "element");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "elements");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "toggle");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "tri-state");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "-moz-all");
|
||||
assert_roundtrip_with_context!(_moz_user_select::parse, "-moz-text");
|
||||
assert_eq!(parse(_moz_user_select::parse, "-moz-none"),
|
||||
Ok(_moz_user_select::SpecifiedValue::none));
|
||||
|
||||
assert!(parse(_moz_user_select::parse, "potato").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_caret_color() {
|
||||
use style::properties::longhands::caret_color;
|
||||
|
||||
let auto = parse_longhand!(caret_color, "auto");
|
||||
assert_eq!(auto, Either::Second(Auto));
|
||||
|
||||
let blue_color = Color::Numeric {
|
||||
parsed: RGBA {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 255,
|
||||
alpha: 255,
|
||||
},
|
||||
authored: Some(String::from("blue").into_boxed_str()),
|
||||
};
|
||||
|
||||
let color = parse_longhand!(caret_color, "blue");
|
||||
assert_eq!(color, Either::First(blue_color));
|
||||
}
|
|
@ -4,14 +4,13 @@
|
|||
|
||||
use properties::{parse, parse_input};
|
||||
use style::computed_values::display::T::inline_block;
|
||||
use style::properties::{PropertyDeclaration, Importance, PropertyId};
|
||||
use style::properties::{PropertyDeclaration, Importance};
|
||||
use style::properties::parse_property_declaration_list;
|
||||
use style::values::{CustomIdent, RGBA, Auto};
|
||||
use style::values::generics::flex::FlexBasis;
|
||||
use style::values::specified::{BorderStyle, BorderSideWidth, Color};
|
||||
use style::values::specified::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
use style::values::specified::{NoCalcLength, PositionComponent};
|
||||
use style::values::specified::position::Y;
|
||||
use style::values::specified::NoCalcLength;
|
||||
use style::values::specified::url::SpecifiedUrl;
|
||||
use style_traits::ToCss;
|
||||
use stylesheets::block_from;
|
||||
|
@ -98,44 +97,6 @@ mod shorthand_serialization {
|
|||
}
|
||||
}
|
||||
|
||||
mod text {
|
||||
use style::properties::longhands::text_decoration_line as TextDecorationLine;
|
||||
use style::properties::longhands::text_decoration_style::SpecifiedValue as TextDecorationStyle;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn text_decoration_should_show_all_properties_when_set() {
|
||||
let mut properties = Vec::new();
|
||||
|
||||
let line = TextDecorationLine::OVERLINE;
|
||||
let style = TextDecorationStyle::dotted;
|
||||
let color = RGBA::new(128, 0, 128, 255).into();
|
||||
|
||||
properties.push(PropertyDeclaration::TextDecorationLine(line));
|
||||
properties.push(PropertyDeclaration::TextDecorationStyle(style));
|
||||
properties.push(PropertyDeclaration::TextDecorationColor(color));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(serialization, "text-decoration: overline dotted rgb(128, 0, 128);");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_decoration_should_not_serialize_initial_style_value() {
|
||||
let mut properties = Vec::new();
|
||||
|
||||
let line = TextDecorationLine::UNDERLINE;
|
||||
let style = TextDecorationStyle::solid;
|
||||
let color = Color::currentcolor();
|
||||
|
||||
properties.push(PropertyDeclaration::TextDecorationLine(line));
|
||||
properties.push(PropertyDeclaration::TextDecorationStyle(style));
|
||||
properties.push(PropertyDeclaration::TextDecorationColor(color));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(serialization, "text-decoration: underline;");
|
||||
}
|
||||
}
|
||||
|
||||
mod four_sides_shorthands {
|
||||
pub use super::*;
|
||||
|
||||
|
@ -592,60 +553,6 @@ mod shorthand_serialization {
|
|||
assert_eq!(serialization, "flex-flow: row wrap;");
|
||||
}
|
||||
|
||||
mod font {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn font_should_serialize_to_empty_if_there_are_nondefault_subproperties() {
|
||||
// Test with non-default font-kerning value
|
||||
let block_text = "font-style: italic; \
|
||||
font-variant: normal; \
|
||||
font-weight: bolder; \
|
||||
font-stretch: expanded; \
|
||||
font-size: 4px; \
|
||||
line-height: 3; \
|
||||
font-family: serif; \
|
||||
font-size-adjust: none; \
|
||||
font-variant-caps: normal; \
|
||||
font-variant-position: normal; \
|
||||
font-language-override: normal; \
|
||||
font-kerning: none";
|
||||
|
||||
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
|
||||
|
||||
let mut s = String::new();
|
||||
let id = PropertyId::parse("font".into()).unwrap();
|
||||
let x = block.property_value_to_css(&id, &mut s);
|
||||
|
||||
assert_eq!(x.is_ok(), true);
|
||||
assert_eq!(s, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_should_serialize_all_available_properties() {
|
||||
let block_text = "font-style: italic; \
|
||||
font-variant: normal; \
|
||||
font-weight: bolder; \
|
||||
font-stretch: expanded; \
|
||||
font-size: 4px; \
|
||||
line-height: 3; \
|
||||
font-family: serif; \
|
||||
font-size-adjust: none; \
|
||||
font-kerning: auto; \
|
||||
font-variant-caps: normal; \
|
||||
font-variant-position: normal; \
|
||||
font-language-override: normal; \
|
||||
font-feature-settings: normal;";
|
||||
|
||||
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
|
||||
|
||||
let serialization = block.to_css_string();
|
||||
|
||||
assert_eq!(serialization, "font: italic normal bolder expanded 4px/3 serif;");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mod background {
|
||||
use super::*;
|
||||
|
||||
|
@ -770,220 +677,6 @@ mod shorthand_serialization {
|
|||
}
|
||||
}
|
||||
|
||||
mod mask {
|
||||
use style::properties::longhands::mask_clip as clip;
|
||||
use style::properties::longhands::mask_composite as composite;
|
||||
use style::properties::longhands::mask_image as image;
|
||||
use style::properties::longhands::mask_mode as mode;
|
||||
use style::properties::longhands::mask_origin as origin;
|
||||
use style::properties::longhands::mask_position_x as position_x;
|
||||
use style::properties::longhands::mask_position_y as position_y;
|
||||
use style::properties::longhands::mask_repeat as repeat;
|
||||
use style::properties::longhands::mask_size as size;
|
||||
use style::values::Either;
|
||||
use style::values::generics::background::BackgroundSize;
|
||||
use style::values::generics::image::Image;
|
||||
use super::*;
|
||||
|
||||
macro_rules! single_vec_value_typedef {
|
||||
($name:ident, $path:expr) => {
|
||||
$name::SpecifiedValue(
|
||||
vec![$path]
|
||||
)
|
||||
};
|
||||
}
|
||||
macro_rules! single_vec_keyword_value {
|
||||
($name:ident, $kw:ident) => {
|
||||
$name::SpecifiedValue(
|
||||
vec![$name::single_value::SpecifiedValue::$kw]
|
||||
)
|
||||
};
|
||||
}
|
||||
macro_rules! single_vec_variant_value {
|
||||
($name:ident, $variant:expr) => {
|
||||
$name::SpecifiedValue(
|
||||
vec![$variant]
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_should_serialize_all_available_properties_when_specified() {
|
||||
let mut properties = Vec::new();
|
||||
|
||||
let image = single_vec_value_typedef!(
|
||||
image,
|
||||
Either::Second(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png")))
|
||||
);
|
||||
|
||||
let mode = single_vec_keyword_value!(mode, luminance);
|
||||
|
||||
let position_x = single_vec_value_typedef!(position_x,
|
||||
PositionComponent::Length(LengthOrPercentage::Length(NoCalcLength::from_px(7f32)))
|
||||
);
|
||||
let position_y = single_vec_value_typedef!(position_y,
|
||||
PositionComponent::Side(
|
||||
Y::Bottom,
|
||||
Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))),
|
||||
)
|
||||
);
|
||||
|
||||
let size = single_vec_variant_value!(
|
||||
size,
|
||||
BackgroundSize::Explicit {
|
||||
width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)),
|
||||
height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)),
|
||||
}
|
||||
);
|
||||
|
||||
let repeat = single_vec_keyword_value!(repeat, RepeatX);
|
||||
let origin = single_vec_keyword_value!(origin, padding_box);
|
||||
let clip = single_vec_keyword_value!(clip, border_box);
|
||||
let composite = single_vec_keyword_value!(composite, subtract);
|
||||
|
||||
properties.push(PropertyDeclaration::MaskImage(image));
|
||||
properties.push(PropertyDeclaration::MaskMode(mode));
|
||||
properties.push(PropertyDeclaration::MaskPositionX(position_x));
|
||||
properties.push(PropertyDeclaration::MaskPositionY(position_y));
|
||||
properties.push(PropertyDeclaration::MaskSize(size));
|
||||
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
||||
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
||||
properties.push(PropertyDeclaration::MaskClip(clip));
|
||||
properties.push(PropertyDeclaration::MaskComposite(composite));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(
|
||||
serialization,
|
||||
"mask: url(\"http://servo/test.png\") luminance left 7px bottom 4px / 70px 50px \
|
||||
repeat-x padding-box border-box subtract;"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_should_combine_origin_and_clip_properties_when_equal() {
|
||||
let mut properties = Vec::new();
|
||||
|
||||
let image = single_vec_value_typedef!(
|
||||
image,
|
||||
Either::Second(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png")))
|
||||
);
|
||||
|
||||
let mode = single_vec_keyword_value!(mode, luminance);
|
||||
|
||||
let position_x = single_vec_value_typedef!(position_x,
|
||||
PositionComponent::Length(LengthOrPercentage::Length(NoCalcLength::from_px(7f32)))
|
||||
);
|
||||
|
||||
let position_y = single_vec_value_typedef!(position_y,
|
||||
PositionComponent::Length(LengthOrPercentage::Length(NoCalcLength::from_px(4f32)))
|
||||
);
|
||||
|
||||
let size = single_vec_variant_value!(
|
||||
size,
|
||||
BackgroundSize::Explicit {
|
||||
width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)),
|
||||
height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)),
|
||||
}
|
||||
);
|
||||
|
||||
let repeat = single_vec_keyword_value!(repeat, RepeatX);
|
||||
let origin = single_vec_keyword_value!(origin, padding_box);
|
||||
let clip = single_vec_keyword_value!(clip, padding_box);
|
||||
let composite = single_vec_keyword_value!(composite, subtract);
|
||||
|
||||
properties.push(PropertyDeclaration::MaskImage(image));
|
||||
properties.push(PropertyDeclaration::MaskMode(mode));
|
||||
properties.push(PropertyDeclaration::MaskPositionX(position_x));
|
||||
properties.push(PropertyDeclaration::MaskPositionY(position_y));
|
||||
properties.push(PropertyDeclaration::MaskSize(size));
|
||||
properties.push(PropertyDeclaration::MaskRepeat(repeat));
|
||||
properties.push(PropertyDeclaration::MaskOrigin(origin));
|
||||
properties.push(PropertyDeclaration::MaskClip(clip));
|
||||
properties.push(PropertyDeclaration::MaskComposite(composite));
|
||||
|
||||
let serialization = shorthand_properties_to_string(properties);
|
||||
assert_eq!(
|
||||
serialization,
|
||||
"mask: url(\"http://servo/test.png\") luminance 7px 4px / 70px 50px \
|
||||
repeat-x padding-box subtract;"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_mask_position_with_multiple_values() {
|
||||
let block_text = "mask-position: 1px 2px, 4px 3px;";
|
||||
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
|
||||
let serialization = block.to_css_string();
|
||||
assert_eq!(serialization, block_text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mask_position_should_be_a_valid_form_its_longhands() {
|
||||
// If there is any longhand consisted of both keyword and position,
|
||||
// the shorthand result should be the 4-value format.
|
||||
let block_text = "\
|
||||
mask-position-x: 30px;\
|
||||
mask-position-y: bottom 20px;";
|
||||
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
|
||||
let serialization = block.to_css_string();
|
||||
assert_eq!(serialization, "mask-position: left 30px bottom 20px;");
|
||||
|
||||
// If there is no longhand consisted of both keyword and position,
|
||||
// the shorthand result should be the 2-value format.
|
||||
let block_text = "\
|
||||
mask-position-x: center;\
|
||||
mask-position-y: 20px;";
|
||||
let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
|
||||
let serialization = block.to_css_string();
|
||||
assert_eq!(serialization, "mask-position: center 20px;");
|
||||
}
|
||||
}
|
||||
|
||||
mod scroll_snap_type {
|
||||
pub use super::*;
|
||||
use style::properties::longhands::scroll_snap_type_x::SpecifiedValue as ScrollSnapTypeXValue;
|
||||
|
||||
#[test]
|
||||
fn should_serialize_to_empty_string_if_sub_types_not_equal() {
|
||||
let declarations = vec![
|
||||
(PropertyDeclaration::ScrollSnapTypeX(ScrollSnapTypeXValue::mandatory),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::ScrollSnapTypeY(ScrollSnapTypeXValue::none),
|
||||
Importance::Normal)
|
||||
];
|
||||
|
||||
let block = block_from(declarations);
|
||||
|
||||
let mut s = String::new();
|
||||
|
||||
let id = PropertyId::parse("scroll-snap-type".into()).unwrap();
|
||||
let x = block.single_value_to_css(&id, &mut s);
|
||||
|
||||
assert_eq!(x.is_ok(), true);
|
||||
assert_eq!(s, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_serialize_to_single_value_if_sub_types_are_equal() {
|
||||
let declarations = vec![
|
||||
(PropertyDeclaration::ScrollSnapTypeX(ScrollSnapTypeXValue::mandatory),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::ScrollSnapTypeY(ScrollSnapTypeXValue::mandatory),
|
||||
Importance::Normal)
|
||||
];
|
||||
|
||||
let block = block_from(declarations);
|
||||
|
||||
let mut s = String::new();
|
||||
|
||||
let id = PropertyId::parse("scroll-snap-type".into()).unwrap();
|
||||
let x = block.single_value_to_css(&id, &mut s);
|
||||
|
||||
assert_eq!(x.is_ok(), true);
|
||||
assert_eq!(s, "mandatory");
|
||||
}
|
||||
}
|
||||
|
||||
mod transform {
|
||||
pub use super::*;
|
||||
use style::properties::longhands::transform::SpecifiedOperation;
|
||||
|
|
|
@ -13,6 +13,7 @@ use style::properties::{longhands, Importance, PropertyDeclaration, PropertyDecl
|
|||
use style::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
|
||||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylesheets::{Origin, Stylesheet, CssRule};
|
||||
use style::thread_state;
|
||||
use test::{self, Bencher};
|
||||
|
||||
struct ErrorringErrorReporter;
|
||||
|
@ -92,6 +93,7 @@ fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, C
|
|||
#[bench]
|
||||
fn bench_insertion_basic(b: &mut Bencher) {
|
||||
let r = RuleTree::new();
|
||||
thread_state::initialize(thread_state::SCRIPT);
|
||||
|
||||
let rules_matched = parse_rules(
|
||||
".foo { width: 200px; } \
|
||||
|
@ -110,6 +112,7 @@ fn bench_insertion_basic(b: &mut Bencher) {
|
|||
#[bench]
|
||||
fn bench_insertion_basic_per_element(b: &mut Bencher) {
|
||||
let r = RuleTree::new();
|
||||
thread_state::initialize(thread_state::SCRIPT);
|
||||
|
||||
let rules_matched = parse_rules(
|
||||
".foo { width: 200px; } \
|
||||
|
@ -126,6 +129,7 @@ fn bench_insertion_basic_per_element(b: &mut Bencher) {
|
|||
#[bench]
|
||||
fn bench_expensive_insertion(b: &mut Bencher) {
|
||||
let r = RuleTree::new();
|
||||
thread_state::initialize(thread_state::SCRIPT);
|
||||
|
||||
// This test case tests a case where you style a bunch of siblings
|
||||
// matching the same rules, with a different style attribute each
|
||||
|
@ -148,6 +152,7 @@ fn bench_expensive_insertion(b: &mut Bencher) {
|
|||
#[bench]
|
||||
fn bench_insertion_basic_parallel(b: &mut Bencher) {
|
||||
let r = RuleTree::new();
|
||||
thread_state::initialize(thread_state::SCRIPT);
|
||||
|
||||
let rules_matched = parse_rules(
|
||||
".foo { width: 200px; } \
|
||||
|
@ -177,8 +182,9 @@ fn bench_insertion_basic_parallel(b: &mut Bencher) {
|
|||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_expensive_insersion_parallel(b: &mut Bencher) {
|
||||
fn bench_expensive_insertion_parallel(b: &mut Bencher) {
|
||||
let r = RuleTree::new();
|
||||
thread_state::initialize(thread_state::SCRIPT);
|
||||
|
||||
let rules_matched = parse_rules(
|
||||
".foo { width: 200px; } \
|
||||
|
|
|
@ -14,7 +14,6 @@ use servo_url::ServoUrl;
|
|||
use std::borrow::ToOwned;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use style::computed_values::font_family::{FamilyName, FamilyNameSyntax};
|
||||
use style::context::QuirksMode;
|
||||
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
|
||||
use style::media_queries::MediaList;
|
||||
|
@ -25,8 +24,6 @@ use style::properties::longhands::animation_timing_function;
|
|||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylesheets::{Origin, Namespaces};
|
||||
use style::stylesheets::{Stylesheet, StylesheetContents, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule};
|
||||
use style::stylesheets::font_feature_values_rule::{FFVDeclaration, FontFeatureValuesRule};
|
||||
use style::stylesheets::font_feature_values_rule::{SingleValue, PairValues, VectorValues};
|
||||
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframePercentage};
|
||||
use style::values::{KeyframesName, CustomIdent};
|
||||
use style::values::computed::Percentage;
|
||||
|
@ -68,14 +65,6 @@ fn test_parse_stylesheet() {
|
|||
animation-name: 'foo'; /* animation properties not allowed here */
|
||||
animation-timing-function: ease; /* … except animation-timing-function */
|
||||
}
|
||||
}
|
||||
@font-feature-values test {
|
||||
@swash { foo: 12; bar: 24; }
|
||||
@swash { bar: 36; baz: 48; }
|
||||
@stylistic { fooo: 14; }
|
||||
@rubbish { shouldnt-parse: 1; }
|
||||
@styleset { hello: 10 11 12; }
|
||||
@character-variant { ok: 78 2; }
|
||||
}";
|
||||
let url = ServoUrl::parse("about::test").unwrap();
|
||||
let lock = SharedRwLock::new();
|
||||
|
@ -250,52 +239,7 @@ fn test_parse_stylesheet() {
|
|||
line: 16,
|
||||
column: 19,
|
||||
},
|
||||
}))),
|
||||
CssRule::FontFeatureValues(Arc::new(stylesheet.shared_lock.wrap(FontFeatureValuesRule {
|
||||
family_names: vec![FamilyName {
|
||||
name: Atom::from("test"),
|
||||
syntax: FamilyNameSyntax::Identifiers(String::from("test")),
|
||||
}],
|
||||
swash: vec![
|
||||
FFVDeclaration {
|
||||
name: "foo".into(),
|
||||
value: SingleValue(12 as u32),
|
||||
},
|
||||
FFVDeclaration {
|
||||
name: "bar".into(),
|
||||
value: SingleValue(36 as u32),
|
||||
},
|
||||
FFVDeclaration {
|
||||
name: "baz".into(),
|
||||
value: SingleValue(48 as u32),
|
||||
}
|
||||
],
|
||||
stylistic: vec![
|
||||
FFVDeclaration {
|
||||
name: "fooo".into(),
|
||||
value: SingleValue(14 as u32),
|
||||
}
|
||||
],
|
||||
ornaments: vec![],
|
||||
annotation: vec![],
|
||||
character_variant: vec![
|
||||
FFVDeclaration {
|
||||
name: "ok".into(),
|
||||
value: PairValues(78 as u32, Some(2 as u32)),
|
||||
},
|
||||
],
|
||||
styleset: vec![
|
||||
FFVDeclaration {
|
||||
name: "hello".into(),
|
||||
value: VectorValues(vec![10 as u32, 11 as u32, 12 as u32]),
|
||||
},
|
||||
],
|
||||
source_location: SourceLocation {
|
||||
line: 25,
|
||||
column: 29,
|
||||
},
|
||||
})))
|
||||
|
||||
], &stylesheet.shared_lock),
|
||||
},
|
||||
media: Arc::new(stylesheet.shared_lock.wrap(MediaList::empty())),
|
||||
|
|
|
@ -229,6 +229,7 @@ fn mock_stylist() -> Stylist {
|
|||
|
||||
#[test]
|
||||
fn test_stylist_device_accessors() {
|
||||
thread_state::initialize(thread_state::LAYOUT);
|
||||
let stylist = mock_stylist();
|
||||
assert_eq!(stylist.device().media_type(), MediaType::Screen);
|
||||
let mut stylist_mut = mock_stylist();
|
||||
|
@ -237,6 +238,7 @@ fn test_stylist_device_accessors() {
|
|||
|
||||
#[test]
|
||||
fn test_stylist_rule_tree_accessors() {
|
||||
thread_state::initialize(thread_state::LAYOUT);
|
||||
let stylist = mock_stylist();
|
||||
stylist.rule_tree();
|
||||
stylist.rule_tree().root();
|
||||
|
|
Загрузка…
Ссылка в новой задаче