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) {
|
||||
var name = unwrapSymbol(symbol);
|
||||
if (declaration is MethodMirror) {
|
||||
names.add('$name()');
|
||||
names.add(name);
|
||||
} else if (declaration is ClassMirror) {
|
||||
var classMirror = declaration as ClassMirror;
|
||||
if (classMirror.isAbstract) name = '$name';
|
||||
names.add(name);
|
||||
classMirror.staticMembers.forEach(members('$name#', names));
|
||||
classMirror.instanceMembers.forEach(members('$name.', names));
|
||||
} else if (declaration is TypedefMirror) {
|
||||
names.add(name);
|
||||
} else if (declaration is VariableMirror) {
|
||||
|
@ -76,15 +74,6 @@ class ExportedSymbol {
|
|||
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 {
|
||||
List<ExportedSymbol> names;
|
||||
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.
|
||||
|
|
|
@ -27,47 +27,12 @@ const IGNORE =
|
|||
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):
|
||||
string[] {
|
||||
var symbols: string[] = [];
|
||||
for (var name in lib) {
|
||||
var symbol = `${name}`;
|
||||
var ref = lib[name];
|
||||
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);
|
||||
}
|
||||
symbols.push(symbol);
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
|
|
@ -11,49 +11,48 @@ import {
|
|||
xit
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {IS_DART} from 'angular2/src/facade/lang';
|
||||
import {getSymbolsFromLibrary} from './symbol_inspector';
|
||||
import {SymbolsDiff} from './symbol_differ';
|
||||
|
||||
export function main() {
|
||||
describe('symbol inspector', () => {
|
||||
it('should extract symbols', () => {
|
||||
var symbols = getSymbolsFromLibrary("simple_library");
|
||||
|
||||
expect(new SymbolsDiff(symbols,
|
||||
[
|
||||
'A',
|
||||
'A#staticField',
|
||||
'A#staticField=',
|
||||
'A#staticMethod()',
|
||||
'A.field',
|
||||
'A.field=',
|
||||
'A.getter',
|
||||
'A.method()',
|
||||
'A.methodWithFunc()',
|
||||
'ClosureParam',
|
||||
'ClosureReturn',
|
||||
'ConsParamType',
|
||||
'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()']);
|
||||
if (IS_DART) {
|
||||
it('should extract symbols (dart)', () => {
|
||||
var symbols = getSymbolsFromLibrary("simple_library");
|
||||
expect(symbols).toEqual([
|
||||
'A',
|
||||
'ClosureParam',
|
||||
'ClosureReturn',
|
||||
'ConsParamType',
|
||||
'FieldType',
|
||||
'Generic',
|
||||
'GetterType',
|
||||
'MethodReturnType',
|
||||
'ParamType',
|
||||
'SomeInterface',
|
||||
'StaticFieldType',
|
||||
'TypedefParam',
|
||||
'TypedefReturnType'
|
||||
]);
|
||||
});
|
||||
});
|
||||
} 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…
Reference in New Issue