'use strict';

import {expect} from "chai"
import {Node} from "../../../source/types/node.mjs";
import {NodeList} from "../../../source/types/nodelist.mjs";
import {NodeRecursiveIterator} from "../../../source/types/noderecursiveiterator.mjs";

describe('NodeRecursiveIterator', function () {

    it('should throw exeption', function () {
        expect(() => new NodeRecursiveIterator()).to.throw(Error)
    });
    it('should be a function', function () {
        expect(NodeRecursiveIterator).to.be.a('function');
    });

    it('should be a constructor', function () {
        expect(new NodeRecursiveIterator(new Node)).to.be.an.instanceof(NodeRecursiveIterator);
    });

    /**
     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
     */
    it('undefined should not result in undefined node', function () {
        const iterator = new NodeRecursiveIterator(new Node);

        const result = [];
        for (const n of iterator) {
            expect(n).to.be.an.instanceof(Node);
            result.push(n.value);
        }

        expect(result).to.deep.equal([undefined]);

    });

    it('should iterate', function () {
        const node =
            new Node('1')
        node.appendChild(
            (new Node('2')).appendChild(new Node('2.1')).appendChild(new Node('2.2')).appendChild(new Node('2.3'))).appendChild(new Node('3')).appendChild(new Node('4').appendChild(new Node('4.1')).appendChild(new Node('4.2')));

        const iterator = new NodeRecursiveIterator(node);

        const result = [];
        for (const n of iterator) {
            expect(n).to.be.an.instanceof(Node);
            result.push(n.value);
        }

        expect(result).to.deep.equal(['1', '2', '2.1', '2.2', '2.3', '3', '4', '4.1', '4.2']);

    });

    it('should iterate nodelist', function () {
        const nodeList = new NodeList();

        nodeList.add(
            (new Node('2')).appendChild(new Node('2.1')).appendChild(new Node('2.2')).appendChild(new Node('2.3')).appendChild(new Node('3')).appendChild(new Node('4').appendChild(new Node('4.1')).appendChild(new Node('4.2'))));

        nodeList.add(new Node('x'));

        const iterator = new NodeRecursiveIterator(nodeList);

        const result = [];
        for (const n of iterator) {
            expect(n).to.be.an.instanceof(Node);
            result.push(n.value);
        }
        
        expect(result).to.deep.equal(['2', '2.1', '2.2', '2.3', '3', '4', '4.1', '4.2', 'x']);

    });

});