<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 = document.createTextNode('');
            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>
