aboutsummaryrefslogtreecommitdiffstats
path: root/test/service
diff options
context:
space:
mode:
authorMisko Hevery2011-09-08 13:56:29 -0700
committerIgor Minar2011-10-11 11:01:45 -0700
commit4f78fd692c0ec51241476e6be9a4df06cd62fdd6 (patch)
tree91f70bb89b9c095126fbc093f51cedbac5cb0c78 /test/service
parentdf6d2ba3266de405ad6c2f270f24569355706e76 (diff)
downloadangular.js-4f78fd692c0ec51241476e6be9a4df06cd62fdd6.tar.bz2
feat(forms): new and improved forms
Diffstat (limited to 'test/service')
-rw-r--r--test/service/formFactorySpec.js218
-rw-r--r--test/service/invalidWidgetsSpec.js41
-rw-r--r--test/service/routeSpec.js20
3 files changed, 232 insertions, 47 deletions
diff --git a/test/service/formFactorySpec.js b/test/service/formFactorySpec.js
new file mode 100644
index 00000000..5223cede
--- /dev/null
+++ b/test/service/formFactorySpec.js
@@ -0,0 +1,218 @@
+'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 += '<init>';
+ 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('<init>$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);
+ });
+ });
+ });
+ });
+});
diff --git a/test/service/invalidWidgetsSpec.js b/test/service/invalidWidgetsSpec.js
deleted file mode 100644
index fe7efe38..00000000
--- a/test/service/invalidWidgetsSpec.js
+++ /dev/null
@@ -1,41 +0,0 @@
-'use strict';
-
-describe('$invalidWidgets', function() {
- var scope;
-
- beforeEach(function(){
- scope = angular.scope();
- });
-
-
- afterEach(function(){
- dealoc(scope);
- });
-
-
- it("should count number of invalid widgets", function(){
- var element = jqLite('<input name="price" ng:required ng:validate="number">');
- jqLite(document.body).append(element);
- scope = compile(element)();
- var $invalidWidgets = scope.$service('$invalidWidgets');
- expect($invalidWidgets.length).toEqual(1);
-
- scope.price = 123;
- scope.$digest();
- expect($invalidWidgets.length).toEqual(0);
-
- scope.$element.remove();
- scope.price = 'abc';
- scope.$digest();
- expect($invalidWidgets.length).toEqual(0);
-
- jqLite(document.body).append(scope.$element);
- scope.price = 'abcd'; //force revalidation, maybe this should be done automatically?
- scope.$digest();
- expect($invalidWidgets.length).toEqual(1);
-
- jqLite(document.body).html('');
- scope.$digest();
- expect($invalidWidgets.length).toEqual(0);
- });
-});
diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js
index c8c8cbeb..5aba2a1f 100644
--- a/test/service/routeSpec.js
+++ b/test/service/routeSpec.js
@@ -152,18 +152,18 @@ describe('$route', function() {
$location.path('/foo');
scope.$digest();
- expect(scope.$$childHead).toBeTruthy();
- expect(scope.$$childHead).toEqual(scope.$$childTail);
+ expect(scope.$$childHead.$id).toBeTruthy();
+ expect(scope.$$childHead.$id).toEqual(scope.$$childTail.$id);
$location.path('/bar');
scope.$digest();
- expect(scope.$$childHead).toBeTruthy();
- expect(scope.$$childHead).toEqual(scope.$$childTail);
+ expect(scope.$$childHead.$id).toBeTruthy();
+ expect(scope.$$childHead.$id).toEqual(scope.$$childTail.$id);
$location.path('/baz');
scope.$digest();
- expect(scope.$$childHead).toBeTruthy();
- expect(scope.$$childHead).toEqual(scope.$$childTail);
+ expect(scope.$$childHead.$id).toBeTruthy();
+ expect(scope.$$childHead.$id).toEqual(scope.$$childTail.$id);
$location.path('/');
scope.$digest();
@@ -172,6 +172,14 @@ describe('$route', function() {
});
+ it('should infer arguments in injection', function() {
+ $route.when('/test', {controller: function($route){ this.$route = $route; }});
+ $location.path('/test');
+ scope.$digest();
+ expect($route.current.scope.$route).toBe($route);
+ });
+
+
describe('redirection', function() {
it('should support redirection via redirectTo property by updating $location', function() {
var onChangeSpy = jasmine.createSpy('onChange');