From 5a0d03025af7f1f169b10b455800776cfe7f1b90 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 23 Aug 2014 07:37:34 +0100 Subject: [PATCH 1/8] feat($compile/ngBind): only add binding info if debugInfo is enabled The compiler and ngBind directives add binding information (`ng-binding` CSS class and `$binding` data object) to elements when they are bound to the scope. This is only to aid testing and debugging for tools such as Protractor and Batarang. In production this is unneccesary and add a performance penalty. We were storing the whole `interpolationFn` in the `$binding` data on elements but this function was bringing a lot of closure variables with it and so was consuming unwanted amounts of memory. Now we are only storing the parsed interpolation expressions from the binding (i.e. the values of `interpolationFn.expressions`). This change disables adding this binding information by default. You can enable it by calling `$compilerProvider.enableDebugInfo()` in a module `config()` block. BREAKING CHANGE: The `ng-binding` CSS class and the `$binding` data object are no longer attached to DOM elements that have a binding to the scope, by default. If you relied on this feature then you can re-enable it in one of your application modules: ``` someModule.config(['$compileProvider', function($compileProvider) { $compileProvider.enableDebugInfo(); }]); ``` Also bindings are always arrays now and they do not include the curly braces `{{ ... }}` in the binding expression that is stored. --- src/ng/compile.js | 51 ++++++++++++++++++++++++++------- src/ng/directive/ngBind.js | 47 ++++++++++++++---------------- src/ngScenario/Scenario.js | 4 +-- test/ng/compileSpec.js | 28 ++++++++++++++---- test/ng/directive/ngBindSpec.js | 10 ++----- test/ngScenario/dslSpec.js | 4 +++ 6 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 18cb173fa035..4c827764cfd1 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -668,6 +668,33 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } }; + /** + * @ngdoc method + * @name $compileProvider#enableDebugInfo + * + * @param {boolean=} enabled update the enableDebugInfo state if provided, otherwise just return the + * current enabled state + * @returns {*} current value if used as getter or itself (chaining) if used as setter + * + * @kind function + * + * @description + * Call this method to enable various debug runtime information in the compiler such as adding + * binding information and a reference to the current scope on to DOM elements. + * If enabled, the compiler will add the following to DOM elements that have been bound to the scope + * * `ng-binding` CSS class + * * `$binding` data object containing the value of the binding (or an array if there are multiple + * bindings) + */ + var enableDebugInfo = false; + this.enableDebugInfo = function(enabled) { + if(isDefined(enabled)) { + enableDebugInfo = enabled; + return this; + } + return enableDebugInfo; + }; + this.$get = [ '$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse', '$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri', @@ -868,6 +895,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }, NG_ATTR_BINDING = /^ngAttr[A-Z]/; + compile.$$addBindingInfo = enableDebugInfo ? function $$addBindingInfo(element, binding) { + element + .addClass('ng-binding') + .data('$binding', + (element.data('$binding') || []).concat(binding.expressions || [binding]) + ); + } : noop; + + compile.$$addScopeInfo = enableDebugInfo ? function $$addScopeInfo(element, scope, isolated, noTemplate) { + safeAddClass(isolated ? 'ng-isolate-scope' : 'ng-scope'); + element .data(noTemplate ? isolated ? '$isolateScopeNoTemplate' : '$isolateScope' : '$scope', scope); + } : noop; return compile; @@ -1948,17 +1987,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { directives.push({ priority: 0, compile: function textInterpolateCompileFn(templateNode) { - // when transcluding a template that has bindings in the root - // then we don't have a parent and should do this in the linkFn - var parent = templateNode.parent(), hasCompileParent = parent.length; - if (hasCompileParent) safeAddClass(templateNode.parent(), 'ng-binding'); - return function textInterpolateLinkFn(scope, node) { - var parent = node.parent(), - bindings = parent.data('$binding') || []; - bindings.push(interpolateFn); - parent.data('$binding', bindings); - if (!hasCompileParent) safeAddClass(parent, 'ng-binding'); + var parent = node.parent(); + compile.$$addBindingInfo(parent, interpolateFn, true); scope.$watch(interpolateFn, function interpolateFnWatchAction(value) { node[0].nodeValue = value; }); diff --git a/src/ng/directive/ngBind.js b/src/ng/directive/ngBind.js index d4dd81fc9121..6be2dfd05fd2 100644 --- a/src/ng/directive/ngBind.js +++ b/src/ng/directive/ngBind.js @@ -51,23 +51,22 @@ */ -var ngBindDirective = ngDirective({ - compile: function ngBindCompile(templateElement) { - templateElement.addClass('ng-binding'); - - return function ngBindLink(scope, element, attr) { - element.data('$binding', attr.ngBind); - element = element[0]; - - scope.$watch(attr.ngBind, function ngBindWatchAction(value) { - // We are purposefully using == here rather than === because we want to - // catch when value is "null or undefined" - // jshint -W041 - element.textContent = (value == undefined ? '' : value); - }); - }; - } -}); +var ngBindDirective = ['$compile', function($compile) { + return { + restrict: 'AC', + compile: function(templateElement) { + return function (scope, element, attr) { + $compile.$$addBindingInfo(element, attr.ngBind); + scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 + element.text(value == undefined ? '' : value); + }); + }; + } + }; +}]; /** @@ -121,11 +120,10 @@ var ngBindDirective = ngDirective({ */ -var ngBindTemplateDirective = ['$interpolate', function($interpolate) { +var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) { return function(scope, element, attr) { - // TODO: move this to scenario runner var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate)); - element.addClass('ng-binding').data('$binding', interpolateFn); + $compile.$$addBindingInfo(element, interpolateFn); attr.$observe('ngBindTemplate', function(value) { element.text(value); }); @@ -178,14 +176,13 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { */ -var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { +var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) { return { restrict: 'A', - compile: function ngBindCompile(tElement, tAttrs) { - tElement.addClass('ng-binding'); + compile: function (tElement, tAttrs) { - return function ngBindLink(scope, element, attr) { - element.data('$binding', attr.ngBindHtml); + return function (scope, element, attr) { + $compile.$$addBindingInfo(element, attr.ngBindHtml); var ngBindHtmlGetter = $parse(attr.ngBindHtml); var ngBindHtmlWatch = $parse(attr.ngBindHtml, function getStringValue(value) { return (value || '').toString(); diff --git a/src/ngScenario/Scenario.js b/src/ngScenario/Scenario.js index 6cf69d84ce79..4f3199028e85 100644 --- a/src/ngScenario/Scenario.js +++ b/src/ngScenario/Scenario.js @@ -304,9 +304,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) { var element = windowJquery(this), bindings; if (bindings = element.data('$binding')) { - if (!angular.isArray(bindings)) { - bindings = [bindings]; - } + for(var expressions = [], binding, j=0, jj=bindings.length; j{{1+2}}')($rootScope); - expect(element.hasClass('ng-binding')).toBe(true); - expect(element.data('$binding')[0].exp).toEqual('{{1+2}}'); - })); + describe("decorating with binding info", function() { + + it('should not occur if `enableDebugInfo` has not been called', inject(function($compile, $rootScope) { + element = $compile('
{{1+2}}
')($rootScope); + expect(element.hasClass('ng-binding')).toBe(false); + expect(element.data('$binding')).toBeUndefined(); + })); + + + it('should occur if `enableDebugInfo` has been called', function() { + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + + inject( + function($compile, $rootScope) { + element = $compile('
{{1+2}}
')($rootScope); + expect(element.hasClass('ng-binding')).toBe(true); + expect(element.data('$binding')).toEqual(['1+2']); + }); + }); + }); it('should observe interpolated attrs', inject(function($rootScope, $compile) { $compile('
')($rootScope); diff --git a/test/ng/directive/ngBindSpec.js b/test/ng/directive/ngBindSpec.js index 704932b09085..646a5d806de8 100644 --- a/test/ng/directive/ngBindSpec.js +++ b/test/ng/directive/ngBindSpec.js @@ -3,6 +3,9 @@ describe('ngBind*', function() { var element; + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); afterEach(function() { dealoc(element); @@ -122,13 +125,6 @@ describe('ngBind*', function() { describe('ngBindHtml', function() { - it('should add ng-binding class to the element in compile phase', inject(function($compile) { - var element = jqLite('
'); - $compile(element); - expect(element.hasClass('ng-binding')).toBe(true); - })); - - describe('SCE disabled', function() { beforeEach(function() { module(function($sceProvider) { $sceProvider.enabled(false); }); diff --git a/test/ngScenario/dslSpec.js b/test/ngScenario/dslSpec.js index 80d4165bd9ef..e30c0e1ed92a 100644 --- a/test/ngScenario/dslSpec.js +++ b/test/ngScenario/dslSpec.js @@ -9,6 +9,10 @@ describe("angular.scenario.dsl", function() { dealoc(element); }); + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); + beforeEach(module('ngSanitize')); beforeEach(inject(function($injector) { From 9af0fa1d289e260090574ac65c3a4b21ea10f33a Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 23 Aug 2014 07:37:34 +0100 Subject: [PATCH 2/8] refact($compile): only add scope info if debugInfo is enabled --- src/ng/compile.js | 55 ++- test/AngularSpec.js | 2 +- test/ng/compileSpec.js | 496 +++++++++++++++++---------- test/ng/directive/formSpec.js | 6 + test/ng/directive/inputSpec.js | 2 + test/ng/directive/ngClassSpec.js | 28 +- test/ng/directive/ngIfSpec.js | 1 + test/ng/directive/ngIncludeSpec.js | 52 +-- test/ng/directive/ngInitSpec.js | 3 +- test/ng/directive/ngSwitchSpec.js | 53 +-- test/ngRoute/directive/ngViewSpec.js | 9 +- 11 files changed, 431 insertions(+), 276 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 4c827764cfd1..a86938662bb4 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -886,6 +886,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } }; + + function safeAddClass($element, className) { + try { + $element.addClass(className); + } catch(e) { + // ignore, since it means that we are trying to set class on + // SVG element, where class name is read-only. + } + } + + var startSymbol = $interpolate.startSymbol(), endSymbol = $interpolate.endSymbol(), denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}') @@ -895,17 +906,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }, NG_ATTR_BINDING = /^ngAttr[A-Z]/; + compile.$$addBindingInfo = enableDebugInfo ? function $$addBindingInfo(element, binding) { - element - .addClass('ng-binding') - .data('$binding', - (element.data('$binding') || []).concat(binding.expressions || [binding]) - ); + safeAddClass(element, 'ng-binding'); + element.data('$binding', (element.data('$binding') || []).concat(binding.expressions || [binding])); } : noop; compile.$$addScopeInfo = enableDebugInfo ? function $$addScopeInfo(element, scope, isolated, noTemplate) { - safeAddClass(isolated ? 'ng-isolate-scope' : 'ng-scope'); - element .data(noTemplate ? isolated ? '$isolateScopeNoTemplate' : '$isolateScope' : '$scope', scope); + safeAddClass(jqLite(element), isolated ? 'ng-isolate-scope' : 'ng-scope'); + var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope'; + element.data ? element.data(dataName, scope) : jqLite.data(element, dataName, scope); } : noop; return compile; @@ -929,9 +939,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); - safeAddClass($compileNodes, 'ng-scope'); - var namespace = null; + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){ + var namespace = null; assertArg(scope, 'scope'); if (!namespace) { namespace = detectNamespaceForChildElements(futureParentElement); @@ -954,7 +964,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } } - $linkNode.data('$scope', scope); + compile.$$addScopeInfo($linkNode, scope); if (cloneConnectFn) cloneConnectFn($linkNode, scope); if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); @@ -972,15 +982,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } } - function safeAddClass($element, className) { - try { - $element.addClass(className); - } catch(e) { - // ignore, since it means that we are trying to set class on - // SVG element, where class name is read-only. - } - } - /** * Compile function matches each node in nodeList against the directives. Once all directives * for a particular node are collected their compile functions are executed. The compile @@ -1013,10 +1014,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { null, [], [], previousCompileContext) : null; - if (nodeLinkFn && nodeLinkFn.scope) { - safeAddClass(attrs.$$element, 'ng-scope'); - } - childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !(childNodes = nodeList[i].childNodes) || !childNodes.length) @@ -1064,7 +1061,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (nodeLinkFn) { if (nodeLinkFn.scope) { childScope = scope.$new(); - jqLite.data(node, '$scope', childScope); + compile.$$addScopeInfo(node, childScope); } else { childScope = scope; } @@ -1565,14 +1562,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { isolateScope = scope.$new(true); - if (templateDirective && (templateDirective === newIsolateScopeDirective || - templateDirective === newIsolateScopeDirective.$$originalDirective)) { - $element.data('$isolateScope', isolateScope); - } else { - $element.data('$isolateScopeNoTemplate', isolateScope); - } - - + compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective || + templateDirective === newIsolateScopeDirective.$$originalDirective))); safeAddClass($element, 'ng-isolate-scope'); diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 42b2bbc48d8b..aa3a18cccb65 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -807,7 +807,7 @@ describe('angular', function() { expect(function () { angular.bootstrap(element); }).toThrowMatching( - /\[ng:btstrpd\] App Already Bootstrapped with this Element '<div class="?ng\-scope"?( ng[0-9]+="?[0-9]+"?)?>'/i + /\[ng:btstrpd\] App Already Bootstrapped with this Element '<div( class="?ng\-scope"?)?( ng[0-9]+="?[0-9]+"?)?>'/i ); dealoc(element); diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 524197bad660..b23d212a99b7 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -294,10 +294,15 @@ describe('$compile', function() { describe('compile phase', function() { - it('should attach scope to the document node when it is compiled explicitly', inject(function($document){ - $compile($document)($rootScope); - expect($document.scope()).toBe($rootScope); - })); + it('should attach scope to the document node when it is compiled explicitly', function() { + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + inject(function($document){ + $compile($document)($rootScope); + expect($document.scope()).toBe($rootScope); + }); + }); it('should wrap root text nodes in spans', inject(function($compile, $rootScope) { element = jqLite('
A<a>B</a>C
'); @@ -464,7 +469,7 @@ describe('$compile', function() { toEqual('
'); expect($exceptionHandler.errors[2][0]).toEqual('LinkingError'); expect(ie($exceptionHandler.errors[2][1])). - toEqual('
'); + toEqual('
'); // crazy stuff to make IE happy @@ -1981,7 +1986,10 @@ describe('$compile', function() { describe('scope', function() { var iscope; - beforeEach(module(function() { + beforeEach(module(function($compileProvider) { + + $compileProvider.enableDebugInfo(true); + forEach(['', 'a', 'b'], function(name) { directive('scope' + uppercase(name), function(log) { return { @@ -2088,11 +2096,18 @@ describe('$compile', function() { })); - it('should allow creation of new scopes', inject(function($rootScope, $compile, log) { - element = $compile('
')($rootScope); - expect(log).toEqual('2; log-2-1; LOG'); - expect(element.find('span').hasClass('ng-scope')).toBe(true); - })); + it('should allow creation of new scopes', function() { + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + + inject(function($rootScope, $compile, log) { + element = $compile('
')($rootScope); + expect(log).toEqual('2; log-2-1; LOG'); + expect(element.find('span').hasClass('ng-scope')).toBe(true); + }); + }); it('should allow creation of new isolated scopes for directives', inject( @@ -2232,6 +2247,10 @@ describe('$compile', function() { describe('scope()/isolate() scope getters', function() { + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); + describe('with no directives', function() { it('should return the scope of the parent node', inject( @@ -2493,11 +2512,18 @@ describe('$compile', function() { describe("decorating with binding info", function() { - it('should not occur if `enableDebugInfo` has not been called', inject(function($compile, $rootScope) { - element = $compile('
{{1+2}}
')($rootScope); - expect(element.hasClass('ng-binding')).toBe(false); - expect(element.data('$binding')).toBeUndefined(); - })); + it('should not occur if `enableDebugInfo` is falsy', function() { + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(false); + }); + + inject(function($compile, $rootScope) { + element = $compile('
{{1+2}}
')($rootScope); + expect(element.hasClass('ng-binding')).toBe(false); + expect(element.data('$binding')).toBeUndefined(); + }); + }); it('should occur if `enableDebugInfo` has been called', function() { @@ -2963,7 +2989,10 @@ describe('$compile', function() { describe('isolated locals', function() { var componentScope, regularScope; - beforeEach(module(function() { + beforeEach(module(function($compileProvider) { + + $compileProvider.enableDebugInfo(true); + directive('myComponent', function() { return { scope: { @@ -3483,6 +3512,11 @@ describe('$compile', function() { describe('controller', function() { + + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); + it('should get required controller', function() { module(function() { directive('main', function(log) { @@ -4246,12 +4280,17 @@ describe('$compile', function() { - it('should not leak if two "element" transclusions are on the same element', function () { + it('should not leak if two "element" transclusions are on the same element (with debug info)', function () { if (jQuery) { // jQuery 2.x doesn't expose the cache storage. return; } + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + inject(function($compile, $rootScope) { expect(jqLiteCacheSize()).toEqual(0); @@ -4273,12 +4312,48 @@ describe('$compile', function() { }); - it('should not leak if two "element" transclusions are on the same element', function () { + it('should not leak if two "element" transclusions are on the same element (without debug info)', function () { + if (jQuery) { + // jQuery 2.x doesn't expose the cache storage. + return; + } + + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(false); + }); + + inject(function($compile, $rootScope) { + expect(jqLiteCacheSize()).toEqual(0); + + element = $compile('
{{x}}
')($rootScope); + expect(jqLiteCacheSize()).toEqual(0); + + $rootScope.$apply('xs = [0,1]'); + expect(jqLiteCacheSize()).toEqual(0); + + $rootScope.$apply('xs = [0]'); + expect(jqLiteCacheSize()).toEqual(0); + + $rootScope.$apply('xs = []'); + expect(jqLiteCacheSize()).toEqual(0); + + element.remove(); + expect(jqLiteCacheSize()).toEqual(0); + }); + }); + + + it('should not leak if two "element" transclusions are on the same element (with debug info)', function () { if (jQuery) { // jQuery 2.x doesn't expose the cache storage. return; } + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + inject(function($compile, $rootScope) { expect(jqLiteCacheSize()).toEqual(0); element = $compile('
{{x}}
')($rootScope); @@ -4303,9 +4378,50 @@ describe('$compile', function() { }); }); + + it('should not leak if two "element" transclusions are on the same element (without debug info)', function () { + if (jQuery) { + // jQuery 2.x doesn't expose the cache storage. + return; + } + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(false); + }); + + inject(function($compile, $rootScope) { + expect(jqLiteCacheSize()).toEqual(0); + element = $compile('
{{x}}
')($rootScope); + + $rootScope.$apply('xs = [0,1]'); + // At this point we have a bunch of comment placeholders but no real transcluded elements + // So the cache only contains the root element's data + expect(jqLiteCacheSize()).toEqual(0); + + $rootScope.$apply('val = true'); + // Now we have two concrete transcluded elements plus some comments so two more cache items + expect(jqLiteCacheSize()).toEqual(0); + + $rootScope.$apply('val = false'); + // Once again we only have comments so no transcluded elements and the cache is back to just + // the root element + expect(jqLiteCacheSize()).toEqual(0); + + element.remove(); + // Now we've even removed the root element along with its cache + expect(jqLiteCacheSize()).toEqual(0); + }); + }); + + if (jQuery) { describe('cleaning up after a replaced element', function () { var $compile, xs; + + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); + beforeEach(inject(function (_$compile_) { $compile = _$compile_; xs = [0, 1]; @@ -4317,7 +4433,7 @@ describe('$compile', function() { element = $compile('
{{x}}
')($rootScope); $rootScope.$apply('xs = [' + xs + ']'); - firstRepeatedElem = element.children('.ng-scope').eq(0); + firstRepeatedElem = element.children().eq(0); expect(firstRepeatedElem.data('$scope')).toBeDefined(); privateData = jQuery._data(firstRepeatedElem[0]); @@ -5216,7 +5332,9 @@ describe('$compile', function() { })); }); inject(function($compile) { - element = $compile('
')($rootScope); + // We need to wrap the transclude directive's element in a parent element so that the + // cloned element gets deallocated/cleaned up correctly + element = $compile('
')($rootScope); expect(capturedTranscludeCtrl).toBeTruthy(); }); }); @@ -5918,175 +6036,187 @@ describe('$compile', function() { })); - it('should set up and destroy the transclusion scopes correctly', - inject(function($compile, $rootScope) { - element = $compile( - '
' + - '
' + - '
' + - '
' - )($rootScope); - $rootScope.$apply('val0 = true; val1 = true; val2 = true'); - - // At this point we should have something like: - // - //
- // - // - // - //
- // - // - // - //
- // - //
- // - // - // - //
- // - // - //
- var ngIfStartScope = element.find('div').eq(0).scope(); - var ngIfEndScope = element.find('div').eq(1).scope(); - - expect(ngIfStartScope.$id).toEqual(ngIfEndScope.$id); - - var ngIf1Scope = element.find('span').eq(0).scope(); - var ngIf2Scope = element.find('span').eq(1).scope(); - - expect(ngIf1Scope.$id).not.toEqual(ngIf2Scope.$id); - expect(ngIf1Scope.$parent.$id).toEqual(ngIf2Scope.$parent.$id); - - $rootScope.$apply('val1 = false'); - - // Now we should have something like: - // - //
- // - //
- // - //
- //
- // - // - // - //
- // - //
- - expect(ngIfStartScope.$$destroyed).not.toEqual(true); - expect(ngIf1Scope.$$destroyed).toEqual(true); - expect(ngIf2Scope.$$destroyed).not.toEqual(true); - - $rootScope.$apply('val0 = false'); - - // Now we should have something like: - // - //
- // - //
- - expect(ngIfStartScope.$$destroyed).toEqual(true); - expect(ngIf1Scope.$$destroyed).toEqual(true); - expect(ngIf2Scope.$$destroyed).toEqual(true); - })); - - - it('should set up and destroy the transclusion scopes correctly', - inject(function($compile, $rootScope) { - element = $compile( - '
' + - '
' + - '
' + - '
' - )($rootScope); - - // To begin with there is (almost) nothing: - //
- // - //
- - expect(element.scope().$id).toEqual($rootScope.$id); + it('should set up and destroy the transclusion scopes correctly', function() { - // Now we create all the elements - $rootScope.$apply('val0 = [1]; val1 = true; val2 = true'); - - // At this point we have: - // - //
- // - // - // - //
- //
- // - // - // - //
- //
- // - // - //
- var ngIf1Scope = element.find('div').eq(0).scope(); - var ngIf2Scope = element.find('div').eq(1).scope(); - var ngRepeatScope = ngIf1Scope.$parent; - - expect(ngIf1Scope.$id).not.toEqual(ngIf2Scope.$id); - expect(ngIf1Scope.$parent.$id).toEqual(ngRepeatScope.$id); - expect(ngIf2Scope.$parent.$id).toEqual(ngRepeatScope.$id); + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); - // What is happening here?? - // We seem to have a repeater scope which doesn't actually match to any element - expect(ngRepeatScope.$parent.$id).toEqual($rootScope.$id); + inject(function($compile, $rootScope) { + element = $compile( + '
' + + '
' + + '
' + + '
' + )($rootScope); + $rootScope.$apply('val0 = true; val1 = true; val2 = true'); + + // At this point we should have something like: + // + //
+ // + // + // + //
+ // + // + // + //
+ // + //
+ // + // + // + //
+ // + // + //
+ var ngIfStartScope = element.find('div').eq(0).scope(); + var ngIfEndScope = element.find('div').eq(1).scope(); + + expect(ngIfStartScope.$id).toEqual(ngIfEndScope.$id); + + var ngIf1Scope = element.find('span').eq(0).scope(); + var ngIf2Scope = element.find('span').eq(1).scope(); + + expect(ngIf1Scope.$id).not.toEqual(ngIf2Scope.$id); + expect(ngIf1Scope.$parent.$id).toEqual(ngIf2Scope.$parent.$id); + + $rootScope.$apply('val1 = false'); + + // Now we should have something like: + // + //
+ // + //
+ // + //
+ //
+ // + // + // + //
+ // + //
+ + expect(ngIfStartScope.$$destroyed).not.toEqual(true); + expect(ngIf1Scope.$$destroyed).toEqual(true); + expect(ngIf2Scope.$$destroyed).not.toEqual(true); + + $rootScope.$apply('val0 = false'); + + // Now we should have something like: + // + //
+ // + //
+ + expect(ngIfStartScope.$$destroyed).toEqual(true); + expect(ngIf1Scope.$$destroyed).toEqual(true); + expect(ngIf2Scope.$$destroyed).toEqual(true); + }); + }); - // Now remove the first ngIf element from the first item in the repeater - $rootScope.$apply('val1 = false'); + it('should set up and destroy the transclusion scopes correctly', function() { - // At this point we should have: - // - //
- // - // - // - // - // - //
- // - // - // - //
- // - expect(ngRepeatScope.$$destroyed).toEqual(false); - expect(ngIf1Scope.$$destroyed).toEqual(true); - expect(ngIf2Scope.$$destroyed).toEqual(false); + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); - // Now remove the second ngIf element from the first item in the repeater - $rootScope.$apply('val2 = false'); + inject(function($compile, $rootScope) { + element = $compile( + '
' + + '
' + + '
' + + '
' + )($rootScope); - // We are mostly back to where we started - // - //
- // - // - // - // - //
- - expect(ngRepeatScope.$$destroyed).toEqual(false); - expect(ngIf1Scope.$$destroyed).toEqual(true); - expect(ngIf2Scope.$$destroyed).toEqual(true); - - // Finally remove the repeat items - $rootScope.$apply('val0 = []'); - - // Somehow this ngRepeat scope knows how to destroy itself... - expect(ngRepeatScope.$$destroyed).toEqual(true); - expect(ngIf1Scope.$$destroyed).toEqual(true); - expect(ngIf2Scope.$$destroyed).toEqual(true); - })); + // To begin with there is (almost) nothing: + //
+ // + //
+ + expect(element.scope().$id).toEqual($rootScope.$id); + + // Now we create all the elements + $rootScope.$apply('val0 = [1]; val1 = true; val2 = true'); + + // At this point we have: + // + //
+ // + // + // + //
+ //
+ // + // + // + //
+ //
+ // + // + //
+ var ngIf1Scope = element.find('div').eq(0).scope(); + var ngIf2Scope = element.find('div').eq(1).scope(); + var ngRepeatScope = ngIf1Scope.$parent; + + expect(ngIf1Scope.$id).not.toEqual(ngIf2Scope.$id); + expect(ngIf1Scope.$parent.$id).toEqual(ngRepeatScope.$id); + expect(ngIf2Scope.$parent.$id).toEqual(ngRepeatScope.$id); + + // What is happening here?? + // We seem to have a repeater scope which doesn't actually match to any element + expect(ngRepeatScope.$parent.$id).toEqual($rootScope.$id); + + + // Now remove the first ngIf element from the first item in the repeater + $rootScope.$apply('val1 = false'); + + // At this point we should have: + // + //
+ // + // + // + // + // + //
+ // + // + // + //
+ // + expect(ngRepeatScope.$$destroyed).toEqual(false); + expect(ngIf1Scope.$$destroyed).toEqual(true); + expect(ngIf2Scope.$$destroyed).toEqual(false); + + // Now remove the second ngIf element from the first item in the repeater + $rootScope.$apply('val2 = false'); + + // We are mostly back to where we started + // + //
+ // + // + // + // + //
+ + expect(ngRepeatScope.$$destroyed).toEqual(false); + expect(ngIf1Scope.$$destroyed).toEqual(true); + expect(ngIf2Scope.$$destroyed).toEqual(true); + + // Finally remove the repeat items + $rootScope.$apply('val0 = []'); + + // Somehow this ngRepeat scope knows how to destroy itself... + expect(ngRepeatScope.$$destroyed).toEqual(true); + expect(ngIf1Scope.$$destroyed).toEqual(true); + expect(ngIf2Scope.$$destroyed).toEqual(true); + }); + }); it('should throw error if unterminated', function () { module(function($compileProvider) { diff --git a/test/ng/directive/formSpec.js b/test/ng/directive/formSpec.js index 21e21f3234dd..f9d7aecee909 100644 --- a/test/ng/directive/formSpec.js +++ b/test/ng/directive/formSpec.js @@ -15,6 +15,11 @@ describe('form', function() { }); })); + // Let's turn on the debugInfo so that we can use element.scope() + beforeEach(module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + })); + beforeEach(inject(function($injector, $sniffer) { $compile = $injector.get('$compile'); scope = $injector.get('$rootScope'); @@ -496,6 +501,7 @@ describe('form', function() { it('should chain nested forms in repeater', function() { + doc = jqLite( '' + '' + diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index a569dc5f3e6a..0975b55c099e 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -452,6 +452,8 @@ describe('ngModel', function() { expect(element).toBeInvalid(); expect(element).toHaveClass('ng-invalid-required'); + + dealoc(element); })); diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index e789d141440d..2475e9101305 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -39,9 +39,9 @@ describe('ngClass', function() { })); - it('should support adding multiple classes conditionally via a map of class names to boolean' + + it('should support adding multiple classes conditionally via a map of class names to boolean ' + 'expressions', inject(function($rootScope, $compile) { - var element = $compile( + element = $compile( '
' + '
')($rootScope); @@ -58,12 +58,13 @@ describe('ngClass', function() { expect(element.hasClass('A')).toBeTruthy(); expect(element.hasClass('B')).toBeTruthy(); expect(element.hasClass('AnotB')).toBeFalsy(); + })); it('should remove classes when the referenced object is the same but its property is changed', inject(function($rootScope, $compile) { - var element = $compile('
')($rootScope); + element = $compile('
')($rootScope); $rootScope.classes = { A: true, B: true }; $rootScope.$digest(); expect(element.hasClass('A')).toBeTruthy(); @@ -124,7 +125,7 @@ describe('ngClass', function() { $rootScope.$digest(); $rootScope.dynCls = 'foo'; $rootScope.$digest(); - expect(element[0].className).toBe('ui-panel ui-selected ng-scope foo'); + expect(element[0].className).toBe('ui-panel ui-selected foo'); })); @@ -132,7 +133,7 @@ describe('ngClass', function() { element = $compile('
')($rootScope); $rootScope.dynCls = 'panel'; $rootScope.$digest(); - expect(element[0].className).toBe('panel bar ng-scope'); + expect(element[0].className).toBe('panel bar'); })); @@ -142,7 +143,7 @@ describe('ngClass', function() { $rootScope.$digest(); $rootScope.dynCls = 'window'; $rootScope.$digest(); - expect(element[0].className).toBe('bar ng-scope window'); + expect(element[0].className).toBe('bar window'); })); @@ -153,7 +154,7 @@ describe('ngClass', function() { element.addClass('foo'); $rootScope.dynCls = ''; $rootScope.$digest(); - expect(element[0].className).toBe('ng-scope'); + expect(element[0].className).toBe(''); })); @@ -161,7 +162,7 @@ describe('ngClass', function() { element = $compile('
')($rootScope); $rootScope.dynCls = [undefined, null]; $rootScope.$digest(); - expect(element[0].className).toBe('ng-scope'); + expect(element[0].className).toBe(''); })); @@ -364,10 +365,14 @@ describe('ngClass', function() { describe('ngClass animations', function() { var body, element, $rootElement; + afterEach(function() { + dealoc(element); + }); + it("should avoid calling addClass accidentally when removeClass is going on", function() { module('ngAnimateMock'); inject(function($compile, $rootScope, $animate, $timeout) { - var element = angular.element('
'); + element = angular.element('
'); var body = jqLite(document.body); body.append(element); $compile(element)($rootScope); @@ -434,7 +439,7 @@ describe('ngClass animations', function() { digestQueue.shift()(); $rootScope.val = 'crazy'; - var element = angular.element('
'); + element = angular.element('
'); jqLite($document[0].body).append($rootElement); $compile(element)($rootScope); @@ -481,7 +486,7 @@ describe('ngClass animations', function() { $rootScope.two = true; $rootScope.three = true; - var element = angular.element('
'); + element = angular.element('
'); $compile(element)($rootScope); $rootScope.$digest(); @@ -511,6 +516,7 @@ describe('ngClass animations', function() { expect(item.args[2]).toBe('two'); expect($animate.queue.length).toBe(0); + }); }); }); diff --git a/test/ng/directive/ngIfSpec.js b/test/ng/directive/ngIfSpec.js index acbbb0627cc9..3c6a9f891802 100755 --- a/test/ng/directive/ngIfSpec.js +++ b/test/ng/directive/ngIfSpec.js @@ -5,6 +5,7 @@ describe('ngIf', function () { beforeEach(module(function(_$compileProvider_) { $compileProvider = _$compileProvider_; + $compileProvider.enableDebugInfo(true); })); beforeEach(inject(function ($rootScope, _$compile_) { $scope = $rootScope.$new(); diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index 828c6d2056fb..113e53785480 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -182,34 +182,42 @@ describe('ngInclude', function() { })); - it('should create child scope and destroy old one', inject( + it('should create child scope and destroy old one', function() { + + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); + + inject( function($rootScope, $compile, $httpBackend) { - $httpBackend.whenGET('url1').respond('partial {{$parent.url}}'); - $httpBackend.whenGET('url2').respond(404); + $httpBackend.whenGET('url1').respond('partial {{$parent.url}}'); + $httpBackend.whenGET('url2').respond(404); - element = $compile('
')($rootScope); - expect(element.children().scope()).toBeFalsy(); + element = $compile('
')($rootScope); + expect(element.children().scope()).toBeFalsy(); - $rootScope.url = 'url1'; - $rootScope.$digest(); - $httpBackend.flush(); - expect(element.children().scope().$parent).toBe($rootScope); - expect(element.text()).toBe('partial url1'); + $rootScope.url = 'url1'; + $rootScope.$digest(); + $httpBackend.flush(); + expect(element.children().scope().$parent).toBe($rootScope); + expect(element.text()).toBe('partial url1'); - $rootScope.url = 'url2'; - $rootScope.$digest(); - $httpBackend.flush(); - expect($rootScope.$$childHead).toBeFalsy(); - expect(element.text()).toBe(''); + $rootScope.url = 'url2'; + $rootScope.$digest(); + $httpBackend.flush(); + expect($rootScope.$$childHead).toBeFalsy(); + expect(element.text()).toBe(''); - $rootScope.url = 'url1'; - $rootScope.$digest(); - expect(element.children().scope().$parent).toBe($rootScope); + $rootScope.url = 'url1'; + $rootScope.$digest(); + expect(element.children().scope().$parent).toBe($rootScope); - $rootScope.url = null; - $rootScope.$digest(); - expect($rootScope.$$childHead).toBeFalsy(); - })); + $rootScope.url = null; + $rootScope.$digest(); + expect($rootScope.$$childHead).toBeFalsy(); + }); + + }); it('should do xhr request and cache it', diff --git a/test/ng/directive/ngInitSpec.js b/test/ng/directive/ngInitSpec.js index 9ed930ad39eb..2b6b2693390a 100644 --- a/test/ng/directive/ngInitSpec.js +++ b/test/ng/directive/ngInitSpec.js @@ -28,8 +28,9 @@ describe('ngInit', function() { it("should be evaluated after ngController", function() { - module(function($controllerProvider) { + module(function($controllerProvider, $compileProvider) { $controllerProvider.register('TestCtrl', function($scope) {}); + $compileProvider.enableDebugInfo(true); }); inject(function($rootScope, $compile) { element = $compile('
' + - '
{{name}}
' + - '')($rootScope); - $rootScope.$apply(); + it('should properly create and destroy child scopes', function() { - var getChildScope = function() { return element.find('div').scope(); }; + module(function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }); - expect(getChildScope()).toBeUndefined(); + inject(function($rootScope, $compile) { + element = $compile( + '' + + '
{{name}}
' + + '
')($rootScope); + $rootScope.$apply(); - $rootScope.url = 'a'; - $rootScope.$apply(); - var child1 = getChildScope(); - expect(child1).toBeDefined(); - spyOn(child1, '$destroy'); + var getChildScope = function() { return element.find('div').scope(); }; - $rootScope.url = 'x'; - $rootScope.$apply(); - expect(getChildScope()).toBeUndefined(); - expect(child1.$destroy).toHaveBeenCalled(); + expect(getChildScope()).toBeUndefined(); - $rootScope.url = 'a'; - $rootScope.$apply(); - var child2 = getChildScope(); - expect(child2).toBeDefined(); - expect(child2).not.toBe(child1); - })); + $rootScope.url = 'a'; + $rootScope.$apply(); + var child1 = getChildScope(); + expect(child1).toBeDefined(); + spyOn(child1, '$destroy'); + + $rootScope.url = 'x'; + $rootScope.$apply(); + expect(getChildScope()).toBeUndefined(); + expect(child1.$destroy).toHaveBeenCalled(); + + $rootScope.url = 'a'; + $rootScope.$apply(); + var child2 = getChildScope(); + expect(child2).toBeDefined(); + expect(child2).not.toBe(child1); + }); + }); it("should interoperate with other transclusion directives like ngRepeat", inject(function($rootScope, $compile) { diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js index 2aa286e85f5e..ab504169a5ca 100644 --- a/test/ngRoute/directive/ngViewSpec.js +++ b/test/ngRoute/directive/ngViewSpec.js @@ -103,9 +103,10 @@ describe('ngView', function() { it('should support string controller declaration', function() { var MyCtrl = jasmine.createSpy('MyCtrl'); - module(function($controllerProvider, $routeProvider) { + module(function($controllerProvider, $routeProvider, $compileProvider) { $controllerProvider.register('MyCtrl', ['$scope', MyCtrl]); $routeProvider.when('/foo', {controller: 'MyCtrl', templateUrl: '/tpl.html'}); + $compileProvider.enableDebugInfo(true); }); inject(function($route, $location, $rootScope, $templateCache) { @@ -489,8 +490,9 @@ describe('ngView', function() { $scope.ctrl = this; } - module(function($routeProvider) { + module(function($routeProvider, $compileProvider) { $routeProvider.when('/foo', {templateUrl: 'tpl.html', controller: MyCtrl}); + $compileProvider.enableDebugInfo(true); }); inject(function($templateCache, $location, $rootScope, $route) { @@ -517,8 +519,9 @@ describe('ngView', function() { it('should not set $scope or $controllerController on top level text elements in the view', function() { function MyCtrl($scope) {} - module(function($routeProvider) { + module(function($routeProvider, $compileProvider) { $routeProvider.when('/foo', {templateUrl: 'tpl.html', controller: MyCtrl}); + $compileProvider.enableDebugInfo(true); }); inject(function($templateCache, $location, $rootScope, $route) { From b1ac95ae879832b467a8471beba90f8fab03c686 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 23 Aug 2014 07:37:34 +0100 Subject: [PATCH 3/8] feat(Angular.js): add angular.reloadWithDebugInfo() method --- src/.jshintrc | 1 + src/Angular.js | 55 ++++++++++++++++++++++++++++++++++++++++++++ src/AngularPublic.js | 3 ++- test/AngularSpec.js | 20 ++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/.jshintrc b/src/.jshintrc index 87dd0638cf94..6b7190b12ff8 100644 --- a/src/.jshintrc +++ b/src/.jshintrc @@ -88,6 +88,7 @@ "getBlockNodes": false, "createMap": false, "VALIDITY_STATE_PROPERTY": false, + "reloadWithDebugInfo": false, "skipDestroyOnNextJQueryCleanData": true, diff --git a/src/Angular.js b/src/Angular.js index 6b7bd00c28a7..614fec2756d6 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1414,6 +1414,13 @@ function bootstrap(element, modules, config) { modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); + + if ( config.enableDebugInfo ) { + modules.unshift(['$compileProvider', function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }]); + } + modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', @@ -1427,8 +1434,14 @@ function bootstrap(element, modules, config) { return injector; }; + var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/; var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; + if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) { + config.enableDebugInfo = true; + window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, ''); + } + if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) { return doBootstrap(); } @@ -1442,6 +1455,48 @@ function bootstrap(element, modules, config) { }; } +/** + * @ngdoc function + * @name angular.reloadWithDebugInfo + * @module ng + * @description + * Use this function to reload the current application with debug information turned on. + * + * To significantly improve performance various debugging information is no longer added to + * the DOM by the compiler. The information that is not included is: + * + * * As a result of `ngBind`, `ngBindHtml` or `{{...}}` interpolations, binding data and CSS class + * `ng-class` is attached to the corresponding element. + * + * * Where the compiler has created a new scope, the scope and either `ng-scope` or `ng-isolated-scope` + * CSS class are attached to the corresponding element. These scope references can then be accessed via + * `element.scope()` and `element.isolateScope()`. + * + * If you wish to debug an application via this information then you should open up a debug + * console in the browser then call this method directly in this console: + * + * ```js + * angular.reloadWithDebugInfo(); + * ``` + * + * The page should reload and the debug information should now be available. + * + * If you want to include this debug information in your application all the time then you + * can turn it on in a configuration block. + * + * ```js + * appModule.config(['$compileProvider', function($compileProvider) { + * $compileProvider.enableDebugInfo(true); + * }]); + * ``` + * + * See {@link $compileProvider}. + */ +function reloadWithDebugInfo(doReload) { + window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name; + if ( doReload !== false ) window.location.reload(); +} + var SNAKE_CASE_REGEXP = /[A-Z]/g; function snake_case(name, separator) { separator = separator || '_'; diff --git a/src/AngularPublic.js b/src/AngularPublic.js index e859a0da7577..a0a61b727b39 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -136,7 +136,8 @@ function publishExternalAPI(angular){ 'uppercase': uppercase, 'callbacks': {counter: 0}, '$$minErr': minErr, - '$$csp': csp + '$$csp': csp, + 'reloadWithDebugInfo': reloadWithDebugInfo }); angularModule = setupModuleLoader(window); diff --git a/test/AngularSpec.js b/test/AngularSpec.js index aa3a18cccb65..2f546460fb14 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -1099,6 +1099,26 @@ describe('angular', function() { }); + describe("reloadWithDebugInfo", function() { + + it("should reload the current page with debugInfo turned on", function() { + + element = jqLite('
{{1+2}}
'); + angular.bootstrap(element); + expect(element.hasClass('ng-scope')).toBe(false); + dealoc(element); + + // We pass the false to prevent the page actually reloading + angular.reloadWithDebugInfo(false); + + element = jqLite('
{{1+2}}
'); + angular.bootstrap(element); + expect(element.hasClass('ng-scope')).toBe(true); + dealoc(element); + }); + }); + + describe('startingElementHtml', function(){ it('should show starting element tag only', function(){ expect(startingTag('
text
')). From 61131ebc66e4bc19ada14bc394324846a3439ce8 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 23 Aug 2014 20:45:44 +0100 Subject: [PATCH 4/8] chore(clean-shrinkwrap): chokidar is fixed since 0.8.2 --- scripts/clean-shrinkwrap.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/clean-shrinkwrap.js b/scripts/clean-shrinkwrap.js index 66326f4f2fca..c46fe295da6b 100755 --- a/scripts/clean-shrinkwrap.js +++ b/scripts/clean-shrinkwrap.js @@ -23,9 +23,6 @@ function cleanModule(module, name) { if (name === 'chokidar') { if (module.version === '0.8.1') { delete module.dependencies; - } else if ( module.version !== '0.8.2') { - throw new Error("Unfamiliar chokidar version (v" + module.version + - ") , please check status of https://github.com/paulmillr/chokidar/pull/106"); } } From 94ad909c54323248e91f21cf1a9699630a29365e Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 23 Aug 2014 20:48:14 +0100 Subject: [PATCH 5/8] chore(package.json): reorder devDependencies into alphabetic order --- package.json | 53 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index e86ec044616d..5e317a2decf6 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,19 @@ "url": "https://github.com/angular/angular.js.git" }, "devDependencies": { + "angular-benchpress": "0.x.x", + "benchmark": "^1.0.0", + "bower": "~1.2.2", + "browserstacktunnel-wrapper": "~1.1.1", + "canonical-path": "0.0.2", + "dgeni": "^0.3.0", + "dgeni-packages": "^0.9.7", + "event-stream": "~3.1.0", "grunt": "~0.4.2", "grunt-bump": "~0.0.13", "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-connect": "~0.5.0", "grunt-contrib-compress": "~0.5.2", + "grunt-contrib-connect": "~0.5.0", "grunt-contrib-copy": "~0.4.1", "grunt-contrib-jshint": "~0.10.0", "grunt-ddescribe-iit": "~0.0.1", @@ -19,42 +27,35 @@ "grunt-merge-conflict": "~0.0.1", "grunt-parallel": "~0.3.1", "grunt-shell": "~0.4.0", - "load-grunt-tasks": "~0.3.0", - "bower": "~1.2.2", + "gulp": "~3.4.0", + "gulp-concat": "~2.1.7", + "gulp-jshint": "~1.4.2", "jasmine-node": "~1.11.0", - "q": "~1.0.0", - "shelljs": "~0.2.6", + "jasmine-reporters": "~0.2.1", + "jshint-stylish": "~0.1.5", "karma": "^0.12.0", - "karma-jasmine": "0.1.5", + "karma-browserstack-launcher": "0.0.7", "karma-chrome-launcher": "0.1.2", "karma-firefox-launcher": "0.1.3", - "karma-ng-scenario": "0.1.0", + "karma-jasmine": "0.1.5", "karma-junit-reporter": "0.2.1", + "karma-ng-scenario": "0.1.0", "karma-sauce-launcher": "0.2.0", "karma-script-launcher": "0.1.0", - "karma-browserstack-launcher": "0.0.7", - "protractor": "1.0.0", - "yaml-js": "~0.0.8", - "rewire": "1.1.3", - "promises-aplus-tests": "~2.0.4", - "semver": "~2.1.0", + "load-grunt-tasks": "~0.3.0", "lodash": "~2.1.0", - "browserstacktunnel-wrapper": "~1.1.1", - "jasmine-reporters": "~0.2.1", - "gulp": "~3.4.0", - "event-stream": "~3.1.0", "marked": "~0.3.0", - "gulp-concat": "~2.1.7", - "canonical-path": "0.0.2", - "winston": "~0.7.2", - "dgeni": "^0.3.0", - "dgeni-packages": "^0.9.7", - "gulp-jshint": "~1.4.2", - "jshint-stylish": "~0.1.5", "node-html-encoder": "0.0.2", - "sorted-object": "^1.0.0", + "promises-aplus-tests": "~2.0.4", + "protractor": "1.0.0", + "q": "~1.0.0", "qq": "^0.3.5", - "angular-benchpress": "0.x.x" + "rewire": "1.1.3", + "semver": "~2.1.0", + "shelljs": "~0.2.6", + "sorted-object": "^1.0.0", + "winston": "~0.7.2", + "yaml-js": "~0.0.8" }, "licenses": [ { From f33a10d9d9493abaa0b005685e27e371a94c16a9 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Mon, 25 Aug 2014 08:27:56 +0100 Subject: [PATCH 6/8] chore(package.json): update to Protractor 1.1.1 --- npm-shrinkwrap.json | 1182 +++++++++++++++++++++++++++++++------------ package.json | 2 +- 2 files changed, 868 insertions(+), 316 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d057b17689ef..5732183e2d2e 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -253,14 +253,6 @@ "chokidar": { "version": "0.8.4", "dependencies": { - "fsevents": { - "version": "0.2.1", - "dependencies": { - "nan": { - "version": "0.8.0" - } - } - }, "recursive-readdir": { "version": "0.0.2" } @@ -492,20 +484,23 @@ } } }, + "benchmark": { + "version": "1.0.0" + }, "bower": { "version": "1.2.8", "dependencies": { "abbrev": { - "version": "1.0.4" + "version": "1.0.5" }, "archy": { "version": "0.0.2" }, "bower-config": { - "version": "0.5.0", + "version": "0.5.2", "dependencies": { "mout": { - "version": "0.6.0" + "version": "0.9.1" }, "optimist": { "version": "0.6.1", @@ -514,20 +509,20 @@ "version": "0.0.2" }, "minimist": { - "version": "0.0.8" + "version": "0.0.10" } } } } }, "bower-endpoint-parser": { - "version": "0.2.1" + "version": "0.2.2" }, "bower-json": { "version": "0.4.0", "dependencies": { "deep-extend": { - "version": "0.2.8" + "version": "0.2.11" }, "intersect": { "version": "0.0.3" @@ -556,7 +551,7 @@ "version": "0.0.2" }, "minimist": { - "version": "0.0.8" + "version": "0.0.10" } } } @@ -587,7 +582,7 @@ "version": "0.2.1", "dependencies": { "has-color": { - "version": "0.1.4" + "version": "0.1.7" }, "ansi-styles": { "version": "0.2.0" @@ -598,8 +593,11 @@ "version": "0.1.0" }, "decompress-zip": { - "version": "0.0.4", + "version": "0.0.8", "dependencies": { + "q": { + "version": "1.0.1" + }, "mkpath": { "version": "0.1.0" }, @@ -628,63 +626,83 @@ } }, "readable-stream": { - "version": "1.1.11", + "version": "1.1.13-1", "dependencies": { "core-util-is": { "version": "1.0.1" }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" }, - "debuglog": { - "version": "0.0.2" + "inherits": { + "version": "2.0.1" } } + }, + "nopt": { + "version": "2.2.1" + }, + "graceful-fs": { + "version": "3.0.2" } } }, "fstream": { - "version": "0.1.25", + "version": "0.1.31", "dependencies": { + "graceful-fs": { + "version": "3.0.2" + }, "inherits": { "version": "2.0.1" + }, + "mkdirp": { + "version": "0.5.0", + "dependencies": { + "minimist": { + "version": "0.0.8" + } + } } } }, "fstream-ignore": { - "version": "0.0.7", + "version": "0.0.10", "dependencies": { + "inherits": { + "version": "2.0.1" + }, "minimatch": { - "version": "0.2.14", + "version": "0.3.0", "dependencies": { "sigmund": { "version": "1.0.0" } } - }, - "inherits": { - "version": "2.0.1" } } }, "glob": { - "version": "3.2.9", + "version": "3.2.11", "dependencies": { + "inherits": { + "version": "2.0.1" + }, "minimatch": { - "version": "0.2.14", + "version": "0.3.0", "dependencies": { "sigmund": { "version": "1.0.0" } } - }, - "inherits": { - "version": "2.0.1" } } }, "graceful-fs": { - "version": "2.0.2" + "version": "2.0.3" }, "handlebars": { "version": "1.0.12", @@ -704,7 +722,7 @@ "version": "0.2.10" }, "source-map": { - "version": "0.1.32", + "version": "0.1.38", "dependencies": { "amdefine": { "version": "0.1.0" @@ -764,7 +782,7 @@ "version": "2.3.1" }, "open": { - "version": "0.0.4" + "version": "0.0.5" }, "osenv": { "version": "0.0.3" @@ -847,10 +865,10 @@ "version": "1.2.11" }, "form-data": { - "version": "0.1.2", + "version": "0.1.4", "dependencies": { "combined-stream": { - "version": "0.0.4", + "version": "0.0.5", "dependencies": { "delayed-stream": { "version": "0.0.5" @@ -858,7 +876,7 @@ } }, "async": { - "version": "0.2.10" + "version": "0.9.0" } } } @@ -873,10 +891,10 @@ } }, "retry": { - "version": "0.6.0" + "version": "0.6.1" }, "rimraf": { - "version": "2.2.6" + "version": "2.2.8" }, "stringify-object": { "version": "0.1.8" @@ -888,7 +906,7 @@ "version": "0.1.1", "dependencies": { "has-color": { - "version": "0.1.4" + "version": "0.1.7" }, "ansi-styles": { "version": "0.1.2" @@ -898,30 +916,44 @@ } }, "tar": { - "version": "0.1.19", + "version": "0.1.20", "dependencies": { - "inherits": { - "version": "2.0.1" - }, "block-stream": { "version": "0.0.7" + }, + "inherits": { + "version": "2.0.1" } } }, "tmp": { - "version": "0.0.23" + "version": "0.0.24" }, "update-notifier": { - "version": "0.1.7", + "version": "0.1.10", "dependencies": { + "chalk": { + "version": "0.4.0", + "dependencies": { + "has-color": { + "version": "0.1.7" + }, + "ansi-styles": { + "version": "1.0.0" + }, + "strip-ansi": { + "version": "0.1.1" + } + } + }, "configstore": { - "version": "0.1.7", + "version": "0.3.1", "dependencies": { - "lodash": { - "version": "2.4.1" + "graceful-fs": { + "version": "3.0.2" }, "js-yaml": { - "version": "2.1.3", + "version": "3.0.2", "dependencies": { "argparse": { "version": "0.1.15", @@ -938,8 +970,118 @@ "version": "1.0.4" } } + }, + "mkdirp": { + "version": "0.5.0", + "dependencies": { + "minimist": { + "version": "0.0.8" + } + } + }, + "object-assign": { + "version": "0.3.1" + }, + "osenv": { + "version": "0.1.0" + }, + "uuid": { + "version": "1.4.1" + } + } + }, + "request": { + "version": "2.40.0", + "dependencies": { + "qs": { + "version": "1.0.2" + }, + "json-stringify-safe": { + "version": "5.0.0" + }, + "mime-types": { + "version": "1.0.2" + }, + "forever-agent": { + "version": "0.5.2" + }, + "node-uuid": { + "version": "1.4.1" + }, + "tough-cookie": { + "version": "0.12.1", + "dependencies": { + "punycode": { + "version": "1.3.1" + } + } + }, + "form-data": { + "version": "0.1.4", + "dependencies": { + "combined-stream": { + "version": "0.0.5", + "dependencies": { + "delayed-stream": { + "version": "0.0.5" + } + } + }, + "mime": { + "version": "1.2.11" + }, + "async": { + "version": "0.9.0" + } + } + }, + "tunnel-agent": { + "version": "0.4.0" + }, + "http-signature": { + "version": "0.10.0", + "dependencies": { + "assert-plus": { + "version": "0.1.2" + }, + "asn1": { + "version": "0.1.11" + }, + "ctype": { + "version": "0.5.2" + } + } + }, + "oauth-sign": { + "version": "0.3.0" + }, + "hawk": { + "version": "1.1.1", + "dependencies": { + "hoek": { + "version": "0.9.1" + }, + "boom": { + "version": "0.4.2" + }, + "cryptiles": { + "version": "0.2.2" + }, + "sntp": { + "version": "0.2.4" + } + } + }, + "aws-sign2": { + "version": "0.5.0" + }, + "stringstream": { + "version": "0.0.4" } } + }, + "semver": { + "version": "2.3.2" } } }, @@ -1258,7 +1400,7 @@ "version": "0.5.0", "dependencies": { "rimraf": { - "version": "2.2.6" + "version": "2.2.8" } } }, @@ -1269,10 +1411,19 @@ "version": "0.4.10", "dependencies": { "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } }, @@ -1285,10 +1436,19 @@ "version": "0.1.0", "dependencies": { "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } } @@ -1341,7 +1501,12 @@ "version": "0.0.1" }, "debug": { - "version": "0.7.4" + "version": "1.0.4", + "dependencies": { + "ms": { + "version": "0.6.2" + } + } } } }, @@ -1360,7 +1525,7 @@ "version": "0.10.0", "dependencies": { "jshint": { - "version": "2.5.2", + "version": "2.5.3", "dependencies": { "shelljs": { "version": "0.3.0" @@ -1376,13 +1541,24 @@ "dependencies": { "inherits": { "version": "2.0.1" + }, + "minimatch": { + "version": "0.3.0", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } } } } } }, "minimatch": { - "version": "0.3.0", + "version": "0.4.0", "dependencies": { "lru-cache": { "version": "2.5.0" @@ -1393,7 +1569,7 @@ } }, "htmlparser2": { - "version": "3.7.2", + "version": "3.7.3", "dependencies": { "domhandler": { "version": "2.2.0" @@ -1452,7 +1628,7 @@ }, "grunt-jasmine-node": { "version": "0.1.0", - "from": "grunt-jasmine-node@git://github.com/vojtajina/grunt-jasmine-node.git#ced17cbe52c1412b2ada53160432a5b681f37cd7", + "from": "grunt-jasmine-node@git://github.com/vojtajina/grunt-jasmine-node.git#fix-grunt-exit-code", "resolved": "git://github.com/vojtajina/grunt-jasmine-node.git#ced17cbe52c1412b2ada53160432a5b681f37cd7" }, "grunt-jscs-checker": { @@ -1664,27 +1840,49 @@ "version": "0.0.2" }, "minimist": { - "version": "0.0.8" + "version": "0.0.10" } } }, "gulp-util": { - "version": "2.2.14", + "version": "2.2.20", "dependencies": { "chalk": { - "version": "0.4.0", + "version": "0.5.1", "dependencies": { - "has-color": { - "version": "0.1.4" - }, "ansi-styles": { - "version": "1.0.0" + "version": "1.1.0" + }, + "escape-string-regexp": { + "version": "1.0.1" + }, + "has-ansi": { + "version": "0.1.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } }, "strip-ansi": { - "version": "0.1.1" + "version": "0.3.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } + }, + "supports-color": { + "version": "0.2.0" } } }, + "dateformat": { + "version": "1.0.8-1.2.3" + }, + "lodash._reinterpolate": { + "version": "2.4.1" + }, "lodash.template": { "version": "2.4.1", "dependencies": { @@ -1752,73 +1950,104 @@ } } }, - "lodash._reinterpolate": { - "version": "2.4.1" - }, - "vinyl": { - "version": "0.2.3", + "minimist": { + "version": "0.2.0" + }, + "multipipe": { + "version": "0.1.1", "dependencies": { - "clone-stats": { - "version": "0.0.1" + "duplexer2": { + "version": "0.0.2", + "dependencies": { + "readable-stream": { + "version": "1.1.13-1", + "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "string_decoder": { + "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" + } + } + } + } } } }, "through2": { - "version": "0.4.1", + "version": "0.5.1", "dependencies": { "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } }, "xtend": { - "version": "2.1.2", - "dependencies": { - "object-keys": { - "version": "0.4.0" - } - } + "version": "3.0.0" } } }, - "dateformat": { - "version": "1.0.7-1.2.3" - }, - "multipipe": { - "version": "0.0.2", + "vinyl": { + "version": "0.2.3", "dependencies": { - "duplexer2": { + "clone-stats": { "version": "0.0.1" } } - }, - "minimist": { - "version": "0.0.8" } } }, "orchestrator": { - "version": "0.3.3", + "version": "0.3.7", "dependencies": { + "end-of-stream": { + "version": "0.1.5", + "dependencies": { + "once": { + "version": "1.3.0" + } + } + }, "sequencify": { "version": "0.0.7" + }, + "stream-consume": { + "version": "0.1.0" } } }, "resolve": { - "version": "0.6.1" + "version": "0.6.3" }, "findup-sync": { - "version": "0.1.2", + "version": "0.1.3", "dependencies": { "glob": { - "version": "3.1.21", + "version": "3.2.11", "dependencies": { + "inherits": { + "version": "2.0.1" + }, "minimatch": { - "version": "0.2.14", + "version": "0.3.0", "dependencies": { "lru-cache": { "version": "2.5.0" @@ -1827,22 +2056,16 @@ "version": "1.0.0" } } - }, - "graceful-fs": { - "version": "1.2.3" - }, - "inherits": { - "version": "1.0.0" } } }, "lodash": { - "version": "1.0.1" + "version": "2.4.1" } } }, "pretty-hrtime": { - "version": "0.2.0" + "version": "0.2.1" }, "vinyl-fs": { "version": "0.0.1", @@ -1856,18 +2079,35 @@ } }, "glob-stream": { - "version": "3.1.9", + "version": "3.1.14", "dependencies": { "glob": { - "version": "3.2.9", + "version": "4.0.5", "dependencies": { "inherits": { "version": "2.0.1" + }, + "minimatch": { + "version": "1.0.0", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } + }, + "once": { + "version": "1.3.0" + }, + "graceful-fs": { + "version": "3.0.2" } } }, "minimatch": { - "version": "0.2.14", + "version": "0.3.0", "dependencies": { "lru-cache": { "version": "2.5.0" @@ -1878,24 +2118,193 @@ } }, "ordered-read-streams": { - "version": "0.0.7" + "version": "0.0.8" }, "glob2base": { - "version": "0.0.8" + "version": "0.0.9", + "dependencies": { + "lodash.findindex": { + "version": "2.4.1", + "dependencies": { + "lodash.createcallback": { + "version": "2.4.1", + "dependencies": { + "lodash._basecreatecallback": { + "version": "2.4.1", + "dependencies": { + "lodash.bind": { + "version": "2.4.1", + "dependencies": { + "lodash._createwrapper": { + "version": "2.4.1", + "dependencies": { + "lodash._basebind": { + "version": "2.4.1", + "dependencies": { + "lodash._basecreate": { + "version": "2.4.1", + "dependencies": { + "lodash._isnative": { + "version": "2.4.1" + }, + "lodash.noop": { + "version": "2.4.1" + } + } + } + } + }, + "lodash._basecreatewrapper": { + "version": "2.4.1", + "dependencies": { + "lodash._basecreate": { + "version": "2.4.1", + "dependencies": { + "lodash._isnative": { + "version": "2.4.1" + }, + "lodash.noop": { + "version": "2.4.1" + } + } + } + } + }, + "lodash.isfunction": { + "version": "2.4.1" + } + } + }, + "lodash._slice": { + "version": "2.4.1" + } + } + }, + "lodash.identity": { + "version": "2.4.1" + }, + "lodash._setbinddata": { + "version": "2.4.1", + "dependencies": { + "lodash._isnative": { + "version": "2.4.1" + }, + "lodash.noop": { + "version": "2.4.1" + } + } + }, + "lodash.support": { + "version": "2.4.1", + "dependencies": { + "lodash._isnative": { + "version": "2.4.1" + } + } + } + } + }, + "lodash._baseisequal": { + "version": "2.4.1", + "dependencies": { + "lodash.forin": { + "version": "2.4.1" + }, + "lodash._getarray": { + "version": "2.4.1", + "dependencies": { + "lodash._arraypool": { + "version": "2.4.1" + } + } + }, + "lodash.isfunction": { + "version": "2.4.1" + }, + "lodash._objecttypes": { + "version": "2.4.1" + }, + "lodash._releasearray": { + "version": "2.4.1", + "dependencies": { + "lodash._arraypool": { + "version": "2.4.1" + }, + "lodash._maxpoolsize": { + "version": "2.4.1" + } + } + } + } + }, + "lodash.isobject": { + "version": "2.4.1", + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1" + } + } + }, + "lodash.keys": { + "version": "2.4.1", + "dependencies": { + "lodash._isnative": { + "version": "2.4.1" + }, + "lodash._shimkeys": { + "version": "2.4.1", + "dependencies": { + "lodash._objecttypes": { + "version": "2.4.1" + } + } + } + } + }, + "lodash.property": { + "version": "2.4.1" + } + } + } + } + } + } }, "unique-stream": { - "version": "0.0.3" + "version": "1.0.0" }, - "through": { - "version": "2.3.4" + "through2": { + "version": "0.5.1", + "dependencies": { + "readable-stream": { + "version": "1.0.27-1", + "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "string_decoder": { + "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" + } + } + }, + "xtend": { + "version": "3.0.0" + } + } } } }, "glob-watcher": { - "version": "0.0.3", + "version": "0.0.6", "dependencies": { "gaze": { - "version": "0.4.3", + "version": "0.5.1", "dependencies": { "globule": { "version": "0.1.0", @@ -1935,7 +2344,7 @@ "version": "0.3.5" }, "graceful-fs": { - "version": "2.0.2" + "version": "2.0.3" }, "map-stream": { "version": "0.1.0" @@ -1957,22 +2366,44 @@ "version": "2.3.4" }, "gulp-util": { - "version": "2.2.14", + "version": "2.2.20", "dependencies": { "chalk": { - "version": "0.4.0", + "version": "0.5.1", "dependencies": { - "has-color": { - "version": "0.1.4" - }, "ansi-styles": { - "version": "1.0.0" + "version": "1.1.0" + }, + "escape-string-regexp": { + "version": "1.0.1" + }, + "has-ansi": { + "version": "0.1.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } }, "strip-ansi": { - "version": "0.1.1" + "version": "0.3.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } + }, + "supports-color": { + "version": "0.2.0" } } }, + "dateformat": { + "version": "1.0.8-1.2.3" + }, + "lodash._reinterpolate": { + "version": "2.4.1" + }, "lodash.template": { "version": "2.4.1", "dependencies": { @@ -2040,51 +2471,68 @@ } } }, - "lodash._reinterpolate": { - "version": "2.4.1" + "minimist": { + "version": "0.2.0" }, - "vinyl": { - "version": "0.2.3", + "multipipe": { + "version": "0.1.1", "dependencies": { - "clone-stats": { - "version": "0.0.1" + "duplexer2": { + "version": "0.0.2", + "dependencies": { + "readable-stream": { + "version": "1.1.13-1", + "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "string_decoder": { + "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" + } + } + } + } } } }, "through2": { - "version": "0.4.1", + "version": "0.5.1", "dependencies": { "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } }, "xtend": { - "version": "2.1.2", - "dependencies": { - "object-keys": { - "version": "0.4.0" - } - } + "version": "3.0.0" } } }, - "dateformat": { - "version": "1.0.7-1.2.3" - }, - "multipipe": { - "version": "0.0.2", + "vinyl": { + "version": "0.2.3", "dependencies": { - "duplexer2": { + "clone-stats": { "version": "0.0.1" } } - }, - "minimist": { - "version": "0.0.8" } } } @@ -2109,17 +2557,34 @@ "version": "0.4.5", "dependencies": { "glob": { - "version": "3.2.9", + "version": "4.0.5", "dependencies": { "inherits": { "version": "2.0.1" + }, + "minimatch": { + "version": "1.0.0", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } + }, + "once": { + "version": "1.3.0" + }, + "graceful-fs": { + "version": "3.0.2" } } } } }, "minimatch": { - "version": "0.2.14", + "version": "0.4.0", "dependencies": { "lru-cache": { "version": "2.5.0" @@ -2142,10 +2607,19 @@ "version": "1.1.1" }, "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } } @@ -2160,22 +2634,44 @@ } }, "gulp-util": { - "version": "2.2.14", + "version": "2.2.20", "dependencies": { "chalk": { - "version": "0.4.0", + "version": "0.5.1", "dependencies": { - "has-color": { - "version": "0.1.4" - }, "ansi-styles": { - "version": "1.0.0" + "version": "1.1.0" + }, + "escape-string-regexp": { + "version": "1.0.1" + }, + "has-ansi": { + "version": "0.1.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } }, "strip-ansi": { - "version": "0.1.1" + "version": "0.3.0", + "dependencies": { + "ansi-regex": { + "version": "0.2.1" + } + } + }, + "supports-color": { + "version": "0.2.0" } } }, + "dateformat": { + "version": "1.0.8-1.2.3" + }, + "lodash._reinterpolate": { + "version": "2.4.1" + }, "lodash.template": { "version": "2.4.1", "dependencies": { @@ -2243,51 +2739,68 @@ } } }, - "lodash._reinterpolate": { - "version": "2.4.1" + "minimist": { + "version": "0.2.0" }, - "vinyl": { - "version": "0.2.3", + "multipipe": { + "version": "0.1.1", "dependencies": { - "clone-stats": { - "version": "0.0.1" + "duplexer2": { + "version": "0.0.2", + "dependencies": { + "readable-stream": { + "version": "1.1.13-1", + "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "string_decoder": { + "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" + } + } + } + } } } }, "through2": { - "version": "0.4.1", + "version": "0.5.1", "dependencies": { "readable-stream": { - "version": "1.0.26", + "version": "1.0.27-1", "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, "string_decoder": { "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" } } }, "xtend": { - "version": "2.1.2", - "dependencies": { - "object-keys": { - "version": "0.4.0" - } - } + "version": "3.0.0" } } }, - "dateformat": { - "version": "1.0.7-1.2.3" - }, - "multipipe": { - "version": "0.0.2", + "vinyl": { + "version": "0.2.3", "dependencies": { - "duplexer2": { + "clone-stats": { "version": "0.0.1" } } - }, - "minimist": { - "version": "0.0.8" } } }, @@ -2480,7 +2993,7 @@ "version": "1.7.1" }, "jasmine-growl-reporter": { - "version": "0.0.2", + "version": "0.0.3", "dependencies": { "growl": { "version": "1.7.0" @@ -2488,7 +3001,7 @@ } }, "requirejs": { - "version": "2.1.11" + "version": "2.1.14" }, "walkdir": { "version": "0.0.7" @@ -2514,10 +3027,21 @@ "version": "0.1.5", "dependencies": { "glob": { - "version": "3.2.9", + "version": "3.2.11", "dependencies": { "inherits": { "version": "2.0.1" + }, + "minimatch": { + "version": "0.3.0", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } } } } @@ -2540,7 +3064,7 @@ "version": "0.4.0", "dependencies": { "has-color": { - "version": "0.1.4" + "version": "0.1.7" }, "ansi-styles": { "version": "1.0.0" @@ -2861,19 +3385,132 @@ "version": "0.2.0", "dependencies": { "wd": { - "version": "0.2.10", + "version": "0.2.27", "dependencies": { + "archiver": { + "version": "0.10.1", + "dependencies": { + "buffer-crc32": { + "version": "0.2.3" + }, + "readable-stream": { + "version": "1.0.27-1", + "dependencies": { + "core-util-is": { + "version": "1.0.1" + }, + "isarray": { + "version": "0.0.1" + }, + "string_decoder": { + "version": "0.10.25-1" + }, + "inherits": { + "version": "2.0.1" + } + } + }, + "tar-stream": { + "version": "0.4.4", + "dependencies": { + "bl": { + "version": "0.8.2" + }, + "end-of-stream": { + "version": "0.1.5", + "dependencies": { + "once": { + "version": "1.3.0" + } + } + }, + "xtend": { + "version": "3.0.0" + } + } + }, + "zip-stream": { + "version": "0.3.7", + "dependencies": { + "crc32-stream": { + "version": "0.2.0" + }, + "debug": { + "version": "1.0.4", + "dependencies": { + "ms": { + "version": "0.6.2" + } + } + }, + "deflate-crc32-stream": { + "version": "0.1.1" + } + } + }, + "lazystream": { + "version": "0.1.0" + }, + "file-utils": { + "version": "0.2.0", + "dependencies": { + "iconv-lite": { + "version": "0.2.11" + }, + "rimraf": { + "version": "2.2.8" + }, + "glob": { + "version": "3.2.11", + "dependencies": { + "inherits": { + "version": "2.0.1" + }, + "minimatch": { + "version": "0.3.0", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } + } + } + }, + "minimatch": { + "version": "0.2.14", + "dependencies": { + "lru-cache": { + "version": "2.5.0" + }, + "sigmund": { + "version": "1.0.0" + } + } + }, + "findup-sync": { + "version": "0.1.3" + }, + "isbinaryfile": { + "version": "2.0.1" + } + } + } + } + }, "async": { - "version": "0.2.10" + "version": "0.9.0" }, - "vargs": { - "version": "0.1.0" + "lodash": { + "version": "2.4.1" }, "q": { - "version": "1.0.0" + "version": "1.0.1" }, "request": { - "version": "2.33.0", + "version": "2.36.0", "dependencies": { "qs": { "version": "0.6.6" @@ -2881,28 +3518,28 @@ "json-stringify-safe": { "version": "5.0.0" }, + "mime": { + "version": "1.2.11" + }, "forever-agent": { "version": "0.5.2" }, "node-uuid": { "version": "1.4.1" }, - "mime": { - "version": "1.2.11" - }, "tough-cookie": { "version": "0.12.1", "dependencies": { "punycode": { - "version": "1.2.4" + "version": "1.3.1" } } }, "form-data": { - "version": "0.1.2", + "version": "0.1.4", "dependencies": { "combined-stream": { - "version": "0.0.4", + "version": "0.0.5", "dependencies": { "delayed-stream": { "version": "0.0.5" @@ -2912,7 +3549,7 @@ } }, "tunnel-agent": { - "version": "0.3.0" + "version": "0.4.0" }, "http-signature": { "version": "0.10.0", @@ -2953,109 +3590,11 @@ } } }, - "archiver": { - "version": "0.5.2", - "dependencies": { - "readable-stream": { - "version": "1.0.26", - "dependencies": { - "string_decoder": { - "version": "0.10.25-1" - } - } - }, - "zip-stream": { - "version": "0.1.4", - "dependencies": { - "lodash.defaults": { - "version": "2.4.1", - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "dependencies": { - "lodash._isnative": { - "version": "2.4.1" - }, - "lodash.isobject": { - "version": "2.4.1" - }, - "lodash._shimkeys": { - "version": "2.4.1" - } - } - }, - "lodash._objecttypes": { - "version": "2.4.1" - } - } - } - } - }, - "lazystream": { - "version": "0.1.0" - }, - "file-utils": { - "version": "0.1.5", - "dependencies": { - "lodash": { - "version": "2.1.0" - }, - "iconv-lite": { - "version": "0.2.11" - }, - "rimraf": { - "version": "2.2.6" - }, - "glob": { - "version": "3.2.9", - "dependencies": { - "inherits": { - "version": "2.0.1" - } - } - }, - "minimatch": { - "version": "0.2.14", - "dependencies": { - "lru-cache": { - "version": "2.5.0" - }, - "sigmund": { - "version": "1.0.0" - } - } - }, - "findup-sync": { - "version": "0.1.2", - "dependencies": { - "glob": { - "version": "3.1.21", - "dependencies": { - "graceful-fs": { - "version": "1.2.3" - }, - "inherits": { - "version": "1.0.0" - } - } - }, - "lodash": { - "version": "1.0.1" - } - } - }, - "isbinaryfile": { - "version": "0.1.9" - } - } - } - } - }, - "lodash": { - "version": "2.4.1" - }, "underscore.string": { "version": "2.3.3" + }, + "vargs": { + "version": "0.1.0" } } }, @@ -3156,39 +3695,44 @@ "version": "0.0.2" }, "promises-aplus-tests": { - "version": "2.0.4", + "version": "2.0.5", "dependencies": { "mocha": { - "version": "1.11.0", + "version": "1.21.4", "dependencies": { "commander": { - "version": "0.6.1" + "version": "2.0.0" }, "growl": { - "version": "1.7.0" + "version": "1.8.1" }, "jade": { "version": "0.26.3", "dependencies": { + "commander": { + "version": "0.6.1" + }, "mkdirp": { "version": "0.3.0" } } }, "diff": { - "version": "1.0.2" + "version": "1.0.7" }, "debug": { - "version": "0.7.4" + "version": "1.0.4", + "dependencies": { + "ms": { + "version": "0.6.2" + } + } }, "mkdirp": { "version": "0.3.5" }, - "ms": { - "version": "0.3.0" - }, "glob": { - "version": "3.2.1", + "version": "3.2.3", "dependencies": { "minimatch": { "version": "0.2.14", @@ -3202,35 +3746,43 @@ } }, "graceful-fs": { - "version": "1.2.3" + "version": "2.0.3" }, "inherits": { - "version": "1.0.0" + "version": "2.0.1" } } } } }, "sinon": { - "version": "1.7.3", + "version": "1.10.3", "dependencies": { - "buster-format": { - "version": "0.5.6", + "formatio": { + "version": "1.0.2", + "dependencies": { + "samsam": { + "version": "1.1.1" + } + } + }, + "util": { + "version": "0.10.3", "dependencies": { - "buster-core": { - "version": "0.6.4" + "inherits": { + "version": "2.0.1" } } } } }, "underscore": { - "version": "1.4.4" + "version": "1.6.0" } } }, "protractor": { - "version": "1.0.0", + "version": "1.1.1", "dependencies": { "request": { "version": "2.36.0", @@ -3254,7 +3806,7 @@ "version": "0.12.1", "dependencies": { "punycode": { - "version": "1.3.0" + "version": "1.3.1" } } }, diff --git a/package.json b/package.json index 5e317a2decf6..49938bc0b2d4 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "marked": "~0.3.0", "node-html-encoder": "0.0.2", "promises-aplus-tests": "~2.0.4", - "protractor": "1.0.0", + "protractor": "^1.1.1", "q": "~1.0.0", "qq": "^0.3.5", "rewire": "1.1.3", From 9387fae47804d8c4c8fb05a267d2f9c0cdfc0ccd Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Mon, 25 Aug 2014 08:28:29 +0100 Subject: [PATCH 7/8] chore(protractor-shared-conf): add enableDebugInfo module --- protractor-shared-conf.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/protractor-shared-conf.js b/protractor-shared-conf.js index d2ac3ced7bd8..039d8ce973c8 100644 --- a/protractor-shared-conf.js +++ b/protractor-shared-conf.js @@ -19,6 +19,13 @@ exports.config = { browser.addMockModule('disableNgAnimate', disableNgAnimate); + browser.addMockModule('enable-binding-info', function() { + angular.module('enable-binding-info', []) + .config(['$compileProvider', function($compileProvider) { + $compileProvider.enableDebugInfo(true); + }]); + }); + // Store the name of the browser that's currently being used. browser.getCapabilities().then(function(caps) { browser.params.browser = caps.get('browserName'); From ee4329b72e0396d9b4a361bb353c412ca2fa94b3 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Mon, 25 Aug 2014 08:28:51 +0100 Subject: [PATCH 8/8] test(*): fix e2e bindings --- docs/content/guide/$location.ngdoc | 72 +++++++++++++++--------------- docs/content/guide/module.ngdoc | 4 +- src/ng/directive/input.js | 8 ++-- src/ng/directive/select.js | 9 ++-- src/ng/filter/filters.js | 2 +- src/ng/filter/limitTo.js | 4 +- 6 files changed, 50 insertions(+), 49 deletions(-) diff --git a/docs/content/guide/$location.ngdoc b/docs/content/guide/$location.ngdoc index 81a7d85ad299..f7a1557a90f8 100644 --- a/docs/content/guide/$location.ngdoc +++ b/docs/content/guide/$location.ngdoc @@ -469,12 +469,12 @@ In these examples we use `` it("should show fake browser info on load", function(){ expect(addressBar.getAttribute('value')).toBe(url); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/path'); - expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}'); - expect(element(by.binding('$location.hash')).getText()).toBe('h'); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/path'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"a":"b"}'); + expect(element(by.binding('$location.hash()')).getText()).toBe('h'); }); @@ -485,24 +485,24 @@ In these examples we use `` expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/first?a=b"); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/first'); - expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}'); - expect(element(by.binding('$location.hash')).getText()).toBe(''); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/first'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"a":"b"}'); + expect(element(by.binding('$location.hash()')).getText()).toBe(''); navigation.get(1).click(); expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/sec/ond?flag#hash"); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/sec/ond'); - expect(element(by.binding('$location.search')).getText()).toBe('{"flag":true}'); - expect(element(by.binding('$location.hash')).getText()).toBe('hash'); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/sec/ond'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"flag":true}'); + expect(element(by.binding('$location.hash()')).getText()).toBe('hash'); }); @@ -621,12 +621,12 @@ In these examples we use `` it("should show fake browser info on load", function(){ expect(addressBar.getAttribute('value')).toBe(url); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/path'); - expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}'); - expect(element(by.binding('$location.hash')).getText()).toBe('h'); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/path'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"a":"b"}'); + expect(element(by.binding('$location.hash()')).getText()).toBe('h'); }); @@ -637,24 +637,24 @@ In these examples we use `` expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/index.html#!/first?a=b"); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/first'); - expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}'); - expect(element(by.binding('$location.hash')).getText()).toBe(''); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/first'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"a":"b"}'); + expect(element(by.binding('$location.hash()')).getText()).toBe(''); navigation.get(1).click(); expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/index.html#!/sec/ond?flag#hash"); - expect(element(by.binding('$location.protocol')).getText()).toBe('http'); - expect(element(by.binding('$location.host')).getText()).toBe('www.example.com'); - expect(element(by.binding('$location.port')).getText()).toBe('80'); - expect(element(by.binding('$location.path')).getText()).toBe('/sec/ond'); - expect(element(by.binding('$location.search')).getText()).toBe('{"flag":true}'); - expect(element(by.binding('$location.hash')).getText()).toBe('hash'); + expect(element(by.binding('$location.protocol()')).getText()).toBe('http'); + expect(element(by.binding('$location.host()')).getText()).toBe('www.example.com'); + expect(element(by.binding('$location.port()')).getText()).toBe('80'); + expect(element(by.binding('$location.path()')).getText()).toBe('/sec/ond'); + expect(element(by.binding('$location.search()')).getText()).toBe('{"flag":true}'); + expect(element(by.binding('$location.hash()')).getText()).toBe('hash'); }); diff --git a/docs/content/guide/module.ngdoc b/docs/content/guide/module.ngdoc index 5315da44ba91..1ef968347a05 100644 --- a/docs/content/guide/module.ngdoc +++ b/docs/content/guide/module.ngdoc @@ -50,7 +50,7 @@ I'm in a hurry. How do I get a Hello World module working? it('should add Hello to the name', function() { - expect(element(by.binding("{{ 'World' | greet }}")).getText()).toEqual('Hello, World!'); + expect(element(by.binding(" 'World' | greet ")).getText()).toEqual('Hello, World!'); }); @@ -128,7 +128,7 @@ The above is a suggestion. Tailor it to your needs. it('should add Hello to the name', function() { - expect(element(by.binding("{{ greeting }}")).getText()).toEqual('Bonjour World!'); + expect(element(by.binding(" greeting ")).getText()).toEqual('Bonjour World!'); }); diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index c2cf92332081..051f15c021d2 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -798,7 +798,7 @@ var inputType = { it('should change state', function() { - var color = element(by.binding('color')); + var color = element(by.binding('color | json')); expect(color.getText()).toContain('blue'); @@ -1334,7 +1334,7 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
- var user = element(by.binding('{{user}}')); + var user = element(by.binding('user')); var userNameValid = element(by.binding('myForm.userName.$valid')); var lastNameValid = element(by.binding('myForm.lastName.$valid')); var lastNameError = element(by.binding('myForm.lastName.$error')); @@ -2414,7 +2414,7 @@ var minlengthDirective = function() { * * * var listInput = element(by.model('names')); - * var names = element(by.binding('{{names}}')); + * var names = element(by.binding('names')); * var valid = element(by.binding('myForm.namesInput.$valid')); * var error = element(by.css('span.error')); * @@ -2444,7 +2444,7 @@ var minlengthDirective = function() { * * it("should split the text by newlines", function() { * var listInput = element(by.model('list')); - * var output = element(by.binding('{{ list | json }}')); + * var output = element(by.binding(' list | json ')); * listInput.sendKeys('abc\ndef\nghi'); * expect(output.getText()).toContain('[\n "abc",\n "def",\n "ghi"\n]'); * }); diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index 8bb93c56ceec..237c29e8791d 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -115,7 +115,7 @@ var ngOptionsMinErr = minErr('ngOptions'); Select bogus.

- Currently selected: {{ {selected_color:myColor} }} + Currently selected: {{ {selected_color:myColor} }}
@@ -123,13 +123,14 @@ var ngOptionsMinErr = minErr('ngOptions');
it('should check ng-options', function() { - expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red'); + var selectedColor = element(by.binding(' {selected_color:myColor} ')); + expect(selectedColor.getText()).toMatch('red'); element.all(by.model('myColor')).first().click(); element.all(by.css('select[ng-model="myColor"] option')).first().click(); - expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black'); + expect(selectedColor.getText()).toMatch('black'); element(by.css('.nullable select[ng-model="myColor"]')).click(); element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click(); - expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null'); + expect(selectedColor.getText()).toMatch('null'); }); diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 91cb588aff75..72ca9d7b47fd 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -480,7 +480,7 @@ function dateFilter($locale) {
it('should jsonify filtered objects', function() { - expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/); + expect(element(by.binding(" {'name':'value'} | json ")).getText()).toMatch(/\{\n "name": ?"value"\n}/); }); diff --git a/src/ng/filter/limitTo.js b/src/ng/filter/limitTo.js index 52abd260b9a2..6f01aa9c1f86 100644 --- a/src/ng/filter/limitTo.js +++ b/src/ng/filter/limitTo.js @@ -40,8 +40,8 @@ var numLimitInput = element(by.model('numLimit')); var letterLimitInput = element(by.model('letterLimit')); - var limitedNumbers = element(by.binding('numbers | limitTo:numLimit')); - var limitedLetters = element(by.binding('letters | limitTo:letterLimit')); + var limitedNumbers = element(by.binding(' numbers | limitTo:numLimit ')); + var limitedLetters = element(by.binding(' letters | limitTo:letterLimit ')); it('should limit the number array to first three items', function() { expect(numLimitInput.getAttribute('value')).toBe('3');