Unverified Commit e997a3ab authored by Gary Qian's avatar Gary Qian Committed by GitHub

Add tests for migrate command methods (#103466)

parent 5e85d237
......@@ -2,38 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// import 'package:process/process.dart';
// import '../base/file_system.dart';
import '../base/logger.dart';
// import '../base/platform.dart';
import '../base/terminal.dart';
import '../migrate/migrate_utils.dart';
import '../runner/flutter_command.dart';
// TODO(garyq): Add each of these back in as they land.
// import 'migrate_abandon.dart';
// import 'migrate_apply.dart';
// import 'migrate_resolve_conflicts.dart';
// import 'migrate_start.dart';
// import 'migrate_status.dart';
/// Base command for the migration tool.
class MigrateCommand extends FlutterCommand {
MigrateCommand({
// bool verbose = false,
required this.logger,
// TODO(garyq): Add each of these back in as they land.
// required FileSystem fileSystem,
// required Terminal terminal,
// required Platform platform,
// required ProcessManager processManager,
// TODO(garyq): Add each parameters in as subcommands land.
}) {
// TODO(garyq): Add each of these back in as they land.
// addSubcommand(MigrateAbandonCommand(logger: logger, fileSystem: fileSystem, terminal: terminal, platform: platform, processManager: processManager));
// addSubcommand(MigrateApplyCommand(verbose: verbose, logger: logger, fileSystem: fileSystem, terminal: terminal, platform: platform, processManager: processManager));
// addSubcommand(MigrateResolveConflictsCommand(logger: logger, fileSystem: fileSystem, terminal: terminal));
// addSubcommand(MigrateStartCommand(verbose: verbose, logger: logger, fileSystem: fileSystem, platform: platform, processManager: processManager));
// addSubcommand(MigrateStatusCommand(verbose: verbose, logger: logger, fileSystem: fileSystem, platform: platform, processManager: processManager));
// TODO(garyq): Add subcommands.
}
final Logger logger;
......
......@@ -242,32 +242,32 @@ class MigrateUtils {
bool exit = true,
bool silent = false
}) {
if (!allowedExitCodes.contains(result.exitCode) && !allowedExitCodes.contains(-1)) {
if (!silent) {
_logger.printError('Command encountered an error with exit code ${result.exitCode}.');
if (commandDescription != null) {
_logger.printError('Command:');
_logger.printError(commandDescription, indent: 2);
}
_logger.printError('Stdout:');
_logger.printError(result.stdout, indent: 2);
_logger.printError('Stderr:');
_logger.printError(result.stderr, indent: 2);
}
if (exit) {
throwToolExit('Command failed with exit code ${result.exitCode}', exitCode: result.exitCode);
if (allowedExitCodes.contains(result.exitCode) || allowedExitCodes.contains(-1)) {
return true;
}
if (!silent) {
_logger.printError('Command encountered an error with exit code ${result.exitCode}.');
if (commandDescription != null) {
_logger.printError('Command:');
_logger.printError(commandDescription, indent: 2);
}
return false;
_logger.printError('Stdout:');
_logger.printError(result.stdout, indent: 2);
_logger.printError('Stderr:');
_logger.printError(result.stderr, indent: 2);
}
return true;
if (exit) {
throwToolExit('Command failed with exit code ${result.exitCode}', exitCode: result.exitCode);
}
return false;
}
/// Returns true if the file does not contain any git conflit markers.
bool conflictsResolved(String contents) {
if (contents.contains('>>>>>>>') && contents.contains('=======') && contents.contains('<<<<<<<')) {
return false;
}
return true;
final bool hasMarker = contents.contains('>>>>>>>') ||
contents.contains('=======') ||
contents.contains('<<<<<<<');
return !hasMarker;
}
}
......
......@@ -4,6 +4,7 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/migrate/migrate_manifest.dart';
import 'package:flutter_tools/src/migrate/migrate_result.dart';
import 'package:flutter_tools/src/migrate/migrate_utils.dart';
......@@ -13,12 +14,119 @@ import '../../src/common.dart';
void main() {
late FileSystem fileSystem;
late File manifestFile;
late BufferLogger logger;
setUpAll(() {
fileSystem = MemoryFileSystem.test();
logger = BufferLogger.test();
manifestFile = fileSystem.file('.migrate_manifest');
});
group('checkAndPrintMigrateStatus', () {
testWithoutContext('empty MigrateResult produces empty output', () async {
final Directory workingDir = fileSystem.directory('migrate_working_dir');
workingDir.createSync(recursive: true);
final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult(
mergeResults: <MergeResult>[],
addedFiles: <FilePendingMigration>[],
deletedFiles: <FilePendingMigration>[],
mergeTypeMap: <String, MergeType>{},
diffMap: <String, DiffResult>{},
tempDirectories: <Directory>[],
sdkDirs: <String, Directory>{},
));
checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger);
expect(logger.statusText, contains('\n'));
});
testWithoutContext('populated MigrateResult produces correct output', () async {
final Directory workingDir = fileSystem.directory('migrate_working_dir');
workingDir.createSync(recursive: true);
final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult(
mergeResults: <MergeResult>[
StringMergeResult.explicit(
localPath: 'merged_file',
mergedString: 'str',
hasConflict: false,
exitCode: 0,
),
StringMergeResult.explicit(
localPath: 'conflict_file',
mergedString: 'hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n',
hasConflict: true,
exitCode: 1,
),
],
addedFiles: <FilePendingMigration>[FilePendingMigration('added_file', fileSystem.file('added_file'))],
deletedFiles: <FilePendingMigration>[FilePendingMigration('deleted_file', fileSystem.file('deleted_file'))],
// The following are ignored by the manifest.
mergeTypeMap: <String, MergeType>{'test': MergeType.threeWay},
diffMap: <String, DiffResult>{},
tempDirectories: <Directory>[],
sdkDirs: <String, Directory>{},
));
final File conflictFile = workingDir.childFile('conflict_file');
conflictFile.writeAsStringSync('hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n', flush: true);
checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger);
expect(logger.statusText, contains('''
Added files:
- added_file
Deleted files:
- deleted_file
Modified files:
- conflict_file
- merged_file
'''));
});
testWithoutContext('populated MigrateResult detects fixed conflict', () async {
final Directory workingDir = fileSystem.directory('migrate_working_dir');
workingDir.createSync(recursive: true);
final MigrateManifest manifest = MigrateManifest(migrateRootDir: workingDir, migrateResult: MigrateResult(
mergeResults: <MergeResult>[
StringMergeResult.explicit(
localPath: 'merged_file',
mergedString: 'str',
hasConflict: false,
exitCode: 0,
),
StringMergeResult.explicit(
localPath: 'conflict_file',
mergedString: 'hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n',
hasConflict: true,
exitCode: 1,
),
],
addedFiles: <FilePendingMigration>[FilePendingMigration('added_file', fileSystem.file('added_file'))],
deletedFiles: <FilePendingMigration>[FilePendingMigration('deleted_file', fileSystem.file('deleted_file'))],
// The following are ignored by the manifest.
mergeTypeMap: <String, MergeType>{'test': MergeType.threeWay},
diffMap: <String, DiffResult>{},
tempDirectories: <Directory>[],
sdkDirs: <String, Directory>{},
));
final File conflictFile = workingDir.childFile('conflict_file');
conflictFile.writeAsStringSync('hello\nwow a bunch of lines\nhi\n', flush: true);
checkAndPrintMigrateStatus(manifest, workingDir, warnConflict: true, logger: logger);
expect(logger.statusText, contains('''
Added files:
- added_file
Deleted files:
- deleted_file
Modified files:
- conflict_file
- merged_file
'''));
});
});
group('manifest file parsing', () {
testWithoutContext('empty fails', () async {
manifestFile.writeAsStringSync('');
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/commands/migrate.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/migrate/migrate_utils.dart';
import '../src/common.dart';
void main() {
BufferLogger logger;
FileSystem fileSystem;
Directory projectRoot;
String projectRootPath;
ProcessUtils processUtils;
MigrateUtils utils;
setUpAll(() async {
fileSystem = globals.localFileSystem;
logger = BufferLogger.test();
utils = MigrateUtils(
logger: logger,
fileSystem: fileSystem,
platform: globals.platform,
processManager: globals.processManager,
);
processUtils = ProcessUtils(processManager: globals.processManager, logger: logger);
});
group('git', () {
setUp(() async {
projectRoot = fileSystem.systemTempDirectory.createTempSync('flutter_migrate_command_test');
projectRoot.createSync(recursive: true);
projectRootPath = projectRoot.path;
});
tearDown(() async {
tryToDelete(projectRoot);
});
testWithoutContext('isGitRepo', () async {
expect(projectRoot.existsSync(), true);
expect(projectRoot.childDirectory('.git').existsSync(), false);
expect(await gitRepoExists(projectRootPath, logger, utils), false);
expect(logger.statusText, contains('Project is not a git repo. Please initialize a git repo and try again.'));
await utils.gitInit(projectRootPath);
expect(projectRoot.childDirectory('.git').existsSync(), true);
expect(await gitRepoExists(projectRootPath, logger, utils), true);
});
testWithoutContext('printCommandText produces formatted output', () async {
printCommandText('some command --help', logger);
expect(logger.statusText, contains(r' $ some command --help'));
});
testWithoutContext('hasUncommittedChanges false on clean repo', () async {
expect(projectRoot.existsSync(), true);
expect(projectRoot.childDirectory('.git').existsSync(), false);
await utils.gitInit(projectRootPath);
expect(projectRoot.childDirectory('.git').existsSync(), true);
projectRoot.childFile('.gitignore')
..createSync()
..writeAsStringSync('ignored_file.dart', flush: true);
await processUtils.run(<String>['git', 'add', '.'], workingDirectory: projectRootPath);
await processUtils.run(<String>['git', 'commit', '-m', 'Initial commit'], workingDirectory: projectRootPath);
expect(await hasUncommittedChanges(projectRootPath, logger, utils), false);
});
testWithoutContext('hasUncommittedChanges true on dirty repo', () async {
expect(projectRoot.existsSync(), true);
expect(projectRoot.childDirectory('.git').existsSync(), false);
await utils.gitInit(projectRootPath);
expect(projectRoot.childDirectory('.git').existsSync(), true);
projectRoot.childFile('some_file.dart')
..createSync()
..writeAsStringSync('void main() {}', flush: true);
expect(await hasUncommittedChanges(projectRootPath, logger, utils), true);
});
});
}
......@@ -40,6 +40,10 @@ void main() {
projectRootPath = projectRoot.path;
});
tearDown(() async {
tryToDelete(projectRoot);
});
testWithoutContext('init', () async {
expect(projectRoot.existsSync(), true);
expect(projectRoot.childDirectory('.git').existsSync(), false);
......@@ -220,4 +224,15 @@ void main() {
projectRoot.deleteSync(recursive: true);
});
});
testWithoutContext('conflictsResolved', () async {
expect(utils.conflictsResolved(''), true);
expect(utils.conflictsResolved('hello'), true);
expect(utils.conflictsResolved('hello\n'), true);
expect(utils.conflictsResolved('hello\nwow a bunch of lines\n\nhi\n'), true);
expect(utils.conflictsResolved('hello\nwow a bunch of lines\n>>>>>>>\nhi\n'), false);
expect(utils.conflictsResolved('hello\nwow a bunch of lines\n=======\nhi\n'), false);
expect(utils.conflictsResolved('hello\nwow a bunch of lines\n<<<<<<<\nhi\n'), false);
expect(utils.conflictsResolved('hello\nwow a bunch of lines\n<<<<<<<\n=======\n<<<<<<<\nhi\n'), false);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment