cleanup(testing): clean up public api spec
Change the old public api spec to check only the exported top-level symbols. This will make sure that Dart and JS do not diverge. The new public api spec verifies the TS api. Closes #7447
This commit is contained in:
parent
c25b9fcf97
commit
201475e8d8
File diff suppressed because it is too large
Load Diff
@ -1,68 +0,0 @@
|
|||||||
import {StringWrapper, RegExpWrapper, isJsObject} from 'angular2/src/facade/lang';
|
|
||||||
|
|
||||||
var IS_FIELD = RegExpWrapper.create('^\\w+[\\.|\\#]\\w+=?$');
|
|
||||||
var IS_INTERFACE = RegExpWrapper.create('^\\{.+\\}');
|
|
||||||
var IS_DART = RegExpWrapper.create('\\:dart$');
|
|
||||||
var IS_JS = RegExpWrapper.create('\\:js$');
|
|
||||||
var IS_OPTIONAL = RegExpWrapper.create('\\:optional$');
|
|
||||||
var JS = 'JS';
|
|
||||||
var DART = 'Dart';
|
|
||||||
var MODE = isJsObject({}) ? JS : DART;
|
|
||||||
|
|
||||||
export class SymbolsDiff {
|
|
||||||
missing: string[] = [];
|
|
||||||
extra: string[] = [];
|
|
||||||
errors: string[] = [];
|
|
||||||
|
|
||||||
constructor(public actual: string[], public expected: string[]) {
|
|
||||||
this.actual.sort(compareIgnoreLang);
|
|
||||||
this.expected.sort(compareIgnoreLang);
|
|
||||||
this.computeDiff();
|
|
||||||
}
|
|
||||||
|
|
||||||
computeDiff(): void {
|
|
||||||
for (var i = 0, j = 0, length = this.expected.length + this.actual.length; i + j < length;) {
|
|
||||||
var expectedName: string = i < this.expected.length ? this.expected[i] : '~';
|
|
||||||
var actualName: string = j < this.actual.length ? this.actual[j] : '~';
|
|
||||||
if (stripLang(expectedName) == stripLang(actualName)) {
|
|
||||||
i++;
|
|
||||||
j++;
|
|
||||||
} else if (StringWrapper.compare(stripLang(expectedName), stripLang(actualName)) > 0) {
|
|
||||||
// JS does not see fields so ignore none method symbols
|
|
||||||
if (!this.shouldIgnore(expectedName)) {
|
|
||||||
this.extra.push(actualName);
|
|
||||||
this.errors.push('+ ' + actualName);
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
} else {
|
|
||||||
if (!this.shouldIgnore(expectedName)) {
|
|
||||||
this.missing.push(expectedName);
|
|
||||||
this.errors.push('- ' + expectedName);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldIgnore(expected: string): boolean {
|
|
||||||
var ignore = false;
|
|
||||||
if (MODE == JS) {
|
|
||||||
ignore = RegExpWrapper.test(IS_FIELD, expected) ||
|
|
||||||
RegExpWrapper.test(IS_INTERFACE, expected) ||
|
|
||||||
RegExpWrapper.test(IS_DART, expected) || RegExpWrapper.test(IS_OPTIONAL, expected)
|
|
||||||
} else {
|
|
||||||
ignore = RegExpWrapper.test(IS_JS, expected) || RegExpWrapper.test(IS_OPTIONAL, expected)
|
|
||||||
}
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function stripLang(text: string): string {
|
|
||||||
var index = text.indexOf(':');
|
|
||||||
if (index >= 0) text = text.substring(0, index);
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareIgnoreLang(a: string, b: string): number {
|
|
||||||
return StringWrapper.compare(stripLang(a), stripLang(b));
|
|
||||||
}
|
|
@ -57,13 +57,11 @@ class ExportedSymbol {
|
|||||||
addTo(List<String> names) {
|
addTo(List<String> names) {
|
||||||
var name = unwrapSymbol(symbol);
|
var name = unwrapSymbol(symbol);
|
||||||
if (declaration is MethodMirror) {
|
if (declaration is MethodMirror) {
|
||||||
names.add('$name()');
|
names.add(name);
|
||||||
} else if (declaration is ClassMirror) {
|
} else if (declaration is ClassMirror) {
|
||||||
var classMirror = declaration as ClassMirror;
|
var classMirror = declaration as ClassMirror;
|
||||||
if (classMirror.isAbstract) name = '$name';
|
if (classMirror.isAbstract) name = '$name';
|
||||||
names.add(name);
|
names.add(name);
|
||||||
classMirror.staticMembers.forEach(members('$name#', names));
|
|
||||||
classMirror.instanceMembers.forEach(members('$name.', names));
|
|
||||||
} else if (declaration is TypedefMirror) {
|
} else if (declaration is TypedefMirror) {
|
||||||
names.add(name);
|
names.add(name);
|
||||||
} else if (declaration is VariableMirror) {
|
} else if (declaration is VariableMirror) {
|
||||||
@ -76,15 +74,6 @@ class ExportedSymbol {
|
|||||||
toString() => unwrapSymbol(symbol);
|
toString() => unwrapSymbol(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
members(String prefix, List<String> names) {
|
|
||||||
return (Symbol symbol, MethodMirror method) {
|
|
||||||
var name = unwrapSymbol(symbol);
|
|
||||||
if (method.isOperator || method.isPrivate || IGNORE[name] == true) return;
|
|
||||||
var suffix = (method.isSetter || method.isGetter) ? '' : '()';
|
|
||||||
names.add('$prefix$name$suffix');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class LibraryInfo {
|
class LibraryInfo {
|
||||||
List<ExportedSymbol> names;
|
List<ExportedSymbol> names;
|
||||||
Map<Symbol, List<Symbol>> symbolsUsedForName;
|
Map<Symbol, List<Symbol>> symbolsUsedForName;
|
||||||
@ -135,19 +124,6 @@ Iterable<Symbol> _getUsedSymbols(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decl is MethodMirror) {
|
|
||||||
MethodMirror mdecl = decl;
|
|
||||||
if (mdecl.parameters != null) mdecl.parameters.forEach((p) {
|
|
||||||
used.addAll(_getUsedSymbols(p.type, seenDecls, path, true));
|
|
||||||
});
|
|
||||||
used.addAll(_getUsedSymbols(mdecl.returnType, seenDecls, path, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decl is VariableMirror) {
|
|
||||||
VariableMirror vdecl = decl;
|
|
||||||
used.addAll(_getUsedSymbols(vdecl.type, seenDecls, path, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip out type variables.
|
// Strip out type variables.
|
||||||
|
@ -27,47 +27,12 @@ const IGNORE =
|
|||||||
wrapperStack: true, '@@observable': true
|
wrapperStack: true, '@@observable': true
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectClassSymbols(symbols: string[], prefix: String, type: Function):
|
|
||||||
void {
|
|
||||||
// static
|
|
||||||
for (var name in type) {
|
|
||||||
if (IGNORE[name] || name.charAt(0) == '_') continue;
|
|
||||||
var suf = type[name] instanceof Function ? '()' : '';
|
|
||||||
var symbol = `${prefix}#${name}${suf}`;
|
|
||||||
symbols.push(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
// instance
|
|
||||||
for (var name in type.prototype) {
|
|
||||||
if (IGNORE[name] || name.charAt(0) == '_') continue;
|
|
||||||
if (name == 'constructor') continue;
|
|
||||||
var suf = '';
|
|
||||||
try {
|
|
||||||
if (type.prototype[name] instanceof Function) suf = '()';
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
var symbol = `${prefix}.${name}${suf}`;
|
|
||||||
symbols.push(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectTopLevelSymbols(prefix: string, lib: any):
|
function collectTopLevelSymbols(prefix: string, lib: any):
|
||||||
string[] {
|
string[] {
|
||||||
var symbols: string[] = [];
|
var symbols: string[] = [];
|
||||||
for (var name in lib) {
|
for (var name in lib) {
|
||||||
var symbol = `${name}`;
|
var symbol = `${name}`;
|
||||||
var ref = lib[name];
|
symbols.push(symbol);
|
||||||
if (ref instanceof Function) {
|
|
||||||
if (symbol.charAt(0) == symbol.charAt(0).toLowerCase()) {
|
|
||||||
// assume it is top level function
|
|
||||||
symbols.push(symbol + '()');
|
|
||||||
} else {
|
|
||||||
symbols.push(symbol);
|
|
||||||
collectClassSymbols(symbols, symbol, ref);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
symbols.push(symbol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return symbols;
|
return symbols;
|
||||||
}
|
}
|
||||||
|
@ -11,49 +11,48 @@ import {
|
|||||||
xit
|
xit
|
||||||
} from 'angular2/testing_internal';
|
} from 'angular2/testing_internal';
|
||||||
|
|
||||||
|
import {IS_DART} from 'angular2/src/facade/lang';
|
||||||
import {getSymbolsFromLibrary} from './symbol_inspector';
|
import {getSymbolsFromLibrary} from './symbol_inspector';
|
||||||
import {SymbolsDiff} from './symbol_differ';
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('symbol inspector', () => {
|
describe('symbol inspector', () => {
|
||||||
it('should extract symbols', () => {
|
if (IS_DART) {
|
||||||
var symbols = getSymbolsFromLibrary("simple_library");
|
it('should extract symbols (dart)', () => {
|
||||||
|
var symbols = getSymbolsFromLibrary("simple_library");
|
||||||
expect(new SymbolsDiff(symbols,
|
expect(symbols).toEqual([
|
||||||
[
|
'A',
|
||||||
'A',
|
'ClosureParam',
|
||||||
'A#staticField',
|
'ClosureReturn',
|
||||||
'A#staticField=',
|
'ConsParamType',
|
||||||
'A#staticMethod()',
|
'FieldType',
|
||||||
'A.field',
|
'Generic',
|
||||||
'A.field=',
|
'GetterType',
|
||||||
'A.getter',
|
'MethodReturnType',
|
||||||
'A.method()',
|
'ParamType',
|
||||||
'A.methodWithFunc()',
|
'SomeInterface',
|
||||||
'ClosureParam',
|
'StaticFieldType',
|
||||||
'ClosureReturn',
|
'TypedefParam',
|
||||||
'ConsParamType',
|
'TypedefReturnType'
|
||||||
'FieldType',
|
]);
|
||||||
'Generic',
|
|
||||||
'Generic.getter',
|
|
||||||
'GetterType',
|
|
||||||
'MethodReturnType',
|
|
||||||
'ParamType',
|
|
||||||
'StaticFieldType',
|
|
||||||
'TypedefParam',
|
|
||||||
'TypedefReturnType',
|
|
||||||
'SomeInterface:dart',
|
|
||||||
])
|
|
||||||
.errors)
|
|
||||||
.toEqual([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('assert', () => {
|
|
||||||
it('should assert symbol names are correct', () => {
|
|
||||||
var diffs = new SymbolsDiff(['a()', 'c()', 'd()'], ['a()', 'b()', 'd()']);
|
|
||||||
expect(diffs.errors).toEqual(['- b()', '+ c()']);
|
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
|
it('should extract symbols (js)', () => {
|
||||||
|
var symbols = getSymbolsFromLibrary("simple_library");
|
||||||
|
expect(symbols).toEqual([
|
||||||
|
'A',
|
||||||
|
'ClosureParam',
|
||||||
|
'ClosureReturn',
|
||||||
|
'ConsParamType',
|
||||||
|
'FieldType',
|
||||||
|
'Generic',
|
||||||
|
'GetterType',
|
||||||
|
'MethodReturnType',
|
||||||
|
'ParamType',
|
||||||
|
'StaticFieldType',
|
||||||
|
'TypedefParam',
|
||||||
|
'TypedefReturnType'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user