Skip to content

Commit

Permalink
feat: add input prompt component (#14)
Browse files Browse the repository at this point in the history
* test: add tests and helper for new features

* feat: add input prompt component

* test: remove redundant test case but introduce casing in existing test
  • Loading branch information
hampuslavin authored Jan 17, 2025
1 parent b6377fa commit 297d4fd
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/src/prompts/input.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'dart:io';

import 'package:cli_tools/cli_tools.dart';

/// Prompts the user for input.
/// If [defaultValue] is provided, the user can skip the prompt by pressing Enter.
Future<String> input(
String message, {
String? defaultValue,
required Logger logger,
}) async {
var defaultDescription = defaultValue == null ? '' : ' ($defaultValue)';

logger.write(
'$message$defaultDescription: ',
LogLevel.info,
newLine: false,
newParagraph: false,
);
var input = stdin.readLineSync()?.trim();
var missingInput = input == null || input.isEmpty;
if (missingInput) {
return defaultValue ?? '';
}

return input;
}
129 changes: 129 additions & 0 deletions test/prompts/input_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import 'package:cli_tools/cli_tools.dart';
import 'package:cli_tools/src/prompts/input.dart';
import 'package:test/test.dart';

import '../test_utils/io_helper.dart';

void main() {
var logger = StdOutLogger(LogLevel.debug);

test(
'Given input prompt '
'when providing valid input "HelloWorld" '
'then should return the input', () async {
late Future<String> result;
await collectOutput(
stdinLines: ['HelloWorld'],
() {
result = input(
'Enter something',
logger: logger,
);
},
);

await expectLater(
result,
completion('HelloWorld'),
);
});

test(
'Given input prompt '
'when providing empty input with default value "default" '
'then should return "default"', () async {
late Future<String> result;
await collectOutput(
stdinLines: [''],
() async {
result = input(
'Enter something',
defaultValue: 'default',
logger: logger,
);
},
);

await expectLater(
result,
completion('default'),
);
});

test(
'Given input prompt '
'when providing empty input without default value '
'then should return an empty string', () async {
late Future<String> result;
await collectOutput(
stdinLines: [''],
() async {
result = input(
'Enter something',
logger: logger,
);
},
);

await expectLater(
result,
completion(''),
);
});

test(
'Given input prompt '
'when providing input with leading and trailing spaces '
'then should trim string', () async {
late Future<String> result;
await collectOutput(
stdinLines: [' hello '],
() async {
result = input(
'Enter something',
logger: logger,
);
},
);

await expectLater(
result,
completion('hello'),
);
});

test(
'Given input prompt '
'when providing defult value '
'then should display prompt with default value', () async {
var (:stdout, :stderr, :stdin) = await collectOutput(
stdinLines: [''],
() async {
await input(
'Enter something',
defaultValue: 'default',
logger: logger,
);
},
);

expect(stdout.output, 'Enter something (default): ');
});

test(
'Given input prompt '
'when providing no default value '
'then should not display a default description', () async {
var (:stdout, :stderr, :stdin) = await collectOutput(
stdinLines: ['value'],
() async {
await input(
'Enter something',
logger: logger,
);
},
);

expect(stdout.output, 'Enter something: ');
});
}

0 comments on commit 297d4fd

Please sign in to comment.