Delete Sky tests that we're not going to run with Dart

This CL removes a number of tests that we don't plan to port to Dart:

1) custom-elements. We're going to use a different mechanism for custom
   elements. We'll need to write a new set of tests as we implement it.
2) inspector. These are tests of the JS inspector backend, which we don't
   plan to use.
3) js. This is a test of a JavaScript feature.
4) mocha. These are tests of the JavaScript testing framework we were using.
5) mutation-observer. We're keeping the C++ code for mutation observers, but
   it's unclear how we want to expose this in the platform.
6) resources. These are JavaScript-based testing frameworks.

R=eseidel@chromium.org, ojan@chromium.org

Review URL: https://codereview.chromium.org/920343002
This commit is contained in:
Adam Barth
2015-02-13 13:51:26 -08:00
parent fb3af8b4c2
commit d7ee97cc3d
87 changed files with 1 additions and 3075 deletions

View File

@@ -1,10 +1,4 @@
# These tests require gc() to be exposed.
crbug.com/1 mutation-observer/observer-wrapper-dropoff-transient.sky [ Skip ]
crbug.com/1 mutation-observer/observer-wrapper-dropoff.sky [ Skip ]
crbug.com/1 mutation-observer/transient-gc-crash.sky [ Skip ]
crbug.com/1 mutation-observer/weak-callback-gc-crash.sky [ Skip ]
# These tests need more basic testing support plumbed right into the
# platform, which we don't currently have:
https://github.com/domokit/mojo/issues/15 parser/cr.sky [ Skip ]
@@ -16,29 +10,12 @@ https://github.com/domokit/mojo/issues/14 parser/normaliser-null.sky [ Skip ]
https://github.com/domokit/mojo/issues/14 parser/utf16.sky [ Skip ]
https://github.com/domokit/mojo/issues/16 parser/normaliser-crlf.sky [ Skip ]
# These tests are flaky on the bots
https://github.com/domokit/mojo/issues/24 custom-elements/constructor-calls-created-synchronously.sky [ Skip ]
https://github.com/domokit/mojo/issues/24 mutation-observer/observe-attributes.sky [ Skip ]
# We don't implement embed ViewManagerClient yet.
crbug.com/2 services/iframe-embed-vmc.sky [ Skip ]
# This test only fails on the bots:
#crbug.com/434822 inspector/page-agent-get-resource-tree.sky [ Pass Failure ]
# These tests broke during the Dart migration
crbug.com/2 animation/basic-imperative.sky [ Skip ]
crbug.com/2 animation/basic-transition.sky [ Skip ]
crbug.com/2 custom-elements/document-register-basic.sky [ Skip ]
crbug.com/2 custom-elements/document-register-reentrant-null-constructor.sky [ Skip ]
crbug.com/2 custom-elements/document-register-reentrant-returning-fake.sky [ Skip ]
crbug.com/2 custom-elements/document-register-reentrant-throwing-constructor.sky [ Skip ]
crbug.com/2 custom-elements/element-upgrade-no-register-and-leak.sky [ Skip ]
crbug.com/2 custom-elements/generated-constructor.sky [ Skip ]
crbug.com/2 custom-elements/html-element-type-extension-assert.sky [ Skip ]
crbug.com/2 custom-elements/lifecycle-created-createElement-recursion.sky [ Skip ]
crbug.com/2 custom-elements/lifecycle-created-createElement-reentrancy.sky [ Skip ]
crbug.com/2 custom-elements/lifecycle-created-parser-script.sky [ Skip ]
crbug.com/2 custom-elements/resources/document-register-fuzz.sky [ Skip ]
crbug.com/2 editing/backspace.sky [ Skip ]
crbug.com/2 editing/delete_block_contents.sky [ Skip ]
crbug.com/2 editing/replace.sky [ Skip ]
@@ -58,47 +35,15 @@ crbug.com/2 framework/xmlhttprequest/unicode-post.sky [ Skip ]
crbug.com/2 framework/xmlhttprequest/xhr-does-not-exist.sky [ Skip ]
crbug.com/2 framework/xmlhttprequest/xhr-relative.sky [ Skip ]
crbug.com/2 framework/xmlhttprequest/xhr.sky [ Skip ]
crbug.com/2 inspector/css-computed-style.sky [ Skip ]
crbug.com/2 inspector/dom-mutation-modify-text-node-and-append.sky [ Skip ]
crbug.com/2 inspector/dom-mutation.sky [ Skip ]
crbug.com/2 inspector/page-agent-get-resource-tree.sky [ Skip ]
crbug.com/2 js/classes.sky [ Skip ]
crbug.com/2 layout/margins-absolute.sky [ Skip ]
crbug.com/2 layout/margins.sky [ Skip ]
crbug.com/2 lowlevel/createElement.sky [ Skip ]
crbug.com/2 mocha/describe-only.sky [ Skip ]
crbug.com/2 mocha/it-only.sky [ Skip ]
crbug.com/2 modules/application.sky [ Skip ]
crbug.com/2 modules/instance-of-application.sky [ Skip ]
crbug.com/2 modules/instance-of-module.sky [ Skip ]
crbug.com/2 modules/load-event.sky [ Skip ]
crbug.com/2 modules/modules.sky [ Skip ]
crbug.com/2 modules/resources/does-not-export.sky [ Skip ]
crbug.com/2 modules/resources/instance-of-module-module.sky [ Skip ]
crbug.com/2 modules/resources/intermediate.sky [ Skip ]
crbug.com/2 modules/resources/pass.sky [ Skip ]
crbug.com/2 modules/script-import.sky [ Skip ]
crbug.com/2 mutation-observer/callback-arguments.sky [ Skip ]
crbug.com/2 mutation-observer/clear-transient-without-delivery.sky [ Skip ]
crbug.com/2 mutation-observer/create-during-delivery.sky [ Skip ]
crbug.com/2 mutation-observer/cross-document.sky [ Skip ]
crbug.com/2 mutation-observer/delivery-order.sky [ Skip ]
crbug.com/2 mutation-observer/disconnect-cancel-pending.sky [ Skip ]
crbug.com/2 mutation-observer/document-fragment-insertion.sky [ Skip ]
crbug.com/2 mutation-observer/mutate-during-delivery.sky [ Skip ]
crbug.com/2 mutation-observer/mutation-callback-non-element-crash.sky [ Skip ]
crbug.com/2 mutation-observer/mutation-observer-constructor.sky [ Skip ]
crbug.com/2 mutation-observer/mutation-record-constructor.sky [ Skip ]
crbug.com/2 mutation-observer/mutation-record-nullity.sky [ Skip ]
crbug.com/2 mutation-observer/observe-characterdata.sky [ Skip ]
crbug.com/2 mutation-observer/observe-childList.sky [ Skip ]
crbug.com/2 mutation-observer/observe-exceptions.sky [ Skip ]
crbug.com/2 mutation-observer/observe-options-attributes.sky [ Skip ]
crbug.com/2 mutation-observer/observe-options-character-data.sky [ Skip ]
crbug.com/2 mutation-observer/observe-subtree.sky [ Skip ]
crbug.com/2 mutation-observer/script-append.sky [ Skip ]
crbug.com/2 mutation-observer/shadow-dom.sky [ Skip ]
crbug.com/2 mutation-observer/takeRecords.sky [ Skip ]
crbug.com/2 parser/script.sky [ Skip ]
crbug.com/2 services/buffer.sky [ Skip ]
crbug.com/2 services/codec.sky [ Skip ]

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 Custom element constructors should run the createdCallback synchronously
1 tests
1 pass
0 fail

View File

@@ -1,21 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<body>
<div id="container"></div>
<script>
describe('Custom element constructors', function() {
it('should run the createdCallback synchronously', function() {
var proto = Object.create(HTMLElement.prototype);
var ncallbacks = 0;
proto.createdCallback = function () {
ncallbacks++;
};
var A = document.registerElement('x-a', {prototype: proto});
var x = new A();
assert.equal(ncallbacks, 1);
});
});
</script>
</body>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 document.registerElement() should have basic behaviors
1 tests
1 pass
0 fail

View File

@@ -1,101 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<body>
<div id="container"></div>
<script>
describe('document.registerElement()', function() {
it('should have basic behaviors', function() {
function createRegisterParameters()
{
return {
prototype: Object.create(HTMLElement.prototype, { thisIsPrototype: { value: true } })
};
}
var fooConstructor = document.registerElement('x-foo', createRegisterParameters());
assert.equal(typeof fooConstructor, "function");
assert.equal(fooConstructor.prototype.__proto__, HTMLElement.prototype);
assert.ok(fooConstructor.prototype.thisIsPrototype);
// Bad prototype: prototype is already a built-in interface prototype object
assert.throws(function() {
document.registerElement("x-bad-a", HTMLElement)
});
// Bad prototype: prototype is already a Custom Element interface prototype object
assert.throws(function() {
document.registerElement("x-bad-b", fooConstructor)
});
// Bad prototype: 'constructor' is not configurable
var proto = Object.create(HTMLElement.prototype, {
constructor: {configurable: false, writable: true}
});
assert.throws(function() {
document.registerElement("x-bad-c", { prototype: proto })
});
// Call as function
assert.throws(function() {
fooConstructor()
})
// Constructor initiated instantiation
var createdFoo = new fooConstructor();
// JS built-in properties
assert.equal(createdFoo.__proto__, fooConstructor.prototype);
assert.equal(createdFoo.constructor, fooConstructor);
// Native getter
assert.equal(createdFoo.tagName, "x-foo");
// Native setter
createdFoo.textContent = 'Hello';
assert.equal(createdFoo.textContent, "Hello");
// Native method
var childDiv = document.createElement('div');
createdFoo.appendChild(childDiv);
assert.equal(createdFoo.lastChild, childDiv);
// Parser initiated instantiation
var container = document.getElementById('container');
container.appendChild(document.createElement("x-foo"));
var parsedFoo = container.firstChild;
assert.equal(parsedFoo.__proto__, fooConstructor.prototype);
assert.equal(parsedFoo.tagName, "x-foo");
// Ensuring the wrapper is retained
parsedFoo.someProperty = 'hello';
assert.equal(parsedFoo.someProperty, container.firstChild.someProperty);
// Having another constructor
var barConstructor = document.registerElement('x-bar', createRegisterParameters());
assert.ok('barConstructor !== fooConstructor');
var createdBar = new barConstructor();
assert.equal(createdBar.tagName, "x-bar");
// Having a subclass
var bazConstructor = document.registerElement('x-baz', { prototype: Object.create(fooConstructor.prototype, { thisIsAlsoPrototype: { value: true } }) });
var createdBaz = new bazConstructor();
assert.equal(createdBaz.tagName, "x-baz");
assert.ok(createdBaz.thisIsPrototype);
assert.ok(createdBaz.thisIsAlsoPrototype);
// With irregular cases
var createdUpperBar = document.createElement('X-BAR');
var createdMixedBar = document.createElement('X-Bar');
assert.notEqual(createdUpperBar.constructor, barConstructor);
assert.notEqual(createdUpperBar.tagName, "x-bar");
assert.notEqual(createdMixedBar.constructor, barConstructor);
assert.notEqual(createdMixedBar.tagName, "x-bar");
// Constructors shouldn't interfere with each other
assert.equal((new fooConstructor).tagName, "x-foo");
assert.equal((new barConstructor).tagName, "x-bar");
assert.equal((new bazConstructor).tagName, "x-baz");
});
});
</script>
</body>
</html>

View File

@@ -1,2 +0,0 @@
CONSOLE: LOG: Constructor object isn't created.
Fuzzing document.registerElement() through getters. PASS unless crash.

View File

@@ -1,18 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
<body>
<div id="container"></div>
Fuzzing document.registerElement() through getters. PASS unless crash.
<script>
fuzzer.setupObjectHooks({
prototypeGet: function() { },
prototypeSet: function(value) { },
constructorGet: function() { },
constructorSet: function(value) { }
});
fuzzer.exerciseDocumentRegister();
</script>
</body>
</html>

View File

@@ -1 +0,0 @@
Fuzzing document.registerElement() through getters. PASS uless crash.

View File

@@ -1,21 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
<body>
<div id="container"></div>
Fuzzing document.registerElement() through getters. PASS uless crash.
<script>
var badPrototype = Image.prototype;
var badConstructor = Image.prototype.constructor;
fuzzer.setupObjectHooks({
prototypeGet: function() { return badPrototype; },
prototypeSet: function(value) { },
constructorGet: function() { return badConstructor; },
constructorSet: function(value) { }
});
fuzzer.exerciseDocumentRegister();
</script>
</body>
</html>

View File

@@ -1,2 +0,0 @@
CONSOLE: LOG: Constructor object isn't created.
Fuzzing document.registerElement() through getters. PASS unless crash.

View File

@@ -1,18 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
<body>
<div id="container"></div>
Fuzzing document.registerElement() through getters. PASS unless crash.
<script>
fuzzer.setupObjectHooks({
prototypeGet: function() { throw "Error"; },
prototypeSet: function(value) { throw "Error"; },
constructorGet: function() { throw "Error"; },
constructorSet: function(value) { throw "Error"; }
});
fuzzer.exerciseDocumentRegister();
</script>
</body>
</html>

View File

@@ -1,2 +0,0 @@
Tests unresolved element not leaking if never resolved.

View File

@@ -1,13 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<body>
Tests unresolved element not leaking if never resolved.
<div id="container"></div>
<script>
// Verify that a custom tag for which no element is ever registered
// doesn't cause a document nor elements to leak.
var host = document.createElement('div');
host.appendChild(document.createElement('x-a'));
</script>
</body>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 Custom element constructor should inherit from the passed constructor
1 tests
1 pass
0 fail

View File

@@ -1,19 +0,0 @@
<html>
<import src="../resources/mocha.sky" />
<import src="../resources/chai.sky" />
<script>
describe("Custom element constructor", function() {
it("should inherit from the passed constructor", function() {
class TestElementClass extends HTMLElement {
static test() { return 10; }
}
var TestElement = document.registerElement("test-element-1", {
prototype: TestElementClass.prototype,
});
assert.isFunction(TestElement.test);
assert.equal(TestElement.test(), 10);
assert.equal(Object.getPrototypeOf(TestElement), TestElementClass);
});
});
</script>
</html>

View File

@@ -1 +0,0 @@
Tests that type extension of a element whose DOM interface is HTMLElement does not assert

View File

@@ -1,11 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<body>
<section id="a" is="x-a"></section>
Tests that type extension of a element whose DOM interface is HTMLElement does not assert
<script>
var u = document.querySelector('#a');
var v = document.createElement('section', 'x-a');
</script>
</body>
</html>

View File

@@ -1,10 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<body>
<script>
document.registerElement("x-foo", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function () { this.innerHTML = "<x-foo>Hello</x-foo>"; } } }) });
document.createElement("x-foo");
console.log("PASS unless crash");
</script>
</body>
</html>

View File

@@ -1 +0,0 @@
This test ensures that is visible in following script block.

View File

@@ -1,29 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<import src="../resources/chai.sky" />
<body>
This test ensures that is visible in following script block.
<script>
window.callbacksCalled = [];
function fooCreatedFunction() {
assert.deepEqual(window.callbacksCalled, []);
window.callbacksCalled.push(this.tagName);
this.appendChild(document.createElement("x-bar"));
assert.deepEqual(window.callbacksCalled, ['x-foo', 'x-bar']);
}
function barCreatedFunction() {
assert.deepEqual(window.callbacksCalled, ['x-foo']);
window.callbacksCalled.push(this.tagName);
}
document.registerElement("x-foo", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: fooCreatedFunction } }) });
document.registerElement("x-bar", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: barCreatedFunction } }) });
</script>
<script>
document.createElement("x-foo");
assert.deepEqual(window.callbacksCalled, ['x-foo', 'x-bar']);
</script>
</body>
</html>

View File

@@ -1,2 +0,0 @@
This test ensures that the lifecycle callback of a parser-made element is visible in following script block.

View File

@@ -1,15 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<import src="../resources/chai.sky" />
<body>
This test ensures that the lifecycle callback of a parser-made element is visible in following script block.
<script>
var proto = Object.create(HTMLElement.prototype, { createdCallback: { value: function() { window.callbacksCalled = true; } } });
document.registerElement("x-foo", { prototype: proto });
</script>
<x-foo></x-foo>
<script>
assert.ok("window.callbacksCalled");
</script>
</body>
</html>

View File

@@ -1,60 +0,0 @@
<script>
function setupObjectHooks(hooks)
{
// Wrapper for these object should be materialized before setting hooks.
console.log;
document.register;
Object.defineProperty(Object.prototype, "prototype", {
get: function() { return hooks.prototypeGet(); },
set: function(value) { return hooks.prototypeSet(value); }
});
Object.defineProperty(Object.prototype, "constructor", {
get: function() { return hooks.constructorGet(); },
set: function(value) { return hooks.constructorSet(value); }
});
return hooks;
}
function exerciseDocumentRegister()
{
register('x-a', {});
register('x-b', {prototype: Object.create(HTMLElement.prototype)});
}
function register(name, options)
{
var myConstructor = null;
try {
myConstructor = document.registerElement(name, options);
} catch (e) { }
try {
if (!myConstructor) {
console.log("Constructor object isn't created.");
return;
}
if (myConstructor.prototype != options.prototype) {
console.log("FAIL: bad prototype");
return;
}
var element = new myConstructor();
if (!element)
return;
if (element.constructor != myConstructor) {
console.log("FAIL: bad constructor");
return;
}
} catch (e) { console.log(e); }
}
module.exports = {
setupObjectHooks: setupObjectHooks,
exerciseDocumentRegister: exerciseDocumentRegister,
register: register,
}
</script>

View File

@@ -1,18 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="/sky/framework/inspector/css-agent.sky" as="CSSAgent" />
<script>
var fakeDOMAgent = {
getNodeForId: function(id) {
return document.documentElement;
}
};
var cssAgent = new CSSAgent(fakeDOMAgent);
cssAgent.enable();
var response = cssAgent.getComputedStyleForNode({nodeId: '1'});
assert.isTrue(response["computedStyle"].length > 0);
internals.notifyTestComplete("Done!");
</script>
</html>

View File

@@ -1,6 +0,0 @@
CONSOLE: LOG: DOM.childNodeInserted
CONSOLE: LOG: 2
CONSOLE: LOG: 3
CONSOLE: LOG: DOM.childNodeInserted
CONSOLE: LOG: 3
adding

View File

@@ -1,34 +0,0 @@
<html>
<import src="/sky/framework/inspector/dom-agent.sky" as="DOMAgent" />
<div></div>
<script>
// FIXME: This shows a bug in our DOM mutation handling, we should
// only get one childNodeInserted record here, but we get two, which
// means the inspector shows two nodes where it should only show one.
// setTimeout to flush pending DOM modifications and measure
// only the changes we want to.
setTimeout(function() {
var delegate = {
sendMessage: function(message, params) {
console.log(message);
if (params.node)
console.log(params.node.nodeId);
if (params.node && params.node.children)
console.log(params.node.children[0].nodeId);
}
};
var domAgent = new DOMAgent(delegate);
domAgent.enable();
var adding = document.createElement('adding');
document.querySelector('div').appendChild(adding);
adding.textContent = 'adding';
setTimeout(function() {
internals.notifyTestComplete(internals.contentAsText());
});
});
</script>
</html>

View File

@@ -1,36 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="/sky/framework/inspector/dom-agent.sky" as="DOMAgent" />
<div><div></div></div>
<script>
// setTimeout to flush pending DOM modifications and measure
// only the changes we want to.
var expectedMessages = [
'DOM.childNodeRemoved',
'DOM.childNodeInserted',
];
var actualMessages = [];
setTimeout(function() {
var delegate = {
sendMessage: function(message, params) {
actualMessages.push(message);
}
};
var domAgent = new DOMAgent(delegate);
domAgent.enable();
var adding = document.createElement('adding');
var container = document.querySelector('div');
container.firstChild.remove();
container.appendChild(document.createElement('adding'));
setTimeout(function() {
assert.equal(JSON.stringify(expectedMessages),
JSON.stringify(actualMessages));
internals.notifyTestComplete("Done!");
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 PageAgent.getResourceTree should dump the current resource tree
1 tests
1 pass
0 fail

View File

@@ -1,43 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<import src="/sky/framework/inspector/page-agent.sky" as="PageAgent" />
<img src='does_not_exist.jpg' />
<script>
describe('PageAgent.getResourceTree', function() {
it('should dump the current resource tree', function() {
var pageAgent = new PageAgent();
pageAgent.enable();
var resourceTree = pageAgent.getResourceTree();
assert.deepEqual(resourceTree, {
"frameTree": {
"frame": {
"id": "1",
"loaderId": "1",
"url": "http://127.0.0.1:8000/sky/tests/inspector/page-agent-get-resource-tree.sky",
"mimeType": "text/html",
"securityOrigin": "http://127.0.0.1:8000/sky/tests/inspector/page-agent-get-resource-tree.sky"
},
"resources": [{
"url": "http://127.0.0.1:8000/sky/tests/resources/chai.sky",
"type": "Document",
"mimeType": "text/html"
}, {
"url": "http://127.0.0.1:8000/sky/tests/resources/mocha.sky",
"type": "Document",
"mimeType": "text/html"
}, {
"url": "http://127.0.0.1:8000/sky/framework/inspector/page-agent.sky",
"type": "Document",
"mimeType": "text/html"
}, {
"url": "http://127.0.0.1:8000/sky/tests/inspector/does_not_exist.jpg",
"type": "Image",
"mimeType": "image/unknown"
}]
}
});
});
});
</script>
</html>

View File

@@ -1,14 +0,0 @@
Running 10 tests
ok 1 ES6 classes should create instances
ok 2 ES6 classes should create subclasses
ok 3 ES6 classes should create anonymous classes
ok 4 ES6 classes should put methods on the prototype
ok 5 ES6 classes should call methods with |this|
ok 6 ES6 classes should let toMethod rebind super
ok 7 ES6 classes should support super() constructor calls
ok 8 ES6 classes should automatically call super() in default constructor
ok 9 ES6 classes should call super.method()
ok 10 ES6 classes should support getters and setters
10 tests
10 pass
0 fail

View File

@@ -1,163 +0,0 @@
<sky>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe("ES6 classes", function() {
it("should create instances", function() {
class Example {}
var instance = new Example();
assert.instanceOf(instance, Example);
});
it("should create subclasses", function() {
class Parent {}
class Child extends Parent {}
var instance = new Child();
assert.instanceOf(instance, Child);
assert.instanceOf(instance, Parent);
});
it("should create anonymous classes", function() {
var Parent = class {}
var Child = class extends Parent {}
var instance = new Child();
assert.instanceOf(instance, Child);
assert.instanceOf(instance, Parent);
});
it("should put methods on the prototype", function() {
class Test {
exampleMethod() { }
}
var instance = new Test();
assert.isFalse(instance.hasOwnProperty("exampleMethod"));
var proto = Object.getPrototypeOf(instance);
assert.isTrue(proto.hasOwnProperty("exampleMethod"));
});
it("should call methods with |this|", function() {
class Adder {
constructor(value) {
this.value = value;
}
add(other) {
return this.value + other;
}
}
var adder = new Adder(10);
assert.equal(adder.add(15), 25);
});
it("should let toMethod rebind super", function() {
var getValue = function() {
assert.isFunction(this.value);
assert.isFunction(this.superValue);
return this.value() + super.superValue();
}
class HolderParent {
superValue() {
return 5;
}
}
class Holder extends HolderParent {
constructor() {
this.value_ = 5;
}
value() {
return this.value_;
}
}
var holder = new Holder();
var getValueMethod = getValue.toMethod(Holder.prototype);
assert.equal(getValueMethod.call(holder), 10);
});
it("should support super() constructor calls", function() {
class Parent {
constructor(value) {
this.value = value;
}
}
class Child extends Parent {
constructor(value) {
super(value + 5);
}
}
var child = new Child(10);
assert.equal(child.value, 15);
});
it("should automatically call super() in default constructor", function() {
class Parent {
constructor() {
this.value = 10;
}
}
class Child extends Parent {
}
var child = new Child();
assert.equal(child.value, 10);
});
it("should call super.method()", function() {
class Parent {
value() {
return 10;
}
}
class Child extends Parent {
value() {
return super.value() + 5;
}
}
var child = new Child();
assert.equal(child.value(), 15);
});
it("should support getters and setters", function() {
class Variable {
constructor(value) {
this.value_ = value;
}
get value() {
return this.value_;
}
set value(newValue) {
this.value_ = newValue;
}
}
var variable = new Variable("first");
// Methods are on the prototype.
var proto = Object.getPrototypeOf(variable);
var descriptor = Object.getOwnPropertyDescriptor(proto, "value");
assert.isObject(descriptor);
assert.isFunction(descriptor.get);
assert.isFunction(descriptor.set);
assert.isUndefined(descriptor.value);
// Getter and setter should not be on the instance.
assert.isUndefined(Object.getOwnPropertyDescriptor(variable, "value"));
assert.equal(variable.value, "first");
assert.equal(variable.value_, "first");
variable.value = "second";
assert.equal(variable.value, "second");
assert.equal(variable.value_, "second");
});
});
</script>
</sky>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 This suite should run this test
1 tests
1 pass
0 fail

View File

@@ -1,20 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe.only('This suite', function() {
it('should run this test', function() {
assert.ok(true);
});
});
describe('That suite', function() {
it('should not run this test', function() {
assert.ok(false);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 This suite should only run this test
1 tests
1 pass
0 fail

View File

@@ -1,18 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('This suite', function() {
it.only('should only run this test', function() {
assert.ok(true);
});
it('should not run this test', function() {
assert.ok(false);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver should pass the callback and observer arguments
1 tests
1 pass
0 fail

View File

@@ -1,18 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver', function() {
it('should pass the callback and observer arguments', function(done) {
var mutationObserver = new MutationObserver(function(mutations, observer) {
assert.equal(this, mutationObserver);
assert.equal(mutationObserver, observer);
done();
});
var div = document.createElement('div');
mutationObserver.observe(div, {attributes: true});
div.setAttribute('foo', 'bar');
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 Transient registrations should be cleared even without delivery
1 tests
1 pass
0 fail

View File

@@ -1,28 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('Transient registrations', function() {
it('should be cleared even without delivery', function(done) {
var mutationsDelivered = false;
var observer = new MutationObserver(function(mutations) {
mutationsDelivered = true;
});
var div = document.createElement('div');
var span = div.appendChild(document.createElement('span'));
observer.observe(div, {attributes: true, subtree: true});
div.removeChild(span);
setTimeout(function() {
// By the time this function runs the transient registration should
// be cleared, so we expect not to be notified of this attribute
// mutation.
span.setAttribute('bar', 'baz');
setTimeout(function() {
assert.notOk(mutationsDelivered);
done();
}, 0);
}, 0);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObservers must wait for the next loop when created during delivery
1 tests
1 pass
0 fail

View File

@@ -1,37 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
window.jsTestIsAsync = true;
describe('MutationObservers', function() {
it ('must wait for the next loop when created during delivery', function(done) {
var order = [];
var div = document.createElement('div');
var observer3;
var observer1 = new MutationObserver(function(mutations) {
order.push(1);
if (!observer3) {
observer3 = new MutationObserver(function(mutations) {
order.push(3);
});
observer3.observe(div, {attributes: true});
div.setAttribute('foo', 'baz');
}
});
var observer2 = new MutationObserver(function(mutations) {
order.push(2);
});
observer1.observe(div, {attributes: true});
observer2.observe(div, {attributes: true});
div.setAttribute('foo', 'bar');
setTimeout(function() {
assert.deepEqual(order, [1, 2, 1, 3]);
done();
}, 0);
});
});
</script>
</html>

View File

@@ -1,6 +0,0 @@
Running 2 tests
ok 1 MutationObserver cross document moves should handle basic observation
ok 2 MutationObserver cross document moves should handle subtree observation
2 tests
2 pass
0 fail

View File

@@ -1,49 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver cross document moves', function() {
it('should handle basic observation', function(done) {
var mutations;
var div = document.createElement('div');
var observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true});
var newDoc = new Document();
newDoc.appendChild(div);
div.id = 'foo';
setTimeout(function() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, 'attributes');
assert.equal(mutations[0].target, div);
assert.equal(mutations[0].attributeName, 'id');
observer.disconnect();
done();
}, 0);
});
it('should handle subtree observation', function(done) {
var mutations;
var div = document.createElement('div');
var subDiv = div.appendChild(document.createElement('div'));
var observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true, subtree: true});
var newDoc = new Document();
newDoc.appendChild(div);
subDiv.id = 'foo';
setTimeout(function() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, 'attributes');
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, 'id');
observer.disconnect();
done();
}, 0);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver should deliver in order of creation
1 tests
1 pass
0 fail

View File

@@ -1,40 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver', function() {
it('should deliver in order of creation', function(done) {
var order = [];
var observers = [];
function setUpOrdering(num) {
observers.push(new MutationObserver(function(mutations) {
order.push(num);
}));
}
for (var i = 0; i < 10; ++i)
setUpOrdering(i);
var div = document.createElement('div');
observers[3].observe(div, {attributes: true});
observers[2].observe(div, {characterData: true, subtree: true});
observers[1].observe(div, {attributes: true});
observers[7].observe(div, {childList: true});
observers[4].observe(div, {attributes: true});
observers[9].observe(div, {attributes: true});
observers[0].observe(div, {childList: true});
observers[5].observe(div, {attributes: true});
observers[6].observe(div, {characterData: true, subtree: true});
observers[8].observe(div, {attributes: true});
div.setAttribute('foo', 'bar');
div.appendChild(new Text('hello'));
div.firstChild.textContent = 'goodbye';
setTimeout(function() {
assert.deepEqual(order, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
done();
}, 0);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver.disconnect should cancel pending delivery
1 tests
1 pass
0 fail

View File

@@ -1,44 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.disconnect', function() {
it('should cancel pending delivery', function(done) {
var mutations;
var observer;
var div;
function start() {
mutations = null;
div = document.createElement('div');
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { attributes: true });
div.setAttribute('foo', 'bar');
observer.disconnect();
setTimeout(next, 0);
}
function next() {
// Disconnecting should cancel any pending delivery...
assert.equal(mutations, null);
observer.observe(div, { attributes: true });
div.setAttribute('bar', 'baz');
setTimeout(finish, 0);
}
function finish() {
// ...and re-observing should not see any of the previously-generated records.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].attributeName, "bar");
done();
}
start();
});
});
</script>
</html>

View File

@@ -1,7 +0,0 @@
Running 3 tests
ok 1 DocumentFragments should remove all children of the fragment before moving children, using appendChild
ok 2 DocumentFragments should remove all children of the fragment before moving children, using insertBefore
ok 3 DocumentFragments should remove all children of the fragment before moving children, using replaceChild
3 tests
3 pass
0 fail

View File

@@ -1,69 +0,0 @@
<html>
<import src="../resources/mocha.sky" />
<import src="../resources/chai.sky" />
<script>
describe('DocumentFragments should remove all children of the fragment before moving children, ', function() {
var mutations;
var observer;
beforeEach(function() {
mutations = null;
observer = new MutationObserver(function(records) {
mutations = records;
});
});
function createObservedFragment() {
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createElement('b'));
fragment.appendChild(document.createElement('i'));
observer.observe(fragment, {childList: true});
return fragment;
}
it('using appendChild', function(done) {
var div = document.createElement('div');
observer.observe(div, {childList: true});
div.appendChild(createObservedFragment());
setTimeout(function() {
assert.equal(mutations.length, 2);
assert.equal(mutations[0].addedNodes.length, 0);
assert.equal(mutations[0].removedNodes.length, 2);
assert.equal(mutations[1].addedNodes.length, 2);
assert.equal(mutations[1].removedNodes.length, 0);
done();
}, 0);
});
it('using insertBefore', function(done) {
var div = document.createElement('div');
div.appendChild(document.createElement('span'));
observer.observe(div, {childList: true});
div.insertBefore(createObservedFragment(), div.firstChild);
setTimeout(function() {
assert.equal(mutations.length, 2);
assert.equal(mutations[0].addedNodes.length, 0);
assert.equal(mutations[0].removedNodes.length, 2);
assert.equal(mutations[1].addedNodes.length, 2);
assert.equal(mutations[1].removedNodes.length, 0);
done();
}, 0);
});
it('using replaceChild', function(done) {
var div = document.createElement('div');
div.appendChild(document.createElement('span'));
observer.observe(div, {childList: true});
div.replaceChild(createObservedFragment(), div.firstChild);
setTimeout(function() {
assert.equal(mutations.length, 2);
assert.equal(mutations[0].addedNodes.length, 0);
assert.equal(mutations[0].removedNodes.length, 2);
assert.equal(mutations[1].addedNodes.length, 2);
assert.equal(mutations[1].removedNodes.length, 1);
done();
}, 0);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver should not interrupt delivery order on getting mutations during delivery
1 tests
1 pass
0 fail

View File

@@ -1,34 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver', function() {
it('should not interrupt delivery order on getting mutations during delivery', function(done) {
function finish() {
assert.deepEqual(order, [1, 3, 2]);
done();
}
var order = [];
var div = document.createElement('div');
var observer1 = new MutationObserver(function(mutations) {
order.push(1);
div.appendChild(document.createElement('span'));
});
var observer2 = new MutationObserver(function(mutations) {
order.push(2);
});
var observer3 = new MutationObserver(function(mutations) {
order.push(3);
});
observer1.observe(div, {attributes: true});
observer2.observe(div, {childList: true});
observer3.observe(div, {attributes: true});
div.setAttribute('foo', 'bar');
setTimeout(finish, 0);
});
});
</script>
</html>

View File

@@ -1,15 +0,0 @@
<html>
<import src="../resources/dump-as-text.sky" />
<body id="body">
<script>
function mutationCallback(mutations, observer) {
mutations[0].addedNodes[-1];
}
var mutationObserver = new MutationObserver(mutationCallback);
var body = document.getElementById("body");
mutationObserver.observe(body, {childList: true});
body.appendChild(new Text("PASS. We didn't crash"));
</script>
</body>
</html>

View File

@@ -1,6 +0,0 @@
Running 2 tests
ok 1 MutationObserver should have methods
ok 2 MutationObserver should throw with incorrect constructor args
2 tests
2 pass
0 fail

View File

@@ -1,28 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver', function() {
var observer = new MutationObserver(function(mutations) { });
it('should have methods', function() {
assert.equal(typeof observer.observe, 'function');
assert.equal(typeof observer.disconnect, 'function');
});
it('should throw with incorrect constructor args', function() {
assert.throw(function() {
new MutationObserver({ handleEvent: function() {} });
}, TypeError);
assert.throw(function() {
new MutationObserver({});
}, TypeError);
assert.throw(function() {
new MutationObserver(42);
}, TypeError);
assert.throw(function() {
new MutationObserver("foo");
}, TypeError);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationRecord should be exposed on window but not constructable
1 tests
1 pass
0 fail

View File

@@ -1,22 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationRecord', function() {
it('should be exposed on window but not constructable', function() {
assert.ok(window.MutationRecord);
assert.equal(typeof MutationRecord, "function");
assert.throw(function() {
new MutationRecord
}, TypeError);
var div = document.createElement('div');
var observer = new MutationObserver(function(){});
observer.observe(div, {attributes: true});
div.id = 'foo';
var record = observer.takeRecords()[0];
assert.ok(record instanceof MutationRecord);
});
});
</script>
</html>

View File

@@ -1,7 +0,0 @@
Running 3 tests
ok 1 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on characterData records
ok 2 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on childList records
ok 3 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on attribute records
3 tests
3 pass
0 fail

View File

@@ -1,42 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty', function() {
var observer = new MutationObserver(function() {});
it('on characterData records', function() {
var text = new Text('something');
observer.observe(text, {characterData: true});
text.data = 'something else';
var record = observer.takeRecords()[0];
assert.isNull(record.attributeName);
assert.isNull(record.oldValue);
assert.isNull(record.previousSibling);
assert.isNull(record.nextSibling);
assert.equal(record.addedNodes.length, 0);
assert.equal(record.removedNodes.length, 0);
});
it('on childList records', function() {
var div = document.createElement('div');
observer.observe(div, {childList: true});
div.appendChild(document.createElement('span'));
var record = observer.takeRecords()[0];
assert.isNull(record.attributeName);
assert.isNull(record.oldValue);
});
it('on attribute records', function() {
var div = document.createElement('div');
observer.observe(div, {attributes: true});
div.setAttribute('data-foo', 'bar');
var record = observer.takeRecords()[0];
assert.isNull(record.oldValue);
assert.isNull(record.previousSibling);
assert.isNull(record.nextSibling);
assert.equal(record.addedNodes.length, 0);
assert.equal(record.removedNodes.length, 0);
});
});
</script>
</html>

View File

@@ -1,20 +0,0 @@
ERROR: Failed to load resource: the server responded with a status of 404 ()
SOURCE: http://127.0.0.1:8000/sky/tests/mutation-observer/baz.png:0
Running 14 tests
ok 1 MutationObserver.observe on attributes should handle basic aspects of attribute observation
ok 2 MutationObserver.observe on attributes should not notify of attribute changes without asking
ok 3 MutationObserver.observe on attributes re-observing the same node with the same observer has the effect of resetting the options
ok 4 MutationObserver.observe on attributes multiple observers can be registered to a given node and both receive mutations
ok 5 MutationObserver.observe on attributes should deliver mutations on modifications to node properties which delegate to attribute storage
ok 6 MutationObserver.observe on attributes should handle basic oldValue delivery
ok 7 MutationObserver.observe on attributes should deliver oldValue when needed
ok 8 MutationObserver.observe on attributes should give attributeOldValue if any entries request it with multiple observers
ok 9 MutationObserver.observe on attributes should handle setting an attribute via reflected IDL attribute
ok 10 MutationObserver.observe on attributes should respect attributeFilter on HTML elements
ok 11 MutationObserver.observe on attributes should respect different attributeFilters when observing multiple subtree nodes
ok 12 MutationObserver.observe on attributes should create records for the style property
ok 13 MutationObserver.observe on attributes should have oldValue for style property mutations
ok 14 MutationObserver.observe on attributes should not create records for noop style property mutation
14 tests
14 pass
0 fail

View File

@@ -1,569 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.observe on attributes', function() {
it('should handle basic aspects of attribute observation', function(done) {
var div;
var observer;
var mutations;
function start() {
div = document.createElement('div');
div.setAttribute('bar', 'foo');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, { attributes: true, characterData: true });
div.setAttribute('foo', 'bar');
div.removeAttribute('bar');
setTimeout(checkDisconnectAndMutate, 0);
}
function checkDisconnectAndMutate() {
// ...can attribute changes be observed at all
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "bar");
mutations = null;
observer.disconnect();
div.setAttribute('foo', 'baz');
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
}
function checkNotDeliveredAndMutateMultiple() {
// ...observer.disconnect() should prevent further delivery of mutations.
assert.equal(mutations, null);
observer.observe(div, { attributes: true });
div.setAttribute('foo', 'bat');
div.setAttribute('bar', 'foo');
setTimeout(finish);
}
function finish() {
// ...re-observing after disconnect works with the same observer.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "bar");
observer.disconnect();
done();
}
start();
});
it('should not notify of attribute changes without asking', function(done) {
var div;
var observer;
var mutations;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, { childList: true, characterData: true });
div.setAttribute('foo', 'bar');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('re-observing the same node with the same observer has the effect of resetting the options', function(done) {
var div;
var observer;
var mutations;
var calls = 0;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(records) {
mutations = records;
calls++;
});
observer.observe(div, { attributes: true, characterData: true });
observer.observe(div, { attributes: true });
div.setAttribute('foo', 'bar');
setTimeout(checkDisconnectAndMutate, 0);
}
function checkDisconnectAndMutate() {
assert.equal(calls, 1);
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
mutations = null;
observer.observe(div, { attributes: true, characterData: true });
observer.observe(div, { childList: true });
div.setAttribute('foo', 'baz');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('multiple observers can be registered to a given node and both receive mutations', function(done) {
var div;
var observer;
var observer2;
var mutations;
var mutations2;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer2 = new MutationObserver(function(records) {
mutations2 = records;
});
observer.observe(div, { attributes: true });
observer2.observe(div, { attributes: true });
div.setAttribute('foo', 'bar');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations2.length, 1);
assert.equal(mutations2[0].type, "attributes");
assert.equal(mutations2[0].attributeName, "foo");
observer.disconnect();
observer2.disconnect();
done();
}
start();
});
it('should deliver mutations on modifications to node properties which delegate to attribute storage', function(done) {
var img, a;
var observer;
var mutations;
function start() {
img = document.createElement('img');
a = document.createElement('a');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(img, { attributes: true });
observer.observe(a, { attributes: true });
img.src = 'baz.png';
a.href = 'foo.html';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "src");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "href");
observer.disconnect();
done();
}
start();
});
it('should handle basic oldValue delivery', function(done) {
var div;
var observer;
var mutations;
function start() {
div = document.createElement('div');
div.setAttribute('bar', 'boo');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, { attributes: true, attributeOldValue: true });
div.setAttribute('foo', 'bar');
div.setAttribute('foo', 'baz');
div.removeAttribute('bar');
div.removeAttribute('non-existant');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[0].oldValue, null);
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "foo");
assert.equal(mutations[1].oldValue, "bar");
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "bar");
assert.equal(mutations[2].oldValue, "boo");
observer.disconnect();
done();
}
start();
});
it('should deliver oldValue when needed', function(done) {
var div;
var observerWithOldValue;
var observer;
var mutationsWithOldValue;
var mutations;
function start() {
div = document.createElement('div');
div.setAttribute('foo', 'bar');
observerWithOldValue = new MutationObserver(function(records) {
mutationsWithOldValue = records;
});
observer = new MutationObserver(function(records) {
mutations = records;
});
observerWithOldValue.observe(div, { attributes: true, attributeOldValue: true });
observer.observe(div, { attributes: true });
div.setAttribute('foo', 'baz');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutationsWithOldValue.length, 1);
assert.equal(mutationsWithOldValue[0].type, "attributes");
assert.equal(mutationsWithOldValue[0].attributeName, "foo");
assert.equal(mutationsWithOldValue[0].oldValue, "bar");
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[0].oldValue, null);
observerWithOldValue.disconnect();
observer.disconnect();
done();
}
start();
});
it('should give attributeOldValue if any entries request it with multiple observers', function(done) {
var div;
var span;
var observer;
var mutations;
function start() {
div = document.createElement('div');
span = div.appendChild(document.createElement('span'));
span.setAttribute('foo', 'bar');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, { attributes: true, attributeOldValue: true, subtree: true });
observer.observe(span, { attributes: true });
span.setAttribute('foo', 'baz');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[0].oldValue, "bar");
observer.disconnect();
done();
}
start();
});
it('should handle setting an attribute via reflected IDL attribute', function(done) {
var div;
var observer;
var mutations;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, { attributes: true, attributeOldValue: true });
div.id = 'foo';
div.id = 'bar';
div.id = null;
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "id");
assert.equal(mutations[0].oldValue, null);
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "id");
assert.equal(mutations[1].oldValue, "foo");
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "id");
assert.equal(mutations[2].oldValue, "bar");
observer.disconnect();
done();
}
start();
});
it('should respect attributeFilter on HTML elements', function(done) {
var div, path;
var observer;
var mutations;
function start() {
observer = new MutationObserver(function(records) {
mutations = records;
});
div = document.createElement('div');
observer.observe(div, { attributes: true, attributeFilter: ['foo', 'bar', 'booM'] });
div.setAttribute('foo', 'foo');
div.setAttribute('bar', 'bar');
div.setAttribute('baz', 'baz');
div.setAttribute('BOOm', 'boom');
setTimeout(finish, 0);
}
function finish() {
// ...only foo and bar should be received.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "bar");
observer.disconnect();
done();
}
start();
});
it('should respect different attributeFilters when observing multiple subtree nodes', function(done) {
var div, div2, div3;
var observer;
var mutations;
function start() {
observer = new MutationObserver(function(records) {
mutations = records;
});
div = document.createElement('div');
div2 = div.appendChild(document.createElement('div'));
div3 = div2.appendChild(document.createElement('div'));
observer.observe(div, { attributes: true, subtree: true, attributeFilter: ['foo', 'bar'] });
observer.observe(div2, { attributes: true, subtree: true, attributeFilter: ['bar', 'bat'] });
div3.setAttribute('foo', 'foo');
div3.setAttribute('bar', 'bar');
div3.setAttribute('bat', 'bat');
div3.setAttribute('baz', 'baz');
setTimeout(checkAndObserveAll, 0);
}
function checkAndObserveAll() {
// ...only foo, bar & bat should be received.
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "bar");
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "bat");
observer.observe(div2, { attributes: true, subtree: true });
div3.setAttribute('bar', 'bar');
div3.setAttribute('bat', 'bat');
div3.setAttribute('baz', 'baz');
setTimeout(finish, 0);
}
function finish() {
// ...bar, bat & baz should all be received.
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "bar");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "bat");
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "baz");
observer.disconnect();
done();
}
start();
});
it('should create records for the style property', function(done) {
var div, path;
var observer;
var mutations;
function start() {
observer = new MutationObserver(function(records) {
mutations = records;
});
div = document.createElement('div');
div.setAttribute('style', 'color: yellow; width: 100px;');
observer.observe(div, { attributes: true });
div.style.color = 'red';
div.style.width = '200px';
div.style.color = 'blue';
setTimeout(checkAndContinue, 0);
}
function checkAndContinue() {
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "style");
assert.equal(mutations[0].oldValue, null);
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "style");
assert.equal(mutations[1].oldValue, null);
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "style");
assert.equal(mutations[2].oldValue, null);
mutations = null;
div.getAttribute('style');
setTimeout(finish, 0);
}
function finish() {
// ...mutation record created.
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('should have oldValue for style property mutations', function(done) {
var div, path;
var observer;
var mutations;
function start() {
observer = new MutationObserver(function(records) {
mutations = records;
});
div = document.createElement('div');
div.setAttribute('style', 'color: yellow; width: 100px;');
observer.observe(div, { attributes: true, attributeOldValue: true });
div.style.color = 'red';
div.style.width = '200px';
div.style.color = 'blue';
setTimeout(checkAndContinue, 0);
}
function checkAndContinue() {
assert.equal(mutations.length, 3);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].attributeName, "style");
assert.equal(mutations[0].oldValue, "color: yellow; width: 100px;");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].attributeName, "style");
assert.equal(mutations[1].oldValue, "color: rgb(255, 0, 0); width: 100px;");
assert.equal(mutations[2].type, "attributes");
assert.equal(mutations[2].attributeName, "style");
assert.equal(mutations[2].oldValue, "color: rgb(255, 0, 0); width: 200px;");
mutations = null;
div.getAttribute('style');
setTimeout(finish, 0);
}
function finish() {
// ...mutation record created.
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('should not create records for noop style property mutation', function(done) {
var div, path;
var observer;
var mutations;
function start() {
observer = new MutationObserver(function(records) {
mutations = records;
});
div = document.createElement('div');
div.setAttribute('style', 'color: yellow; width: 100px;');
observer.observe(div, { attributes: true });
div.style.removeProperty('height');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
});
</script>
</body>
</html>

View File

@@ -1,10 +0,0 @@
Running 6 tests
ok 1 MutationObserver on character data should handle basic aspects of characterData observation
ok 2 MutationObserver on character data should only notify of characterData changes when requested
ok 3 MutationObserver on character data should allow multiple observers can be registered to a given node and both receive mutations
ok 4 MutationObserver on character data should provide oldValue is returned when requested
ok 5 MutationObserver on character data should allow observing both with and without oldValue
ok 6 MutationObserver on character data should provide oldValue if any observation requests it
6 tests
6 pass
0 fail

View File

@@ -1,229 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<body id="body">
<script>
document.body = document.getElementById("body");
describe('MutationObserver on character data', function() {
it('should handle basic aspects of characterData observation', function(done) {
var observer;
var mutations;
var charDataNode;
function start() {
var div = document.createElement('div');
div.textContent = 'foo';
charDataNode = div.firstChild;
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(charDataNode, {characterData: true});
charDataNode.textContent = 'bar';
setTimeout(checkDisconnectAndMutate, 0);
}
function checkDisconnectAndMutate() {
// ...can characterData changes be observed at all
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].target, charDataNode);
mutations = null;
observer.disconnect();
charDataNode.textContent = 'baz';
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
}
function checkNotDeliveredAndMutateMultiple() {
// ...observer.disconnect() should prevent further delivery of mutations.
assert.equal(mutations, null);
charDataNode = new Text('');
observer.observe(charDataNode, { characterData: true });
charDataNode.textContent = 'foo';
charDataNode.textContent = 'bar';
setTimeout(finish);
}
function finish() {
// ...re-observing after disconnect works with the same observer.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].target, charDataNode);
assert.equal(mutations[1].type, "characterData");
assert.equal(mutations[1].target, charDataNode);
observer.disconnect();
done();
}
start();
});
it('should only notify of characterData changes when requested', function(done) {
var observer;
var mutations;
function start() {
var div = document.createElement('div');
div.textContent = 'hello';
var charDataNode = div.firstChild;
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(charDataNode, {childList: true, attributes: true});
charDataNode = 'goodbye';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('should allow multiple observers can be registered to a given node and both receive mutations', function(done) {
var observer;
var observer2;
var charDataNode;
var mutations;
var mutations2;
function start() {
var div = document.createElement('div');
div.textContent = 'foo';
charDataNode = div.firstChild;
observer = new MutationObserver(function(records) {
mutations = records;
});
observer2 = new MutationObserver(function(records) {
mutations2 = records;
});
observer.observe(charDataNode, {characterData: true});
observer2.observe(charDataNode, {characterData: true});
charDataNode.textContent = 'bar';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].target, charDataNode);
assert.equal(mutations2.length, 1);
assert.equal(mutations2[0].type, "characterData");
assert.equal(mutations2[0].target, charDataNode);
observer.disconnect();
observer2.disconnect();
done();
}
start();
});
it('should provide oldValue is returned when requested', function(done) {
var observer;
var mutations;
var charDataNode;
function start() {
var div = document.createElement('div');
div.textContent = 'foo';
charDataNode = div.firstChild;
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(charDataNode, {characterData: true, characterDataOldValue: true});
charDataNode.textContent = 'bar';
charDataNode.textContent = 'baz';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].target, charDataNode);
assert.equal(mutations[0].oldValue, "foo");
assert.equal(mutations[1].type, "characterData");
assert.equal(mutations[1].target, charDataNode);
assert.equal(mutations[1].oldValue, "bar");
observer.disconnect();
done();
}
start();
});
it('should allow observing both with and without oldValue', function(done) {
var observerWithOldValue;
var observer;
var mutations;
var mutationsWithOldValue;
function start() {
var div = document.createElement('div');
div.textContent = 'foo';
var charDataNode = div.firstChild;
observerWithOldValue = new MutationObserver(function(records) {
mutationsWithOldValue = records;
});
observer = new MutationObserver(function(records) {
mutations = records;
});
observerWithOldValue.observe(charDataNode, {characterData: true, characterDataOldValue: true});
observer.observe(charDataNode, {characterData: true});
charDataNode.textContent = 'bar';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutationsWithOldValue.length, 1);
assert.equal(mutationsWithOldValue[0].type, "characterData");
assert.equal(mutationsWithOldValue[0].oldValue, "foo");
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].oldValue, null);
observerWithOldValue.disconnect();
observer.disconnect();
done();
}
start();
});
it('should provide oldValue if any observation requests it', function(done) {
var observer;
var mutations;
function start() {
var div = document.createElement('div');
div.textContent = 'foo';
var charDataNode = div.firstChild;
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {characterData: true, characterDataOldValue: true, subtree: true});
observer.observe(charDataNode, {characterData: true});
charDataNode.textContent = 'bar';
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].oldValue, "foo");
observer.disconnect();
done();
}
start();
});
});
</script>
</html>

View File

@@ -1,11 +0,0 @@
Running 7 tests
ok 1 MutationObserver.observe on childList should handle basic observation
ok 2 MutationObserver.observe on childList should handle observing without specifying "childList" does not result in hearing about childList changes
ok 3 MutationObserver.observe on childList should handle re-observing the same node with the same observer has the effect of resetting the options
ok 4 MutationObserver.observe on childList should handle multiple observers can be registered to a given node and both receive mutations
ok 5 MutationObserver.observe on childList should create minimal mutations for replaceChild
ok 6 MutationObserver.observe on childList should create minimal mutations for insertBefore
ok 7 MutationObserver.observe on childList should create minimal mutations for appendChild
7 tests
7 pass
0 fail

View File

@@ -1,322 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.observe on childList', function() {
it('should handle basic observation', function(done) {
var div;
var observer;
var mutations;
var removedDiv1, removedDiv2;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { childList: true });
removedDiv1 = div.appendChild(document.createElement('div'));
setTimeout(checkDisconnectAndMutate, 0);
}
function checkDisconnectAndMutate() {
// ...can childList changes be observed at all.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].addedNodes.length, 1);
assert.equal(mutations[0].addedNodes[0], removedDiv1);
mutations = null;
observer.disconnect();
removedDiv1 = div.appendChild(document.createElement('div'));
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
}
function checkNotDeliveredAndMutateMultiple() {
// ...observer.disconnect() should prevent further delivery of mutations.
assert.equal(mutations, null);
observer.observe(div, { childList: true });
removedDiv1 = div.removeChild(div.firstChild);
removedDiv2 = div.removeChild(div.firstChild);
setTimeout(finish);
}
function finish() {
// ...re-observing after disconnect works with the same observer.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].removedNodes.length, 1);
assert.equal(mutations[0].removedNodes[0], removedDiv1);
assert.equal(mutations[1].type, "childList");
assert.equal(mutations[1].removedNodes.length, 1);
assert.equal(mutations[1].removedNodes[0], removedDiv2);
observer.disconnect();
done();
}
start();
});
it('should handle observing without specifying "childList" does not result in hearing about childList changes', function(done) {
var div;
var observer;
var mutations;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { attributes: true, characterData: true });
div.appendChild(document.createElement('div'));
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('should handle re-observing the same node with the same observer has the effect of resetting the options', function(done) {
var div;
var observer;
var mutations;
var calls = 0;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(m) {
mutations = m;
calls++;
});
observer.observe(div, { childList: true, characterData: true });
observer.observe(div, { childList: true });
div.appendChild(document.createElement('div'));
setTimeout(checkDisconnectAndMutate, 0);
}
function checkDisconnectAndMutate() {
assert.equal(calls, 1);
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
mutations = null;
observer.observe(div, { childList: true, characterData: true });
observer.observe(div, { attributes: true });
div.appendChild(document.createElement('div'));
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations, null);
observer.disconnect();
done();
}
start();
});
it('should handle multiple observers can be registered to a given node and both receive mutations', function(done) {
var div;
var observer;
var observer2;
var mutations;
var mutations2;
function start() {
div = document.createElement('div');
observer = new MutationObserver(function(m) {
mutations = m;
});
observer2 = new MutationObserver(function(m) {
mutations2 = m;
});
observer.observe(div, { childList: true });
observer2.observe(div, { childList: true });
div.appendChild(document.createElement('div'));
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations2.length, 1);
assert.equal(mutations2[0].type, "childList");
observer.disconnect();
observer2.disconnect();
done();
}
start();
});
it('should create minimal mutations for replaceChild', function(done) {
var div;
var observer;
var fragment;
var mutations;
var addedDiv1;
var addedDiv2;
var removedDiv1;
function start() {
div = document.createElement('div');
var first = document.createElement('span');
first.textContent = 'Foo';
div.appendChild(first);
var second = document.createElement('div');
second.textContent = 'Bar';
div.appendChild(second);
removedDiv1 = div.firstChild;
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { childList: true });
addedDiv1 = document.createElement('div');
div.replaceChild(addedDiv1, div.firstChild);
setTimeout(checkReplaceWithNode, 0);
}
function checkReplaceWithNode() {
// ...simple replace child
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].addedNodes.length, 1);
assert.equal(mutations[0].addedNodes[0], addedDiv1);
assert.equal(mutations[0].removedNodes.length, 1);
assert.equal(mutations[0].removedNodes[0], removedDiv1);
mutations = null;
fragment = document.createDocumentFragment();
addedDiv1 = fragment.appendChild(document.createElement('div'));
addedDiv2 = fragment.appendChild(document.createElement('div'));
removedDiv1 = div.firstChild;
div.replaceChild(fragment, removedDiv1);
setTimeout(finish, 0);
}
function finish() {
// ...replace with DocumentFragment.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].addedNodes.length, 2);
assert.equal(mutations[0].addedNodes[0], addedDiv1);
assert.equal(mutations[0].addedNodes[1], addedDiv2);
assert.equal(mutations[0].removedNodes.length, 1);
assert.equal(mutations[0].removedNodes[0], removedDiv1);
observer.disconnect();
done();
}
start();
});
it('should create minimal mutations for insertBefore', function(done) {
var div;
var observer;
var fragment;
var mutations;
var addedDiv1;
var addedDiv2;
function start() {
div = document.createElement('div');
var first = document.createElement('span');
first.textContent = 'Foo';
div.appendChild(first);
fragment = document.createDocumentFragment();
addedDiv1 = fragment.appendChild(document.createElement('div'));
addedDiv2 = fragment.appendChild(document.createElement('div'));
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { childList: true });
div.insertBefore(fragment, div.firstChild);
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].addedNodes.length, 2);
assert.equal(mutations[0].addedNodes[0], addedDiv1);
assert.equal(mutations[0].addedNodes[1], addedDiv2);
assert.equal(mutations[0].removedNodes.length, 0);
observer.disconnect();
done();
}
start();
});
it('should create minimal mutations for appendChild', function(done) {
var div;
var observer;
var fragment;
var mutations;
var addedDiv1;
var addedDiv2;
function start() {
div = document.createElement('div');
var first = document.createElement('span');
first.textContent = 'Foo';
div.appendChild(first);
fragment = document.createDocumentFragment();
addedDiv1 = fragment.appendChild(document.createElement('div'));
addedDiv2 = fragment.appendChild(document.createElement('div'));
observer = new MutationObserver(function(m) {
mutations = m;
});
observer.observe(div, { childList: true });
div.appendChild(fragment);
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "childList");
assert.equal(mutations[0].addedNodes.length, 2);
assert.equal(mutations[0].addedNodes[0], addedDiv1);
assert.equal(mutations[0].addedNodes[1], addedDiv2);
assert.equal(mutations[0].removedNodes.length, 0);
observer.disconnect();
done();
}
start();
});
});
</script>
</body>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver observe should throw on invalid input
1 tests
1 pass
0 fail

View File

@@ -1,54 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver observe', function() {
it('should throw on invalid input', function() {
var div = document.createElement('div');
var observer = new MutationObserver(function(mutations) { });
assert.throw(function() {
observer.observe();
});
assert.throw(function() {
observer.observe(null);
});
assert.throw(function() {
observer.observe(undefined)
});
assert.throw(function() {
observer.observe(div);
});
assert.throw(function() {
observer.observe(div, null);
});
assert.throw(function() {
observer.observe(div, undefined);
});
assert.throw(function() {
observer.observe(null, {attributes: true});
});
assert.throw(function() {
observer.observe(undefined, {attributes: true});
});
assert.throw(function() {
observer.observe(div, {subtree: true});
});
assert.throw(function() {
observer.observe(div, {attributes: false, attributeOldValue: true});
});
assert.throw(function() {
observer.observe(div, {attributes: false, attributeFilter: ["id"]});
});
assert.throw(function() {
observer.observe(div, {attributes: false, attributeOldValue: false});
});
assert.throw(function() {
observer.observe(div, {characterData: false, characterDataOldValue: true});
});
assert.throw(function() {
observer.observe(div, {characterData: false, characterDataOldValue: false});
});
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver.observe should observe attributes
1 tests
1 pass
0 fail

View File

@@ -1,34 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.observe', function() {
it('should observe attributes', function() {
var observer = new MutationObserver(function() {});
var element = document.createElement('div');
element.setAttribute('data-test', '1');
observer.observe(element, {attributeOldValue: true});
element.setAttribute('data-test', '2');
var records = observer.takeRecords();
assert.equal(records.length, 1);
assert.equal(records[0].oldValue, 1);
observer.disconnect();
observer.observe(element, {attributeOldValue: false});
element.setAttribute('data-test', '3');
var records = observer.takeRecords();
assert.equal(records.length, 1);
assert.isNull(records[0].oldValue);
observer.disconnect();
observer.observe(element, {attributeFilter: ['data-test']});
element.setAttribute('data-test', '4');
var records = observer.takeRecords();
assert.equal(records.length, 1);
assert.isNull(records[0].oldValue);
observer.disconnect();
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 Test MutationObserver.observe should respect character data options
1 tests
1 pass
0 fail

View File

@@ -1,26 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('Test MutationObserver.observe', function() {
it('should respect character data options', function() {
var observer = new MutationObserver(function() {});
var text = new Text('0');
observer.observe(text, {characterDataOldValue: true});
text.data = '1';
var records = observer.takeRecords();
assert.equal(records.length, 1);
assert.equal(records[0].oldValue, 0);
observer.disconnect();
observer.observe(text, {characterDataOldValue: false});
text.data = '2';
var records = observer.takeRecords();
assert.equal(records.length, 1);
assert.isNull(records[0].oldValue);
observer.disconnect();
});
});
</script>
</html>

View File

@@ -1,9 +0,0 @@
Running 5 tests
ok 1 MutationObserver.observe on a subtree should handle basic aspects of subtree observation
ok 2 MutationObserver.observe on a subtree should handle two observers at different depths
ok 3 MutationObserver.observe on a subtree should handle one observer at two different depths
ok 4 MutationObserver.observe on a subtree should handle transiently detached nodes are still observed via subtree
ok 5 MutationObserver.observe on a subtree should have correct behavior of transient observation with complex movement
5 tests
5 pass
0 fail

View File

@@ -1,267 +0,0 @@
<!DOCTYPE html>
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.observe on a subtree', function() {
it('should handle basic aspects of subtree observation', function(done) {
var observer;
var subDiv;
var mutations;
function start() {
var div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
subDiv.textContent = 'hello, world';
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true, characterData: true, subtree: true});
subDiv.setAttribute('foo', 'bar');
subDiv.firstChild.textContent = 'goodbye!';
setTimeout(finish, 0);
}
function finish() {
// ...attribute and characterData changes in subtree
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "characterData");
assert.equal(mutations[1].target, subDiv.firstChild);
observer.disconnect();
done();
}
start();
});
it('should handle two observers at different depths', function(done) {
var observer;
var observer2;
var mutations;
var mutations2;
var subDiv;
function start() {
var div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
observer = new MutationObserver(function(records) {
mutations = records;
});
observer2 = new MutationObserver(function(records) {
mutations2 = records;
});
observer.observe(div, {attributes: true, subtree: true});
observer2.observe(subDiv, {attributes: true});
subDiv.setAttribute('foo', 'bar');
setTimeout(finish, 0);
}
function finish() {
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations2.length, 1);
assert.equal(mutations2[0].type, "attributes");
assert.equal(mutations2[0].target, subDiv);
assert.equal(mutations2[0].attributeName, "foo");
observer.disconnect();
observer2.disconnect();
done();
}
start();
});
it('should handle one observer at two different depths', function(done) {
var observer;
var mutations;
var calls = 0;
var subDiv;
function start() {
var div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
observer = new MutationObserver(function(records) {
mutations = records;
++calls;
});
observer.observe(div, {attributes: true, subtree: true});
observer.observe(subDiv, {attributes: true, subtree: true});
subDiv.setAttribute('foo', 'bar');
setTimeout(finish, 0);
}
function finish() {
assert.equal(calls, 1);
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
observer.disconnect();
done();
}
start();
});
// FIXME(sky): This test is huge, it should be broken up.
it('should handle transiently detached nodes are still observed via subtree', function(done) {
var observer;
var mutations;
var div;
var subDiv;
function start() {
div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
subDiv.textContent = 'hello, world';
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true, characterData: true, subtree: true});
subDiv.setAttribute('foo', 'bar');
div.removeChild(subDiv);
subDiv.setAttribute('test', 'test');
setTimeout(checkDeliveredAndChangeAgain, 0);
}
function checkDeliveredAndChangeAgain() {
// ...both changes should be received. Change detached subDiv again.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].target, subDiv);
assert.equal(mutations[1].attributeName, "test");
mutations = null;
subDiv.setAttribute('foo', 'baz');
setTimeout(checkNotDeliveredAndReattach, 0);
}
function checkNotDeliveredAndReattach() {
// ...transient subtree observation was stopped after delivery, so subDiv change should not be received. Reattach and change again.
assert.equal(mutations, null);
mutations = null
div.appendChild(subDiv);
subDiv.setAttribute('foo', 'bat');
setTimeout(checkDeliveredAndReobserve, 0);
}
function checkDeliveredAndReobserve() {
//...reattached subtree should now be observable. Try detaching and re-observing.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
mutations = null;
div.removeChild(subDiv);
subDiv.firstChild.textContent = 'badbye';
observer.observe(div, {attributes: true, characterData: true, subtree: true});
subDiv.setAttribute('foo', 'boo');
setTimeout(finish, 0);
}
function finish() {
// ...The change made before re-observing should be received, but not the one after.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "characterData");
assert.equal(mutations[0].target, subDiv.firstChild);
observer.disconnect();
done();
}
start();
});
it('should have correct behavior of transient observation with complex movement', function(done) {
var observer;
var text;
var subDiv;
var mutations;
var subDiv2;
var subDiv3;
function start() {
var div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
subDiv2 = subDiv.appendChild(document.createElement('div'));
subDiv2.textContent = 'hello, world';
subDiv3 = document.createElement('div');
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true, characterData: true, subtree: true});
div.removeChild(subDiv);
subDiv.removeChild(subDiv2);
text = subDiv2.removeChild(subDiv2.firstChild);
subDiv.setAttribute('a', 'a');
subDiv2.setAttribute('b', 'b');
text.textContent = 'c';
subDiv3.appendChild(subDiv2);
subDiv3.setAttribute('d', 'd');
subDiv2.setAttribute('e', 'e');
div.appendChild(subDiv3);
subDiv3.setAttribute('f', 'f');
subDiv2.setAttribute('g', 'g');
setTimeout(finish, 0);
}
function finish() {
// ...All changes should be received except for setting the "d" attribute on subDiv3 before it was reachable from div.
assert.equal(mutations.length, 6);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "a");
assert.equal(mutations[1].type, "attributes");
assert.equal(mutations[1].target, subDiv2);
assert.equal(mutations[1].attributeName, "b");
assert.equal(mutations[2].type, "characterData");
assert.equal(mutations[2].target, text);
assert.equal(mutations[3].type, "attributes");
assert.equal(mutations[3].target, subDiv2);
assert.equal(mutations[3].attributeName, "e");
assert.equal(mutations[4].type, "attributes");
assert.equal(mutations[4].target, subDiv3);
assert.equal(mutations[4].attributeName, "f");
assert.equal(mutations[5].type, "attributes");
assert.equal(mutations[5].target, subDiv2);
assert.equal(mutations[5].attributeName, "g");
observer.disconnect();
done();
}
start();
});
});
</script>
</html>

View File

@@ -1,29 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver wrappers', function() {
it('should survive GC for passing into the callback even if JS has lost references and the only remaining observations are transient.', function(done) {
function addObserver(node, fn) {
var observer = new MutationObserver(fn);
observer.testProperty = true;
observer.observe(node, {attributes:true, subtree: true});
}
var root = document.createElement('div');
var child = root.appendChild(document.createElement('span'));
addObserver(root, function(records, observer) {
window.observer = observer;
assert.ok(observer.testProperty);
done();
});
root.removeChild(child);
child.setAttribute('foo', 'bar');
root = null;
gc();
});
});
</script>
</html>

View File

@@ -1,28 +0,0 @@
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<script>
description('MutationObserver wrappers should survive GC for passing into the callback even if JS has lost references.');
jsTestIsAsync = true;
function addObserver(node, fn) {
var observer = new MutationObserver(fn);
observer.testProperty = true;
observer.observe(node, {attributes:true});
}
window.addEventListener("load", function() {
addObserver(document.body, function(records, observer) {
window.observer = observer;
shouldBe('observer.testProperty', 'true');
finishJSTest();
});
gc();
document.body.setAttribute('touch', 'the node');
});
</script>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver should not invoke callbacks when appending a script
1 tests
1 pass
0 fail

View File

@@ -1,27 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver', function() {
it('should not invoke callbacks when appending a script', function() {
var mutationsDelivered = false;
function callback(mutations) {
mutationsDelivered = true;
}
var observer = new MutationObserver(callback);
var div = document.createElement('div');
observer.observe(div, {attributes: true});
div.setAttribute('foo', 'bar');
assert.notOk(mutationsDelivered);
var scriptDidRun = false;
var script = document.createElement('script');
script.textContent = 'scriptDidRun = true';
assert.notOk(scriptDidRun);
document.documentElement.appendChild(script);
assert.notOk(scriptDidRun);
assert.notOk(mutationsDelivered);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObservers should handle shadow dom
1 tests
1 pass
0 fail

View File

@@ -1,40 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<div id="range"></div>
<script>
describe('MutationObservers', function() {
it('should handle shadow dom', function() {
function mutate(element) {
element.setAttribute('data-foo', 'bar');
element.insertBefore(new Text('hello'), element.firstChild);
element.firstChild.textContent = 'goodbye';
element.removeChild(element.firstChild);
}
var range = document.getElementById('range');
var shadowRoot = range.ensureShadowRoot();
shadowRoot.appendChild(document.createElement('div'));
var observer = new MutationObserver(function() { });
observer.observe(shadowRoot.firstChild, {attributes: true, childList: true, characterData: true, subtree: true});
mutate(shadowRoot.firstChild);
var mutations = observer.takeRecords();
// Mutations in shadow DOM should have been observed:
assert.equal(mutations.length, 4);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[1].type, "childList");
assert.equal(mutations[2].type, "characterData");
assert.equal(mutations[3].type, "childList");
observer.disconnect();
mutations = observer.takeRecords();
observer.observe(document, {attributes: true, childList: true, characterData: true, subtree: true});
mutate(shadowRoot.firstChild);
// Observing from outside shadow DOM should not see mutations in the shadow:
assert.equal(mutations.length, 0);
});
});
</script>
</html>

View File

@@ -1,5 +0,0 @@
Running 1 tests
ok 1 MutationObserver.takeRecords should allow taking records synchronously or getting a notification
1 tests
1 pass
0 fail

View File

@@ -1,53 +0,0 @@
<html>
<import src="../resources/chai.sky" />
<import src="../resources/mocha.sky" />
<script>
describe('MutationObserver.takeRecords', function() {
it('should allow taking records synchronously or getting a notification', function(done) {
var mutations;
var div;
var subDiv;
var observer;
// Testing takeRecords.
mutations = null;
div = document.createElement('div');
subDiv = div.appendChild(document.createElement('div'));
subDiv.textContent = 'hello, world';
observer = new MutationObserver(function(records) {
mutations = records;
});
observer.observe(div, {attributes: true, characterData: true, subtree: true});
subDiv.setAttribute('foo', 'bar');
subDiv.firstChild.textContent = 'goodbye!';
div.removeChild(subDiv);
mutations = observer.takeRecords();
// ...records are taken synchronously.
assert.equal(mutations.length, 2);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
assert.equal(mutations[1].type, "characterData");
assert.equal(mutations[1].target, subDiv.firstChild);
subDiv.setAttribute('foo', 'baz');
setTimeout(function() {
// ...takeRecord took records, but did not clear transient observers.
assert.equal(mutations.length, 1);
assert.equal(mutations[0].type, "attributes");
assert.equal(mutations[0].target, subDiv);
assert.equal(mutations[0].attributeName, "foo");
observer.disconnect();
done();
}, 0);
});
});
</script>
</html>

View File

@@ -1,22 +0,0 @@
<script src="../../../resources/js-test.js"></script>
<script>
window.jsTestIsAsync = true;
description('Clearing transient observers after observation node is GCed should not cause a crash.');
function callback(mutations) {
window.mutations = mutations;
}
var observer = new MutationObserver(callback);
var div = document.createElement('div');
var span = div.appendChild(document.createElement('span'));
observer.observe(div, {attributes: true, subtree: true});
div.removeChild(span);
div = null;
gc();
span.setAttribute('foo', 'bar');
setTimeout(function() {
shouldBe('mutations.length', '1');
finishJSTest();
}, 0);
</script>

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<div>Test passes if it does not crash</div>
<script src="../../../resources/gc.js"></script>
<script>
if (window.testRunner) {
testRunner.waitUntilDone();
testRunner.dumpAsText();
}
var observer = new MutationObserver(function() {console.log('Should not appear')});
var div = document.createElement('div');
observer.observe(div, {attributes: true});
div.id = 'foo';
div = null;
observer = null;
gc();
setTimeout(function() { testRunner.notifyDone(); }, 0);
</script>