adding packages

This commit is contained in:
2026-01-15 14:38:46 -08:00
parent ef86e3ab6a
commit 6869cf47e5
5253 changed files with 726695 additions and 34 deletions
@@ -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;
}
}