Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [2.1.0] - Update dependencies

* Update min SDK to 3.7.0
* Update build_runner and dependencies (by @lsaudon)
* Remove Extra Curly Braces from Data Table Variables in Scenario Outlines (by @tide-khushal)

## [2.0.1] - Custom headers support

* Add `customHeaders` configuration option to include custom header lines (imports, comments, etc.) in all generated step files and feature files
Expand Down
3 changes: 3 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ linter:
constant_identifier_names: false
lines_longer_than_80_chars: false
public_member_api_docs: false

formatter:
trailing_commas: preserve
25 changes: 13 additions & 12 deletions lib/bdd_widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import 'package:yaml/yaml.dart';
///
/// Returns a [FeatureBuilder] instance configured with the specified options.
Builder featureBuilder(BuilderOptions options) => FeatureBuilder(
GeneratorOptions.fromMap(options.config),
);
GeneratorOptions.fromMap(options.config),
);

/// A code generator builder that transforms BDD feature files into Dart test files.
///
Expand Down Expand Up @@ -139,7 +139,7 @@ class FeatureBuilder implements Builder {
final featureDir = p.dirname(inputId.path);
final isIntegrationTest =
inputId.pathSegments.contains('integration_test') &&
_hasIntegrationTestDevDependency();
_hasIntegrationTestDevDependency();

final feature = FeatureFile(
featureDir: featureDir,
Expand All @@ -159,9 +159,8 @@ class FeatureBuilder implements Builder {
);

final steps = feature.getStepFiles().whereType<NewStepFile>().map(
(e) =>
_createFileRecursively(e.filename, formatDartCode(e.dartContent)),
);
(e) => _createFileRecursively(e.filename, formatDartCode(e.dartContent)),
);
await Future.wait(steps);

final hookFile = feature.hookFile;
Expand All @@ -171,12 +170,14 @@ class FeatureBuilder implements Builder {
}

Future<GeneratorOptions> _prepareOptions() async {
final fileOptions = fs.file('bdd_options.yaml').existsSync()
? readFromUri(Uri.file('bdd_options.yaml'))
: null;
final mergedOptions = fileOptions != null
? merge(generatorOptions, fileOptions)
: generatorOptions;
final fileOptions =
fs.file('bdd_options.yaml').existsSync()
? readFromUri(Uri.file('bdd_options.yaml'))
: null;
final mergedOptions =
fileOptions != null
? merge(generatorOptions, fileOptions)
: generatorOptions;
final options = await flattenOptions(mergedOptions);
return options;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/src/bdd_line.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class BddLine {
BddLine(this.rawLine)
: type = _lineTypeFromString(rawLine),
value = _removeLinePrefix(rawLine);
: type = _lineTypeFromString(rawLine),
value = _removeLinePrefix(rawLine);

BddLine.fromValue(this.type, this.value) : rawLine = '';
BddLine.fromRawValue(this.type, this.rawLine)
: value = _removeLinePrefix(rawLine);
: value = _removeLinePrefix(rawLine);

final String rawLine;
final String value;
Expand Down
20 changes: 11 additions & 9 deletions lib/src/data_table_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import 'package:bdd_widget_test/src/scenario_generator.dart';

bool hasBddDataTable(List<BddLine> lines) {
for (var index = 0; index < lines.length; index++) {
final isStep = lines[index].type == LineType.step ||
final isStep =
lines[index].type == LineType.step ||
lines[index].type == LineType.dataTableStep;
final isNextLineTable = isTable(lines: lines, index: index + 1);
final isExamplesFormatted = hasExamplesFormat(bddLine: lines[index]);
Expand All @@ -17,13 +18,15 @@ bool hasBddDataTable(List<BddLine> lines) {

Iterable<BddLine> replaceDataTables(List<BddLine> lines) sync* {
for (var index = 0; index < lines.length; index++) {
final isStep = lines[index].type == LineType.step ||
final isStep =
lines[index].type == LineType.step ||
lines[index].type == LineType.dataTableStep;
final isNextLineTable = isTable(lines: lines, index: index + 1);
if (isStep && isNextLineTable) {
final table = !hasExamplesFormat(bddLine: lines[index])
? _createCucumberDataTable(lines: lines, index: index)
: _createDataTableFromExamples(lines: lines, index: index);
final table =
!hasExamplesFormat(bddLine: lines[index])
? _createCucumberDataTable(lines: lines, index: index)
: _createDataTableFromExamples(lines: lines, index: index);
yield* table;
// skip the parsed table
while (isTable(lines: lines, index: index + 1)) {
Expand All @@ -38,8 +41,7 @@ Iterable<BddLine> replaceDataTables(List<BddLine> lines) sync* {
bool isTable({
required List<BddLine> lines,
required int index,
}) =>
index < lines.length && lines[index].type == LineType.examples;
}) => index < lines.length && lines[index].type == LineType.examples;

bool hasExamplesFormat({required BddLine bddLine}) =>
examplesRegExp.firstMatch(bddLine.rawLine) != null;
Expand Down Expand Up @@ -75,8 +77,8 @@ Iterable<BddLine> _createDataTableFromExamples({
final dataTable = [lines[index]];
do {
dataTable.add(lines[++index]);
} while (
index + 1 < lines.length && lines[index + 1].type == LineType.examples);
} while (index + 1 < lines.length &&
lines[index + 1].type == LineType.examples);
final data = generateScenariosFromScenarioOutline([
// pretend to be an Example section to re-use some logic
BddLine.fromValue(LineType.exampleTitle, ''),
Expand Down
5 changes: 4 additions & 1 deletion lib/src/existing_steps.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ Map<String, String> getExistingStepSubfolders(
if (!steps.existsSync()) {
return {};
}
return steps.listSync(recursive: true).asMap().map(
return steps
.listSync(recursive: true)
.asMap()
.map(
(_, step) => MapEntry<String, String>(
p.basename(step.path),
p.dirname(
Expand Down
136 changes: 72 additions & 64 deletions lib/src/feature_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ class FeatureFile {
this.includeIntegrationTestBinding = false,
this.existingSteps = const <String, String>{},
this.generatorOptions = const GeneratorOptions(),
}) : _lines = _prepareLines(
input.split('\n').map((line) => line.trim()).map(BddLine.new),
),
hookFile = generatorOptions.addHooks
? HookFile.create(
featureDir: featureDir,
package: package,
generatorOptions: generatorOptions,
)
: null {
}) : _lines = _prepareLines(
input.split('\n').map((line) => line.trim()).map(BddLine.new),
),
hookFile =
generatorOptions.addHooks
? HookFile.create(
featureDir: featureDir,
package: package,
generatorOptions: generatorOptions,
)
: null {
_testerType = parseCustomTagFromFeatureTagLine(
_lines,
generatorOptions.testerType,
Expand All @@ -40,23 +41,25 @@ class FeatureFile {
testerNameTag,
);

_stepFiles = _lines
.where(
(line) =>
line.type == LineType.step || line.type == LineType.dataTableStep,
)
.map(
(bddLine) => StepFile.create(
featureDir,
package,
bddLine,
existingSteps,
generatorOptions,
_testerType,
_testerName,
),
)
.toList();
_stepFiles =
_lines
.where(
(line) =>
line.type == LineType.step ||
line.type == LineType.dataTableStep,
)
.map(
(bddLine) => StepFile.create(
featureDir,
package,
bddLine,
existingSteps,
generatorOptions,
_testerType,
_testerName,
),
)
.toList();
}

late List<StepFile> _stepFiles;
Expand All @@ -75,52 +78,57 @@ class FeatureFile {
final HookFile? hookFile;

String get dartContent => generateFeatureDart(
_lines,
getStepFiles(),
generatorOptions.testMethodName,
_testerType,
_testerName,
includeIntegrationTestBinding,
includeIntegrationTestImport,
hookFile,
generatorOptions,
);
_lines,
getStepFiles(),
generatorOptions.testMethodName,
_testerType,
_testerName,
includeIntegrationTestBinding,
includeIntegrationTestImport,
hookFile,
generatorOptions,
);

List<StepFile> getStepFiles() => _stepFiles;

static List<BddLine> _prepareLines(Iterable<BddLine> input) {
final lines = input.mapIndexed(
(index, bddLine) {
final isStep = bddLine.type == LineType.step;
final hasExamplesFormat = data_table_parser.hasExamplesFormat(
bddLine: bddLine,
);
final isNextTable = data_table_parser.isTable(
lines: input.toList(),
index: index + 1,
);
if (isStep && !hasExamplesFormat && isNextTable) {
return BddLine.fromRawValue(LineType.dataTableStep, bddLine.rawLine);
} else {
return bddLine;
}
},
).toList(growable: false);
final lines = input
.mapIndexed(
(index, bddLine) {
final isStep = bddLine.type == LineType.step;
final hasExamplesFormat = data_table_parser.hasExamplesFormat(
bddLine: bddLine,
);
final isNextTable = data_table_parser.isTable(
lines: input.toList(),
index: index + 1,
);
if (isStep && !hasExamplesFormat && isNextTable) {
return BddLine.fromRawValue(
LineType.dataTableStep,
bddLine.rawLine,
);
} else {
return bddLine;
}
},
)
.toList(growable: false);

final headers = lines
.takeWhile((value) => value.type != LineType.feature)
.where((value) => value.type == LineType.unknown)
.foldIndexed(
// this removes empty line dupicates
<BddLine>[],
(index, headers, line) => [
...headers,
if (index == 0 && line.rawLine != '\n' && line.rawLine.isNotEmpty)
line
else if (headers.isNotEmpty && headers.last.rawLine != line.rawLine)
line,
],
);
// this removes empty line dupicates
<BddLine>[],
(index, headers, line) => [
...headers,
if (index == 0 && line.rawLine != '\n' && line.rawLine.isNotEmpty)
line
else if (headers.isNotEmpty && headers.last.rawLine != line.rawLine)
line,
],
);
final steps = lines.where((value) => value.type != LineType.unknown);
return [...headers, ...steps];
}
Expand Down
Loading