feat(dart/transform): Detect annotations which extend Injectable or Template.
Create a method that recursively walks imports from an entry point and determines where classes are registered. Use this information to determine if a particular annotation implements or extends Injectable or Template.
This commit is contained in:
@@ -1,24 +1,47 @@
|
||||
library angular2.test.transform.directive_processor.all_tests;
|
||||
|
||||
import 'package:barback/barback.dart';
|
||||
import 'package:angular2/src/transform/directive_processor/rewriter.dart';
|
||||
import '../common/read_file.dart';
|
||||
import 'package:angular2/src/transform/common/classdef_parser.dart';
|
||||
import 'package:dart_style/dart_style.dart';
|
||||
import 'package:guinness/guinness.dart';
|
||||
|
||||
import '../common/read_file.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
var formatter = new DartFormatter();
|
||||
|
||||
main() {
|
||||
allTests();
|
||||
}
|
||||
|
||||
void allTests() {
|
||||
it('should preserve parameter annotations as const instances.', () {
|
||||
var inputPath = 'parameter_metadata/soup.dart';
|
||||
var expected = _readFile('parameter_metadata/expected/soup.ng_deps.dart');
|
||||
var output =
|
||||
formatter.format(createNgDeps(_readFile(inputPath), inputPath));
|
||||
_testNgDeps('should preserve parameter annotations as const instances.',
|
||||
'parameter_metadata/soup.dart');
|
||||
|
||||
_testNgDeps('should recognize annotations which extend Injectable.',
|
||||
'custom_metadata/tortilla_soup.dart');
|
||||
|
||||
_testNgDeps('should recognize annotations which implement Injectable.',
|
||||
'custom_metadata/chicken_soup.dart');
|
||||
|
||||
_testNgDeps(
|
||||
'should recognize annotations which implement a class that extends '
|
||||
'Injectable.', 'custom_metadata/chicken_soup.dart');
|
||||
}
|
||||
|
||||
void _testNgDeps(String name, String inputPath) {
|
||||
it(name, () async {
|
||||
var inputId = _assetIdForPath(inputPath);
|
||||
var reader = new TestAssetReader();
|
||||
var defMap = await createTypeMap(reader, inputId);
|
||||
var input = await reader.readAsString(inputId);
|
||||
var output = formatter.format(createNgDeps(input, inputPath, defMap));
|
||||
var expectedPath = path.join(path.dirname(inputPath), 'expected',
|
||||
path.basename(inputPath).replaceFirst('.dart', '.ng_deps.dart'));
|
||||
var expected = await reader.readAsString(_assetIdForPath(expectedPath));
|
||||
expect(output).toEqual(expected);
|
||||
});
|
||||
}
|
||||
|
||||
var pathBase = 'directive_processor';
|
||||
|
||||
/// Smooths over differences in CWD between IDEs and running tests in Travis.
|
||||
String _readFile(String path) => readFile('$pathBase/$path');
|
||||
AssetId _assetIdForPath(String path) =>
|
||||
new AssetId('angular2', 'test/transform/directive_processor/$path');
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
library dinner.chicken_soup;
|
||||
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
class Food implements Injectable {
|
||||
@CONST()
|
||||
const Food() : super();
|
||||
}
|
||||
|
||||
class Soup extends Food {
|
||||
@CONST()
|
||||
const Soup() : super();
|
||||
}
|
||||
|
||||
@Soup()
|
||||
class ChickenSoup {
|
||||
ChickenSoup();
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
library dinner.chicken_soup.ng_deps.dart;
|
||||
|
||||
import 'chicken_soup.dart';
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
bool _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(ChickenSoup, {
|
||||
'factory': () => new ChickenSoup(),
|
||||
'parameters': const [],
|
||||
'annotations': const [const Soup()]
|
||||
});
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
library dinner.split_pea_soup.ng_deps.dart;
|
||||
|
||||
import 'split_pea_soup.dart';
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
bool _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(SplitPea, {
|
||||
'factory': () => new SplitPea(),
|
||||
'parameters': const [],
|
||||
'annotations': const [const Soup()]
|
||||
});
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
library dinner.tortilla_soup.ng_deps.dart;
|
||||
|
||||
import 'tortilla_soup.dart';
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
bool _visited = false;
|
||||
void initReflector(reflector) {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
reflector
|
||||
..registerType(TortillaSoup, {
|
||||
'factory': () => new TortillaSoup(),
|
||||
'parameters': const [],
|
||||
'annotations': const [const Soup()]
|
||||
});
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
library dinner.split_pea_soup;
|
||||
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
class Food extends Injectable {
|
||||
@CONST()
|
||||
const Food() : super();
|
||||
}
|
||||
|
||||
class Soup implements Food {
|
||||
@CONST()
|
||||
const Soup() : super();
|
||||
}
|
||||
|
||||
@Soup()
|
||||
class SplitPeaSoup {
|
||||
SplitPeaSoup();
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
library dinner.tortilla_soup;
|
||||
|
||||
import 'package:angular2/di.dart' show Injectable;
|
||||
import 'package:angular2/src/facade/lang.dart' show CONST;
|
||||
|
||||
class Food extends Injectable {
|
||||
@CONST()
|
||||
const Food() : super();
|
||||
}
|
||||
|
||||
class Soup extends Food {
|
||||
@CONST()
|
||||
const Soup() : super();
|
||||
}
|
||||
|
||||
@Soup()
|
||||
class TortillaSoup {
|
||||
TortillaSoup();
|
||||
}
|
||||
Reference in New Issue
Block a user