From 9998b8dcbb2674ac680fd6598aea0840e69c0e1b Mon Sep 17 00:00:00 2001 From: Kai Compagner Date: Wed, 14 Jul 2010 12:08:55 -0700 Subject: fix undefine style --- src/directives.js | 2 +- test/directivesSpec.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/directives.js b/src/directives.js index a333c4c4..6b81d864 100644 --- a/src/directives.js +++ b/src/directives.js @@ -255,7 +255,7 @@ angularDirective("ng:hide", function(expression, element){ angularDirective("ng:style", function(expression, element){ return function(element){ this.$onEval(function(){ - element.css(this.$eval(expression)); + element.css(this.$eval(expression) || {}); }, element); }; }); diff --git a/test/directivesSpec.js b/test/directivesSpec.js index df0b5b94..ef4814bf 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -174,6 +174,13 @@ describe("directives", function(){ expect(element.css('color')).toEqual('red'); }); + it('should silently ignore undefined ng:style', function() { + var scope = compile('
'); + scope.$eval(); + dump(sortedHtml(element)); + expect(element.hasClass('ng-exception')).toBeFalsy(); + }); + it('should ng:show', function(){ var scope = compile('
'); scope.$eval(); -- cgit v1.2.3 From e7b90956552bc129935e7b8dec947eb3e30f3c29 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Tue, 10 Aug 2010 19:10:43 -0700 Subject: Change repeater dsl to collect and return an array of string contents based on match --- src/scenario/DSL.js | 39 ++++++++++++++++++------------ test/scenario/DSLSpec.js | 63 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index 96447aaf..2dd37250 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -43,6 +43,8 @@ angular.scenario.dsl.input = function(selector) { }; }, +angular.scenario.dsl.NG_BIND_PATTERN =/\{\{[^\}]+\}\}/; + angular.scenario.dsl.repeater = function(selector) { var namePrefix = "repeater '" + selector + "'"; return { @@ -51,23 +53,30 @@ angular.scenario.dsl.repeater = function(selector) { done(this.testDocument.find(selector).size()); }); }, - collect: function() { - return $scenario.addFuture(namePrefix + ' collect', function(done) { + collect: function(collectSelector) { + return $scenario.addFuture( + namePrefix + " collect '" + collectSelector + "'", + function(done) { var self = this; var doCollect = bind(this, function() { - var repeaterArray = []; + var repeaterArray = [], ngBindPattern; + var startIndex = collectSelector.search( + angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = collectSelector.substring( + startIndex + 2, collectSelector.length - 2); + collectSelector = '*'; + + } this.testDocument.find(selector).each(function() { - var element = angular.extend(self.jQuery(this), - {bindings: [], - boundTo: function(name) { return this.bindings[name]; }} - ); - element.find('*').each(function() { - var bindName = self.jQuery(this).attr('ng:bind'); - if (bindName) { - element.bindings[bindName] = self.jQuery(this).text(); - } + var element = self.jQuery(this); + element.find(collectSelector). + each(function() { + var foundElem = self.jQuery(this); + if (foundElem.attr('ng:bind') == ngBindPattern) { + repeaterArray.push(foundElem.text()); + } }); - repeaterArray[index] = element; }); return repeaterArray; }); @@ -86,9 +95,9 @@ angular.scenario.dsl.element = function(selector) { boundTo: function(name) { return this.bindings[name]; } }); element.find('*').each(function() { - var bindName = self.jQuery(elem).attr('ng:bind'); + var bindName = self.jQuery(this).attr('ng:bind'); if (bindName) { - element.bindings[bindName] = self.jQuery(elem).text(); + element.bindings[bindName] = self.jQuery(this).text(); } }); done(element); diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index 62de9d6c..f414db6d 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -42,6 +42,27 @@ describe("DSL", function() { describe('repeater', function() { var repeater = angular.scenario.dsl.repeater; + var html; + beforeEach(function() { + html = "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
" + + "John Marston" + + "" + + "Red Dead Redemption" + + "
" + + "Nathan Drake" + + "" + + "Uncharted" + + "
"; + }); it('should count', function() { var future = repeater('.repeater-row').count(); expect(future.name).toEqual("repeater '.repeater-row' count"); @@ -55,29 +76,31 @@ describe("DSL", function() { expect(future.value).toEqual(2); }); - it('should collect', function() { - var future = repeater('.epic').collect(); - expect(future.name).toEqual("repeater '.epic' collect"); - executeFuture(future, - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "
John MarstonRed Dead Redemption
Nathan DrakeUncharted 2
", - function(value) { - future.fulfill(value); + function assertFutureState(future, expectedName, expectedValue) { + expect(future.name).toEqual(expectedName); + executeFuture(future, html, function(value) { + future.fulfill(value); }); expect(future.fulfilled).toBeTruthy(); - expect(future.value[0].boundTo('hero')).toEqual('John Marston'); - expect(future.value[0].boundTo('game')).toEqual('Red Dead Redemption'); - expect(future.value[1].boundTo('hero')).toEqual('Nathan Drake'); - expect(future.value[1].boundTo('game')).toEqual('Uncharted 2'); + expect(future.value).toEqual(expectedValue); + } + it('should collect bindings', function() { + assertFutureState(repeater('.epic').collect('{{hero}}'), + "repeater '.epic' collect '{{hero}}'", + ['John Marston', 'Nathan Drake']); + assertFutureState(repeater('.epic').collect('{{game}}'), + "repeater '.epic' collect '{{game}}'", + ['Red Dead Redemption', 'Uncharted']); + }); + it('should collect normal selectors', function() { + assertFutureState(repeater('.epic').collect('.hero-name'), + "repeater '.epic' collect '.hero-name'", + ['John Marston', 'Nathan Drake']); + assertFutureState(repeater('.epic').collect('.game-name'), + "repeater '.epic' collect '.game-name'", + ['Red Dead Redemption', 'Uncharted']); }); + it('should collect normal attributes', function() {}); }); describe('element', function() { -- cgit v1.2.3 From 567341c10fc7f74d5333f27514bb2201f1dbee42 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Wed, 11 Aug 2010 10:54:11 -0700 Subject: modify element dsl to understand angular bindings and return jquery object for further checking --- src/scenario/DSL.js | 23 +++++++++++------------ test/scenario/DSLSpec.js | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index 2dd37250..3b049dc6 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -89,17 +89,16 @@ angular.scenario.dsl.repeater = function(selector) { angular.scenario.dsl.element = function(selector) { var nameSuffix = "element '" + selector + "'"; return $scenario.addFuture('Find ' + nameSuffix, function(done) { - var self = this; - var element = angular.extend(this.testDocument.find(selector), { - bindings: [], - boundTo: function(name) { return this.bindings[name]; } - }); - element.find('*').each(function() { - var bindName = self.jQuery(this).attr('ng:bind'); - if (bindName) { - element.bindings[bindName] = self.jQuery(this).text(); - } - }); - done(element); + var self = this, repeaterArray = [], ngBindPattern; + var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); + var element = this.testDocument.find('*').filter(function() { + return self.jQuery(this).attr('ng:bind') == ngBindPattern; + }); + done(element); + } else { + done(this.testDocument.find(selector)); + } }); }; diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index f414db6d..c8e30917 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -100,7 +100,9 @@ describe("DSL", function() { "repeater '.epic' collect '.game-name'", ['Red Dead Redemption', 'Uncharted']); }); - it('should collect normal attributes', function() {}); + it('should collect normal attributes', function() { + //TODO(shyamseshadri) : Left as an exercise to the user + }); }); describe('element', function() { @@ -118,24 +120,25 @@ describe("DSL", function() { '' + ''; }); + function timeTravel(future) { + executeFuture(future, html, function(value) { future.fulfill(value); }); + expect(future.fulfilled).toBeTruthy(); + } it('should find elements on the page and provide jquery api', function() { var future = element('.reports-detail'); expect(future.name).toEqual("Find element '.reports-detail'"); - executeFuture(future, html, function(value) { future.fulfill(value); }); - expect(future.fulfilled).toBeTruthy(); + timeTravel(future); expect(future.value.text()). toEqual('Description : Details...Date created: 01/01/01'); expect(future.value.find('.desc').text()). toEqual('Description : Details...'); }); - it('should know how to find ng:bind elements on page', function() { - var future = element('.reports-detail'); - expect(future.name).toEqual("Find element '.reports-detail'"); - executeFuture(future, html, function(value) { future.fulfill(value); }); - expect(future.fulfilled).toBeTruthy(); - expect(future.value.boundTo('report.description')).toEqual('Details...'); - expect(future.value.boundTo('report.creationDate')).toEqual('01/01/01'); - expect(future.value.boundTo('doesnotexist')).not.toBeDefined(); + it('should find elements with angular syntax', function() { + var future = element('{{report.description}}'); + expect(future.name).toEqual("Find element '{{report.description}}'"); + timeTravel(future); + expect(future.value.text()).toEqual('Details...'); + expect(future.value.attr('ng:bind')).toEqual('report.description'); }); }); }); -- cgit v1.2.3 From 412f05977c41fbda46278b637c4d1a84996d48d1 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Wed, 11 Aug 2010 11:17:55 -0700 Subject: removed google charts and few other filters, switched to simple optimization for compiler --- Rakefile | 4 +- perf/startup.html | 30 +++++ src/Angular.js | 8 -- src/filters.js | 358 ++++++++++------------------------------------------ test/FiltersTest.js | 73 ----------- 5 files changed, 97 insertions(+), 376 deletions(-) create mode 100644 perf/startup.html diff --git a/Rakefile b/Rakefile index bf37edce..de1f7527 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,4 @@ -include FileUtils + include FileUtils task :default => [:compile, :test] @@ -91,7 +91,7 @@ task :compile do f.close %x(java -jar lib/compiler-closure/compiler.jar \ - --compilation_level ADVANCED_OPTIMIZATIONS \ + --compilation_level SIMPLE_OPTIMIZATIONS \ --js angular-debug.js \ --externs externs.js \ --create_source_map ./angular-minified.map \ diff --git a/perf/startup.html b/perf/startup.html new file mode 100644 index 00000000..2fc948ef --- /dev/null +++ b/perf/startup.html @@ -0,0 +1,30 @@ + + + + + + + + + READY + + diff --git a/src/Angular.js b/src/Angular.js index e11a0679..902ae013 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -307,14 +307,6 @@ function bind(_this, _function) { } } -function outerHTML(node) { - var temp = document.createElement('div'); - temp.appendChild(node); - var outerHTML = temp.innerHTML; - temp.removeChild(node); - return outerHTML; -} - function toBoolean(value) { if (value && value.length !== 0) { var v = lowercase("" + value); diff --git a/src/filters.js b/src/filters.js index 99d17405..27e3deca 100644 --- a/src/filters.js +++ b/src/filters.js @@ -1,302 +1,74 @@ -var angularFilterGoogleChartApi; - -foreach({ - 'currency': function(amount){ - this.$element.toggleClass('ng:format-negative', amount < 0); - return '$' + angularFilter['number'].apply(this, [amount, 2]); - }, - - 'number': function(amount, fractionSize){ - if (isNaN(amount) || !isFinite(amount)) { - return ''; - } - fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize; - var isNegative = amount < 0; - amount = Math.abs(amount); - var pow = Math.pow(10, fractionSize); - var text = "" + Math.round(amount * pow); - var whole = text.substring(0, text.length - fractionSize); - whole = whole || '0'; - var frc = text.substring(text.length - fractionSize); - text = isNegative ? '-' : ''; - for (var i = 0; i < whole.length; i++) { - if ((whole.length - i)%3 === 0 && i !== 0) { - text += ','; - } - text += whole.charAt(i); - } - if (fractionSize > 0) { - for (var j = frc.length; j < fractionSize; j++) { - frc += '0'; - } - text += '.' + frc.substring(0, fractionSize); - } - return text; - }, - - 'date': function(date) { - if (date instanceof Date) - return date.toLocaleDateString(); - else - return date; - }, - - 'json': function(object) { - this.$element.addClass("ng-monospace"); - return toJson(object, true); - }, - - 'trackPackage': (function(){ - var MATCHERS = [ - { name: "UPS", - url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=", - regexp: [ - /^1Z[0-9A-Z]{16}$/i]}, - { name: "FedEx", - url: "http://www.fedex.com/Tracking?tracknumbers=", - regexp: [ - /^96\d{10}?$/i, - /^96\d{17}?$/i, - /^96\d{20}?$/i, - /^\d{15}$/i, - /^\d{12}$/i]}, - { name: "USPS", - url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=", - regexp: [ - /^(91\d{20})$/i, - /^(91\d{18})$/i]}]; - return function(trackingNo, noMatch) { - trackingNo = trim(trackingNo); - var tNo = trackingNo.replace(/ /g, ''); - var returnValue; - foreach(MATCHERS, function(carrier){ - foreach(carrier.regexp, function(regexp){ - if (!returnValue && regexp.test(tNo)) { - var text = carrier.name + ": " + trackingNo; - var url = carrier.url + trackingNo; - returnValue = jqLite(''); - returnValue.text(text); - returnValue.attr('href', url); - } - }); - }); - if (returnValue) - return returnValue; - else if (trackingNo) - return noMatch || trackingNo + " is not recognized"; - else - return null; - };})(), - - 'link': function(obj, title) { - if (obj) { - var text = title || obj.text || obj; - var url = obj.url || obj; - if (url) { - if (angular.validator.email(url) === null) { - url = "mailto:" + url; - } - var a = jqLite(''); - a.attr('href', url); - a.text(text); - return a; - } - } - return obj; - }, - - - 'bytes': (function(){ - var SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']; - return function(size) { - if(size === null) return ""; - - var suffix = 0; - while (size > 1000) { - size = size / 1024; - suffix++; - } - var txt = "" + size; - var dot = txt.indexOf('.'); - if (dot > -1 && dot + 2 < txt.length) { - txt = txt.substring(0, dot + 2); - } - return txt + " " + SUFFIX[suffix]; - }; - })(), - - 'image': function(obj, width, height) { - if (obj && obj.url) { - var style = "", img = jqLite(''); - if (width) { - img.css('max-width', width + 'px'); - img.css('max-height', (height || width) + 'px'); - } - img.attr('src', obj.url); - return img; +angularFilter.currency = function(amount){ + this.$element.toggleClass('ng:format-negative', amount < 0); + return '$' + angularFilter['number'].apply(this, [amount, 2]); +}; + +angularFilter.number = function(amount, fractionSize){ + if (isNaN(amount) || !isFinite(amount)) { + return ''; + } + fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize; + var isNegative = amount < 0; + amount = Math.abs(amount); + var pow = Math.pow(10, fractionSize); + var text = "" + Math.round(amount * pow); + var whole = text.substring(0, text.length - fractionSize); + whole = whole || '0'; + var frc = text.substring(text.length - fractionSize); + text = isNegative ? '-' : ''; + for (var i = 0; i < whole.length; i++) { + if ((whole.length - i)%3 === 0 && i !== 0) { + text += ','; } - return null; - }, - - 'lowercase': lowercase, - - 'uppercase': uppercase, - - 'linecount': function (obj) { - if (isString(obj)) { - if (obj==='') return 1; - return obj.split(/\n|\f/).length; + text += whole.charAt(i); + } + if (fractionSize > 0) { + for (var j = frc.length; j < fractionSize; j++) { + frc += '0'; } - return 1; - }, - - 'if': function (result, expression) { - return expression ? result : undefined; - }, - - 'unless': function (result, expression) { - return expression ? undefined : result; - }, - - 'googleChartApi': extend( - function(type, data, width, height) { - data = data || {}; - var chart = { - 'cht':type, - 'chco':angularFilterGoogleChartApi['collect'](data, 'color'), - 'chtt':angularFilterGoogleChartApi['title'](data), - 'chdl':angularFilterGoogleChartApi['collect'](data, 'label'), - 'chd':angularFilterGoogleChartApi['values'](data), - 'chf':'bg,s,FFFFFF00' - }; - if (_.isArray(data['xLabels'])) { - chart['chxt']='x'; - chart['chxl']='0:|' + data.xLabels.join('|'); - } - return angularFilterGoogleChartApi['encode'](chart, width, height); - }, - { - 'values': function(data){ - var seriesValues = []; - foreach(data['series']||[], function(serie){ - var values = []; - foreach(serie['values']||[], function(value){ - values.push(value); - }); - seriesValues.push(values.join(',')); - }); - var values = seriesValues.join('|'); - return values === "" ? null : "t:" + values; - }, - - 'title': function(data){ - var titles = []; - var title = data['title'] || []; - foreach(_.isArray(title)?title:[title], function(text){ - titles.push(encodeURIComponent(text)); - }); - return titles.join('|'); - }, + text += '.' + frc.substring(0, fractionSize); + } + return text; +}; - 'collect': function(data, key){ - var outterValues = []; - var count = 0; - foreach(data['series']||[], function(serie){ - var innerValues = []; - var value = serie[key] || []; - foreach(_.isArray(value)?value:[value], function(color){ - innerValues.push(encodeURIComponent(color)); - count++; - }); - outterValues.push(innerValues.join('|')); - }); - return count?outterValues.join(','):null; - }, +angularFilter.date = function(date) { + if (date instanceof Date) + return date.toLocaleDateString(); + else + return date; +}; - 'encode': function(params, width, height) { - width = width || 200; - height = height || width; - var url = "http://chart.apis.google.com/chart?", - urlParam = [], - img = jqLite(''); - params['chs'] = width + "x" + height; - foreach(params, function(value, key){ - if (value) { - urlParam.push(key + "=" + value); - } - }); - urlParam.sort(); - url += urlParam.join("&"); - img.attr('src', url); - img.css({width: width + 'px', height: height + 'px'}); - return img; - } - } - ), +angularFilter.json = function(object) { + this.$element.addClass("ng-monospace"); + return toJson(object, true); +}; +angularFilter.lowercase = lowercase; - 'qrcode': function(value, width, height) { - return angularFilterGoogleChartApi['encode']({ - 'cht':'qr', 'chl':encodeURIComponent(value)}, width, height); - }, - 'chart': { - 'pie':function(data, width, height) { - return angularFilterGoogleChartApi('p', data, width, height); - }, - 'pie3d':function(data, width, height) { - return angularFilterGoogleChartApi('p3', data, width, height); - }, - 'pieConcentric':function(data, width, height) { - return angularFilterGoogleChartApi('pc', data, width, height); - }, - 'barHorizontalStacked':function(data, width, height) { - return angularFilterGoogleChartApi('bhs', data, width, height); - }, - 'barHorizontalGrouped':function(data, width, height) { - return angularFilterGoogleChartApi('bhg', data, width, height); - }, - 'barVerticalStacked':function(data, width, height) { - return angularFilterGoogleChartApi('bvs', data, width, height); - }, - 'barVerticalGrouped':function(data, width, height) { - return angularFilterGoogleChartApi('bvg', data, width, height); - }, - 'line':function(data, width, height) { - return angularFilterGoogleChartApi('lc', data, width, height); - }, - 'sparkline':function(data, width, height) { - return angularFilterGoogleChartApi('ls', data, width, height); - }, - 'scatter':function(data, width, height) { - return angularFilterGoogleChartApi('s', data, width, height); - } - }, +angularFilter.uppercase = uppercase; - 'html': function(html){ - return new HTML(html); - }, +angularFilter.html = function(html){ + return new HTML(html); +}; - 'linky': function(text){ - if (!text) return text; - function regExpEscape(text) { - return text.replace(/([\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1'); - } - var URL = /(ftp|http|https|mailto):\/\/([^\(\)|\s]+)/; - var match; - var raw = text; - var html = []; - while (match=raw.match(URL)) { - var url = match[0].replace(/[\.\;\,\(\)\{\}\<\>]$/,''); - var i = raw.indexOf(url); - html.push(escapeHtml(raw.substr(0, i))); - html.push(''); - html.push(url); - html.push(''); - raw = raw.substring(i + url.length); - } - html.push(escapeHtml(raw)); - return new HTML(html.join('')); +angularFilter.linky = function(text){ + if (!text) return text; + function regExpEscape(text) { + return text.replace(/([\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1'); } -}, function(v,k){angularFilter[k] = v;}); - -angularFilterGoogleChartApi = angularFilter['googleChartApi']; + var URL = /(ftp|http|https|mailto):\/\/([^\(\)|\s]+)/; + var match; + var raw = text; + var html = []; + while (match=raw.match(URL)) { + var url = match[0].replace(/[\.\;\,\(\)\{\}\<\>]$/,''); + var i = raw.indexOf(url); + html.push(escapeHtml(raw.substr(0, i))); + html.push(''); + html.push(url); + html.push(''); + raw = raw.substring(i + url.length); + } + html.push(escapeHtml(raw)); + return new HTML(html.join('')); +}; diff --git a/test/FiltersTest.js b/test/FiltersTest.js index 903a7a2f..d5484fd0 100644 --- a/test/FiltersTest.js +++ b/test/FiltersTest.js @@ -41,54 +41,6 @@ FiltersTest.prototype.testJson = function () { assertEquals(toJson({a:"b"}, true), angular.filter.json.call({$element:jqLite('
')}, {a:"b"})); }; -FiltersTest.prototype.testPackageTracking = function () { - var assert = function(title, trackingNo) { - var val = angular.filter.trackPackage(trackingNo, title); - assertNotNull("Did Not Match: " + trackingNo, val); - assertEquals(title + ": " + trim(trackingNo), val.text()); - assertNotNull(val.attr('href')); - }; - assert('UPS', ' 1Z 999 999 99 9999 999 9 '); - assert('UPS', '1ZW5w5220379084747'); - - assert('FedEx', '418822131061812'); - assert('FedEx', '9612019 5935 3267 2473 738'); - assert('FedEx', '9612019593532672473738'); - assert('FedEx', '235354667129449'); - assert('FedEx', '915368880571'); - assert('FedEx', '901712142390'); - assert('FedEx', '297391510063413'); - - assert('USPS', '9101 8052 1390 7402 4335 49'); - assert('USPS', '9101010521297963339560'); - assert('USPS', '9102901001301038667029'); - assert('USPS', '910 27974 4490 3000 8916 56'); - assert('USPS', '9102801438635051633253'); -}; - -FiltersTest.prototype.testLink = function() { - var assert = function(text, url, obj){ - var val = angular.filter.link(obj); - assertEquals('' + text + '', sortedHtml(val)); - }; - assert("url", "url", "url"); - assert("hello", "url", {text:"hello", url:"url"}); - assert("a@b.com", "mailto:a@b.com", "a@b.com"); -}; - -FiltersTest.prototype.testImage = function(){ - assertEquals(null, angular.filter.image()); - assertEquals(null, angular.filter.image({})); - assertEquals(null, angular.filter.image("")); - assertEquals('http://localhost/abc', angular.filter.image({url:"http://localhost/abc"}).attr('src')); -}; - -FiltersTest.prototype.testQRcode = function() { - assertEquals( - 'http://chart.apis.google.com/chart?chl=Hello%20world&chs=200x200&cht=qr', - angular.filter.qrcode('Hello world').attr('src')); -}; - FiltersTest.prototype.testLowercase = function() { assertEquals('abc', angular.filter.lowercase('AbC')); assertEquals(null, angular.filter.lowercase(null)); @@ -99,30 +51,6 @@ FiltersTest.prototype.testUppercase = function() { assertEquals(null, angular.filter.uppercase(null)); }; -FiltersTest.prototype.testLineCount = function() { - assertEquals(1, angular.filter.linecount(null)); - assertEquals(1, angular.filter.linecount('')); - assertEquals(1, angular.filter.linecount('a')); - assertEquals(2, angular.filter.linecount('a\nb')); - assertEquals(3, angular.filter.linecount('a\nb\nc')); -}; - -FiltersTest.prototype.testIf = function() { - assertEquals('A', angular.filter['if']('A', true)); - assertEquals(undefined, angular.filter['if']('A', false)); -}; - -FiltersTest.prototype.testUnless = function() { - assertEquals('A', angular.filter.unless('A', false)); - assertEquals(undefined, angular.filter.unless('A', true)); -}; - -FiltersTest.prototype.testGoogleChartApiEncode = function() { - assertEquals( - 'http://chart.apis.google.com/chart?chl=Hello world&chs=200x200&cht=qr', - angular.filter.googleChartApi.encode({cht:"qr", chl:"Hello world"}).attr('src')); -}; - FiltersTest.prototype.testHtml = function() { var html = angular.filter.html("acd"); expect(html instanceof HTML).toBeTruthy(); @@ -140,4 +68,3 @@ FiltersTest.prototype.testLinky = function() { assertEquals(undefined, linky(undefined)); }; - -- cgit v1.2.3 From b27fb8a6448b7c8d59b533fe2df9497170fbaa70 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Wed, 11 Aug 2010 11:42:04 -0700 Subject: Fix toEqual matcher to use angular.equals instead of simple == comparison, which breaks down for arrays and objects --- jsTestDriver.conf | 2 +- src/scenario/Matcher.js | 2 +- test/scenario/MatcherSpec.js | 8 ++++++++ test/testabilityPatch.js | 15 +++++++++------ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/jsTestDriver.conf b/jsTestDriver.conf index bcd01694..c7d74b75 100644 --- a/jsTestDriver.conf +++ b/jsTestDriver.conf @@ -8,9 +8,9 @@ load: - src/Angular.js - src/JSON.js - src/*.js + - test/testabilityPatch.js - src/scenario/Runner.js - src/scenario/*.js - - test/testabilityPatch.js - test/angular-mocks.js - test/scenario/*.js - test/*.js diff --git a/src/scenario/Matcher.js b/src/scenario/Matcher.js index 62f094c8..a9c86571 100644 --- a/src/scenario/Matcher.js +++ b/src/scenario/Matcher.js @@ -18,4 +18,4 @@ Matcher.addMatcher = function(name, matcher) { }; }; -Matcher.addMatcher('toEqual', function(a,b) { return a == b; }); +Matcher.addMatcher('toEqual', angular.equals); diff --git a/test/scenario/MatcherSpec.js b/test/scenario/MatcherSpec.js index c47f0c25..2eddd2bc 100644 --- a/test/scenario/MatcherSpec.js +++ b/test/scenario/MatcherSpec.js @@ -27,4 +27,12 @@ describe('Matcher', function () { expect(e).toEqual('Expected 456 but was 123'); } }); + it('should correctly match arrays', function() { + var future = $scenario.addFuture('Calculate first future', function(done) { + done(['a', 'b']); + }); + matcher = new Matcher(this, future); + matcher.toEqual(['a', 'b']); + executeFutures(); + }); }); \ No newline at end of file diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index 5d0df780..e9a88b67 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -35,22 +35,25 @@ function childNode(element, index) { } extend(angular, { - 'bind': bind, + 'element': jqLite, 'compile': compile, + 'scope': createScope, 'copy': copy, - 'element': jqLite, 'extend': extend, + 'equals': equals, 'foreach': foreach, + 'noop':noop, + 'bind':bind, + 'toJson': toJson, + 'fromJson': fromJson, 'identity':identity, 'isUndefined': isUndefined, 'isDefined': isDefined, - 'isObject': isObject, 'isString': isString, 'isFunction': isFunction, + 'isObject': isObject, 'isNumber': isNumber, - 'isArray': isArray, - 'noop':noop, - 'scope': createScope + 'isArray': isArray }); -- cgit v1.2.3 From 3d5719cd44868f89352ebbedd0e1b1f2575520cb Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Wed, 11 Aug 2010 11:44:12 -0700 Subject: removed undocumented/unneeded methods from Array API --- src/Angular.js | 20 +++++++--------- src/apis.js | 71 ------------------------------------------------------- test/ApiTest.js | 73 --------------------------------------------------------- 3 files changed, 9 insertions(+), 155 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 902ae013..3970f762 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -291,19 +291,17 @@ function escapeAttr(html) { '"'); } -function bind(_this, _function) { - var curryArgs = slice.call(arguments, 2, arguments.length); - if (typeof _function == 'function') { - return curryArgs.length == 0 ? - function() { - return _function.apply(_this, arguments); - } : - function() { - return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length))); - }; +function bind(self, fn) { + var curryArgs = arguments.length > 2 ? slice.call(arguments, 2, arguments.length) : []; + if (typeof fn == 'function') { + return curryArgs.length ? function() { + return arguments.length ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0, arguments.length))) : fn.apply(self, curryArgs); + }: function() { + return arguments.length ? fn.apply(self, arguments) : fn.call(self); + }; } else { // in IE, native methods ore not functions and so they can not be bound (but they don't need to be) - return _function; + return fn; } } diff --git a/src/apis.js b/src/apis.js index 136473b6..0cf24016 100644 --- a/src/apis.js +++ b/src/apis.js @@ -21,17 +21,6 @@ var angularObject = { }; var angularArray = { 'indexOf': indexOf, - 'include': includes, - 'includeIf':function(array, value, condition) { - var index = indexOf(array, value); - if (condition) { - if (index == -1) - array.push(value); - } else { - array.splice(index, 1); - } - return array; - }, 'sum':function(array, expression) { var fn = angular['Function']['compile'](expression); var sum = 0; @@ -49,20 +38,6 @@ var angularArray = { array.splice(index, 1); return value; }, - 'find':function(array, condition, defaultValue) { - if (!condition) return undefined; - var fn = angular['Function']['compile'](condition); - foreach(array, function($){ - if (fn($)){ - defaultValue = $; - return true; - } - }); - return defaultValue; - }, - 'findById':function(array, id) { - return angular.Array.find(array, function($){return $.$id == id;}, null); - }, 'filter':function(array, expression) { var predicates = []; predicates.check = function(value) { @@ -195,52 +170,6 @@ var angularArray = { var arrayCopy = []; for ( var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); } return arrayCopy.sort(reverse(comparator, descend)); - }, - 'orderByToggle':function(predicate, attribute) { - var STRIP = /^([+|-])?(.*)/; - var ascending = false; - var index = -1; - foreach(predicate, function($, i){ - if (index == -1) { - if ($ == attribute) { - ascending = true; - index = i; - return true; - } - if (($.charAt(0)=='+'||$.charAt(0)=='-') && $.substring(1) == attribute) { - ascending = $.charAt(0) == '+'; - index = i; - return true; - } - } - }); - if (index >= 0) { - predicate.splice(index, 1); - } - predicate.unshift((ascending ? "-" : "+") + attribute); - return predicate; - }, - 'orderByDirection':function(predicate, attribute, ascend, descend) { - ascend = ascend || 'ng-ascend'; - descend = descend || 'ng-descend'; - var att = predicate[0] || ''; - var direction = true; - if (att.charAt(0) == '-') { - att = att.substring(1); - direction = false; - } else if(att.charAt(0) == '+') { - att = att.substring(1); - } - return att == attribute ? (direction ? ascend : descend) : ""; - }, - 'merge':function(array, index, mergeValue) { - var value = array[index]; - if (!value) { - value = {}; - array[index] = value; - } - merge(mergeValue, value); - return array; } }; diff --git a/test/ApiTest.js b/test/ApiTest.js index 4035cdbb..9f09773d 100644 --- a/test/ApiTest.js +++ b/test/ApiTest.js @@ -18,27 +18,6 @@ ApiTest.prototype.testItShouldReturnSize = function(){ assertEquals(1, angular.Array.size([0])); }; -ApiTest.prototype.testIncludeIf = function() { - var array = []; - var obj = {}; - - angular.Array.includeIf(array, obj, true); - angular.Array.includeIf(array, obj, true); - assertTrue(includes(array, obj)); - assertEquals(1, array.length); - - angular.Array.includeIf(array, obj, false); - assertFalse(includes(array, obj)); - assertEquals(0, array.length); - - angular.Array.includeIf(array, obj, 'x'); - assertTrue(includes(array, obj)); - assertEquals(1, array.length); - angular.Array.includeIf(array, obj, ''); - assertFalse(includes(array, obj)); - assertEquals(0, array.length); -}; - ApiTest.prototype.testSum = function(){ assertEquals(3, angular.Array.sum([{a:"1"}, {a:"2"}], 'a')); }; @@ -48,13 +27,6 @@ ApiTest.prototype.testSumContainingNaN = function(){ assertEquals(1, angular.Array.sum([{a:1}, {a:Number.NaN}], function($){return $.a;})); }; -ApiTest.prototype.testInclude = function(){ - assertTrue(angular.Array.include(['a'], 'a')); - assertTrue(angular.Array.include(['a', 'b'], 'a')); - assertTrue(!angular.Array.include(['c'], 'a')); - assertTrue(!angular.Array.include(['c', 'b'], 'a')); -}; - ApiTest.prototype.testIndex = function(){ assertEquals(angular.Array.indexOf(['a'], 'a'), 0); assertEquals(angular.Array.indexOf(['a', 'b'], 'a'), 0); @@ -80,14 +52,6 @@ ApiTest.prototype.testRemove = function(){ assertEquals(items.length, 0); }; -ApiTest.prototype.testFindById = function() { - var items = [{$id:1}, {$id:2}, {$id:3}]; - assertNull(angular.Array.findById(items, 0)); - assertEquals(items[0], angular.Array.findById(items, 1)); - assertEquals(items[1], angular.Array.findById(items, 2)); - assertEquals(items[2], angular.Array.findById(items, 3)); -}; - ApiTest.prototype.testFilter = function() { var items = ["MIsKO", {name:"shyam"}, ["adam"], 1234]; assertEquals(4, angular.Array.filter(items, "").length); @@ -161,16 +125,6 @@ ApiTest.prototype.testCount = function() { assertEquals(1, angular.Array.count(array, 'name=="a"')); }; -ApiTest.prototype.testFind = function() { - var array = [{name:'a'},{name:'b'},{name:''}]; - var obj = {}; - - assertEquals(undefined, angular.Array.find(array, 'false')); - assertEquals('default', angular.Array.find(array, 'false', 'default')); - assertEquals('a', angular.Array.find(array, 'name == "a"').name); - assertEquals('', angular.Array.find(array, 'name == ""').name); -}; - ApiTest.prototype.testItShouldSortArray = function() { assertEquals([2,15], angular.Array.orderBy([15,2])); assertEquals(["a","B", "c"], angular.Array.orderBy(["c","B", "a"])); @@ -211,33 +165,6 @@ ApiTest.prototype.testQuoteUnicode = function(){ assertEquals('"abc\\u00a0def"', angular.String.quoteUnicode('abc\u00A0def')); }; -ApiTest.prototype.testMerge = function() { - var array = [{name:"misko"}]; - angular.Array.merge(array, 0, {name:"", email:"email1"}); - angular.Array.merge(array, 1, {name:"adam", email:"email2"}); - assertJsonEquals([{"email":"email1","name":"misko"},{"email":"email2","name":"adam"}], array); -}; - -ApiTest.prototype.testOrderByToggle = function() { - var orderByToggle = angular.Array.orderByToggle; - var predicate = []; - assertEquals(['+a'], orderByToggle(predicate, 'a')); - assertEquals(['-a'], orderByToggle(predicate, 'a')); - - assertEquals(['-a', '-b'], orderByToggle(['-b', 'a'], 'a')); -}; - -ApiTest.prototype.testOrderByToggle = function() { - var orderByDirection = angular.Array.orderByDirection; - assertEquals("", orderByDirection(['+a','b'], 'x')); - assertEquals("", orderByDirection(['+a','b'], 'b')); - assertEquals('ng-ascend', orderByDirection(['a','b'], 'a')); - assertEquals('ng-ascend', orderByDirection(['+a','b'], 'a')); - assertEquals('ng-descend', orderByDirection(['-a','b'], 'a')); - assertEquals('up', orderByDirection(['+a','b'], 'a', 'up', 'down')); - assertEquals('down', orderByDirection(['-a','b'], 'a', 'up', 'down')); -}; - ApiTest.prototype.testDateToUTC = function(){ var date = new Date("Sep 10 2003 13:02:03 GMT"); assertEquals("date", angular.Object.typeOf(date)); -- cgit v1.2.3 From 044ecb91c10753c14e1521f95b5f0cd52ff5bf87 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Wed, 11 Aug 2010 12:04:02 -0700 Subject: clean up for better obfuscation --- perf/startup.html | 2 ++ src/JSON.js | 6 +----- src/Scope.js | 9 ++++----- src/formatters.js | 49 +++++++++++++++++++++++-------------------------- src/jqLite.js | 27 ++++++++++----------------- src/services.js | 7 ++++--- 6 files changed, 44 insertions(+), 56 deletions(-) diff --git a/perf/startup.html b/perf/startup.html index 2fc948ef..91a46898 100644 --- a/perf/startup.html +++ b/perf/startup.html @@ -25,6 +25,8 @@ + reload +
READY diff --git a/src/JSON.js b/src/JSON.js index 340b075a..1e468e89 100644 --- a/src/JSON.js +++ b/src/JSON.js @@ -1,4 +1,4 @@ -array = [].constructor; +var array = [].constructor; function toJson(obj, pretty){ var buf = []; @@ -6,10 +6,6 @@ function toJson(obj, pretty){ return buf.join(''); } -function toPrettyJson(obj) { - return toJson(obj, true); -} - function fromJson(json) { if (!json) return json; try { diff --git a/src/Scope.js b/src/Scope.js index 86d5bc14..30e56915 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -44,9 +44,10 @@ function setter(instance, path, value){ } /////////////////////////////////// - -var getterFnCache = {}; -var JS_KEYWORDS = {}; +var scopeId = 0; + getterFnCache = {}, + compileCache = {}, + JS_KEYWORDS = {}; foreach( ["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", @@ -88,7 +89,6 @@ function getterFn(path){ /////////////////////////////////// -var compileCache = {}; function expressionCompile(exp){ if (typeof exp === 'function') return exp; var fn = compileCache[exp]; @@ -108,7 +108,6 @@ function errorHandlerFor(element, error) { elementError(element, NG_EXCEPTION, isDefined(error) ? toJson(error) : error); } -var scopeId = 0; function createScope(parent, services, existing) { function Parent(){} function API(){} diff --git a/src/formatters.js b/src/formatters.js index ca1ce83e..9122489f 100644 --- a/src/formatters.js +++ b/src/formatters.js @@ -3,31 +3,28 @@ function toString(obj) {return (isDefined(obj) && obj !== null) ? "" + obj : obj var NUMBER = /^\s*[-+]?\d*(\.\d*)?\s*$/; -extend(angularFormatter, { - 'noop':formatter(identity, identity), - 'json':formatter(toJson, fromJson), - 'boolean':formatter(toString, toBoolean), - 'number':formatter(toString, - function(obj){ - if (isString(obj) && NUMBER.exec(obj)) { - return obj ? 1*obj : null; - } - throw "Not a number"; - }), +angularFormatter.noop = formatter(identity, identity); +angularFormatter.json = formatter(toJson, fromJson); +angularFormatter['boolean'] = formatter(toString, toBoolean); +angularFormatter.number = formatter(toString, function(obj){ + if (isString(obj) && NUMBER.exec(obj)) { + return obj ? 1*obj : null; + } + throw "Not a number"; +}); - 'list':formatter( - function(obj) { return obj ? obj.join(", ") : obj; }, - function(value) { - var list = []; - foreach((value || '').split(','), function(item){ - item = trim(item); - if (item) list.push(item); - }); - return list; - } - ), +angularFormatter.list = formatter( + function(obj) { return obj ? obj.join(", ") : obj; }, + function(value) { + var list = []; + foreach((value || '').split(','), function(item){ + item = trim(item); + if (item) list.push(item); + }); + return list; + } +); - 'trim':formatter( - function(obj) { return obj ? trim("" + obj) : ""; } - ) -}); +angularFormatter.trim = formatter( + function(obj) { return obj ? trim("" + obj) : ""; } +); diff --git a/src/jqLite.js b/src/jqLite.js index 22b3c070..1ad4d96d 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -2,24 +2,17 @@ //JQLite ////////////////////////////////// -var jqCache = {}; -var jqName = 'ng-' + new Date().getTime(); -var jqId = 1; -function jqNextId() { return (jqId++); } - -var addEventListener = window.document.attachEvent ? - function(element, type, fn) { - element.attachEvent('on' + type, fn); - } : function(element, type, fn) { - element.addEventListener(type, fn, false); - }; +var jqCache = {}, + jqName = 'ng-' + new Date().getTime(), + jqId = 1, + addEventListener = (window.document.attachEvent ? + function(element, type, fn) {element.attachEvent('on' + type, fn);} : + function(element, type, fn) {element.addEventListener(type, fn, false);}), + removeEventListener = (window.document.detachEvent ? + function(element, type, fn) {element.detachEvent('on' + type, fn); } : + function(element, type, fn) { element.removeEventListener(type, fn, false); }); -var removeEventListener = window.document.detachEvent ? - function(element, type, fn) { - element.detachEvent('on' + type, fn); - } : function(element, type, fn) { - element.removeEventListener(type, fn, false); - }; +function jqNextId() { return (jqId++); } function jqClearData(element) { var cacheId = element[jqName], diff --git a/src/services.js b/src/services.js index fa9cdaa4..a5158149 100644 --- a/src/services.js +++ b/src/services.js @@ -1,11 +1,12 @@ +var URL_MATCH = /^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?([^\?#]+)(\?([^#]*))?(#(.*))?$/, + HASH_MATCH = /^([^\?]*)?(\?([^\?]*))?$/, + DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp':21}; + angularService("$window", bind(window, identity, window)); angularService("$document", function(window){ return jqLite(window.document); }, {inject:['$window']}); -var URL_MATCH = /^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?([^\?#]+)(\?([^#]*))?(#(.*))?$/; -var HASH_MATCH = /^([^\?]*)?(\?([^\?]*))?$/; -var DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp':21}; angularService("$location", function(browser){ var scope = this, location = {parse:parseUrl, toString:toString, update:update}, -- cgit v1.2.3 From 946b5284cdcfde587bedf059e9beadee7da9f91b Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Wed, 11 Aug 2010 13:33:21 -0700 Subject: fix the other jstest driver conf --- jsTestDriver-jquery.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsTestDriver-jquery.conf b/jsTestDriver-jquery.conf index e5dac727..ed58d269 100644 --- a/jsTestDriver-jquery.conf +++ b/jsTestDriver-jquery.conf @@ -8,9 +8,9 @@ load: - src/Angular.js - src/JSON.js - src/*.js + - test/testabilityPatch.js - src/scenario/Runner.js - src/scenario/*.js - - test/testabilityPatch.js - test/angular-mocks.js - test/scenario/*.js - test/*.js -- cgit v1.2.3 From 577ddaa5392dfad3b984515de0ad9262764a8721 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Fri, 13 Aug 2010 09:31:06 -0700 Subject: Pull in Rajat's changes to add click and url checking dsl --- src/scenario/DSL.js | 50 ++++++++++++++++++++++++++++++++++++------------ test/scenario/DSLSpec.js | 45 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index 3b049dc6..ca944014 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -1,5 +1,6 @@ angular.scenario.dsl.browser = { navigateTo: function(url){ + var location = this.location; return $scenario.addFuture('Navigate to: ' + url, function(done){ var self = this; this.testFrame.load(function(){ @@ -15,8 +16,22 @@ angular.scenario.dsl.browser = { this.testFrame[0].contentWindow.location.reload(); } else { this.testFrame.attr('src', url); + location.setLocation(url); } }); + }, + location: { + href: "", + hash: "", + toEqual: function(url) { + return (this.hash == "" ? (url == this.href) : + (url == (this.href + "/#/" + this.hash))); + }, + setLocation: function(url) { + var urlParts = url.split("/#/"); + this.href = urlParts[0] || ""; + this.hash = urlParts[1] || ""; + } } }; @@ -88,17 +103,28 @@ angular.scenario.dsl.repeater = function(selector) { angular.scenario.dsl.element = function(selector) { var nameSuffix = "element '" + selector + "'"; - return $scenario.addFuture('Find ' + nameSuffix, function(done) { - var self = this, repeaterArray = [], ngBindPattern; - var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); - if (startIndex >= 0) { - ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); - var element = this.testDocument.find('*').filter(function() { - return self.jQuery(this).attr('ng:bind') == ngBindPattern; - }); - done(element); - } else { - done(this.testDocument.find(selector)); + return { + find: function() { + return $scenario.addFuture('Find ' + nameSuffix, function(done) { + var self = this, repeaterArray = [], ngBindPattern; + var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); + var element = this.testDocument.find('*').filter(function() { + return self.jQuery(this).attr('ng:bind') == ngBindPattern; + }); + done(element); + } else { + done(this.testDocument.find(selector)); + } + }); + }, + click: function() { + var self = this; + return $scenario.addFuture('Click ' + nameSuffix, function(done) { + _jQuery(self).click(); + done(); + }); } - }); + }; }; diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index c8e30917..9bf6d31d 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -6,10 +6,12 @@ describe("DSL", function() { setUpContext(); executeFuture = function(future, html, callback) { lastDocument = _jQuery('
' + html + '
'); + lastFrame = _jQuery(''); _jQuery(document.body).append(lastDocument); var specThis = { testWindow: window, testDocument: lastDocument, + testFrame: lastFrame, jQuery: _jQuery }; future.behavior.call(specThis, callback || noop); @@ -39,6 +41,38 @@ describe("DSL", function() { }); }); + describe('browser', function() { + var browser = angular.scenario.dsl.browser; + it('shoud return true if location with empty hash provided is same ' + + 'as location of the page', function() { + browser.location.href = "http://server"; + expect(browser.location.toEqual("http://server")).toEqual(true); + }); + it('shoud return true if location with hash provided is same ' + + 'as location of the page', function() { + browser.location.href = "http://server"; + browser.location.hash = "hashPath"; + expect(browser.location.toEqual("http://server/#/hashPath")) + .toEqual(true); + }); + it('should return true if the location provided is the same as which ' + + 'browser navigated to', function() { + var future = browser.navigateTo("http://server/#/hashPath"); + expect(future.name).toEqual("Navigate to: http://server/#/hashPath"); + executeFuture(future, ''); + expect(browser.location.toEqual("http://server/#/hashPath")) + .toEqual(true); + expect(browser.location.toEqual("http://server/")) + .toEqual(false); + + future = browser.navigateTo("http://server/"); + expect(future.name).toEqual("Navigate to: http://server/"); + executeFuture(future, ''); + expect(browser.location.toEqual("http://server/")) + .toEqual(true); + }); + }); + describe('repeater', function() { var repeater = angular.scenario.dsl.repeater; @@ -125,7 +159,7 @@ describe("DSL", function() { expect(future.fulfilled).toBeTruthy(); } it('should find elements on the page and provide jquery api', function() { - var future = element('.reports-detail'); + var future = element('.reports-detail').find(); expect(future.name).toEqual("Find element '.reports-detail'"); timeTravel(future); expect(future.value.text()). @@ -134,11 +168,18 @@ describe("DSL", function() { toEqual('Description : Details...'); }); it('should find elements with angular syntax', function() { - var future = element('{{report.description}}'); + var future = element('{{report.description}}').find(); expect(future.name).toEqual("Find element '{{report.description}}'"); timeTravel(future); expect(future.value.text()).toEqual('Details...'); expect(future.value.attr('ng:bind')).toEqual('report.description'); }); + it('should be able to click elements', function(){ + var future = element('.link-class').click(); + expect(future.name).toEqual("Click element '.link-class'"); + executeFuture(future, html, function(value) { future.fulfill(value); }); + expect(future.fulfilled).toBeTruthy(); + // TODO(rajat): look for some side effect from click happening? + }); }); }); -- cgit v1.2.3 From 2767d7773f2e480552e9968eded31bd2b08bec71 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Fri, 13 Aug 2010 09:45:56 -0700 Subject: Revert click dsl, since what is returned by element is a jquery object --- src/scenario/DSL.js | 35 ++++++++++++----------------------- test/scenario/DSLSpec.js | 7 ------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index ca944014..a64f8548 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -103,28 +103,17 @@ angular.scenario.dsl.repeater = function(selector) { angular.scenario.dsl.element = function(selector) { var nameSuffix = "element '" + selector + "'"; - return { - find: function() { - return $scenario.addFuture('Find ' + nameSuffix, function(done) { - var self = this, repeaterArray = [], ngBindPattern; - var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); - if (startIndex >= 0) { - ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); - var element = this.testDocument.find('*').filter(function() { - return self.jQuery(this).attr('ng:bind') == ngBindPattern; - }); - done(element); - } else { - done(this.testDocument.find(selector)); - } - }); - }, - click: function() { - var self = this; - return $scenario.addFuture('Click ' + nameSuffix, function(done) { - _jQuery(self).click(); - done(); - }); + return $scenario.addFuture('Find ' + nameSuffix, function(done) { + var self = this, repeaterArray = [], ngBindPattern; + var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); + var element = this.testDocument.find('*').filter(function() { + return self.jQuery(this).attr('ng:bind') == ngBindPattern; + }); + done(element); + } else { + done(this.testDocument.find(selector)); } - }; + }); }; diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index 9bf6d31d..ccd9e32b 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -174,12 +174,5 @@ describe("DSL", function() { expect(future.value.text()).toEqual('Details...'); expect(future.value.attr('ng:bind')).toEqual('report.description'); }); - it('should be able to click elements', function(){ - var future = element('.link-class').click(); - expect(future.name).toEqual("Click element '.link-class'"); - executeFuture(future, html, function(value) { future.fulfill(value); }); - expect(future.fulfilled).toBeTruthy(); - // TODO(rajat): look for some side effect from click happening? - }); }); }); -- cgit v1.2.3 From 5c14a35e6210fb8500456b3b4ca026cfeb889776 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 13 Aug 2010 09:50:03 -0700 Subject: initial perf testing --- perf/blank.html | 33 ++++ perf/buzz.css | 89 +++++++++ perf/buzz.html | 86 +++++++++ perf/buzz_raw.html | 548 +++++++++++++++++++++++++++++++++++++++++++++++++++++ perf/startup.html | 32 ---- src/Scope.js | 2 +- 6 files changed, 757 insertions(+), 33 deletions(-) create mode 100644 perf/blank.html create mode 100644 perf/buzz.css create mode 100644 perf/buzz.html create mode 100644 perf/buzz_raw.html delete mode 100644 perf/startup.html diff --git a/perf/blank.html b/perf/blank.html new file mode 100644 index 00000000..f38c368b --- /dev/null +++ b/perf/blank.html @@ -0,0 +1,33 @@ + + + + + + + + + reload +
+ READY + + diff --git a/perf/buzz.css b/perf/buzz.css new file mode 100644 index 00000000..5fd5763d --- /dev/null +++ b/perf/buzz.css @@ -0,0 +1,89 @@ +body { + background: -webkit-gradient(linear, left top, left 100, from(#bbb), to(#fff)); + background-repeat: no-repeat; + margin: 0px; + font-family: sans-serif; + font-size: 12px; +} + +body > div { + border-top: 1px solid white; + border-bottom: 1px solid black; + text-align: center; + background: -webkit-gradient(linear, left top, left bottom, from(#CCC), to(#888)); + -webkit-background-origin: padding; -webkit-background-clip: content; +} +body > div button { + margin: 5px; +} + +body > div span:FIRST-CHILD { + float: left; + font-family: monospace; + font-size: 1.5em; + color: black; + padding: 2px 5px; +} + +body > div span:last-child { + float: right; +} + +ul { + list-style: none; + padding: 10px; + margin: 0; +} + +body > ul > li { + border: 1px solid black; + margin: 15px 5px; + padding: 0; + -webkit-box-shadow: 5px 5px 5px #888; +} + +body > ul > li > h1 { + margin: 0; + background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#999)); + font-size: 13px; + border-bottom: 1px solid black; +} + +h1 > img, +li > img { + max-height: 30px; + max-width: 30px; + vertical-align: middle; + padding: 3px; +} + +a > img { + margin-right: 5px; + margin-top: 5px; +} + +body > ul > li > h1 > a:last-child { + float: right; + margin: 10px; +} + +body > ul > li > div { + background-color: white; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ddd)); + margin: 0; + padding: 10px; +} + +body > ul > li ul { + margin: 0; + padding: 0; + margin-left: 5px; + border-left: 5px solid lightgray; +} + +body > ul > li ul > li { + margin: 0; + padding: 10px; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ddd)); +} + diff --git a/perf/buzz.html b/perf/buzz.html new file mode 100644 index 00000000..1d0e155c --- /dev/null +++ b/perf/buzz.html @@ -0,0 +1,86 @@ + + + + + + + + + + + + reload +
+
+ <angular/> Buzz + + filter: + + + + user: + + + +
+ + +
+ + diff --git a/perf/buzz_raw.html b/perf/buzz_raw.html new file mode 100644 index 00000000..fb1144af --- /dev/null +++ b/perf/buzz_raw.html @@ -0,0 +1,548 @@ + + + + + + + + + + reload +
+
+ <angular/> Buzz + + filter: + + + + user: + + + +
+ + +
+ + diff --git a/perf/startup.html b/perf/startup.html deleted file mode 100644 index 91a46898..00000000 --- a/perf/startup.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - reload -
- READY - - diff --git a/src/Scope.js b/src/Scope.js index 30e56915..27fafc3a 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -76,7 +76,7 @@ function getterFn(path){ code += ' type = angular.Global.typeOf(last);\n'; code += ' fn = (angular[type.charAt(0).toUpperCase() + type.substring(1)]||{})["' + name + '"];\n'; code += ' if (fn)\n'; - code += ' self = function(){ return fn.apply(last, [last].concat(slice.call(arguments, 0, arguments.length))); };\n'; + code += ' self = function(){ return fn.apply(last, [last].concat(Array.prototype.slice.call(arguments, 0, arguments.length))); };\n'; code += ' }\n'; } }); -- cgit v1.2.3 From 449d2ef7246b029eb927261526dc1b907ffa3734 Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Sat, 14 Aug 2010 00:31:06 +0800 Subject: Pull in Rajat's changes to add click and url checking dsl --- src/scenario/DSL.js | 50 ++++++++++++++++++++++++++++++++++++------------ test/scenario/DSLSpec.js | 45 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index 3b049dc6..ca944014 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -1,5 +1,6 @@ angular.scenario.dsl.browser = { navigateTo: function(url){ + var location = this.location; return $scenario.addFuture('Navigate to: ' + url, function(done){ var self = this; this.testFrame.load(function(){ @@ -15,8 +16,22 @@ angular.scenario.dsl.browser = { this.testFrame[0].contentWindow.location.reload(); } else { this.testFrame.attr('src', url); + location.setLocation(url); } }); + }, + location: { + href: "", + hash: "", + toEqual: function(url) { + return (this.hash == "" ? (url == this.href) : + (url == (this.href + "/#/" + this.hash))); + }, + setLocation: function(url) { + var urlParts = url.split("/#/"); + this.href = urlParts[0] || ""; + this.hash = urlParts[1] || ""; + } } }; @@ -88,17 +103,28 @@ angular.scenario.dsl.repeater = function(selector) { angular.scenario.dsl.element = function(selector) { var nameSuffix = "element '" + selector + "'"; - return $scenario.addFuture('Find ' + nameSuffix, function(done) { - var self = this, repeaterArray = [], ngBindPattern; - var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); - if (startIndex >= 0) { - ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); - var element = this.testDocument.find('*').filter(function() { - return self.jQuery(this).attr('ng:bind') == ngBindPattern; - }); - done(element); - } else { - done(this.testDocument.find(selector)); + return { + find: function() { + return $scenario.addFuture('Find ' + nameSuffix, function(done) { + var self = this, repeaterArray = [], ngBindPattern; + var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); + var element = this.testDocument.find('*').filter(function() { + return self.jQuery(this).attr('ng:bind') == ngBindPattern; + }); + done(element); + } else { + done(this.testDocument.find(selector)); + } + }); + }, + click: function() { + var self = this; + return $scenario.addFuture('Click ' + nameSuffix, function(done) { + _jQuery(self).click(); + done(); + }); } - }); + }; }; diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index c8e30917..9bf6d31d 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -6,10 +6,12 @@ describe("DSL", function() { setUpContext(); executeFuture = function(future, html, callback) { lastDocument = _jQuery('
' + html + '
'); + lastFrame = _jQuery(''); _jQuery(document.body).append(lastDocument); var specThis = { testWindow: window, testDocument: lastDocument, + testFrame: lastFrame, jQuery: _jQuery }; future.behavior.call(specThis, callback || noop); @@ -39,6 +41,38 @@ describe("DSL", function() { }); }); + describe('browser', function() { + var browser = angular.scenario.dsl.browser; + it('shoud return true if location with empty hash provided is same ' + + 'as location of the page', function() { + browser.location.href = "http://server"; + expect(browser.location.toEqual("http://server")).toEqual(true); + }); + it('shoud return true if location with hash provided is same ' + + 'as location of the page', function() { + browser.location.href = "http://server"; + browser.location.hash = "hashPath"; + expect(browser.location.toEqual("http://server/#/hashPath")) + .toEqual(true); + }); + it('should return true if the location provided is the same as which ' + + 'browser navigated to', function() { + var future = browser.navigateTo("http://server/#/hashPath"); + expect(future.name).toEqual("Navigate to: http://server/#/hashPath"); + executeFuture(future, ''); + expect(browser.location.toEqual("http://server/#/hashPath")) + .toEqual(true); + expect(browser.location.toEqual("http://server/")) + .toEqual(false); + + future = browser.navigateTo("http://server/"); + expect(future.name).toEqual("Navigate to: http://server/"); + executeFuture(future, ''); + expect(browser.location.toEqual("http://server/")) + .toEqual(true); + }); + }); + describe('repeater', function() { var repeater = angular.scenario.dsl.repeater; @@ -125,7 +159,7 @@ describe("DSL", function() { expect(future.fulfilled).toBeTruthy(); } it('should find elements on the page and provide jquery api', function() { - var future = element('.reports-detail'); + var future = element('.reports-detail').find(); expect(future.name).toEqual("Find element '.reports-detail'"); timeTravel(future); expect(future.value.text()). @@ -134,11 +168,18 @@ describe("DSL", function() { toEqual('Description : Details...'); }); it('should find elements with angular syntax', function() { - var future = element('{{report.description}}'); + var future = element('{{report.description}}').find(); expect(future.name).toEqual("Find element '{{report.description}}'"); timeTravel(future); expect(future.value.text()).toEqual('Details...'); expect(future.value.attr('ng:bind')).toEqual('report.description'); }); + it('should be able to click elements', function(){ + var future = element('.link-class').click(); + expect(future.name).toEqual("Click element '.link-class'"); + executeFuture(future, html, function(value) { future.fulfill(value); }); + expect(future.fulfilled).toBeTruthy(); + // TODO(rajat): look for some side effect from click happening? + }); }); }); -- cgit v1.2.3 From f6527bd53c1d80c7db549b22ecf3aa02e96cda1f Mon Sep 17 00:00:00 2001 From: Shyam Seshadri Date: Sat, 14 Aug 2010 00:45:56 +0800 Subject: Revert click dsl, since what is returned by element is a jquery object --- src/scenario/DSL.js | 35 ++++++++++++----------------------- test/scenario/DSLSpec.js | 7 ------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js index ca944014..a64f8548 100644 --- a/src/scenario/DSL.js +++ b/src/scenario/DSL.js @@ -103,28 +103,17 @@ angular.scenario.dsl.repeater = function(selector) { angular.scenario.dsl.element = function(selector) { var nameSuffix = "element '" + selector + "'"; - return { - find: function() { - return $scenario.addFuture('Find ' + nameSuffix, function(done) { - var self = this, repeaterArray = [], ngBindPattern; - var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); - if (startIndex >= 0) { - ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); - var element = this.testDocument.find('*').filter(function() { - return self.jQuery(this).attr('ng:bind') == ngBindPattern; - }); - done(element); - } else { - done(this.testDocument.find(selector)); - } - }); - }, - click: function() { - var self = this; - return $scenario.addFuture('Click ' + nameSuffix, function(done) { - _jQuery(self).click(); - done(); - }); + return $scenario.addFuture('Find ' + nameSuffix, function(done) { + var self = this, repeaterArray = [], ngBindPattern; + var startIndex = selector.search(angular.scenario.dsl.NG_BIND_PATTERN); + if (startIndex >= 0) { + ngBindPattern = selector.substring(startIndex + 2, selector.length - 2); + var element = this.testDocument.find('*').filter(function() { + return self.jQuery(this).attr('ng:bind') == ngBindPattern; + }); + done(element); + } else { + done(this.testDocument.find(selector)); } - }; + }); }; diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js index 9bf6d31d..ccd9e32b 100644 --- a/test/scenario/DSLSpec.js +++ b/test/scenario/DSLSpec.js @@ -174,12 +174,5 @@ describe("DSL", function() { expect(future.value.text()).toEqual('Details...'); expect(future.value.attr('ng:bind')).toEqual('report.description'); }); - it('should be able to click elements', function(){ - var future = element('.link-class').click(); - expect(future.name).toEqual("Click element '.link-class'"); - executeFuture(future, html, function(value) { future.fulfill(value); }); - expect(future.fulfilled).toBeTruthy(); - // TODO(rajat): look for some side effect from click happening? - }); }); }); -- cgit v1.2.3 From 68900e2039e80f9279bbde9a56753aaa342a2eb7 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 13 Aug 2010 10:05:25 -0700 Subject: learning about git head --- perf/buzz_raw.html | 1 + 1 file changed, 1 insertion(+) diff --git a/perf/buzz_raw.html b/perf/buzz_raw.html index fb1144af..ff86ff70 100644 --- a/perf/buzz_raw.html +++ b/perf/buzz_raw.html @@ -20,6 +20,7 @@ }; } window.browser = time('boot:'); + @@ -39,8 +41,9 @@ window.browser.lap('parse model'); - - reload + + reload
+ {{line}}

<angular/> Buzz -- cgit v1.2.3 From 26b5ae410970aab022452b5f0aa7f01a3963623a Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Sat, 14 Aug 2010 10:29:50 -0700 Subject: fix __proto__ for ie. --- test/JsonTest.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/JsonTest.js b/test/JsonTest.js index d077c0df..f6da26b5 100644 --- a/test/JsonTest.js +++ b/test/JsonTest.js @@ -75,11 +75,11 @@ JsonTest.prototype.testItShouldPreventRecursion = function () { }; JsonTest.prototype.testItShouldSerializeOnlyOwnProperties = function() { - var parent = { p: 'p'}; - var child = { c: 'c'}; - child.__proto__ = parent; - assertEquals('{"c":"c"}', angular.toJson(child)); -} + var parent = createScope(); + var child = createScope(parent); + child.c = 'c'; + expect(angular.toJson(child)).toEqual('{"c":"c"}'); +}; JsonTest.prototype.testItShouldSerializeSameObjectsMultipleTimes = function () { var obj = {a:'b'}; -- cgit v1.2.3 From 91104f878debd0cd86ba62fed2f30be433200690 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Sat, 14 Aug 2010 11:03:36 -0700 Subject: add ftp script to auto deploy to angularjs.org --- .gitignore | 1 + Rakefile | 6 ++++++ angularjs.ftp | 5 +++++ 3 files changed, 12 insertions(+) create mode 100644 angularjs.ftp diff --git a/.gitignore b/.gitignore index 2631c477..0d5db979 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ angular.js angular-minified.js angular-debug.js angular-scenario.js +angularjs.netrc \ No newline at end of file diff --git a/Rakefile b/Rakefile index de1f7527..c4e53987 100644 --- a/Rakefile +++ b/Rakefile @@ -120,3 +120,9 @@ task :lint do out = %x(lib/jsl/jsl -conf lib/jsl/jsl.default.conf) print out end + +desc 'push_angularajs' +task :push_angularjs do + Rake::Task['compile'].execute 0 + sh %(cat angularjs.ftp | ftp -N angularjs.netrc angularjs.org) +end diff --git a/angularjs.ftp b/angularjs.ftp new file mode 100644 index 00000000..dbe10397 --- /dev/null +++ b/angularjs.ftp @@ -0,0 +1,5 @@ +bin +cd angularjs.org/ng +put angular-debug.js js/angular-debug.js +put angular-minified.js js/angular-minified.js +put angular-scenario.js js/angular-scenario.js -- cgit v1.2.3