Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fa73cb4e7 | |||
| f6458826ac | |||
| ab2531143e | |||
| 9a83f9d2fa | |||
| 3f07eb227d | |||
| 446e5669a1 | |||
| b264be40bc | |||
| 814c9847e8 | |||
| dde613f18e | |||
| e6a2527cdf | |||
| d0351c4803 | |||
| b2b6d74ae5 | |||
| 30694c8027 | |||
| 655ac6474b | |||
| e5a9b265ba | |||
| e2b9eccde0 | |||
| 9b3d9656a6 | |||
| 1e6a5b29a6 | |||
| 8f05ca5552 | |||
| 2ec8d1ffc0 | |||
| 08cd5c19c7 | |||
| 41dc7d5ebd | |||
| 0caa5ad83f | |||
| 5d36353bc9 | |||
| 719d5c5fa5 | |||
| 266da34098 |
+1
-1
@@ -60,7 +60,7 @@
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- ***:** use Object.create instead of creating temporary constructors
|
||||
- use Object.create instead of creating temporary constructors
|
||||
([bf6a79c3](https://github.com/angular/angular.js/commit/bf6a79c3484f474c300b5442ae73483030ef5782),
|
||||
[#10058](https://github.com/angular/angular.js/issues/10058))
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ to anchors on the same page without needing to know on which page the user curre
|
||||
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
|
||||
to entry point of your application (e.g. index.html). Requiring a `<base>` tag is also important for
|
||||
this case, as it allows Angular to differentiate between the part of the url that is the application
|
||||
base and the path that should be handeled by the application.
|
||||
base and the path that should be handled by the application.
|
||||
|
||||
### Sending links among different browsers
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ To make your Angular application work on IE please make sure that:
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
5. Use `ng-style` tags instead of `style="{{ someCss }}"`. The later works in Chrome and Firefox
|
||||
5. Use `ng-style` tags instead of `style="{{ someCss }}"`. The latter works in Chrome and Firefox
|
||||
but does not work in Internet Explorer <= 11 (the most recent version at time of writing).
|
||||
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ npm --version
|
||||
```
|
||||
|
||||
|
||||
<div class="alert alert-info">If you need to run a different versions of node.js
|
||||
<div class="alert alert-info">If you need to run different versions of node.js
|
||||
in your local environment, consider installing
|
||||
<a href="https://github.com/creationix/nvm" title="Node Version Manager Github Repo link">
|
||||
Node Version Manager (nvm)
|
||||
|
||||
+2
-2
@@ -162,8 +162,8 @@ if ('i' !== 'I'.toLowerCase()) {
|
||||
}
|
||||
|
||||
|
||||
var /** holds major version number for IE or NaN for real browsers */
|
||||
msie,
|
||||
var
|
||||
msie, // holds major version number for IE, or NaN if UA is not IE.
|
||||
jqLite, // delay binding since jQuery could be loaded after us.
|
||||
jQuery, // delay binding
|
||||
slice = [].slice,
|
||||
|
||||
+2
-2
@@ -803,7 +803,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
||||
* urls during a[href] sanitization.
|
||||
*
|
||||
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
||||
* The sanitization is a security measure aimed at preventing XSS attacks via html links.
|
||||
*
|
||||
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into
|
||||
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
|
||||
@@ -870,7 +870,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
* * `ng-binding` CSS class
|
||||
* * `$binding` data property containing an array of the binding expressions
|
||||
*
|
||||
* You may want to use this in production for a significant performance boost. See
|
||||
* You may want to disable this in production for a significant performance boost. See
|
||||
* {@link guide/production#disabling-debug-data Disabling Debug Data} for more.
|
||||
*
|
||||
* The default value is true.
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
* make the link go to the wrong URL if the user clicks it before
|
||||
* Angular has a chance to replace the `{{hash}}` markup with its
|
||||
* value. Until Angular replaces the markup the link will be broken
|
||||
* and will most likely return a 404 error.
|
||||
*
|
||||
* The `ngHref` directive solves this problem.
|
||||
* and will most likely return a 404 error. The `ngHref` directive
|
||||
* solves this problem.
|
||||
*
|
||||
* The wrong way to write it:
|
||||
* ```html
|
||||
|
||||
@@ -40,7 +40,6 @@ var scriptDirective = ['$templateCache', function($templateCache) {
|
||||
compile: function(element, attr) {
|
||||
if (attr.type == 'text/ng-template') {
|
||||
var templateUrl = attr.id,
|
||||
// IE is not consistent, in scripts we have to read .text but in other nodes we have to read .textContent
|
||||
text = element[0].text;
|
||||
|
||||
$templateCache.put(templateUrl, text);
|
||||
|
||||
@@ -212,7 +212,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
||||
self.removeOption = function(value) {
|
||||
if (this.hasOption(value)) {
|
||||
delete optionsMap[value];
|
||||
if (ngModelCtrl.$viewValue == value) {
|
||||
if (ngModelCtrl.$viewValue === value) {
|
||||
this.renderUnknownOption(value);
|
||||
}
|
||||
}
|
||||
@@ -679,18 +679,23 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
||||
updateLabelMap(labelMap, option.label, false);
|
||||
option.element.remove();
|
||||
}
|
||||
forEach(labelMap, function(count, label) {
|
||||
if (count > 0) {
|
||||
selectCtrl.addOption(label);
|
||||
} else if (count < 0) {
|
||||
selectCtrl.removeOption(label);
|
||||
}
|
||||
});
|
||||
}
|
||||
// remove any excessive OPTGROUPs from select
|
||||
while (optionGroupsCache.length > groupIndex) {
|
||||
optionGroupsCache.pop()[0].element.remove();
|
||||
// remove all the labels in the option group
|
||||
optionGroup = optionGroupsCache.pop();
|
||||
for (index = 1; index < optionGroup.length; ++index) {
|
||||
updateLabelMap(labelMap, optionGroup[index].label, false);
|
||||
}
|
||||
optionGroup[0].element.remove();
|
||||
}
|
||||
forEach(labelMap, function(count, label) {
|
||||
if (count > 0) {
|
||||
selectCtrl.addOption(label);
|
||||
} else if (count < 0) {
|
||||
selectCtrl.removeOption(label);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -610,12 +610,14 @@ function $HttpProvider() {
|
||||
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* request body and headers and returns its transformed (typically serialized) version.
|
||||
* See {@link #overriding-the-default-transformations-per-request Overriding the Default Transformations}
|
||||
* See {@link ng.$http#overriding-the-default-transformations-per-request
|
||||
* Overriding the Default Transformations}
|
||||
* - **transformResponse** –
|
||||
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* response body and headers and returns its transformed (typically deserialized) version.
|
||||
* See {@link #overriding-the-default-transformations-per-request Overriding the Default Transformations}
|
||||
* See {@link ng.$http#overriding-the-default-transformations-per-request
|
||||
* Overriding the Default Transformations}
|
||||
* - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
|
||||
* GET request, otherwise if a cache instance built with
|
||||
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
|
||||
|
||||
@@ -126,7 +126,9 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
||||
|
||||
function completeRequest(callback, status, response, headersString, statusText) {
|
||||
// cancel timeout and subsequent timeout promise resolution
|
||||
timeoutId && $browserDefer.cancel(timeoutId);
|
||||
if (timeoutId !== undefined) {
|
||||
$browserDefer.cancel(timeoutId);
|
||||
}
|
||||
jsonpDone = xhr = null;
|
||||
|
||||
callback(status, response, headersString, statusText);
|
||||
|
||||
+2
-2
@@ -722,13 +722,13 @@ Parser.prototype = {
|
||||
ensureSafeObject(context, expressionText);
|
||||
ensureSafeFunction(fn, expressionText);
|
||||
|
||||
// IE stupidity! (IE doesn't have apply for some native functions)
|
||||
// IE doesn't have apply for some native functions
|
||||
var v = fn.apply
|
||||
? fn.apply(context, args)
|
||||
: fn(args[0], args[1], args[2], args[3], args[4]);
|
||||
|
||||
return ensureSafeObject(v, expressionText);
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
// This is used with json array declaration
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
* @description
|
||||
* The root element of Angular application. This is either the element where {@link
|
||||
* ng.directive:ngApp ngApp} was declared or the element passed into
|
||||
* {@link angular.bootstrap}. The element represent the root element of application. It is also the
|
||||
* location where the applications {@link auto.$injector $injector} service gets
|
||||
* published, it can be retrieved using `$rootElement.injector()`.
|
||||
* {@link angular.bootstrap}. The element represents the root element of application. It is also the
|
||||
* location where the application's {@link auto.$injector $injector} service gets
|
||||
* published, and can be retrieved using `$rootElement.injector()`.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -28,14 +28,9 @@ function $TemplateRequestProvider() {
|
||||
var transformResponse = $http.defaults && $http.defaults.transformResponse;
|
||||
|
||||
if (isArray(transformResponse)) {
|
||||
var original = transformResponse;
|
||||
transformResponse = [];
|
||||
for (var i = 0; i < original.length; ++i) {
|
||||
var transformer = original[i];
|
||||
if (transformer !== defaultHttpResponseTransform) {
|
||||
transformResponse.push(transformer);
|
||||
}
|
||||
}
|
||||
transformResponse = transformResponse.filter(function(transformer) {
|
||||
return transformer !== defaultHttpResponseTransform;
|
||||
});
|
||||
} else if (transformResponse === defaultHttpResponseTransform) {
|
||||
transformResponse = null;
|
||||
}
|
||||
@@ -53,12 +48,12 @@ function $TemplateRequestProvider() {
|
||||
return html;
|
||||
}, handleError);
|
||||
|
||||
function handleError() {
|
||||
function handleError(resp) {
|
||||
self.totalPendingRequests--;
|
||||
if (!ignoreRequestError) {
|
||||
throw $compileMinErr('tpload', 'Failed to load template: {0}', tpl);
|
||||
}
|
||||
return $q.reject();
|
||||
return $q.reject(resp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -1142,7 +1142,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
||||
return function() {
|
||||
return angular.isNumber(status)
|
||||
? [status, data, headers, statusText]
|
||||
: [200, status, data];
|
||||
: [200, status, data, headers];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2047,7 +2047,7 @@ angular.mock.e2e.$httpBackendDecorator =
|
||||
*
|
||||
* In addition to all the regular `Scope` methods, the following helper methods are available:
|
||||
*/
|
||||
angular.mock.$RootScopeDecorator = function($delegate) {
|
||||
angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
|
||||
|
||||
var $rootScopePrototype = Object.getPrototypeOf($delegate);
|
||||
|
||||
@@ -2119,7 +2119,7 @@ angular.mock.$RootScopeDecorator = function($delegate) {
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
if (window.jasmine || window.mocha) {
|
||||
|
||||
@@ -175,7 +175,7 @@ function $RouteProvider() {
|
||||
* @description
|
||||
*
|
||||
* A boolean property indicating if routes defined
|
||||
* using this provider should be matched using a case sensitive
|
||||
* using this provider should be matched using a case insensitive
|
||||
* algorithm. Defaults to `false`.
|
||||
*/
|
||||
this.caseInsensitiveMatch = false;
|
||||
|
||||
@@ -142,7 +142,7 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
|
||||
'" ');
|
||||
}
|
||||
html.push('href="',
|
||||
url.replace('"', '"'),
|
||||
url.replace(/"/g, '"'),
|
||||
'">');
|
||||
addText(text);
|
||||
html.push('</a>');
|
||||
|
||||
@@ -40,6 +40,23 @@ describe('select', function() {
|
||||
return equals(expectedValues, actualValues);
|
||||
},
|
||||
|
||||
toEqualSelectWithOptions: function(expected) {
|
||||
var actualValues = {};
|
||||
var optionGroup;
|
||||
|
||||
forEach(this.actual.find('option'), function(option) {
|
||||
optionGroup = option.parentNode.label || '';
|
||||
actualValues[optionGroup] = actualValues[optionGroup] || [];
|
||||
actualValues[optionGroup].push(option.label);
|
||||
});
|
||||
|
||||
this.message = function() {
|
||||
return 'Expected ' + toJson(actualValues) + ' to equal ' + toJson(expected) + '.';
|
||||
};
|
||||
|
||||
return equals(expected, actualValues);
|
||||
},
|
||||
|
||||
toEqualOption: function(value, text, label) {
|
||||
var errors = [];
|
||||
if (this.actual.attr('value') !== value) {
|
||||
@@ -233,6 +250,31 @@ describe('select', function() {
|
||||
expect(scope.robot).toBe('');
|
||||
});
|
||||
|
||||
it('should not be set when an option is selected and options are set asynchronously',
|
||||
inject(function($timeout) {
|
||||
compile('<select ng-model="model" ng-options="opt.id as opt.label for opt in options">' +
|
||||
'</select>');
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.model = 0;
|
||||
});
|
||||
|
||||
$timeout(function() {
|
||||
scope.options = [
|
||||
{id: 0, label: 'x'},
|
||||
{id: 1, label: 'y'}
|
||||
];
|
||||
}, 0);
|
||||
|
||||
$timeout.flush();
|
||||
|
||||
var options = element.find('option');
|
||||
|
||||
expect(options.length).toEqual(2);
|
||||
expect(options.eq(0)).toEqualOption('0', 'x');
|
||||
expect(options.eq(1)).toEqualOption('1', 'y');
|
||||
})
|
||||
);
|
||||
|
||||
describe('interactions with repeated options', function() {
|
||||
|
||||
@@ -447,6 +489,7 @@ describe('select', function() {
|
||||
expect(selectCtrl.hasOption('r2d2')).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should return false for options popped via ngOptions', function() {
|
||||
scope.robots = [
|
||||
{value: 1, label: 'c3p0'},
|
||||
@@ -467,6 +510,7 @@ describe('select', function() {
|
||||
expect(selectCtrl.hasOption('r2d2')).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should return true for options added via ngOptions', function() {
|
||||
scope.robots = [
|
||||
{value: 2, label: 'r2d2'}
|
||||
@@ -485,6 +529,169 @@ describe('select', function() {
|
||||
expect(selectCtrl.hasOption('c3p0')).toBe(true);
|
||||
expect(selectCtrl.hasOption('r2d2')).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should keep all the options when changing the model', function() {
|
||||
compile('<select ng-model="mySelect" ng-options="o for o in [\'A\',\'B\',\'C\']"></select>');
|
||||
var selectCtrl = element.controller('select');
|
||||
scope.$apply(function() {
|
||||
scope.mySelect = 'C';
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(true);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(element).toEqualSelectWithOptions({'': ['A', 'B', 'C']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when elements move from a previous group', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'first'},
|
||||
{name: 'E', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values[3] = {name: 'D', group: 'second'};
|
||||
scope.values.shift();
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(false);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(selectCtrl.hasOption('D')).toBe(true);
|
||||
expect(selectCtrl.hasOption('E')).toBe(true);
|
||||
expect(element).toEqualSelectWithOptions({'': [''], 'first':['B', 'C'], 'second': ['D', 'E']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when elements move from a following group', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'second'},
|
||||
{name: 'E', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values[3].group = 'first';
|
||||
scope.values.shift();
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(false);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(selectCtrl.hasOption('D')).toBe(true);
|
||||
expect(selectCtrl.hasOption('E')).toBe(true);
|
||||
expect(element).toEqualSelectWithOptions({'': [''], 'first':['B', 'C', 'D'], 'second': ['E']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when an element is replaced with an element from a previous group', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'first'},
|
||||
{name: 'E', group: 'second'},
|
||||
{name: 'F', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values[3].group = 'second';
|
||||
scope.values.pop();
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(true);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(selectCtrl.hasOption('D')).toBe(true);
|
||||
expect(selectCtrl.hasOption('E')).toBe(true);
|
||||
expect(selectCtrl.hasOption('F')).toBe(false);
|
||||
expect(element).toEqualSelectWithOptions({'': ['', 'A'], 'first':['B', 'C'], 'second': ['D', 'E']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when element is replaced with an element from a following group', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'second'},
|
||||
{name: 'E', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values[3].group = 'first';
|
||||
scope.values.splice(2, 1);
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(true);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(false);
|
||||
expect(selectCtrl.hasOption('D')).toBe(true);
|
||||
expect(selectCtrl.hasOption('E')).toBe(true);
|
||||
expect(element).toEqualSelectWithOptions({'': ['', 'A'], 'first':['B', 'D'], 'second': ['E']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when an element is removed', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'second'},
|
||||
{name: 'E', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values.splice(3, 1);
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(true);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(selectCtrl.hasOption('D')).toBe(false);
|
||||
expect(selectCtrl.hasOption('E')).toBe(true);
|
||||
expect(element).toEqualSelectWithOptions({'': ['', 'A'], 'first':['B', 'C'], 'second': ['E']});
|
||||
});
|
||||
|
||||
|
||||
it('should be able to detect when a group is removed', function() {
|
||||
scope.values = [
|
||||
{name: 'A'},
|
||||
{name: 'B', group: 'first'},
|
||||
{name: 'C', group: 'first'},
|
||||
{name: 'D', group: 'second'},
|
||||
{name: 'E', group: 'second'}
|
||||
];
|
||||
|
||||
compile('<select ng-model="mySelect" ng-options="item.name group by item.group for item in values"></select>');
|
||||
var selectCtrl = element.data().$selectController;
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.values.splice(3, 2);
|
||||
});
|
||||
expect(selectCtrl.hasOption('A')).toBe(true);
|
||||
expect(selectCtrl.hasOption('B')).toBe(true);
|
||||
expect(selectCtrl.hasOption('C')).toBe(true);
|
||||
expect(selectCtrl.hasOption('D')).toBe(false);
|
||||
expect(selectCtrl.hasOption('E')).toBe(false);
|
||||
expect(element).toEqualSelectWithOptions({'': ['', 'A'], 'first':['B', 'C']});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,36 +4,7 @@
|
||||
describe('$httpBackend', function() {
|
||||
|
||||
var $backend, $browser, callbacks,
|
||||
xhr, fakeDocument, callback,
|
||||
fakeTimeoutId = 0;
|
||||
|
||||
// TODO(vojta): should be replaced by $defer mock
|
||||
function fakeTimeout(fn, delay) {
|
||||
fakeTimeout.fns.push(fn);
|
||||
fakeTimeout.delays.push(delay);
|
||||
fakeTimeout.ids.push(++fakeTimeoutId);
|
||||
return fakeTimeoutId;
|
||||
}
|
||||
|
||||
fakeTimeout.fns = [];
|
||||
fakeTimeout.delays = [];
|
||||
fakeTimeout.ids = [];
|
||||
fakeTimeout.flush = function() {
|
||||
var len = fakeTimeout.fns.length;
|
||||
fakeTimeout.delays = [];
|
||||
fakeTimeout.ids = [];
|
||||
while (len--) fakeTimeout.fns.shift()();
|
||||
};
|
||||
fakeTimeout.cancel = function(id) {
|
||||
var i = fakeTimeout.ids.indexOf(id);
|
||||
if (i >= 0) {
|
||||
fakeTimeout.fns.splice(i, 1);
|
||||
fakeTimeout.delays.splice(i, 1);
|
||||
fakeTimeout.ids.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
xhr, fakeDocument, callback;
|
||||
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
@@ -57,7 +28,7 @@ describe('$httpBackend', function() {
|
||||
})
|
||||
}
|
||||
};
|
||||
$backend = createHttpBackend($browser, createMockXhr, fakeTimeout, callbacks, fakeDocument);
|
||||
$backend = createHttpBackend($browser, createMockXhr, $browser.defer, callbacks, fakeDocument);
|
||||
callback = jasmine.createSpy('done');
|
||||
}));
|
||||
|
||||
@@ -154,7 +125,7 @@ describe('$httpBackend', function() {
|
||||
xhr = MockXhr.$$lastInstance;
|
||||
spyOn(xhr, 'abort');
|
||||
|
||||
fakeTimeout.flush();
|
||||
$browser.defer.flush();
|
||||
expect(xhr.abort).toHaveBeenCalledOnce();
|
||||
|
||||
xhr.status = 0;
|
||||
@@ -171,9 +142,9 @@ describe('$httpBackend', function() {
|
||||
xhr = MockXhr.$$lastInstance;
|
||||
spyOn(xhr, 'abort');
|
||||
|
||||
expect(fakeTimeout.delays[0]).toBe(2000);
|
||||
expect($browser.deferredFns[0].time).toBe(2000);
|
||||
|
||||
fakeTimeout.flush();
|
||||
$browser.defer.flush();
|
||||
expect(xhr.abort).toHaveBeenCalledOnce();
|
||||
|
||||
xhr.status = 0;
|
||||
@@ -227,13 +198,13 @@ describe('$httpBackend', function() {
|
||||
xhr = MockXhr.$$lastInstance;
|
||||
spyOn(xhr, 'abort');
|
||||
|
||||
expect(fakeTimeout.delays[0]).toBe(2000);
|
||||
expect($browser.deferredFns[0].time).toBe(2000);
|
||||
|
||||
xhr.status = 200;
|
||||
xhr.onload();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
|
||||
expect(fakeTimeout.delays.length).toBe(0);
|
||||
expect($browser.deferredFns.length).toBe(0);
|
||||
expect(xhr.abort).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -342,12 +313,12 @@ describe('$httpBackend', function() {
|
||||
|
||||
$backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback, null, 2000);
|
||||
expect(fakeDocument.$$scripts.length).toBe(1);
|
||||
expect(fakeTimeout.delays[0]).toBe(2000);
|
||||
expect($browser.deferredFns[0].time).toBe(2000);
|
||||
|
||||
var script = fakeDocument.$$scripts.shift(),
|
||||
callbackId = script.src.match(SCRIPT_URL)[2];
|
||||
|
||||
fakeTimeout.flush();
|
||||
$browser.defer.flush();
|
||||
expect(fakeDocument.$$scripts.length).toBe(0);
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
|
||||
|
||||
@@ -1232,7 +1232,7 @@ describe('$location', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should not rewrite full url links do different domain', function() {
|
||||
it('should not rewrite full url links to different domain', function() {
|
||||
configureService({linkHref: 'http://www.dot.abc/a?b=c', html5Mode: true});
|
||||
inject(
|
||||
initBrowser(),
|
||||
@@ -1298,7 +1298,7 @@ describe('$location', function() {
|
||||
|
||||
|
||||
it ('should not rewrite links when rewriting links is disabled', function() {
|
||||
configureService('/a?b=c', true, true, '', 'some content', false);
|
||||
configureService({linkHref: 'link?a#b', html5Mode: {enabled: true, rewriteLinks:false}, supportHist: true});
|
||||
inject(
|
||||
initBrowser(),
|
||||
initLocation(),
|
||||
|
||||
@@ -43,6 +43,20 @@ describe('$templateRequest', function() {
|
||||
}).toThrowMinErr('$compile', 'tpload', 'Failed to load template: tpl.html');
|
||||
}));
|
||||
|
||||
it('should not throw when the template is not found and ignoreRequestError is true',
|
||||
inject(function($rootScope, $templateRequest, $httpBackend) {
|
||||
|
||||
$httpBackend.expectGET('tpl.html').respond(404);
|
||||
|
||||
var err;
|
||||
$templateRequest('tpl.html', true).catch(function(reason) { err = reason; });
|
||||
|
||||
$rootScope.$digest();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(err.status).toBe(404);
|
||||
}));
|
||||
|
||||
it('should not throw an error when the template is empty',
|
||||
inject(function($rootScope, $templateRequest, $httpBackend) {
|
||||
|
||||
|
||||
Vendored
+18
-11
@@ -1059,17 +1059,6 @@ describe('ngMock', function() {
|
||||
expect(callback).toHaveBeenCalledOnceWith(200, 'first', 'header: val', 'OK');
|
||||
});
|
||||
|
||||
it('should take function', function() {
|
||||
hb.expect('GET', '/some').respond(function(m, u, d, h) {
|
||||
return [301, m + u + ';' + d + ';a=' + h.a, {'Connection': 'keep-alive'}, 'Moved Permanently'];
|
||||
});
|
||||
|
||||
hb('GET', '/some', 'data', callback, {a: 'b'});
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith(301, 'GET/some;data;a=b', 'Connection: keep-alive', 'Moved Permanently');
|
||||
});
|
||||
|
||||
it('should default status code to 200', function() {
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(status).toBe(200);
|
||||
@@ -1085,6 +1074,24 @@ describe('ngMock', function() {
|
||||
expect(callback.callCount).toBe(2);
|
||||
});
|
||||
|
||||
it('should default status code to 200 and provide status text', function() {
|
||||
hb.expect('GET', '/url1').respond('first', {'header': 'val'}, 'OK');
|
||||
hb('GET', '/url1', null, callback);
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith(200, 'first', 'header: val', 'OK');
|
||||
});
|
||||
|
||||
it('should take function', function() {
|
||||
hb.expect('GET', '/some').respond(function(m, u, d, h) {
|
||||
return [301, m + u + ';' + d + ';a=' + h.a, {'Connection': 'keep-alive'}, 'Moved Permanently'];
|
||||
});
|
||||
|
||||
hb('GET', '/some', 'data', callback, {a: 'b'});
|
||||
hb.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith(301, 'GET/some;data;a=b', 'Connection: keep-alive', 'Moved Permanently');
|
||||
});
|
||||
|
||||
it('should default response headers to ""', function() {
|
||||
hb.expect('GET', '/url1').respond(200, 'first');
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('linky', function() {
|
||||
});
|
||||
|
||||
it('should handle quotes in the email', function() {
|
||||
expect(linky('foo@"bar.com')).toEqual('<a href="mailto:foo@"bar.com">foo@"bar.com</a>');
|
||||
expect(linky('foo@"bar".com')).toEqual('<a href="mailto:foo@"bar".com">foo@"bar".com</a>');
|
||||
});
|
||||
|
||||
it('should handle target:', function() {
|
||||
|
||||
Reference in New Issue
Block a user