From c6feae3c5ce2a25dfd809699eb0b8d2a96c1816e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 2 Aug 2016 12:22:16 +0530 Subject: [PATCH] Add roundtrip parsing tests for basic_shape/position --- tests/unit/style/lib.rs | 1 + tests/unit/style/parsing/basic_shape.rs | 98 ++++++++++++++++++++++++- tests/unit/style/parsing/mod.rs | 29 ++++++++ tests/unit/style/parsing/position.rs | 30 ++++++++ 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 tests/unit/style/parsing/mod.rs create mode 100644 tests/unit/style/parsing/position.rs diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs index 74546cb12f05..56111373e964 100644 --- a/tests/unit/style/lib.rs +++ b/tests/unit/style/lib.rs @@ -21,6 +21,7 @@ mod attr; mod cache; mod logical_geometry; mod media_queries; +mod parsing; mod properties; mod str; mod stylesheets; diff --git a/tests/unit/style/parsing/basic_shape.rs b/tests/unit/style/parsing/basic_shape.rs index d6a14edef084..0f8f6f4ccb57 100644 --- a/tests/unit/style/parsing/basic_shape.rs +++ b/tests/unit/style/parsing/basic_shape.rs @@ -1,3 +1,99 @@ /* 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/. */ \ No newline at end of file + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use parsing::parse; +use style::values::specified::basic_shape::*; + +// 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!($fun, $input, $output); + assert_roundtrip!(BasicShape::parse, $input, $output); + } +} + +#[test] +fn test_inset() { + // these are actually wrong, we should be serializing to the minimum possible result + // the advantage of being wrong is that the roundtrip test actually suffices + // for testing the intermediate state + assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px)", "inset(10px 10px 10px 10px)"); + assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px 20%)", "inset(10px 20% 10px 20%)"); + + assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px round 10px)", + "inset(10px 10px 10px 10px round 10px 10px 10px 10px \ + / 10px 10px 10px 10px)"); + assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px round 10px 20px 30px 40px)", + "inset(10px 10px 10px 10px round 10px 20px 30px 40px \ + / 10px 20px 30px 40px)"); + assert_roundtrip_basicshape!(InsetRect::parse, "inset(10px 10px 10px 10px round 10px 20px 30px 40px \ + / 1px 2px 3px 4px)", + "inset(10px 10px 10px 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(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!(parse(Circle::parse, "circle(at top 40%)").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 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 10px 10px)"); + + assert!(parse(Polygon::parse, "polygon()").is_err()); +} diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs new file mode 100644 index 000000000000..76ff804b97a9 --- /dev/null +++ b/tests/unit/style/parsing/mod.rs @@ -0,0 +1,29 @@ +/* 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/. */ + +//! Tests for parsing and serialization of values/properties + +use cssparser::Parser; + +fn parse Result>(f: F, s: &str) -> Result { + let mut parser = Parser::new(s); + f(&mut parser) +} + +// This is a macro so that the file/line information +// is preserved in the panic +macro_rules! assert_roundtrip { + ($fun:expr, $input:expr, $output:expr) => { + let parsed = $crate::parsing::parse($fun, $input) + .expect(&format!("Failed to parse {}", $input)); + let mut serialized = String::new(); + ::cssparser::ToCss::to_css(&parsed, &mut serialized) + .expect("Failed to serialize"); + assert_eq!(serialized, $output); + } +} + + +mod basic_shape; +mod position; \ No newline at end of file diff --git a/tests/unit/style/parsing/position.rs b/tests/unit/style/parsing/position.rs new file mode 100644 index 000000000000..bc4f1c514333 --- /dev/null +++ b/tests/unit/style/parsing/position.rs @@ -0,0 +1,30 @@ +/* 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::values::specified::position::*; + +#[test] +fn test_position() { + // Serialization is not actually specced + // though these are the values expected by basic-shape + // https://github.com/w3c/csswg-drafts/issues/368 + assert_roundtrip!(Position::parse, "center", "50% 50%"); + assert_roundtrip!(Position::parse, "top left", "0% 0%"); + assert_roundtrip!(Position::parse, "left top", "0% 0%"); + assert_roundtrip!(Position::parse, "top right", "100% 0%"); + assert_roundtrip!(Position::parse, "right top", "100% 0%"); + assert_roundtrip!(Position::parse, "bottom left", "0% 100%"); + assert_roundtrip!(Position::parse, "left bottom", "0% 100%"); + assert_roundtrip!(Position::parse, "left center", "0% 50%"); + assert_roundtrip!(Position::parse, "right center", "100% 50%"); + assert_roundtrip!(Position::parse, "center top", "50% 0%"); + assert_roundtrip!(Position::parse, "center bottom", "50% 100%"); + assert_roundtrip!(Position::parse, "center 10px", "50% 10px"); + assert_roundtrip!(Position::parse, "center 10%", "50% 10%"); + assert_roundtrip!(Position::parse, "right 10%", "100% 10%"); + + // we don't yet handle 4-valued positions + // https://github.com/servo/servo/issues/12690 +}