test(select, ngOptions): add more tests for "required" with "empty" or "unknown" option
This commit is contained in:
committed by
Martin Staffa
parent
080357e906
commit
8d7c7f4a8e
@@ -704,7 +704,6 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
|
||||
ngModelCtrl.$render();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
describe('ngOptions', function() {
|
||||
|
||||
var scope, formElement, element, $compile, linkLog;
|
||||
var scope, formElement, element, $compile, linkLog, ngModelCtrl;
|
||||
|
||||
function compile(html) {
|
||||
formElement = jqLite('<form name="form">' + html + '</form>');
|
||||
element = formElement.find('select');
|
||||
$compile(formElement)(scope);
|
||||
ngModelCtrl = element.controller('ngModel');
|
||||
scope.$apply();
|
||||
}
|
||||
|
||||
@@ -181,6 +182,7 @@ describe('ngOptions', function() {
|
||||
afterEach(function() {
|
||||
scope.$destroy(); //disables unknown option work during destruction
|
||||
dealoc(formElement);
|
||||
ngModelCtrl = null;
|
||||
});
|
||||
|
||||
function createSelect(attrs, blank, unknown) {
|
||||
@@ -2925,42 +2927,68 @@ describe('ngOptions', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('ngRequired', function() {
|
||||
describe('required state', function() {
|
||||
|
||||
it('should allow bindings on ngRequired', function() {
|
||||
it('should set the error if the empty option is selected', function() {
|
||||
createSelect({
|
||||
'ng-model': 'selection',
|
||||
'ng-options': 'item for item in values',
|
||||
'required': ''
|
||||
}, true);
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values = ['a', 'b'];
|
||||
scope.selection = scope.values[0];
|
||||
});
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
var options = element.find('option');
|
||||
|
||||
// view -> model
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
|
||||
browserTrigger(options[1], 'click');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
// model -> view
|
||||
scope.$apply('selection = "unmatched value"');
|
||||
expect(options[0]).toBeMarkedAsSelected();
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('should validate with empty option and bound ngRequired', function() {
|
||||
createSelect({
|
||||
'ng-model': 'value',
|
||||
'ng-options': 'item.name for item in values',
|
||||
'ng-required': 'required'
|
||||
}, true);
|
||||
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values = [{name: 'A', id: 1}, {name: 'B', id: 2}];
|
||||
scope.required = false;
|
||||
});
|
||||
|
||||
element.val('');
|
||||
browserTrigger(element, 'change');
|
||||
var options = element.find('option');
|
||||
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeValid();
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.required = true;
|
||||
});
|
||||
scope.$apply('required = true');
|
||||
expect(element).toBeInvalid();
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.value = scope.values[0];
|
||||
});
|
||||
scope.$apply('value = values[0]');
|
||||
expect(element).toBeValid();
|
||||
|
||||
element.val('');
|
||||
browserTrigger(element, 'change');
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeInvalid();
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.required = false;
|
||||
});
|
||||
scope.$apply('required = false');
|
||||
expect(element).toBeValid();
|
||||
});
|
||||
|
||||
@@ -2989,6 +3017,43 @@ describe('ngOptions', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should NOT set the error if the empty option is present but required attribute is not',
|
||||
function() {
|
||||
scope.$apply(function() {
|
||||
scope.values = ['a', 'b'];
|
||||
});
|
||||
|
||||
createSingleSelect();
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(element).toBePristine();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
it('should NOT set the error if the unknown option is selected', function() {
|
||||
createSelect({
|
||||
'ng-model': 'selection',
|
||||
'ng-options': 'item for item in values',
|
||||
'required': ''
|
||||
});
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values = ['a', 'b'];
|
||||
scope.selection = 'a';
|
||||
});
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
scope.$apply('selection = "c"');
|
||||
expect(element).toEqualSelect(['?'], 'string:a', 'string:b');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
});
|
||||
|
||||
|
||||
it('should allow falsy values as values', function() {
|
||||
createSelect({
|
||||
'ng-model': 'value',
|
||||
@@ -3009,6 +3074,34 @@ describe('ngOptions', function() {
|
||||
expect(element).toBeValid();
|
||||
expect(scope.value).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should validate after option list was updated', function() {
|
||||
createSelect({
|
||||
'ng-model': 'selection',
|
||||
'ng-options': 'item for item in values',
|
||||
'required': ''
|
||||
}, true);
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values = ['A', 'B'];
|
||||
scope.selection = scope.values[0];
|
||||
});
|
||||
|
||||
expect(element).toEqualSelect('', ['string:A'], 'string:B');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values = ['C', 'D'];
|
||||
});
|
||||
|
||||
expect(element).toEqualSelect([''], 'string:C', 'string:D');
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
// ngModel sets undefined for invalid values
|
||||
expect(scope.selection).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('required and empty option', function() {
|
||||
|
||||
+124
-39
@@ -7,6 +7,7 @@ describe('select', function() {
|
||||
formElement = jqLite('<form name="form">' + html + '</form>');
|
||||
element = formElement.find('select');
|
||||
$compile(formElement)(scope);
|
||||
ngModelCtrl = element.controller('ngModel');
|
||||
scope.$digest();
|
||||
}
|
||||
|
||||
@@ -79,6 +80,7 @@ describe('select', function() {
|
||||
afterEach(function() {
|
||||
scope.$destroy(); //disables unknown option work during destruction
|
||||
dealoc(formElement);
|
||||
ngModelCtrl = null;
|
||||
});
|
||||
|
||||
|
||||
@@ -190,55 +192,109 @@ describe('select', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should require', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection" required ng-change="change()">' +
|
||||
'<option value=""></option>' +
|
||||
'<option value="c">C</option>' +
|
||||
'</select>');
|
||||
describe('required state', function() {
|
||||
|
||||
scope.change = function() {
|
||||
scope.log += 'change;';
|
||||
};
|
||||
it('should set the error if the empty option is selected', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection" required>' +
|
||||
'<option value=""></option>' +
|
||||
'<option value="a">A</option>' +
|
||||
'<option value="b">B</option>' +
|
||||
'</select>');
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.log = '';
|
||||
scope.selection = 'c';
|
||||
scope.$apply(function() {
|
||||
scope.selection = 'a';
|
||||
});
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
var options = element.find('option');
|
||||
|
||||
// view -> model
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
|
||||
browserTrigger(options[1], 'click');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
// model -> view
|
||||
scope.$apply('selection = null');
|
||||
options = element.find('option');
|
||||
expect(options[0]).toBeMarkedAsSelected();
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
});
|
||||
|
||||
expect(scope.form.select.$error.required).toBeFalsy();
|
||||
expect(element).toBeValid();
|
||||
expect(element).toBePristine();
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.selection = '';
|
||||
it('should validate with empty option and bound ngRequired', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection" ng-required="required">' +
|
||||
'<option value=""></option>' +
|
||||
'<option value="a">A</option>' +
|
||||
'<option value="b">B</option>' +
|
||||
'</select>');
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.required = false;
|
||||
});
|
||||
|
||||
var options = element.find('option');
|
||||
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeValid();
|
||||
|
||||
scope.$apply('required = true');
|
||||
expect(element).toBeInvalid();
|
||||
|
||||
scope.$apply('selection = "a"');
|
||||
expect(element).toBeValid();
|
||||
expect(element).toEqualSelect('', ['a'], 'b');
|
||||
|
||||
browserTrigger(options[0], 'click');
|
||||
expect(element).toBeInvalid();
|
||||
|
||||
scope.$apply('required = false');
|
||||
expect(element).toBeValid();
|
||||
});
|
||||
|
||||
expect(scope.form.select.$error.required).toBeTruthy();
|
||||
expect(element).toBeInvalid();
|
||||
expect(element).toBePristine();
|
||||
expect(scope.log).toEqual('');
|
||||
|
||||
element[0].value = 'c';
|
||||
browserTrigger(element, 'change');
|
||||
expect(element).toBeValid();
|
||||
expect(element).toBeDirty();
|
||||
expect(scope.log).toEqual('change;');
|
||||
it('should not be invalid if no required attribute is present', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection">' +
|
||||
'<option value=""></option>' +
|
||||
'<option value="c">C</option>' +
|
||||
'</select>');
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(element).toBePristine();
|
||||
});
|
||||
|
||||
|
||||
it('should NOT set the error if the unknown option is selected', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection" required>' +
|
||||
'<option value="a">A</option>' +
|
||||
'<option value="b">B</option>' +
|
||||
'</select>');
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.selection = 'a';
|
||||
});
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
scope.$apply('selection = "c"');
|
||||
expect(element).toEqualSelect([unknownValue('c')], 'a', 'b');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should not be invalid if no require', function() {
|
||||
compile(
|
||||
'<select name="select" ng-model="selection">' +
|
||||
'<option value=""></option>' +
|
||||
'<option value="c">C</option>' +
|
||||
'</select>');
|
||||
|
||||
expect(element).toBeValid();
|
||||
expect(element).toBePristine();
|
||||
});
|
||||
|
||||
|
||||
it('should work with repeated value options', function() {
|
||||
scope.robots = ['c3p0', 'r2d2'];
|
||||
scope.robot = 'r2d2';
|
||||
@@ -2358,6 +2414,35 @@ describe('select', function() {
|
||||
expect(previouslySelectedOptionElement).not.toBe(optionElements[0]);
|
||||
});
|
||||
|
||||
|
||||
it('should validate when the options change', function() {
|
||||
scope.values = ['A', 'B'];
|
||||
scope.selection = 'A';
|
||||
|
||||
compile(
|
||||
'<select ng-model="selection" required>' +
|
||||
'<option value="">--select--</option>' +
|
||||
'<option ng-repeat="option in values" value="{{option}}">{{option}}</option>' +
|
||||
'</select>'
|
||||
);
|
||||
|
||||
expect(element).toEqualSelect('', ['A'], 'B');
|
||||
expect(element).toBeValid();
|
||||
expect(ngModelCtrl.$error.required).toBeFalsy();
|
||||
|
||||
scope.$apply(function() {
|
||||
// Only when new objects are used, ngRepeat re-creates the element from scratch
|
||||
scope.values = ['B', 'C'];
|
||||
});
|
||||
|
||||
expect(element).toEqualSelect([''], 'B', 'C');
|
||||
expect(element).toBeInvalid();
|
||||
expect(ngModelCtrl.$error.required).toBeTruthy();
|
||||
// ngModel sets undefined for invalid values
|
||||
expect(scope.selection).toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user