Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

feat(tests): async tests #44

Merged
merged 1 commit into from
Jul 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/angular.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ class AngularModule extends Module {
type(CacheFactory, CacheFactory);
type(Http, Http);
type(UrlRewriter, UrlRewriter);
type(HttpFutures, HttpFutures);
type(HttpBackend, HttpBackend);
type(BlockCache, BlockCache);
type(TemplateCache, TemplateCache);
Expand Down
11 changes: 2 additions & 9 deletions lib/http.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
part of angular;

// NOTE(deboer): This should be a generic utility class, but lets make sure
// it works in this case first!
class HttpFutures {
async.Future value(x) => new async.Future.value(x);
}

class UrlRewriter {
String call(url) => url;
}
Expand Down Expand Up @@ -36,9 +30,8 @@ class Http {
Map<String, async.Future<String>> _pendingRequests = <String, async.Future<String>>{};
UrlRewriter rewriter;
HttpBackend backend;
HttpFutures futures;

Http(UrlRewriter this.rewriter, HttpBackend this.backend, HttpFutures this.futures);
Http(UrlRewriter this.rewriter, HttpBackend this.backend);

async.Future<String> getString(String url,
{bool withCredentials, void onProgress(ProgressEvent e), Cache cache}) {
Expand All @@ -64,7 +57,7 @@ class Http {
}
var cachedValue = cache != null ? cache.get(url) : null;
if (cachedValue != null) {
return futures.value(cachedValue);
return new async.Future.value(cachedValue);
}
var result = backend.request(url,
method: method,
Expand Down
16 changes: 1 addition & 15 deletions test/_http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class MockHttp extends Http {
Map<String, MockHttpData> gets = {};
List futures = [];

MockHttp(UrlRewriter rewriter, HttpBackend backend, HttpFutures futures) : super(rewriter, backend, futures);
MockHttp(UrlRewriter rewriter, HttpBackend backend) : super(rewriter, backend);

expectGET(String url, String content, {int times: 1}) {
gets[url] = new MockHttpData(content, times);
Expand Down Expand Up @@ -47,20 +47,6 @@ class MockHttpData {
toString() => value;
}

class MockHttpFutures extends HttpFutures {
List completersAndValues = [];
Future value(x) {
var completer = new Completer.sync();
completersAndValues.add([completer, x]);
return completer.future;
}

trigger() {
completersAndValues.forEach((cv) => cv[0].complete(cv[1]));
completersAndValues = [];
}
}

class MockHttpBackend extends HttpBackend {
Map<String, MockHttpData> gets = {};
List completersAndValues = [];
Expand Down
16 changes: 16 additions & 0 deletions test/_specs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library ng_specs;


import 'dart:html';
import 'dart:async' as dartAsync;
import 'package:unittest/unittest.dart' as unit;
import 'package:angular/debug.dart';
import 'dart:mirrors' as mirror;
Expand Down Expand Up @@ -154,6 +155,21 @@ class Logger implements List {
noSuchMethod(Invocation invocation) => mirror.reflect(_list).delegate(invocation);
}

List<Function> _asyncQueue = [];

nextTurn() {
// copy the queue as it may change.
var toRun = new List.from(_asyncQueue);
_asyncQueue = [];
toRun.forEach((fn) => fn());
}

async(Function fn) =>
() {
dartAsync.runZonedExperimental(fn, onRunAsync: (asyncFn) => _asyncQueue.add(asyncFn));
expect(_asyncQueue.isEmpty).toBe(true);
};

class SpecInjector {
Injector moduleInjector;
Injector injector;
Expand Down
72 changes: 72 additions & 0 deletions test/_specs_spec.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "_specs.dart";
import "dart:async";

main() {
describe('renderedText', () {
Expand Down Expand Up @@ -32,6 +33,77 @@ main() {
expect(div.html()).toEqual('text');
});
});
});

describe('async', () {
it('should run synchronous code', () {
var ran = false;
async(() { ran = true; })();
expect(ran).toBe(true);
});


it('should run async code', () {
var ran = false;
var thenRan = false;
async(() {
new Future.value('s').then((_) { thenRan = true; });
expect(thenRan).toBe(false);
nextTurn();
expect(thenRan).toBe(true);
ran = true;
})();
expect(ran).toBe(true);
});


it('should run chained thens', () {
var log = [];
async(() {
new Future.value('s')
.then((_) { log.add('firstThen'); })
.then((_) { log.add('2ndThen'); });
expect(log.join(' ')).toEqual('');
nextTurn();
expect(log.join(' ')).toEqual('firstThen 2ndThen');
})();
});


it('shold run futures created in futures', () {
var log = [];
async(() {
new Future.value('s')
.then((_) {
log.add('firstThen');
new Future.value('t').then((_) {
log.add('2ndThen');
});
});
expect(log.join(' ')).toEqual('');
nextTurn();
expect(log.join(' ')).toEqual('firstThen');
nextTurn();
expect(log.join(' ')).toEqual('firstThen 2ndThen');
})();
});


it('should complain if you dangle callbacks', () {
expect(() {
async(() {
new Future.value("s").then((_) {});
})();
}).toThrow();
});


it('should complain if the test throws an exception', () {
expect(() {
async(() {
throw "blah";
})();
}).toThrow("blah");
});
});
}
11 changes: 4 additions & 7 deletions test/directives/ng_include_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ main() {

beforeEach(beforeEachTestBed((tb) => _ = tb));

beforeEach(module((AngularModule module) {
module.type(HttpFutures, MockHttpFutures);
}));

it('should fetch tempalte from url', inject((Scope scope, TemplateCache cache, HttpFutures futures) {
it('should fetch tempalte from url', async(inject((Scope scope, TemplateCache cache) {
cache.put('tpl.html', new HttpResponse(200, 'my name is {{name}}'));

var element = _.compile('<div ng-include="template"></div>');
Expand All @@ -23,9 +19,10 @@ main() {
scope['name'] = 'Vojta';
scope['template'] = 'tpl.html';
});
futures.trigger();

nextTurn(); // load the template from cache.
expect(element.text()).toEqual('my name is Vojta');
}));
})));


it('should support inlined templates', inject((Scope scope) {
Expand Down
30 changes: 14 additions & 16 deletions test/http_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ main() {
var rewriter, futures, backend, cache;
beforeEach(() {
rewriter = new SubstringRewriter();
futures = new MockHttpFutures();
backend = new MockHttpBackend();
cache = new FakeCache();
});

it('should rewrite URLs before calling the backend', () {
backend.expectGET('a', VALUE, times: 1);

var http = new Http(rewriter, backend, futures);
var http = new Http(rewriter, backend);
var called = 0;
http.getString('a[not sent to backed]').then((v) {
expect(v).toBe(VALUE);
Expand All @@ -46,7 +45,7 @@ main() {
it('should support pending requests for different raw URLs', () {
backend.expectGET('a', VALUE, times: 1);

var http = new Http(rewriter, backend, futures);
var http = new Http(rewriter, backend);
var called = 0;
http.getString('a[some string]', cache: cache).then((v) {
expect(v).toBe(VALUE);
Expand All @@ -63,8 +62,8 @@ main() {
backend.assertAllGetsCalled();
});

it('should support caching', () {
var http = new Http(rewriter, backend, futures);
it('should support caching', async(() {
var http = new Http(rewriter, backend);
var called = 0;
http.getString('fromCache', cache: cache).then((v) {
expect(v).toBe(CACHED_VALUE);
Expand All @@ -73,25 +72,24 @@ main() {

expect(called).toEqual(0);
backend.flush();
futures.trigger();
nextTurn();

expect(called).toEqual(1);
backend.assertAllGetsCalled();
});
}));
});

describe('http caching', () {
var rewriter, futures, backend, cache;
var rewriter, backend, cache;
beforeEach(() {
rewriter = new UrlRewriter();
futures = new MockHttpFutures();
backend = new MockHttpBackend();
cache = new FakeCache();
});
it('should not cache if no cache is present', () {
backend.expectGET('a', VALUE, times: 2);

var http = new Http(rewriter, backend, futures);
var http = new Http(rewriter, backend);
var called = 0;
http.getString('a').then((v) {
expect(v).toBe(VALUE);
Expand All @@ -114,7 +112,7 @@ main() {
it('should return a pending request', inject(() {
backend.expectGET('a', VALUE, times: 1);

var http = new Http(rewriter, backend, futures);
var http = new Http(rewriter, backend);
var called = 0;
http.getString('a', cache: cache).then((v) {
expect(v).toBe(VALUE);
Expand All @@ -135,7 +133,7 @@ main() {
it('should not return a pending request after the request is complete', () {
backend.expectGET('a', VALUE, times: 2);

var http = new Http(rewriter, backend, futures);
var http = new Http(rewriter, backend);
var called = 0;
http.getString('a', cache: cache).then((v) {
expect(v).toBe(VALUE);
Expand All @@ -157,8 +155,8 @@ main() {
});


it('should return a cached value if present', () {
var http = new Http(rewriter, backend, futures);
it('should return a cached value if present', async(() {
var http = new Http(rewriter, backend);
var called = 0;
// The URL string 'f' is primed in the FakeCache
http.getString('f', cache: cache).then((v) {
Expand All @@ -168,10 +166,10 @@ main() {

expect(called).toEqual(0);
backend.flush();
futures.trigger();
nextTurn();

expect(called).toEqual(1);
backend.assertAllGetsCalled();
});
}));
});
}