| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:convert'; | |
| import 'dart:io'; | |
| import 'package:dartdev/src/commands/create.dart'; | |
| import 'package:dartdev/src/sdk.dart'; | |
| import 'package:dartdev/src/templates.dart' as templates; | |
| import 'package:dartdev/src/utils.dart'; | |
| import 'package:path/path.dart' as path; | |
| import 'package:test/test.dart'; | |
| import '../utils.dart'; | |
| void main() { | |
| group('create', defineCreateTests, timeout: longTimeout); | |
| } | |
| void defineCreateTests() { | |
| test('--help', () async { | |
| final p = project(); | |
| var result = await p.run(['create', '--help']); | |
| expect(result.stdout, contains('Create a new Dart project.')); | |
| expect( | |
| result.stdout, | |
| contains('Usage: dart create [arguments] <directory>'), | |
| ); | |
| expect(result.stderr, isEmpty); | |
| expect(result.exitCode, 0); | |
| }); | |
| test('--help --verbose', () async { | |
| final p = project(); | |
| var result = await p.run(['create', '--help', '--verbose']); | |
| expect(result.stdout, contains('Create a new Dart project.')); | |
| expect( | |
| result.stdout, | |
| contains('Usage: dart [vm-options] create [arguments] <directory>'), | |
| ); | |
| expect(result.stderr, isEmpty); | |
| expect(result.exitCode, 0); | |
| }); | |
| test('default template exists', () async { | |
| expect( | |
| CreateCommand.legalTemplateIds(), | |
| contains(CreateCommand.defaultTemplateId), | |
| ); | |
| }); | |
| test('no templates IDs overlap', () async { | |
| final ids = <String>{}; | |
| for (final g in templates.generators) { | |
| expect(ids.contains(g.id), false); | |
| ids.add(g.id); | |
| if (g.alternateId != null) { | |
| expect(ids.contains(g.alternateId), false); | |
| ids.add(g.alternateId!); | |
| } | |
| } | |
| }); | |
| test('list templates', () async { | |
| final p = project(); | |
| ProcessResult result = await p.run(['create', '--list-templates']); | |
| expect(result.exitCode, 0); | |
| String output = result.stdout.toString(); | |
| var parsedResult = jsonDecode(output); | |
| expect(parsedResult[0]['name'], isNotNull); | |
| expect(parsedResult[0]['label'], isNotNull); | |
| expect(parsedResult[0]['description'], isNotNull); | |
| }); | |
| test('no directory given', () async { | |
| final p = project(); | |
| ProcessResult result = await p.run(['create']); | |
| expect(result.exitCode, 1); | |
| }); | |
| test('directory already exists', () async { | |
| final p = project(); | |
| ProcessResult result = await p.run([ | |
| 'create', | |
| '--template', | |
| CreateCommand.defaultTemplateId, | |
| p.dir.path, | |
| ]); | |
| expect(result.exitCode, 73); | |
| }); | |
| test('project in current directory', () async { | |
| final tempDir = Directory.systemTemp.createTempSync('create_test'); | |
| try { | |
| final p = project(); | |
| final projectDir = Directory.fromUri(tempDir.uri.resolve('foo/')) | |
| ..createSync(); | |
| final result = await p.run([ | |
| 'create', | |
| '--force', | |
| '.', | |
| ], workingDir: projectDir.path); | |
| expect(result.stderr, isEmpty); | |
| expect(result.stdout, contains('Created project foo in .!')); | |
| expect(result.exitCode, 0); | |
| } finally { | |
| tempDir.deleteSync(recursive: true); | |
| } | |
| }); | |
| test('project with normalized package name, with -', () async { | |
| final p = project(); | |
| final result = await p.run([ | |
| 'create', | |
| '--no-pub', | |
| 'requires-normalization', | |
| ]); | |
| expect(result.stderr, isEmpty); | |
| expect( | |
| result.stdout, | |
| contains( | |
| 'Created project requires_normalization in requires-normalization!', | |
| ), | |
| ); | |
| expect(result.exitCode, 0); | |
| }); | |
| test('project with normalized package name, with camel case', () async { | |
| final p = project(); | |
| final result = await p.run(['create', '--no-pub', 'RequiresNormalization']); | |
| expect(result.stderr, isEmpty); | |
| expect( | |
| result.stdout, | |
| contains( | |
| 'Created project requires_normalization in RequiresNormalization!', | |
| ), | |
| ); | |
| expect(result.exitCode, 0); | |
| }); | |
| test('project with normalized package name, all upper case', () async { | |
| final p = project(); | |
| final result = await p.run(['create', '--no-pub', 'HTML']); | |
| expect(result.stderr, isEmpty); | |
| expect(result.stdout, contains('Created project html in HTML!')); | |
| expect(result.exitCode, 0); | |
| }); | |
| test('project name to lower case', () { | |
| expect(projectNameToLowerCase('lower_case'), 'lower_case'); | |
| expect(projectNameToLowerCase('camelCase'), 'camel_case'); | |
| expect(projectNameToLowerCase('PascalCase'), 'pascal_case'); | |
| expect(projectNameToLowerCase('already_snake_case'), 'already_snake_case'); | |
| expect( | |
| projectNameToLowerCase('mixedCamel_AndPascal_and_snake'), | |
| 'mixed_camel_and_pascal_and_snake', | |
| ); | |
| expect(projectNameToLowerCase('with123Numbers'), 'with123_numbers'); | |
| expect( | |
| projectNameToLowerCase('CONSECUTIVE_UPPER_CASE'), | |
| 'consecutive_upper_case', | |
| ); | |
| }); | |
| test('project with an invalid package name', () async { | |
| final p = project(); | |
| final result = await p.run(['create', 'bad-package^name']); | |
| expect( | |
| result.stderr, | |
| contains( | |
| '"bad_package^name" is not a valid Dart project name.\n\n' | |
| 'See https://dart.dev/tools/pub/pubspec#name for more information.', | |
| ), | |
| ); | |
| expect(result.exitCode, 73); | |
| }); | |
| test('bad template id', () async { | |
| final p = project(); | |
| ProcessResult result = await p.run([ | |
| 'create', | |
| '--no-pub', | |
| '--template', | |
| 'foo-bar', | |
| p.dir.path, | |
| ]); | |
| expect(result.exitCode, isNot(0)); | |
| }); | |
| // Create tests for each template. | |
| for (String templateId in CreateCommand.legalTemplateIds( | |
| includeDeprecated: true, | |
| )) { | |
| test(templateId, () async { | |
| final p = project(); | |
| const projectName = 'template_project'; | |
| ProcessResult result = await p.run([ | |
| 'create', | |
| '--force', | |
| '--no-pub', | |
| '--template', | |
| templateId, | |
| projectName, | |
| ]); | |
| expect(result.exitCode, 0); | |
| String entry = templates.getGenerator(templateId)!.entrypoint!.path; | |
| entry = entry.replaceAll('__projectName__', projectName); | |
| File entryFile = File(path.join(p.dir.path, projectName, entry)); | |
| expect( | |
| entryFile.existsSync(), | |
| true, | |
| reason: 'File not found: ${entryFile.path}', | |
| ); | |
| }); | |
| } | |
| for (final generator in templates.generators) { | |
| test('${generator.id} getting started message', () { | |
| const dir = 'foo'; | |
| const projectName = dir; | |
| final lines = generator | |
| .getInstallInstructions(dir, scriptPath: projectName) | |
| .split('\n') | |
| .map((e) => e.trim()) | |
| .toList(); | |
| if (generator.categories.contains('web')) { | |
| expect(lines.length, 3); | |
| expect(lines[0], 'cd $dir'); | |
| expect(lines[1], 'dart pub global activate webdev'); | |
| expect(lines[2], 'webdev serve'); | |
| } else if (generator.categories.contains('console')) { | |
| expect(lines.length, 2); | |
| expect(lines[0], 'cd $dir'); | |
| expect(lines[1], 'dart run'); | |
| } else if (generator.categories.contains('server')) { | |
| expect(lines.length, 2); | |
| expect(lines[0], 'cd $dir'); | |
| expect(lines[1], 'dart run bin/server.dart'); | |
| } else if (generator.categories.contains('cli')) { | |
| expect(lines.length, 2); | |
| expect(lines[0], 'cd $dir'); | |
| expect(lines[1], 'dart run bin/$projectName.dart'); | |
| } else { | |
| expect(lines.length, 2); | |
| expect(lines[0], 'cd $dir'); | |
| expect(lines[1], 'dart run example/${projectName}_example.dart'); | |
| } | |
| }); | |
| } | |
| for (final generator in templates.generators) { | |
| test('${generator.id} generated pubspec file', () { | |
| final pubspec = generator.getFile('pubspec.yaml'); | |
| expect(pubspec, isNotNull); | |
| final pubspecContent = pubspec!.content; | |
| expect(pubspecContent, contains('sdk: ^${sdk.version}')); | |
| }); | |
| } | |
| } |