feat(test_lib): implement SpyObject

This commit is contained in:
vsavkin 2014-11-25 15:16:53 -08:00
parent 965f70bfbe
commit f06433fb58
7 changed files with 107 additions and 22 deletions

View File

@ -1,5 +1,5 @@
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, FakeObject} from 'test_lib/test_lib'; import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, SpyObject} from 'test_lib/test_lib';
import {isBlank, isPresent, FIELD, IMPLEMENTS} from 'facade/lang'; import {isBlank, isPresent, FIELD, IMPLEMENTS, proxy} from 'facade/lang';
import {ListWrapper, MapWrapper, List} from 'facade/collection'; import {ListWrapper, MapWrapper, List} from 'facade/collection';
import {ProtoElementInjector, PreBuiltObjects} from 'core/compiler/element_injector'; import {ProtoElementInjector, PreBuiltObjects} from 'core/compiler/element_injector';
import {Parent, Ancestor} from 'core/annotations/visibility'; import {Parent, Ancestor} from 'core/annotations/visibility';
@ -9,12 +9,10 @@ import {ProtoRecordRange} from 'change_detection/record_range';
import {ViewPort} from 'core/compiler/viewport'; import {ViewPort} from 'core/compiler/viewport';
import {NgElement} from 'core/dom/element'; import {NgElement} from 'core/dom/element';
//TODO: vsavkin: use a spy object @proxy
class DummyView extends View { @IMPLEMENTS(View)
constructor() { class DummyView extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
super(null, null, new ProtoRecordRange(), MapWrapper.create());
}
}
class Directive { class Directive {
} }

View File

@ -1,4 +1,5 @@
import {assert} from 'rtts_assert/rtts_assert'; import {assert} from 'rtts_assert/rtts_assert';
export {proxy} from 'rtts_assert/rtts_assert';
export var Type = Function; export var Type = Function;
export var Math = window.Math; export var Math = window.Math;

View File

@ -13,6 +13,9 @@ function argPositionName(i) {
var primitives = $traceurRuntime.type; var primitives = $traceurRuntime.type;
export function proxy(){
}
function assertArgumentTypes(...params) { function assertArgumentTypes(...params) {
var actual, type; var actual, type;
var currentArgErrors; var currentArgErrors;
@ -78,11 +81,14 @@ function prettyPrint(value) {
} }
function isType(value, T, errors) { function isType(value, T, errors) {
if (T === primitives.void) { if (T === primitives.void) {
return typeof value === 'undefined'; return typeof value === 'undefined';
} }
if (_isProxy(value)) {
return true;
}
if (T === primitives.any || value === null) { if (T === primitives.any || value === null) {
return true; return true;
} }
@ -143,6 +149,11 @@ function isType(value, T, errors) {
// return res; // return res;
} }
function _isProxy(obj) {
if (!obj || !obj.constructor || !obj.constructor.annotations) return false;
return obj.constructor.annotations.filter((a) => a instanceof proxy).length > 0;
}
function formatErrors(errors, indent = ' ') { function formatErrors(errors, indent = ' ') {
return errors.map((e) => { return errors.map((e) => {
if (typeof e === 'string') return indent + '- ' + e; if (typeof e === 'string') return indent + '- ' + e;

View File

@ -24,6 +24,7 @@ class Expect extends gns.Expect {
void toEqual(expected) => toHaveSameProps(expected); void toEqual(expected) => toHaveSameProps(expected);
void toThrowError([message=""]) => this.toThrowWith(message: message); void toThrowError([message=""]) => this.toThrowWith(message: message);
void toBePromise() => _expect(actual is Future, equals(true)); void toBePromise() => _expect(actual is Future, equals(true));
void toImplement(expected) => toBeA(expected);
Function get _expect => gns.guinness.matchers.expect; Function get _expect => gns.guinness.matchers.expect;
} }

View File

@ -73,10 +73,51 @@ window.beforeEach(function() {
}; };
} }
}; };
},
toImplement: function() {
return {
compare: function(actualObject, expectedInterface) {
var objProps = Object.keys(actualObject.constructor.prototype);
var intProps = Object.keys(expectedInterface.prototype);
var missedMethods = [];
intProps.forEach((k) => {
if (!actualObject.constructor.prototype[k]) missedMethods.push(k);
});
return {
pass: missedMethods.length == 0,
get message() {
return 'Expected ' + actualObject + ' to have the following methods: ' + missedMethods.join(", ");
}
};
}
};
} }
}); });
}); });
export class SpyObject {
spy(name){
if (! this[name]) {
this[name] = this._createGuinnessCompatibleSpy();
}
return this[name];
}
rttsAssert(value) {
return true;
}
_createGuinnessCompatibleSpy(){
var newSpy = jasmine.createSpy();
newSpy.andCallFake = newSpy.and.callFake;
return newSpy;
}
}
function mapToString(m) { function mapToString(m) {
if (!m) { if (!m) {
return ''+m; return ''+m;

View File

@ -1,6 +1,7 @@
import {describe, it, iit, ddescribe, expect, tick, async} from 'test_lib/test_lib'; import {describe, it, iit, ddescribe, expect, tick, async, SpyObject, beforeEach} from 'test_lib/test_lib';
import {MapWrapper, ListWrapper} from 'facade/collection'; import {MapWrapper, ListWrapper} from 'facade/collection';
import {PromiseWrapper} from 'facade/async'; import {PromiseWrapper} from 'facade/async';
import {IMPLEMENTS, proxy} from 'facade/lang';
class TestObj { class TestObj {
prop; prop;
@ -9,6 +10,10 @@ class TestObj {
} }
} }
@proxy
@IMPLEMENTS(TestObj)
class SpyTestObj extends SpyObject {noSuchMethod(m){return super.noSuchMethod(m)}}
export function main() { export function main() {
describe('test_lib', () => { describe('test_lib', () => {
describe('equality', () => { describe('equality', () => {
@ -48,5 +53,29 @@ export function main() {
expect(MapWrapper.createFromStringMap({'a': 1})).not.toEqual(MapWrapper.createFromStringMap({'a': 1, 'b': 1})); expect(MapWrapper.createFromStringMap({'a': 1})).not.toEqual(MapWrapper.createFromStringMap({'a': 1, 'b': 1}));
}); });
}); });
describe("spy objects", () => {
var spyObj;
beforeEach(() => {
spyObj = new SpyTestObj();
});
it("should pass the runtime check", () => {
var t:TestObj = spyObj;
expect(t).toBeDefined();
});
it("should return a new spy func with no calls", () => {
expect(spyObj.spy("someFunc")).not.toHaveBeenCalled();
});
it("should record function calls", () => {
spyObj.spy("someFunc").andCallFake((a,b) => a + b);
expect(spyObj.someFunc(1,2)).toEqual(3);
expect(spyObj.spy("someFunc")).toHaveBeenCalledWith(1,2);
});
});
}); });
} }

View File

@ -1,22 +1,26 @@
import {ddescribe, describe, it, expect, IS_DARTIUM} from 'test_lib/test_lib'; import {ddescribe, describe, it, iit, expect, IS_DARTIUM} from 'test_lib/test_lib';
import {IMPLEMENTS} from './fixtures/annotations'; import {IMPLEMENTS} from './fixtures/annotations';
class Interface1 {} class Interface1 {
class Interface2 {} one(){}
}
class Interface2 {
two(){}
}
@IMPLEMENTS(Interface1, Interface2) @IMPLEMENTS(Interface1, Interface2)
class SomeClass {} class SomeClass {
one(){}
two(){}
}
export function main() { export function main() {
describe('interfaces', function() { describe('interfaces', function() {
//TODO: remvoe when interfaces are supported in AtScript it('should work', function () {
if (IS_DARTIUM) { var s = new SomeClass();
it('should work', function () { expect(s).toImplement(Interface1);
var s = new SomeClass(); expect(s).toImplement(Interface2);
expect(s instanceof Interface1).toBeTrue(); });
expect(s instanceof Interface2).toBeTrue();
});
}
}); });
} }