border.rs (9289B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 use parsing::parse; 6 use style::parser::Parse; 7 use style::properties::longhands::{border_image_outset, border_image_repeat, border_image_slice}; 8 use style::properties::longhands::{border_image_source, border_image_width}; 9 use style::properties::shorthands::border_image; 10 use style::properties::MaybeBoxed; 11 use style::values::specified::BorderRadius; 12 use style_traits::ToCss; 13 14 macro_rules! assert_longhand { 15 ($parsed_shorthand: expr, $prop: ident, $value_string: expr) => { 16 assert_eq!( 17 $parsed_shorthand.$prop, 18 parse_longhand!($prop, $value_string).maybe_boxed() 19 ) 20 }; 21 } 22 23 macro_rules! assert_initial { 24 ($parsed_shorthand: expr, $prop: ident) => { 25 assert_eq!( 26 $parsed_shorthand.$prop, 27 $prop::get_initial_specified_value().maybe_boxed() 28 ) 29 }; 30 } 31 32 macro_rules! assert_border_radius_values { 33 ($input:expr; $tlw:expr, $trw:expr, $brw:expr, $blw:expr ; 34 $tlh:expr, $trh:expr, $brh:expr, $blh:expr) => { 35 let input = parse(BorderRadius::parse, $input) 36 .expect(&format!("Failed parsing {} as border radius", $input)); 37 assert_eq!( 38 ::style_traits::ToCss::to_css_string(&input.top_left.0.width()), 39 $tlw 40 ); 41 assert_eq!( 42 ::style_traits::ToCss::to_css_string(&input.top_right.0.width()), 43 $trw 44 ); 45 assert_eq!( 46 ::style_traits::ToCss::to_css_string(&input.bottom_right.0.width()), 47 $brw 48 ); 49 assert_eq!( 50 ::style_traits::ToCss::to_css_string(&input.bottom_left.0.width()), 51 $blw 52 ); 53 assert_eq!( 54 ::style_traits::ToCss::to_css_string(&input.top_left.0.height()), 55 $tlh 56 ); 57 assert_eq!( 58 ::style_traits::ToCss::to_css_string(&input.top_right.0.height()), 59 $trh 60 ); 61 assert_eq!( 62 ::style_traits::ToCss::to_css_string(&input.bottom_right.0.height()), 63 $brh 64 ); 65 assert_eq!( 66 ::style_traits::ToCss::to_css_string(&input.bottom_left.0.height()), 67 $blh 68 ); 69 }; 70 } 71 72 #[test] 73 fn test_border_radius() { 74 assert_border_radius_values!("10px"; 75 "10px", "10px", "10px", "10px" ; 76 "10px", "10px", "10px", "10px"); 77 assert_border_radius_values!("10px 20px"; 78 "10px", "20px", "10px", "20px" ; 79 "10px", "20px", "10px", "20px"); 80 assert_border_radius_values!("10px 20px 30px"; 81 "10px", "20px", "30px", "20px" ; 82 "10px", "20px", "30px", "20px"); 83 assert_border_radius_values!("10px 20px 30px 40px"; 84 "10px", "20px", "30px", "40px" ; 85 "10px", "20px", "30px", "40px"); 86 assert_border_radius_values!("10% / 20px"; 87 "10%", "10%", "10%", "10%" ; 88 "20px", "20px", "20px", "20px"); 89 assert_border_radius_values!("10px / 20px 30px"; 90 "10px", "10px", "10px", "10px" ; 91 "20px", "30px", "20px", "30px"); 92 assert_border_radius_values!("10px 20px 30px 40px / 1px 2px 3px 4px"; 93 "10px", "20px", "30px", "40px" ; 94 "1px", "2px", "3px", "4px"); 95 assert_border_radius_values!("10px 20px 30px 40px / 1px 2px 3px 4px"; 96 "10px", "20px", "30px", "40px" ; 97 "1px", "2px", "3px", "4px"); 98 assert_border_radius_values!("10px 20px 30px 40px / 1px 2px 3px 4px"; 99 "10px", "20px", "30px", "40px" ; 100 "1px", "2px", "3px", "4px"); 101 assert_border_radius_values!("10px -20px 30px 40px"; 102 "10px", "10px", "10px", "10px"; 103 "10px", "10px", "10px", "10px"); 104 assert_border_radius_values!("10px 20px -30px 40px"; 105 "10px", "20px", "10px", "20px"; 106 "10px", "20px", "10px", "20px"); 107 assert_border_radius_values!("10px 20px 30px -40px"; 108 "10px", "20px", "30px", "20px"; 109 "10px", "20px", "30px", "20px"); 110 assert!(parse(BorderRadius::parse, "-10px 20px 30px 40px").is_err()); 111 } 112 113 #[test] 114 fn border_image_shorthand_should_parse_when_all_properties_specified() { 115 let input = "linear-gradient(red, blue) 30 30% 45 fill / 20px 40px / 10px round stretch"; 116 let result = parse(border_image::parse_value, input).unwrap(); 117 118 assert_longhand!(result, border_image_source, "linear-gradient(red, blue)"); 119 assert_longhand!(result, border_image_slice, "30 30% 45 fill"); 120 assert_longhand!(result, border_image_width, "20px 40px"); 121 assert_longhand!(result, border_image_outset, "10px"); 122 assert_longhand!(result, border_image_repeat, "round stretch"); 123 } 124 125 #[test] 126 fn border_image_shorthand_should_parse_without_width() { 127 let input = "linear-gradient(red, blue) 30 30% 45 fill / / 10px round stretch"; 128 let result = parse(border_image::parse_value, input).unwrap(); 129 130 assert_longhand!(result, border_image_source, "linear-gradient(red, blue)"); 131 assert_longhand!(result, border_image_slice, "30 30% 45 fill"); 132 assert_longhand!(result, border_image_outset, "10px"); 133 assert_longhand!(result, border_image_repeat, "round stretch"); 134 assert_initial!(result, border_image_width); 135 } 136 137 #[test] 138 fn border_image_shorthand_should_parse_without_outset() { 139 let input = "linear-gradient(red, blue) 30 30% 45 fill / 20px 40px round"; 140 let result = parse(border_image::parse_value, input).unwrap(); 141 142 assert_longhand!(result, border_image_source, "linear-gradient(red, blue)"); 143 assert_longhand!(result, border_image_slice, "30 30% 45 fill"); 144 assert_longhand!(result, border_image_width, "20px 40px"); 145 assert_longhand!(result, border_image_repeat, "round"); 146 assert_initial!(result, border_image_outset); 147 } 148 149 #[test] 150 fn border_image_shorthand_should_parse_without_width_or_outset() { 151 let input = "linear-gradient(red, blue) 30 30% 45 fill round"; 152 let result = parse(border_image::parse_value, input).unwrap(); 153 154 assert_longhand!(result, border_image_source, "linear-gradient(red, blue)"); 155 assert_longhand!(result, border_image_slice, "30 30% 45 fill"); 156 assert_longhand!(result, border_image_repeat, "round"); 157 assert_initial!(result, border_image_width); 158 assert_initial!(result, border_image_outset); 159 } 160 161 #[test] 162 fn border_image_shorthand_should_parse_with_just_source() { 163 let result = parse(border_image::parse_value, "linear-gradient(red, blue)").unwrap(); 164 165 assert_longhand!(result, border_image_source, "linear-gradient(red, blue)"); 166 assert_initial!(result, border_image_slice); 167 assert_initial!(result, border_image_width); 168 assert_initial!(result, border_image_outset); 169 assert_initial!(result, border_image_repeat); 170 } 171 172 #[test] 173 fn border_image_outset_should_error_on_negative_length() { 174 let result = parse(border_image_outset::parse, "-1em"); 175 assert!(result.is_err()); 176 } 177 178 #[test] 179 fn border_image_outset_should_error_on_negative_number() { 180 let result = parse(border_image_outset::parse, "-15"); 181 assert!(result.is_err()); 182 } 183 184 #[test] 185 fn border_image_outset_should_return_number_on_plain_zero() { 186 let result = parse(border_image_outset::parse, "0"); 187 assert_eq!(result.unwrap(), parse_longhand!(border_image_outset, "0")); 188 } 189 190 #[test] 191 fn border_image_outset_should_return_length_on_length_zero() { 192 let result = parse(border_image_outset::parse, "0em"); 193 assert_eq!(result.unwrap(), parse_longhand!(border_image_outset, "0em")); 194 } 195 196 #[test] 197 fn test_border_style() { 198 use style::values::specified::BorderStyle; 199 200 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"none"#); 201 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"hidden"#); 202 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"solid"#); 203 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"double"#); 204 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"dotted"#); 205 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"dashed"#); 206 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"groove"#); 207 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"ridge"#); 208 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"inset"#); 209 assert_roundtrip_with_context!(<BorderStyle as Parse>::parse, r#"outset"#); 210 } 211 212 #[test] 213 fn test_border_spacing() { 214 use style::properties::longhands::border_spacing; 215 216 assert_parser_exhausted!(border_spacing::parse, "1px rubbish", false); 217 assert_parser_exhausted!(border_spacing::parse, "1px", true); 218 assert_parser_exhausted!(border_spacing::parse, "1px 2px", true); 219 }