adding packages
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ngflutter/src/file_reader.dart';
|
||||
import 'package:ngflutter/src/package_uri_resolver.dart';
|
||||
import 'package:ngflutter/src/visitors/ast_cache.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('AstCache', () {
|
||||
FileReader.reader = new FileReaderMock();
|
||||
AstCache asts;
|
||||
setUp(() {
|
||||
asts =
|
||||
new AstCache('package:a/a.dart', new PackageUriResolver('.packages'));
|
||||
asts.build();
|
||||
});
|
||||
|
||||
test('should only collect correct URIs', () {
|
||||
var allUris = <String>[];
|
||||
for (var file in _files) {
|
||||
allUris.add(file['uri']);
|
||||
}
|
||||
expect(asts.allUris, equals(allUris));
|
||||
});
|
||||
|
||||
test('should report correct public URIs', () {
|
||||
for (var file in _files) {
|
||||
expect(asts.publicUris[file['uri']], equals(file['public_uri']),
|
||||
reason: "${file['uri']} does not have correct public URI");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var _files = [
|
||||
{
|
||||
'uri': 'package:a/a.dart',
|
||||
'public_uri': 'package:a/a.dart',
|
||||
'path': path.join('a', 'lib', 'a.dart'),
|
||||
'content': '''
|
||||
import 'package:b/b.dart';
|
||||
import 'a1.dart';
|
||||
export 'src/a2.dart';
|
||||
'''
|
||||
},
|
||||
{
|
||||
'uri': 'package:b/b.dart',
|
||||
'public_uri': 'package:b/b.dart',
|
||||
'path': path.join('b', 'lib', 'b.dart'),
|
||||
'content': '''
|
||||
import 'package:flutter/flutter.dart';
|
||||
'''
|
||||
},
|
||||
{
|
||||
'uri': 'package:a/a1.dart',
|
||||
'public_uri': 'package:a/a1.dart',
|
||||
'path': path.join('a', 'lib', 'a1.dart'),
|
||||
'content': '''
|
||||
import 'dart:io';
|
||||
'''
|
||||
},
|
||||
{
|
||||
'uri': 'package:a/src/a2.dart',
|
||||
'public_uri': 'package:a/a.dart',
|
||||
'path': path.join('a', 'lib', 'src', 'a2.dart'),
|
||||
'content': '''
|
||||
import 'a3.dart';
|
||||
export 'a4.dart';
|
||||
'''
|
||||
},
|
||||
{
|
||||
'uri': 'package:a/src/a3.dart',
|
||||
'public_uri': 'package:a/src/a3.dart',
|
||||
'path': path.join('a', 'lib', 'src', 'a3.dart'),
|
||||
'content': '''
|
||||
import 'package:flutter/flutter.dart';
|
||||
'''
|
||||
},
|
||||
{
|
||||
'uri': 'package:a/src/a4.dart',
|
||||
'public_uri': 'package:a/a.dart',
|
||||
'path': path.join('a', 'lib', 'src', 'a4.dart'),
|
||||
'content': '''
|
||||
import 'package:flutter/flutter.dart';
|
||||
'''
|
||||
}
|
||||
];
|
||||
|
||||
var _dotPackages = ['a:a/lib/', 'b:b/lib/'];
|
||||
|
||||
class FileReaderMock implements FileReader {
|
||||
@override
|
||||
List<String> readAsLines(String filePath, {Encoding encoding: utf8}) {
|
||||
if (filePath == '.packages') return _dotPackages;
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String readAsString(String filePath, {Encoding encoding: utf8}) {
|
||||
for (var file in _files) {
|
||||
if (file['path'] == filePath) return file['content'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:ngflutter/src/visitors/binding_helper.dart';
|
||||
import 'package:ngflutter/src/visitors/binding_info.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('TestBedBindingVisitor', () {
|
||||
_BindingVisitorForTest visitor;
|
||||
|
||||
setUp(() {
|
||||
visitor = new _BindingVisitorForTest();
|
||||
});
|
||||
|
||||
parse(String contents) {
|
||||
parseCompilationUnit(contents).accept(visitor);
|
||||
}
|
||||
|
||||
test('should parse simple binding', () {
|
||||
parse('const x = A;');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren, equals(['A']));
|
||||
});
|
||||
|
||||
test('should parse list bindings', () {
|
||||
parse('const x = [p.A, B];');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren, equals(['B']));
|
||||
});
|
||||
|
||||
test('should parse "const Provider(A)"', () {
|
||||
parse('const x = const Provider(A);');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, isEmpty);
|
||||
});
|
||||
|
||||
test('should parse "const Provider(const A())"', () {
|
||||
parse('const x = const Provider(const A());');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, isEmpty);
|
||||
});
|
||||
|
||||
test('should throw error for "const Provider([A])"', () {
|
||||
expect(() => parse('const x = const Provider([A]);'),
|
||||
throwsUnsupportedError);
|
||||
});
|
||||
|
||||
test('should parse "provide(A, useClass: B)"', () {
|
||||
parse('dynamic x = provide(A, useClass: B);');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
});
|
||||
|
||||
test('should parse "provide(const A(), useExisting: B)"', () {
|
||||
parse('dynamic x = provide(const A(), useExisting: B);');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
});
|
||||
|
||||
// May need to add support for this scenario.
|
||||
test('should throw error for "provide(A(), toAlias: B)"', () {
|
||||
expect(() => parse('dynamic x = provide(A(), toAlias: B);'),
|
||||
throwsUnsupportedError);
|
||||
});
|
||||
|
||||
test('should parse const Provider(A, useClass: B)', () {
|
||||
var bindingStr = 'const Provider(A, useClass: B)';
|
||||
parse('const x = $bindingStr;');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
expect(binding.creationExpression, bindingStr);
|
||||
});
|
||||
|
||||
test('should parse const Provider(A, useFactory: f, deps: const [B, C])',
|
||||
() {
|
||||
var bindingStr = 'const Provider(A, useFactory: f, deps: const [B, C])';
|
||||
parse('const x = $bindingStr;');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B', 'C'])));
|
||||
expect(binding.creationExpression, bindingStr);
|
||||
});
|
||||
|
||||
test('should parse const Provider(A, useValue: new B())', () {
|
||||
parse('const x = const Provider(A, useValue: new B());');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
});
|
||||
|
||||
test("should parse const Provider('someThing', useValue: new B())", () {
|
||||
parse("const x = const Provider('someThing', useValue: new B());");
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'someThing');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
});
|
||||
|
||||
test('should parse list in deps', () {
|
||||
parse('''
|
||||
const x = const Provider(A,
|
||||
useFactory: f,
|
||||
deps: const [ const [B, const C()]]);
|
||||
''');
|
||||
|
||||
expect(visitor.modules['x'], isNotNull);
|
||||
expect(visitor.modules['x'].directChildren.length, 1);
|
||||
var binding = visitor.modules['x'].directChildren[0] as BindingInstance;
|
||||
expect(binding.className, 'A');
|
||||
expect(binding.referencedClasses, equals(new Set.from(['B'])));
|
||||
});
|
||||
});
|
||||
|
||||
group('ModuleInfo', () {
|
||||
_BindingVisitorForTest visitor;
|
||||
|
||||
setUp(() {
|
||||
visitor = new _BindingVisitorForTest();
|
||||
});
|
||||
|
||||
parse(String contents) {
|
||||
parseCompilationUnit(contents).accept(visitor);
|
||||
}
|
||||
|
||||
void checkExpandedModule(
|
||||
List<BindingInstance> allBindingInstances, List<String> expected) {
|
||||
expect(allBindingInstances, isNotNull);
|
||||
var actual = [];
|
||||
for (var binding in allBindingInstances) {
|
||||
actual.add(binding.className);
|
||||
}
|
||||
|
||||
expect(actual, equals(expected));
|
||||
}
|
||||
|
||||
test('should expand bindings', () {
|
||||
parse('''
|
||||
const a = A;
|
||||
const b = [
|
||||
a,
|
||||
B1,
|
||||
const Provider(B2, useClass: X)
|
||||
];
|
||||
|
||||
dynamic c = [
|
||||
provide(C, useClass: X),
|
||||
b
|
||||
];
|
||||
''');
|
||||
|
||||
expect(visitor.modules['a'], isNotNull);
|
||||
expect(visitor.modules['b'], isNotNull);
|
||||
expect(visitor.modules['c'], isNotNull);
|
||||
|
||||
checkExpandedModule(
|
||||
visitor.modules['a'].getAllBindingInstances(visitor.modules), ['A']);
|
||||
checkExpandedModule(
|
||||
visitor.modules['b'].getAllBindingInstances(visitor.modules),
|
||||
['A', 'B1', 'B2']);
|
||||
checkExpandedModule(
|
||||
visitor.modules['c'].getAllBindingInstances(visitor.modules),
|
||||
['C', 'A', 'B1', 'B2']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class _BindingVisitorForTest extends RecursiveAstVisitor {
|
||||
Map<String, ModuleInfo> modules = {};
|
||||
|
||||
_BindingVisitorForTest();
|
||||
|
||||
@override
|
||||
visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
|
||||
var variable = node.variables.variables[0];
|
||||
var name = variable.name.name;
|
||||
var initializer = variable.initializer;
|
||||
|
||||
var module = modules.putIfAbsent(name, () => new ModuleInfo());
|
||||
module.name = name;
|
||||
|
||||
if (initializer is ListLiteral) {
|
||||
extractBindingInfo(initializer, module);
|
||||
} else {
|
||||
processBindingElement(initializer, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:ngflutter/src/visitors/binding_info.dart';
|
||||
import 'package:ngflutter/src/visitors/binding_visitor.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('BindingVisitor', () {
|
||||
Map<String, ModuleInfo> visit(String content) {
|
||||
var compilationUnit = parseCompilationUnit(content);
|
||||
var out = <String, ModuleInfo>{};
|
||||
var visitor = new BindingVisitor('', out, {}, new Set<String>());
|
||||
compilationUnit.accept(visitor);
|
||||
return out;
|
||||
}
|
||||
|
||||
test('should skip misc variable', () {
|
||||
var module = visit('''
|
||||
library a;
|
||||
const xyz = const [A, B, C];
|
||||
''')['xyz'];
|
||||
expect(module, isNull);
|
||||
});
|
||||
|
||||
test('should skip empty initializer', () {
|
||||
var module = visit('''
|
||||
library a;
|
||||
dynamic aModule;
|
||||
''')['aModule'];
|
||||
|
||||
expect(module, isNull);
|
||||
});
|
||||
|
||||
test('should parse list bindings', () {
|
||||
var results = visit('''
|
||||
library a;
|
||||
const testBinding = const [A, B, C];
|
||||
const testModule = D;
|
||||
const someBindings = testModule;
|
||||
''');
|
||||
|
||||
ModuleInfo module = results['testBinding'];
|
||||
expect(module, isNotNull);
|
||||
expect(module.directChildren, equals(['A', 'B', 'C']));
|
||||
module = results['testModule'];
|
||||
expect(module, isNotNull);
|
||||
expect(module.directChildren, equals(['D']));
|
||||
module = results['someBindings'];
|
||||
expect(module, isNotNull);
|
||||
expect(module.directChildren, equals(['testModule']));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:ngflutter/src/visitors/dart_class_info.dart';
|
||||
import 'package:ngflutter/src/visitors/dart_class_visitor.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('DartClassVisitor', () {
|
||||
Map<String, DartClassInfo> visit(String content) {
|
||||
var compilationUnit = parseCompilationUnit(content);
|
||||
var out = <String, DartClassInfo>{};
|
||||
var visitor = new DartClassVisitor('', out, {});
|
||||
compilationUnit.accept(visitor);
|
||||
return out;
|
||||
}
|
||||
|
||||
test('should collect OpaqueToken', () {
|
||||
var classInfo =
|
||||
visit("const token = const OpaqueToken('token');")['token'];
|
||||
|
||||
expect(classInfo, isNotNull);
|
||||
});
|
||||
|
||||
test('should collect the components constructor types', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
Cons(String x, Exotic y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['String', 'Exotic']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y']));
|
||||
});
|
||||
|
||||
test('should collect constructor types which reference this', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(this.y, Exotic z);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['String', 'Exotic']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['y', 'z']));
|
||||
});
|
||||
|
||||
test('should collect member type for field declaration', () {
|
||||
var classInfo = visit("""
|
||||
class Cons {
|
||||
final x = new Clock.fixed();
|
||||
List<SomeThing> y;
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.memberTypes['x'].className, equals('Clock'));
|
||||
expect(classInfo.memberTypes['y'].className, equals('List<SomeThing>'));
|
||||
});
|
||||
|
||||
test(
|
||||
'should collect constructor types which reference this'
|
||||
' and defined after constructor', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(this.x, this.y, List<Exotic> z);
|
||||
SomeClass x;
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['SomeClass', 'String', 'List<Exotic>']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y', 'z']));
|
||||
});
|
||||
|
||||
test('should collect classes types with implicit constructors', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.constructorParameters, equals([]));
|
||||
});
|
||||
|
||||
test('shoulde collect extends clauses', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons extends SuperAwesomeBase {
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.extendsType, equals('SuperAwesomeBase'));
|
||||
});
|
||||
|
||||
test('should collect implements clauses', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons implements dull.DullInterface, AwesomeInterface {
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.implementsTypes,
|
||||
equals(['DullInterface', 'AwesomeInterface']));
|
||||
});
|
||||
|
||||
test('should skip optional parameter', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
Cons(@Optional() String x, @SkipSelf() Exotic y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.constructorParameters.isEmpty, true);
|
||||
});
|
||||
|
||||
test('should get type from @Inject(MyString)', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(@Inject(MyString) String x, @Inject(YString) this.y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['MyString', 'YString']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y']));
|
||||
});
|
||||
|
||||
test("should get type from @Inject('someString')", () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(@Inject('someString') String x, @Inject(YString) this.y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['someString', 'YString']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y']));
|
||||
});
|
||||
|
||||
test('should get type from @Inject(const MyString())', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(@Inject(const MyString()) String x,
|
||||
@Inject(const YString()) this.y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['MyString', 'YString']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y']));
|
||||
});
|
||||
|
||||
test('should get type from @MyString()', () {
|
||||
var classInfo = visit("""
|
||||
library x;
|
||||
|
||||
class Cons {
|
||||
final String y;
|
||||
Cons(@MyString String x,
|
||||
@YString this.y);
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(
|
||||
classInfo.constructorParameters
|
||||
.map((parameter) => parameter.dependency),
|
||||
equals(['MyString', 'YString']));
|
||||
expect(classInfo.constructorParameters.map((parameter) => parameter.name),
|
||||
equals(['x', 'y']));
|
||||
});
|
||||
|
||||
test('should get member type for setter', () {
|
||||
var classInfo = visit("""
|
||||
class Cons {
|
||||
var x;
|
||||
var y;
|
||||
var z;
|
||||
Cons();
|
||||
|
||||
set x(String value){x = value;}
|
||||
set y(value){y = value;}
|
||||
set z(List<String> value){z = value;}
|
||||
}
|
||||
""")['Cons'];
|
||||
|
||||
expect(classInfo.memberTypes['x'].className, equals('String'));
|
||||
expect(classInfo.memberTypes['y'].className, equals('dynamic'));
|
||||
expect(classInfo.memberTypes['z'].className, equals('List<String>'));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Entity name', () {
|
||||
test('should produce correct formats of names', () {
|
||||
final name = new ReCase('abc_bcd_cde');
|
||||
expect(name.titleCase, 'Abc Bcd Cde');
|
||||
expect(name.camelCase, 'AbcBcdCde');
|
||||
expect(name.camelCase.toLowerCase(), 'abcBcdCde');
|
||||
expect(name.paramCase, 'abc-bcd-cde');
|
||||
expect(name.snakeCase, 'abc_bcd_cde');
|
||||
});
|
||||
test('should be handle to handle different types of input', () {
|
||||
final camelCasedName1 = new ReCase('AbcBcdCde');
|
||||
expect(camelCasedName1.snakeCase, 'abc_bcd_cde');
|
||||
final camelCasedName2 = new ReCase('abcBcdCde');
|
||||
expect(camelCasedName2.snakeCase, 'abc_bcd_cde');
|
||||
final dashedName = new ReCase('abc-bcd-cde');
|
||||
expect(dashedName.snakeCase, 'abc_bcd_cde');
|
||||
});
|
||||
test('should throw for incorrect formats', () {
|
||||
expect(() => new ReCase('Abc-bcd'), throwsArgumentError);
|
||||
expect(() => new ReCase('abc-bcd_cde'), throwsArgumentError);
|
||||
expect(() => new ReCase('_abc'), throwsArgumentError);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:ngflutter/src/visitors/flutter_component_visitor.dart';
|
||||
import 'package:ngflutter/src/visitors/component_info.dart';
|
||||
import 'package:ngflutter/src/visitors/dart_class_info.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('FlutterComponentVisitor', () {
|
||||
Map<String, ComponentInfo> visit(
|
||||
Map<String, DartClassInfo> classes, String content) {
|
||||
var compilationUnit = parseCompilationUnit(content);
|
||||
var out = <String, ComponentInfo>{};
|
||||
var visitor = new FlutterComponentVisitor(classes, out);
|
||||
compilationUnit.accept(visitor);
|
||||
return out;
|
||||
}
|
||||
|
||||
test('should parse an Flutter component', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'A': new DartClassInfo('A'),
|
||||
'B': new DartClassInfo('B'),
|
||||
'TestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
|
||||
var component = visit(classes, '''
|
||||
library a;
|
||||
|
||||
@Component(
|
||||
selector: 'test',
|
||||
directives: const [A, B],
|
||||
templateUrl: 'test.html'
|
||||
)
|
||||
class TestComponent {}
|
||||
''')['TestComponent'];
|
||||
|
||||
expect(component, isNotNull);
|
||||
expect(component.selectorName, equals('test'));
|
||||
expect(component.templatePath, equals('test.html'));
|
||||
expect(
|
||||
component.templateTypes
|
||||
.map((templateType) => templateType.classInfo.className),
|
||||
equals(['A', 'B']));
|
||||
});
|
||||
|
||||
test('should collect inline template', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'TestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
|
||||
var component = visit(classes, '''
|
||||
library a;
|
||||
|
||||
@Component(
|
||||
selector: 'test',
|
||||
template: '<div></div>'
|
||||
)
|
||||
class TestComponent {}
|
||||
''')['TestComponent'];
|
||||
|
||||
expect(component, isNotNull);
|
||||
expect(component.inlineTemplate, equals('<div></div>'));
|
||||
});
|
||||
|
||||
test('can combine component and view tags values', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'A': new DartClassInfo('A'),
|
||||
'B': new DartClassInfo('B'),
|
||||
'TestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
var component = visit(classes, '''
|
||||
library a;
|
||||
|
||||
@Component(
|
||||
selector: 'test'
|
||||
)
|
||||
@View(
|
||||
directives: const [A, B],
|
||||
templateUrl: 'test.html'
|
||||
)
|
||||
class TestComponent {}
|
||||
''')['TestComponent'];
|
||||
|
||||
expect(component, isNotNull);
|
||||
expect(component.selectorName, equals('test'));
|
||||
expect(component.templatePath, equals('test.html'));
|
||||
expect(
|
||||
component.templateTypes
|
||||
.map((templateType) => templateType.classInfo.className),
|
||||
equals(['A', 'B']));
|
||||
});
|
||||
|
||||
test('can parse directives which value is a variable', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'A': new DartClassInfo('A'),
|
||||
'B': new DartClassInfo('B'),
|
||||
'GtTestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
var component = visit(classes, '''
|
||||
const myDirectives = const [A, B];
|
||||
@Component(
|
||||
selector: 'gt-test',
|
||||
directives: myDirectives,
|
||||
templateUrl: 'gt_test.html'
|
||||
)
|
||||
class GtTestComponent {}
|
||||
''')['TestComponent'];
|
||||
|
||||
expect(
|
||||
component.templateTypes
|
||||
.map((templateType) => templateType.classInfo.className),
|
||||
equals(['A', 'B']));
|
||||
});
|
||||
|
||||
test('should collect component binding list', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'A': new DartClassInfo('A'),
|
||||
'B': new DartClassInfo('B'),
|
||||
'TestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
|
||||
var component = visit(classes, '''
|
||||
library a;
|
||||
|
||||
@Component(
|
||||
providers: const [A, B],
|
||||
selector: 'test'
|
||||
)
|
||||
class TestComponent {}
|
||||
''')['TestComponent'];
|
||||
|
||||
expect(component, isNotNull);
|
||||
expect(component.module, isNotNull);
|
||||
expect(component.module.directChildren, equals(['A', 'B']));
|
||||
});
|
||||
|
||||
test('should collect component binding variable', () {
|
||||
final classes = <String, DartClassInfo>{
|
||||
'A': new DartClassInfo('A'),
|
||||
'TestComponent': new DartClassInfo('TestComponent')
|
||||
};
|
||||
var component = visit(classes, '''
|
||||
library a;
|
||||
|
||||
@Component(
|
||||
providers: A,
|
||||
selector: 'test'
|
||||
)
|
||||
class TestComponent {}
|
||||
''')['TestComponent'];
|
||||
expect(component, isNotNull);
|
||||
expect(component.module, isNotNull);
|
||||
expect(component.module.directChildren, equals(['A']));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ngflutter/src/app_logger.dart';
|
||||
import 'package:ngflutter/src/command_runner.dart';
|
||||
import 'package:ngflutter/src/file_reader.dart';
|
||||
import 'package:ngflutter/src/file_writer.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('ngflutter', () {
|
||||
AppLoggerMock logger;
|
||||
FileWriterMock writer;
|
||||
FileReader.reader = new FileReaderMock();
|
||||
NgDartCommanderRunner runner;
|
||||
|
||||
setUp(() {
|
||||
AppLogger.log = logger = new AppLoggerMock();
|
||||
FileWriter.writer = writer = new FileWriterMock();
|
||||
runner = new NgDartCommanderRunner();
|
||||
});
|
||||
|
||||
test('should generate test with default path', () async {
|
||||
await runner
|
||||
.run(['generate', 'test', path.join('lib', 'app_component.dart')]);
|
||||
|
||||
expect(writer.filesWritten.length, 2);
|
||||
expect(writer.filesWritten[0].startsWith('test'), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class AppLoggerMock implements AppLogger {
|
||||
int severeCount = 0;
|
||||
int warningCount = 0;
|
||||
bool verbose = false;
|
||||
|
||||
@override
|
||||
void fine(message, [Object error, StackTrace stackTrace]) {}
|
||||
|
||||
@override
|
||||
void info(message, [Object error, StackTrace stackTrace]) {}
|
||||
|
||||
@override
|
||||
void severe(message, [Object error, StackTrace stackTrace]) {
|
||||
++severeCount;
|
||||
}
|
||||
|
||||
@override
|
||||
void warning(message, [Object error, StackTrace stackTrace]) {
|
||||
++warningCount;
|
||||
}
|
||||
|
||||
@override
|
||||
set isVerbose(bool value) {
|
||||
verbose = value;
|
||||
}
|
||||
}
|
||||
|
||||
class FileWriterMock implements FileWriter {
|
||||
List<String> filesWritten = [];
|
||||
FileWriterMock();
|
||||
@override
|
||||
void write(String destination, String content) {
|
||||
filesWritten.add(destination);
|
||||
}
|
||||
}
|
||||
|
||||
var _files = [
|
||||
{
|
||||
'path': path.join('hello_flutter', 'lib', 'app_component.dart'),
|
||||
'content': '''
|
||||
import 'package:flutter/flutter.dart';
|
||||
|
||||
@Component(
|
||||
selector: 'app-component',
|
||||
templateUrl: 'app_component.html')
|
||||
class AppComponent {
|
||||
var name = 'Flutter';
|
||||
}
|
||||
'''
|
||||
},
|
||||
{
|
||||
'path': path.join('lib', 'app_component.html'),
|
||||
'content': '''
|
||||
<h1>Hello Flutter</h1>
|
||||
'''
|
||||
}
|
||||
];
|
||||
|
||||
var _dotPackages = ['hello_flutter:hello_flutter/lib/'];
|
||||
var _pubSpec = ['name: hello_flutter'];
|
||||
|
||||
class FileReaderMock implements FileReader {
|
||||
@override
|
||||
List<String> readAsLines(String filePath, {Encoding encoding: utf8}) {
|
||||
if (filePath == '.packages') {
|
||||
return _dotPackages;
|
||||
} else if (filePath == 'pubspec.yaml') {
|
||||
return _pubSpec;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String readAsString(String filePath, {Encoding encoding: utf8}) {
|
||||
for (var file in _files) {
|
||||
if (file['path'] == filePath) return file['content'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:ngflutter/src/app_logger.dart';
|
||||
import 'package:ngflutter/src/command_runner.dart';
|
||||
import 'package:ngflutter/src/file_writer.dart';
|
||||
import 'package:ngflutter/src/path_util.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('ngflutter', () {
|
||||
AppLoggerMock logger;
|
||||
FileWriterMock writer;
|
||||
NgDartCommanderRunner runner;
|
||||
|
||||
setUp(() {
|
||||
AppLogger.log = logger = new AppLoggerMock();
|
||||
FileWriter.writer = writer = new FileWriterMock();
|
||||
runner = new NgDartCommanderRunner();
|
||||
});
|
||||
|
||||
test('should fix invalid path', () {
|
||||
expect(getNormalizedPath(r'path/to\some/folder'),
|
||||
path.join('path', 'to', 'some', 'folder'));
|
||||
});
|
||||
|
||||
test('should generate component with default path', () async {
|
||||
await runner.run(['generate', 'component', 'HelloWorldComponent']);
|
||||
|
||||
expect(writer.filesWritten.length, 2);
|
||||
expect(writer.filesWritten[0].startsWith('lib'), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate component with specified path', () async {
|
||||
final componentPath = path.join('some', 'path');
|
||||
await runner.run([
|
||||
'generate',
|
||||
'component',
|
||||
'--path=$componentPath',
|
||||
'HelloWorldComponent'
|
||||
]);
|
||||
expect(writer.filesWritten.length, 2);
|
||||
expect(writer.filesWritten[0].startsWith(componentPath), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate project with default path', () async {
|
||||
final projectPath = path.join('.', 'hello_flutter');
|
||||
await runner.run(['-v', 'new', 'HelloFlutter']);
|
||||
expect(logger.verbose, isTrue);
|
||||
expect(writer.filesWritten.length, 8);
|
||||
expect(writer.filesWritten[0].startsWith(projectPath), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate project with specified path', () async {
|
||||
final projectPath = path.join('some', 'path');
|
||||
await runner.run(['new', 'HelloFlutter', '-p $projectPath']);
|
||||
expect(logger.verbose, isFalse);
|
||||
expect(writer.filesWritten.length, 8);
|
||||
expect(
|
||||
writer.filesWritten[0]
|
||||
.startsWith(path.join(projectPath, 'hello_flutter')),
|
||||
isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate directive with default path', () async {
|
||||
await runner.run(['generate', 'directive', 'HelloWorldDirective']);
|
||||
|
||||
expect(writer.filesWritten.length, 1);
|
||||
expect(writer.filesWritten[0].startsWith('lib'), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate directive with specified path', () async {
|
||||
final directivePath = path.join('some', 'path');
|
||||
await runner.run([
|
||||
'generate',
|
||||
'directive',
|
||||
'--path=$directivePath',
|
||||
'HelloWorldDirective'
|
||||
]);
|
||||
expect(writer.filesWritten.length, 1);
|
||||
expect(writer.filesWritten[0].startsWith(directivePath), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate pipe with default path', () async {
|
||||
await runner.run(['generate', 'pipe', 'HelloWorldPipe']);
|
||||
|
||||
expect(writer.filesWritten.length, 1);
|
||||
expect(writer.filesWritten[0].startsWith('lib'), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should generate pipe with specified path', () async {
|
||||
final directivePath = path.join('some', 'path');
|
||||
await runner
|
||||
.run(['generate', 'pipe', '--path=$directivePath', 'HelloWorldPipe']);
|
||||
expect(writer.filesWritten.length, 1);
|
||||
expect(writer.filesWritten[0].startsWith(directivePath), isTrue);
|
||||
expect(logger.warningCount, 0);
|
||||
expect(logger.severeCount, 0);
|
||||
});
|
||||
|
||||
test('should throw UsageException for missing project name', () {
|
||||
expect(runner.run(['new']), throwsA(const TypeMatcher<UsageException>()));
|
||||
});
|
||||
|
||||
test('should throw UsageException for missing component name', () {
|
||||
expect(runner.run(['generate', 'component']),
|
||||
throwsA(const TypeMatcher<UsageException>()));
|
||||
});
|
||||
|
||||
test('should throw UsageException for missing directive name', () {
|
||||
expect(runner.run(['generate', 'directive']),
|
||||
throwsA(const TypeMatcher<UsageException>()));
|
||||
});
|
||||
|
||||
test('should throw UsageException for missing pipe name', () {
|
||||
expect(runner.run(['generate', 'pipe']),
|
||||
throwsA(const TypeMatcher<UsageException>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class AppLoggerMock implements AppLogger {
|
||||
int severeCount = 0;
|
||||
int warningCount = 0;
|
||||
bool verbose = false;
|
||||
|
||||
@override
|
||||
void fine(message, [Object error, StackTrace stackTrace]) {}
|
||||
|
||||
@override
|
||||
void info(message, [Object error, StackTrace stackTrace]) {}
|
||||
|
||||
@override
|
||||
void severe(message, [Object error, StackTrace stackTrace]) {
|
||||
++severeCount;
|
||||
}
|
||||
|
||||
@override
|
||||
void warning(message, [Object error, StackTrace stackTrace]) {
|
||||
++warningCount;
|
||||
}
|
||||
|
||||
@override
|
||||
set isVerbose(bool value) {
|
||||
verbose = value;
|
||||
}
|
||||
}
|
||||
|
||||
class FileWriterMock implements FileWriter {
|
||||
List<String> filesWritten = [];
|
||||
FileWriterMock();
|
||||
@override
|
||||
void write(String destination, String content) {
|
||||
filesWritten.add(destination);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ngflutter/src/exceptions.dart';
|
||||
import 'package:ngflutter/src/file_reader.dart';
|
||||
import 'package:ngflutter/src/package_uri_resolver.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('PackageUriResolver', () {
|
||||
FileReader.reader = new FileReaderMock();
|
||||
|
||||
PackageUriResolver resolver;
|
||||
|
||||
setUp(() {
|
||||
resolver = new PackageUriResolver('.packages');
|
||||
});
|
||||
|
||||
test('should parse dependent package URI', () {
|
||||
var filePath = resolver.resolve('package:some_package/some_file.dart');
|
||||
expect(
|
||||
filePath,
|
||||
equals(path.join(
|
||||
path.separator,
|
||||
path.join(
|
||||
'home',
|
||||
'someone',
|
||||
'.pub-cache',
|
||||
'hosted',
|
||||
'pub.dartlang.org',
|
||||
'some_package-1.0.0',
|
||||
'lib',
|
||||
'some_file.dart'))));
|
||||
});
|
||||
|
||||
test('should parse current project URI', () {
|
||||
var filePath = resolver.resolve('package:ngflutter/some_file.dart');
|
||||
expect(filePath, equals(path.join('lib', 'some_file.dart')));
|
||||
});
|
||||
|
||||
test('should throw for unknow package', () {
|
||||
expect(() => resolver.resolve('package:unknown/some_file.dart'),
|
||||
throwsA(const TypeMatcher<UsageException>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class FileReaderMock implements FileReader {
|
||||
static const List<String> _dotPackages = const [
|
||||
'# Generated by pub on 2017-05-01 00:00:00.00001.',
|
||||
'some_package:file:///home/someone/.pub-cache/hosted/'
|
||||
'pub.dartlang.org/some_package-1.0.0/lib/',
|
||||
'ngflutter:lib/'
|
||||
];
|
||||
|
||||
@override
|
||||
List<String> readAsLines(Object uri, {Encoding encoding: utf8}) {
|
||||
if (uri is String && uri == '.packages') return _dotPackages;
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String readAsString(Object uri, {Encoding encoding: utf8}) => null;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'package:ngflutter/src/page_object_data.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('PageObjectData', () {
|
||||
test('should generate items.', () {
|
||||
var po = new PageObjectData(
|
||||
'<action-button class="good"></action-button>',
|
||||
);
|
||||
expect(po.variables.first.getterString,
|
||||
'Future<PageLoaderElement> get good => _getGood();');
|
||||
expect(po.variables.first.internalString,
|
||||
"@ByClass('good')\n Lazy<PageLoaderElement> _getGood;");
|
||||
expect(po.variables.first.type.uri, 'package:pageloader/objects.dart');
|
||||
});
|
||||
|
||||
test('should generate items in list', () {
|
||||
var po = new PageObjectData(
|
||||
'<action-button class="good" *ngFor="xxx"></action-button>',
|
||||
);
|
||||
expect(po.variables.first.getterString,
|
||||
'Future<List<PageLoaderElement>> get good => _getGood();');
|
||||
expect(po.variables.first.internalString,
|
||||
"@ByClass('good')\n Lazy<List<PageLoaderElement>> _getGood;");
|
||||
});
|
||||
|
||||
test('should generate items in parents list', () {
|
||||
var po = new PageObjectData(
|
||||
'<p *ngFor="xxx"><action-button class="good">'
|
||||
'</action-button></p>',
|
||||
);
|
||||
expect(po.variables.first.getterString,
|
||||
'Future<List<PageLoaderElement>> get good => _getGood();');
|
||||
expect(po.variables.first.internalString,
|
||||
"@ByClass('good')\n Lazy<List<PageLoaderElement>> _getGood;");
|
||||
});
|
||||
|
||||
test('should generate items with default type', () {
|
||||
var po = new PageObjectData('<some-widget class="cool"></some-widget>');
|
||||
expect(po.variables.first.getterString,
|
||||
'Future<PageLoaderElement> get cool => _getCool();');
|
||||
expect(po.variables.first.internalString,
|
||||
"@ByClass('cool')\n Lazy<PageLoaderElement> _getCool;");
|
||||
expect(po.variables.first.type.uri, 'package:pageloader/objects.dart');
|
||||
});
|
||||
|
||||
test('should sort generated items', () {
|
||||
var po1 = new PageObjectData(
|
||||
'<action-button class="good"></action-button>'
|
||||
'<action-button class="bad"></action-button>',
|
||||
);
|
||||
expect(po1.variables.first.name, 'Bad');
|
||||
expect(po1.variables.last.name, 'Good');
|
||||
var po2 = new PageObjectData(
|
||||
'<action-button class="good"></action-button>'
|
||||
'<action-button class="bad"></action-button>',
|
||||
);
|
||||
expect(po2.variables.first.name, 'Bad');
|
||||
expect(po2.variables.last.name, 'Good');
|
||||
});
|
||||
|
||||
test('should ignore some tags.', () {
|
||||
var po = new PageObjectData('<p>123</p>');
|
||||
expect(po.variables.isEmpty, true);
|
||||
});
|
||||
|
||||
test('should add optional annotation.', () {
|
||||
var po = new PageObjectData('<some-widget *ngIf="1"></some-widget>');
|
||||
expect(po.variables[0].internalString, startsWith('@optional'));
|
||||
});
|
||||
|
||||
test('should add optional annotation when parent is optional.', () {
|
||||
var po = new PageObjectData(
|
||||
'<div *ngIf="1"><some-widget></some-widget></div>');
|
||||
expect(po.variables[0].internalString, startsWith('@optional'));
|
||||
});
|
||||
|
||||
test('should add optional annotation when in <template [ngIf]>', () {
|
||||
var po = new PageObjectData(
|
||||
'<template [ngIf]="1"><some-widget></some-widget></template>',
|
||||
);
|
||||
expect(po.variables[0].internalString, startsWith('@optional'));
|
||||
});
|
||||
|
||||
test('should choose correct selector.', () {
|
||||
var po = new PageObjectData(
|
||||
'<some-widget class="cool"></some-widget>'
|
||||
'<some-widget class="cool" id="cooler"></some-widget>'
|
||||
'<some-widget></some-widget>',
|
||||
);
|
||||
expect(po.variables.length, 3);
|
||||
expect(po.variables[0].selector.toString(), "@ByClass('cool')");
|
||||
expect(po.variables[1].selector.toString(), "@ById('cooler')");
|
||||
expect(po.variables[2].selector.toString(), "@ByTagName('some-widget')");
|
||||
});
|
||||
|
||||
test('should work with selectors with attributes', () {
|
||||
var po = new PageObjectData(
|
||||
'<some-cell class="field-class"></some-cell>'
|
||||
'<some-cell id="fieldWithId"></some-cell>',
|
||||
);
|
||||
expect(po.variables[0].selector.toString(), "@ByClass('field-class')");
|
||||
expect(po.variables[1].selector.toString(), "@ById('fieldWithId')");
|
||||
|
||||
expect(po.variables[0].name, 'FieldClass');
|
||||
expect(po.variables[1].name, 'FieldWithId');
|
||||
});
|
||||
|
||||
test('should produce correct commonDependencies.', () {
|
||||
var po1 = new PageObjectData('');
|
||||
expect(po1.commonDependencies, [PageObjectData.pageLoaderDependency]);
|
||||
var po3 = new PageObjectData('<some-widget></some-widget>');
|
||||
expect(po3.commonDependencies, [
|
||||
PageObjectData.pageLoaderDependency,
|
||||
PageObjectData.asyncDependency
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright 2017 Google Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ngflutter/src/file_reader.dart';
|
||||
import 'package:ngflutter/src/project_model.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('ProjectModel', () {
|
||||
FileReader.reader = new FileReaderMock();
|
||||
ProjectModel projectModel;
|
||||
setUp(() {
|
||||
projectModel = new ProjectModel(
|
||||
'.packages', 'pubspec.yaml', path.join('lib', 'a.dart'), null);
|
||||
});
|
||||
|
||||
test('shoud export project name', () {
|
||||
expect(projectModel.projectName, equals('a'));
|
||||
});
|
||||
|
||||
test('should export component class URI', () {
|
||||
expect(projectModel.componentClassUri, equals('package:a/a.dart'));
|
||||
});
|
||||
|
||||
test('should export component class name', () {
|
||||
expect(projectModel.componentClassName, equals('TestComponent'));
|
||||
});
|
||||
|
||||
test('should export service classes used', () {
|
||||
expect(projectModel.serviceClasses, equals(['D']));
|
||||
expect(projectModel.needProviders, isTrue);
|
||||
expect(projectModel.referencedUris, equals(['package:a/a.dart']));
|
||||
});
|
||||
|
||||
test('should export dart classes.', () {
|
||||
expect(projectModel.dartClasses.keys.length, equals(5));
|
||||
expect(projectModel.dartClasses.keys.toList(),
|
||||
equals(['TestComponent', 'A', 'C', 'D', 'E']));
|
||||
});
|
||||
|
||||
test('should export component classes.', () {
|
||||
expect(projectModel.components.keys.length, equals(1));
|
||||
expect(projectModel.components.keys.first, equals('TestComponent'));
|
||||
});
|
||||
|
||||
test('should export binding modules.', () {
|
||||
expect(projectModel.modules.length, equals(1));
|
||||
expect(projectModel.modules.keys.first, equals('someThing'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var _files = [
|
||||
{
|
||||
'path': path.join('a', 'lib', 'a.dart'),
|
||||
'content': '''
|
||||
library test_a;
|
||||
|
||||
import 'package:flutter/flutter.dart';
|
||||
import 'a1.dart';
|
||||
|
||||
part 'src/d.dart';
|
||||
|
||||
@Component(
|
||||
selector: 'test-component',
|
||||
providers: const [
|
||||
someThing,
|
||||
const Provider(A, useClass: B)
|
||||
],
|
||||
templateUrl: 'test.html')
|
||||
class TestComponent {
|
||||
A _a;
|
||||
C _c;
|
||||
D _d;
|
||||
E _e;
|
||||
TestComponent(this._a, this._c, this._d, this._e);
|
||||
}
|
||||
'''
|
||||
},
|
||||
{
|
||||
'path': path.join('a', 'lib', 'src', 'd.dart'),
|
||||
'content': '''
|
||||
part of test_a;
|
||||
|
||||
class D{}
|
||||
'''
|
||||
},
|
||||
{
|
||||
'path': path.join('a', 'lib', 'a1.dart'),
|
||||
'content': '''
|
||||
import 'package:flutter/flutter.dart';
|
||||
|
||||
const someThing = const [
|
||||
const Provider(C, useValue: 'test')
|
||||
];
|
||||
'''
|
||||
}
|
||||
];
|
||||
|
||||
var _dotPackages = ['a:a/lib/'];
|
||||
var _pubSpec = ['name: a'];
|
||||
|
||||
class FileReaderMock implements FileReader {
|
||||
@override
|
||||
List<String> readAsLines(String filePath, {Encoding encoding: utf8}) {
|
||||
if (filePath == '.packages') {
|
||||
return _dotPackages;
|
||||
} else if (filePath == 'pubspec.yaml') {
|
||||
return _pubSpec;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String readAsString(String filePath, {Encoding encoding: utf8}) {
|
||||
for (var file in _files) {
|
||||
if (file['path'] == filePath) return file['content'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user