Started on the dart_gherkin 3.0 conversion
This commit is contained in:
parent
c6b64cae2e
commit
5c15f0c2c0
|
@ -8,7 +8,18 @@ import 'package:glob/glob.dart';
|
|||
import 'package:glob/list_local_fs.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
class NoOpReporter extends Reporter {}
|
||||
class NoOpReporter extends MessageReporter {
|
||||
@override
|
||||
Future<void> message(String message, MessageLevel level) async {
|
||||
if(level == MessageLevel.info || level == MessageLevel.debug) {
|
||||
print(message);
|
||||
}else if(level == MessageLevel.warning) {
|
||||
print('\x1B[33m$message\x1B[0m');
|
||||
}else if(level == MessageLevel.error) {
|
||||
print('\x1B[31m$message\x1B[0m');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GherkinSuiteTestGenerator
|
||||
extends GeneratorForAnnotation<GherkinTestSuite> {
|
||||
|
@ -52,16 +63,12 @@ void executeTestSuite(
|
|||
.getField('index')!
|
||||
.toIntValue()!;
|
||||
final executionOrder = ExecutionOrder.values[idx];
|
||||
final featureFiles = annotation
|
||||
final featureFiles = annotation
|
||||
.read('featurePaths')
|
||||
.listValue
|
||||
.map((path) => Glob(path.toStringValue()!))
|
||||
.map(
|
||||
(glob) => glob
|
||||
.listSync()
|
||||
.map((entity) => File(entity.path).readAsStringSync())
|
||||
.toList(),
|
||||
)
|
||||
.map((glob) =>
|
||||
glob.listSync().map((entity) => File(entity.path)).toList())
|
||||
.reduce((value, element) => value..addAll(element));
|
||||
|
||||
if (executionOrder == ExecutionOrder.random) {
|
||||
|
@ -73,11 +80,11 @@ void executeTestSuite(
|
|||
final featuresToExecute = new StringBuffer();
|
||||
var id = 0;
|
||||
|
||||
for (var featureFileContent in featureFiles) {
|
||||
for (var featureFile in featureFiles) {
|
||||
final code = await generator.generate(
|
||||
id++,
|
||||
featureFileContent,
|
||||
'',
|
||||
featureFile.readAsStringSync(),
|
||||
featureFile.absolute.path,
|
||||
_languageService,
|
||||
_reporter,
|
||||
);
|
||||
|
@ -104,7 +111,7 @@ class FeatureFileTestGenerator {
|
|||
String featureFileContents,
|
||||
String path,
|
||||
LanguageService languageService,
|
||||
Reporter reporter,
|
||||
MessageReporter reporter,
|
||||
) async {
|
||||
final visitor = FeatureFileTestGeneratorVisitor();
|
||||
|
||||
|
@ -148,14 +155,14 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
{{step_multi_line_strings}},
|
||||
{{step_table}},
|
||||
dependencies,
|
||||
hasToSkip
|
||||
hasToSkip,
|
||||
);}
|
||||
''';
|
||||
static const String ON_BEFORE_SCENARIO_RUN = '''
|
||||
onBefore: () async => onBeforeRunFeature('{{feature_name}}', {{feature_tags}},),
|
||||
''';
|
||||
static const String ON_AFTER_SCENARIO_RUN = '''
|
||||
onAfter: () async => onAfterRunFeature('{{feature_name}}',),
|
||||
onAfter: () async => onAfterRunFeature('{{feature_name}}', '{{path}}'),
|
||||
''';
|
||||
|
||||
final StringBuffer _buffer = StringBuffer();
|
||||
|
@ -171,7 +178,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
String featureFileContents,
|
||||
String path,
|
||||
LanguageService languageService,
|
||||
Reporter reporter,
|
||||
MessageReporter reporter,
|
||||
) async {
|
||||
_id = id;
|
||||
await visit(
|
||||
|
@ -214,14 +221,9 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> visitScenario(
|
||||
String featureName,
|
||||
Iterable<String> featureTags,
|
||||
String name,
|
||||
Iterable<String> tags,
|
||||
bool isFirst,
|
||||
bool isLast,
|
||||
) async {
|
||||
Future<void> visitScenario(String featureName, Iterable<String> featureTags,
|
||||
String name, Iterable<String> tags, String path,
|
||||
{required bool isFirst, required bool isLast}) async {
|
||||
_flushScenario();
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
SCENARIO_TEMPLATE,
|
||||
|
@ -238,6 +240,11 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor {
|
|||
'feature_name',
|
||||
_escapeText(featureName),
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'path',
|
||||
_escapeText(path),
|
||||
);
|
||||
_currentScenarioCode = _replaceVariable(
|
||||
_currentScenarioCode!,
|
||||
'feature_tags',
|
||||
|
|
|
@ -24,32 +24,6 @@ import 'package:flutter_test/flutter_test.dart';
|
|||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
class FlutterTestConfiguration extends TestConfiguration {
|
||||
|
||||
/// ~~The path(s) to all the features.~~
|
||||
/// ~~All three [Pattern]s are supported: [RegExp], [String], [Glob].~~
|
||||
///
|
||||
/// Instead of using this variable, give the features in the `@GherkinTestSuite(features: <String>[])` option.
|
||||
@deprecated
|
||||
Iterable<Pattern> features = const <Pattern>[];
|
||||
|
||||
/// ~~The execution order of features - this default to random to avoid any inter-test dependencies~~
|
||||
///
|
||||
/// Instead of using this variable, give the executionOrder in the `@GherkinTestSuite(executionOrder: ExecutionOrder.random)` option.
|
||||
@deprecated
|
||||
ExecutionOrder order = ExecutionOrder.random;
|
||||
|
||||
/// ~~Lists feature files paths, which match [features] patterns.~~
|
||||
///
|
||||
/// Instead of using this variable, give the features in the `@GherkinTestSuite(features: <String>[])` option.
|
||||
@deprecated
|
||||
FeatureFileMatcher featureFileMatcher = const IoFeatureFileAccessor();
|
||||
|
||||
/// ~~The feature file reader.~~
|
||||
/// ~~Takes files/resources paths from [featureFileIndexer] and returns their content as String.~~
|
||||
///
|
||||
/// Instead of using this variable, give the features in the `@GherkinTestSuite(features: <String>[])` option.
|
||||
@deprecated
|
||||
FeatureFileReader featureFileReader = const IoFeatureFileAccessor();
|
||||
|
||||
/// Enable semantics in a test by creating a [SemanticsHandle].
|
||||
/// See: [testWidgets] and [WidgetController.ensureSemantics].
|
||||
|
@ -63,7 +37,6 @@ class FlutterTestConfiguration extends TestConfiguration {
|
|||
String targetAppPath = 'test_driver/integration_test_driver.dart',
|
||||
}) {
|
||||
return FlutterTestConfiguration()
|
||||
..features = [RegExp(featurePath)]
|
||||
..reporters = [
|
||||
StdoutReporter(MessageLevel.error),
|
||||
ProgressReporter(),
|
||||
|
|
|
@ -39,7 +39,7 @@ class FlutterAppRunnerHook extends Hook {
|
|||
TestConfiguration config,
|
||||
String scenario,
|
||||
Iterable<Tag> tags,
|
||||
bool failed,
|
||||
{bool? passed,}
|
||||
) async {
|
||||
final flutterConfig = _castConfig(config);
|
||||
haveRunFirstScenario = true;
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/adapters/widget_tester_app_driver_adapter.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/world/flutter_world.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
@ -24,14 +20,14 @@ abstract class GherkinIntegrationTestRunner {
|
|||
TagExpressionEvaluator();
|
||||
final TestConfiguration configuration;
|
||||
final Future<void> Function(World world) appMainFunction;
|
||||
Reporter? _reporter;
|
||||
AggregatedReporter _reporter = new AggregatedReporter();
|
||||
Hook? _hook;
|
||||
Iterable<ExecutableStep>? _executableSteps;
|
||||
Iterable<CustomParameter>? _customParameters;
|
||||
|
||||
IntegrationTestWidgetsFlutterBinding? _binding;
|
||||
|
||||
Reporter get reporter => _reporter!;
|
||||
AggregatedReporter get reporter => _reporter;
|
||||
Hook get hook => _hook!;
|
||||
LiveTestWidgetsFlutterBindingFramePolicy? get framePolicy => null;
|
||||
|
||||
|
@ -42,7 +38,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
this.appMainFunction,
|
||||
) {
|
||||
configuration.prepare();
|
||||
_reporter = _registerReporters(configuration.reporters);
|
||||
_registerReporters(configuration.reporters);
|
||||
_hook = _registerHooks(configuration.hooks);
|
||||
_customParameters =
|
||||
_registerCustomParameters(configuration.customStepParameterDefinitions);
|
||||
|
@ -66,7 +62,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
);
|
||||
|
||||
_safeInvokeFuture(() async => await hook.onBeforeRun(configuration));
|
||||
_safeInvokeFuture(() async => await reporter.onTestRunStarted());
|
||||
_safeInvokeFuture(() async => await reporter.test.onStarted.maybeCall());
|
||||
|
||||
onRun();
|
||||
}
|
||||
|
@ -74,7 +70,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
void onRun();
|
||||
|
||||
void onRunComplete() {
|
||||
_safeInvokeFuture(() async => await reporter.onTestRunFinished());
|
||||
_safeInvokeFuture(() async => await reporter.test.onFinished.maybeCall());
|
||||
_safeInvokeFuture(() async => await hook.onAfterRun(configuration));
|
||||
setTestResultData(_binding!);
|
||||
_safeInvokeFuture(() async => await reporter.dispose());
|
||||
|
@ -82,7 +78,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
|
||||
void setTestResultData(IntegrationTestWidgetsFlutterBinding binding) {
|
||||
if (reporter is SerializableReporter) {
|
||||
final json = (reporter as SerializableReporter).toJson();
|
||||
final json = (reporter as SerializableReporter).serialize();
|
||||
binding.reportData = {'gherkin_reports': json};
|
||||
}
|
||||
}
|
||||
|
@ -109,12 +105,11 @@ abstract class GherkinIntegrationTestRunner {
|
|||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
final featureTags =
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t.toString(), 0));
|
||||
await reporter.onFeatureStarted(
|
||||
StartedMessage(
|
||||
Target.feature,
|
||||
name,
|
||||
debugInformation,
|
||||
featureTags,
|
||||
await reporter.feature.onStarted.maybeCall(
|
||||
FeatureMessage(
|
||||
name: name,
|
||||
context: debugInformation,
|
||||
tags: featureTags.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -122,13 +117,14 @@ abstract class GherkinIntegrationTestRunner {
|
|||
@protected
|
||||
Future<void> onAfterRunFeature(
|
||||
String name,
|
||||
String path
|
||||
) async {
|
||||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
await reporter.onFeatureFinished(
|
||||
FinishedMessage(
|
||||
Target.feature,
|
||||
name,
|
||||
debugInformation,
|
||||
final debugInformation = RunnableDebugInformation(path, 0, name);
|
||||
await reporter.test.onFinished.maybeCall(
|
||||
TestMessage(
|
||||
target: Target.feature,
|
||||
name: name,
|
||||
context: debugInformation,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -138,7 +134,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
String name,
|
||||
Iterable<String>? tags,
|
||||
List<Future<StepResult> Function(TestDependencies dependencies, bool skip,)>
|
||||
steps, {
|
||||
steps, String path, {
|
||||
Future<void> Function()? onBefore,
|
||||
Future<void> Function()? onAfter,
|
||||
}) {
|
||||
|
@ -151,7 +147,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
}
|
||||
var failed = false;
|
||||
|
||||
final debugInformation = RunnableDebugInformation('', 0, name);
|
||||
final debugInformation = RunnableDebugInformation(path, 0, name);
|
||||
final scenarioTags =
|
||||
(tags ?? Iterable<Tag>.empty()).map((t) => Tag(t.toString(), 0));
|
||||
final dependencies = await createTestDependencies(
|
||||
|
@ -177,12 +173,11 @@ abstract class GherkinIntegrationTestRunner {
|
|||
scenarioTags,
|
||||
);
|
||||
|
||||
await reporter.onScenarioStarted(
|
||||
StartedMessage(
|
||||
Target.scenario,
|
||||
name,
|
||||
debugInformation,
|
||||
scenarioTags,
|
||||
await reporter.scenario.onStarted.maybeCall(
|
||||
ScenarioMessage(
|
||||
name: name,
|
||||
context: debugInformation,
|
||||
tags: scenarioTags.toList(),
|
||||
),
|
||||
);
|
||||
var hasToSkip = false;
|
||||
|
@ -200,11 +195,11 @@ abstract class GherkinIntegrationTestRunner {
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
await reporter.onScenarioFinished(
|
||||
ScenarioFinishedMessage(
|
||||
name,
|
||||
debugInformation,
|
||||
!failed,
|
||||
await reporter.scenario.onFinished.maybeCall(
|
||||
ScenarioMessage(
|
||||
name: name,
|
||||
context: debugInformation,
|
||||
hasPassed: !failed,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -212,7 +207,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
configuration,
|
||||
name,
|
||||
scenarioTags,
|
||||
!failed,
|
||||
passed: !failed,
|
||||
);
|
||||
|
||||
if (onAfter != null) {
|
||||
|
@ -300,7 +295,7 @@ abstract class GherkinIntegrationTestRunner {
|
|||
|
||||
if (hasToSkip) {
|
||||
result = new StepResult(
|
||||
0, StepExecutionResult.skipped, "Previous step(s) failed.");
|
||||
0, StepExecutionResult.skipped, resultReason: "Previous step(s) failed.");
|
||||
} else {
|
||||
for (int i = 0; i < this.configuration.stepMaxRetries + 1; i++) {
|
||||
result = await executable.step.run(
|
||||
|
@ -345,13 +340,10 @@ abstract class GherkinIntegrationTestRunner {
|
|||
);
|
||||
}
|
||||
|
||||
Reporter _registerReporters(Iterable<Reporter>? reporters) {
|
||||
final reporter = AggregatedReporter();
|
||||
void _registerReporters(Iterable<Reporter>? reporters) {
|
||||
if (reporters != null) {
|
||||
reporters.forEach((r) => reporter.addReporter(r));
|
||||
reporters.forEach((r) => _reporter.addReporter(r));
|
||||
}
|
||||
|
||||
return reporter;
|
||||
}
|
||||
|
||||
Hook _registerHooks(Iterable<Hook>? hooks) {
|
||||
|
@ -429,12 +421,12 @@ abstract class GherkinIntegrationTestRunner {
|
|||
result,
|
||||
);
|
||||
|
||||
await reporter.onStepFinished(
|
||||
StepFinishedMessage(
|
||||
step,
|
||||
RunnableDebugInformation('', 0, step),
|
||||
result,
|
||||
dependencies.attachmentManager.getAttachmentsForContext(step),
|
||||
await reporter.step.onStarted.maybeCall(
|
||||
StepMessage(
|
||||
name: step,
|
||||
context: RunnableDebugInformation('', 0, step),
|
||||
result: result,
|
||||
attachments: dependencies.attachmentManager.getAttachmentsForContext(step).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -446,10 +438,10 @@ abstract class GherkinIntegrationTestRunner {
|
|||
Iterable<String> multiLineStrings,
|
||||
) async {
|
||||
await hook.onBeforeStep(world, step);
|
||||
await reporter.onStepStarted(
|
||||
StepStartedMessage(
|
||||
step,
|
||||
RunnableDebugInformation('', 0, step),
|
||||
await reporter.step.onStarted.maybeCall(
|
||||
StepMessage(
|
||||
name: step,
|
||||
context: RunnableDebugInformation('', 0, step),
|
||||
table: table,
|
||||
multilineString:
|
||||
multiLineStrings.isNotEmpty ? multiLineStrings.first : null,
|
||||
|
|
|
@ -22,7 +22,7 @@ StepDefinitionGeneric ThenExpectElementToHaveValue() {
|
|||
|
||||
context.expect(text, value);
|
||||
} catch (e) {
|
||||
await context.reporter.message('Step error: $e', MessageLevel.error);
|
||||
// await context.reporter('Step error: $e', MessageLevel.error);
|
||||
rethrow;
|
||||
}
|
||||
},
|
||||
|
|
44
pubspec.lock
44
pubspec.lock
|
@ -21,7 +21,7 @@ packages:
|
|||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.11"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -35,7 +35,7 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.1"
|
||||
version: "2.8.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -63,7 +63,7 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -98,7 +98,7 @@ packages:
|
|||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -126,7 +126,7 @@ packages:
|
|||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -160,7 +160,7 @@ packages:
|
|||
name: gherkin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
version: "3.0.0"
|
||||
glob:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -193,7 +193,14 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.11"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.4"
|
||||
meta:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -214,7 +221,7 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.1"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -228,14 +235,14 @@ packages:
|
|||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.1.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
version: "4.2.4"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -268,7 +275,7 @@ packages:
|
|||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
version: "1.8.2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -310,7 +317,7 @@ packages:
|
|||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
version: "0.4.9"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -318,20 +325,27 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.1"
|
||||
version: "8.2.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -354,5 +368,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
dart: ">=2.17.0-0 <3.0.0"
|
||||
flutter: ">=2.2.0"
|
||||
|
|
|
@ -18,7 +18,7 @@ dependencies:
|
|||
sdk: flutter
|
||||
analyzer: ">=1.7.1 <3.0.0"
|
||||
collection: ^1.15.0
|
||||
gherkin: ^2.0.8
|
||||
gherkin: ^3.0.0
|
||||
source_gen: ^1.1.1
|
||||
build: ^2.1.1
|
||||
glob: ^2.0.2
|
||||
|
|
Loading…
Reference in New Issue