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 bf37edce..c4e53987 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 \
@@ -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
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..f2e95c85
--- /dev/null
+++ b/perf/buzz.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+ reload
+ {{line}}
+
+
+ <angular/> Buzz
+
+ filter:
+
+
+
+ user:
+
+ fetch
+
+
+
+
+
+
+ {{item.object.content | html}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/perf/buzz_raw.html b/perf/buzz_raw.html
new file mode 100644
index 00000000..059b80d6
--- /dev/null
+++ b/perf/buzz_raw.html
@@ -0,0 +1,550 @@
+
+
+
+
+
+
+
+
+
+ reload
+
+
+ <angular/> Buzz
+
+ filter:
+
+
+
+ user:
+
+ fetch
+
+
+
+
+
+
+
AutoShare from YouTube to Buzz
+
+ If you use YouTube a lot, you may be familiar with AutoShare (see http://help.youtube.com/support/youtube/bin/answer.py?hl=en&answer=157215 ) which you can use to automatically share your favorites, likes, uploads, or comments on videos to Facebook. Twitter, and Google Reader. Now you can choose to automatically share from YouTube to Google Buzz as well.
+
+ You can still keep YouTube as a connected site in Buzz if you hooked it up previously, but that only automatically posts your uploads for now.
+
+
+
+
+
+
+
+
+
Google Buzz API talks and hackathons
+
+ Come join us to talk about how you can build on Google Buzz -- check out the list below to see if weÍll be in a city near you. We'll cover several open standards (Activity Streams, OAuth, PubSubHubbub, and Salmon) and go in depth with the Google Buzz API and libraries. In some locations weÍll have extended time for hacking with Googlers on hand to answer your questions.
+
+ HereÍs the schedule (weÍll add links for the Cambridge, Kiev, and Moscow sessions soon):
+
+ Sydney, Australia - July 1: http://code.google.com/events/devfests/2010/sydney4.html
+ Manila, Philippines - July 6: http://code.google.com/events/devfests/2010/asia1.html
+ Singapore - July 9: http://code.google.com/events/devfests/2010/asia2.html
+ Kuala Lumpur, Malaysia - July 16: http://code.google.com/events/devfests/2010/asia3.html
+ New York, NY, USA - July 21: http://www.meetup.com/NYC-GTUG/calendar/13899003/
+ Cambridge, MA, USA - August 7
+ Stockholm, Sweden - July 12: extra gtug mte juli
+ Berlin, Germany - July 15: http://www.berlin-gtug.org/2010/06/july-2010-berlin-gtug-meeting.html
+ Kiev, Ukraine - July 17
+ Moscow, Russia - July 19
+ Lisbon, Portugal - July 28th: https://spreadsheets.google.com/a/google.com/viewform?formkey=dFd5aFo3WVVUX2xaeUZOVDJJVlo1ekE6MQ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
New! Comments and likes tabs on your profile
+
+ Many of you have asked for an easy way to refer back to the posts you've commented on and/or liked. Some of you have also requested a way to see what other people have commented on or liked -- a great way to discover posts that may interest you too.
+
+ Starting today, you'll see new tabs on your profile that show all the posts you've commented on or liked. By default, these tabs are only visible to you. If you want to share your comments and likes tabs, you can choose to make them publicly visible to others from the Buzz tab under Settings. This won't change who can see each post; private posts stay private.
+
+
+
+
+
+
+
+
+
Fighting follower spam
+
+ Any web service that involves following has to fight "follower spam" -- accounts that follow lots and lots of people in the hopes that some of them will click through to their profiles and a few might even end up buying whatever it is they're selling. Buzz is no different. If you're getting following notices from Buzz users with names that sound suspiciously like spammy marketing scams, the chances are that's exactly what they are -- and we're after them. Just like we work hard to protect your Gmail accounts from email spam, we're working to protect Buzz from follower spam. We look at lots of factors when determining whether to disable an account for follower spam including the number of people it attempts to follow and whether people are blocking it. And just as we're constantly tweaking the algorithms which detect Gmail spam, the same goes for follower spam in Buzz.
+
+ If you're followed by any suspicious looking users, you can report them by clicking the "Report this profile" link on their profile. If they aren't really suspicious but you just don't want them following you, you can always block them.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Two quick Buzz for mobile updates
+
+ Yesterday we rolled out a new design for rendering location attached to posts, including a better place icon, a bigger map, and an easy way to get directions from the post itself.
+
+ In addition, you can now disable comments from Buzz for mobile. (Look for this option under "More Actions").
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
If you started using Google Buzz before we changed the start-up experience from auto-following to suggestions for people to follow, we want to help you ensure that Buzz is set up the way you want. So the next time you click into the Buzz tab you'll see a page asking you to confirm your Buzz settings -- you can review and edit your settings from here, or at anytime from the Buzz tab of Gmail Settings.
+
+ For more info, check out this post on the Gmail blog: http://gmailblog.blogspot.com/2010/04/confirm-your-buzz-settings.html
+
+
+
+
+
+
+
+
+
Hey all -- this is the account for the Google Buzz team. We'll post all sorts of updates here about what we're working on. Feel free to give us feedback and ideas on Google Buzz!
+
+ Here's a photo of our launch "war room" from last week. :-)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
New! View entire photo albums in Buzz
+
+ Tired of only being able to view a handful of photos from a given Flickr or Picasa album in Buzz's photo viewer? Now you can view the entire thing.
+
+ @Thomas Hawk -- we thought you'd appreciate this ;)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Reshare from your mobile device
+
+ For the last month or so, you've been able to reshare interesting buzz posts from your computer (see http://gmailblog.blogspot.com/2010/05/reshare-in-google-buzz.html for more info).
+
+ Today, we're excited to announce that we've enabled this feature for buzz.google.com on Android and iPhone as well. (If you don't see it right away, try clearing your cache/cookies.)
+
+
+
+
+
+
+
+
+
In San Francisco or Toronto? Come chat with the Buzz for mobile team and other Buzz users.
+
+ Google Buzz can be a great place to have a conversation, but we all know face-to-face interactions are still invaluable. Many of you have suggested in person meet ups to mingle and chat with other people using Google Buzz, so we're having our first meet ups focused on Buzz for mobile next week in San Francisco and Toronto. Join @Punit Soni and @Robin Norvell from the Buzz for mobile team as well as other users for what promises to be an interesting discussion.
+
+ San Francisco meet up
+ Tuesday, June 22nd 6pm
+ Axis Cafe
+ 1201 8th Street
+ San Francisco, CA 94107
+
+ Toronto meet up*
+ Tuesday, June 29th 7pm
+ linuxcaffe
+ 326 Harbord Street
+ Toronto, ON M6G 1H3
+
+ * Updated with new Toronto location
+
+
+
+
+
+
+
+
+
+
+
Two quick Google Buzz for mobile updates
+
+ Today we released two new features for buzz.google.com on your phone.
+
+Address auto-complete for @replies: Just type @ and the first few letters of the person's name and you'll be prompted with email addresses to choose from. Less typing on tiny mobile keyboards = good ;) You may notice that the first time you do this it seems a little slow to load, but it should get faster after that.
+
+Full rendering of Google Reader shared items: You'll now see more details from blogs/Reader shared items right in the post.
+
+ Try these out and let us know what you think in the comments.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Reshare - coming out today!
+
+ When you find an interesting buzz post you want to reshare, instead of copying and pasting it (and maybe attributing the original poster with an @reply along the way), you'll now be able to reshare posts with two clicks. If you don't see the "Reshare" link quite yet, hang tight. It should be on for everyone by the end of the day.
+
+ Learn more at: http://gmailblog.blogspot.com/2010/05/reshare-in-google-buzz.html
+
+
+
+
+
+
+
+
+
Tweets with location now showing with Buzz on the map
+
+ If you've added Twitter as a connected site in Google Buzz and your tweets have a location (via Twitter or other services), they'll now appear in the mobile buzz.google.com "Nearby" view and on the Buzz layer in Google Maps (both mobile and desktop). Check out one of these views to see buzz posts, tweets and more around you.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Angular.js b/src/Angular.js
index e11a0679..3970f762 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -291,30 +291,20 @@ 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;
}
}
-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/JSON.js b/src/JSON.js
index ba3d700e..49ed0b29 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..27fafc3a 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",
@@ -75,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';
}
});
@@ -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/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/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;
+angularFilter.currency = function(amount){
+ this.$element.toggleClass('ng:format-negative', amount < 0);
+ return '$' + angularFilter['number'].apply(this, [amount, 2]);
+};
-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;
- }
- return null;
- },
-
- 'lowercase': lowercase,
-
- 'uppercase': uppercase,
-
- 'linecount': function (obj) {
- if (isString(obj)) {
- if (obj==='') return 1;
- return obj.split(/\n|\f/).length;
- }
- 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('|');
- },
-
- '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;
- },
-
- '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;
- }
- }
- ),
-
-
- '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);
- }
- },
-
- '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.number = function(amount, fractionSize){
+ if (isNaN(amount) || !isFinite(amount)) {
+ return '';
}
-}, function(v,k){angularFilter[k] = v;});
+ 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;
+};
-angularFilterGoogleChartApi = angularFilter['googleChartApi'];
+angularFilter.date = function(date) {
+ if (date instanceof Date)
+ return date.toLocaleDateString();
+ else
+ return date;
+};
+
+angularFilter.json = function(object) {
+ this.$element.addClass("ng-monospace");
+ return toJson(object, true);
+};
+
+angularFilter.lowercase = lowercase;
+
+angularFilter.uppercase = uppercase;
+
+angularFilter.html = function(html){
+ return new HTML(html);
+};
+
+angularFilter.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(''));
+};
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";
- }),
-
- '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.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";
});
+
+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;
+ }
+);
+
+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,25 +2,18 @@
//JQLite
//////////////////////////////////
-var jqCache = {};
-var jqName = 'ng-' + new Date().getTime();
-var jqId = 1;
+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); });
+
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 removeEventListener = window.document.detachEvent ?
- function(element, type, fn) {
- element.detachEvent('on' + type, fn);
- } : function(element, type, fn) {
- element.removeEventListener(type, fn, false);
- };
-
function jqClearData(element) {
var cacheId = element[jqName],
cache = jqCache[cacheId];
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
index 3b049dc6..0607238c 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] || "";
+ }
}
};
@@ -87,18 +102,30 @@ 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));
- }
- });
+ var namePrefix = "Element '" + selector + "'";
+ var futureJquery = {};
+ for (key in (jQuery || _jQuery).fn) {
+ (function(){
+ var jqFnName = key;
+ var jqFn = (jQuery || _jQuery).fn[key];
+ futureJquery[key] = function() {
+ var jqArgs = arguments;
+ return $scenario.addFuture(namePrefix + "." + jqFnName + "()",
+ 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(jqFn.apply(element, jqArgs));
+ } else {
+ done(jqFn.apply(this.testDocument.find(selector), jqArgs));
+ }
+ });
+ };
+ })();
+ }
+ return futureJquery;
};
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},
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));
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("ac d");
expect(html instanceof HTML).toBeTruthy();
@@ -140,4 +68,3 @@ FiltersTest.prototype.testLinky = function() {
assertEquals(undefined, linky(undefined));
};
-
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'};
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 278f9c4c..f0eb5c09 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -216,6 +216,12 @@ describe("directives", function(){
});
});
+ it('should silently ignore undefined ng:style', function() {
+ var scope = compile('
');
+ scope.$eval();
+ expect(element.hasClass('ng-exception')).toBeFalsy();
+ });
+
it('should ng:show', function(){
var scope = compile('
');
scope.$eval();
diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js
index c8e30917..f8606641 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,20 +159,27 @@ describe("DSL", function() {
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'");
+ var future = element('.reports-detail').text();
+ expect(future.name).toEqual("Element '.reports-detail'.text()");
timeTravel(future);
- expect(future.value.text()).
+ expect(future.value).
toEqual('Description : Details...Date created: 01/01/01');
- expect(future.value.find('.desc').text()).
- toEqual('Description : Details...');
+// expect(future.value.find('.desc').text()).
+// toEqual('Description : Details...');
});
it('should find elements with angular syntax', function() {
- var future = element('{{report.description}}');
- expect(future.name).toEqual("Find element '{{report.description}}'");
+ var future = element('{{report.description}}').text();
+ expect(future.name).toEqual("Element '{{report.description}}'.text()");
timeTravel(future);
- expect(future.value.text()).toEqual('Details...');
- expect(future.value.attr('ng:bind')).toEqual('report.description');
+ expect(future.value).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("Element '.link-class'.click()");
+ executeFuture(future, html, function(value) { future.fulfill(value); });
+ expect(future.fulfilled).toBeTruthy();
+ // TODO(rajat): look for some side effect from click happening?
});
});
});