Esta directiva de validación personalizada es un ejemplo presentado en el sitio oficial de angular. http://docs.angularjs.org/guide/forms Verifica que una entrada de texto esté en formato numérico o no.
var INTEGER_REGEXP = /^\-?\d*$/;
app.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (INTEGER_REGEXP.test(viewValue)) {
// it is valid
ctrl.$setValidity('integer', true);
return viewValue;
} else {
// it is invalid, return undefined (no model update)
ctrl.$setValidity('integer', false);
return undefined;
}
});
}
};
});
Para probar este código unitario, escribí esto:
describe('directives', function() {
beforeEach(module('exampleDirective'));
describe('integer', function() {
it('should validate an integer', function() {
inject(function($compile, $rootScope) {
var element = angular.element(
'<form name="form">' +
'<input ng-model="someNum" name="someNum" integer>' +
'</form>'
);
$compile(element)($rootScope);
$rootScope.$digest();
element.find('input').val(5);
expect($rootScope.someNum).toEqual(5);
});
});
});
});
Entonces me sale este error:
Expected undefined to equal 5.
Error: Expected undefined to equal 5.
Pongo declaraciones impresas en todas partes para ver qué está sucediendo, y parece que nunca se llama a la directiva. ¿Cuál es una forma adecuada de probar una directiva simple como esta?
Respuestas:
Las pruebas de la otra respuesta deben escribirse como:
describe('directives', function() { var $scope, form; beforeEach(module('exampleDirective')); beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; var element = angular.element( '<form name="form">' + '<input ng-model="model.somenum" name="somenum" integer />' + '</form>' ); $scope.model = { somenum: null } $compile(element)($scope); form = $scope.form; })); describe('integer', function() { it('should pass with integer', function() { form.somenum.$setViewValue('3'); $scope.$digest(); expect($scope.model.somenum).toEqual('3'); expect(form.somenum.$valid).toBe(true); }); it('should not pass with string', function() { form.somenum.$setViewValue('a'); $scope.$digest(); expect($scope.model.somenum).toBeUndefined(); expect(form.somenum.$valid).toBe(false); }); }); });
Tenga en cuenta que
$scope.$digest()
ahora se invoca después$setViewValue
. Esto establece el formulario en un estado "sucio", de lo contrario permanecería "prístino", que probablemente no es lo que desea.fuente
$setViewValue()
, no sé si me faltan muchos casos ...Lo descubrí leyendo el código de la aplicación angular https://github.com/angular-app/angular-app Este video también ayuda http://youtu.be/ZhfUv0spHCY?t=31m17s
Dos errores que cometí:
Aquí está la versión actualizada. La directiva es la misma, solo la prueba que cambié.
describe('directives', function() { var $scope, form; beforeEach(module('exampleDirective')); beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; var element = angular.element( '<form name="form">' + '<input ng-model="model.somenum" name="somenum" integer />' + '</form>' ); $scope.model = { somenum: null } $compile(element)($scope); $scope.$digest(); form = $scope.form; })); describe('integer', function() { it('should pass with integer', function() { form.somenum.$setViewValue('3'); expect($scope.model.somenum).toEqual('3'); expect(form.somenum.$valid).toBe(true); }); it('should not pass with string', function() { form.somenum.$setViewValue('a'); expect($scope.model.somenum).toBeUndefined(); expect(form.somenum.$valid).toBe(false); }); }); });
fuente
$scope.$digest()
después de llamar$setViewValue
. ¿Estoy haciendo algo extraño o falta esto en tu ejemplo? EDITAR: lo siento, no vi la respuesta a continuación.Pruebo mis directivas personalizadas buscando en el objeto "$ error" el nombre de la validación personalizada. Ejemplo:
'use strict'; describe('Directive: validadorCorreo', function () { // load the directive's module beforeEach(module('sistemaRegistroProCivilApp')); var inputCorreo, formulario, elementoFormulario, scope, $compile; beforeEach(inject(function ($rootScope, _$compile_) { scope = $rootScope.$new(); $compile = _$compile_; elementoFormulario = angular.element('<form name="formulario">' + '<input type="text" name="correo" data-ng-model="correo" required data-validador-correo/>' + '</form'); scope.correo = ''; elementoFormulario = $compile(elementoFormulario)(scope); scope.$digest(); inputCorreo = elementoFormulario.find('input'); formulario = scope.formulario; console.log(formulario.correo.$error); })); it('Deberia Validar si un correo ingresado en el input es correcto e incorrecto', inject(function ($compile) { inputCorreo.val('[email protected]').triggerHandler('input'); expect(formulario.correo.$error.email).toBe(true); //Here, the name of the custom validation appears in the $error object. console.log(formulario.correo.$error); inputCorreo.val('[email protected]').triggerHandler('input'); expect(formulario.correo.$error.email).toBeUndefined();//Here, the name of the custom validation disappears in the $error object. Is Undefined console.log(formulario.correo.$error.email) })); });
¡Espero que yo puedo ayudarle!
fuente