import {
    validatePrimitive,
    validateBoolean,
    validateString,
    validateObject,
    validateArray,
    validateFunction,
    validateInteger,
    validateInstance,
    validateIterable,
    validateSymbol
} from "../../../source/types/validate.mjs"

import {Base} from "../../../source/types/base.mjs"
import {ID} from "../../../source/types/id.mjs"

import {expect} from "chai"

describe('validate', function () {

    describe('.validatePrimitive()', function () {

        [
            ['test1', true],
            [undefined, true],
            [null, true],
            [() => {
            }, false],
            [2, true],
            [false, true],
            [true, true],
            [4.5, true],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), true],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validatePrimitive(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => validatePrimitive(a)).to.throw(TypeError);
                });

            } else {
                it('.validatePrimitive(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validatePrimitive(a)).to.be.equal(a);
                });
            }

        });


    });

    describe('.validateInteger()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, true],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateInteger(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => validateInteger(a)).to.throw(TypeError);
                });

            } else {
                it('.validateInteger(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateInteger(a)).to.be.equal(a);
                });
            }

        });


    });
    
    describe('.validateSymbol()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), true],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateSymbol(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => validateSymbol(a)).to.throw(TypeError);
                });

            } else {
                it('.validateSymbol(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateSymbol(a)).to.be.equal(a);
                });
            }

        });


    });

    describe('.validateIterable()', function () {

        [
            ['test1', true],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], true],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateIterable(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateIterable(a)
                    }).to.throw(TypeError);
                    ;
                });

            } else {
                it('.validateIterable(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateIterable(a)).to.be.equal(a);
                });
            }

        });


    });

    describe('.validateBoolean()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, true],
            [true, true],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateBoolean(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateBoolean(a)
                    }).to.throw(TypeError);
                });

            } else {
                it('.validateBoolean(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateBoolean(a)).to.be.equal(a);
                });
            }


        });


    });

    describe('.validateString()', function () {

        [
            ['test1', true],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateString(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateString(a)
                    }).to.throw(TypeError);
                    ;
                });

            } else {
                it('.validateString(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateString(a)).to.be.equal(a);
                });
            }

        });


    });

    describe('.validateObject()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, true],
            [[1, 2, 3], false],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateObject(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateObject(a)
                    }).to.throw(TypeError);
                    ;
                });

            } else {
                it('.validateObject(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateObject(a)).to.be.equal(a);
                });
            }

        });


    });

    describe('.validateInstance()', function () {

        [
            ['test1', Object],
            [undefined, Object],
            [null, Object],
            [() => {
            }, Object],
            [2, Object],
            [false, Object],
            [true, Object],
            [4.5, Object],
            [{}, Base],
            [[1, 2, 3], Object],
            [Symbol("foo"), Object],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()


            it('.validateInstance(' + typeof a + ') should throw TypeException ' , function () {
                expect(() => {
                    validateInstance(a, b)
                }).to.throw(TypeError);
                ;
            });

        });


    });

    describe('.validateInstance()', function () {

        [
            [{}, Object, true],
            [new Base, Base, true],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            it('.validateInstance(' + typeof a + ') should not throw TypeException ' , function () {
                expect(validateInstance(a, b)).to.be.equal(a);
            });

        });


    });


    describe('.validateArray()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, false],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], true],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateArray(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateArray(a)
                    }).to.throw(TypeError);
                    ;
                });

            } else {
                it('.validateArray(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateArray(a)).to.be.equal(a);
                });
            }


        });
    });

    describe('.validateFunction()', function () {

        [
            ['test1', false],
            [undefined, false],
            [null, false],
            [() => {
            }, true],
            [2, false],
            [false, false],
            [true, false],
            [4.5, false],
            [{}, false],
            [[1, 2, 3], false],
            [Symbol("foo"), false],
        ].forEach(function (data) {

            let a = data.shift()
            let b = data.shift()

            if (b === false) {

                it('.validateFunction(' + typeof a + ') should throw TypeException ' + b, function () {
                    expect(() => {
                        validateFunction(a)
                    }).to.throw(TypeError);
                    ;
                });

            } else {
                it('.validateFunction(' + typeof a + ') should not throw TypeException ' + b, function () {
                    expect(validateFunction(a)).to.be.equal(a);
                });
            }


        });
    });

});

