describe('Directive rule', () => {
    let $scope;
    let $element;
    let element;

    beforeEach(ngModule('vnCore'));

    function compile(html, value) {
        inject(($compile, $rootScope, $window) => {
            $window.validations = {Model:
                {validations: {field: [{validation: 'absence'}]}}
            };

            $scope = $rootScope.$new();

            $element = angular.element(html);
            $compile($element)($scope);
            element = $element[0];

            $scope.model = {field: value};
            $scope.$digest();
        });
    }

    afterEach(() => {
        $scope.$destroy();
        $element.remove();
    });

    describe('Errors', () => {
        it(`should throw an error if the rule doesn't have the right syntax`, () => {
            expect(() => {
                compile(`
                    <form>
                    <input
                        type="text"
                        ng-model="model.field"
                        rule="invalidLowerCamelCaseModel">
                    </input>
                    </form>
                `);
            }).toThrow(new Error(`rule: Attribute must have this syntax: [ModelName[.fieldName]]`));
        });

        it('should throw an error if cannot retrieve model or field', () => {
            expect(() => {
                compile(`
                    <form>
                    <input
                        type="text"
                        ng-model="model"
                        rule>
                    </input>
                    </form>
                `);
            }).toThrow(new Error(`rule: Cannot retrieve model or field attribute`));
        });

        it('should throw an error if the model is not defined', () => {
            expect(() => {
                compile(`
                    <form>
                    <input
                        type="text"
                        ng-model="model.field"
                        rule="NonExistentModel.field">
                    </input>
                    </form>
                `);
            }).toThrow(new Error(`rule: Model 'NonExistentModel' doesn't exist`));
        });
    });

    describe('Validator extended', () => {
        let html = `
            <form>
            <input
                type="text"
                ng-model="model.field"
                rule="Model.field">
            </input>
            </form>
        `;

        it('should not validate the entity as it has a wrong value', () => {
            compile(html, 'invalidValue');

            expect(element.classList).toContain('ng-invalid');
        });

        it('should validate the entity as it has a valid value', () => {
            compile(html, '');

            expect(element.classList).toContain('ng-valid');
        });
    });

    describe('Validator minimal', () => {
        let html = `
            <input
                type="text"
                ng-model="model.field"
                rule>
            </input>
        `;

        it('should validate with empty rule and without specifying a parent form', () => {
            compile(html, 'invalidValue');

            expect(element.classList).toContain('ng-invalid');
        });
    });
});