/// <reference path="../node_modules/@types/jasmine/index.d.ts" />

import { ParamDefinition, ParamDomain, ParamDomainValue } from "../src/param";
import { MessageCode, Message } from "../src/util/message";

describe('Class ParamDomain : ', () => {
    function shouldFail(f: () => void, min: number = undefined, max: number = undefined) {
        try {
            f();
            fail();
        }
        catch (e) {
            expect(e instanceof Message).toBeTruthy();
            expect(e.code).toEqual(MessageCode.ERROR_PARAMDOMAIN_INTERVAL_BOUNDS);
            expect(e.extraVar["minValue"] == min).toBeTruthy();
            expect(e.extraVar["maxValue"] == max).toBeTruthy();
        }
    }

    it('test 1', () => {
        let d = new ParamDomain(ParamDomainValue.ANY);
        d = new ParamDomain(ParamDomainValue.INTERVAL, 0, 1);
        d = new ParamDomain(ParamDomainValue.NOT_NULL);
        d = new ParamDomain(ParamDomainValue.POS);
        d = new ParamDomain(ParamDomainValue.POS_NULL);
    });

    it('test 2', () => {
        shouldFail(() => {
            const d = new ParamDomain(ParamDomainValue.ANY, 0, 1);
        }, 0, 1);
    });

    it('test 3', () => {
        shouldFail(() => {
            const d = new ParamDomain(ParamDomainValue.ANY, 0, undefined);
        }, 0);
    });

    it('test 4', () => {
        shouldFail(() => {
            const d = new ParamDomain(ParamDomainValue.INTERVAL);
        });
    });

    it('test 5', () => {
        shouldFail(() => {
            const d = new ParamDomain(ParamDomainValue.INTERVAL, 1, 0);
        }, 1, 0);
    });
});

describe('Class ParamDefinition : ', () => {
    function shouldFail(f: () => void, code: MessageCode) {
        try {
            f();
            fail();
        }
        catch (e) {
            expect(e instanceof Message).toBeTruthy();
            expect(e.code).toEqual(code);
        }
    }

    describe('Domaine de définition : POS : ', () => {
        it('test 1', () => {
            let p = new ParamDefinition(undefined, "a", ParamDomainValue.POS, 1e-8);
            p = new ParamDefinition(undefined, "a", ParamDomainValue.POS, 10);
        });

        it('test 2', () => {
            shouldFail(() => {
                const p = new ParamDefinition(undefined, "a", ParamDomainValue.POS, 0);
            }, MessageCode.ERROR_PARAMDEF_VALUE_POS);
        });

        it('test 3', () => {
            shouldFail(() => {
                const p = new ParamDefinition(undefined, "a", ParamDomainValue.POS, -1);
            }, MessageCode.ERROR_PARAMDEF_VALUE_POS);
        });
    });

    describe('Domaine de définition : POS_NULL : ', () => {
        it('test 1', () => {
            let p = new ParamDefinition(undefined, "a", ParamDomainValue.POS_NULL, 0);
            p = new ParamDefinition(undefined, "a", ParamDomainValue.POS_NULL, 10);
        });

        it('test 2', () => {
            shouldFail(() => {
                const p = new ParamDefinition(undefined, "a", ParamDomainValue.POS_NULL, -1);
            }, MessageCode.ERROR_PARAMDEF_VALUE_POSNULL);
        });
    });

    describe('Domaine de définition : NOT_NULL : ', () => {
        it('test 1', () => {
            let p = new ParamDefinition(undefined, "a", ParamDomainValue.NOT_NULL, -1);
            p = new ParamDefinition(undefined, "a", ParamDomainValue.NOT_NULL, 1);
        });

        it('test 2', () => {
            shouldFail(() => {
                const p = new ParamDefinition(undefined, "a", ParamDomainValue.NOT_NULL, 0);
            }, MessageCode.ERROR_PARAMDEF_VALUE_NULL);
        });
    });

    describe('Domaine de définition : ANY : ', () => {
        it('test 1', () => {
            let p = new ParamDefinition(undefined, "a", ParamDomainValue.ANY, -1);
            p = new ParamDefinition(undefined, "a", ParamDomainValue.ANY, 0);
            p = new ParamDefinition(undefined, "a", ParamDomainValue.ANY, 1);
        });
    });

    describe('Domaine de définition : INTERVAL : ', () => {
        it('test 1', () => {
            let d = new ParamDomain(ParamDomainValue.INTERVAL, 0, 10)
            let p = new ParamDefinition(undefined, "a", d, 0);
            p = new ParamDefinition(undefined, "a", d, 1);
            p = new ParamDefinition(undefined, "a", d, 10);
        });

        it('test 2', () => {
            shouldFail(() => {
                let d = new ParamDomain(ParamDomainValue.INTERVAL, 0, 10)
                let p = new ParamDefinition(undefined, "a", d, -1e-8);
            }, MessageCode.ERROR_PARAMDEF_VALUE_INTERVAL);
        });

        it('test 3', () => {
            shouldFail(() => {
                let d = new ParamDomain(ParamDomainValue.INTERVAL, 0, 10)
                let p = new ParamDefinition(undefined, "a", d, 10 + 1e-8);
            }, MessageCode.ERROR_PARAMDEF_VALUE_INTERVAL);
        });
    });
});