aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMisko Hevery2011-01-13 10:35:26 -0800
committerMisko Hevery2011-01-14 10:30:00 -0800
commit347be5ae9aa6829427e1e8e1b1e58afdf2a36c0a (patch)
tree3b350a12378c1ec63f60cce0fe674186d204726e /test
parent934f44f69e94a77a3ea6c19dc5c6f82ade2cc669 (diff)
downloadangular.js-347be5ae9aa6829427e1e8e1b1e58afdf2a36c0a.tar.bz2
fixed select with ng:format
select (one/multiple) could not chose from a list of objects, since DOM requires string ids. Solved by adding index formatter, which exposed incorrect handling of formatters in select widgets.
Diffstat (limited to 'test')
-rw-r--r--test/FormattersSpec.js15
-rw-r--r--test/JsonSpec.js17
-rw-r--r--test/ParserSpec.js25
-rw-r--r--test/directivesSpec.js15
-rw-r--r--test/widgetsSpec.js98
5 files changed, 142 insertions, 28 deletions
diff --git a/test/FormattersSpec.js b/test/FormattersSpec.js
index af50f384..1ebd8e22 100644
--- a/test/FormattersSpec.js
+++ b/test/FormattersSpec.js
@@ -33,5 +33,20 @@ describe("formatter", function(){
assertEquals('a', angular.formatter.trim.format(" a "));
assertEquals('a', angular.formatter.trim.parse(' a '));
});
+
+ describe('json', function(){
+ it('should treat empty string as null', function(){
+ expect(angular.formatter.json.parse('')).toEqual(null);
+ });
+ });
+
+ describe('index', function(){
+ it('should parse an object from array', function(){
+ expect(angular.formatter.index.parse('1', ['A', 'B', 'C'])).toEqual('B');
+ });
+ it('should format an index from array', function(){
+ expect(angular.formatter.index.format('B', ['A', 'B', 'C'])).toEqual('1');
+ });
+ });
});
diff --git a/test/JsonSpec.js b/test/JsonSpec.js
index 6d8a40e4..4a160905 100644
--- a/test/JsonSpec.js
+++ b/test/JsonSpec.js
@@ -92,11 +92,11 @@ describe('json', function(){
it('should not serialize undefined values', function() {
expect(angular.toJson({A:undefined})).toEqual('{}');
});
-
+
it('should not serialize $window object', function() {
expect(toJson(window)).toEqual('WINDOW');
});
-
+
it('should not serialize $document object', function() {
expect(toJson(document)).toEqual('DOCUMENT');
});
@@ -116,6 +116,13 @@ describe('json', function(){
expect(fromJson("{exp:1.2e-10}")).toEqual({exp:1.2E-10});
});
+ it('should ignore non-strings', function(){
+ expect(fromJson([])).toEqual([]);
+ expect(fromJson({})).toEqual({});
+ expect(fromJson(null)).toEqual(null);
+ expect(fromJson(undefined)).toEqual(undefined);
+ });
+
//run these tests only in browsers that have native JSON parser
if (JSON && JSON.parse) {
@@ -187,18 +194,18 @@ describe('json', function(){
expect(function(){fromJson('[].constructor');}).
toThrow(new Error("Parse Error: Token '.' is not valid json at column 3 of expression [[].constructor] starting at [.constructor]."));
});
-
+
it('should not allow object dereference', function(){
expect(function(){fromJson('{a:1, b: $location, c:1}');}).toThrow();
expect(function(){fromJson("{a:1, b:[1]['__parent__']['location'], c:1}");}).toThrow();
});
-
+
it('should not allow assignments', function(){
expect(function(){fromJson("{a:1, b:[1]=1, c:1}");}).toThrow();
expect(function(){fromJson("{a:1, b:=1, c:1}");}).toThrow();
expect(function(){fromJson("{a:1, b:x=1, c:1}");}).toThrow();
});
-
+
});
});
diff --git a/test/ParserSpec.js b/test/ParserSpec.js
index c237aa40..4d0e14dc 100644
--- a/test/ParserSpec.js
+++ b/test/ParserSpec.js
@@ -396,4 +396,29 @@ describe('parser', function() {
expect(scope.obj.name).toBeUndefined();
expect(scope.obj[0].name).toEqual(1);
});
+
+ describe('formatter', function(){
+ it('should return no argument function', function() {
+ var noop = parser('noop').formatter()();
+ expect(noop.format(null, 'abc')).toEqual('abc');
+ expect(noop.parse(null, '123')).toEqual('123');
+ });
+
+ it('should delegate arguments', function(){
+ var index = parser('index:objs').formatter()();
+ expect(index.format({objs:['A','B']}, 'B')).toEqual('1');
+ expect(index.parse({objs:['A','B']}, '1')).toEqual('B');
+ });
+ });
+
+ describe('assignable', function(){
+ it('should expose assignment function', function(){
+ var fn = parser('a').assignable();
+ expect(fn.assign).toBeTruthy();
+ var scope = {};
+ fn.assign(scope, 123);
+ expect(scope).toEqual({a:123});
+ });
+ });
+
});
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index ab1813c3..ef8241f1 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -104,10 +104,17 @@ describe("directive", function(){
});
- it('should ng:bind-attr', function(){
- var scope = compile('<img ng:bind-attr="{src:\'http://localhost/mysrc\', alt:\'myalt\'}"/>');
- expect(element.attr('src')).toEqual('http://localhost/mysrc');
- expect(element.attr('alt')).toEqual('myalt');
+ describe('ng:bind-attr', function(){
+ it('should bind attributes', function(){
+ var scope = compile('<img ng:bind-attr="{src:\'http://localhost/mysrc\', alt:\'myalt\'}"/>');
+ expect(element.attr('src')).toEqual('http://localhost/mysrc');
+ expect(element.attr('alt')).toEqual('myalt');
+ });
+
+ it('should not pretty print JSON in attributes', function(){
+ var scope = compile('<img alt="{{ {a:1} }}"/>');
+ expect(element.attr('alt')).toEqual('{"a":1}');
+ });
});
it('should remove special attributes on false', function(){
diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js
index 8dab4630..946c433f 100644
--- a/test/widgetsSpec.js
+++ b/test/widgetsSpec.js
@@ -44,7 +44,7 @@ describe("widget", function(){
expect(scope.$get('name')).toEqual('Kai');
expect(scope.$get('count')).toEqual(2);
});
-
+
it('should not trigger eval if value does not change', function(){
compile('<input type="Text" name="name" value="Misko" ng:change="count = count + 1" ng:init="count=0"/>');
expect(scope.name).toEqual("Misko");
@@ -53,7 +53,7 @@ describe("widget", function(){
expect(scope.name).toEqual("Misko");
expect(scope.count).toEqual(0);
});
-
+
it('should allow complex refernce binding', function(){
compile('<div ng:init="obj={abc:{}}">'+
'<input type="Text" name="obj[\'abc\'].name" value="Misko""/>'+
@@ -416,7 +416,7 @@ describe("widget", function(){
scope.$eval();
expect(element[0].childNodes[1].selected).toEqual(true);
});
-
+
it('should select default option on repeater', function(){
compile(
'<select name="selection">' +
@@ -424,7 +424,7 @@ describe("widget", function(){
'</select>');
expect(scope.selection).toEqual('1');
});
-
+
it('should select selected option on repeater', function(){
compile(
'<select name="selection">' +
@@ -433,7 +433,7 @@ describe("widget", function(){
'</select>');
expect(scope.selection).toEqual('ABC');
});
-
+
it('should select dynamically selected option on repeater', function(){
compile(
'<select name="selection">' +
@@ -441,21 +441,81 @@ describe("widget", function(){
'</select>');
expect(scope.selection).toEqual('2');
});
-
+
+ it('should allow binding to objects through JSON', function(){
+ compile(
+ '<select name="selection" ng:format="json">' +
+ '<option ng:repeat="obj in objs" value="{{obj}}">{{obj.name}}</option>' +
+ '</select>');
+ scope.objs = [{name:'A'}, {name:'B'}];
+ scope.$eval();
+ expect(scope.selection).toEqual({name:'A'});
+ });
+
+ it('should allow binding to objects through index', function(){
+ compile(
+ '<select name="selection" ng:format="index:objs">' +
+ '<option ng:repeat="obj in objs" value="{{$index}}">{{obj.name}}</option>' +
+ '</select>');
+ scope.objs = [{name:'A'}, {name:'B'}];
+ scope.$eval();
+ expect(scope.selection).toBe(scope.objs[0]);
+ });
+
});
- it('should support type="select-multiple"', function(){
- compile(
- '<select name="selection" multiple>' +
- '<option>A</option>' +
- '<option selected>B</option>' +
- '</select>');
- expect(scope.selection).toEqual(['B']);
- scope.selection = ['A'];
- scope.$eval();
- expect(element[0].childNodes[0].selected).toEqual(true);
+ describe('select-multiple', function(){
+ it('should support type="select-multiple"', function(){
+ compile('<select name="selection" multiple>' +
+ '<option>A</option>' +
+ '<option selected>B</option>' +
+ '</select>');
+ expect(scope.selection).toEqual(['B']);
+ scope.selection = ['A'];
+ scope.$eval();
+ expect(element[0].childNodes[0].selected).toEqual(true);
+ });
+
+ it('should allow binding to objects through index', function(){
+ compile('<select name="selection" multiple ng:format="index:list">' +
+ '<option selected value="0">A</option>' +
+ '<option selected value="1">B</option>' +
+ '<option value="2">C</option>' +
+ '</select>',
+ function(){
+ scope.list = [{name:'A'}, {name:'B'}, {name:'C'}];
+ });
+ scope.$eval();
+ expect(scope.selection).toEqual([{name:'A'}, {name:'B'}]);
+ });
+
+ it('should be empty array when no items are selected', function(){
+ compile(
+ '<select name="selection" multiple ng:format="index:list">' +
+ '<option value="0">A</option>' +
+ '<option value="1">B</option>' +
+ '<option value="2">C</option>' +
+ '</select>');
+ scope.list = [{name:'A'}, {name:'B'}, {name:'C'}];
+ scope.$eval();
+ expect(scope.selection).toEqual([]);
+ });
+
+ it('should be contain the selected object', function(){
+ compile('<select name="selection" multiple ng:format="index:list">' +
+ '<option value="0">A</option>' +
+ '<option value="1" selected>B</option>' +
+ '<option value="2">C</option>' +
+ '</select>',
+ function(){
+ scope.list = [{name:'A'}, {name:'B'}, {name:'C'}];
+ });
+ scope.$eval();
+ expect(scope.selection).toEqual([{name:'B'}]);
+ });
+
});
-
+
it('should ignore text widget which have no name', function(){
compile('<input type="text"/>');
expect(scope.$element.attr('ng-exception')).toBeFalsy();
@@ -504,7 +564,7 @@ describe("widget", function(){
scope.$eval();
expect(element.text()).toEqual('true:misko');
});
-
+
it("should compare stringified versions", function(){
var switchWidget = angular.widget('ng:switch');
expect(switchWidget.equals(true, 'true')).toEqual(true);
@@ -521,7 +581,7 @@ describe("widget", function(){
scope.$eval();
expect(element.text()).toEqual('one');
});
-
+
it("should match urls", function(){
var scope = angular.compile('<ng:switch on="url" using="route:params"><div ng:switch-when="/Book/:name">{{params.name}}</div></ng:switch>');
scope.url = '/Book/Moby';