Compare commits
263 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 652feebd86 | |||
| 16ccbc4f61 | |||
| 072d45fd01 | |||
| 4439e39319 | |||
| b49c3a1a1e | |||
| c7addd4886 | |||
| 6df60aff52 | |||
| e7a080d6e6 | |||
| 661a728764 | |||
| 89303fd2dc | |||
| 1f8be1ca66 | |||
| cbc2024092 | |||
| f0ff7023c3 | |||
| 6e8728a364 | |||
| f179a63dd4 | |||
| 3a71c1e595 | |||
| ef7a61a67e | |||
| a6b2ee785b | |||
| d5a1336e6b | |||
| d4312b731a | |||
| 66f051386e | |||
| 8b3f9684e0 | |||
| 331f32deac | |||
| bb80c96754 | |||
| 0d8e19c26f | |||
| ed2fd2d0ca | |||
| 7c60151cb8 | |||
| 965308a32c | |||
| 92c612a9de | |||
| a7b53abcad | |||
| d575e1f613 | |||
| 2ba458387d | |||
| 98489a1d0c | |||
| 51d501aab2 | |||
| 841bdf1c07 | |||
| 86cac55c7c | |||
| c0995399d4 | |||
| de6cc287e5 | |||
| afd6771163 | |||
| 4cda028609 | |||
| 8ecce7642b | |||
| d1d5761232 | |||
| 759cba1a8d | |||
| 23cd40a8ec | |||
| f3188c1d09 | |||
| 2f4967f100 | |||
| 4fe4e7457c | |||
| d4e7274d4b | |||
| cffa015554 | |||
| 1104c7d75b | |||
| 4c6b4447db | |||
| 741a37b338 | |||
| 1157c5d341 | |||
| e48adebfb7 | |||
| 0a61dcb486 | |||
| 4b51eaadf8 | |||
| e2457ca16d | |||
| bd62790080 | |||
| 53fdcafa44 | |||
| af6f2483be | |||
| d8522aa349 | |||
| bae3121683 | |||
| 54c0d464b0 | |||
| cf89e8653c | |||
| 0c3500f532 | |||
| c12f525df4 | |||
| e7ba830691 | |||
| 4eb0716711 | |||
| ed90f3b7ea | |||
| 14b19ecf5e | |||
| 644432a14c | |||
| a03e370a09 | |||
| 23677d3ddb | |||
| fc781560a3 | |||
| c9199ee663 | |||
| 6f18adedef | |||
| 6ad894cd58 | |||
| cde2f1a868 | |||
| 6a831495de | |||
| 6e2c38f54d | |||
| 00e7e31418 | |||
| ff4b3e20c1 | |||
| 269fb43b36 | |||
| 7530654328 | |||
| c7bd464384 | |||
| ef1874d1f3 | |||
| c6d8205fdd | |||
| 55150a669a | |||
| 1eb9e22d45 | |||
| c0de8fb737 | |||
| 557e3894d7 | |||
| 38a9695413 | |||
| 293e0336b0 | |||
| 1f5bc0a1cd | |||
| 1fe666192b | |||
| 29541e735d | |||
| f5b567d44b | |||
| 5ee3bbee90 | |||
| 80927c5811 | |||
| ca8b344e20 | |||
| 3dab93874d | |||
| 7550f90a57 | |||
| d78fea87d1 | |||
| 27cee7db0a | |||
| 60acba3840 | |||
| 51bed36370 | |||
| 6d940213ac | |||
| 494b527fa7 | |||
| 8ce84cb2ea | |||
| d981c2a3ec | |||
| 537e20065a | |||
| 97578b4dae | |||
| fa12564607 | |||
| 54bcb9ae25 | |||
| ad7ce0d402 | |||
| 085e0ea8ef | |||
| bb52c4e8d3 | |||
| 295af335c1 | |||
| 2c2e18c37a | |||
| adfb75e3c6 | |||
| 9bff5c60df | |||
| 3ba008d4b2 | |||
| 4e45a2f8e2 | |||
| 4dbd8452eb | |||
| 45a8db9c08 | |||
| d930a410fb | |||
| 66505ffc40 | |||
| 045de959b9 | |||
| 3ca11d5235 | |||
| d5d8ac01e3 | |||
| ace81c053c | |||
| 1e95c419b8 | |||
| 49ed63d26a | |||
| 6ff2685668 | |||
| c4573c04aa | |||
| d57abdb3f7 | |||
| 4050e89446 | |||
| b6620c737f | |||
| 0c8e908841 | |||
| 5595e196a8 | |||
| f92e4146d1 | |||
| 8b7108e3c9 | |||
| caf702cc88 | |||
| cf2c49ed7f | |||
| ccd52abf5d | |||
| 74c574015d | |||
| 1f1a6fb6d2 | |||
| 8632e893b0 | |||
| c2b6e127fa | |||
| 06eceeb09f | |||
| 8133d468b9 | |||
| 074a354fa9 | |||
| e191582a02 | |||
| 6fbe926cda | |||
| ebbc224e09 | |||
| 2c6aa4c300 | |||
| f7a8f17fc7 | |||
| 191efbb558 | |||
| bf873d6f02 | |||
| e741107c55 | |||
| 82f4b99d99 | |||
| 7210b7ae1d | |||
| afed23c001 | |||
| 1f69cc2989 | |||
| 3401833c83 | |||
| 06606e2816 | |||
| eba64e1f31 | |||
| 81dd1df1b1 | |||
| dbafbb0de5 | |||
| 1d0aa7b7c6 | |||
| afd02ca48c | |||
| 67db7616ad | |||
| 3d7c752e27 | |||
| f02833d634 | |||
| 0eb373e0e6 | |||
| fd3071843c | |||
| a631ceb223 | |||
| a713928210 | |||
| 05fa20df81 | |||
| 125573602f | |||
| ed5dfbcd66 | |||
| d2e52b2376 | |||
| a56aaa9877 | |||
| 79bb7b1f0b | |||
| b936e52874 | |||
| 0d52ff0f10 | |||
| baf52e902d | |||
| dffea9e2b7 | |||
| 4a411b8f82 | |||
| 278bfc4bb2 | |||
| 18731173f9 | |||
| d43fb404d7 | |||
| da984ad187 | |||
| 4015357ce5 | |||
| dc3d11ad19 | |||
| 0e1545eb04 | |||
| ec7cabf5c9 | |||
| 3051beba2f | |||
| 92304323b1 | |||
| c28123a872 | |||
| d798423813 | |||
| 2583e77cc7 | |||
| f66836fee4 | |||
| 0ccc445d53 | |||
| b7d5fa1cbe | |||
| 8bb3942453 | |||
| 51a79cebcb | |||
| 36bcf64008 | |||
| 5c6630605b | |||
| 125827406c | |||
| 62c21422a6 | |||
| 98d489712e | |||
| 2cab2d8ef1 | |||
| 8fa2bb72bc | |||
| d151f94937 | |||
| 5b74b7185b | |||
| 4f0be2ae4e | |||
| bb9badeb2a | |||
| c287c8361d | |||
| ade7127c79 | |||
| d341483f1f | |||
| b36acbc857 | |||
| a4fea38b94 | |||
| 300c5c0c99 | |||
| 152537c4e9 | |||
| 8b46bf6bc9 | |||
| aef861eb41 | |||
| f61d36861d | |||
| 2af0348cea | |||
| 78c5743494 | |||
| 2cb9fbd043 | |||
| e9dad5dbf4 | |||
| 54895fc2a1 | |||
| 60a12b4161 | |||
| cd7e58ba41 | |||
| 9391475dc3 | |||
| 7840803add | |||
| 7d77de2834 | |||
| ab044cada6 | |||
| d010e0cc7d | |||
| 40f728b1aa | |||
| 23abb26405 | |||
| fd55bc8e1d | |||
| 541aaa4e08 | |||
| f22c422547 | |||
| 0e461f0c07 | |||
| 5074448443 | |||
| 8d66af11e6 | |||
| 169948bb47 | |||
| 58d9469574 | |||
| 8d858a2360 | |||
| 5540748890 | |||
| f8a52be817 | |||
| 3b5f1105f6 | |||
| 663ccc5449 | |||
| 263f47819f | |||
| 6b75475ce3 | |||
| 07c354a8c0 | |||
| 1391579599 | |||
| 5d2bd1d84c | |||
| bf77e212af | |||
| eef2f9c31e | |||
| 438627c2c3 |
@@ -57,6 +57,25 @@ task :concat_scenario => :init do
|
||||
end
|
||||
|
||||
|
||||
desc 'Concat JSTD Scenario Adapter'
|
||||
task :concat_jstd_scenario_adapter => :init do
|
||||
|
||||
concat_file('jstd-scenario-adapter.js', [
|
||||
'src/ngScenario/jstd-scenario-adapter/angular.prefix',
|
||||
'src/ngScenario/jstd-scenario-adapter/Adapter.js',
|
||||
'src/ngScenario/jstd-scenario-adapter/angular.suffix',
|
||||
])
|
||||
|
||||
# TODO(vojta) use jstd configuration when implemented
|
||||
# (instead of including jstd-adapter-config.js)
|
||||
File.open(path_to('jstd-scenario-adapter-config.js'), 'w') do |f|
|
||||
f.write("/**\r\n" +
|
||||
" * Configuration for jstd scenario adapter \n */\n" +
|
||||
"var jstdScenarioAdapter = {\n relativeUrlPrefix: '/build/docs/'\n};\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
desc 'Concat AngularJS files'
|
||||
task :concat => :init do
|
||||
@@ -96,7 +115,7 @@ end
|
||||
|
||||
|
||||
desc 'Minify JavaScript'
|
||||
task :minify => [:init, :concat, :concat_scenario] do
|
||||
task :minify => [:init, :concat, :concat_scenario, :concat_jstd_scenario_adapter] do
|
||||
[ 'angular.js',
|
||||
'angular-cookies.js',
|
||||
'angular-loader.js',
|
||||
|
||||
Vendored
+3651
-3687
File diff suppressed because it is too large
Load Diff
Vendored
+4
-2
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
1.8.2
|
||||
1.7.2
|
||||
|
||||
@@ -410,10 +410,9 @@ function createInjector(modulesToLoad) {
|
||||
decorator: decorator
|
||||
}
|
||||
},
|
||||
providerInjector = (providerCache.$injector =
|
||||
createInternalInjector(providerCache, function() {
|
||||
throw Error("Unknown provider: " + path.join(' <- '));
|
||||
})),
|
||||
providerInjector = createInternalInjector(providerCache, function() {
|
||||
throw Error("Unknown provider: " + path.join(' <- '));
|
||||
}),
|
||||
instanceCache = {},
|
||||
instanceInjector = (instanceCache.$injector =
|
||||
createInternalInjector(instanceCache, function(servicename) {
|
||||
@@ -490,7 +489,9 @@ function createInjector(modulesToLoad) {
|
||||
try {
|
||||
for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
|
||||
var invokeArgs = invokeQueue[i],
|
||||
provider = providerInjector.get(invokeArgs[0]);
|
||||
provider = invokeArgs[0] == '$injector'
|
||||
? providerInjector
|
||||
: providerInjector.get(invokeArgs[0]);
|
||||
|
||||
provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
|
||||
}
|
||||
|
||||
+3
-4
@@ -353,11 +353,11 @@ var JQLitePrototype = JQLite.prototype = {
|
||||
// value on get.
|
||||
//////////////////////////////////////////
|
||||
var BOOLEAN_ATTR = {};
|
||||
forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
|
||||
forEach('multiple,selected,checked,disabled,readOnly,required'.split(','), function(value) {
|
||||
BOOLEAN_ATTR[lowercase(value)] = value;
|
||||
});
|
||||
var BOOLEAN_ELEMENTS = {};
|
||||
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
|
||||
forEach('input,select,option,textarea,button,form'.split(','), function(value) {
|
||||
BOOLEAN_ELEMENTS[uppercase(value)] = true;
|
||||
});
|
||||
|
||||
@@ -659,9 +659,8 @@ forEach({
|
||||
|
||||
append: function(element, node) {
|
||||
forEach(new JQLite(node), function(child){
|
||||
if (element.nodeType === 1 || element.nodeType === 11) {
|
||||
if (element.nodeType === 1)
|
||||
element.appendChild(child);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* @returns {object} Newly created cache object with the following set of methods:
|
||||
*
|
||||
* - `{object}` `info()` — Returns id, size, and options of cache.
|
||||
* - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns it.
|
||||
* - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache.
|
||||
* - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
|
||||
* - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
|
||||
* - `{void}` `removeAll()` — Removes all cached values.
|
||||
@@ -53,8 +53,6 @@ function $CacheFactoryProvider() {
|
||||
if (size > capacity) {
|
||||
this.remove(staleEnd.key);
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -272,37 +272,6 @@
|
||||
* @param {string} expression Angular expression that will be evaluated.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngOpen
|
||||
* @restrict A
|
||||
*
|
||||
* @description
|
||||
* The HTML specs do not require browsers to preserve the special attributes such as open.
|
||||
* (The presence of them means true and absence means false)
|
||||
* This prevents the angular compiler from correctly retrieving the binding expression.
|
||||
* To solve this problem, we introduce the `ngOpen` directive.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
Check me check multiple: <input type="checkbox" ng-model="open"><br/>
|
||||
<details id="details" ng-open="open">
|
||||
<summary>Show/Hide me</summary>
|
||||
</details>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should toggle open', function() {
|
||||
expect(element('#details').prop('open')).toBeFalsy();
|
||||
input('open').check();
|
||||
expect(element('#details').prop('open')).toBeTruthy();
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*
|
||||
* @element DETAILS
|
||||
* @param {string} expression Angular expression that will be evaluated.
|
||||
*/
|
||||
|
||||
var ngAttributeAliasDirectives = {};
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ var nullFormCtrl = {
|
||||
$addControl: noop,
|
||||
$removeControl: noop,
|
||||
$setValidity: noop,
|
||||
$setDirty: noop,
|
||||
$setPristine: noop
|
||||
$setDirty: noop
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -38,8 +37,7 @@ function FormController(element, attrs) {
|
||||
var form = this,
|
||||
parentForm = element.parent().controller('form') || nullFormCtrl,
|
||||
invalidCount = 0, // used to easily determine if we are valid
|
||||
errors = form.$error = {},
|
||||
controls = [];
|
||||
errors = form.$error = {};
|
||||
|
||||
// init state
|
||||
form.$name = attrs.name;
|
||||
@@ -63,8 +61,6 @@ function FormController(element, attrs) {
|
||||
}
|
||||
|
||||
form.$addControl = function(control) {
|
||||
controls.push(control);
|
||||
|
||||
if (control.$name && !form.hasOwnProperty(control.$name)) {
|
||||
form[control.$name] = control;
|
||||
}
|
||||
@@ -77,8 +73,6 @@ function FormController(element, attrs) {
|
||||
forEach(errors, function(queue, validationToken) {
|
||||
form.$setValidity(validationToken, true, control);
|
||||
});
|
||||
|
||||
arrayRemove(controls, control);
|
||||
};
|
||||
|
||||
form.$setValidity = function(validationToken, isValid, control) {
|
||||
@@ -126,29 +120,6 @@ function FormController(element, attrs) {
|
||||
parentForm.$setDirty();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name ng.directive:form.FormController#$setPristine
|
||||
* @methodOf ng.directive:form.FormController
|
||||
*
|
||||
* @description
|
||||
* Sets the form to its pristine state.
|
||||
*
|
||||
* This method can be called to remove the 'ng-dirty' class and set the form to its pristine
|
||||
* state (ng-pristine class). This method will also propagate to all the controls contained
|
||||
* in this form.
|
||||
*
|
||||
* Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
|
||||
* saving or resetting it.
|
||||
*/
|
||||
form.$setPristine = function () {
|
||||
element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
||||
form.$dirty = false;
|
||||
form.$pristine = true;
|
||||
forEach(controls, function(control) {
|
||||
control.$setPristine();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ var inputType = {
|
||||
* patterns defined as scope expressions.
|
||||
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
||||
* interaction with the input element.
|
||||
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trimming the
|
||||
* input.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
@@ -37,12 +35,12 @@ var inputType = {
|
||||
<script>
|
||||
function Ctrl($scope) {
|
||||
$scope.text = 'guest';
|
||||
$scope.word = /^\s*\w*\s*$/;
|
||||
$scope.word = /^\w*$/;
|
||||
}
|
||||
</script>
|
||||
<form name="myForm" ng-controller="Ctrl">
|
||||
Single word: <input type="text" name="input" ng-model="text"
|
||||
ng-pattern="word" required ng-trim="false">
|
||||
ng-pattern="word" required>
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.pattern">
|
||||
@@ -71,12 +69,6 @@ var inputType = {
|
||||
input('text').enter('hello world');
|
||||
expect(binding('myForm.input.$valid')).toEqual('false');
|
||||
});
|
||||
|
||||
it('should not be trimmed', function() {
|
||||
input('text').enter('untrimmed ');
|
||||
expect(binding('text')).toEqual('untrimmed ');
|
||||
expect(binding('myForm.input.$valid')).toEqual('true');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
@@ -390,14 +382,7 @@ function isEmpty(value) {
|
||||
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
|
||||
var listener = function() {
|
||||
var value = element.val();
|
||||
|
||||
// By default we will trim the value
|
||||
// If the attribute ng-trim exists we will avoid trimming
|
||||
// e.g. <input ng-model="foo" ng-trim="false">
|
||||
if (toBoolean(attr.ngTrim || 'T')) {
|
||||
value = trim(value);
|
||||
}
|
||||
var value = trim(element.val());
|
||||
|
||||
if (ctrl.$viewValue !== value) {
|
||||
scope.$apply(function() {
|
||||
@@ -978,22 +963,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
parentForm.$setValidity(validationErrorKey, isValid, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name ng.directive:ngModel.NgModelController#$setPristine
|
||||
* @methodOf ng.directive:ngModel.NgModelController
|
||||
*
|
||||
* @description
|
||||
* Sets the control to its pristine state.
|
||||
*
|
||||
* This method can be called to remove the 'ng-dirty' class and set the control to its pristine
|
||||
* state (ng-pristine class).
|
||||
*/
|
||||
this.$setPristine = function () {
|
||||
this.$dirty = false;
|
||||
this.$pristine = true;
|
||||
$element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*/
|
||||
var ngEventDirectives = {};
|
||||
forEach(
|
||||
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup'.split(' '),
|
||||
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
|
||||
function(name) {
|
||||
var directiveName = directiveNormalize('ng-' + name);
|
||||
ngEventDirectives[directiveName] = ['$parse', function($parse) {
|
||||
@@ -164,38 +164,6 @@ forEach(
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngKeydown
|
||||
*
|
||||
* @description
|
||||
* Specify custom behavior on keydown event.
|
||||
*
|
||||
* @element ANY
|
||||
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
||||
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
||||
*
|
||||
* @example
|
||||
* See {@link ng.directive:ngClick ngClick}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngKeyup
|
||||
*
|
||||
* @description
|
||||
* Specify custom behavior on keyup event.
|
||||
*
|
||||
* @element ANY
|
||||
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
||||
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
||||
*
|
||||
* @example
|
||||
* See {@link ng.directive:ngClick ngClick}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngSubmit
|
||||
|
||||
@@ -330,22 +330,18 @@ function dateFilter($locale) {
|
||||
|
||||
|
||||
var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
|
||||
// 1 2 3 4 5 6 7 8 9 10 11
|
||||
function jsonStringToDate(string) {
|
||||
function jsonStringToDate(string){
|
||||
var match;
|
||||
if (match = string.match(R_ISO8601_STR)) {
|
||||
var date = new Date(0),
|
||||
tzHour = 0,
|
||||
tzMin = 0,
|
||||
dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
|
||||
timeSetter = match[8] ? date.setUTCHours : date.setHours;
|
||||
|
||||
tzMin = 0;
|
||||
if (match[9]) {
|
||||
tzHour = int(match[9] + match[10]);
|
||||
tzMin = int(match[9] + match[11]);
|
||||
}
|
||||
dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
|
||||
timeSetter.call(date, int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
|
||||
date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
|
||||
date.setUTCHours(int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
|
||||
return date;
|
||||
}
|
||||
return string;
|
||||
|
||||
+33
-50
@@ -6,20 +6,20 @@
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Creates a new array or string containing only a specified number of elements. The elements
|
||||
* are taken from either the beginning or the end of the source array or string, as specified by
|
||||
* the value and sign (positive or negative) of `limit`.
|
||||
* Creates a new array containing only a specified number of elements in an array. The elements
|
||||
* are taken from either the beginning or the end of the source array, as specified by the
|
||||
* value and sign (positive or negative) of `limit`.
|
||||
*
|
||||
* Note: This function is used to augment the `Array` type in Angular expressions. See
|
||||
* {@link ng.$filter} for more information about Angular arrays.
|
||||
*
|
||||
* @param {Array|string} input Source array or string to be limited.
|
||||
* @param {string|number} limit The length of the returned array or string. If the `limit` number
|
||||
* is positive, `limit` number of items from the beginning of the source array/string are copied.
|
||||
* If the number is negative, `limit` number of items from the end of the source array/string
|
||||
* are copied. The `limit` will be trimmed if it exceeds `array.length`
|
||||
* @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
|
||||
* had less than `limit` elements.
|
||||
* @param {Array} array Source array to be limited.
|
||||
* @param {string|Number} limit The length of the returned array. If the `limit` number is
|
||||
* positive, `limit` number of items from the beginning of the source array are copied.
|
||||
* If the number is negative, `limit` number of items from the end of the source array are
|
||||
* copied. The `limit` will be trimmed if it exceeds `array.length`
|
||||
* @returns {Array} A new sub-array of length `limit` or less if input array had less than `limit`
|
||||
* elements.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
@@ -27,76 +27,59 @@
|
||||
<script>
|
||||
function Ctrl($scope) {
|
||||
$scope.numbers = [1,2,3,4,5,6,7,8,9];
|
||||
$scope.letters = "abcdefghi";
|
||||
$scope.numLimit = 3;
|
||||
$scope.letterLimit = 3;
|
||||
$scope.limit = 3;
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="Ctrl">
|
||||
Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
|
||||
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
|
||||
Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
|
||||
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
||||
Limit {{numbers}} to: <input type="integer" ng-model="limit">
|
||||
<p>Output: {{ numbers | limitTo:limit }}</p>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should limit the number array to first three items', function() {
|
||||
expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3');
|
||||
expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3');
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('abc');
|
||||
it('should limit the numer array to first three items', function() {
|
||||
expect(element('.doc-example-live input[ng-model=limit]').val()).toBe('3');
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3]');
|
||||
});
|
||||
|
||||
it('should update the output when -3 is entered', function() {
|
||||
input('numLimit').enter(-3);
|
||||
input('letterLimit').enter(-3);
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('ghi');
|
||||
input('limit').enter(-3);
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[7,8,9]');
|
||||
});
|
||||
|
||||
it('should not exceed the maximum size of input array', function() {
|
||||
input('numLimit').enter(100);
|
||||
input('letterLimit').enter(100);
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi');
|
||||
input('limit').enter(100);
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3,4,5,6,7,8,9]');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
function limitToFilter(){
|
||||
return function(input, limit) {
|
||||
if (!isArray(input) && !isString(input)) return input;
|
||||
|
||||
return function(array, limit) {
|
||||
if (!(array instanceof Array)) return array;
|
||||
limit = int(limit);
|
||||
|
||||
if (isString(input)) {
|
||||
//NaN check on limit
|
||||
if (limit) {
|
||||
return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
var out = [],
|
||||
i, n;
|
||||
|
||||
// check that array is iterable
|
||||
if (!array || !(array instanceof Array))
|
||||
return out;
|
||||
|
||||
// if abs(limit) exceeds maximum length, trim it
|
||||
if (limit > input.length)
|
||||
limit = input.length;
|
||||
else if (limit < -input.length)
|
||||
limit = -input.length;
|
||||
if (limit > array.length)
|
||||
limit = array.length;
|
||||
else if (limit < -array.length)
|
||||
limit = -array.length;
|
||||
|
||||
if (limit > 0) {
|
||||
i = 0;
|
||||
n = limit;
|
||||
} else {
|
||||
i = input.length + limit;
|
||||
n = input.length;
|
||||
i = array.length + limit;
|
||||
n = array.length;
|
||||
}
|
||||
|
||||
for (; i<n; i++) {
|
||||
out.push(input[i]);
|
||||
out.push(array[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
+17
-65
@@ -29,43 +29,6 @@ function parseHeaders(headers) {
|
||||
}
|
||||
|
||||
|
||||
var IS_SAME_DOMAIN_URL_MATCH = /^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/;
|
||||
|
||||
|
||||
/**
|
||||
* Parse a request and location URL and determine whether this is a same-domain request.
|
||||
*
|
||||
* @param {string} requestUrl The url of the request.
|
||||
* @param {string} locationUrl The current browser location url.
|
||||
* @returns {boolean} Whether the request is for the same domain.
|
||||
*/
|
||||
function isSameDomain(requestUrl, locationUrl) {
|
||||
var match = IS_SAME_DOMAIN_URL_MATCH.exec(requestUrl);
|
||||
// if requestUrl is relative, the regex does not match.
|
||||
if (match == null) return true;
|
||||
|
||||
var domain1 = {
|
||||
protocol: match[2],
|
||||
host: match[4],
|
||||
port: int(match[6]) || DEFAULT_PORTS[match[2]] || null,
|
||||
// IE8 sets unmatched groups to '' instead of undefined.
|
||||
relativeProtocol: match[2] === undefined || match[2] === ''
|
||||
};
|
||||
|
||||
match = URL_MATCH.exec(locationUrl);
|
||||
var domain2 = {
|
||||
protocol: match[1],
|
||||
host: match[3],
|
||||
port: int(match[5]) || DEFAULT_PORTS[match[1]] || null
|
||||
};
|
||||
|
||||
return (domain1.protocol == domain2.protocol || domain1.relativeProtocol) &&
|
||||
domain1.host == domain2.host &&
|
||||
(domain1.port == domain2.port || (domain1.relativeProtocol &&
|
||||
domain2.port == DEFAULT_PORTS[domain2.protocol]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a function that provides access to parsed headers.
|
||||
*
|
||||
@@ -125,7 +88,7 @@ function $HttpProvider() {
|
||||
JSON_END = /[\}\]]\s*$/,
|
||||
PROTECTION_PREFIX = /^\)\]\}',?\n/;
|
||||
|
||||
var defaults = this.defaults = {
|
||||
var $config = this.defaults = {
|
||||
// transform incoming response data
|
||||
transformResponse: [function(data) {
|
||||
if (isString(data)) {
|
||||
@@ -145,7 +108,8 @@ function $HttpProvider() {
|
||||
// default headers
|
||||
headers: {
|
||||
common: {
|
||||
'Accept': 'application/json, text/plain, */*'
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
post: {'Content-Type': 'application/json;charset=utf-8'},
|
||||
put: {'Content-Type': 'application/json;charset=utf-8'}
|
||||
@@ -251,6 +215,7 @@ function $HttpProvider() {
|
||||
*
|
||||
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
|
||||
* - `Accept: application/json, text/plain, * / *`
|
||||
* - `X-Requested-With: XMLHttpRequest`
|
||||
* - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
|
||||
* - `Content-Type: application/json`
|
||||
* - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
|
||||
@@ -385,7 +350,7 @@ function $HttpProvider() {
|
||||
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
|
||||
* called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
|
||||
* runs on your domain could read the cookie, your server can be assured that the XHR came from
|
||||
* JavaScript running on your domain. The header will not be set for cross-domain requests.
|
||||
* JavaScript running on your domain.
|
||||
*
|
||||
* To take advantage of this, your server needs to set a token in a JavaScript readable session
|
||||
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
|
||||
@@ -419,8 +384,6 @@ function $HttpProvider() {
|
||||
* - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
||||
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
||||
* requests with credentials} for more information.
|
||||
* - **responseType** - `{string}` - see {@link
|
||||
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
||||
*
|
||||
* @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
|
||||
* standard `then` method and two http specific methods: `success` and `error`. The `then`
|
||||
@@ -513,12 +476,10 @@ function $HttpProvider() {
|
||||
function $http(config) {
|
||||
config.method = uppercase(config.method);
|
||||
|
||||
var reqTransformFn = config.transformRequest || defaults.transformRequest,
|
||||
respTransformFn = config.transformResponse || defaults.transformResponse,
|
||||
defHeaders = defaults.headers,
|
||||
xsrfToken = isSameDomain(config.url, $browser.url()) ?
|
||||
$browser.cookies()['XSRF-TOKEN'] : undefined,
|
||||
reqHeaders = extend({'X-XSRF-TOKEN': xsrfToken},
|
||||
var reqTransformFn = config.transformRequest || $config.transformRequest,
|
||||
respTransformFn = config.transformResponse || $config.transformResponse,
|
||||
defHeaders = $config.headers,
|
||||
reqHeaders = extend({'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
|
||||
defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
|
||||
reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
|
||||
promise;
|
||||
@@ -528,10 +489,6 @@ function $HttpProvider() {
|
||||
delete reqHeaders['Content-Type'];
|
||||
}
|
||||
|
||||
if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
|
||||
config.withCredentials = defaults.withCredentials;
|
||||
}
|
||||
|
||||
// send request
|
||||
promise = sendReq(config, reqData, reqHeaders);
|
||||
|
||||
@@ -663,11 +620,11 @@ function $HttpProvider() {
|
||||
*
|
||||
* @description
|
||||
* Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
|
||||
* default headers, withCredentials as well as request and response transformations.
|
||||
* default headers as well as request and response transformations.
|
||||
*
|
||||
* See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
|
||||
*/
|
||||
$http.defaults = defaults;
|
||||
$http.defaults = $config;
|
||||
|
||||
|
||||
return $http;
|
||||
@@ -702,7 +659,7 @@ function $HttpProvider() {
|
||||
* Makes the request
|
||||
*
|
||||
* !!! ACCESSES CLOSURE VARS:
|
||||
* $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
|
||||
* $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
|
||||
*/
|
||||
function sendReq(config, reqData, reqHeaders) {
|
||||
var deferred = $q.defer(),
|
||||
@@ -743,7 +700,7 @@ function $HttpProvider() {
|
||||
// if we won't have the response in cache, send the request to the backend
|
||||
if (!cachedResp) {
|
||||
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
|
||||
config.withCredentials, config.responseType);
|
||||
config.withCredentials);
|
||||
}
|
||||
|
||||
return promise;
|
||||
@@ -798,15 +755,10 @@ function $HttpProvider() {
|
||||
var parts = [];
|
||||
forEachSorted(params, function(value, key) {
|
||||
if (value == null || value == undefined) return;
|
||||
if (!isArray(value)) value = [value];
|
||||
|
||||
forEach(value, function(v) {
|
||||
if (isObject(v)) {
|
||||
v = toJson(v);
|
||||
}
|
||||
parts.push(encodeURIComponent(key) + '=' +
|
||||
encodeURIComponent(v));
|
||||
});
|
||||
if (isObject(value)) {
|
||||
value = toJson(value);
|
||||
}
|
||||
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
|
||||
});
|
||||
return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ function $HttpBackendProvider() {
|
||||
|
||||
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
|
||||
// TODO(vojta): fix the signature
|
||||
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
||||
return function(method, url, post, callback, headers, timeout, withCredentials) {
|
||||
$browser.$$incOutstandingRequestCount();
|
||||
url = url || $browser.url();
|
||||
|
||||
@@ -65,8 +65,8 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
||||
// always async
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
completeRequest(callback, status || xhr.status, xhr.response || xhr.responseText,
|
||||
xhr.getAllResponseHeaders());
|
||||
completeRequest(
|
||||
callback, status || xhr.status, xhr.responseText, xhr.getAllResponseHeaders());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,10 +74,6 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
||||
xhr.withCredentials = true;
|
||||
}
|
||||
|
||||
if (responseType) {
|
||||
xhr.responseType = responseType;
|
||||
}
|
||||
|
||||
xhr.send(post || '');
|
||||
|
||||
if (timeout > 0) {
|
||||
|
||||
+10
-16
@@ -52,7 +52,7 @@ function $InterpolateProvider() {
|
||||
};
|
||||
|
||||
|
||||
this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
|
||||
this.$get = ['$parse', function($parse) {
|
||||
var startSymbolLength = startSymbol.length,
|
||||
endSymbolLength = endSymbol.length;
|
||||
|
||||
@@ -124,24 +124,18 @@ function $InterpolateProvider() {
|
||||
if (!mustHaveExpression || hasInterpolation) {
|
||||
concat.length = length;
|
||||
fn = function(context) {
|
||||
try {
|
||||
for(var i = 0, ii = length, part; i<ii; i++) {
|
||||
if (typeof (part = parts[i]) == 'function') {
|
||||
part = part(context);
|
||||
if (part == null || part == undefined) {
|
||||
part = '';
|
||||
} else if (typeof part != 'string') {
|
||||
part = toJson(part);
|
||||
}
|
||||
for(var i = 0, ii = length, part; i<ii; i++) {
|
||||
if (typeof (part = parts[i]) == 'function') {
|
||||
part = part(context);
|
||||
if (part == null || part == undefined) {
|
||||
part = '';
|
||||
} else if (typeof part != 'string') {
|
||||
part = toJson(part);
|
||||
}
|
||||
concat[i] = part;
|
||||
}
|
||||
return concat.join('');
|
||||
}
|
||||
catch(err) {
|
||||
var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
|
||||
$exceptionHandler(newErr);
|
||||
concat[i] = part;
|
||||
}
|
||||
return concat.join('');
|
||||
};
|
||||
fn.exp = text;
|
||||
fn.parts = parts;
|
||||
|
||||
+1
-45
@@ -33,33 +33,7 @@
|
||||
</example>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name ng.$logProvider
|
||||
* @description
|
||||
* Use the `$logProvider` to configure how the application logs messages
|
||||
*/
|
||||
function $LogProvider(){
|
||||
var debug = true,
|
||||
self = this;
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name ng.$logProvider#debugEnabled
|
||||
* @methodOf ng.$logProvider
|
||||
* @description
|
||||
* @param {string=} flag enable or disable debug level messages
|
||||
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
||||
*/
|
||||
this.debugEnabled = function(flag) {
|
||||
if (isDefined(flag)) {
|
||||
debug = flag;
|
||||
return this;
|
||||
} else {
|
||||
return debug;
|
||||
}
|
||||
};
|
||||
|
||||
this.$get = ['$window', function($window){
|
||||
return {
|
||||
/**
|
||||
@@ -100,25 +74,7 @@ function $LogProvider(){
|
||||
* @description
|
||||
* Write an error message
|
||||
*/
|
||||
error: consoleLog('error'),
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ng.$log#debug
|
||||
* @methodOf ng.$log
|
||||
*
|
||||
* @description
|
||||
* Write a debug message
|
||||
*/
|
||||
debug: (function () {
|
||||
var fn = consoleLog('debug');
|
||||
|
||||
return function() {
|
||||
if (debug) {
|
||||
fn.apply(self, arguments);
|
||||
}
|
||||
}
|
||||
}())
|
||||
error: consoleLog('error')
|
||||
};
|
||||
|
||||
function formatError(arg) {
|
||||
|
||||
+5
-13
@@ -20,8 +20,6 @@ var OPERATORS = {
|
||||
'%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
|
||||
'^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},
|
||||
'=':noop,
|
||||
'===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
|
||||
'!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
|
||||
'==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
|
||||
'!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},
|
||||
'<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},
|
||||
@@ -72,14 +70,9 @@ function lex(text, csp){
|
||||
continue;
|
||||
} else {
|
||||
var ch2 = ch + peek(),
|
||||
ch3 = ch2 + peek(2),
|
||||
fn = OPERATORS[ch],
|
||||
fn2 = OPERATORS[ch2],
|
||||
fn3 = OPERATORS[ch3];
|
||||
if (fn3) {
|
||||
tokens.push({index:index, text:ch3, fn:fn3});
|
||||
index += 3;
|
||||
} else if (fn2) {
|
||||
fn2 = OPERATORS[ch2];
|
||||
if (fn2) {
|
||||
tokens.push({index:index, text:ch2, fn:fn2});
|
||||
index += 2;
|
||||
} else if (fn) {
|
||||
@@ -101,9 +94,8 @@ function lex(text, csp){
|
||||
return chars.indexOf(lastCh) != -1;
|
||||
}
|
||||
|
||||
function peek(i) {
|
||||
var num = i || 1;
|
||||
return index + num < text.length ? text.charAt(index + num) : false;
|
||||
function peek() {
|
||||
return index + 1 < text.length ? text.charAt(index + 1) : false;
|
||||
}
|
||||
function isNumber(ch) {
|
||||
return '0' <= ch && ch <= '9';
|
||||
@@ -464,7 +456,7 @@ function parser(text, json, $filter, csp){
|
||||
function equality() {
|
||||
var left = relational();
|
||||
var token;
|
||||
if ((token = expect('==','!=','===','!=='))) {
|
||||
if ((token = expect('==','!='))) {
|
||||
left = binaryFn(left, token.fn, equality());
|
||||
}
|
||||
return left;
|
||||
|
||||
+11
-11
@@ -196,6 +196,7 @@ function $RootScopeProvider(){
|
||||
child['this'] = child;
|
||||
child.$$listeners = {};
|
||||
child.$parent = this;
|
||||
child.$$asyncQueue = [];
|
||||
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
||||
child.$$prevSibling = this.$$childTail;
|
||||
if (this.$$childHead) {
|
||||
@@ -362,7 +363,7 @@ function $RootScopeProvider(){
|
||||
$digest: function() {
|
||||
var watch, value, last,
|
||||
watchers,
|
||||
asyncQueue = this.$$asyncQueue,
|
||||
asyncQueue,
|
||||
length,
|
||||
dirty, ttl = TTL,
|
||||
next, current, target = this,
|
||||
@@ -371,19 +372,18 @@ function $RootScopeProvider(){
|
||||
|
||||
beginPhase('$digest');
|
||||
|
||||
do { // "while dirty" loop
|
||||
do {
|
||||
dirty = false;
|
||||
current = target;
|
||||
|
||||
while(asyncQueue.length) {
|
||||
try {
|
||||
current.$eval(asyncQueue.shift());
|
||||
} catch (e) {
|
||||
$exceptionHandler(e);
|
||||
do {
|
||||
asyncQueue = current.$$asyncQueue;
|
||||
while(asyncQueue.length) {
|
||||
try {
|
||||
current.$eval(asyncQueue.shift());
|
||||
} catch (e) {
|
||||
$exceptionHandler(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do { // "traverse the scopes" loop
|
||||
if ((watchers = current.$$watchers)) {
|
||||
// process our watches
|
||||
length = watchers.length;
|
||||
|
||||
+7
-28
@@ -35,24 +35,12 @@ function $RouteProvider(){
|
||||
* - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
|
||||
* created scope or the name of a {@link angular.Module#controller registered controller}
|
||||
* if passed as a string.
|
||||
* - `template` – `{string=|function()=}` – html template as a string or function that returns
|
||||
* an html template as a string which should be used by {@link ng.directive:ngView ngView} or
|
||||
* - `template` – `{string=}` – html template as a string that should be used by
|
||||
* {@link ng.directive:ngView ngView} or
|
||||
* {@link ng.directive:ngInclude ngInclude} directives.
|
||||
* This property takes precedence over `templateUrl`.
|
||||
*
|
||||
* If `template` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
|
||||
* template that should be used by {@link ng.directive:ngView ngView}.
|
||||
*
|
||||
* If `templateUrl` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* this property takes precedence over `templateUrl`.
|
||||
* - `templateUrl` – `{string=}` – path to an html template that should be used by
|
||||
* {@link ng.directive:ngView ngView}.
|
||||
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
||||
* be injected into the controller. If any of these dependencies are promises, they will be
|
||||
* resolved and converted to a value before the controller is instantiated and the
|
||||
@@ -407,18 +395,9 @@ function $RouteProvider(){
|
||||
values.push(isString(value) ? $injector.get(value) : $injector.invoke(value));
|
||||
});
|
||||
if (isDefined(template = next.template)) {
|
||||
if (isFunction(template)) {
|
||||
template = template(next.params);
|
||||
}
|
||||
} else if (isDefined(template = next.templateUrl)) {
|
||||
if (isFunction(template)) {
|
||||
template = template(next.params);
|
||||
}
|
||||
if (isDefined(template)) {
|
||||
next.loadedTemplateUrl = template;
|
||||
template = $http.get(template, {cache: $templateCache}).
|
||||
then(function(response) { return response.data; });
|
||||
}
|
||||
template = $http.get(template, {cache: $templateCache}).
|
||||
then(function(response) { return response.data; });
|
||||
}
|
||||
if (isDefined(template)) {
|
||||
keys.push('$template');
|
||||
|
||||
+6
-7
@@ -5,7 +5,6 @@
|
||||
*
|
||||
* @name ng.$sniffer
|
||||
* @requires $window
|
||||
* @requires $document
|
||||
*
|
||||
* @property {boolean} history Does the browser support html5 history api ?
|
||||
* @property {boolean} hashchange Does the browser support hashchange event ?
|
||||
@@ -14,10 +13,9 @@
|
||||
* This is very simple implementation of testing browser's features.
|
||||
*/
|
||||
function $SnifferProvider() {
|
||||
this.$get = ['$window', '$document', function($window, $document) {
|
||||
this.$get = ['$window', function($window) {
|
||||
var eventSupport = {},
|
||||
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1]),
|
||||
document = $document[0];
|
||||
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1]);
|
||||
|
||||
return {
|
||||
// Android has history.pushState, but it does not update location correctly
|
||||
@@ -27,7 +25,7 @@ function $SnifferProvider() {
|
||||
history: !!($window.history && $window.history.pushState && !(android < 4)),
|
||||
hashchange: 'onhashchange' in $window &&
|
||||
// IE8 compatible mode lies
|
||||
(!document.documentMode || document.documentMode > 7),
|
||||
(!$window.document.documentMode || $window.document.documentMode > 7),
|
||||
hasEvent: function(event) {
|
||||
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
||||
// it. In particular the event is not fired when backspace or delete key are pressed or
|
||||
@@ -35,13 +33,14 @@ function $SnifferProvider() {
|
||||
if (event == 'input' && msie == 9) return false;
|
||||
|
||||
if (isUndefined(eventSupport[event])) {
|
||||
var divElm = document.createElement('div');
|
||||
var divElm = $window.document.createElement('div');
|
||||
eventSupport[event] = 'on' + event in divElm;
|
||||
}
|
||||
|
||||
return eventSupport[event];
|
||||
},
|
||||
csp: document.securityPolicy ? document.securityPolicy.isActive : false
|
||||
// TODO(i): currently there is no way to feature detect CSP without triggering alerts
|
||||
csp: false
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
Vendored
+35
-61
@@ -1352,49 +1352,17 @@ function MockXhr() {
|
||||
* @description
|
||||
*
|
||||
* This service is just a simple decorator for {@link ng.$timeout $timeout} service
|
||||
* that adds a "flush" and "verifyNoPendingTasks" methods.
|
||||
*/
|
||||
* that adds a "flush" method.
|
||||
*/
|
||||
|
||||
angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#flush
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Flushes the queue of pending tasks.
|
||||
*/
|
||||
$delegate.flush = function() {
|
||||
$browser.defer.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#verifyNoPendingTasks
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Verifies that there are no pending tasks that need to be flushed.
|
||||
*/
|
||||
$delegate.verifyNoPendingTasks = function() {
|
||||
if ($browser.deferredFns.length) {
|
||||
throw Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
||||
formatPendingTasksAsString($browser.deferredFns));
|
||||
}
|
||||
};
|
||||
|
||||
function formatPendingTasksAsString(tasks) {
|
||||
var result = [];
|
||||
angular.forEach(tasks, function(task) {
|
||||
result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
|
||||
});
|
||||
|
||||
return result.join(', ');
|
||||
}
|
||||
|
||||
return $delegate;
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#flush
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Flushes the queue of pending tasks.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -1420,9 +1388,15 @@ angular.module('ngMock', ['ng']).provider({
|
||||
$httpBackend: angular.mock.$HttpBackendProvider,
|
||||
$rootElement: angular.mock.$RootElementProvider
|
||||
}).config(function($provide) {
|
||||
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
|
||||
$provide.decorator('$timeout', function($delegate, $browser) {
|
||||
$delegate.flush = function() {
|
||||
$browser.defer.flush();
|
||||
};
|
||||
return $delegate;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name ngMockE2E
|
||||
@@ -1636,20 +1610,14 @@ window.jstestdriver && (function(window) {
|
||||
})(window);
|
||||
|
||||
|
||||
(window.jasmine || window.mocha) && (function(window) {
|
||||
|
||||
var currentSpec = null;
|
||||
|
||||
beforeEach(function() {
|
||||
currentSpec = this;
|
||||
});
|
||||
window.jasmine && (function(window) {
|
||||
|
||||
afterEach(function() {
|
||||
var injector = currentSpec.$injector;
|
||||
var spec = getCurrentSpec();
|
||||
var injector = spec.$injector;
|
||||
|
||||
currentSpec.$injector = null;
|
||||
currentSpec.$modules = null;
|
||||
currentSpec = null;
|
||||
spec.$injector = null;
|
||||
spec.$modules = null;
|
||||
|
||||
if (injector) {
|
||||
injector.get('$rootElement').unbind();
|
||||
@@ -1671,8 +1639,13 @@ window.jstestdriver && (function(window) {
|
||||
angular.callbacks.counter = 0;
|
||||
});
|
||||
|
||||
function getCurrentSpec() {
|
||||
return jasmine.getEnv().currentSpec;
|
||||
}
|
||||
|
||||
function isSpecRunning() {
|
||||
return currentSpec && currentSpec.queue.running;
|
||||
var spec = getCurrentSpec();
|
||||
return spec && spec.queue.running;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1697,10 +1670,11 @@ window.jstestdriver && (function(window) {
|
||||
return isSpecRunning() ? workFn() : workFn;
|
||||
/////////////////////
|
||||
function workFn() {
|
||||
if (currentSpec.$injector) {
|
||||
var spec = getCurrentSpec();
|
||||
if (spec.$injector) {
|
||||
throw Error('Injector already created, can not register a module!');
|
||||
} else {
|
||||
var modules = currentSpec.$modules || (currentSpec.$modules = []);
|
||||
var modules = spec.$modules || (spec.$modules = []);
|
||||
angular.forEach(moduleFns, function(module) {
|
||||
modules.push(module);
|
||||
});
|
||||
@@ -1767,13 +1741,13 @@ window.jstestdriver && (function(window) {
|
||||
return isSpecRunning() ? workFn() : workFn;
|
||||
/////////////////////
|
||||
function workFn() {
|
||||
var modules = currentSpec.$modules || [];
|
||||
|
||||
var spec = getCurrentSpec();
|
||||
var modules = spec.$modules || [];
|
||||
modules.unshift('ngMock');
|
||||
modules.unshift('ng');
|
||||
var injector = currentSpec.$injector;
|
||||
var injector = spec.$injector;
|
||||
if (!injector) {
|
||||
injector = currentSpec.$injector = angular.injector(modules);
|
||||
injector = spec.$injector = angular.injector(modules);
|
||||
}
|
||||
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
||||
try {
|
||||
|
||||
+15
-42
@@ -24,8 +24,7 @@
|
||||
* number, like this: `$resource('http://example.com\\:8080/api')`.
|
||||
*
|
||||
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
||||
* `actions` methods. If any of the parameter value is a function, it will be executed every time
|
||||
* when a param value needs to be obtained for a request (unless the param was overriden).
|
||||
* `actions` methods.
|
||||
*
|
||||
* Each key value in the parameter object is first bound to url template if present and then any
|
||||
* excess keys are appended to the url search query after the `?`.
|
||||
@@ -37,40 +36,21 @@
|
||||
* the data object (useful for non-GET operations).
|
||||
*
|
||||
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend the
|
||||
* default set of resource actions. The declaration should be created in the format of {@link
|
||||
* ng.$http#Parameters $http.config}:
|
||||
* default set of resource actions. The declaration should be created in the following format:
|
||||
*
|
||||
* {action1: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* {action1: {method:?, params:?, isArray:?},
|
||||
* action2: {method:?, params:?, isArray:?},
|
||||
* ...}
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* - **`action`** – {string} – The name of action. This name becomes the name of the method on your
|
||||
* - `action` – {string} – The name of action. This name becomes the name of the method on your
|
||||
* resource object.
|
||||
* - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
||||
* and `JSONP`.
|
||||
* - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of the
|
||||
* parameter value is a function, it will be executed every time when a param value needs to be
|
||||
* obtained for a request (unless the param was overriden).
|
||||
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, see
|
||||
* - `method` – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
||||
* and `JSONP`
|
||||
* - `params` – {object=} – Optional set of pre-bound parameters for this action.
|
||||
* - isArray – {boolean=} – If true then the returned object for this action is an array, see
|
||||
* `returns` section.
|
||||
* - **`transformRequest`** – `{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.
|
||||
* - **`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.
|
||||
* - **`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
|
||||
* caching.
|
||||
* - **`timeout`** – `{number}` – timeout in milliseconds.
|
||||
* - **`withCredentials`** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
||||
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
||||
* requests with credentials} for more information.
|
||||
* - **`responseType`** - `{string}` - see {@link
|
||||
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
||||
*
|
||||
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
||||
* optionally extended with custom `actions`. The default set contains these actions:
|
||||
@@ -152,7 +132,7 @@
|
||||
* The object returned from this function execution is a resource "class" which has "static" method
|
||||
* for each action in the definition.
|
||||
*
|
||||
* Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and `headers`.
|
||||
* Calling these methods invoke `$http` on the `url` template with the given `method` and `params`.
|
||||
* When the data is returned from the server then the object is an instance of the resource type and
|
||||
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
||||
* operations (create, read, update, delete) on server-side data.
|
||||
@@ -344,7 +324,6 @@ angular.module('ngResource', ['ng']).
|
||||
var ids = {};
|
||||
actionParams = extend({}, paramDefaults, actionParams);
|
||||
forEach(actionParams, function(value, key){
|
||||
if (isFunction(value)) { value = value(); }
|
||||
ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
|
||||
});
|
||||
return ids;
|
||||
@@ -397,17 +376,11 @@ angular.module('ngResource', ['ng']).
|
||||
}
|
||||
|
||||
var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
|
||||
var httpConfig = {};
|
||||
|
||||
forEach(action, function(value, key) {
|
||||
if (key != 'params' && key != 'isArray' ) {
|
||||
httpConfig[key] = copy(value);
|
||||
}
|
||||
});
|
||||
httpConfig.data = data;
|
||||
httpConfig.url = route.url(extend({}, extractParams(data, action.params || {}), params))
|
||||
|
||||
$http(httpConfig).then(function(response) {
|
||||
$http({
|
||||
method: action.method,
|
||||
url: route.url(extend({}, extractParams(data, action.params || {}), params)),
|
||||
data: data
|
||||
}).then(function(response) {
|
||||
var data = response.data;
|
||||
|
||||
if (data) {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
* plain email address links.
|
||||
*
|
||||
* @param {string} text Input text.
|
||||
* @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
|
||||
* @returns {string} Html-linkified text.
|
||||
*
|
||||
* @usage
|
||||
@@ -25,7 +24,6 @@
|
||||
'mailto:us@somewhere.org,\n'+
|
||||
'another@somewhere.org,\n'+
|
||||
'and one more: ftp://127.0.0.1/.';
|
||||
$scope.snippetWithTarget = 'http://angularjs.org/';
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="Ctrl">
|
||||
@@ -45,15 +43,6 @@
|
||||
<div ng-bind-html="snippet | linky"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="linky-target">
|
||||
<td>linky target</td>
|
||||
<td>
|
||||
<pre><div ng-bind-html="snippetWithTarget | linky:'_blank'"><br></div></pre>
|
||||
</td>
|
||||
<td>
|
||||
<div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="escaped-html">
|
||||
<td>no filter</td>
|
||||
<td><pre><div ng-bind="snippet"><br></div></pre></td>
|
||||
@@ -86,11 +75,6 @@
|
||||
toBe('new <a href="http://link">http://link</a>.');
|
||||
expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
|
||||
});
|
||||
|
||||
it('should work with the target property', function() {
|
||||
expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
|
||||
toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
@@ -98,7 +82,7 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,
|
||||
MAILTO_REGEXP = /^mailto:/;
|
||||
|
||||
return function(text, target) {
|
||||
return function(text) {
|
||||
if (!text) return text;
|
||||
var match;
|
||||
var raw = text;
|
||||
@@ -107,10 +91,6 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
var writer = htmlSanitizeWriter(html);
|
||||
var url;
|
||||
var i;
|
||||
var properties = {};
|
||||
if (angular.isDefined(target)) {
|
||||
properties.target = target;
|
||||
}
|
||||
while ((match = raw.match(LINKY_URL_REGEXP))) {
|
||||
// We can not end in these as they are sometimes found at the end of the sentence
|
||||
url = match[0];
|
||||
@@ -118,8 +98,7 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
if (match[2] == match[3]) url = 'mailto:' + url;
|
||||
i = match.index;
|
||||
writer.chars(raw.substr(0, i));
|
||||
properties.href = url;
|
||||
writer.start('a', properties);
|
||||
writer.start('a', {href:url});
|
||||
writer.chars(match[0].replace(MAILTO_REGEXP, ''));
|
||||
writer.end('a');
|
||||
raw = raw.substring(i + match[0].length);
|
||||
|
||||
@@ -123,7 +123,7 @@ var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:
|
||||
BEGING_END_TAGE_REGEXP = /^<\s*\//,
|
||||
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
||||
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
||||
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/,
|
||||
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/,
|
||||
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
|
||||
|
||||
|
||||
|
||||
@@ -298,8 +298,6 @@ angular.scenario.dsl('select', function() {
|
||||
option = select.find('option:contains("' + value + '")');
|
||||
if (option.length) {
|
||||
select.val(option.val());
|
||||
} else {
|
||||
return done("option '" + value + "' not found");
|
||||
}
|
||||
}
|
||||
select.trigger('change');
|
||||
@@ -327,7 +325,6 @@ angular.scenario.dsl('select', function() {
|
||||
* Usage:
|
||||
* element(selector, label).count() get the number of elements that match selector
|
||||
* element(selector, label).click() clicks an element
|
||||
* element(selector, label).mouseover() mouseover an element
|
||||
* element(selector, label).query(fn) executes fn(selectedElements, done)
|
||||
* element(selector, label).{method}() gets the value (as defined by jQuery, ex. val)
|
||||
* element(selector, label).{method}(value) sets the value (as defined by jQuery, ex. val)
|
||||
@@ -368,30 +365,6 @@ angular.scenario.dsl('element', function() {
|
||||
});
|
||||
};
|
||||
|
||||
chain.dblclick = function() {
|
||||
return this.addFutureAction("element '" + this.label + "' dblclick", function($window, $document, done) {
|
||||
var elements = $document.elements();
|
||||
var href = elements.attr('href');
|
||||
var eventProcessDefault = elements.trigger('dblclick')[0];
|
||||
|
||||
if (href && elements[0].nodeName.toUpperCase() === 'A' && eventProcessDefault) {
|
||||
this.application.navigateTo(href, function() {
|
||||
done();
|
||||
}, done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
chain.mouseover = function() {
|
||||
return this.addFutureAction("element '" + this.label + "' mouseover", function($window, $document, done) {
|
||||
var elements = $document.elements();
|
||||
elements.trigger('mouseover');
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
chain.query = function(fn) {
|
||||
return this.addFutureAction('element ' + this.label + ' custom query', function($window, $document, done) {
|
||||
fn.call(this, $document.elements(), done);
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* JSTestDriver adapter for angular scenario tests
|
||||
*
|
||||
* Example of jsTestDriver.conf for running scenario tests with JSTD:
|
||||
<pre>
|
||||
server: http://localhost:9877
|
||||
|
||||
load:
|
||||
- lib/angular-scenario.js
|
||||
- lib/jstd-scenario-adapter-config.js
|
||||
- lib/jstd-scenario-adapter.js
|
||||
# your test files go here #
|
||||
|
||||
proxy:
|
||||
- {matcher: "/your-prefix/*", server: "http://localhost:8000/"}
|
||||
</pre>
|
||||
*
|
||||
* For more information on how to configure jstd proxy, see {@link http://code.google.com/p/js-test-driver/wiki/Proxy}
|
||||
* Note the order of files - it's important !
|
||||
*
|
||||
* Example of jstd-scenario-adapter-config.js
|
||||
<pre>
|
||||
var jstdScenarioAdapter = {
|
||||
relativeUrlPrefix: '/your-prefix/'
|
||||
};
|
||||
</pre>
|
||||
*
|
||||
* Whenever you use <code>browser().navigateTo('relativeUrl')</code> in your scenario test, the relativeUrlPrefix will be prepended.
|
||||
* You have to configure this to work together with JSTD proxy.
|
||||
*
|
||||
* Let's assume you are using the above configuration (jsTestDriver.conf and jstd-scenario-adapter-config.js):
|
||||
* Now, when you call <code>browser().navigateTo('index.html')</code> in your scenario test, the browser will open /your-prefix/index.html.
|
||||
* That matches the proxy, so JSTD will proxy this request to http://localhost:8000/index.html.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom type of test case
|
||||
*
|
||||
* @const
|
||||
* @see jstestdriver.TestCaseInfo
|
||||
*/
|
||||
var SCENARIO_TYPE = 'scenario';
|
||||
|
||||
/**
|
||||
* Plugin for JSTestDriver
|
||||
* Connection point between scenario's jstd output and jstestdriver.
|
||||
*
|
||||
* @see jstestdriver.PluginRegistrar
|
||||
*/
|
||||
function JstdPlugin() {
|
||||
var nop = function() {};
|
||||
|
||||
this.reportResult = nop;
|
||||
this.reportEnd = nop;
|
||||
this.runScenario = nop;
|
||||
|
||||
this.name = 'Angular Scenario Adapter';
|
||||
|
||||
/**
|
||||
* Called for each JSTD TestCase
|
||||
*
|
||||
* Handles only SCENARIO_TYPE test cases. There should be only one fake TestCase.
|
||||
* Runs all scenario tests (under one fake TestCase) and report all results to JSTD.
|
||||
*
|
||||
* @param {jstestdriver.TestRunConfiguration} configuration
|
||||
* @param {Function} onTestDone
|
||||
* @param {Function} onAllTestsComplete
|
||||
* @returns {boolean} True if this type of test is handled by this plugin, false otherwise
|
||||
*/
|
||||
this.runTestConfiguration = function(configuration, onTestDone, onAllTestsComplete) {
|
||||
if (configuration.getTestCaseInfo().getType() != SCENARIO_TYPE) return false;
|
||||
|
||||
this.reportResult = onTestDone;
|
||||
this.reportEnd = onAllTestsComplete;
|
||||
this.runScenario();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
this.getTestRunsConfigurationFor = function(testCaseInfos, expressions, testRunsConfiguration) {
|
||||
testRunsConfiguration.push(
|
||||
new jstestdriver.TestRunConfiguration(
|
||||
new jstestdriver.TestCaseInfo(
|
||||
'Angular Scenario Tests', function() {}, SCENARIO_TYPE), []));
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton instance of the plugin
|
||||
* Accessed using closure by:
|
||||
* - jstd output (reports to this plugin)
|
||||
* - initScenarioAdapter (register the plugin to jstd)
|
||||
*/
|
||||
var plugin = new JstdPlugin();
|
||||
|
||||
/**
|
||||
* Initialise scenario jstd-adapter
|
||||
* (only if jstestdriver is defined)
|
||||
*
|
||||
* @param {Object} jstestdriver Undefined when run from browser (without jstd)
|
||||
* @param {Function} initScenarioAndRun Function that inits scenario and runs all the tests
|
||||
* @param {Object=} config Configuration object, supported properties:
|
||||
* - relativeUrlPrefix: prefix for all relative links when navigateTo()
|
||||
*/
|
||||
function initScenarioAdapter(jstestdriver, initScenarioAndRun, config) {
|
||||
if (jstestdriver) {
|
||||
// create and register ScenarioPlugin
|
||||
jstestdriver.pluginRegistrar.register(plugin);
|
||||
plugin.runScenario = initScenarioAndRun;
|
||||
|
||||
/**
|
||||
* HACK (angular.scenario.Application.navigateTo)
|
||||
*
|
||||
* We need to navigate to relative urls when running from browser (without JSTD),
|
||||
* because we want to allow running scenario tests without creating its own virtual host.
|
||||
* For example: http://angular.local/build/docs/docs-scenario.html
|
||||
*
|
||||
* On the other hand, when running with JSTD, we need to navigate to absolute urls,
|
||||
* because of JSTD proxy. (proxy, because of same domain policy)
|
||||
*
|
||||
* So this hack is applied only if running with JSTD and change all relative urls to absolute.
|
||||
*/
|
||||
var appProto = angular.scenario.Application.prototype,
|
||||
navigateTo = appProto.navigateTo,
|
||||
relativeUrlPrefix = config && config.relativeUrlPrefix || '/';
|
||||
|
||||
appProto.navigateTo = function(url, loadFn, errorFn) {
|
||||
if (url.charAt(0) != '/' && url.charAt(0) != '#' &&
|
||||
url != 'about:blank' && !url.match(/^https?/)) {
|
||||
url = relativeUrlPrefix + url;
|
||||
}
|
||||
|
||||
return navigateTo.call(this, url, loadFn, errorFn);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds proper TestResult object from given model spec
|
||||
*
|
||||
* TODO(vojta) report error details
|
||||
*
|
||||
* @param {angular.scenario.ObjectModel.Spec} spec
|
||||
* @returns {jstestdriver.TestResult}
|
||||
*/
|
||||
function createTestResultFromSpec(spec) {
|
||||
var map = {
|
||||
success: 'PASSED',
|
||||
error: 'ERROR',
|
||||
failure: 'FAILED'
|
||||
};
|
||||
|
||||
return new jstestdriver.TestResult(
|
||||
spec.fullDefinitionName,
|
||||
spec.name,
|
||||
jstestdriver.TestResult.RESULT[map[spec.status]],
|
||||
spec.error || '',
|
||||
spec.line || '',
|
||||
spec.duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates JSTD output (jstestdriver.TestResult)
|
||||
*/
|
||||
angular.scenario.output('jstd', function(context, runner, model) {
|
||||
model.on('SpecEnd', function(spec) {
|
||||
plugin.reportResult(createTestResultFromSpec(spec));
|
||||
});
|
||||
|
||||
model.on('RunnerEnd', function() {
|
||||
plugin.reportEnd();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @license AngularJS v"NG_VERSION_FULL"
|
||||
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window) {
|
||||
@@ -0,0 +1,2 @@
|
||||
initScenarioAdapter(window.jstestdriver, angular.scenario.setUpAndRun, window.jstdScenarioAdapter);
|
||||
})(window);
|
||||
+1
-1
@@ -175,7 +175,7 @@ describe('Binder', function() {
|
||||
$rootScope.error['throw'] = function() {throw 'MyError';};
|
||||
errorLogs.length = 0;
|
||||
$rootScope.$apply();
|
||||
expect(errorLogs.shift().message).toBe('Error while interpolating: {{error.throw()}}\nMyError');
|
||||
expect(errorLogs.shift()).toBe('MyError');
|
||||
|
||||
$rootScope.error['throw'] = function() {return 'ok';};
|
||||
$rootScope.$apply();
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
describe('injector', function() {
|
||||
var providers;
|
||||
var injector;
|
||||
var providerInjector;
|
||||
|
||||
beforeEach(module(function($provide, $injector) {
|
||||
beforeEach(module(function($provide) {
|
||||
providers = function(name, factory, annotations) {
|
||||
$provide.factory(name, extend(factory, annotations||{}));
|
||||
};
|
||||
providerInjector = $injector;
|
||||
}));
|
||||
beforeEach(inject(function($injector){
|
||||
injector = $injector;
|
||||
@@ -74,11 +72,6 @@ describe('injector', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should create a new $injector for the run phase', inject(function($injector) {
|
||||
expect($injector).not.toBe(providerInjector);
|
||||
}));
|
||||
|
||||
|
||||
describe('invoke', function() {
|
||||
var args;
|
||||
|
||||
@@ -556,26 +549,26 @@ describe('injector', function() {
|
||||
|
||||
|
||||
it('should decorate the missing service error with module name', function() {
|
||||
angular.module('TestModule', [], function(xyzzy) {});
|
||||
angular.module('TestModule', [], function($injector) {});
|
||||
expect(function() {
|
||||
createInjector(['TestModule']);
|
||||
}).toThrow('Unknown provider: xyzzy from TestModule');
|
||||
}).toThrow('Unknown provider: $injector from TestModule');
|
||||
});
|
||||
|
||||
|
||||
it('should decorate the missing service error with module function', function() {
|
||||
function myModule(xyzzy){}
|
||||
function myModule($injector){}
|
||||
expect(function() {
|
||||
createInjector([myModule]);
|
||||
}).toThrow('Unknown provider: xyzzy from ' + myModule);
|
||||
}).toThrow('Unknown provider: $injector from ' + myModule);
|
||||
});
|
||||
|
||||
|
||||
it('should decorate the missing service error with module array function', function() {
|
||||
function myModule(xyzzy){}
|
||||
function myModule($injector){}
|
||||
expect(function() {
|
||||
createInjector([['xyzzy', myModule]]);
|
||||
}).toThrow('Unknown provider: xyzzy from ' + myModule);
|
||||
createInjector([['$injector', myModule]]);
|
||||
}).toThrow('Unknown provider: $injector from ' + myModule);
|
||||
});
|
||||
|
||||
|
||||
|
||||
+1
-6
@@ -955,14 +955,9 @@ describe('jqLite', function() {
|
||||
expect(root.append('text')).toEqual(root);
|
||||
expect(root.html()).toEqual('text');
|
||||
});
|
||||
it('should append to document fragment', function() {
|
||||
it('should not append anything if parent node is not of type element', function() {
|
||||
var root = jqLite(document.createDocumentFragment());
|
||||
expect(root.append('<p>foo</p>')).toBe(root);
|
||||
expect(root.children().length).toBe(1);
|
||||
});
|
||||
it('should not append anything if parent node is not of type element or docfrag', function() {
|
||||
var root = jqLite('<p>some text node</p>').contents();
|
||||
expect(root.append('<p>foo</p>')).toBe(root);
|
||||
expect(root.children().length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,12 +104,6 @@ describe('$cacheFactory', function() {
|
||||
cache.remove(123);
|
||||
expect(cache.info().size).toBe(0);
|
||||
}));
|
||||
|
||||
|
||||
it("should return value from put", inject(function($cacheFactory) {
|
||||
var obj = {};
|
||||
expect(cache.put('k1', obj)).toBe(obj);
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -74,16 +74,6 @@ describe('boolean attr directives', function() {
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('multiple')).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('should bind open', inject(function($rootScope, $compile) {
|
||||
element = $compile('<details ng-open="isOpen"></details>')($rootScope)
|
||||
$rootScope.isOpen=false;
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('open')).toBeFalsy();
|
||||
$rootScope.isOpen=true;
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('open')).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -430,110 +430,4 @@ describe('form', function() {
|
||||
expect(doc).toBeDirty();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('$setPristine', function() {
|
||||
|
||||
it('should reset pristine state of form and controls', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<input ng-model="named1" name="foo">' +
|
||||
'<input ng-model="named2" name="bar">' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
input1 = form.find('input').eq(0),
|
||||
input1Ctrl = input1.controller('ngModel'),
|
||||
input2 = form.find('input').eq(1),
|
||||
input2Ctrl = input2.controller('ngModel');
|
||||
|
||||
input1Ctrl.$setViewValue('xx');
|
||||
input2Ctrl.$setViewValue('yy');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(input1).toBeDirty();
|
||||
expect(input2).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(input1).toBePristine();
|
||||
expect(input1Ctrl.$pristine).toBe(true);
|
||||
expect(input1Ctrl.$dirty).toBe(false);
|
||||
expect(input2).toBePristine();
|
||||
expect(input2Ctrl.$pristine).toBe(true);
|
||||
expect(input2Ctrl.$dirty).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should reset pristine state of anonymous form controls', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<input ng-model="anonymous">' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
input = form.find('input').eq(0),
|
||||
inputCtrl = input.controller('ngModel');
|
||||
|
||||
inputCtrl.$setViewValue('xx');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(input).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(input).toBePristine();
|
||||
expect(inputCtrl.$pristine).toBe(true);
|
||||
expect(inputCtrl.$dirty).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should reset pristine state of nested forms', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<div ng-form>' +
|
||||
'<input ng-model="named" name="foo">' +
|
||||
'</div>' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
nestedForm = form.find('div'),
|
||||
nestedFormCtrl = nestedForm.controller('form'),
|
||||
nestedInput = form.find('input').eq(0),
|
||||
nestedInputCtrl = nestedInput.controller('ngModel');
|
||||
|
||||
nestedInputCtrl.$setViewValue('xx');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(nestedForm).toBeDirty();
|
||||
expect(nestedInput).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(nestedForm).toBePristine();
|
||||
expect(nestedFormCtrl.$pristine).toBe(true);
|
||||
expect(nestedFormCtrl.$dirty).toBe(false);
|
||||
expect(nestedInput).toBePristine();
|
||||
expect(nestedInputCtrl.$pristine).toBe(true);
|
||||
expect(nestedInputCtrl.$dirty).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,18 +117,6 @@ describe('NgModelController', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPristine', function() {
|
||||
|
||||
it('should set control to its pristine state', function() {
|
||||
ctrl.$setViewValue('edit');
|
||||
expect(ctrl.$dirty).toBe(true);
|
||||
expect(ctrl.$pristine).toBe(false);
|
||||
|
||||
ctrl.$setPristine();
|
||||
expect(ctrl.$dirty).toBe(false);
|
||||
expect(ctrl.$pristine).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('view -> model', function() {
|
||||
|
||||
@@ -394,14 +382,6 @@ describe('input', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should update the model and not trim the value', function() {
|
||||
compileInput('<input type="text" ng-model="name" name="alias" ng-trim="false" />');
|
||||
|
||||
changeInputValueTo(' a ');
|
||||
expect(scope.name).toEqual(' a ');
|
||||
});
|
||||
|
||||
|
||||
it('should allow complex reference binding', function() {
|
||||
compileInput('<input type="text" ng-model="obj[\'abc\'].name"/>');
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('ngKeyup and ngKeydown directives', function() {
|
||||
var element;
|
||||
|
||||
afterEach(function() {
|
||||
dealoc(element);
|
||||
});
|
||||
|
||||
it('should get called on a keyup', inject(function($rootScope, $compile) {
|
||||
element = $compile('<input ng-keyup="touched = true">')($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect($rootScope.touched).toBeFalsy();
|
||||
|
||||
browserTrigger(element, 'keyup');
|
||||
expect($rootScope.touched).toEqual(true);
|
||||
}));
|
||||
|
||||
it('should get called on a keydown', inject(function($rootScope, $compile) {
|
||||
element = $compile('<input ng-keydown="touched = true">')($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect($rootScope.touched).toBeFalsy();
|
||||
|
||||
browserTrigger(element, 'keydown');
|
||||
expect($rootScope.touched).toEqual(true);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
@@ -253,37 +253,32 @@ describe('filters', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should support various iso8061 date strings with timezone as input', function() {
|
||||
var format = 'yyyy-MM-dd ss';
|
||||
it('should support various iso8061 date strings as input', function() {
|
||||
var format = 'yyyy-MM ss';
|
||||
|
||||
//full ISO8061
|
||||
expect(date('2003-09-10T13:02:03.000Z', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03.000Z', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('2003-09-10T13:02:03.000+00:00', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03.000+00:00', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('20030910T033203-0930', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03-08:00', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('20030910T033203-0930', format)).toEqual('2003-09 03');
|
||||
|
||||
//no timezone
|
||||
expect(date('2003-09-10T13:02:03.000', format)).toEqual('2003-09 03');
|
||||
|
||||
//no millis
|
||||
expect(date('2003-09-10T13:02:03Z', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03Z', format)).toEqual('2003-09 03');
|
||||
|
||||
//no seconds
|
||||
expect(date('2003-09-10T13:02Z', format)).toEqual('2003-09-10 00');
|
||||
expect(date('2003-09-10T13:02Z', format)).toEqual('2003-09 00');
|
||||
|
||||
//no minutes
|
||||
expect(date('2003-09-10T13Z', format)).toEqual('2003-09-10 00');
|
||||
});
|
||||
|
||||
|
||||
it('should parse iso8061 date strings without timezone as local time', function() {
|
||||
var format = 'yyyy-MM-dd HH-mm-ss';
|
||||
|
||||
//full ISO8061 without timezone
|
||||
expect(date('2003-09-10T03:02:04.000', format)).toEqual('2003-09-10 03-02-04');
|
||||
|
||||
expect(date('20030910T030204', format)).toEqual('2003-09-10 03-02-04');
|
||||
expect(date('2003-09-10T13Z', format)).toEqual('2003-09 00');
|
||||
|
||||
//no time
|
||||
expect(date('2003-09-10', format)).toEqual('2003-09-10 00-00-00');
|
||||
expect(date('2003-09-10', format)).toEqual('2003-09 00');
|
||||
});
|
||||
|
||||
it('should support different degrees of subsecond precision', function () {
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
describe('Filter: limitTo', function() {
|
||||
var items;
|
||||
var str
|
||||
var limitTo;
|
||||
|
||||
beforeEach(inject(function($filter) {
|
||||
items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
||||
str = "tuvwxyz";
|
||||
limitTo = $filter('limitTo');
|
||||
}));
|
||||
|
||||
@@ -15,16 +13,12 @@ describe('Filter: limitTo', function() {
|
||||
it('should return the first X items when X is positive', function() {
|
||||
expect(limitTo(items, 3)).toEqual(['a', 'b', 'c']);
|
||||
expect(limitTo(items, '3')).toEqual(['a', 'b', 'c']);
|
||||
expect(limitTo(str, 3)).toEqual("tuv");
|
||||
expect(limitTo(str, '3')).toEqual("tuv");
|
||||
});
|
||||
|
||||
|
||||
it('should return the last X items when X is negative', function() {
|
||||
expect(limitTo(items, -3)).toEqual(['f', 'g', 'h']);
|
||||
expect(limitTo(items, '-3')).toEqual(['f', 'g', 'h']);
|
||||
expect(limitTo(str, -3)).toEqual("xyz");
|
||||
expect(limitTo(str, '-3')).toEqual("xyz");
|
||||
});
|
||||
|
||||
|
||||
@@ -36,17 +30,11 @@ describe('Filter: limitTo', function() {
|
||||
expect(limitTo(items, undefined)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return an empty string when X cannot be parsed', function() {
|
||||
expect(limitTo(str, 'bogus')).toEqual("");
|
||||
expect(limitTo(str, 'null')).toEqual("");
|
||||
expect(limitTo(str, 'undefined')).toEqual("");
|
||||
expect(limitTo(str, null)).toEqual("");
|
||||
expect(limitTo(str, undefined)).toEqual("");
|
||||
});
|
||||
|
||||
|
||||
it('should return input if not String or Array', function() {
|
||||
expect(limitTo(1,1)).toEqual(1);
|
||||
it('should return an empty array when input is not Array type', function() {
|
||||
expect(limitTo('bogus', 1)).toEqual('bogus');
|
||||
expect(limitTo(null, 1)).toEqual(null);
|
||||
expect(limitTo(undefined, 1)).toEqual(undefined);
|
||||
expect(limitTo(null, 1)).toEqual(null);
|
||||
expect(limitTo(undefined, 1)).toEqual(undefined);
|
||||
expect(limitTo({}, 1)).toEqual({});
|
||||
@@ -54,18 +42,11 @@ describe('Filter: limitTo', function() {
|
||||
|
||||
|
||||
it('should return a copy of input array if X is exceeds array length', function () {
|
||||
expect(limitTo(items, 9)).toEqual(items);
|
||||
expect(limitTo(items, 19)).toEqual(items);
|
||||
expect(limitTo(items, '9')).toEqual(items);
|
||||
expect(limitTo(items, -9)).toEqual(items);
|
||||
expect(limitTo(items, '-9')).toEqual(items);
|
||||
|
||||
expect(limitTo(items, 9)).not.toBe(items);
|
||||
});
|
||||
|
||||
it('should return the entire string if X exceeds input length', function() {
|
||||
expect(limitTo(str, 9)).toEqual(str);
|
||||
expect(limitTo(str, '9')).toEqual(str);
|
||||
expect(limitTo(str, -9)).toEqual(str);
|
||||
expect(limitTo(str, '-9')).toEqual(str);
|
||||
})
|
||||
});
|
||||
|
||||
@@ -135,24 +135,6 @@ describe('$httpBackend', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should set responseType and return xhr.response', function() {
|
||||
$backend('GET', '/whatever', null, callback, {}, null, null, 'blob');
|
||||
|
||||
var xhrInstance = MockXhr.$$lastInstance;
|
||||
expect(xhrInstance.responseType).toBe('blob');
|
||||
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(response).toBe(xhrInstance.response);
|
||||
});
|
||||
|
||||
xhrInstance.response = {some: 'object'};
|
||||
xhrInstance.readyState = 4;
|
||||
xhrInstance.onreadystatechange();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
|
||||
describe('JSONP', function() {
|
||||
|
||||
var SCRIPT_URL = /([^\?]*)\?cb=angular\.callbacks\.(.*)/;
|
||||
|
||||
+10
-69
@@ -147,12 +147,6 @@ describe('$http', function() {
|
||||
$httpBackend.expect('GET', '/url?a=1&b=%7B%22c%22%3A3%7D').respond('');
|
||||
$http({url: '/url', params: {a:1, b:{c:3}}, method: 'GET'});
|
||||
}));
|
||||
|
||||
|
||||
it('should expand arrays in params map', inject(function($httpBackend, $http) {
|
||||
$httpBackend.expect('GET', '/url?a=1&a=2&a=3').respond('');
|
||||
$http({url: '/url', params: {a: [1,2,3]}, method: 'GET'});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
@@ -377,7 +371,8 @@ describe('$http', function() {
|
||||
|
||||
it('should set default headers for GET request', function() {
|
||||
$httpBackend.expect('GET', '/url', undefined, function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*';
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest';
|
||||
}).respond('');
|
||||
|
||||
$http({url: '/url', method: 'GET', headers: {}});
|
||||
@@ -388,6 +383,7 @@ describe('$http', function() {
|
||||
it('should set default headers for POST request', function() {
|
||||
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'application/json;charset=utf-8';
|
||||
}).respond('');
|
||||
|
||||
@@ -399,6 +395,7 @@ describe('$http', function() {
|
||||
it('should set default headers for PUT request', function() {
|
||||
$httpBackend.expect('PUT', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'application/json;charset=utf-8';
|
||||
}).respond('');
|
||||
|
||||
@@ -409,7 +406,8 @@ describe('$http', function() {
|
||||
|
||||
it('should set default headers for custom HTTP method', function() {
|
||||
$httpBackend.expect('FOO', '/url', undefined, function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*';
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest';
|
||||
}).respond('');
|
||||
|
||||
$http({url: '/url', method: 'FOO', headers: {}});
|
||||
@@ -420,6 +418,7 @@ describe('$http', function() {
|
||||
it('should override default headers with custom', function() {
|
||||
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'Rewritten' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'Rewritten';
|
||||
}).respond('');
|
||||
|
||||
@@ -430,17 +429,6 @@ describe('$http', function() {
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should not set XSRF cookie for cross-domain requests', inject(function($browser) {
|
||||
$browser.cookies('XSRF-TOKEN', 'secret');
|
||||
$browser.url('http://host.com/base');
|
||||
$httpBackend.expect('GET', 'http://www.test.com/url', undefined, function(headers) {
|
||||
return headers['X-XSRF-TOKEN'] === undefined;
|
||||
}).respond('');
|
||||
|
||||
$http({url: 'http://www.test.com/url', method: 'GET', headers: {}});
|
||||
$httpBackend.flush();
|
||||
}));
|
||||
|
||||
|
||||
it('should not send Content-Type header if request data/body is undefined', function() {
|
||||
$httpBackend.expect('POST', '/url', undefined, function(headers) {
|
||||
@@ -971,13 +959,12 @@ describe('$http', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should pass timeout, withCredentials and responseType', function() {
|
||||
it('should pass timeout and withCredentials', function() {
|
||||
var $httpBackend = jasmine.createSpy('$httpBackend');
|
||||
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials, responseType) {
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials) {
|
||||
expect(timeout).toBe(12345);
|
||||
expect(withCredentials).toBe(true);
|
||||
expect(responseType).toBe('json');
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
@@ -985,56 +972,10 @@ describe('$http', function() {
|
||||
});
|
||||
|
||||
inject(function($http) {
|
||||
$http({
|
||||
method: 'GET', url: 'some.html', timeout: 12345, withCredentials: true, responseType: 'json'
|
||||
});
|
||||
$http({method: 'GET', url: 'some.html', timeout: 12345, withCredentials: true});
|
||||
expect($httpBackend).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
$httpBackend.verifyNoOutstandingExpectation = noop;
|
||||
});
|
||||
|
||||
|
||||
it('should use withCredentials from default', function() {
|
||||
var $httpBackend = jasmine.createSpy('$httpBackend');
|
||||
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials, responseType) {
|
||||
expect(withCredentials).toBe(true);
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('$httpBackend', $httpBackend);
|
||||
});
|
||||
|
||||
inject(function($http) {
|
||||
$http.defaults.withCredentials = true;
|
||||
$http({
|
||||
method: 'GET', url: 'some.html', timeout: 12345, responseType: 'json'
|
||||
});
|
||||
expect($httpBackend).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
$httpBackend.verifyNoOutstandingExpectation = noop;
|
||||
});
|
||||
|
||||
describe('isSameDomain', function() {
|
||||
it('should support various combinations of urls', function() {
|
||||
expect(isSameDomain('path/morepath',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('http://www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'https://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'http://www.adomain.com:1234')).toBe(false);
|
||||
expect(isSameDomain('https://www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
expect(isSameDomain('http://www.adomain.com:1234/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
expect(isSameDomain('http://www.anotherdomain.com/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,29 +26,6 @@ describe('$interpolate', function() {
|
||||
expect($interpolate('{{ false }}')()).toEqual('false');
|
||||
}));
|
||||
|
||||
it('should rethrow exceptions', inject(function($interpolate, $rootScope) {
|
||||
$rootScope.err = function () {
|
||||
throw new Error('oops');
|
||||
};
|
||||
expect(function () {
|
||||
$interpolate('{{err()}}')($rootScope);
|
||||
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
|
||||
}));
|
||||
|
||||
it('should stop interpolation when encountering an exception', inject(function($interpolate, $compile, $rootScope) {
|
||||
$rootScope.err = function () {
|
||||
throw new Error('oops');
|
||||
};
|
||||
var dom = jqLite('<div>{{1 + 1}}</div><div>{{err()}}</div><div>{{1 + 2}}</div>');
|
||||
$compile(dom)($rootScope);
|
||||
expect(function () {
|
||||
$rootScope.$apply();
|
||||
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
|
||||
expect(dom[0].innerHTML).toEqual('2');
|
||||
expect(dom[1].innerHTML).toEqual('{{err()}}');
|
||||
expect(dom[2].innerHTML).toEqual('{{1 + 2}}');
|
||||
}));
|
||||
|
||||
|
||||
it('should return interpolation function', inject(function($interpolate, $rootScope) {
|
||||
$rootScope.name = 'Misko';
|
||||
|
||||
+8
-45
@@ -1,24 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
function initService(debugEnabled) {
|
||||
return module(function($logProvider){
|
||||
$logProvider.debugEnabled(debugEnabled);
|
||||
});
|
||||
}
|
||||
|
||||
describe('$log', function() {
|
||||
var $window, logger, log, warn, info, error, debug;
|
||||
var $window, logger, log, warn, info, error;
|
||||
|
||||
|
||||
|
||||
beforeEach(module(function($provide){
|
||||
$window = {navigator: {}, document: {}};
|
||||
$window = {navigator: {}};
|
||||
logger = '';
|
||||
log = function() { logger+= 'log;'; };
|
||||
warn = function() { logger+= 'warn;'; };
|
||||
info = function() { logger+= 'info;'; };
|
||||
error = function() { logger+= 'error;'; };
|
||||
debug = function() { logger+= 'debug;'; };
|
||||
|
||||
$provide.provider('$log', $LogProvider);
|
||||
$provide.value('$exceptionHandler', angular.mock.rethrow);
|
||||
@@ -30,16 +23,14 @@ describe('$log', function() {
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
error: error};
|
||||
},
|
||||
function($log) {
|
||||
$log.log();
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;warn;info;error;debug;');
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
}
|
||||
));
|
||||
|
||||
@@ -53,8 +44,7 @@ describe('$log', function() {
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;log;log;log;log;');
|
||||
expect(logger).toEqual('log;log;log;log;');
|
||||
}
|
||||
));
|
||||
|
||||
@@ -65,7 +55,6 @@ describe('$log', function() {
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
}
|
||||
));
|
||||
|
||||
@@ -75,48 +64,22 @@ describe('$log', function() {
|
||||
log.apply = log.call =
|
||||
warn.apply = warn.call =
|
||||
info.apply = info.call =
|
||||
error.apply = error.call =
|
||||
debug.apply = debug.call = null;
|
||||
error.apply = error.call = null;
|
||||
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
error: error};
|
||||
},
|
||||
function($log) {
|
||||
$log.log.apply($log);
|
||||
$log.warn.apply($log);
|
||||
$log.info.apply($log);
|
||||
$log.error.apply($log);
|
||||
$log.debug.apply($log);
|
||||
expect(logger).toEqual('log;warn;info;error;debug;');
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
})
|
||||
);
|
||||
|
||||
describe("$log.debug", function () {
|
||||
|
||||
beforeEach(initService(false));
|
||||
|
||||
it("should skip debugging output if disabled", inject(
|
||||
function(){
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
},
|
||||
function($log) {
|
||||
$log.log();
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
}
|
||||
));
|
||||
|
||||
});
|
||||
|
||||
describe('$log.error', function() {
|
||||
var e, $log, errorArgs;
|
||||
|
||||
+3
-13
@@ -91,8 +91,8 @@ describe('parser', function() {
|
||||
expect(tokens[1].text).toEqual('b');
|
||||
});
|
||||
|
||||
it('should tokenize relation and equality', function() {
|
||||
var tokens = lex("! == != < > <= >= === !==");
|
||||
it('should tokenize relation', function() {
|
||||
var tokens = lex("! == != < > <= >=");
|
||||
expect(tokens[0].text).toEqual('!');
|
||||
expect(tokens[1].text).toEqual('==');
|
||||
expect(tokens[2].text).toEqual('!=');
|
||||
@@ -100,8 +100,6 @@ describe('parser', function() {
|
||||
expect(tokens[4].text).toEqual('>');
|
||||
expect(tokens[5].text).toEqual('<=');
|
||||
expect(tokens[6].text).toEqual('>=');
|
||||
expect(tokens[7].text).toEqual('===');
|
||||
expect(tokens[8].text).toEqual('!==');
|
||||
});
|
||||
|
||||
it('should tokenize statements', function() {
|
||||
@@ -199,20 +197,12 @@ describe('parser', function() {
|
||||
expect(scope.$eval("false")).toBeFalsy();
|
||||
expect(scope.$eval("!true")).toBeFalsy();
|
||||
expect(scope.$eval("1==1")).toBeTruthy();
|
||||
expect(scope.$eval("1==true")).toBeTruthy();
|
||||
expect(scope.$eval("1===1")).toBeTruthy();
|
||||
expect(scope.$eval("1==='1'")).toBeFalsy();
|
||||
expect(scope.$eval("1===true")).toBeFalsy();
|
||||
expect(scope.$eval("'true'===true")).toBeFalsy();
|
||||
expect(scope.$eval("1!==2")).toBeTruthy();
|
||||
expect(scope.$eval("1!=='1'")).toBeTruthy();
|
||||
expect(scope.$eval("1!=2")).toBeTruthy();
|
||||
expect(scope.$eval("1<2")).toBeTruthy();
|
||||
expect(scope.$eval("1<=1")).toBeTruthy();
|
||||
expect(scope.$eval("1>2")).toEqual(1>2);
|
||||
expect(scope.$eval("2>=1")).toEqual(2>=1);
|
||||
expect(scope.$eval("true==2<3")).toEqual(true == 2<3);
|
||||
expect(scope.$eval("true===2<3")).toEqual(true === 2<3);
|
||||
expect(scope.$eval("true==2<3")).toEqual(true === 2<3);
|
||||
});
|
||||
|
||||
it('should parse logical', function() {
|
||||
|
||||
@@ -457,7 +457,7 @@ describe('Scope', function() {
|
||||
child.$evalAsync(function(scope) { log += 'child.async;'; });
|
||||
child.$watch('value', function() { log += 'child.$digest;'; });
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('parent.async;child.async;parent.$digest;child.$digest;');
|
||||
expect(log).toEqual('parent.async;parent.$digest;child.async;child.$digest;');
|
||||
}));
|
||||
|
||||
it('should cause a $digest rerun', inject(function($rootScope) {
|
||||
|
||||
@@ -715,53 +715,6 @@ describe('$route', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should allow using a function as a template', function() {
|
||||
var customTemplateWatcher = jasmine.createSpy('customTemplateWatcher');
|
||||
|
||||
function customTemplateFn(routePathParams) {
|
||||
customTemplateWatcher(routePathParams);
|
||||
expect(routePathParams).toEqual({id: 'id3'});
|
||||
return '<h1>' + routePathParams.id + '</h1>';
|
||||
}
|
||||
|
||||
module(function($routeProvider){
|
||||
$routeProvider.when('/bar/:id/:subid/:subsubid', {templateUrl: 'bar.html'});
|
||||
$routeProvider.when('/foo/:id', {template: customTemplateFn});
|
||||
});
|
||||
|
||||
inject(function($route, $location, $rootScope) {
|
||||
$location.path('/foo/id3');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(customTemplateWatcher).toHaveBeenCalledWith({id: 'id3'});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should allow using a function as a templateUrl', function() {
|
||||
var customTemplateUrlWatcher = jasmine.createSpy('customTemplateUrlWatcher');
|
||||
|
||||
function customTemplateUrlFn(routePathParams) {
|
||||
customTemplateUrlWatcher(routePathParams);
|
||||
expect(routePathParams).toEqual({id: 'id3'});
|
||||
return 'foo.html';
|
||||
}
|
||||
|
||||
module(function($routeProvider){
|
||||
$routeProvider.when('/bar/:id/:subid/:subsubid', {templateUrl: 'bar.html'});
|
||||
$routeProvider.when('/foo/:id', {templateUrl: customTemplateUrlFn});
|
||||
});
|
||||
|
||||
inject(function($route, $location, $rootScope) {
|
||||
$location.path('/foo/id3');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(customTemplateUrlWatcher).toHaveBeenCalledWith({id: 'id3'});
|
||||
expect($route.current.loadedTemplateUrl).toEqual('foo.html');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('reload', function() {
|
||||
|
||||
it('should reload even if reloadOnSearch is false', function() {
|
||||
|
||||
+6
-24
@@ -2,10 +2,9 @@
|
||||
|
||||
describe('$sniffer', function() {
|
||||
|
||||
function sniffer($window, $document) {
|
||||
function sniffer($window) {
|
||||
$window.navigator = {};
|
||||
$document = jqLite($document || {});
|
||||
return new $SnifferProvider().$get[2]($window, $document);
|
||||
return new $SnifferProvider().$get[1]($window);
|
||||
}
|
||||
|
||||
describe('history', function() {
|
||||
@@ -21,15 +20,15 @@ describe('$sniffer', function() {
|
||||
|
||||
describe('hashchange', function() {
|
||||
it('should be true if onhashchange property defined', function() {
|
||||
expect(sniffer({onhashchange: true}, {}).hashchange).toBe(true);
|
||||
expect(sniffer({onhashchange: true, document: {}}).hashchange).toBe(true);
|
||||
});
|
||||
|
||||
it('should be false if onhashchange property not defined', function() {
|
||||
expect(sniffer({}, {}).hashchange).toBe(false);
|
||||
expect(sniffer({document: {}}).hashchange).toBe(false);
|
||||
});
|
||||
|
||||
it('should be false if documentMode is 7 (IE8 comp mode)', function() {
|
||||
expect(sniffer({onhashchange: true}, {documentMode: 7}).hashchange).toBe(false);
|
||||
expect(sniffer({onhashchange: true, document: {documentMode: 7}}).hashchange).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,7 +42,7 @@ describe('$sniffer', function() {
|
||||
if (elm === 'div') return mockDivElement;
|
||||
});
|
||||
|
||||
$sniffer = sniffer({}, mockDocument);
|
||||
$sniffer = sniffer({document: mockDocument});
|
||||
});
|
||||
|
||||
|
||||
@@ -79,21 +78,4 @@ describe('$sniffer', function() {
|
||||
expect($sniffer.hasEvent('input')).toBe((msie == 9) ? false : true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('csp', function() {
|
||||
it('should be false if document.securityPolicy.isActive not available', function() {
|
||||
expect(sniffer({}, {}).csp).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should use document.securityPolicy.isActive if available', function() {
|
||||
var createDocumentWithCSP = function(csp) {
|
||||
return {securityPolicy: {isActive: csp}};
|
||||
};
|
||||
|
||||
expect(sniffer({}, createDocumentWithCSP(false)).csp).toBe(false);
|
||||
expect(sniffer({}, createDocumentWithCSP(true)).csp).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
-16
@@ -327,22 +327,6 @@ describe('ngMock', function() {
|
||||
$timeout.flush();
|
||||
expect(logger).toEqual(['t1', 't3', 't2']);
|
||||
}));
|
||||
|
||||
|
||||
it('should throw an exception when not flushed', inject(function($timeout){
|
||||
$timeout(noop);
|
||||
|
||||
var expectedError = 'Deferred tasks to flush (1): {id: 0, time: 0}';
|
||||
expect(function() {$timeout.verifyNoPendingTasks();}).toThrow(expectedError);
|
||||
}));
|
||||
|
||||
|
||||
it('should do nothing when all tasks have been flushed', inject(function($timeout) {
|
||||
$timeout(noop);
|
||||
|
||||
$timeout.flush();
|
||||
expect(function() {$timeout.verifyNoPendingTasks();}).not.toThrow();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -14,14 +14,7 @@ describe("resource", function() {
|
||||
},
|
||||
patch: {
|
||||
method: 'PATCH'
|
||||
},
|
||||
conditionalPut: {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'If-None-Match': '*'
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
callback = jasmine.createSpy();
|
||||
}));
|
||||
@@ -220,15 +213,6 @@ describe("resource", function() {
|
||||
});
|
||||
|
||||
|
||||
it('should send correct headers', function() {
|
||||
$httpBackend.expectPUT('/CreditCard/123', undefined, function(headers) {
|
||||
return headers['If-None-Match'] == "*";
|
||||
}).respond({id:123});
|
||||
|
||||
CreditCard.conditionalPut({id: {key:123}});
|
||||
});
|
||||
|
||||
|
||||
it("should read partial resource", function() {
|
||||
$httpBackend.expect('GET', '/CreditCard').respond([{id:{key:123}}]);
|
||||
var ccs = CreditCard.query();
|
||||
@@ -381,35 +365,6 @@ describe("resource", function() {
|
||||
});
|
||||
|
||||
|
||||
it('should support dynamic default parameters (global)', function() {
|
||||
var currentGroup = 'students',
|
||||
Person = $resource('/Person/:group/:id', { group: function() { return currentGroup; }});
|
||||
|
||||
|
||||
$httpBackend.expect('GET', '/Person/students/fedor').respond({id: 'fedor', email: 'f@f.com'});
|
||||
|
||||
var fedor = Person.get({id: 'fedor'});
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(fedor).toEqualData({id: 'fedor', email: 'f@f.com'});
|
||||
});
|
||||
|
||||
|
||||
it('should support dynamic default parameters (action specific)', function() {
|
||||
var currentGroup = 'students',
|
||||
Person = $resource('/Person/:group/:id', {}, {
|
||||
fetch: {method: 'GET', params: {group: function() { return currentGroup; }}}
|
||||
});
|
||||
|
||||
$httpBackend.expect('GET', '/Person/students/fedor').respond({id: 'fedor', email: 'f@f.com'});
|
||||
|
||||
var fedor = Person.fetch({id: 'fedor'});
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(fedor).toEqualData({id: 'fedor', email: 'f@f.com'});
|
||||
});
|
||||
|
||||
|
||||
it('should exercise full stack', function() {
|
||||
var Person = $resource('/Person/:id');
|
||||
|
||||
@@ -452,26 +407,4 @@ describe("resource", function() {
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should transform request/response', function() {
|
||||
var Person = $resource('/Person/:id', {}, {
|
||||
save: {
|
||||
method: 'POST',
|
||||
params: {id: '@id'},
|
||||
transformRequest: function(data) {
|
||||
return angular.toJson({ __id: data.id });
|
||||
},
|
||||
transformResponse: function(data) {
|
||||
return { id: data.__id };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$httpBackend.expect('POST', '/Person/123', { __id: 123 }).respond({ __id: 456 });
|
||||
var person = new Person({id:123});
|
||||
person.$save();
|
||||
$httpBackend.flush();
|
||||
expect(person.id).toEqual(456);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,11 +24,4 @@ describe('linky', function() {
|
||||
expect(linky("send email to me@example.com, but")).
|
||||
toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but');
|
||||
});
|
||||
|
||||
it('should handle target:', function() {
|
||||
expect(linky("http://example.com", "_blank")).
|
||||
toEqual('<a target="_blank" href="http://example.com">http://example.com</a>')
|
||||
expect(linky("http://example.com", "someNamedIFrame")).
|
||||
toEqual('<a target="someNamedIFrame" href="http://example.com">http://example.com</a>')
|
||||
});
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ describe('HTML', function() {
|
||||
expect(html).toEqual('<div>');
|
||||
});
|
||||
|
||||
describe('explicitly disallow', function() {
|
||||
describe('explicitly dissallow', function() {
|
||||
it('should not allow attributes', function() {
|
||||
writer.start('div', {id:'a', name:'a', style:'a'});
|
||||
expect(html).toEqual('<div>');
|
||||
@@ -230,11 +230,10 @@ describe('HTML', function() {
|
||||
expect(isUri('https://abc')).toBeTruthy();
|
||||
expect(isUri('ftp://abc')).toBeTruthy();
|
||||
expect(isUri('mailto:me@example.com')).toBeTruthy();
|
||||
expect(isUri('tel:123-123-1234')).toBeTruthy();
|
||||
expect(isUri('#anchor')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not be URI', function() {
|
||||
it('should not be UIR', function() {
|
||||
expect(isUri('')).toBeFalsy();
|
||||
expect(isUri('javascript:alert')).toBeFalsy();
|
||||
});
|
||||
|
||||
@@ -270,16 +270,6 @@ describe("angular.scenario.dsl", function() {
|
||||
expect($root.futureError).toMatch(/did not match/);
|
||||
});
|
||||
|
||||
it('should fail to select an option that does not exist', function(){
|
||||
doc.append(
|
||||
'<select ng-model="test">' +
|
||||
' <option value=A>one</option>' +
|
||||
' <option value=B selected>two</option>' +
|
||||
'</select>'
|
||||
);
|
||||
$root.dsl.select('test').option('three');
|
||||
expect($root.futureError).toMatch(/not found/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Element', function() {
|
||||
@@ -315,58 +305,6 @@ describe("angular.scenario.dsl", function() {
|
||||
dealoc(elm);
|
||||
});
|
||||
|
||||
it('should execute dblclick', function() {
|
||||
var clicked;
|
||||
// Hash is important, otherwise we actually
|
||||
// go to a different page and break the runner
|
||||
doc.append('<a href="#"></a>');
|
||||
doc.find('a').dblclick(function() {
|
||||
clicked = true;
|
||||
});
|
||||
$root.dsl.element('a').dblclick();
|
||||
});
|
||||
|
||||
it('should navigate page if dblclick on anchor', function() {
|
||||
expect($window.location).not.toEqual('#foo');
|
||||
doc.append('<a href="#foo"></a>');
|
||||
$root.dsl.element('a').dblclick();
|
||||
expect($window.location).toMatch(/#foo$/);
|
||||
});
|
||||
|
||||
it('should not navigate if dblclick event was cancelled', function() {
|
||||
var initLocation = $window.location,
|
||||
elm = jqLite('<a href="#foo"></a>');
|
||||
|
||||
doc.append(elm);
|
||||
elm.bind('dblclick', function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
$root.dsl.element('a').dblclick();
|
||||
expect($window.location).toBe(initLocation);
|
||||
dealoc(elm);
|
||||
});
|
||||
|
||||
it('should execute mouseover', function() {
|
||||
var mousedOver;
|
||||
doc.append('<div></div>');
|
||||
doc.find('div').mouseover(function() {
|
||||
mousedOver = true;
|
||||
});
|
||||
$root.dsl.element('div').mouseover();
|
||||
expect(mousedOver).toBe(true);
|
||||
});
|
||||
|
||||
it('should bubble up the mouseover event', function() {
|
||||
var mousedOver;
|
||||
doc.append('<div id="outer"><div id="inner"></div></div>');
|
||||
doc.find('#outer').mouseover(function() {
|
||||
mousedOver = true;
|
||||
});
|
||||
$root.dsl.element('#inner').mouseover();
|
||||
expect(mousedOver).toBe(true);
|
||||
});
|
||||
|
||||
it('should count matching elements', function() {
|
||||
doc.append('<span></span><span></span>');
|
||||
$root.dsl.element('span').count();
|
||||
|
||||
@@ -13,7 +13,7 @@ var util = require('util');
|
||||
|
||||
|
||||
var MAX_LENGTH = 70;
|
||||
var PATTERN = /^(?:fixup!\s*)?(\w*)(\(([\w\$\.\-\*/]*)\))?\: (.*)$/;
|
||||
var PATTERN = /^(\w*)(\(([\w\$\.\-\*/]*)\))?\: (.*)$/;
|
||||
var IGNORED = /^WIP\:/;
|
||||
var TYPES = {
|
||||
feat: true,
|
||||
@@ -51,7 +51,7 @@ var validateMessage = function(message) {
|
||||
var match = PATTERN.exec(message);
|
||||
|
||||
if (!match) {
|
||||
error('does not match "<type>(<scope>): <subject>" ! was: ' + message);
|
||||
error('does not match "<type>(<scope>): <subject>" !');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ describe('validate-commit-msg.js', function() {
|
||||
describe('validateMessage', function() {
|
||||
|
||||
it('should be valid', function() {
|
||||
expect(m.validateMessage('fixup! fix($compile): something')).toBe(VALID);
|
||||
expect(m.validateMessage('fix($compile): something')).toBe(VALID);
|
||||
expect(m.validateMessage('feat($location): something')).toBe(VALID);
|
||||
expect(m.validateMessage('docs($filter): something')).toBe(VALID);
|
||||
@@ -51,7 +50,7 @@ describe('validate-commit-msg.js', function() {
|
||||
var msg = 'not correct format';
|
||||
|
||||
expect(m.validateMessage(msg)).toBe(INVALID);
|
||||
expect(errors).toEqual(['INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" ! was: not correct format']);
|
||||
expect(errors).toEqual(['INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" !']);
|
||||
});
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# AngularJS build config file
|
||||
---
|
||||
version: 1.1.2
|
||||
codename: tofu-animation
|
||||
version: 1.0.4
|
||||
codename: bewildering-hair
|
||||
stable: 1.0.3
|
||||
|
||||
Reference in New Issue
Block a user