Auto merge of #14464 - canaltinova:cssom-test, r=Manishearth

Write tests for CSSOM Interfaces

<!-- Please describe your changes on the following line: -->
ToCss implementation was wrong about Keyframe percentage values, it was writing values between 0-1. I had to fix it. Wrote some tests about CSSKeyframesRule, CSSNamespaceRule, CSSRuleList, CSSStyleSheet, StyleSheetList interfaces.
CSSFontFaceRule and CSSViewportRule looks like not implemented yet. I didn't write one for them.
Also name attribute in CSSKeyframesRule isn't implemented yet. Is there any complication about it? If not, I can implement it.

r? @Manishearth

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [X] There are tests for these changes OR

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14464)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-12-07 13:38:50 -08:00 committed by GitHub
commit 8dfaed2183
7 changed files with 230 additions and 3 deletions

View file

@ -14,7 +14,7 @@ use std::sync::Arc;
use style_traits::ToCss; use style_traits::ToCss;
use stylesheets::{MemoryHoleReporter, Stylesheet}; use stylesheets::{MemoryHoleReporter, Stylesheet};
/// A number from 1 to 100, indicating the percentage of the animation where /// A number from 0 to 1, indicating the percentage of the animation where
/// this keyframe should run. /// this keyframe should run.
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] #[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -30,6 +30,12 @@ impl ::std::cmp::Ord for KeyframePercentage {
impl ::std::cmp::Eq for KeyframePercentage { } impl ::std::cmp::Eq for KeyframePercentage { }
impl ToCss for KeyframePercentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
write!(dest, "{}%", self.0 * 100.0)
}
}
impl KeyframePercentage { impl KeyframePercentage {
#[inline] #[inline]
pub fn new(value: f32) -> KeyframePercentage { pub fn new(value: f32) -> KeyframePercentage {
@ -93,10 +99,10 @@ pub struct Keyframe {
impl ToCss for Keyframe { impl ToCss for Keyframe {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let mut iter = self.selector.percentages().iter(); let mut iter = self.selector.percentages().iter();
try!(write!(dest, "{}%", iter.next().unwrap().0)); try!(iter.next().unwrap().to_css(dest));
for percentage in iter { for percentage in iter {
try!(write!(dest, ", ")); try!(write!(dest, ", "));
try!(write!(dest, "{}%", percentage.0)); try!(percentage.to_css(dest));
} }
try!(dest.write_str(" { ")); try!(dest.write_str(" { "));
try!(self.block.read().to_css(dest)); try!(self.block.read().to_css(dest));

View file

@ -39677,12 +39677,42 @@
"deleted_reftests": {}, "deleted_reftests": {},
"items": { "items": {
"testharness": { "testharness": {
"cssom/CSSKeyframesRule.html": [
{
"path": "cssom/CSSKeyframesRule.html",
"url": "/cssom/CSSKeyframesRule.html"
}
],
"cssom/CSSNamespaceRule.html": [
{
"path": "cssom/CSSNamespaceRule.html",
"url": "/cssom/CSSNamespaceRule.html"
}
],
"cssom/CSSRuleList.html": [
{
"path": "cssom/CSSRuleList.html",
"url": "/cssom/CSSRuleList.html"
}
],
"cssom/CSSStyleSheet.html": [
{
"path": "cssom/CSSStyleSheet.html",
"url": "/cssom/CSSStyleSheet.html"
}
],
"cssom/MediaList.html": [ "cssom/MediaList.html": [
{ {
"path": "cssom/MediaList.html", "path": "cssom/MediaList.html",
"url": "/cssom/MediaList.html" "url": "/cssom/MediaList.html"
} }
], ],
"cssom/StyleSheetList.html": [
{
"path": "cssom/StyleSheetList.html",
"url": "/cssom/StyleSheetList.html"
}
],
"cssom/shorthand-serialization.html": [ "cssom/shorthand-serialization.html": [
{ {
"path": "cssom/shorthand-serialization.html", "path": "cssom/shorthand-serialization.html",

View file

@ -0,0 +1,58 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - CSSKeyframesRule interface</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
@keyframes foo {
0% { top: 0px; }
100% { top: 200px; }
}
</style>
<script>
test(function () {
var keyframe = document.styleSheets[0].cssRules[0];
assert_equals(keyframe.cssRules.length, 2, "CSSKeyframesRule cssRule length attribute");
assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute");
assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute");
keyframe.appendRule("50% { top: 100px; }");
assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after appendRule function");
assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
assert_equals(keyframe.cssRules[2].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
keyframe.appendRule("0% { top: 50px; }");
assert_equals(keyframe.cssRules.length, 4, "CSSKeyframesRule prefix attribute after appendRule function");
assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
assert_equals(keyframe.cssRules[2].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
assert_equals(keyframe.cssRules[3].cssText, "0% { top: 50px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function");
var find1 = keyframe.findRule("50%");
assert_equals(find1.cssText, "50% { top: 100px; }", "CSSKeyframesRule findRule function");
var find2 = keyframe.findRule("0%");
assert_equals(find2.cssText, "0% { top: 50px; }", "CSSKeyframesRule findRule function");
var find3 = keyframe.findRule("70%");
assert_equals(find3, null, "CSSKeyframesRule findRule function");
keyframe.deleteRule("100%");
assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after deleteRule function");
assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[1].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[2].cssText, "0% { top: 50px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[3], undefined, "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
keyframe.deleteRule("80%");
assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after deleteRule function");
assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[1].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[2].cssText, "0% { top: 50px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
assert_equals(keyframe.cssRules[3], undefined, "CSSKeyframesRule cssRule cssText attribute after deleteRule function");
});
</script>
</head>
</html>

View file

@ -0,0 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - CSSNamespaceRule interface</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
@namespace svg url(http://servo);
@namespace url(http://servo1);
@namespace svg url("http://servo2");
</style>
<script>
test(function () {
var rules = document.styleSheets[0].cssRules;
assert_equals(rules[0].prefix, "svg", "CSSNamespaceRule prefix attribute");
assert_equals(rules[0].namespaceURI, "http://servo", "CSSNamespaceRule namespaceURI attribute");
assert_equals(rules[0].cssText, "@namespace svg url(\"http://servo\");", "CSSNamespaceRule cssText attribute");
assert_equals(rules[1].prefix, "", "CSSNamespaceRule prefix attribute");
assert_equals(rules[1].namespaceURI, "http://servo1", "CSSNamespaceRule namespaceURI attribute");
assert_equals(rules[1].cssText, "@namespace url(\"http://servo1\");", "CSSNamespaceRule cssText attribute");
assert_equals(rules[2].prefix, "svg", "CSSNamespaceRule prefix attribute");
assert_equals(rules[2].namespaceURI, "http://servo2", "CSSNamespaceRule namespaceURI attribute");
assert_equals(rules[2].cssText, "@namespace svg url(\"http://servo2\");", "CSSNamespaceRule cssText attribute");
});
</script>
</head>
</html>

View file

@ -0,0 +1,26 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - CSSRuleList interface</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body { width: 50%; }
#foo { height: 100px; }
</style>
<script>
test(function () {
var ruleList = document.styleSheets[0].cssRules;
assert_equals(ruleList.length, 2, "CSSRuleList length attribute");
assert_equals(ruleList[0].cssText, "body { width: 50%; }", "CSSRuleList indexed getter");
assert_equals(ruleList[1].cssText, "#foo { height: 100px; }", "CSSRuleList indexed getter");
assert_equals(ruleList[2], undefined, "CSSRuleList indexed getter");
assert_equals(ruleList.item(0).cssText, "body { width: 50%; }", "CSSRuleList item function");
assert_equals(ruleList.item(1).cssText, "#foo { height: 100px; }", "CSSRuleList item function");
assert_equals(ruleList.item(2), null, "CSSRuleList item function");
});
</script>
</head>
</html>

View file

@ -0,0 +1,43 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - CSSStyleSheet interface</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style id="my-stylesheet">
body { width: 50%; }
#foo { height: 100px; }
</style>
<script>
test(function () {
var styleSheet = document.styleSheets[0];
styleSheet.cssRules[0].randomProperty = 1;
styleSheet.cssRules[1].randomProperty = 2;
assert_equals(styleSheet, document.getElementById("my-stylesheet").sheet, "CSSStyleSheet and LinkStyle's sheet attribute");
assert_equals(styleSheet.cssRules.length, 2, "CSSStyleSheet cssRules attribute");
assert_equals(styleSheet.cssRules[0].cssText, "body { width: 50%; }", "CSSStyleSheet cssRules attribute");
assert_equals(styleSheet.cssRules[1].cssText, "#foo { height: 100px; }", "CSSStyleSheet cssRules attribute");
assert_equals(styleSheet.cssRules[2], undefined, "CSSStyleSheet cssRules attribute");
styleSheet.insertRule("#bar { margin: 10px; }", 1);
assert_equals(styleSheet.cssRules.length, 3, "CSSStyleSheet cssRules attribute after insertRule function");
assert_equals(styleSheet.cssRules[0].cssText, "body { width: 50%; }", "CSSStyleSheet cssRules attribute");
assert_equals(styleSheet.cssRules[1].cssText, "#bar { margin: 10px; }", "CSSStyleSheet cssRules attribute after insertRule function");
assert_equals(styleSheet.cssRules[2].cssText, "#foo { height: 100px; }", "CSSStyleSheet cssRules attribute after insertRule function");
assert_equals(styleSheet.cssRules[0].randomProperty, 1, "[SameObject] cssRules attribute after insertRule function");
assert_equals(styleSheet.cssRules[2].randomProperty, 2, "[SameObject] cssRules attribute after insertRule function");
styleSheet.deleteRule(1);
assert_equals(styleSheet.cssRules.length, 2, "CSSStyleSheet cssRules attribute after deleteRule function");
assert_equals(styleSheet.cssRules[0].cssText, "body { width: 50%; }", "CSSStyleSheet cssRules attribute after deleteRule function");
assert_equals(styleSheet.cssRules[1].cssText, "#foo { height: 100px; }", "CSSStyleSheet cssRules attribute after deleteRule function");
assert_equals(styleSheet.cssRules[2], undefined, "CSSStyleSheet cssRules attribute after deleteRule function");
assert_equals(styleSheet.cssRules[0].randomProperty, 1, "[SameObject] cssRules attribute after deleteRule function");
assert_equals(styleSheet.cssRules[1].randomProperty, 2, "[SameObject] cssRules attribute after deleteRule function");
});
</script>
</head>
</html>

View file

@ -0,0 +1,33 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - StyleSheetList interface</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body { width: 50%; }
</style>
<style>
#foo { width: 10%; }
#bar { height: 100px; }
</style>
<script>
test(function () {
var styleSheets = document.styleSheets;
assert_equals(styleSheets.length, 2, "StyleSheetList length attribute");
assert_equals(styleSheets[0].cssRules.length, 1, "StyleSheetList indexed getter length attribute");
assert_equals(styleSheets[1].cssRules.length, 2, "StyleSheetList indexed getter length attribute");
assert_equals(styleSheets[2], undefined, "StyleSheetList indexed getter length attribute");
assert_equals(styleSheets.item(0).cssRules.length, 1, "StyleSheetList item function length attribute");
assert_equals(styleSheets.item(1).cssRules.length, 2, "StyleSheetList item function length attribute");
assert_equals(styleSheets.item(2), null, "StyleSheetList item function length attribute");
styleSheets[0].randomProperty = 1;
var style = document.createElement("style");
document.head.appendChild(style);
assert_equals(styleSheets[0].randomProperty, 1, "[SameObject] StyleSheetList");
});
</script>
</head>
</html>