mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-21 04:41:51 +00:00
Refactored the Browser:
- change from using prototype to inner functions to help with better compression - removed watchers (url/cookie) and introduced a poller concept - moved the checking of URL and cookie into services which register with poolers Benefits: - Smaller minified file - can call $browser.poll() from tests to simulate polling - single place where setTimeout needs to be tested - More testable $browser
This commit is contained in:
parent
eefb920d0e
commit
0649009624
11 changed files with 207 additions and 260 deletions
2
Rakefile
2
Rakefile
|
|
@ -121,7 +121,7 @@ task :lint do
|
||||||
print out
|
print out
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'push_angularajs'
|
desc 'push_angularjs'
|
||||||
task :push_angularjs do
|
task :push_angularjs do
|
||||||
Rake::Task['compile'].execute 0
|
Rake::Task['compile'].execute 0
|
||||||
sh %(cat angularjs.ftp | ftp -N angularjs.netrc angularjs.org)
|
sh %(cat angularjs.ftp | ftp -N angularjs.netrc angularjs.org)
|
||||||
|
|
|
||||||
22
scenario/browser.html
Normal file
22
scenario/browser.html
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html xmlns:ng="http://angularjs.org">
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
|
||||||
|
</head>
|
||||||
|
<body ng:init="$window.$scope = this">
|
||||||
|
|
||||||
|
<h1>Should mark input field red and create hover</h1>
|
||||||
|
<input type="text" name="name" ng:required/>
|
||||||
|
|
||||||
|
<h1>Should reflect changes in URL</h1>
|
||||||
|
<pre>$location={{$location}}</pre>
|
||||||
|
hash: <input type="text" name="$location.hash"/> <br/>
|
||||||
|
hashPath: <input type="text" name="$location.hashPath"/> <br/>
|
||||||
|
hashSearch: <input type="text" name="$location.hashSearch" ng:format="json"/> <br/>
|
||||||
|
|
||||||
|
<h1>Should reflect changes in Cookie</h1>
|
||||||
|
<pre>$cookies={{$cookies}}</pre>
|
||||||
|
$cookies: <input type="text" name="$cookies" ng:format="json"/> <br/>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns:ng="http://angularjs.org">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||||
<script type="text/javascript" src="../src/angular-bootstrap.js#autobind"></script>
|
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
|
||||||
</head>
|
</head>
|
||||||
<body ng:init="$window.$scope = this">
|
<body ng:init="$window.$scope = this">
|
||||||
<table>
|
<table>
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ var _undefined = undefined,
|
||||||
msie = !!/(msie) ([\w.]+)/.exec(lowercase(navigator.userAgent)),
|
msie = !!/(msie) ([\w.]+)/.exec(lowercase(navigator.userAgent)),
|
||||||
jqLite = jQuery || jqLiteWrap,
|
jqLite = jQuery || jqLiteWrap,
|
||||||
slice = Array.prototype.slice,
|
slice = Array.prototype.slice,
|
||||||
|
push = Array.prototype.push,
|
||||||
error = window[$console] ? bind(window[$console], window[$console]['error'] || noop) : noop,
|
error = window[$console] ? bind(window[$console], window[$console]['error'] || noop) : noop,
|
||||||
angular = window[$angular] || (window[$angular] = {}),
|
angular = window[$angular] || (window[$angular] = {}),
|
||||||
angularTextMarkup = extensionMap(angular, 'markup'),
|
angularTextMarkup = extensionMap(angular, 'markup'),
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ angularService('$browser', function browserFactory(){
|
||||||
browserSingleton = new Browser(
|
browserSingleton = new Browser(
|
||||||
window.location,
|
window.location,
|
||||||
jqLite(window.document),
|
jqLite(window.document),
|
||||||
jqLite(window.document.getElementsByTagName('head')[0]));
|
jqLite(window.document.getElementsByTagName('head')[0]),
|
||||||
browserSingleton.startUrlWatcher();
|
XHR);
|
||||||
browserSingleton.startCookieWatcher();
|
browserSingleton.startPoller(50, function(delay, fn){setTimeout(delay,fn);});
|
||||||
browserSingleton.bind();
|
browserSingleton.bind();
|
||||||
}
|
}
|
||||||
return browserSingleton;
|
return browserSingleton;
|
||||||
|
|
|
||||||
263
src/Browser.js
263
src/Browser.js
|
|
@ -1,45 +1,118 @@
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Browser
|
// Browser
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
var XHR = window.XMLHttpRequest || function () {
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
|
||||||
|
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
|
||||||
|
throw new Error("This browser does not support XMLHttpRequest.");
|
||||||
|
};
|
||||||
|
|
||||||
function Browser(location, document, head) {
|
function Browser(location, document, head, XHR) {
|
||||||
this.delay = 50;
|
var self = this;
|
||||||
this.expectedUrl = location.href;
|
self.isMock = false;
|
||||||
this.urlListeners = [];
|
|
||||||
this.hoverListener = noop;
|
|
||||||
this.isMock = false;
|
|
||||||
this.outstandingRequests = { count: 0, callbacks:[]};
|
|
||||||
|
|
||||||
this.XHR = window.XMLHttpRequest || function () {
|
//////////////////////////////////////////////////////////////
|
||||||
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
|
// XHR API
|
||||||
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
|
//////////////////////////////////////////////////////////////
|
||||||
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
|
var idCounter = 0;
|
||||||
throw new Error("This browser does not support XMLHttpRequest.");
|
var outstandingRequestCount = 0;
|
||||||
};
|
var outstandingRequestCallbacks = [];
|
||||||
this.setTimeout = function(fn, delay) {
|
|
||||||
window.setTimeout(fn, delay);
|
self.xhr = function(method, url, post, callback){
|
||||||
|
if (isFunction(post)) {
|
||||||
|
callback = post;
|
||||||
|
post = _null;
|
||||||
|
}
|
||||||
|
if (lowercase(method) == 'json') {
|
||||||
|
var callbackId = "angular_" + Math.random() + '_' + (idCounter++);
|
||||||
|
callbackId = callbackId.replace(/\d\./, '');
|
||||||
|
var script = document[0].createElement('script');
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = url.replace('JSON_CALLBACK', callbackId);
|
||||||
|
head.append(script);
|
||||||
|
window[callbackId] = function(data){
|
||||||
|
window[callbackId] = _undefined;
|
||||||
|
callback(200, data);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
var xhr = new XHR();
|
||||||
|
xhr.open(method, url, true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
|
||||||
|
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
||||||
|
outstandingRequestCount ++;
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState == 4) {
|
||||||
|
try {
|
||||||
|
callback(xhr.status || 200, xhr.responseText);
|
||||||
|
} finally {
|
||||||
|
outstandingRequestCount--;
|
||||||
|
if (outstandingRequestCount === 0) {
|
||||||
|
while(outstandingRequestCallbacks.length) {
|
||||||
|
try {
|
||||||
|
outstandingRequestCallbacks.pop()();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(post || '');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.location = location;
|
self.notifyWhenNoOutstandingRequests = function(callback){
|
||||||
this.document = document;
|
if (outstandingRequestCount === 0) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
outstandingRequestCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Poll Watcher API
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
var pollFns = [];
|
||||||
|
function poll(){
|
||||||
|
foreach(pollFns, function(pollFn){ pollFn(); });
|
||||||
|
}
|
||||||
|
self.poll = poll;
|
||||||
|
self.addPollFn = bind(pollFns, push);
|
||||||
|
self.startPoller = function(interval, setTimeout){
|
||||||
|
(function check(){
|
||||||
|
poll();
|
||||||
|
setTimeout(check, interval);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// URL API
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
self.setUrl = function(url) {
|
||||||
|
var existingURL = location.href;
|
||||||
|
if (!existingURL.match(/#/)) existingURL += '#';
|
||||||
|
if (!url.match(/#/)) url += '#';
|
||||||
|
location.href = url;
|
||||||
|
};
|
||||||
|
self.getUrl = function() {
|
||||||
|
return location.href;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Cookies API
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
var rawDocument = document[0];
|
var rawDocument = document[0];
|
||||||
this.head = head;
|
|
||||||
this.idCounter = 0;
|
|
||||||
|
|
||||||
this.cookies = cookies;
|
|
||||||
this.watchCookies = function(fn){ cookieListeners.push(fn); };
|
|
||||||
|
|
||||||
// functions
|
|
||||||
var lastCookies = {};
|
var lastCookies = {};
|
||||||
var lastCookieString = '';
|
var lastCookieString = '';
|
||||||
var cookieListeners = [];
|
|
||||||
/**
|
/**
|
||||||
* cookies() -> hash of all cookies
|
* cookies() -> hash of all cookies
|
||||||
* cookies(name, value) -> set name to value
|
* cookies(name, value) -> set name to value
|
||||||
* if value is undefined delete it
|
* if value is undefined delete it
|
||||||
* cookies(name) -> should get value, but deletes (no one calls it right now that way)
|
* cookies(name) -> should get value, but deletes (no one calls it right now that way)
|
||||||
*/
|
*/
|
||||||
function cookies(name, value){
|
self.cookies = function (name, value){
|
||||||
if (name) {
|
if (name) {
|
||||||
if (value === _undefined) {
|
if (value === _undefined) {
|
||||||
delete lastCookies[name];
|
delete lastCookies[name];
|
||||||
|
|
@ -59,139 +132,33 @@ function Browser(location, document, head) {
|
||||||
lastCookies[unescape(keyValue[0])] = unescape(keyValue[1]);
|
lastCookies[unescape(keyValue[0])] = unescape(keyValue[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(cookieListeners, function(fn){
|
|
||||||
fn(lastCookies);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return lastCookies;
|
return lastCookies;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
Browser.prototype = {
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Misc API
|
||||||
bind: function() {
|
//////////////////////////////////////////////////////////////
|
||||||
var self = this;
|
var hoverListener = noop;
|
||||||
self.document.bind("mouseover", function(event){
|
self.hover = function(listener) { hoverListener = listener; };
|
||||||
self.hoverListener(jqLite(msie ? event.srcElement : event.target), true);
|
self.bind = function() {
|
||||||
|
document.bind("mouseover", function(event){
|
||||||
|
hoverListener(jqLite(msie ? event.srcElement : event.target), true);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
self.document.bind("mouseleave mouseout click dblclick keypress keyup", function(event){
|
document.bind("mouseleave mouseout click dblclick keypress keyup", function(event){
|
||||||
self.hoverListener(jqLite(event.target), false);
|
hoverListener(jqLite(event.target), false);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
hover: function(hoverListener) {
|
|
||||||
this.hoverListener = hoverListener;
|
|
||||||
},
|
|
||||||
|
|
||||||
addCss: function(url) {
|
self.addCss = function(url) {
|
||||||
var doc = this.document[0],
|
var link = jqLite(rawDocument.createElement('link'));
|
||||||
head = jqLite(doc.getElementsByTagName('head')[0]),
|
|
||||||
link = jqLite(doc.createElement('link'));
|
|
||||||
link.attr('rel', 'stylesheet');
|
link.attr('rel', 'stylesheet');
|
||||||
link.attr('type', 'text/css');
|
link.attr('type', 'text/css');
|
||||||
link.attr('href', url);
|
link.attr('href', url);
|
||||||
head.append(link);
|
head.append(link);
|
||||||
},
|
};
|
||||||
|
}
|
||||||
xhr: function(method, url, post, callback){
|
|
||||||
if (isFunction(post)) {
|
|
||||||
callback = post;
|
|
||||||
post = _null;
|
|
||||||
}
|
|
||||||
if (lowercase(method) == 'json') {
|
|
||||||
var callbackId = "angular_" + Math.random() + '_' + (this.idCounter++);
|
|
||||||
callbackId = callbackId.replace(/\d\./, '');
|
|
||||||
var script = this.document[0].createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = url.replace('JSON_CALLBACK', callbackId);
|
|
||||||
this.head.append(script);
|
|
||||||
window[callbackId] = function(data){
|
|
||||||
window[callbackId] = _undefined;
|
|
||||||
callback(200, data);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
var xhr = new this.XHR(),
|
|
||||||
self = this;
|
|
||||||
xhr.open(method, url, true);
|
|
||||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
|
|
||||||
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
||||||
this.outstandingRequests.count ++;
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState == 4) {
|
|
||||||
try {
|
|
||||||
callback(xhr.status || 200, xhr.responseText);
|
|
||||||
} finally {
|
|
||||||
self.outstandingRequests.count--;
|
|
||||||
self.processRequestCallbacks();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send(post || '');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
processRequestCallbacks: function(){
|
|
||||||
if (this.outstandingRequests.count === 0) {
|
|
||||||
while(this.outstandingRequests.callbacks.length) {
|
|
||||||
try {
|
|
||||||
this.outstandingRequests.callbacks.pop()();
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
notifyWhenNoOutstandingRequests: function(callback){
|
|
||||||
if (this.outstandingRequests.count === 0) {
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
this.outstandingRequests.callbacks.push(callback);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watchUrl: function(fn){
|
|
||||||
this.urlListeners.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
startUrlWatcher: function() {
|
|
||||||
var self = this;
|
|
||||||
(function pull () {
|
|
||||||
if (self.expectedUrl !== self.location.href) {
|
|
||||||
foreach(self.urlListeners, function(listener){
|
|
||||||
try {
|
|
||||||
listener(self.location.href);
|
|
||||||
} catch (e) {
|
|
||||||
error(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.expectedUrl = self.location.href;
|
|
||||||
}
|
|
||||||
self.setTimeout(pull, self.delay);
|
|
||||||
})();
|
|
||||||
},
|
|
||||||
|
|
||||||
startCookieWatcher: function() {
|
|
||||||
var self = this;
|
|
||||||
(function poll() {
|
|
||||||
self.cookies();
|
|
||||||
self.setTimeout(poll, self.delay);
|
|
||||||
})();
|
|
||||||
},
|
|
||||||
|
|
||||||
setUrl: function(url) {
|
|
||||||
var existingURL = this.location.href;
|
|
||||||
if (!existingURL.match(/#/)) existingURL += '#';
|
|
||||||
if (!url.match(/#/)) url += '#';
|
|
||||||
if (existingURL != url) {
|
|
||||||
this.location.href = this.expectedUrl = url;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getUrl: function() {
|
|
||||||
return this.location.href;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,17 @@ angularService("$location", function(browser){
|
||||||
var scope = this,
|
var scope = this,
|
||||||
location = {parse:parseUrl, toString:toString, update:update},
|
location = {parse:parseUrl, toString:toString, update:update},
|
||||||
lastLocation = {};
|
lastLocation = {};
|
||||||
|
var lastBrowserUrl = browser.getUrl();
|
||||||
|
|
||||||
browser.watchUrl(function(url){
|
browser.addPollFn(function(){
|
||||||
update(url);
|
if (lastBrowserUrl !== browser.getUrl()) {
|
||||||
scope.$root.$eval();
|
update(lastBrowserUrl = browser.getUrl());
|
||||||
|
scope.$eval();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.$onEval(PRIORITY_FIRST, update);
|
this.$onEval(PRIORITY_FIRST, update);
|
||||||
this.$onEval(PRIORITY_LAST, update);
|
this.$onEval(PRIORITY_LAST, update);
|
||||||
update(browser.getUrl());
|
update(lastBrowserUrl);
|
||||||
return location;
|
return location;
|
||||||
|
|
||||||
function update(href){
|
function update(href){
|
||||||
|
|
@ -395,10 +398,14 @@ angularService('$resource', function($xhr){
|
||||||
|
|
||||||
|
|
||||||
angularService('$cookies', function($browser) {
|
angularService('$cookies', function($browser) {
|
||||||
var cookies = {}, rootScope = this;
|
var cookies = {}, rootScope = this, lastCookies;
|
||||||
$browser.watchCookies(function(newCookies){
|
$browser.addPollFn(function(){
|
||||||
copy(newCookies, cookies);
|
var currentCookies = $browser.cookies();
|
||||||
rootScope.$eval();
|
if (lastCookies != currentCookies) {
|
||||||
|
lastCookies = currentCookies;
|
||||||
|
copy(currentCookies, cookies);
|
||||||
|
rootScope.$eval();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.$onEval(PRIORITY_FIRST, update);
|
this.$onEval(PRIORITY_FIRST, update);
|
||||||
this.$onEval(PRIORITY_LAST, update);
|
this.$onEval(PRIORITY_LAST, update);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
describe('browser', function(){
|
describe('browser', function(){
|
||||||
|
|
||||||
var browser, location, head;
|
var browser, location, head, xhr;
|
||||||
|
|
||||||
beforeEach(function(){
|
beforeEach(function(){
|
||||||
location = {href:"http://server", hash:""};
|
location = {href:"http://server", hash:""};
|
||||||
|
|
@ -8,44 +8,19 @@ describe('browser', function(){
|
||||||
scripts: [],
|
scripts: [],
|
||||||
append: function(node){head.scripts.push(node);}
|
append: function(node){head.scripts.push(node);}
|
||||||
};
|
};
|
||||||
browser = new Browser(location, jqLite(window.document), head);
|
xhr = null;
|
||||||
browser.setTimeout = noop;
|
browser = new Browser(location, jqLite(window.document), head, function(){
|
||||||
});
|
xhr = this;
|
||||||
|
this.open = noop;
|
||||||
it('should watch url', function(){
|
this.setRequestHeader = noop;
|
||||||
browser.delay = 1;
|
this.send = noop;
|
||||||
expectAsserts(2);
|
|
||||||
browser.watchUrl(function(url){
|
|
||||||
assertEquals('http://getangular.test', url);
|
|
||||||
});
|
});
|
||||||
browser.setTimeout = function(fn, delay){
|
|
||||||
assertEquals(1, delay);
|
|
||||||
location.href = "http://getangular.test";
|
|
||||||
browser.setTimeout = function(fn, delay) {};
|
|
||||||
fn();
|
|
||||||
};
|
|
||||||
browser.startUrlWatcher();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should contain cookie cruncher', function() {
|
it('should contain cookie cruncher', function() {
|
||||||
expect(browser.cookies).toBeDefined();
|
expect(browser.cookies).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to start cookie watcher', function() {
|
|
||||||
browser.delay = 1;
|
|
||||||
expectAsserts(2);
|
|
||||||
browser.watchCookies(function(cookies){
|
|
||||||
assertEquals({'foo':'bar'}, cookies);
|
|
||||||
});
|
|
||||||
browser.setTimeout = function(fn, delay){
|
|
||||||
assertEquals(1, delay);
|
|
||||||
document.cookie = 'foo=bar';
|
|
||||||
browser.setTimeout = function(fn, delay) {};
|
|
||||||
fn();
|
|
||||||
};
|
|
||||||
browser.startCookieWatcher();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('outstading requests', function(){
|
describe('outstading requests', function(){
|
||||||
it('should process callbacks immedietly with no outstanding requests', function(){
|
it('should process callbacks immedietly with no outstanding requests', function(){
|
||||||
var callback = jasmine.createSpy('callback');
|
var callback = jasmine.createSpy('callback');
|
||||||
|
|
@ -55,15 +30,12 @@ describe('browser', function(){
|
||||||
|
|
||||||
it('should queue callbacks with outstanding requests', function(){
|
it('should queue callbacks with outstanding requests', function(){
|
||||||
var callback = jasmine.createSpy('callback');
|
var callback = jasmine.createSpy('callback');
|
||||||
browser.outstandingRequests.count = 1;
|
browser.xhr('GET', '/url', noop);
|
||||||
browser.notifyWhenNoOutstandingRequests(callback);
|
browser.notifyWhenNoOutstandingRequests(callback);
|
||||||
expect(callback).not.wasCalled();
|
expect(callback).not.wasCalled();
|
||||||
|
|
||||||
browser.processRequestCallbacks();
|
xhr.readyState = 4;
|
||||||
expect(callback).not.wasCalled();
|
xhr.onreadystatechange();
|
||||||
|
|
||||||
browser.outstandingRequests.count = 0;
|
|
||||||
browser.processRequestCallbacks();
|
|
||||||
expect(callback).wasCalled();
|
expect(callback).wasCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -220,44 +192,6 @@ describe('browser', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('watch', function() {
|
|
||||||
|
|
||||||
it('should allow listeners to be registered', function() {
|
|
||||||
expectAsserts(1);
|
|
||||||
|
|
||||||
browser.watchCookies(function(cookies) {
|
|
||||||
assertEquals({'aaa':'bbb'}, cookies);
|
|
||||||
});
|
|
||||||
|
|
||||||
browser.cookies('aaa','bbb');
|
|
||||||
browser.cookies();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should fire listeners when cookie changes are discovered', function() {
|
|
||||||
expectAsserts(1);
|
|
||||||
|
|
||||||
browser.watchCookies(function(cookies) {
|
|
||||||
assertEquals({'foo':'bar'}, cookies);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.cookie = 'foo=bar';
|
|
||||||
browser.cookies();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should not fire listeners when no cookies were changed', function() {
|
|
||||||
expectAsserts(0);
|
|
||||||
|
|
||||||
browser.cookies(function(cookies) {
|
|
||||||
assertEquals({'shouldnt':'fire'}, cookies);
|
|
||||||
});
|
|
||||||
|
|
||||||
browser.cookies(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should pick up external changes made to browser cookies', function() {
|
it('should pick up external changes made to browser cookies', function() {
|
||||||
browser.cookies('oatmealCookie', 'drool');
|
browser.cookies('oatmealCookie', 'drool');
|
||||||
expect(browser.cookies()).toEqual({'oatmealCookie':'drool'});
|
expect(browser.cookies()).toEqual({'oatmealCookie':'drool'});
|
||||||
|
|
@ -274,5 +208,29 @@ describe('browser', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('poll', function(){
|
||||||
|
it('should call all fns on poll', function(){
|
||||||
|
var log = '';
|
||||||
|
browser.addPollFn(function(){log+='a';});
|
||||||
|
browser.addPollFn(function(){log+='b';});
|
||||||
|
expect(log).toEqual('');
|
||||||
|
browser.poll();
|
||||||
|
expect(log).toEqual('ab');
|
||||||
|
browser.poll();
|
||||||
|
expect(log).toEqual('abab');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should startPoller', function(){
|
||||||
|
var log = '';
|
||||||
|
var setTimeoutSpy = jasmine.createSpy('setTimeout');
|
||||||
|
browser.addPollFn(function(){log+='.';});
|
||||||
|
browser.startPoller(50, setTimeoutSpy);
|
||||||
|
expect(log).toEqual('.');
|
||||||
|
expect(setTimeoutSpy.mostRecentCall.args[1]).toEqual(50);
|
||||||
|
setTimeoutSpy.mostRecentCall.args[0]();
|
||||||
|
expect(log).toEqual('..');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ describe("ScenarioSpec: configuration", function(){
|
||||||
it("should take location object", function(){
|
it("should take location object", function(){
|
||||||
var url = "http://server/#?book=moby";
|
var url = "http://server/#?book=moby";
|
||||||
var scope = compile("<div>{{$location}}</div>");
|
var scope = compile("<div>{{$location}}</div>");
|
||||||
var $location = scope.$get('$location');
|
var $location = scope.$location;
|
||||||
expect($location.hashSearch.book).toBeUndefined();
|
expect($location.hashSearch.book).toBeUndefined();
|
||||||
scope.$browser.setUrl(url);
|
scope.$browser.setUrl(url);
|
||||||
scope.$browser.fireUrlWatchers();
|
scope.$browser.poll();
|
||||||
expect($location.hashSearch.book).toEqual('moby');
|
expect($location.hashSearch.book).toEqual('moby');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
24
test/angular-mocks.js
vendored
24
test/angular-mocks.js
vendored
|
|
@ -29,7 +29,7 @@ function MockBrowser() {
|
||||||
|
|
||||||
this.isMock = true;
|
this.isMock = true;
|
||||||
self.url = "http://server";
|
self.url = "http://server";
|
||||||
self.watches = [];
|
self.pollFns = [];
|
||||||
|
|
||||||
self.xhr = function(method, url, data, callback) {
|
self.xhr = function(method, url, data, callback) {
|
||||||
if (angular.isFunction(data)) {
|
if (angular.isFunction(data)) {
|
||||||
|
|
@ -78,6 +78,14 @@ function MockBrowser() {
|
||||||
}
|
}
|
||||||
MockBrowser.prototype = {
|
MockBrowser.prototype = {
|
||||||
|
|
||||||
|
poll: function poll(){
|
||||||
|
foreach(this.pollFns, function(pollFn){ pollFn(); });
|
||||||
|
},
|
||||||
|
|
||||||
|
addPollFn: function(pollFn) {
|
||||||
|
this.pollFns.push(pollFn);
|
||||||
|
},
|
||||||
|
|
||||||
hover: function(onHover) {
|
hover: function(onHover) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -89,20 +97,6 @@ MockBrowser.prototype = {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
},
|
},
|
||||||
|
|
||||||
watchUrl: function(fn) {
|
|
||||||
this.watches.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
watchCookies: function(fn) {
|
|
||||||
this.watches.push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
fireUrlWatchers: function() {
|
|
||||||
for(var i=0; i<this.watches.length; i++) {
|
|
||||||
this.watches[i](this.url);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
cookies: function(name, value) {
|
cookies: function(name, value) {
|
||||||
if (name) {
|
if (name) {
|
||||||
if (value == undefined) {
|
if (value == undefined) {
|
||||||
|
|
|
||||||
|
|
@ -377,8 +377,7 @@ describe("service", function(){
|
||||||
expect(scope.$cookies).toEqual({});
|
expect(scope.$cookies).toEqual({});
|
||||||
|
|
||||||
scope.$browser.cookies('brandNew', 'cookie');
|
scope.$browser.cookies('brandNew', 'cookie');
|
||||||
//TODO: This is a hacky way of calling the watch function, once pooling is refactored, this will go away.
|
scope.$browser.poll();
|
||||||
scope.$browser.watches[1](scope.$browser.cookies());
|
|
||||||
|
|
||||||
expect(scope.$cookies).toEqual({'brandNew':'cookie'});
|
expect(scope.$cookies).toEqual({'brandNew':'cookie'});
|
||||||
});
|
});
|
||||||
|
|
@ -448,8 +447,7 @@ describe("service", function(){
|
||||||
|
|
||||||
it('should deserialize json to object', function() {
|
it('should deserialize json to object', function() {
|
||||||
scope.$browser.cookies('objectCookie', '{"id":123,"name":"blah"}');
|
scope.$browser.cookies('objectCookie', '{"id":123,"name":"blah"}');
|
||||||
//TODO: This is a hacky way of calling the watch function, once pooling is refactored, this will go away.
|
scope.$browser.poll();
|
||||||
scope.$browser.watches[1](scope.$browser.cookies());
|
|
||||||
expect(scope.$sessionStore.get('objectCookie')).toEqual({id: 123, name: 'blah'});
|
expect(scope.$sessionStore.get('objectCookie')).toEqual({id: 123, name: 'blah'});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue