diff --git a/lib/src/commands/account_command/account_command.dart b/lib/src/commands/account_command/account_command.dart deleted file mode 100644 index 295df3f..0000000 --- a/lib/src/commands/account_command/account_command.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:args/command_runner.dart'; -import 'package:langsync/src/commands/account_command/sub_commands/api_key_command.dart'; -import 'package:langsync/src/commands/account_command/sub_commands/auth_command.dart'; -import 'package:langsync/src/commands/account_command/sub_commands/info_command.dart'; -import 'package:langsync/src/commands/account_command/sub_commands/logout_command.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class AccountCommand extends Command { - AccountCommand({ - required Logger logger, - }) : _logger = logger { - addSubcommand(AuthCommand(logger: _logger)); - addSubcommand(InfoCommand(logger: _logger)); - addSubcommand(LogoutCommand(logger: _logger)); - addSubcommand(AccountCreateCommand(logger: _logger)); - } - - @override - String get description => 'Manage the authenticated account in use.'; - - @override - String get name => 'account'; - - final Logger _logger; -} diff --git a/lib/src/commands/account_command/sub_commands/api_key_command.dart b/lib/src/commands/account_command/sub_commands/api_key_command.dart deleted file mode 100644 index 654fa09..0000000 --- a/lib/src/commands/account_command/sub_commands/api_key_command.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/etc/networking/client.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class AccountCreateCommand extends Command { - AccountCreateCommand({ - required this.logger, - }); - - final Logger logger; - - @override - String get description => 'Create your unique API key & LangSync account.'; - - @override - String get name => 'create'; - - @override - FutureOr? run() async { - final userSure = logger.confirm( - "You're about to create a brand new unique API key, do you want to continue?", - ); - - if (!userSure) { - logger.info('Aborted!'); - return 0; - } - - logger.info('\n'); - - final userName = logger.prompt( - 'Please enter your desired username (will be used to identify you): ', - ); - - if (userName.isEmpty) { - logger.err("Username can't be empty!"); - return 1; - } - - final progress = logger.progress('Creating your API key...'); - - try { - final apiKeyDoc = await NetClient.instance.createApiKey(userName); - - progress.complete('API key created successfully!'); - logger - ..info('\n') - ..success('Your API key: ${apiKeyDoc.apiKey}') - ..info('\n') - ..warn( - "Please make sure to save your API key somewhere safe, as you won't be able to retrieve it again!", - ) - ..info('\n') - ..info( - "run 'langsync account auth' to configure LangSync with that API key to start using it.", - ); - - return ExitCode.success.code; - } catch (e, stacktrace) { - logger.customErr( - progress: progress, - update: 'Failed to create API key!', - error: e, - ); - - try { - await NetClient.instance.logException( - e: e, - stacktrace: stacktrace, - commandName: name, - ); - - logger - ..info('\n') - ..warn( - 'This error has been reported to the LangSync team, we will definitely look into it!', - ); - } catch (e) {} - - return ExitCode.software.code; - } - } -} diff --git a/lib/src/commands/account_command/sub_commands/auth_command.dart b/lib/src/commands/account_command/sub_commands/auth_command.dart deleted file mode 100644 index 593c349..0000000 --- a/lib/src/commands/account_command/sub_commands/auth_command.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:hive/hive.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/etc/networking/client.dart'; -import 'package:langsync/src/etc/utils.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class AuthCommand extends Command { - AuthCommand({ - required this.logger, - }); - - final Logger logger; - - @override - String get description => 'Authenticate your account with CLI.'; - - @override - String get name => 'auth'; - - @override - FutureOr? run() async { - logger - ..info('Please, provide your account API key to authenticate.') - ..info('You can find & manage your API keys from your dashboard.'); - - final apiKey = logger.prompt('Enter API key here: '); - - if (utils.isValidApiKeyFormatted(apiKey)) { - final configBox = Hive.box('config'); - - final savingProgress = - logger.customProgress('Your API key is being saved..'); - - try { - if (configBox.get('apiKey') != null) { - savingProgress.update('Deleting your previous set API key..'); - - await configBox.delete('apiKey'); - - savingProgress - .update('Your Previous API key has been deleted successfully.'); - } - - savingProgress.update('Saving your API key..'); - - await configBox.put('apiKey', apiKey); - - savingProgress.complete('Your API key has been saved successfully.'); - - return ExitCode.success.code; - } catch (e, stacktrace) { - logger.customErr( - error: e, - progress: savingProgress, - update: - 'Something went wrong while saving your API key, please try again.', - ); - - try { - await NetClient.instance.logException( - e: e, - stacktrace: stacktrace, - commandName: name, - ); - - logger - ..info('\n') - ..warn( - 'This error has been reported to the LangSync team, we will definitely look into it!', - ); - } catch (e) {} - - return ExitCode.ioError.code; - } - } else { - logger - ..err('The API key you provided is not valid, please try again.') - ..docsInfo(path: '/cli-usage/auth'); - - return ExitCode.ioError.code; - } - } -} diff --git a/lib/src/commands/account_command/sub_commands/info_command.dart b/lib/src/commands/account_command/sub_commands/info_command.dart deleted file mode 100644 index 4f6dd41..0000000 --- a/lib/src/commands/account_command/sub_commands/info_command.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:hive/hive.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/etc/networking/client.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class InfoCommand extends Command { - InfoCommand({ - required this.logger, - }) { - argParser.addFlag( - 'reveal-api-key', - negatable: false, - help: 'Shows the API key of the current account.', - ); - } - - @override - final name = 'info'; - - @override - final description = 'Show account information'; - - final Logger logger; - - @override - FutureOr? run() async { - final configBox = Hive.box('config'); - - final apiKey = configBox.get('apiKey') as String?; - - if (apiKey == null) { - logger - ..info( - 'You are not authenticated, please provide an API key to authenticate.', - ) - ..docsInfo(path: '/cli-usage/auth'); - - return ExitCode.usage.code; - } - - final shouldRevealApiKey = argResults?['reveal-api-key'] == true; - - final shownApiKey = shouldRevealApiKey ? apiKey : apiKey.hiddenBy('*'); - - final fetchingProgress = logger.customProgress( - "Fetching account's information...", - ); - - try { - final userInfo = await NetClient.instance.userInfo(apiKey: apiKey); - - fetchingProgress.complete("fetched account's information successfully."); - - logger - ..info('') - ..info('The API key in use: $shownApiKey'); - - final fields = userInfo.toJson().entries.toList(); - - for (var index = 0; index < fields.length; index++) { - final curr = fields[index]; - logger.info('${curr.key}: ${curr.value}'); - } - - return ExitCode.success.code; - } catch (e, stacktrace) { - logger.customErr( - error: e, - progress: fetchingProgress, - update: 'Failed to fetch account information.', - ); - - try { - await NetClient.instance.logException( - e: e, - stacktrace: stacktrace, - commandName: name, - ); - - logger - ..info('\n') - ..warn( - 'This error has been reported to the LangSync team, we will definitely look into it!', - ); - } catch (e) {} - - return ExitCode.software.code; - } - } -} diff --git a/lib/src/commands/account_command/sub_commands/logout_command.dart b/lib/src/commands/account_command/sub_commands/logout_command.dart deleted file mode 100644 index c4ab874..0000000 --- a/lib/src/commands/account_command/sub_commands/logout_command.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:args/command_runner.dart'; -import 'package:hive/hive.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/etc/networking/client.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class LogoutCommand extends Command { - LogoutCommand({ - required this.logger, - }); - - @override - String get description => 'Logout from the current account'; - - @override - String get name => 'logout'; - - final Logger logger; - - @override - Future run() async { - final configBox = Hive.box('config'); - - final apiKey = configBox.get('apiKey') as String?; - - if (apiKey == null) { - logger - ..info('No account was logged in previously.') - ..docsInfo(path: '/cli-usage/auth'); - - return ExitCode.success.code; - } else { - final confirm = logger.confirm( - 'Are you sure you want to logout from the current account?', - ); - - if (!confirm) { - logger - ..info('Logout aborted.') - ..docsInfo(path: '/cli-usage/auth'); - - return ExitCode.success.code; - } - - final logoutProgress = - logger.customProgress('Logging out from the account..'); - - try { - await configBox.delete('apiKey'); - logoutProgress.complete('Successfully logged out.'); - - return ExitCode.success.code; - } catch (e, stacktrace) { - logger.customErr( - error: e, - progress: logoutProgress, - update: 'Something went wrong while logging out, please try again.', - ); - - try { - await NetClient.instance.logException( - e: e, - stacktrace: stacktrace, - commandName: name, - ); - logger - ..info('\n') - ..warn( - 'This error has been reported to the LangSync team, we will definitely look into it!', - ); - } catch (e) {} - - return ExitCode.ioError.code; - } - } - } -} diff --git a/lib/src/commands/commands.dart b/lib/src/commands/commands.dart deleted file mode 100644 index 30041fe..0000000 --- a/lib/src/commands/commands.dart +++ /dev/null @@ -1,2 +0,0 @@ -export './account_command/account_command.dart'; -export 'update_command.dart'; diff --git a/lib/src/commands/start_command/start_command.dart b/lib/src/commands/start_command/start_command.dart index c309e85..86844ce 100644 --- a/lib/src/commands/start_command/start_command.dart +++ b/lib/src/commands/start_command/start_command.dart @@ -108,7 +108,7 @@ class StartCommand extends Command { ); try { - final jsonPartitionRes = await NetClient.instance.savePartitionsJson( + final jsonPartitionRes = await NetClient.instance.saveFile( apiKey: apiKey, sourceFile: File(asConfig.sourceFile), ); @@ -138,6 +138,7 @@ class StartCommand extends Command { final outputList = await NetClient.instance.retrieveJsonPartitionWithOutput( outputPartitionId: result.outputPartitionId, + apiKey: apiKey, ); await _writeNewLocalizationFiles( @@ -272,7 +273,7 @@ class StartCommand extends Command { final processStream = NetClient.instance.startAIProcess( apiKey: apiKey, langs: langs, - jsonPartitionId: partitionId, + operationId: partitionId, languageLocalizationMaxDelay: languageLocalizationMaxDelay, ); diff --git a/lib/src/commands/supported_laungages_command/supported_laungages_command.dart b/lib/src/commands/supported_laungages_command/supported_laungages_command.dart deleted file mode 100644 index c5e4ea4..0000000 --- a/lib/src/commands/supported_laungages_command/supported_laungages_command.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'dart:async'; - -import 'package:args/command_runner.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/etc/networking/client.dart'; -import 'package:mason_logger/mason_logger.dart'; - -class SupportedLangsCommand extends Command { - SupportedLangsCommand({ - required this.logger, - }) { - argParser.addOption( - 'langs', - help: 'Check for multiple languages support.', - ); - } - - final Logger logger; - - @override - String get description => 'Check supported languages that can be used.'; - - @override - String get name => 'supported-langs'; - - @override - FutureOr? run() async { - final langsOption = argResults?['langs'] as String?; - - if (langsOption != null) { - final langs = langsOption.split(',').map((e) => e.trim()).toList(); - - return await _checkLangsSupport(langs); - } else { - logger.info('you will need to provide one or many langs to check.'); - - var langPrompt = logger.prompt( - 'What language(s) do you want to check? (comma separated): ', - ); - - langPrompt = langPrompt.trim(); - - if (langPrompt.isEmpty) { - logger - ..err('No language(s) provided.') - ..docsInfo(path: '/cli-usage/check_launguages_support'); - - return ExitCode.usage.code; - } else { - final langs = langPrompt.split(',').map((e) => e.trim()).toList(); - - return await _checkLangsSupport(langs); - } - } - } - - // Future _handleLangSupport(String lang, Progress prog) async { - // if (lang.split(',').length > 1) { - // logger.err('Only one language is allowed with the --lang flag'); - - // return ExitCode.usage.code; - // } - - // try { - // prog.update('Checking language $lang support'); - - // final isSupported = await NetClient.instance.supportsLang(lang); - // if (isSupported) { - // prog.complete('Language $lang is supported.'); - // } else { - // prog.complete('Language $lang is not supported.'); - // } - - // return ExitCode.success.code; - // } catch (e) { - // logger.customErr( - // error: e, - // progress: prog, - // update: - // 'Something went wrong while checking language $lang support, please try again.', - // ); - - // return ExitCode.software.code; - // } - // } - - Future _checkLangsSupport(List langs) async { - final checkProgress = - logger.progress('Checking languages support for: $langs'); - - try { - final langsCheckResponse = await NetClient.instance.supportsLang(langs); - checkProgress.complete('Done checking languages support.'); - - for (final element in langs) { - if (langsCheckResponse[element] ?? false) { - logger.success('The language $element is supported.'); - } else { - logger.err('The language $element is not supported.'); - } - } - - return ExitCode.success.code; - } catch (e, stacktrace) { - logger.customErr( - progress: checkProgress, - update: 'Something went wrong..', - error: e, - ); - - try { - await NetClient.instance.logException( - e: e, - stacktrace: stacktrace, - commandName: name, - ); - - logger.info('\n'); - logger.warn( - 'This error has been reported to the LangSync team, we will definitely look into it!', - ); - } catch (e) {} - - return ExitCode.software.code; - } - } -} diff --git a/lib/src/etc/networking/client.dart b/lib/src/etc/networking/client.dart index c1392be..0ab59d0 100644 --- a/lib/src/etc/networking/client.dart +++ b/lib/src/etc/networking/client.dart @@ -17,34 +17,10 @@ class NetClient extends NetClientBoilerPlate { static NetClient get instance => _instance; - Future userInfo({required String apiKey}) { - return makeRes('user', 'GET', { - 'Authorization': 'Bearer $apiKey', - }, {}, (res) { - return UserInfo.fromJson(res); - }); - } - - Future> supportsLang(List lang) { - return makeRes>('/langs-support', 'POST', {}, { - 'langs': lang, - }, (res) { - final map = {}; - - final list = (res['checkResultList'] as List).cast(); - - for (final element in list) { - map[element] = true; - } - - return map; - }); - } - Stream> startAIProcess({ required Iterable langs, required String apiKey, - required String jsonPartitionId, + required String operationId, required int? languageLocalizationMaxDelay, bool includeOutput = false, }) { @@ -53,7 +29,7 @@ class NetClient extends NetClientBoilerPlate { 'POST', {'Authorization': 'Bearer $apiKey'}, { - 'jsonPartitionsId': jsonPartitionId, + 'operationId': operationId, 'langs': langs.toList(), 'includeOutput': includeOutput, 'languageLocalizationMaxDelay': languageLocalizationMaxDelay, @@ -71,12 +47,12 @@ class NetClient extends NetClientBoilerPlate { ); } - Future savePartitionsJson({ + Future saveFile({ required String apiKey, required File sourceFile, }) { return makeMultiPartRes( - '/save-partitioned-json-of-user', + 'json/save-file', 'post', {'Authorization': 'Bearer $apiKey'}, {'sourceFile': sourceFile}, @@ -84,36 +60,18 @@ class NetClient extends NetClientBoilerPlate { ); } - Future checkWetherApiKeyExistsForSomeUser({ - required String apiKey, - }) async { - return makeRes( - '/verify-api-key-existence', - 'GET', - {'Authorization': 'Bearer $apiKey'}, - {}, - (res) { - final exists = res['exists'] as bool?; - - if (exists == null) { - throw Exception( - "the 'exists' field does not exist in the response of this API endpoint", - ); - } - return exists; - }, - ); - } - Future> retrieveJsonPartitionWithOutput({ required String outputPartitionId, + required String apiKey, }) { return makeRes( - '/get-partitioned-json-of-user', + '/file-operation-of-user', 'GET', - {}, { - 'jsonPartitionsId': outputPartitionId, + 'Authorization': 'Bearer ${apiKey}', + }, + { + 'operationId': outputPartitionId, }, (res) { final output = (res['output'] as List) diff --git a/lib/src/etc/utils.dart b/lib/src/etc/utils.dart index 7185fb4..68cf9ed 100644 --- a/lib/src/etc/utils.dart +++ b/lib/src/etc/utils.dart @@ -21,31 +21,6 @@ class Utils { return isNotEmpty && hasValidLength; } - Future doesApiKeyExistsForSomeUser({ - required String apiKey, - required Logger logger, - }) async { - final apiKeyCheckProgress = - logger.customProgress('starting api key check..'); - - try { - final doesApiKeyExistsForSomeUser = - await NetClient.instance.checkWetherApiKeyExistsForSomeUser( - apiKey: apiKey, - ); - - return doesApiKeyExistsForSomeUser; - } catch (e, stacktrace) { - logger.customErr( - progress: apiKeyCheckProgress, - update: '', - error: stacktrace, - ); - - return false; - } - } - Directory localeDataDir() { if (Platform.isWindows) { final appDataDir = Directory(Platform.environment['APPDATA']!); diff --git a/test/ensure_build_test.dart b/test/ensure_build_test.dart deleted file mode 100644 index 92d78d4..0000000 --- a/test/ensure_build_test.dart +++ /dev/null @@ -1,10 +0,0 @@ -@Tags(['version-verify']) -library ensure_build_test; - -import 'package:build_verify/build_verify.dart'; -import 'package:test/test.dart'; -// - -void main() { - test('ensure_build', expectBuildClean); -} diff --git a/test/src/command_runner_test.dart b/test/src/command_runner_test.dart deleted file mode 100644 index 8a9f279..0000000 --- a/test/src/command_runner_test.dart +++ /dev/null @@ -1,179 +0,0 @@ -import 'dart:io'; - -import 'package:args/command_runner.dart'; -import 'package:cli_completion/cli_completion.dart'; -import 'package:langsync/src/command_runner.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/version.dart'; -import 'package:mason_logger/mason_logger.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:pub_updater/pub_updater.dart'; -import 'package:test/test.dart'; - -class _MockLogger extends Mock implements Logger {} - -class _MockProcessResult extends Mock implements ProcessResult {} - -class _MockProgress extends Mock implements Progress {} - -class _MockPubUpdater extends Mock implements PubUpdater {} - -const latestVersion = '0.0.0'; - -final updatePrompt = ''' -${lightYellow.wrap('Update available!')} ${lightCyan.wrap(packageVersion)} \u2192 ${lightCyan.wrap(latestVersion)} -Run ${lightCyan.wrap('$executableName update')} to update'''; - -void main() { - group('LangsyncCommandRunner', () { - late PubUpdater pubUpdater; - late Logger logger; - late ProcessResult processResult; - late LangsyncCommandRunner commandRunner; - - setUp(() { - pubUpdater = _MockPubUpdater(); - - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => packageVersion); - - logger = _MockLogger(); - - processResult = _MockProcessResult(); - when(() => processResult.exitCode).thenReturn(ExitCode.success.code); - - commandRunner = LangsyncCommandRunner( - logger: logger, - pubUpdater: pubUpdater, - ); - }); - - test('shows update message when newer version exists', () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - - final result = await commandRunner.run(['--version']); - expect(result, equals(ExitCode.success.code)); - verify(() => logger.info(updatePrompt)).called(1); - }); - - test( - 'Does not show update message when the shell calls the ' - 'completion command', - () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - - final result = await commandRunner.run(['completion']); - expect(result, equals(ExitCode.success.code)); - verifyNever(() => logger.info(updatePrompt)); - }, - ); - - test('does not show update message when using update command', () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - when( - () => pubUpdater.update( - packageName: packageName, - versionConstraint: any(named: 'versionConstraint'), - ), - ).thenAnswer((_) async => processResult); - when( - () => pubUpdater.isUpToDate( - packageName: any(named: 'packageName'), - currentVersion: any(named: 'currentVersion'), - ), - ).thenAnswer((_) async => true); - - final progress = _MockProgress(); - final progressLogs = []; - when(() => progress.complete(any())).thenAnswer((_) { - final message = _.positionalArguments.elementAt(0) as String?; - if (message != null) progressLogs.add(message); - }); - when(() => logger.customProgress(any())).thenReturn(progress); - - final result = await commandRunner.run(['update']); - expect(result, equals(ExitCode.success.code)); - verifyNever(() => logger.info(updatePrompt)); - }); - - test('can be instantiated without an explicit analytics/logger instance', - () { - final commandRunner = LangsyncCommandRunner(); - expect(commandRunner, isNotNull); - expect(commandRunner, isA>()); - }); - - test('handles FormatException', () async { - const exception = FormatException('oops!'); - var isFirstInvocation = true; - when(() => logger.info(any())).thenAnswer((_) { - if (isFirstInvocation) { - isFirstInvocation = false; - throw exception; - } - }); - final result = await commandRunner.run(['--version']); - expect(result, equals(ExitCode.usage.code)); - verify(() => logger.err(exception.message)).called(1); - verify(() => logger.info(commandRunner.usage)).called(1); - }); - - test('handles UsageException', () async { - final exception = UsageException('oops!', 'exception usage'); - var isFirstInvocation = true; - when(() => logger.info(any())).thenAnswer((_) { - if (isFirstInvocation) { - isFirstInvocation = false; - throw exception; - } - }); - final result = await commandRunner.run(['--version']); - expect(result, equals(ExitCode.usage.code)); - verify(() => logger.err(exception.message)).called(1); - verify(() => logger.info('exception usage')).called(1); - }); - - group('--version', () { - test('outputs current version', () async { - final result = await commandRunner.run(['--version']); - expect(result, equals(ExitCode.success.code)); - verify(() => logger.info(packageVersion)).called(1); - }); - }); - - group('--verbose', () { - test('enables verbose logging', () async { - final result = await commandRunner.run(['--verbose']); - expect(result, equals(ExitCode.success.code)); - - verify(() => logger.detail('Argument information:')).called(1); - verify(() => logger.detail(' Top level options:')).called(1); - verify(() => logger.detail(' - verbose: true')).called(1); - verifyNever(() => logger.detail(' Command options:')); - }); - - test('enables verbose logging for sub commands', () async { - final result = await commandRunner.run([ - '--verbose', - 'sample', - '--cyan', - ]); - expect(result, equals(ExitCode.success.code)); - - verify(() => logger.detail('Argument information:')).called(1); - verify(() => logger.detail(' Top level options:')).called(1); - verify(() => logger.detail(' - verbose: true')).called(1); - verify(() => logger.detail(' Command: sample')).called(1); - verify(() => logger.detail(' Command options:')).called(1); - verify(() => logger.detail(' - cyan: true')).called(1); - }); - }); - }); -} diff --git a/test/src/commands/sample_command_test.dart b/test/src/commands/sample_command_test.dart deleted file mode 100644 index 5a976ff..0000000 --- a/test/src/commands/sample_command_test.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:langsync/src/command_runner.dart'; -import 'package:mason_logger/mason_logger.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:test/test.dart'; - -class _MockLogger extends Mock implements Logger {} - -void main() { - group('sample', () { - late Logger logger; - late LangsyncCommandRunner commandRunner; - - setUp(() { - logger = _MockLogger(); - commandRunner = LangsyncCommandRunner(logger: logger); - }); - - test('tells a joke', () async { - final exitCode = await commandRunner.run(['sample']); - - expect(exitCode, ExitCode.success.code); - - verify( - () => logger.info('Which unicorn has a cold? The Achoo-nicorn!'), - ).called(1); - }); - test('tells a joke in cyan', () async { - final exitCode = await commandRunner.run(['sample', '-c']); - - expect(exitCode, ExitCode.success.code); - - verify( - () => logger.info( - lightCyan.wrap('Which unicorn has a cold? The Achoo-nicorn!'), - ), - ).called(1); - }); - - test('wrong usage', () async { - final exitCode = await commandRunner.run(['sample', '-p']); - - expect(exitCode, ExitCode.usage.code); - - verify(() => logger.err('Could not find an option or flag "-p".')) - .called(1); - verify( - () => logger.info( - ''' -Usage: $executableName sample [arguments] --h, --help Print this usage information. --c, --cyan Prints the same joke, but in cyan - -Run "$executableName help" to see global options.''', - ), - ).called(1); - }); - }); -} diff --git a/test/src/commands/update_command_test.dart b/test/src/commands/update_command_test.dart deleted file mode 100644 index 6aeae13..0000000 --- a/test/src/commands/update_command_test.dart +++ /dev/null @@ -1,193 +0,0 @@ -import 'dart:io'; - -import 'package:langsync/src/command_runner.dart'; -import 'package:langsync/src/commands/commands.dart'; -import 'package:langsync/src/etc/extensions.dart'; -import 'package:langsync/src/version.dart'; -import 'package:mason_logger/mason_logger.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:pub_updater/pub_updater.dart'; -import 'package:test/test.dart'; - -class _MockLogger extends Mock implements Logger {} - -class _MockProcessResult extends Mock implements ProcessResult {} - -class _MockProgress extends Mock implements Progress {} - -class _MockPubUpdater extends Mock implements PubUpdater {} - -void main() { - const latestVersion = '0.0.0'; - - group('update', () { - late PubUpdater pubUpdater; - - late Logger logger; - - late ProcessResult processResult; - - late LangsyncCommandRunner commandRunner; - - setUp(() { - final progress = _MockProgress(); - final progressLogs = []; - pubUpdater = _MockPubUpdater(); - logger = _MockLogger(); - processResult = _MockProcessResult(); - commandRunner = LangsyncCommandRunner( - logger: logger, - pubUpdater: pubUpdater, - ); - - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => packageVersion); - when( - () => pubUpdater.update( - packageName: packageName, - versionConstraint: latestVersion, - ), - ).thenAnswer((_) async => processResult); - when( - () => pubUpdater.isUpToDate( - packageName: any(named: 'packageName'), - currentVersion: any(named: 'currentVersion'), - ), - ).thenAnswer((_) async => true); - when(() => progress.complete(any())).thenAnswer((_) { - final message = _.positionalArguments.elementAt(0) as String?; - if (message != null) progressLogs.add(message); - }); - when(() => logger.customProgress(any())).thenReturn(progress); - when(() => processResult.exitCode).thenReturn(ExitCode.success.code); - }); - - test('can be instantiated without a pub updater', () { - final command = UpdateCommand(logger: logger); - expect(command, isNotNull); - }); - - test( - 'handles pub latest version query errors', - () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenThrow(Exception('oops')); - final result = await commandRunner.run(['update']); - expect(result, equals(ExitCode.software.code)); - verify(() => logger.customProgress('Checking for updates')).called(1); - verify(() => logger.err('Exception: oops')); - verifyNever( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ); - }, - ); - - test( - 'handles pub update errors', - () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - when( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ).thenThrow(Exception('oops')); - final result = await commandRunner.run(['update']); - expect(result, equals(ExitCode.software.code)); - verify(() => logger.customProgress('Checking for updates')).called(1); - verify(() => logger.err('Exception: oops')); - verify( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ).called(1); - }, - ); - - test('handles pub update process errors', () async { - const error = 'Oh no! Installing this is not possible right now!'; - - when(() => processResult.exitCode).thenReturn(1); - when(() => processResult.stderr).thenReturn(error); - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - - when( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ).thenAnswer((_) async => processResult); - - final result = await commandRunner.run(['update']); - - expect(result, equals(ExitCode.software.code)); - verify(() => logger.customProgress('Checking for updates')).called(1); - verify(() => logger.err('Error updating CLI: $error')); - verify( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ).called(1); - }); - - test( - 'updates when newer version exists', - () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => latestVersion); - when( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ).thenAnswer((_) async => processResult); - when(() => logger.customProgress(any())).thenReturn(_MockProgress()); - final result = await commandRunner.run(['update']); - expect(result, equals(ExitCode.success.code)); - verify(() => logger.customProgress('Checking for updates')).called(1); - verify(() => logger.customProgress('Updating to $latestVersion')) - .called(1); - verify( - () => pubUpdater.update( - packageName: packageName, - versionConstraint: latestVersion, - ), - ).called(1); - }, - ); - - test( - 'does not update when already on latest version', - () async { - when( - () => pubUpdater.getLatestVersion(any()), - ).thenAnswer((_) async => packageVersion); - when(() => logger.customProgress(any())).thenReturn(_MockProgress()); - final result = await commandRunner.run(['update']); - expect(result, equals(ExitCode.success.code)); - verify( - () => logger.info('CLI is already at the latest version.'), - ).called(1); - verifyNever(() => logger.customProgress('Updating to $latestVersion')); - verifyNever( - () => pubUpdater.update( - packageName: any(named: 'packageName'), - versionConstraint: any(named: 'versionConstraint'), - ), - ); - }, - ); - }); -}