'use strict'; describe('$formFactory', function() { var rootScope; var formFactory; beforeEach(function() { rootScope = angular.scope(); formFactory = rootScope.$service('$formFactory'); }); it('should have global form', function() { expect(formFactory.rootForm).toBeTruthy(); expect(formFactory.rootForm.$createWidget).toBeTruthy(); }); describe('new form', function() { var form; var scope; var log; function WidgetCtrl($formFactory){ this.$formFactory = $formFactory; log += ''; this.$render = function() { log += '$render();'; }; this.$on('$validate', function(e){ log += '$validate();'; }); } WidgetCtrl.$inject = ['$formFactory']; WidgetCtrl.prototype = { getFormFactory: function() { return this.$formFactory; } }; beforeEach(function() { log = ''; scope = rootScope.$new(); form = formFactory(scope); }); describe('$createWidget', function() { var widget; beforeEach(function() { widget = form.$createWidget({ scope:scope, model:'text', alias:'text', controller:WidgetCtrl }); }); describe('data flow', function() { it('should have status properties', function() { expect(widget.$error).toEqual({}); expect(widget.$valid).toBe(true); expect(widget.$invalid).toBe(false); }); it('should update view when model changes', function() { scope.text = 'abc'; scope.$digest(); expect(log).toEqual('$validate();$render();'); expect(widget.$modelValue).toEqual('abc'); scope.text = 'xyz'; scope.$digest(); expect(widget.$modelValue).toEqual('xyz'); }); it('should have controller prototype methods', function() { expect(widget.getFormFactory()).toEqual(formFactory); }); }); describe('validation', function() { it('should update state on error', function() { widget.$emit('$invalid', 'E'); expect(widget.$valid).toEqual(false); expect(widget.$invalid).toEqual(true); widget.$emit('$valid', 'E'); expect(widget.$valid).toEqual(true); expect(widget.$invalid).toEqual(false); }); it('should have called the model setter before the validation', function() { var modelValue; widget.$on('$validate', function() { modelValue = scope.text; }); widget.$emit('$viewChange', 'abc'); expect(modelValue).toEqual('abc'); }); describe('form', function() { it('should invalidate form when widget is invalid', function() { expect(form.$error).toEqual({}); expect(form.$valid).toEqual(true); expect(form.$invalid).toEqual(false); widget.$emit('$invalid', 'REASON'); expect(form.$error.REASON).toEqual([widget]); expect(form.$valid).toEqual(false); expect(form.$invalid).toEqual(true); var widget2 = form.$createWidget({ scope:scope, model:'text', alias:'text', controller:WidgetCtrl }); widget2.$emit('$invalid', 'REASON'); expect(form.$error.REASON).toEqual([widget, widget2]); expect(form.$valid).toEqual(false); expect(form.$invalid).toEqual(true); widget.$emit('$valid', 'REASON'); expect(form.$error.REASON).toEqual([widget2]); expect(form.$valid).toEqual(false); expect(form.$invalid).toEqual(true); widget2.$emit('$valid', 'REASON'); expect(form.$error).toEqual({}); expect(form.$valid).toEqual(true); expect(form.$invalid).toEqual(false); }); }); }); describe('id assignment', function() { it('should default to name expression', function() { expect(form.text).toEqual(widget); }); it('should use ng:id', function() { widget = form.$createWidget({ scope:scope, model:'text', alias:'my.id', controller:WidgetCtrl }); expect(form['my.id']).toEqual(widget); }); it('should not override existing names', function() { var widget2 = form.$createWidget({ scope:scope, model:'text', alias:'text', controller:WidgetCtrl }); expect(form.text).toEqual(widget); expect(widget2).not.toEqual(widget); }); }); describe('dealocation', function() { it('should dealocate', function() { var widget2 = form.$createWidget({ scope:scope, model:'text', alias:'myId', controller:WidgetCtrl }); expect(form.myId).toEqual(widget2); var widget3 = form.$createWidget({ scope:scope, model:'text', alias:'myId', controller:WidgetCtrl }); expect(form.myId).toEqual(widget2); widget3.$destroy(); expect(form.myId).toEqual(widget2); widget2.$destroy(); expect(form.myId).toBeUndefined(); }); it('should remove invalid fields from errors, when child widget removed', function() { widget.$emit('$invalid', 'MyError'); expect(form.$error.MyError).toEqual([widget]); expect(form.$invalid).toEqual(true); widget.$destroy(); expect(form.$error.MyError).toBeUndefined(); expect(form.$invalid).toEqual(false); }); }); }); }); });