[app_dart] Push GitHub webhooks to PubSub (#2068)
diff --git a/app_dart/README.md b/app_dart/README.md
index 38e13eb..5339528 100644
--- a/app_dart/README.md
+++ b/app_dart/README.md
@@ -35,7 +35,7 @@
To update the JSON serialization generated code, run:
```sh
-$ dart pub run build_runner build
+$ dart run build_runner build
```
Any updates should be checked into source control.
@@ -48,8 +48,8 @@
the protocol buffer compiler (`protoc`). Once installed, update your `PATH`
to include the path to the `protoc` binary.
- On Linux, you may be able to use `sudo apt-get install protocol-compiler` to install.
- On macOS, you may be able to use `brew install protobuf`
+ On Linux, use `sudo apt-get install protocol-compiler` to install.
+ On macOS, use `brew install protobuf`
2. Install the [`protoc_plugin`](https://pub.dev/packages/protoc_plugin) Dart
package. Once installed, update your `PATH` to include the path to the
@@ -59,10 +59,7 @@
3. Run the following command:
```sh
- $ protoc \
- --plugin=/path/to/protoc_plugin/bin/ \
- --dart_out=. \
- lib/src/path/to/file.proto
+ $ protoc --dart_out=. lib/src/model/proto/**/*.proto
```
4. Remove the unused generated files:
diff --git a/app_dart/bin/server.dart b/app_dart/bin/server.dart
index 6a741ee..e3e8b05 100644
--- a/app_dart/bin/server.dart
+++ b/app_dart/bin/server.dart
@@ -71,6 +71,11 @@
),
'/api/github-webhook-pullrequest': GithubWebhook(
config: config,
+ pubsub: const PubSub(),
+ ),
+ '/api/github/webhook-subscription': GithubWebhookSubscription(
+ config: config,
+ cache: cache,
branchService: branchService,
githubChecksService: githubChecksService,
scheduler: scheduler,
diff --git a/app_dart/lib/cocoon_service.dart b/app_dart/lib/cocoon_service.dart
index 0b28dc0..a3c0fa7 100644
--- a/app_dart/lib/cocoon_service.dart
+++ b/app_dart/lib/cocoon_service.dart
@@ -16,6 +16,7 @@
export 'src/request_handlers/get_green_commits.dart';
export 'src/request_handlers/github_rate_limit_status.dart';
export 'src/request_handlers/github_webhook.dart';
+export 'src/request_handlers/github/webhook_subscription.dart';
export 'src/request_handlers/postsubmit_luci_subscription.dart';
export 'src/request_handlers/presubmit_luci_subscription.dart';
export 'src/request_handlers/push_build_status_to_github.dart';
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart b/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart
new file mode 100644
index 0000000..4f4fd7c
--- /dev/null
+++ b/app_dart/lib/src/model/proto/internal/github_webhook.pb.dart
@@ -0,0 +1,82 @@
+///
+// Generated code. Do not modify.
+// source: lib/src/model/proto/internal/github_webhook.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
+
+import 'dart:core' as $core;
+
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class GithubWebhookMessage extends $pb.GeneratedMessage {
+ static final $pb.BuilderInfo _i = $pb.BuilderInfo(
+ const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GithubWebhookMessage',
+ createEmptyInstance: create)
+ ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'event')
+ ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payload')
+ ..hasRequiredFields = false;
+
+ GithubWebhookMessage._() : super();
+ factory GithubWebhookMessage({
+ $core.String? event,
+ $core.String? payload,
+ }) {
+ final _result = create();
+ if (event != null) {
+ _result.event = event;
+ }
+ if (payload != null) {
+ _result.payload = payload;
+ }
+ return _result;
+ }
+ factory GithubWebhookMessage.fromBuffer($core.List<$core.int> i,
+ [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+ create()..mergeFromBuffer(i, r);
+ factory GithubWebhookMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+ create()..mergeFromJson(i, r);
+ @$core.Deprecated('Using this can add significant overhead to your binary. '
+ 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+ 'Will be removed in next major version')
+ GithubWebhookMessage clone() => GithubWebhookMessage()..mergeFromMessage(this);
+ @$core.Deprecated('Using this can add significant overhead to your binary. '
+ 'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+ 'Will be removed in next major version')
+ GithubWebhookMessage copyWith(void Function(GithubWebhookMessage) updates) =>
+ super.copyWith((message) => updates(message as GithubWebhookMessage))
+ as GithubWebhookMessage; // ignore: deprecated_member_use
+ $pb.BuilderInfo get info_ => _i;
+ @$core.pragma('dart2js:noInline')
+ static GithubWebhookMessage create() => GithubWebhookMessage._();
+ GithubWebhookMessage createEmptyInstance() => create();
+ static $pb.PbList<GithubWebhookMessage> createRepeated() => $pb.PbList<GithubWebhookMessage>();
+ @$core.pragma('dart2js:noInline')
+ static GithubWebhookMessage getDefault() =>
+ _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GithubWebhookMessage>(create);
+ static GithubWebhookMessage? _defaultInstance;
+
+ @$pb.TagNumber(1)
+ $core.String get event => $_getSZ(0);
+ @$pb.TagNumber(1)
+ set event($core.String v) {
+ $_setString(0, v);
+ }
+
+ @$pb.TagNumber(1)
+ $core.bool hasEvent() => $_has(0);
+ @$pb.TagNumber(1)
+ void clearEvent() => clearField(1);
+
+ @$pb.TagNumber(2)
+ $core.String get payload => $_getSZ(1);
+ @$pb.TagNumber(2)
+ set payload($core.String v) {
+ $_setString(1, v);
+ }
+
+ @$pb.TagNumber(2)
+ $core.bool hasPayload() => $_has(1);
+ @$pb.TagNumber(2)
+ void clearPayload() => clearField(2);
+}
diff --git a/app_dart/lib/src/model/proto/internal/github_webhook.proto b/app_dart/lib/src/model/proto/internal/github_webhook.proto
new file mode 100644
index 0000000..ef0f4fc
--- /dev/null
+++ b/app_dart/lib/src/model/proto/internal/github_webhook.proto
@@ -0,0 +1,13 @@
+// Copyright 2019 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.
+
+syntax = "proto2";
+
+// TODO(chillers): Use this for the generated models.
+message GithubWebhookMessage {
+ // TODO(chillers)
+ optional string event = 1;
+ // JSON encoded webhook payload from GitHub.
+ optional string payload = 2;
+}
\ No newline at end of file
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pb.dart b/app_dart/lib/src/model/proto/internal/scheduler.pb.dart
index 6a2a588..a17500b 100644
--- a/app_dart/lib/src/model/proto/internal/scheduler.pb.dart
+++ b/app_dart/lib/src/model/proto/internal/scheduler.pb.dart
@@ -3,7 +3,7 @@
// source: lib/src/model/proto/internal/scheduler.proto
//
// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
import 'dart:core' as $core;
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart
index 648c0ce..6fce85b 100644
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart
+++ b/app_dart/lib/src/model/proto/internal/scheduler.pbenum.dart
@@ -3,7 +3,7 @@
// source: lib/src/model/proto/internal/scheduler.proto
//
// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
// ignore_for_file: UNDEFINED_SHOWN_NAME
import 'dart:core' as $core;
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart
index 6a382b0..b2db732 100644
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart
+++ b/app_dart/lib/src/model/proto/internal/scheduler.pbjson.dart
@@ -3,7 +3,7 @@
// source: lib/src/model/proto/internal/scheduler.proto
//
// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
import 'dart:core' as $core;
import 'dart:convert' as $convert;
diff --git a/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart b/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart
index ddb748e..a16fa83 100644
--- a/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart
+++ b/app_dart/lib/src/model/proto/internal/scheduler.pbserver.dart
@@ -3,6 +3,6 @@
// source: lib/src/model/proto/internal/scheduler.proto
//
// @dart = 2.12
-// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name
export 'scheduler.pb.dart';
diff --git a/app_dart/lib/src/model/proto/protos.dart b/app_dart/lib/src/model/proto/protos.dart
index 338120e..ae7cdee 100644
--- a/app_dart/lib/src/model/proto/protos.dart
+++ b/app_dart/lib/src/model/proto/protos.dart
@@ -3,5 +3,6 @@
// found in the LICENSE file.
export 'internal/build_status_response.pb.dart';
+export 'internal/github_webhook.pb.dart';
export 'internal/key.pb.dart';
export 'internal/scheduler.pb.dart';
diff --git a/app_dart/lib/src/request_handlers/github/webhook_subscription.dart b/app_dart/lib/src/request_handlers/github/webhook_subscription.dart
new file mode 100644
index 0000000..48d9b86
--- /dev/null
+++ b/app_dart/lib/src/request_handlers/github/webhook_subscription.dart
@@ -0,0 +1,650 @@
+// Copyright 2019 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.
+
+import 'dart:convert';
+
+import 'package:github/github.dart';
+import 'package:github/hooks.dart';
+import 'package:meta/meta.dart';
+
+import '../../../protos.dart' as pb;
+import '../../model/github/checks.dart' as cocoon_checks;
+import '../../request_handling/body.dart';
+import '../../request_handling/exceptions.dart';
+import '../../request_handling/subscription_handler.dart';
+import '../../service/branch_service.dart';
+import '../../service/config.dart';
+import '../../service/datastore.dart';
+import '../../service/github_checks_service.dart';
+import '../../service/logging.dart';
+import '../../service/scheduler.dart';
+
+// Filenames which are not actually tests.
+const List<String> kNotActuallyATest = <String>[
+ 'packages/flutter/lib/src/gestures/hit_test.dart',
+];
+
+/// List of repos that require check for labels and tests.
+const Set<String> kNeedsCheckLabelsAndTests = <String>{
+ 'flutter/engine',
+ 'flutter/flutter',
+ 'flutter/packages',
+ 'flutter/plugins',
+};
+
+final RegExp kEngineTestRegExp = RegExp(r'(tests?|benchmarks?)\.(dart|java|mm|m|cc)$');
+final List<String> kNeedsTestsLabels = <String>['needs tests'];
+
+/// Subscription for processing GitHub webhooks.
+///
+/// The PubSub subscription is set up here:
+/// https://cloud.google.com/cloudpubsub/subscription/detail/github-webhooks-sub?project=flutter-dashboard&tab=overview
+///
+/// This endpoint enables Cocoon to recover from outages.
+///
+/// This endpoint takes in a POST request with the GitHub event JSON.
+// TODO(chillers): There's potential now to split this into seprate subscriptions
+// for various activities (such as infra vs releases). This would mitigate
+// breakages across Cocoon.
+@immutable
+class GithubWebhookSubscription extends SubscriptionHandler {
+ /// Creates a subscription for processing GitHub webhooks.
+ const GithubWebhookSubscription({
+ required super.cache,
+ required super.config,
+ required this.scheduler,
+ this.githubChecksService,
+ this.datastoreProvider = DatastoreService.defaultProvider,
+ required this.branchService,
+ super.authProvider,
+ }) : super(topicName: 'github-webhooks');
+
+ /// Cocoon scheduler to trigger tasks against changes from GitHub.
+ final Scheduler scheduler;
+
+ /// To provide build status updates to GitHub pull requests.
+ final GithubChecksService? githubChecksService;
+
+ final DatastoreServiceProvider datastoreProvider;
+ final BranchService branchService;
+
+ @override
+ Future<Body> post() async {
+ if (message.data == null || message.data!.isEmpty) {
+ log.warning('GitHub webhook message was empty. No-oping');
+ return Body.empty;
+ }
+
+ final pb.GithubWebhookMessage webhook = pb.GithubWebhookMessage.fromJson(message.data!);
+
+ log.fine('Processing ${webhook.event}');
+ log.finest(webhook.payload);
+ switch (webhook.event) {
+ case 'pull_request':
+ await _handlePullRequest(webhook.payload);
+ break;
+ case 'check_run':
+ final Map<String, dynamic> event = jsonDecode(webhook.payload) as Map<String, dynamic>;
+ final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(event);
+ if (await scheduler.processCheckRun(checkRunEvent) == false) {
+ throw InternalServerError('Failed to process $checkRunEvent');
+ }
+ break;
+ case 'create':
+ final CreateEvent createEvent = CreateEvent.fromJson(json.decode(webhook.payload) as Map<String, dynamic>);
+ await branchService.handleCreateRequest(createEvent);
+ if (createEvent.repository?.slug() == Config.flutterSlug) {
+ await branchService.branchFlutterRecipes(createEvent.ref!);
+ }
+ break;
+ }
+
+ return Body.empty;
+ }
+
+ Future<void> _handlePullRequest(
+ String rawRequest,
+ ) async {
+ final PullRequestEvent? pullRequestEvent = await _getPullRequestEvent(rawRequest);
+ if (pullRequestEvent == null) {
+ throw const BadRequestException('Expected pull request event.');
+ }
+ final String? eventAction = pullRequestEvent.action;
+ final PullRequest pr = pullRequestEvent.pullRequest!;
+
+ // See the API reference:
+ // https://developer.github.com/v3/activity/events/types/#pullrequestevent
+ // which unfortunately is a bit light on explanations.
+ log.fine('Processing $eventAction for ${pr.htmlUrl}');
+ switch (eventAction) {
+ case 'closed':
+ // If it was closed without merging, cancel any outstanding tryjobs.
+ // We'll leave unfinished jobs if it was merged since we care about those
+ // results.
+ if (!pr.merged!) {
+ await scheduler.cancelPreSubmitTargets(pullRequest: pr, reason: 'Pull request closed');
+ } else {
+ // Merged pull requests can be added to CI.
+ await scheduler.addPullRequest(pr);
+ }
+ break;
+ case 'edited':
+ // Editing a PR should not trigger new jobs, but may update whether
+ // it has tests.
+ await _checkForLabelsAndTests(pullRequestEvent);
+ break;
+ case 'opened':
+ case 'reopened':
+ // These cases should trigger LUCI jobs.
+ await _checkForLabelsAndTests(pullRequestEvent);
+ await _scheduleIfMergeable(pullRequestEvent);
+ await _tryReleaseApproval(pullRequestEvent);
+ break;
+ case 'labeled':
+ break;
+ case 'synchronize':
+ // This indicates the PR has new commits. We need to cancel old jobs
+ // and schedule new ones.
+ await _scheduleIfMergeable(pullRequestEvent);
+ break;
+ // Ignore the rest of the events.
+ case 'ready_for_review':
+ case 'unlabeled':
+ case 'assigned':
+ case 'locked':
+ case 'review_request_removed':
+ case 'review_requested':
+ case 'unassigned':
+ case 'unlocked':
+ break;
+ }
+ }
+
+ /// This method assumes that jobs should be cancelled if they are already
+ /// runnning.
+ Future<void> _scheduleIfMergeable(
+ PullRequestEvent pullRequestEvent,
+ ) async {
+ final PullRequest pr = pullRequestEvent.pullRequest!;
+ final RepositorySlug slug = pullRequestEvent.repository!.slug();
+
+ log.info(
+ 'Scheduling tasks if mergeable(${pr.mergeable}): owner=${slug.owner} repo=${slug.name} and pr=${pr.number}');
+
+ // The mergeable flag may be null. False indicates there's a merge conflict,
+ // null indicates unknown. Err on the side of allowing the job to run.
+ if (pr.mergeable == false) {
+ final RepositorySlug slug = pullRequestEvent.repository!.slug();
+ final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
+ final String body = config.mergeConflictPullRequestMessage;
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ }
+
+ return;
+ }
+
+ await scheduler.triggerPresubmitTargets(pullRequest: pr);
+ }
+
+ /// Release tooling generates cherrypick pull requests that should be granted an approval.
+ Future<void> _tryReleaseApproval(
+ PullRequestEvent pullRequestEvent,
+ ) async {
+ final PullRequest pr = pullRequestEvent.pullRequest!;
+ final RepositorySlug slug = pullRequestEvent.repository!.slug();
+
+ final String defaultBranch = Config.defaultBranch(slug);
+ final String? branch = pr.base?.ref;
+ if (branch == null || branch.contains(defaultBranch)) {
+ // This isn't a release branch PR
+ return;
+ }
+
+ final List<String> releaseAccounts = await config.releaseAccounts;
+ if (releaseAccounts.contains(pr.user?.login) == false) {
+ // The author isn't in the list of release accounts, do nothing
+ return;
+ }
+
+ final GitHub gitHubClient = config.createGitHubClientWithToken(await config.githubOAuthToken);
+ final CreatePullRequestReview review = CreatePullRequestReview(slug.owner, slug.name, pr.number!, 'APPROVE');
+ await gitHubClient.pullRequests.createReview(slug, review);
+ }
+
+ Future<void> _checkForLabelsAndTests(PullRequestEvent pullRequestEvent) async {
+ final PullRequest pr = pullRequestEvent.pullRequest!;
+ final String? eventAction = pullRequestEvent.action;
+ final String repo = pr.base!.repo!.fullName.toLowerCase();
+ if (kNeedsCheckLabelsAndTests.contains(repo)) {
+ final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
+ try {
+ await _validateRefs(gitHubClient, pr);
+ if (repo == 'flutter/flutter') {
+ await _applyFrameworkRepoLabels(gitHubClient, eventAction, pr);
+ } else if (repo == 'flutter/engine') {
+ await _applyEngineRepoLabels(gitHubClient, eventAction, pr);
+ } else if (repo == 'flutter/plugins' || repo == 'flutter/packages') {
+ await _applyPackageTestChecks(gitHubClient, eventAction, pr);
+ }
+ } finally {
+ gitHubClient.dispose();
+ }
+ }
+ }
+
+ Future<void> _applyFrameworkRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
+ if (pr.user!.login == 'engine-flutter-autoroll') {
+ return;
+ }
+
+ final RepositorySlug slug = pr.base!.repo!.slug();
+ log.info('Applying framework repo labels for: owner=${slug.owner} repo=${slug.name} and pr=${pr.number}');
+ final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
+
+ final Set<String> labels = <String>{};
+ bool hasTests = false;
+ bool needsTests = false;
+
+ await for (PullRequestFile file in files) {
+ // When null, do not assume 0 lines have been added.
+ final String filename = file.filename!;
+ final int linesAdded = file.additionsCount ?? 1;
+ final int linesDeleted = file.deletionsCount ?? 0;
+ final int linesTotal = file.changesCount ?? linesDeleted + linesAdded;
+ final bool addedCode = linesAdded > 0 || linesDeleted != linesTotal;
+
+ if (addedCode &&
+ !filename.contains('AUTHORS') &&
+ !filename.contains('pubspec.yaml') &&
+ !filename.contains('.ci.yaml') &&
+ !filename.contains('.cirrus.yml') &&
+ !filename.contains('.github') &&
+ !filename.endsWith('.md') &&
+ !filename.contains('CODEOWNERS') &&
+ !filename.startsWith('dev/bots/')) {
+ needsTests = !_allChangesAreCodeComments(file);
+ }
+
+ // Check to see if tests were submitted with this PR.
+ if (_isATest(filename)) {
+ hasTests = true;
+ }
+ labels.addAll(getLabelsForFrameworkPath(filename));
+ }
+
+ if (pr.user!.login == 'fluttergithubbot') {
+ needsTests = false;
+ labels.addAll(<String>['team', 'tech-debt', 'team: flakes']);
+ }
+
+ if (labels.isNotEmpty) {
+ await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, labels.toList());
+ }
+
+ // We do not need to add test labels if this is an auto roller author.
+ if (config.rollerAccounts.contains(pr.user!.login)) {
+ return;
+ }
+
+ if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
+ final String body = config.missingTestsPullRequestMessage;
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ }
+ }
+ }
+
+ bool _isATest(String filename) {
+ if (kNotActuallyATest.any(filename.endsWith)) {
+ return false;
+ }
+ // Check for Objective-C tests which end in either "Tests.m" or "Test.m"
+ // in the "dev" directory.
+ final RegExp objectiveCTestRegex = RegExp(r'.*dev\/.*Test[s]?\.m$');
+ return filename.endsWith('_test.dart') ||
+ filename.endsWith('.expect') ||
+ filename.contains('test_fixes') ||
+ filename.startsWith('dev/bots/analyze.dart') ||
+ filename.startsWith('dev/bots/test.dart') ||
+ filename.startsWith('dev/devicelab/bin/tasks') ||
+ filename.startsWith('dev/devicelab/lib/tasks') ||
+ filename.startsWith('dev/devicelab/lib/tasks') ||
+ objectiveCTestRegex.hasMatch(filename);
+ }
+
+ /// Returns the set of labels applicable to a file in the framework repo.
+ static Set<String> getLabelsForFrameworkPath(String filepath) {
+ final Set<String> labels = <String>{};
+ if (filepath.endsWith('pubspec.yaml')) {
+ // These get updated by a script, and are updated en masse.
+ labels.add('team');
+ return labels;
+ }
+
+ if (filepath.endsWith('fix_data.yaml') || filepath.endsWith('.expect') || filepath.contains('test_fixes')) {
+ // Dart fixes
+ labels.add('team');
+ labels.add('tech-debt');
+ }
+
+ const Map<String, List<String>> pathPrefixLabels = <String, List<String>>{
+ 'bin/internal/engine.version': <String>['engine'],
+ 'dev/': <String>['team'],
+ 'examples/': <String>['d: examples', 'team'],
+ 'examples/api/': <String>['d: examples', 'team', 'd: api docs', 'documentation'],
+ 'examples/flutter_gallery/': <String>['d: examples', 'team', 'team: gallery'],
+ 'packages/flutter_tools/': <String>['tool'],
+ 'packages/flutter_tools/lib/src/ios/': <String>['platform-ios'],
+ 'packages/flutter/': <String>['framework'],
+ 'packages/flutter_driver/': <String>['framework', 'a: tests'],
+ 'packages/flutter_localizations/': <String>['a: internationalization'],
+ 'packages/flutter_goldens/': <String>['framework', 'a: tests', 'team'],
+ 'packages/flutter_goldens_client/': <String>['framework', 'a: tests', 'team'],
+ 'packages/flutter_test/': <String>['framework', 'a: tests'],
+ 'packages/fuchsia_remote_debug_protocol/': <String>['tool'],
+ 'packages/integration_test/': <String>['integration_test'],
+ };
+ const Map<String, List<String>> pathContainsLabels = <String, List<String>>{
+ 'accessibility': <String>['a: accessibility'],
+ 'animation': <String>['a: animation'],
+ 'cupertino': <String>['f: cupertino'],
+ 'focus': <String>['f: focus'],
+ 'gestures': <String>['f: gestures'],
+ 'material': <String>['f: material design'],
+ 'navigator': <String>['f: routes'],
+ 'route': <String>['f: routes'],
+ 'scroll': <String>['f: scrolling'],
+ 'semantics': <String>['a: accessibility'],
+ 'sliver': <String>['f: scrolling'],
+ 'text': <String>['a: text input'],
+ 'viewport': <String>['f: scrolling'],
+ };
+
+ pathPrefixLabels.forEach((String path, List<String> pathLabels) {
+ if (filepath.startsWith(path)) {
+ labels.addAll(pathLabels);
+ }
+ });
+ pathContainsLabels.forEach((String path, List<String> pathLabels) {
+ if (filepath.contains(path)) {
+ labels.addAll(pathLabels);
+ }
+ });
+ return labels;
+ }
+
+ /// Returns the set of labels applicable to a file in the engine repo.
+ static Set<String> getLabelsForEnginePath(String filepath) {
+ const Map<String, List<String>> pathPrefixLabels = <String, List<String>>{
+ 'shell/platform/android': <String>['platform-android'],
+ 'shell/platform/embedder': <String>['embedder'],
+ 'shell/platform/darwin/common': <String>['platform-ios', 'platform-macos'],
+ 'shell/platform/darwin/ios': <String>['platform-ios'],
+ 'shell/platform/darwin/macos': <String>['platform-macos'],
+ 'shell/platform/fuchsia': <String>['platform-fuchsia'],
+ 'shell/platform/linux': <String>['platform-linux'],
+ 'shell/platform/windows': <String>['platform-windows'],
+ 'lib/web_ui': <String>['platform-web'],
+ 'web_sdk': <String>['platform-web'],
+ };
+ final Set<String> labels = <String>{};
+ pathPrefixLabels.forEach((String path, List<String> pathLabels) {
+ if (filepath.startsWith(path)) {
+ labels.addAll(pathLabels);
+ }
+ });
+ return labels;
+ }
+
+ Future<void> _applyEngineRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
+ // Do not apply the test labels for the autoroller accounts.
+ if (pr.user!.login == 'skia-flutter-autoroll') {
+ return;
+ }
+
+ final RepositorySlug slug = pr.base!.repo!.slug();
+ final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
+ final Set<String> labels = <String>{};
+ bool hasTests = false;
+ bool needsTests = false;
+
+ await for (PullRequestFile file in files) {
+ final String filename = file.filename!.toLowerCase();
+ if (filename.endsWith('.dart') ||
+ filename.endsWith('.mm') ||
+ filename.endsWith('.m') ||
+ filename.endsWith('.java') ||
+ filename.endsWith('.cc')) {
+ needsTests = true;
+ }
+
+ if (kEngineTestRegExp.hasMatch(filename)) {
+ hasTests = true;
+ }
+
+ labels.addAll(getLabelsForEnginePath(filename));
+ }
+
+ if (labels.isNotEmpty) {
+ await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, labels.toList());
+ }
+
+ // We do not need to add test labels if this is an auto roller author.
+ if (config.rollerAccounts.contains(pr.user!.login)) {
+ return;
+ }
+
+ if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
+ final String body = config.missingTestsPullRequestMessage;
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, kNeedsTestsLabels);
+ }
+ }
+ }
+
+ // Runs automated test checks for both flutter/packages and flutter/plugins.
+ Future<void> _applyPackageTestChecks(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
+ final RepositorySlug slug = pr.base!.repo!.slug();
+ final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
+ bool hasTests = false;
+ bool needsTests = false;
+
+ await for (PullRequestFile file in files) {
+ final String filename = file.filename!;
+
+ // When null, do not assume 0 lines have been added.
+ final int linesAdded = file.additionsCount ?? 1;
+ final int linesDeleted = file.deletionsCount ?? 0;
+ final int linesTotal = file.changesCount ?? linesDeleted + linesAdded;
+ final bool addedCode = linesAdded > 0 || linesDeleted != linesTotal;
+
+ if (addedCode &&
+ !filename.endsWith('AUTHORS') &&
+ !filename.endsWith('CODEOWNERS') &&
+ !filename.endsWith('pubspec.yaml') &&
+ !filename.endsWith('.ci.yaml') &&
+ !filename.endsWith('.cirrus.yml') &&
+ !filename.contains('.ci/') &&
+ !filename.contains('.github/') &&
+ !filename.endsWith('.md')) {
+ needsTests = !_allChangesAreCodeComments(file);
+ }
+ // See https://github.com/flutter/flutter/wiki/Plugin-Tests for discussion
+ // of various plugin test types and locations.
+ if (filename.endsWith('_test.dart') ||
+ // Native iOS/macOS tests.
+ filename.contains('RunnerTests/') ||
+ filename.contains('RunnerUITests/') ||
+ // Native Android tests.
+ filename.contains('android/src/test/') ||
+ filename.contains('androidTest/') ||
+ // Native Linux tests.
+ filename.endsWith('_test.cc') ||
+ // Native Windows tests.
+ filename.endsWith('_test.cpp')) {
+ hasTests = true;
+ }
+ }
+
+ // We do not need to add test labels if this is an auto roller author.
+ if (config.rollerAccounts.contains(pr.user!.login)) {
+ return;
+ }
+
+ if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
+ final String body = config.missingTestsPullRequestMessage;
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, kNeedsTestsLabels);
+ }
+ }
+ }
+
+ /// Validate the base and head refs of the PR.
+ Future<void> _validateRefs(
+ GitHub gitHubClient,
+ PullRequest pr,
+ ) async {
+ final RepositorySlug slug = pr.base!.repo!.slug();
+ String body;
+ const List<String> releaseChannels = <String>[
+ 'stable',
+ 'beta',
+ 'dev',
+ ];
+ // Close PRs that use a release branch as a source.
+ if (releaseChannels.contains(pr.head!.ref)) {
+ body = config.wrongHeadBranchPullRequestMessage(pr.head!.ref!);
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.pullRequests.edit(
+ slug,
+ pr.number!,
+ state: 'closed',
+ );
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ }
+ return;
+ }
+ final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
+ final String baseName = pr.base!.ref!;
+ if (baseName == defaultBranchName) {
+ return;
+ }
+ if (_isReleaseBranch(pr)) {
+ body = config.releaseBranchPullRequestMessage;
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ }
+ return;
+ }
+
+ // Assume this PR should be based against config.defaultBranch.
+ body = _getWrongBaseComment(base: baseName, defaultBranch: defaultBranchName);
+ if (!await _alreadyCommented(gitHubClient, pr, body)) {
+ await gitHubClient.pullRequests.edit(
+ slug,
+ pr.number!,
+ base: Config.defaultBranch(slug),
+ );
+ await gitHubClient.issues.createComment(slug, pr.number!, body);
+ }
+ }
+
+ bool _isReleaseBranch(PullRequest pr) {
+ final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
+ final String baseName = pr.base!.ref!;
+
+ if (baseName == defaultBranchName) {
+ return false;
+ }
+ // Check if branch name confroms to the format flutter-x.x-candidate.x,
+ // A pr with conforming branch name is likely to be intended
+ // for a release branch, whereas a pr with non conforming name is likely
+ // caused by user misoperations, in which case bot
+ // will suggest open pull request against default branch instead.
+ final RegExp candidateTest = RegExp(r'flutter-\d+\.\d+-candidate\.\d+');
+ if (candidateTest.hasMatch(baseName) && candidateTest.hasMatch(pr.head!.ref!)) {
+ return true;
+ }
+ return false;
+ }
+
+ Future<bool> _alreadyCommented(
+ GitHub gitHubClient,
+ PullRequest pr,
+ String message,
+ ) async {
+ final Stream<IssueComment> comments = gitHubClient.issues.listCommentsByIssue(pr.base!.repo!.slug(), pr.number!);
+ await for (IssueComment comment in comments) {
+ if (comment.body != null && comment.body!.contains(message)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ String _getWrongBaseComment({
+ required String base,
+ required String defaultBranch,
+ }) {
+ final String messageTemplate = config.wrongBaseBranchPullRequestMessage;
+ return messageTemplate.replaceAll('{{target_branch}}', base).replaceAll('{{default_branch}}', defaultBranch);
+ }
+
+ Future<PullRequestEvent?> _getPullRequestEvent(String request) async {
+ try {
+ return PullRequestEvent.fromJson(json.decode(request) as Map<String, dynamic>);
+ } on FormatException {
+ return null;
+ }
+ }
+
+ /// Returns true if the changes to [file] are all code comments.
+ ///
+ /// If that cannot be determined with confidence, returns false. False
+ /// negatives (e.g., for /* */-style multi-line comments) should be expected.
+ bool _allChangesAreCodeComments(PullRequestFile file) {
+ final int? linesAdded = file.additionsCount;
+ final int? linesDeleted = file.deletionsCount;
+ final String? patch = file.patch;
+ // If information is missing, err or the side of assuming it's a non-comment
+ // change.
+ if (linesAdded == null || linesDeleted == null || patch == null) {
+ return false;
+ }
+
+ // Ensure that the file is a language reconized by the check below.
+ const Set<String> codeExtensions = <String>{
+ 'cc',
+ 'cpp',
+ 'dart',
+ 'java',
+ 'kt',
+ 'm',
+ 'mm',
+ 'swift',
+ };
+ final String filename = file.filename!;
+ final String? extension = filename.contains('.') ? filename.split('.').last.toLowerCase() : null;
+ if (extension == null || !codeExtensions.contains(extension)) {
+ return false;
+ }
+
+ // Only handles single-line comments; identifying multi-line comments
+ // would require the full file and non-trivial parsing. Also doesn't handle
+ // end-of-line comments (e.g., "int x = 0; // Info about x").
+ final RegExp commentRegex = RegExp(r'[+-]\s*//');
+ for (String line in patch.split('\n')) {
+ if (!line.startsWith('+') && !line.startsWith('-')) {
+ continue;
+ }
+ if (!commentRegex.hasMatch(line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/app_dart/lib/src/request_handlers/github_webhook.dart b/app_dart/lib/src/request_handlers/github_webhook.dart
index cf1b87d..5ea32e6 100644
--- a/app_dart/lib/src/request_handlers/github_webhook.dart
+++ b/app_dart/lib/src/request_handlers/github_webhook.dart
@@ -4,593 +4,52 @@
import 'dart:async';
import 'dart:convert';
-
-import 'package:cocoon_service/src/service/branch_service.dart';
import 'package:crypto/crypto.dart';
-import 'package:github/github.dart'
- show CreatePullRequestReview, GitHub, IssueComment, PullRequest, PullRequestFile, RepositorySlug;
-import 'package:github/hooks.dart';
-
-import '../model/github/checks.dart' as cocoon_checks;
+import '../model/proto/protos.dart' as pb;
import '../request_handling/body.dart';
import '../request_handling/exceptions.dart';
+import '../request_handling/pubsub.dart';
import '../request_handling/request_handler.dart';
-import '../service/config.dart';
-import '../service/datastore.dart';
-import '../service/github_checks_service.dart';
-import '../service/logging.dart';
-import '../service/scheduler.dart';
-// Filenames which are not actually tests.
-const List<String> kNotActuallyATest = <String>[
- 'packages/flutter/lib/src/gestures/hit_test.dart',
-];
-
-/// List of repos that require check for labels and tests.
-const Set<String> kNeedsCheckLabelsAndTests = <String>{
- 'flutter/engine',
- 'flutter/flutter',
- 'flutter/packages',
- 'flutter/plugins',
-};
-
-final RegExp kEngineTestRegExp = RegExp(r'(tests?|benchmarks?)\.(dart|java|mm|m|cc)$');
-final List<String> kNeedsTestsLabels = <String>['needs tests'];
-
+/// The [RequestHandler] for processing GitHub webhooks and publishing valid events to PubSub.
+///
+/// Requests are only published as a [GithubWebhookMessage] iff they contain:
+/// 1. Event type from the header `X-GitHub-Event`
+/// 2. Event payload that was HMAC authenticated
class GithubWebhook extends RequestHandler<Body> {
GithubWebhook({
required super.config,
- required this.scheduler,
- this.githubChecksService,
- this.datastoreProvider = DatastoreService.defaultProvider,
- required this.branchService,
+ required this.pubsub,
});
- /// Cocoon scheduler to trigger tasks against changes from GitHub.
- final Scheduler scheduler;
-
- /// Github checks service. Used to provide build status to github.
- final GithubChecksService? githubChecksService;
-
- final DatastoreServiceProvider datastoreProvider;
- final BranchService branchService;
+ final PubSub pubsub;
@override
Future<Body> post() async {
- final String? gitHubEvent = request!.headers.value('X-GitHub-Event');
+ final String? event = request!.headers.value('X-GitHub-Event');
- if (gitHubEvent == null || request!.headers.value('X-Hub-Signature') == null) {
+ if (event == null || request!.headers.value('X-Hub-Signature') == null) {
throw const BadRequestException('Missing required headers.');
}
final List<int> requestBytes = await request!.expand((_) => _).toList();
final String? hmacSignature = request!.headers.value('X-Hub-Signature');
- if (!await _validateRequest(hmacSignature, requestBytes)) {
- throw const Forbidden();
- }
+ await _validateRequest(hmacSignature, requestBytes);
- try {
- final String stringRequest = utf8.decode(requestBytes);
- log.fine('Processing $gitHubEvent');
- log.finest(stringRequest);
- switch (gitHubEvent) {
- case 'pull_request':
- await _handlePullRequest(stringRequest);
- break;
- case 'check_run':
- final Map<String, dynamic> event = jsonDecode(stringRequest) as Map<String, dynamic>;
- final cocoon_checks.CheckRunEvent checkRunEvent = cocoon_checks.CheckRunEvent.fromJson(event);
- if (await scheduler.processCheckRun(checkRunEvent) == false) {
- throw InternalServerError('Failed to process $checkRunEvent');
- }
- break;
- case 'create':
- final CreateEvent createEvent = _getCreateEvent(stringRequest)!;
- await branchService.handleCreateRequest(createEvent);
- if (createEvent.repository?.slug() == Config.flutterSlug) {
- await branchService.branchFlutterRecipes(createEvent.ref!);
- }
- break;
- }
+ final String requestString = utf8.decode(requestBytes);
- return Body.empty;
- } on FormatException {
- throw const BadRequestException('Could not process input data.');
- } on InternalServerError {
- rethrow;
- }
+ // TODO(chillers): This won't work until using proto.
+ final pb.GithubWebhookMessage message = pb.GithubWebhookMessage.create()
+ ..event = event
+ ..payload = requestString;
+ await pubsub.publish('github-wehbooks', message);
+
+ return Body.empty;
}
- Future<void> _handlePullRequest(
- String rawRequest,
- ) async {
- final PullRequestEvent? pullRequestEvent = await _getPullRequestEvent(rawRequest);
- if (pullRequestEvent == null) {
- throw const BadRequestException('Expected pull request event.');
- }
- final String? eventAction = pullRequestEvent.action;
- final PullRequest pr = pullRequestEvent.pullRequest!;
-
- // See the API reference:
- // https://developer.github.com/v3/activity/events/types/#pullrequestevent
- // which unfortunately is a bit light on explanations.
- log.fine('Processing $eventAction for ${pr.htmlUrl}');
- switch (eventAction) {
- case 'closed':
- // If it was closed without merging, cancel any outstanding tryjobs.
- // We'll leave unfinished jobs if it was merged since we care about those
- // results.
- if (!pr.merged!) {
- await scheduler.cancelPreSubmitTargets(pullRequest: pr, reason: 'Pull request closed');
- } else {
- // Merged pull requests can be added to CI.
- await scheduler.addPullRequest(pr);
- }
- break;
- case 'edited':
- // Editing a PR should not trigger new jobs, but may update whether
- // it has tests.
- await _checkForLabelsAndTests(pullRequestEvent);
- break;
- case 'opened':
- case 'reopened':
- // These cases should trigger LUCI jobs.
- await _checkForLabelsAndTests(pullRequestEvent);
- await _scheduleIfMergeable(pullRequestEvent);
- await _tryReleaseApproval(pullRequestEvent);
- break;
- case 'labeled':
- break;
- case 'synchronize':
- // This indicates the PR has new commits. We need to cancel old jobs
- // and schedule new ones.
- await _scheduleIfMergeable(pullRequestEvent);
- break;
- // Ignore the rest of the events.
- case 'ready_for_review':
- case 'unlabeled':
- case 'assigned':
- case 'locked':
- case 'review_request_removed':
- case 'review_requested':
- case 'unassigned':
- case 'unlocked':
- break;
- }
- }
-
- /// This method assumes that jobs should be cancelled if they are already
- /// runnning.
- Future<void> _scheduleIfMergeable(
- PullRequestEvent pullRequestEvent,
- ) async {
- final PullRequest pr = pullRequestEvent.pullRequest!;
- final RepositorySlug slug = pullRequestEvent.repository!.slug();
-
- log.info(
- 'Scheduling tasks if mergeable(${pr.mergeable}): owner=${slug.owner} repo=${slug.name} and pr=${pr.number}');
-
- // The mergeable flag may be null. False indicates there's a merge conflict,
- // null indicates unknown. Err on the side of allowing the job to run.
- if (pr.mergeable == false) {
- final RepositorySlug slug = pullRequestEvent.repository!.slug();
- final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
- final String body = config.mergeConflictPullRequestMessage;
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- }
-
- return;
- }
-
- await scheduler.triggerPresubmitTargets(pullRequest: pr);
- }
-
- /// Release tooling generates cherrypick pull requests that should be granted an approval.
- Future<void> _tryReleaseApproval(
- PullRequestEvent pullRequestEvent,
- ) async {
- final PullRequest pr = pullRequestEvent.pullRequest!;
- final RepositorySlug slug = pullRequestEvent.repository!.slug();
-
- final String defaultBranch = Config.defaultBranch(slug);
- final String? branch = pr.base?.ref;
- if (branch == null || branch.contains(defaultBranch)) {
- // This isn't a release branch PR
- return;
- }
-
- final List<String> releaseAccounts = await config.releaseAccounts;
- if (releaseAccounts.contains(pr.user?.login) == false) {
- // The author isn't in the list of release accounts, do nothing
- return;
- }
-
- final GitHub gitHubClient = config.createGitHubClientWithToken(await config.githubOAuthToken);
- final CreatePullRequestReview review = CreatePullRequestReview(slug.owner, slug.name, pr.number!, 'APPROVE');
- await gitHubClient.pullRequests.createReview(slug, review);
- }
-
- Future<void> _checkForLabelsAndTests(PullRequestEvent pullRequestEvent) async {
- final PullRequest pr = pullRequestEvent.pullRequest!;
- final String? eventAction = pullRequestEvent.action;
- final String repo = pr.base!.repo!.fullName.toLowerCase();
- if (kNeedsCheckLabelsAndTests.contains(repo)) {
- final GitHub gitHubClient = await config.createGitHubClient(pullRequest: pr);
- try {
- await _validateRefs(gitHubClient, pr);
- if (repo == 'flutter/flutter') {
- await _applyFrameworkRepoLabels(gitHubClient, eventAction, pr);
- } else if (repo == 'flutter/engine') {
- await _applyEngineRepoLabels(gitHubClient, eventAction, pr);
- } else if (repo == 'flutter/plugins' || repo == 'flutter/packages') {
- await _applyPackageTestChecks(gitHubClient, eventAction, pr);
- }
- } finally {
- gitHubClient.dispose();
- }
- }
- }
-
- Future<void> _applyFrameworkRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
- if (pr.user!.login == 'engine-flutter-autoroll') {
- return;
- }
-
- final RepositorySlug slug = pr.base!.repo!.slug();
- log.info('Applying framework repo labels for: owner=${slug.owner} repo=${slug.name} and pr=${pr.number}');
- final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
-
- final Set<String> labels = <String>{};
- bool hasTests = false;
- bool needsTests = false;
-
- await for (PullRequestFile file in files) {
- // When null, do not assume 0 lines have been added.
- final String filename = file.filename!;
- final int linesAdded = file.additionsCount ?? 1;
- final int linesDeleted = file.deletionsCount ?? 0;
- final int linesTotal = file.changesCount ?? linesDeleted + linesAdded;
- final bool addedCode = linesAdded > 0 || linesDeleted != linesTotal;
-
- if (addedCode &&
- !filename.contains('AUTHORS') &&
- !filename.contains('pubspec.yaml') &&
- !filename.contains('.ci.yaml') &&
- !filename.contains('.cirrus.yml') &&
- !filename.contains('.github') &&
- !filename.endsWith('.md') &&
- !filename.contains('CODEOWNERS') &&
- !filename.startsWith('dev/bots/')) {
- needsTests = !_allChangesAreCodeComments(file);
- }
-
- // Check to see if tests were submitted with this PR.
- if (_isATest(filename)) {
- hasTests = true;
- }
- labels.addAll(getLabelsForFrameworkPath(filename));
- }
-
- if (pr.user!.login == 'fluttergithubbot') {
- needsTests = false;
- labels.addAll(<String>['team', 'tech-debt', 'team: flakes']);
- }
-
- if (labels.isNotEmpty) {
- await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, labels.toList());
- }
-
- // We do not need to add test labels if this is an auto roller author.
- if (config.rollerAccounts.contains(pr.user!.login)) {
- return;
- }
-
- if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
- final String body = config.missingTestsPullRequestMessage;
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- }
- }
- }
-
- bool _isATest(String filename) {
- if (kNotActuallyATest.any(filename.endsWith)) {
- return false;
- }
- // Check for Objective-C tests which end in either "Tests.m" or "Test.m"
- // in the "dev" directory.
- final RegExp objectiveCTestRegex = RegExp(r'.*dev\/.*Test[s]?\.m$');
- return filename.endsWith('_test.dart') ||
- filename.endsWith('.expect') ||
- filename.contains('test_fixes') ||
- filename.startsWith('dev/bots/analyze.dart') ||
- filename.startsWith('dev/bots/test.dart') ||
- filename.startsWith('dev/devicelab/bin/tasks') ||
- filename.startsWith('dev/devicelab/lib/tasks') ||
- objectiveCTestRegex.hasMatch(filename);
- }
-
- /// Returns the set of labels applicable to a file in the framework repo.
- static Set<String> getLabelsForFrameworkPath(String filepath) {
- final Set<String> labels = <String>{};
- if (filepath.endsWith('pubspec.yaml')) {
- // These get updated by a script, and are updated en masse.
- labels.add('team');
- return labels;
- }
-
- if (filepath.endsWith('fix_data.yaml') || filepath.endsWith('.expect') || filepath.contains('test_fixes')) {
- // Dart fixes
- labels.add('team');
- labels.add('tech-debt');
- }
-
- const Map<String, List<String>> pathPrefixLabels = <String, List<String>>{
- 'bin/internal/engine.version': <String>['engine'],
- 'dev/': <String>['team'],
- 'examples/': <String>['d: examples', 'team'],
- 'examples/api/': <String>['d: examples', 'team', 'd: api docs', 'documentation'],
- 'examples/flutter_gallery/': <String>['d: examples', 'team', 'team: gallery'],
- 'packages/flutter_tools/': <String>['tool'],
- 'packages/flutter_tools/lib/src/ios/': <String>['platform-ios'],
- 'packages/flutter/': <String>['framework'],
- 'packages/flutter_driver/': <String>['framework', 'a: tests'],
- 'packages/flutter_localizations/': <String>['a: internationalization'],
- 'packages/flutter_goldens/': <String>['framework', 'a: tests', 'team'],
- 'packages/flutter_goldens_client/': <String>['framework', 'a: tests', 'team'],
- 'packages/flutter_test/': <String>['framework', 'a: tests'],
- 'packages/fuchsia_remote_debug_protocol/': <String>['tool'],
- 'packages/integration_test/': <String>['integration_test'],
- };
- const Map<String, List<String>> pathContainsLabels = <String, List<String>>{
- 'accessibility': <String>['a: accessibility'],
- 'animation': <String>['a: animation'],
- 'cupertino': <String>['f: cupertino'],
- 'focus': <String>['f: focus'],
- 'gestures': <String>['f: gestures'],
- 'material': <String>['f: material design'],
- 'navigator': <String>['f: routes'],
- 'route': <String>['f: routes'],
- 'scroll': <String>['f: scrolling'],
- 'semantics': <String>['a: accessibility'],
- 'sliver': <String>['f: scrolling'],
- 'text': <String>['a: text input'],
- 'viewport': <String>['f: scrolling'],
- };
-
- pathPrefixLabels.forEach((String path, List<String> pathLabels) {
- if (filepath.startsWith(path)) {
- labels.addAll(pathLabels);
- }
- });
- pathContainsLabels.forEach((String path, List<String> pathLabels) {
- if (filepath.contains(path)) {
- labels.addAll(pathLabels);
- }
- });
- return labels;
- }
-
- /// Returns the set of labels applicable to a file in the engine repo.
- static Set<String> getLabelsForEnginePath(String filepath) {
- const Map<String, List<String>> pathPrefixLabels = <String, List<String>>{
- 'shell/platform/android': <String>['platform-android'],
- 'shell/platform/embedder': <String>['embedder'],
- 'shell/platform/darwin/common': <String>['platform-ios', 'platform-macos'],
- 'shell/platform/darwin/ios': <String>['platform-ios'],
- 'shell/platform/darwin/macos': <String>['platform-macos'],
- 'shell/platform/fuchsia': <String>['platform-fuchsia'],
- 'shell/platform/linux': <String>['platform-linux'],
- 'shell/platform/windows': <String>['platform-windows'],
- 'lib/web_ui': <String>['platform-web'],
- 'web_sdk': <String>['platform-web'],
- };
- final Set<String> labels = <String>{};
- pathPrefixLabels.forEach((String path, List<String> pathLabels) {
- if (filepath.startsWith(path)) {
- labels.addAll(pathLabels);
- }
- });
- return labels;
- }
-
- Future<void> _applyEngineRepoLabels(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
- // Do not apply the test labels for the autoroller accounts.
- if (pr.user!.login == 'skia-flutter-autoroll') {
- return;
- }
-
- final RepositorySlug slug = pr.base!.repo!.slug();
- final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
- final Set<String> labels = <String>{};
- bool hasTests = false;
- bool needsTests = false;
-
- await for (PullRequestFile file in files) {
- final String filename = file.filename!.toLowerCase();
- if (filename.endsWith('.dart') ||
- filename.endsWith('.mm') ||
- filename.endsWith('.m') ||
- filename.endsWith('.java') ||
- filename.endsWith('.cc')) {
- needsTests = true;
- }
-
- if (kEngineTestRegExp.hasMatch(filename)) {
- hasTests = true;
- }
-
- labels.addAll(getLabelsForEnginePath(filename));
- }
-
- if (labels.isNotEmpty) {
- await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, labels.toList());
- }
-
- // We do not need to add test labels if this is an auto roller author.
- if (config.rollerAccounts.contains(pr.user!.login)) {
- return;
- }
-
- if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
- final String body = config.missingTestsPullRequestMessage;
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, kNeedsTestsLabels);
- }
- }
- }
-
- // Runs automated test checks for both flutter/packages and flutter/plugins.
- Future<void> _applyPackageTestChecks(GitHub gitHubClient, String? eventAction, PullRequest pr) async {
- final RepositorySlug slug = pr.base!.repo!.slug();
- final Stream<PullRequestFile> files = gitHubClient.pullRequests.listFiles(slug, pr.number!);
- bool hasTests = false;
- bool needsTests = false;
-
- await for (PullRequestFile file in files) {
- final String filename = file.filename!;
-
- // When null, do not assume 0 lines have been added.
- final int linesAdded = file.additionsCount ?? 1;
- final int linesDeleted = file.deletionsCount ?? 0;
- final int linesTotal = file.changesCount ?? linesDeleted + linesAdded;
- final bool addedCode = linesAdded > 0 || linesDeleted != linesTotal;
-
- if (addedCode &&
- !filename.endsWith('AUTHORS') &&
- !filename.endsWith('CODEOWNERS') &&
- !filename.endsWith('pubspec.yaml') &&
- !filename.endsWith('.ci.yaml') &&
- !filename.endsWith('.cirrus.yml') &&
- !filename.contains('.ci/') &&
- !filename.contains('.github/') &&
- !filename.endsWith('.md')) {
- needsTests = !_allChangesAreCodeComments(file);
- }
- // See https://github.com/flutter/flutter/wiki/Plugin-Tests for discussion
- // of various plugin test types and locations.
- if (filename.endsWith('_test.dart') ||
- // Native iOS/macOS tests.
- filename.contains('RunnerTests/') ||
- filename.contains('RunnerUITests/') ||
- // Native Android tests.
- filename.contains('android/src/test/') ||
- filename.contains('androidTest/') ||
- // Native Linux tests.
- filename.endsWith('_test.cc') ||
- // Native Windows tests.
- filename.endsWith('_test.cpp')) {
- hasTests = true;
- }
- }
-
- // We do not need to add test labels if this is an auto roller author.
- if (config.rollerAccounts.contains(pr.user!.login)) {
- return;
- }
-
- if (!hasTests && needsTests && !pr.draft! && !_isReleaseBranch(pr)) {
- final String body = config.missingTestsPullRequestMessage;
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- await gitHubClient.issues.addLabelsToIssue(slug, pr.number!, kNeedsTestsLabels);
- }
- }
- }
-
- /// Validate the base and head refs of the PR.
- Future<void> _validateRefs(
- GitHub gitHubClient,
- PullRequest pr,
- ) async {
- final RepositorySlug slug = pr.base!.repo!.slug();
- String body;
- const List<String> releaseChannels = <String>[
- 'stable',
- 'beta',
- 'dev',
- ];
- // Close PRs that use a release branch as a source.
- if (releaseChannels.contains(pr.head!.ref)) {
- body = config.wrongHeadBranchPullRequestMessage(pr.head!.ref!);
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.pullRequests.edit(
- slug,
- pr.number!,
- state: 'closed',
- );
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- }
- return;
- }
- final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
- final String baseName = pr.base!.ref!;
- if (baseName == defaultBranchName) {
- return;
- }
- if (_isReleaseBranch(pr)) {
- body = config.releaseBranchPullRequestMessage;
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- }
- return;
- }
-
- // Assume this PR should be based against config.defaultBranch.
- body = _getWrongBaseComment(base: baseName, defaultBranch: defaultBranchName);
- if (!await _alreadyCommented(gitHubClient, pr, body)) {
- await gitHubClient.pullRequests.edit(
- slug,
- pr.number!,
- base: Config.defaultBranch(slug),
- );
- await gitHubClient.issues.createComment(slug, pr.number!, body);
- }
- }
-
- bool _isReleaseBranch(PullRequest pr) {
- final String defaultBranchName = Config.defaultBranch(pr.base!.repo!.slug());
- final String baseName = pr.base!.ref!;
-
- if (baseName == defaultBranchName) {
- return false;
- }
- // Check if branch name confroms to the format flutter-x.x-candidate.x,
- // A pr with conforming branch name is likely to be intended
- // for a release branch, whereas a pr with non conforming name is likely
- // caused by user misoperations, in which case bot
- // will suggest open pull request against default branch instead.
- final RegExp candidateTest = RegExp(r'flutter-\d+\.\d+-candidate\.\d+');
- if (candidateTest.hasMatch(baseName) && candidateTest.hasMatch(pr.head!.ref!)) {
- return true;
- }
- return false;
- }
-
- Future<bool> _alreadyCommented(
- GitHub gitHubClient,
- PullRequest pr,
- String message,
- ) async {
- final Stream<IssueComment> comments = gitHubClient.issues.listCommentsByIssue(pr.base!.repo!.slug(), pr.number!);
- await for (IssueComment comment in comments) {
- if (comment.body != null && comment.body!.contains(message)) {
- return true;
- }
- }
- return false;
- }
-
- String _getWrongBaseComment({
- required String base,
- required String defaultBranch,
- }) {
- final String messageTemplate = config.wrongBaseBranchPullRequestMessage;
- return messageTemplate.replaceAll('{{target_branch}}', base).replaceAll('{{default_branch}}', defaultBranch);
- }
-
- Future<bool> _validateRequest(
+ /// Ensures the signature provided for the given payload matches what is expected.
+ ///
+ /// The expected key is the sha1 hash of the payload using the private key of the GitHub app.
+ Future<void> _validateRequest(
String? signature,
List<int> requestBody,
) async {
@@ -599,71 +58,8 @@
final Hmac hmac = Hmac(sha1, key);
final Digest digest = hmac.convert(requestBody);
final String bodySignature = 'sha1=$digest';
- return bodySignature == signature;
- }
-
- Future<PullRequestEvent?> _getPullRequestEvent(String request) async {
- try {
- return PullRequestEvent.fromJson(json.decode(request) as Map<String, dynamic>);
- } on FormatException {
- return null;
- }
- }
-
- /// Returns true if the changes to [file] are all code comments.
- ///
- /// If that cannot be determined with confidence, returns false. False
- /// negatives (e.g., for /* */-style multi-line comments) should be expected.
- bool _allChangesAreCodeComments(PullRequestFile file) {
- final int? linesAdded = file.additionsCount;
- final int? linesDeleted = file.deletionsCount;
- final String? patch = file.patch;
- // If information is missing, err or the side of assuming it's a non-comment
- // change.
- if (linesAdded == null || linesDeleted == null || patch == null) {
- return false;
- }
-
- // Ensure that the file is a language reconized by the check below.
- const Set<String> codeExtensions = <String>{
- 'cc',
- 'cpp',
- 'dart',
- 'java',
- 'kt',
- 'm',
- 'mm',
- 'swift',
- };
- final String filename = file.filename!;
- final String? extension = filename.contains('.') ? filename.split('.').last.toLowerCase() : null;
- if (extension == null || !codeExtensions.contains(extension)) {
- return false;
- }
-
- // Only handles single-line comments; identifying multi-line comments
- // would require the full file and non-trivial parsing. Also doesn't handle
- // end-of-line comments (e.g., "int x = 0; // Info about x").
- final RegExp commentRegex = RegExp(r'[+-]\s*//');
- for (String line in patch.split('\n')) {
- if (!line.startsWith('+') && !line.startsWith('-')) {
- continue;
- }
- if (!commentRegex.hasMatch(line)) {
- return false;
- }
- }
- return true;
- }
-
- CreateEvent? _getCreateEvent(String request) {
- try {
- return CreateEvent.fromJson(json.decode(request) as Map<String, dynamic>);
- } on FormatException {
- return null;
- } catch (e) {
- log.severe('Unexpected exception was encountered while decoding json webhook msg for branch creation: $e');
- return null;
+ if (bodySignature != signature) {
+ throw const Forbidden('X-Hub-Signature does not match expected value');
}
}
}
diff --git a/app_dart/lib/src/service/config.dart b/app_dart/lib/src/service/config.dart
index d01b328..94fa1de 100644
--- a/app_dart/lib/src/service/config.dart
+++ b/app_dart/lib/src/service/config.dart
@@ -30,9 +30,11 @@
const String kDefaultBranchName = 'master';
/// Name of an example release base branch name.
+// TODO(chillers): Delete this as it's only used for tests.
const String kReleaseBaseRef = 'flutter-2.12-candidate.4';
/// Name of an example release head branch name.
+// TODO(chillers): Delete this as it's only used for tests.
const String kReleaseHeadRef = 'cherrypicks-flutter-2.12-candidate.4';
class Config {
diff --git a/app_dart/test/model/push_message_test.dart b/app_dart/test/model/push_message_test.dart
index a998fc1..7a16a0d 100644
--- a/app_dart/test/model/push_message_test.dart
+++ b/app_dart/test/model/push_message_test.dart
@@ -14,6 +14,7 @@
json.decode(buildPushMessageJson) as Map<String, dynamic>,
);
+ // TODO(chillers): This fails in EMEA timezones. Prefer using UTC instead of local.
expect(data.build!.createdTimestamp!.year, 2019);
expect(data.build!.createdTimestamp!.month, 8);
expect(data.build!.createdTimestamp!.day, 5);
diff --git a/app_dart/test/request_handlers/github/webhook_subscription_test.dart b/app_dart/test/request_handlers/github/webhook_subscription_test.dart
new file mode 100644
index 0000000..57fc915
--- /dev/null
+++ b/app_dart/test/request_handlers/github/webhook_subscription_test.dart
@@ -0,0 +1,2382 @@
+// Copyright 2019 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.
+
+import 'package:cocoon_service/src/model/appengine/commit.dart';
+import 'package:cocoon_service/src/model/luci/buildbucket.dart';
+import 'package:cocoon_service/src/request_handlers/github/webhook_subscription.dart';
+import 'package:cocoon_service/src/service/cache_service.dart';
+import 'package:cocoon_service/src/service/config.dart';
+import 'package:cocoon_service/src/service/datastore.dart';
+
+import 'package:github/github.dart' hide Branch;
+import 'package:googleapis/bigquery/v2.dart';
+import 'package:mockito/mockito.dart';
+import 'package:test/test.dart';
+
+import '../../src/datastore/fake_config.dart';
+import '../../src/datastore/fake_datastore.dart';
+import '../../src/request_handling/fake_http.dart';
+import '../../src/request_handling/subscription_tester.dart';
+import '../../src/service/fake_buildbucket.dart';
+import '../../src/service/fake_github_service.dart';
+import '../../src/service/fake_scheduler.dart';
+import '../../src/utilities/entity_generators.dart';
+import '../../src/utilities/mocks.dart';
+import '../../src/utilities/webhook_generators.dart';
+
+void main() {
+ late GithubWebhookSubscription webhook;
+ late FakeBuildBucketClient fakeBuildBucketClient;
+ late FakeConfig config;
+ late FakeDatastoreDB db;
+ late FakeGithubService githubService;
+ late FakeHttpRequest request;
+ late FakeScheduler scheduler;
+ late MockBranchService branchService;
+ late MockGitHub gitHubClient;
+ late MockGithubChecksUtil mockGithubChecksUtil;
+ late MockGithubChecksService mockGithubChecksService;
+ late MockIssuesService issuesService;
+ late MockPullRequestsService pullRequestsService;
+ late SubscriptionTester tester;
+
+ setUp(() {
+ request = FakeHttpRequest();
+ db = FakeDatastoreDB();
+ gitHubClient = MockGitHub();
+ githubService = FakeGithubService();
+ final MockTabledataResource tabledataResource = MockTabledataResource();
+ when(tabledataResource.insertAll(any, any, any, any)).thenAnswer((_) async => TableDataInsertAllResponse());
+ config = FakeConfig(
+ dbValue: db,
+ githubClient: gitHubClient,
+ githubService: githubService,
+ githubOAuthTokenValue: 'githubOAuthKey',
+ missingTestsPullRequestMessageValue: 'missingTestPullRequestMessage',
+ releaseBranchPullRequestMessageValue: 'releaseBranchPullRequestMessage',
+ rollerAccountsValue: const <String>{
+ 'skia-flutter-autoroll',
+ 'engine-flutter-autoroll',
+ 'dependabot',
+ },
+ tabledataResource: tabledataResource,
+ wrongHeadBranchPullRequestMessageValue: 'wrongHeadBranchPullRequestMessage',
+ wrongBaseBranchPullRequestMessageValue: '{{target_branch}} -> {{default_branch}}',
+ );
+ branchService = MockBranchService();
+ issuesService = MockIssuesService();
+ when(issuesService.addLabelsToIssue(any, any, any)).thenAnswer((_) async => <IssueLabel>[]);
+ when(issuesService.createComment(any, any, any)).thenAnswer((_) async => IssueComment());
+ when(issuesService.listCommentsByIssue(any, any))
+ .thenAnswer((_) => Stream<IssueComment>.fromIterable(<IssueComment>[IssueComment()]));
+ pullRequestsService = MockPullRequestsService();
+ when(pullRequestsService.listFiles(Config.flutterSlug, any))
+ .thenAnswer((_) => const Stream<PullRequestFile>.empty());
+ when(pullRequestsService.edit(any, any, title: anyNamed('title'), state: anyNamed('state'), base: anyNamed('base')))
+ .thenAnswer((_) async => PullRequest());
+ fakeBuildBucketClient = FakeBuildBucketClient();
+ mockGithubChecksUtil = MockGithubChecksUtil();
+ scheduler = FakeScheduler(
+ config: config,
+ buildbucket: fakeBuildBucketClient,
+ githubChecksUtil: mockGithubChecksUtil,
+ );
+ tester = SubscriptionTester(request: request);
+
+ mockGithubChecksService = MockGithubChecksService();
+ when(gitHubClient.issues).thenReturn(issuesService);
+ when(gitHubClient.pullRequests).thenReturn(pullRequestsService);
+ when(mockGithubChecksUtil.createCheckRun(any, any, any, any, output: anyNamed('output'))).thenAnswer((_) async {
+ return CheckRun.fromJson(const <String, dynamic>{
+ 'id': 1,
+ 'started_at': '2020-05-10T02:49:31Z',
+ 'check_suite': <String, dynamic>{'id': 2}
+ });
+ });
+
+ webhook = GithubWebhookSubscription(
+ config: config,
+ cache: CacheService(inMemory: true),
+ datastoreProvider: (_) => DatastoreService(config.db, 5),
+ githubChecksService: mockGithubChecksService,
+ scheduler: scheduler,
+ branchService: branchService,
+ );
+ });
+
+ group('github webhook pull_request event', () {
+ test('Closes PR opened from dev', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ headRef: 'dev',
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(pullRequestsService.edit(
+ Config.flutterSlug,
+ issueNumber,
+ state: 'closed',
+ )).called(1);
+
+ verify(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.wrongHeadBranchPullRequestMessageValue)),
+ )).called(1);
+ });
+
+ test('Acts on opened against dev', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: 'dev',
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(pullRequestsService.edit(
+ Config.flutterSlug,
+ issueNumber,
+ base: kDefaultBranchName,
+ )).called(1);
+
+ verify(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains('dev -> master')),
+ )).called(1);
+ });
+
+ test('Acts on opened against master when default is main', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: 'master',
+ slug: Config.engineSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(pullRequestsService.edit(
+ Config.engineSlug,
+ issueNumber,
+ base: 'main',
+ )).called(1);
+
+ verify(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains('master -> main')),
+ )).called(1);
+ });
+
+ // We already schedule checks when a draft is opened, don't need to re-test
+ // just because it was marked ready for review
+ test('Does nothing on ready_for_review', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'ready_for_review',
+ number: issueNumber,
+ );
+ bool batchRequestCalled = false;
+
+ Future<BatchResponse> _getBatchResponse() async {
+ batchRequestCalled = true;
+ fail('Marking a draft ready for review should not trigger new builds');
+ }
+
+ fakeBuildBucketClient.batchResponse = _getBatchResponse;
+
+ await tester.post(webhook);
+
+ expect(batchRequestCalled, isFalse);
+ });
+
+ test('Triggers builds when opening a draft PR', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ isDraft: true,
+ );
+ bool batchRequestCalled = false;
+
+ Future<BatchResponse> _getBatchResponse() async {
+ batchRequestCalled = true;
+ return BatchResponse(
+ responses: <Response>[
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(999, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(998, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ fakeBuildBucketClient.batchResponse = _getBatchResponse;
+
+ await tester.post(webhook);
+
+ expect(batchRequestCalled, isTrue);
+ });
+
+ test('Does nothing against cherry pick PR', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: 'flutter-1.20-candidate.7',
+ headRef: 'cherrypicks-flutter-1.20-candidate.7',
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(pullRequestsService.edit(
+ Config.flutterSlug,
+ issueNumber,
+ base: kDefaultBranchName,
+ ));
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.wrongBaseBranchPullRequestMessage)),
+ ));
+ });
+
+ group('getLabelsForFrameworkPath', () {
+ test('Only the team label is applied to pubspec.yaml', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_tools/pubspec.yaml'),
+ <String>{'team'});
+ });
+
+ test('Tool label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_tools/hot_reload.dart'),
+ contains('tool'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath(
+ 'packages/fuchsia_remote_debug_protocol/hot_reload.dart'),
+ contains('tool'));
+ });
+
+ test('iOS label applied', () {
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_tools/lib/src/ios/devices.dart'),
+ <String>{'platform-ios', 'tool'},
+ );
+ });
+
+ test('Engine label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('bin/internal/engine.version'), contains('engine'));
+ });
+
+ test('Framework label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/widget.dart'),
+ contains('framework'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_test/lib/tester.dart'),
+ contains('framework'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_driver/lib/driver.dart'),
+ contains('framework'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
+ contains('framework'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
+ contains('framework'));
+ });
+
+ test('Material label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('foo/bar/baz/material/design.dart'),
+ contains('f: material design'));
+ });
+
+ test('Cupertino label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('foo/bar/baz/cupertino/design.dart'),
+ contains('f: cupertino'));
+ });
+
+ test('i18n label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_localizations/allo.dart'),
+ contains('a: internationalization'));
+ });
+
+ test('Tests label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_test/lib/tester.dart'),
+ contains('a: tests'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_driver/lib/driver.dart'),
+ contains('a: tests'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
+ contains('a: tests'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
+ contains('a: tests'));
+ });
+
+ test('a11y label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('foo/bar/baz/semantics/voiceover.dart'),
+ contains('a: accessibility'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('foo/bar/baz/accessibility/voiceover.dart'),
+ contains('a: accessibility'));
+ });
+
+ test('Examples label applied', () {
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('examples/foo/bar/baz.dart'), contains('d: examples'));
+ });
+
+ test('API Docs label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('examples/api/bar/baz.dart'),
+ <String>['d: examples', 'team', 'd: api docs', 'documentation']);
+ });
+
+ test('Gallery label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('examples/flutter_gallery/lib/gallery.dart'),
+ contains('team: gallery'));
+ });
+
+ test('Team label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('dev/foo/bar/baz.dart'), contains('team'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('examples/foo/bar/baz.dart'), contains('team'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
+ contains('team'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
+ contains('team'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/fix_data.yaml'),
+ contains('team'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/test_fixes'), contains('team'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/test_fixes/material.expect'),
+ contains('team'));
+ });
+
+ test('tech-debt label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/fix_data.yaml'),
+ contains('tech-debt'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/test_fixes'), contains('tech-debt'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/test_fixes/material.expect'),
+ contains('tech-debt'));
+ });
+
+ test('gestures label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/gestures'),
+ contains('f: gestures'));
+ });
+
+ test('focus label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_node.dart'),
+ contains('f: focus'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_scope.dart'),
+ contains('f: focus'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_manager.dart'),
+ contains('f: focus'));
+ });
+
+ test('routes label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/router.dart'),
+ contains('f: routes'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/routes.dart'),
+ contains('f: routes'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/navigator.dart'),
+ contains('f: routes'));
+ });
+
+ test('text input label applied', () {
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath(
+ 'dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart'),
+ contains('a: text input'));
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath(
+ 'packages/flutter/lib/src/widgets/text_editing_action.dart'),
+ contains('a: text input'));
+ });
+
+ test('animation label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/animation'),
+ contains('a: animation'));
+ });
+
+ test('scrolling label applied', () {
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/sliver.dart'),
+ contains('f: scrolling'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/material/scrollbar.dart'),
+ contains('f: scrolling'));
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/flutter/lib/src/rendering/viewport.dart'),
+ contains('f: scrolling'));
+ });
+
+ test('integration_test label is/isn\'t applied', () {
+ // Label does not apply to integration tests outside of the
+ // integration_test package.
+ expect(
+ GithubWebhookSubscription.getLabelsForFrameworkPath(
+ 'dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart'),
+ <String>{'team', 'a: text input'});
+ // Label applies to integration_test package
+ expect(GithubWebhookSubscription.getLabelsForFrameworkPath('packages/integration_test/lib/common.dart'),
+ contains('integration_test'));
+ });
+ });
+
+ group('getLabelsForEnginePath', () {
+ test('No label is applied to paths with no applicable label', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('nonsense/path/foo.cc'), isEmpty);
+ });
+
+ test('platform-android applied for Android embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/android/RIsForRhubarbPie.java'),
+ contains('platform-android'));
+ });
+
+ test('platform-ios and platform-macos applied for common Darwin code', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/darwin/common/ThinkDifferent.mm'),
+ containsAll(<String>['platform-ios', 'platform-macos']));
+ });
+
+ test('platform-ios and platform-ios applied for iOS embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/darwin/ios/BackButton.mm'),
+ contains('platform-ios'));
+ });
+
+ test('platform-macos applied for macOS embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/darwin/macos/PhysicalEscapeKey.mm'),
+ contains('platform-macos'));
+ });
+
+ test('platform-fuchsia applied for fuchsia embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/fuchsia/spell_checker.cc'),
+ contains('platform-fuchsia'));
+ });
+
+ test('platform-linux applied for linux embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/linux/systemd_integration.cc'),
+ contains('platform-linux'));
+ });
+
+ test('platform-windows applied for windows embedder', () {
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('shell/platform/windows/start_menu.cc'),
+ contains('platform-windows'));
+ });
+
+ test('platform-web applied for web paths', () {
+ expect(
+ GithubWebhookSubscription.getLabelsForEnginePath('lib/web_ui/shadow_dom.dart'), contains('platform-web'));
+ expect(GithubWebhookSubscription.getLabelsForEnginePath('web_sdk/'), contains('platform-web'));
+ });
+ });
+
+ test('release PRs are approved', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ // Base is where the PR will merge into
+ baseRef: 'flutter-2.13-candidate.0',
+ login: 'dart-flutter-releaser',
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber))
+ .thenAnswer((_) => const Stream<PullRequestFile>.empty());
+ when(pullRequestsService.createReview(Config.flutterSlug, any))
+ .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
+
+ await tester.post(webhook);
+
+ final List<dynamic> reviews = verify(pullRequestsService.createReview(Config.flutterSlug, captureAny)).captured;
+ expect(reviews.length, 1);
+ final CreatePullRequestReview review = reviews.single as CreatePullRequestReview;
+ expect(review.event, 'APPROVE');
+ });
+
+ test('fake release PRs are not approved', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ // Base is where the PR will merge into
+ baseRef: 'master',
+ // Head is the branch from the fork
+ headRef: 'flutter-2.13-candidate.0',
+ login: 'dart-flutter-releaser',
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber))
+ .thenAnswer((_) => const Stream<PullRequestFile>.empty());
+ when(pullRequestsService.createReview(Config.flutterSlug, any))
+ .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
+
+ await tester.post(webhook);
+
+ verifyNever(pullRequestsService.createReview(Config.flutterSlug, captureAny));
+ });
+
+ test('release PRs are not approved for outsider PRs', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ headRef: 'flutter-2.13-candidate.0',
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber))
+ .thenAnswer((_) => const Stream<PullRequestFile>.empty());
+ when(pullRequestsService.createReview(Config.flutterSlug, any))
+ .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
+
+ await tester.post(webhook);
+
+ verifyNever(pullRequestsService.createReview(Config.flutterSlug, any));
+ });
+
+ test('Framework labels PRs, comment if no tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.flutterSlug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ verify(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+ });
+
+ group("Auto-roller accounts do not label Framework PR with test label or comment.", () {
+ Set<String> inputs = {
+ 'skia-flutter-autoroll',
+ 'dependabot',
+ };
+
+ for (String element in inputs) {
+ test('Framework does not label PR with no tests label if author is $element', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ login: element,
+ );
+
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+ }
+ });
+
+ test('Framework does not label PR with no tests label if author is engine-flutter-autoroll', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ login: 'engine-flutter-autoroll',
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework'],
+ ));
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels PRs, comment if no tests including hit_test.dart file', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()
+ ..additionsCount = 10
+ ..changesCount = 10
+ ..filename = 'packages/flutter/lib/src/gestures/hit_test.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework', 'f: gestures'],
+ )).called(1);
+
+ verify(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+ });
+
+ test('Framework labels PRs, no dart files', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.md',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ any,
+ ));
+ });
+
+ test('Framework labels PRs, no comment if tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/flutter/semantics_test.dart',
+ PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
+ PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
+ PullRequestFile()..filename = 'dev/bots/test.dart',
+ PullRequestFile()..filename = 'dev/devicelab/bin/tasks/analyzer_benchmark.dart',
+ PullRequestFile()..filename = 'bin/internal/engine.version',
+ PullRequestFile()..filename = 'packages/flutter/lib/src/cupertino/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>[
+ 'framework',
+ 'a: accessibility',
+ 'tool',
+ 'a: tests',
+ 'd: examples',
+ 'team',
+ 'team: gallery',
+ 'engine',
+ 'f: cupertino',
+ 'f: material design',
+ 'a: internationalization',
+ ],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels dart fix PRs, no comment if tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/flutter/test_fixes/material.dart',
+ PullRequestFile()..filename = 'packages/flutter/test_fixes/material.expect',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['team', 'tech-debt', 'framework', 'f: material design'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels bot PR, no comment', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ login: 'fluttergithubbot',
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['tool', 'framework', 'a: tests', 'team', 'tech-debt', 'team: flakes'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels deletion only PR, no test request', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()
+ ..filename = 'packages/flutter/blah.dart'
+ ..deletionsCount = 20
+ ..additionsCount = 0
+ ..changesCount = 20,
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ // The PR here is only deleting code, so no test comment.
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('PR with additions and deletions is commented and labeled', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()
+ ..filename = 'packages/flutter/blah.dart'
+ ..deletionsCount = 20
+ ..additionsCount = 1
+ ..changesCount = 21,
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ verify(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+ });
+
+ test('Framework no comment if code has only devicelab test', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/flutter_tools/lib/src/ios/devices.dart',
+ PullRequestFile()..filename = 'dev/devicelab/lib/tasks/plugin_tests.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no comment if only dev bots or devicelab changed', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(action: 'opened', number: issueNumber);
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'dev/bots/test.dart',
+ PullRequestFile()..filename = 'dev/devicelab/bin/tasks/analyzer_benchmark.dart',
+ PullRequestFile()..filename = 'dev/devicelab/lib/tasks/plugin_tests.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no test comment if Objective-C test changed', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(action: 'opened', number: issueNumber);
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ // Example of real behavior code change.
+ PullRequestFile()
+ ..filename = 'packages/flutter_tools/templates/app_shared/macos.tmpl/Runner/Base.lproj/MainMenu.xib',
+ // Example of Objective-C test.
+ PullRequestFile()..filename = 'dev/integration_tests/flutter_gallery/macos/RunnerTests/RunnerTests.m',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no comment if only AUTHORS changed', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'AUTHORS',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no comment if only ci.yaml and cirrus.yml changed', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = '.ci.yaml',
+ PullRequestFile()..filename = '.cirrus.yml',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no comment if only CODEOWNERS changed', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(action: 'opened', number: issueNumber);
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'CODEOWNERS',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework no comment if only comments changed', () async {
+ const int issueNumber = 123;
+ tester.message = generateGithubWebhookMessage(action: 'opened', number: issueNumber);
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ const String patch = '''
+@@ -128,7 +128,7 @@
+
+/// Insert interesting comment here.
+///
+-/// More details here, but some of them are wrong.
++/// These are the right details!
+void foo() {
+ int bar = 0;
+ String baz = '';
+''';
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()
+ ..filename = 'packages/foo/lib/foo.dart'
+ ..additionsCount = 1
+ ..deletionsCount = 1
+ ..changesCount = 2
+ ..patch = patch,
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels PRs, no comment if tests (dev/bots/test.dart)', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'dev/bots/test.dart',
+ PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
+ PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels PRs, no comment if tests (dev/bots/analyze.dart)', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'dev/bots/analyze.dart',
+ PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
+ PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
+ PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Framework labels PRs, apply label but no comment when rolling engine version', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: kReleaseBaseRef,
+ headRef: kReleaseHeadRef,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()
+ ..filename = 'bin/internal/engine.version'
+ ..deletionsCount = 20
+ ..additionsCount = 1
+ ..changesCount = 21,
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.flutterSlug,
+ issueNumber,
+ <String>['engine'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Engine labels PRs, comment and labels if no tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ );
+ final RepositorySlug slug = RepositorySlug('flutter', 'engine');
+
+ when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['platform-ios'],
+ )).called(1);
+
+ verify(issuesService.createComment(
+ slug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+
+ verify(issuesService.addLabelsToIssue(
+ slug,
+ issueNumber,
+ <String>['needs tests'],
+ )).called(1);
+ });
+
+ group("Auto-roller accounts do not label Engine PR with test label or comment.", () {
+ Set<String> inputs = {
+ 'engine-flutter-autoroll',
+ 'dependabot',
+ };
+
+ for (String element in inputs) {
+ test('Engine does not label PR for no tests if author is $element', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ login: element,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>['platform-ios'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>['needs tests'],
+ ));
+ });
+ }
+ });
+
+ test('Engine does not label PR for no tests if author is skia-flutter-autoroll', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ login: 'skia-flutter-autoroll',
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>['platform-ios'],
+ ));
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>['needs tests'],
+ ));
+ });
+
+ test('Engine labels PRs, no code files', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: 'main',
+ slug: Config.engineSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'DEPS',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ any,
+ ));
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ any,
+ ));
+ });
+
+ test('Engine labels PRs, no comment if Java tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'shell/platform/android/io/flutter/Blah.java',
+ PullRequestFile()..filename = 'shell/platform/android/test/io/flutter/BlahTest.java',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>[
+ 'platform-android',
+ ],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Engine labels PRs, no comment if cc tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'fml/blah.cc',
+ PullRequestFile()..filename = 'fml/blah_unittests.cc',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ any,
+ ));
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Engine labels PRs, no comment if cc becnhmarks', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.engineSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'fml/blah.cc',
+ PullRequestFile()..filename = 'fml/blah_benchmarks.cc',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ any,
+ ));
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Engine labels PRs, no comments if pr is for release branches', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: kReleaseBaseRef,
+ headRef: kReleaseHeadRef,
+ slug: Config.engineSlug,
+ );
+ when(pullRequestsService.listFiles(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.engineSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.engineSlug,
+ issueNumber,
+ <String>['platform-ios'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.engineSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('No labels when only pubspec.yaml changes', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/flutter/pubspec.yaml',
+ PullRequestFile()..filename = 'packages/flutter_tools/pubspec.yaml',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.flutterSlug,
+ issueNumber,
+ <String>['team'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins comments and labels if no tests and no patch info', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.pluginsSlug,
+ issueNumber,
+ <String>['needs tests'],
+ )).called(1);
+ });
+
+ group('Plugins does not comment and label if author is an autoroller account.', () {
+ Set<String> inputs = {
+ 'engine-flutter-autoroll',
+ 'skia-flutter-autoroll',
+ 'dependabot',
+ };
+
+ for (String element in inputs) {
+ test('Plugins does not comment and label if author is $element.', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ login: element,
+ );
+
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.pluginsSlug,
+ issueNumber,
+ <String>['needs tests'],
+ ));
+ });
+ }
+ });
+
+ test('Plugins apply no label or comment if pr is for release branches', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: kReleaseBaseRef,
+ headRef: kReleaseHeadRef,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.pluginsSlug,
+ issueNumber,
+ any,
+ ));
+ });
+
+ test('Plugins comments and labels for code change', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ const String patch = '''
+@@ -128,8 +128,8 @@
+ NSString* foo = "";
+ int bar = 0;
+
+- // Some incorrect code:
+- int baz = 7 / bar;
++ // Better code:
++ int baz = 7 * bar;
+ return baz;
+}
+
+''';
+
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()
+ ..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m'
+ ..additionsCount = 2
+ ..deletionsCount = 2
+ ..changesCount = 4
+ ..patch = patch,
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.pluginsSlug,
+ issueNumber,
+ <String>['needs tests'],
+ )).called(1);
+ });
+
+ test('Plugins comments and labels for code removal with comment addition', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ const String patch = '''
+@@ -128,7 +128,7 @@
+ int foo = 0;
+
+ int bar = 0;
+- int baz = 0;
++ // int baz = 0;
+
+ // More code here:
+
+''';
+
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()
+ ..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m'
+ ..additionsCount = 1
+ ..deletionsCount = 1
+ ..changesCount = 2
+ ..patch = patch,
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.pluginsSlug,
+ issueNumber,
+ <String>['needs tests'],
+ )).called(1);
+ });
+
+ test('Plugins does not comment for comment-only changes', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ const String patch = '''
+@@ -128,7 +128,7 @@
+
+/// Insert interesting comment here.
+///
+-/// More details here, but some of them are wrong.
++/// These are the right details!
+void foo() {
+ int bar = 0;
+ String baz = '';
+''';
+
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()
+ ..filename = 'packages/foo/lib/foo.dart'
+ ..additionsCount = 1
+ ..deletionsCount = 1
+ ..changesCount = 2
+ ..patch = patch,
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if Dart tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
+ PullRequestFile()..filename = 'packages/foo/test/foo_test.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if Android unit tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_android/src/main/Foo.java',
+ PullRequestFile()..filename = 'packages/foo/foo_android/src/test/FooTest.java',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if Android UI tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_android/src/main/Foo.java',
+ PullRequestFile()..filename = 'packages/foo/foo_android/example/android/app/src/androidTest/FooTest.java',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if iOS/macOS unit tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
+ PullRequestFile()..filename = 'packages/foo/foo_ios/example/ios/RunnerTests/FooTests.m',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if iOS/macOS UI tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
+ PullRequestFile()..filename = 'packages/foo/foo_ios/example/ios/RunnerUITests/FooTests.m',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if Windows tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_windows/windows/foo.cpp',
+ PullRequestFile()..filename = 'packages/foo/foo_windows/windows/test/foo_test.cpp',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Plugins does not comment if Linux tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.pluginsSlug,
+ );
+ when(pullRequestsService.listFiles(Config.pluginsSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/foo_linux/linux/foo.cc',
+ PullRequestFile()..filename = 'packages/foo/foo_linux/linux/test/foo_test.cc',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.pluginsSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Packages comments and labels if no tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.packagesSlug,
+ );
+ when(pullRequestsService.listFiles(Config.packagesSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.packagesSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.createComment(
+ Config.packagesSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ )).called(1);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.packagesSlug,
+ issueNumber,
+ <String>['needs tests'],
+ )).called(1);
+ });
+
+ test('Packages do not comment or label if pr is for release branches', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ baseRef: kReleaseBaseRef,
+ headRef: kReleaseHeadRef,
+ slug: Config.packagesSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.packagesSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.packagesSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = 'some other comment',
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.packagesSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+
+ verifyNever(issuesService.addLabelsToIssue(
+ Config.packagesSlug,
+ issueNumber,
+ any,
+ ));
+ });
+
+ test('Packages does not comment if Dart tests', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ slug: Config.packagesSlug,
+ );
+
+ when(pullRequestsService.listFiles(Config.packagesSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
+ PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
+ PullRequestFile()..filename = 'packages/foo/test/foo_test.dart',
+ ]),
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.packagesSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Schedule tasks when pull request is closed and merged', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'closed',
+ number: issueNumber,
+ merged: true,
+ );
+
+ expect(db.values.values.whereType<Commit>().length, 0);
+ await tester.post(webhook);
+ expect(db.values.values.whereType<Commit>().length, 1);
+ });
+
+ test('Does not comment about needing tests on draft pull requests.', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ isDraft: true,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber))
+ .thenAnswer((_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'some_change.dart',
+ ));
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Will not spawn comments if they have already been made.', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ );
+
+ when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<PullRequestFile>.value(
+ PullRequestFile()..filename = 'packages/flutter/blah.dart',
+ ),
+ );
+
+ when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
+ (_) => Stream<IssueComment>.value(
+ IssueComment()..body = config.missingTestsPullRequestMessageValue,
+ ),
+ );
+
+ await tester.post(webhook);
+
+ verify(issuesService.addLabelsToIssue(
+ Config.flutterSlug,
+ issueNumber,
+ <String>['framework'],
+ )).called(1);
+
+ verifyNever(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ argThat(contains(config.missingTestsPullRequestMessageValue)),
+ ));
+ });
+
+ test('Skips labeling or commenting on autorolls', () async {
+ const int issueNumber = 123;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'opened',
+ number: issueNumber,
+ login: 'engine-flutter-autoroll',
+ );
+
+ await tester.post(webhook);
+
+ verifyNever(issuesService.createComment(
+ any,
+ issueNumber,
+ any,
+ ));
+ });
+
+ test('Comments on PR but does not schedule builds for unmergeable PRs', () async {
+ const int issueNumber = 12345;
+ tester.message = generateGithubWebhookMessage(
+ action: 'synchronize',
+ number: issueNumber,
+ // This PR is unmergeable (probably merge conflict)
+ mergeable: false,
+ );
+
+ await tester.post(webhook);
+ verify(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ config.mergeConflictPullRequestMessage,
+ ));
+ });
+
+ test('When synchronized, cancels existing builds and schedules new ones', () async {
+ const int issueNumber = 12345;
+ bool batchRequestCalled = false;
+ Future<BatchResponse> _getBatchResponse() async {
+ batchRequestCalled = true;
+ return BatchResponse(
+ responses: <Response>[
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(999, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(998, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ fakeBuildBucketClient.batchResponse = _getBatchResponse;
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'synchronize',
+ number: issueNumber,
+ );
+
+ final MockRepositoriesService mockRepositoriesService = MockRepositoriesService();
+ when(gitHubClient.repositories).thenReturn(mockRepositoriesService);
+
+ await tester.post(webhook);
+ expect(batchRequestCalled, isTrue);
+ });
+
+ group('BuildBucket', () {
+ const int issueNumber = 123;
+
+ Future<void> _testActions(String action) async {
+ when(issuesService.listLabelsByIssue(any, issueNumber)).thenAnswer((_) {
+ return Stream<IssueLabel>.fromIterable(<IssueLabel>[
+ IssueLabel()..name = 'Random Label',
+ ]);
+ });
+
+ fakeBuildBucketClient.batchResponse = () => Future<BatchResponse>.value(
+ const BatchResponse(
+ responses: <Response>[
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[],
+ ),
+ ),
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[],
+ ),
+ ),
+ ],
+ ),
+ );
+
+ tester.message = generateGithubWebhookMessage(
+ action: action,
+ number: 1,
+ );
+
+ await tester.post(webhook);
+ }
+
+ test('Edited Action works properly', () async {
+ await _testActions('edited');
+ });
+
+ test('Opened Action works properly', () async {
+ await _testActions('opened');
+ });
+
+ test('Ready_for_review Action works properly', () async {
+ await _testActions('ready_for_review');
+ });
+
+ test('Reopened Action works properly', () async {
+ await _testActions('reopened');
+ });
+
+ test('Labeled Action works properly', () async {
+ await _testActions('labeled');
+ });
+
+ test('Synchronize Action works properly', () async {
+ await _testActions('synchronize');
+ });
+
+ test('Comments on PR but does not schedule builds for unmergeable PRs', () async {
+ when(issuesService.listCommentsByIssue(any, any)).thenAnswer((_) => Stream<IssueComment>.value(IssueComment()));
+ tester.message = generateGithubWebhookMessage(
+ action: 'synchronize',
+ number: issueNumber,
+ // This PR is unmergeable (probably merge conflict)
+ mergeable: false,
+ );
+ await tester.post(webhook);
+ verify(issuesService.createComment(
+ Config.flutterSlug,
+ issueNumber,
+ config.mergeConflictPullRequestMessage,
+ ));
+ });
+
+ test('When synchronized, cancels existing builds and schedules new ones', () async {
+ fakeBuildBucketClient.batchResponse = () => Future<BatchResponse>.value(
+ BatchResponse(
+ responses: <Response>[
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(999, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ Response(
+ searchBuilds: SearchBuildsResponse(
+ builds: <Build>[
+ generateBuild(998, name: 'Linux', status: Status.ended),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+
+ tester.message = generateGithubWebhookMessage(
+ action: 'synchronize',
+ number: issueNumber,
+ );
+ final MockRepositoriesService mockRepositoriesService = MockRepositoriesService();
+ when(gitHubClient.repositories).thenReturn(mockRepositoriesService);
+
+ await tester.post(webhook);
+ });
+ });
+ });
+
+ group('github webhook create branch event', () {
+ test('process create branch event', () async {
+ tester.message = generateCreateBranchMessage('flutter-2.12-candidate.4', Config.flutterSlug.fullName);
+ await tester.post(webhook);
+
+ verify(branchService.branchFlutterRecipes('flutter-2.12-candidate.4'));
+ });
+
+ test('do not create recipe branches on non-flutter/flutter branches', () async {
+ tester.message = generateCreateBranchMessage('flutter-2.12-candidate.4', Config.engineSlug.fullName);
+ await tester.post(webhook);
+
+ verifyNever(branchService.branchFlutterRecipes(any));
+ });
+ });
+
+ group('github webhook check_run event', () {
+ test('processes check run event', () async {
+ tester.message = generateCheckRunEvent();
+
+ await tester.post(webhook);
+ });
+
+ test('processes completed check run event', () async {
+ tester.message = generateCheckRunEvent(
+ action: 'completed',
+ numberOfPullRequests: 0,
+ );
+
+ await tester.post(webhook);
+ });
+ });
+}
diff --git a/app_dart/test/request_handlers/github_webhook_test.dart b/app_dart/test/request_handlers/github_webhook_test.dart
index 9ff10c8..cf84d2e 100644
--- a/app_dart/test/request_handlers/github_webhook_test.dart
+++ b/app_dart/test/request_handlers/github_webhook_test.dart
@@ -6,46 +6,23 @@
import 'dart:typed_data';
import 'package:cocoon_service/cocoon_service.dart';
-import 'package:cocoon_service/src/model/appengine/commit.dart';
-import 'package:cocoon_service/src/model/luci/buildbucket.dart';
+import 'package:cocoon_service/protos.dart';
import 'package:cocoon_service/src/request_handling/exceptions.dart';
-import 'package:cocoon_service/src/service/datastore.dart';
import 'package:crypto/crypto.dart';
-import 'package:github/github.dart' hide Branch;
-import 'package:googleapis/bigquery/v2.dart';
-import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../src/datastore/fake_config.dart';
-import '../src/datastore/fake_datastore.dart';
import '../src/request_handling/fake_http.dart';
+import '../src/request_handling/fake_pubsub.dart';
import '../src/request_handling/request_handler_tester.dart';
-import '../src/service/fake_buildbucket.dart';
-import '../src/service/fake_github_service.dart';
-import '../src/service/fake_scheduler.dart';
-import '../src/utilities/entity_generators.dart';
-import '../src/utilities/mocks.dart';
-import '../src/utilities/webhook_generators.dart';
void main() {
late GithubWebhook webhook;
- late FakeBuildBucketClient fakeBuildBucketClient;
late FakeConfig config;
- late FakeDatastoreDB db;
- late FakeGithubService githubService;
late FakeHttpRequest request;
- late FakeScheduler scheduler;
- late MockBranchService branchService;
- late MockGitHub gitHubClient;
- late MockGithubChecksUtil mockGithubChecksUtil;
- late MockGithubChecksService mockGithubChecksService;
- late MockIssuesService issuesService;
- late MockPullRequestsService pullRequestsService;
+ late FakePubSub pubsub;
late RequestHandlerTester tester;
- const String serviceAccountEmail = 'test@test';
- ServiceAccountInfo? serviceAccountInfo;
-
const String keyString = 'not_a_real_key';
String getHmac(Uint8List list, Uint8List key) {
@@ -54,2672 +31,50 @@
}
setUp(() {
- serviceAccountInfo = const ServiceAccountInfo(email: serviceAccountEmail);
request = FakeHttpRequest();
- db = FakeDatastoreDB();
- gitHubClient = MockGitHub();
- githubService = FakeGithubService();
- final MockTabledataResource tabledataResource = MockTabledataResource();
- when(tabledataResource.insertAll(any, any, any, any)).thenAnswer((_) async => TableDataInsertAllResponse());
- config = FakeConfig(
- dbValue: db,
- deviceLabServiceAccountValue: serviceAccountInfo,
- githubService: githubService,
- tabledataResource: tabledataResource,
- githubClient: gitHubClient,
- );
- branchService = MockBranchService();
- issuesService = MockIssuesService();
- when(issuesService.addLabelsToIssue(any, any, any)).thenAnswer((_) async => <IssueLabel>[]);
- when(issuesService.createComment(any, any, any)).thenAnswer((_) async => IssueComment());
- when(issuesService.listCommentsByIssue(any, any))
- .thenAnswer((_) => Stream<IssueComment>.fromIterable(<IssueComment>[IssueComment()]));
- pullRequestsService = MockPullRequestsService();
- when(pullRequestsService.listFiles(Config.flutterSlug, any))
- .thenAnswer((_) => const Stream<PullRequestFile>.empty());
- when(pullRequestsService.edit(any, any, title: anyNamed('title'), state: anyNamed('state'), base: anyNamed('base')))
- .thenAnswer((_) async => PullRequest());
- fakeBuildBucketClient = FakeBuildBucketClient();
- mockGithubChecksUtil = MockGithubChecksUtil();
- scheduler = FakeScheduler(
- config: config,
- buildbucket: fakeBuildBucketClient,
- githubChecksUtil: mockGithubChecksUtil,
- );
tester = RequestHandlerTester(request: request);
- mockGithubChecksService = MockGithubChecksService();
- when(gitHubClient.issues).thenReturn(issuesService);
- when(gitHubClient.pullRequests).thenReturn(pullRequestsService);
- when(mockGithubChecksUtil.createCheckRun(any, any, any, any, output: anyNamed('output'))).thenAnswer((_) async {
- return CheckRun.fromJson(const <String, dynamic>{
- 'id': 1,
- 'started_at': '2020-05-10T02:49:31Z',
- 'check_suite': <String, dynamic>{'id': 2}
- });
- });
+ config = FakeConfig(
+ webhookKeyValue: keyString,
+ );
+ pubsub = FakePubSub();
webhook = GithubWebhook(
config: config,
- datastoreProvider: (_) => DatastoreService(config.db, 5),
- githubChecksService: mockGithubChecksService,
- scheduler: scheduler,
- branchService: branchService,
+ pubsub: pubsub,
);
-
- config.wrongHeadBranchPullRequestMessageValue = 'wrongHeadBranchPullRequestMessage';
- config.wrongBaseBranchPullRequestMessageValue = '{{target_branch}} -> {{default_branch}}';
- config.releaseBranchPullRequestMessageValue = 'releaseBranchPullRequestMessage';
- config.missingTestsPullRequestMessageValue = 'missingTestPullRequestMessage';
- config.githubOAuthTokenValue = 'githubOAuthKey';
- config.webhookKeyValue = keyString;
- config.githubClient = gitHubClient;
- config.deviceLabServiceAccountValue = const ServiceAccountInfo(email: serviceAccountEmail);
- config.rollerAccountsValue = const <String>{
- 'skia-flutter-autoroll',
- 'engine-flutter-autoroll',
- 'dependabot',
- };
});
- group('github webhook pull_request event', () {
- test('Rejects non-POST methods with methodNotAllowed', () async {
- expect(tester.get(webhook), throwsA(isA<MethodNotAllowed>()));
- });
-
- test('Rejects missing headers', () async {
- expect(tester.post(webhook), throwsA(isA<BadRequestException>()));
- });
-
- test('Rejects invalid hmac', () async {
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.headers.set('X-Hub-Signature', 'bar');
- request.body = 'Hello, World!';
- expect(tester.post(webhook), throwsA(isA<Forbidden>()));
- });
-
- test('Rejects malformed unicode', () async {
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.bodyBytes = Uint8List.fromList(<int>[0xc3, 0x28]);
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(request.bodyBytes, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- expect(tester.post(webhook), throwsA(isA<BadRequestException>()));
- });
-
- test('Rejects non-json', () async {
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = 'Hello, World!';
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- expect(tester.post(webhook), throwsA(isA<BadRequestException>()));
- });
-
- test('Closes PR opened from dev', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- headRef: 'dev',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(Config.flutterSlug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(pullRequestsService.edit(
- Config.flutterSlug,
- issueNumber,
- state: 'closed',
- )).called(1);
-
- verify(issuesService.createComment(
- Config.flutterSlug,
- issueNumber,
- argThat(contains(config.wrongHeadBranchPullRequestMessageValue)),
- )).called(1);
- });
-
- test('Acts on opened against dev', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, 'dev');
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(pullRequestsService.edit(
- slug,
- issueNumber,
- base: kDefaultBranchName,
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains('dev -> master')),
- )).called(1);
- });
-
- test('Acts on opened against master when default is main', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- 'master',
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(pullRequestsService.edit(
- slug,
- issueNumber,
- base: 'main',
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains('master -> main')),
- )).called(1);
- });
-
- // We already schedule checks when a draft is opened, don't need to re-test
- // just because it was marked ready for review
- test('Does nothing on ready_for_review', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'ready_for_review',
- issueNumber,
- kDefaultBranchName,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- bool batchRequestCalled = false;
-
- Future<BatchResponse> _getBatchResponse() async {
- batchRequestCalled = true;
- fail('Marking a draft ready for review should not trigger new builds');
- }
-
- fakeBuildBucketClient.batchResponse = _getBatchResponse;
-
- await tester.post(webhook);
-
- expect(batchRequestCalled, isFalse);
- });
-
- test('Triggers builds when opening a draft PR', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- isDraft: true,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- bool batchRequestCalled = false;
-
- Future<BatchResponse> _getBatchResponse() async {
- batchRequestCalled = true;
- return BatchResponse(
- responses: <Response>[
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(999, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(998, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- ],
- );
- }
-
- fakeBuildBucketClient.batchResponse = _getBatchResponse;
-
- await tester.post(webhook);
-
- expect(batchRequestCalled, isTrue);
- });
-
- test('Does nothing against cherry pick PR', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- 'flutter-1.20-candidate.7',
- headRef: 'cherrypicks-flutter-1.20-candidate.7',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(pullRequestsService.edit(
- slug,
- issueNumber,
- base: kDefaultBranchName,
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.wrongBaseBranchPullRequestMessage)),
- ));
- });
-
- group('getLabelsForFrameworkPath', () {
- test('Only the team label is applied to pubspec.yaml', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_tools/pubspec.yaml'), <String>{'team'});
- });
-
- test('Tool label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_tools/hot_reload.dart'), contains('tool'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/fuchsia_remote_debug_protocol/hot_reload.dart'),
- contains('tool'));
- });
-
- test('iOS label applied', () {
- expect(
- GithubWebhook.getLabelsForFrameworkPath('packages/flutter_tools/lib/src/ios/devices.dart'),
- <String>{'platform-ios', 'tool'},
- );
- });
-
- test('Engine label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('bin/internal/engine.version'), contains('engine'));
- });
-
- test('Framework label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/widget.dart'), contains('framework'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_test/lib/tester.dart'), contains('framework'));
- expect(
- GithubWebhook.getLabelsForFrameworkPath('packages/flutter_driver/lib/driver.dart'), contains('framework'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
- contains('framework'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
- contains('framework'));
- });
-
- test('Material label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('foo/bar/baz/material/design.dart'),
- contains('f: material design'));
- });
-
- test('Cupertino label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('foo/bar/baz/cupertino/design.dart'), contains('f: cupertino'));
- });
-
- test('i18n label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_localizations/allo.dart'),
- contains('a: internationalization'));
- });
-
- test('Tests label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_test/lib/tester.dart'), contains('a: tests'));
- expect(
- GithubWebhook.getLabelsForFrameworkPath('packages/flutter_driver/lib/driver.dart'), contains('a: tests'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
- contains('a: tests'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
- contains('a: tests'));
- });
-
- test('a11y label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('foo/bar/baz/semantics/voiceover.dart'),
- contains('a: accessibility'));
- expect(GithubWebhook.getLabelsForFrameworkPath('foo/bar/baz/accessibility/voiceover.dart'),
- contains('a: accessibility'));
- });
-
- test('Examples label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('examples/foo/bar/baz.dart'), contains('d: examples'));
- });
-
- test('API Docs label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('examples/api/bar/baz.dart'),
- <String>['d: examples', 'team', 'd: api docs', 'documentation']);
- });
-
- test('Gallery label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('examples/flutter_gallery/lib/gallery.dart'),
- contains('team: gallery'));
- });
-
- test('Team label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('dev/foo/bar/baz.dart'), contains('team'));
- expect(GithubWebhook.getLabelsForFrameworkPath('examples/foo/bar/baz.dart'), contains('team'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens/lib/flutter_goldens.dart'),
- contains('team'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter_goldens_client/lib/skia_client.dart'),
- contains('team'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/fix_data.yaml'), contains('team'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/test_fixes'), contains('team'));
- expect(
- GithubWebhook.getLabelsForFrameworkPath('packages/flutter/test_fixes/material.expect'), contains('team'));
- });
-
- test('tech-debt label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/fix_data.yaml'), contains('tech-debt'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/test_fixes'), contains('tech-debt'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/test_fixes/material.expect'),
- contains('tech-debt'));
- });
-
- test('gestures label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/gestures'), contains('f: gestures'));
- });
-
- test('focus label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_node.dart'),
- contains('f: focus'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_scope.dart'),
- contains('f: focus'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/focus_manager.dart'),
- contains('f: focus'));
- });
-
- test('routes label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/router.dart'),
- contains('f: routes'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/routes.dart'),
- contains('f: routes'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/navigator.dart'),
- contains('f: routes'));
- });
-
- test('text input label applied', () {
- expect(
- GithubWebhook.getLabelsForFrameworkPath(
- 'dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart'),
- contains('a: text input'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/text_editing_action.dart'),
- contains('a: text input'));
- });
-
- test('animation label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/animation'), contains('a: animation'));
- });
-
- test('scrolling label applied', () {
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/widgets/sliver.dart'),
- contains('f: scrolling'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/material/scrollbar.dart'),
- contains('f: scrolling'));
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/flutter/lib/src/rendering/viewport.dart'),
- contains('f: scrolling'));
- });
-
- test('integration_test label is/isn\'t applied', () {
- // Label does not apply to integration tests outside of the
- // integration_test package.
- expect(
- GithubWebhook.getLabelsForFrameworkPath(
- 'dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart'),
- <String>{'team', 'a: text input'});
- // Label applies to integration_test package
- expect(GithubWebhook.getLabelsForFrameworkPath('packages/integration_test/lib/common.dart'),
- contains('integration_test'));
- });
- });
-
- group('getLabelsForEnginePath', () {
- test('No label is applied to paths with no applicable label', () {
- expect(GithubWebhook.getLabelsForEnginePath('nonsense/path/foo.cc'), isEmpty);
- });
-
- test('platform-android applied for Android embedder', () {
- expect(GithubWebhook.getLabelsForEnginePath('shell/platform/android/RIsForRhubarbPie.java'),
- contains('platform-android'));
- });
-
- test('platform-ios and platform-macos applied for common Darwin code', () {
- expect(GithubWebhook.getLabelsForEnginePath('shell/platform/darwin/common/ThinkDifferent.mm'),
- containsAll(<String>['platform-ios', 'platform-macos']));
- });
-
- test('platform-ios and platform-ios applied for iOS embedder', () {
- expect(
- GithubWebhook.getLabelsForEnginePath('shell/platform/darwin/ios/BackButton.mm'), contains('platform-ios'));
- });
-
- test('platform-macos applied for macOS embedder', () {
- expect(GithubWebhook.getLabelsForEnginePath('shell/platform/darwin/macos/PhysicalEscapeKey.mm'),
- contains('platform-macos'));
- });
-
- test('platform-fuchsia applied for fuchsia embedder', () {
- expect(GithubWebhook.getLabelsForEnginePath('shell/platform/fuchsia/spell_checker.cc'),
- contains('platform-fuchsia'));
- });
-
- test('platform-linux applied for linux embedder', () {
- expect(GithubWebhook.getLabelsForEnginePath('shell/platform/linux/systemd_integration.cc'),
- contains('platform-linux'));
- });
-
- test('platform-windows applied for windows embedder', () {
- expect(
- GithubWebhook.getLabelsForEnginePath('shell/platform/windows/start_menu.cc'), contains('platform-windows'));
- });
-
- test('platform-web applied for web paths', () {
- expect(GithubWebhook.getLabelsForEnginePath('lib/web_ui/shadow_dom.dart'), contains('platform-web'));
- expect(GithubWebhook.getLabelsForEnginePath('web_sdk/'), contains('platform-web'));
- });
- });
-
- test('release PRs are approved', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- // Base is where the PR will merge into
- 'flutter-2.13-candidate.0',
- // Head is the branch from the fork
- headRef: 'master',
- login: 'dart-flutter-releaser',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer((_) => const Stream<PullRequestFile>.empty());
- when(pullRequestsService.createReview(slug, any))
- .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
-
- await tester.post(webhook);
-
- final List<dynamic> reviews = verify(pullRequestsService.createReview(slug, captureAny)).captured;
- expect(reviews.length, 1);
- final CreatePullRequestReview review = reviews.single as CreatePullRequestReview;
- expect(review.event, 'APPROVE');
- });
-
- test('fake release PRs are not approved', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- // Base is where the PR will merge into
- 'master',
- // Head is the branch from the fork
- headRef: 'flutter-2.13-candidate.0',
- login: 'dart-flutter-releaser',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- when(pullRequestsService.listFiles(Config.flutterSlug, issueNumber))
- .thenAnswer((_) => const Stream<PullRequestFile>.empty());
- when(pullRequestsService.createReview(Config.flutterSlug, any))
- .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
-
- await tester.post(webhook);
-
- verifyNever(pullRequestsService.createReview(Config.flutterSlug, captureAny));
- });
-
- test('release PRs are not approved for outsider PRs', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, 'flutter-2.13-candidate.0');
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer((_) => const Stream<PullRequestFile>.empty());
- when(pullRequestsService.createReview(slug, any))
- .thenAnswer((_) async => PullRequestReview(id: 123, user: User()));
-
- await tester.post(webhook);
-
- verifyNever(pullRequestsService.createReview(slug, any));
- });
-
- test('Framework labels PRs, comment if no tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
- });
-
- group("Auto-roller accounts do not label Framework PR with test label or comment.", () {
- Set<String> inputs = {
- 'skia-flutter-autoroll',
- 'dependabot',
- };
-
- for (String element in inputs) {
- test('Framework does not label PR with no tests label if author is $element', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName, login: element);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
- }
- });
-
- test('Framework does not label PR with no tests label if author is engine-flutter-autoroll', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body =
- generatePullRequestEvent('opened', issueNumber, kDefaultBranchName, login: 'engine-flutter-autoroll');
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels PRs, comment if no tests including hit_test.dart file', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()
- ..additionsCount = 10
- ..changesCount = 10
- ..filename = 'packages/flutter/lib/src/gestures/hit_test.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework', 'f: gestures'],
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
- });
-
- test('Framework labels PRs, no dart files', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.md',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- any,
- ));
- });
-
- test('Framework labels PRs, no comment if tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/flutter/semantics_test.dart',
- PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
- PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
- PullRequestFile()..filename = 'dev/bots/test.dart',
- PullRequestFile()..filename = 'dev/devicelab/bin/tasks/analyzer_benchmark.dart',
- PullRequestFile()..filename = 'bin/internal/engine.version',
- PullRequestFile()..filename = 'packages/flutter/lib/src/cupertino/blah.dart',
- PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>[
- 'framework',
- 'a: accessibility',
- 'tool',
- 'a: tests',
- 'd: examples',
- 'team',
- 'team: gallery',
- 'engine',
- 'f: cupertino',
- 'f: material design',
- 'a: internationalization',
- ],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels dart fix PRs, no comment if tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/flutter/test_fixes/material.dart',
- PullRequestFile()..filename = 'packages/flutter/test_fixes/material.expect',
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['team', 'tech-debt', 'framework', 'f: material design'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels bot PR, no comment', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName, login: 'fluttergithubbot');
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['tool', 'framework', 'a: tests', 'team', 'tech-debt', 'team: flakes'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels deletion only PR, no test request', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()
- ..filename = 'packages/flutter/blah.dart'
- ..deletionsCount = 20
- ..additionsCount = 0
- ..changesCount = 20,
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- // The PR here is only deleting code, so no test comment.
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('PR with additions and deletions is commented and labeled', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()
- ..filename = 'packages/flutter/blah.dart'
- ..deletionsCount = 20
- ..additionsCount = 1
- ..changesCount = 21,
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
- });
-
- test('Framework no comment if code has only devicelab test', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/flutter_tools/lib/src/ios/devices.dart',
- PullRequestFile()..filename = 'dev/devicelab/lib/tasks/plugin_tests.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no comment if only dev bots or devicelab changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'dev/bots/test.dart',
- PullRequestFile()..filename = 'dev/devicelab/bin/tasks/analyzer_benchmark.dart',
- PullRequestFile()..filename = 'dev/devicelab/lib/tasks/plugin_tests.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no test comment if Objective-C test changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- // Example of real behavior code change.
- PullRequestFile()
- ..filename = 'packages/flutter_tools/templates/app_shared/macos.tmpl/Runner/Base.lproj/MainMenu.xib',
- // Example of Objective-C test.
- PullRequestFile()..filename = 'dev/integration_tests/flutter_gallery/macos/RunnerTests/RunnerTests.m',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no comment if only AUTHORS changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'AUTHORS',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no comment if only ci.yaml and cirrus.yml changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = '.ci.yaml',
- PullRequestFile()..filename = '.cirrus.yml',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no comment if only CODEOWNERS changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'CODEOWNERS',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework no comment if only comments changed', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- const String patch = '''
-@@ -128,7 +128,7 @@
-
-/// Insert interesting comment here.
-///
--/// More details here, but some of them are wrong.
-+/// These are the right details!
-void foo() {
- int bar = 0;
- String baz = '';
-''';
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()
- ..filename = 'packages/foo/lib/foo.dart'
- ..additionsCount = 1
- ..deletionsCount = 1
- ..changesCount = 2
- ..patch = patch,
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels PRs, no comment if tests (dev/bots/test.dart)', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'dev/bots/test.dart',
- PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
- PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
- PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels PRs, no comment if tests (dev/bots/analyze.dart)', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'dev/bots/analyze.dart',
- PullRequestFile()..filename = 'packages/flutter_tools/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_driver/blah.dart',
- PullRequestFile()..filename = 'examples/flutter_gallery/blah.dart',
- PullRequestFile()..filename = 'packages/flutter/lib/src/material/blah.dart',
- PullRequestFile()..filename = 'packages/flutter_localizations/blah.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Framework labels PRs, apply label but no comment when rolling engine version', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kReleaseBaseRef,
- headRef: kReleaseHeadRef,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()
- ..filename = 'bin/internal/engine.version'
- ..deletionsCount = 20
- ..additionsCount = 1
- ..changesCount = 21,
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['engine'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Engine labels PRs, comment and labels if no tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['platform-ios'],
- )).called(1);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- )).called(1);
- });
-
- group("Auto-roller accounts do not label Engine PR with test label or comment.", () {
- Set<String> inputs = {
- 'engine-flutter-autoroll',
- 'dependabot',
- };
-
- for (String element in inputs) {
- test('Engine does not label PR for no tests if author is $element', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName,
- repoName: 'engine', repoFullName: 'flutter/engine', login: element);
-
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['platform-ios'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- ));
- });
- }
- });
-
- test('Engine does not label PR for no tests if author is skia-flutter-autoroll', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName,
- repoName: 'engine', repoFullName: 'flutter/engine', login: 'skia-flutter-autoroll');
-
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['platform-ios'],
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- ));
- });
-
- test('Engine labels PRs, no code files', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- 'main',
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'DEPS',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- any,
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- any,
- ));
- });
-
- test('Engine labels PRs, no comment if Java tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'shell/platform/android/io/flutter/Blah.java',
- PullRequestFile()..filename = 'shell/platform/android/test/io/flutter/BlahTest.java',
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>[
- 'platform-android',
- ],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Engine labels PRs, no comment if cc tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'fml/blah.cc',
- PullRequestFile()..filename = 'fml/blah_unittests.cc',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- any,
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Engine labels PRs, no comment if cc becnhmarks', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'fml/blah.cc',
- PullRequestFile()..filename = 'fml/blah_benchmarks.cc',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- any,
- ));
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Engine labels PRs, no comments if pr is for release branches', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kReleaseBaseRef,
- headRef: kReleaseHeadRef,
- repoName: 'engine',
- repoFullName: 'flutter/engine',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'engine');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'shell/platform/darwin/ios/framework/Source/boost.mm',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['platform-ios'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('No labels when only pubspec.yaml changes', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/flutter/pubspec.yaml',
- PullRequestFile()..filename = 'packages/flutter_tools/pubspec.yaml',
- ]),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['team'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins comments and labels if no tests and no patch info', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- )).called(1);
- });
-
- group('Plugins does not comment and label if author is an autoroller account.', () {
- Set<String> inputs = {
- 'engine-flutter-autoroll',
- 'skia-flutter-autoroll',
- 'dependabot',
- };
-
- for (String element in inputs) {
- test('Plugins does not comment and label if author is $element.', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- login: element,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- ));
- });
- }
- });
-
- test('Plugins apply no label or comment if pr is for release branches', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kReleaseBaseRef,
- headRef: kReleaseHeadRef,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- any,
- ));
- });
-
- test('Plugins comments and labels for code change', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- const String patch = '''
-@@ -128,8 +128,8 @@
- NSString* foo = "";
- int bar = 0;
-
-- // Some incorrect code:
-- int baz = 7 / bar;
-+ // Better code:
-+ int baz = 7 * bar;
- return baz;
-}
-
-''';
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()
- ..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m'
- ..additionsCount = 2
- ..deletionsCount = 2
- ..changesCount = 4
- ..patch = patch,
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- )).called(1);
- });
-
- test('Plugins comments and labels for code removal with comment addition', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- const String patch = '''
-@@ -128,7 +128,7 @@
- int foo = 0;
-
- int bar = 0;
-- int baz = 0;
-+ // int baz = 0;
-
- // More code here:
-
-''';
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()
- ..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m'
- ..additionsCount = 1
- ..deletionsCount = 1
- ..changesCount = 2
- ..patch = patch,
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- )).called(1);
- });
-
- test('Plugins does not comment for comment-only changes', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- const String patch = '''
-@@ -128,7 +128,7 @@
-
-/// Insert interesting comment here.
-///
--/// More details here, but some of them are wrong.
-+/// These are the right details!
-void foo() {
- int bar = 0;
- String baz = '';
-''';
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()
- ..filename = 'packages/foo/lib/foo.dart'
- ..additionsCount = 1
- ..deletionsCount = 1
- ..changesCount = 2
- ..patch = patch,
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if Dart tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
- PullRequestFile()..filename = 'packages/foo/test/foo_test.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if Android unit tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_android/src/main/Foo.java',
- PullRequestFile()..filename = 'packages/foo/foo_android/src/test/FooTest.java',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if Android UI tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_android/src/main/Foo.java',
- PullRequestFile()..filename = 'packages/foo/foo_android/example/android/app/src/androidTest/FooTest.java',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if iOS/macOS unit tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
- PullRequestFile()..filename = 'packages/foo/foo_ios/example/ios/RunnerTests/FooTests.m',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if iOS/macOS UI tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_ios/ios/Classes/Foo.m',
- PullRequestFile()..filename = 'packages/foo/foo_ios/example/ios/RunnerUITests/FooTests.m',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if Windows tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_windows/windows/foo.cpp',
- PullRequestFile()..filename = 'packages/foo/foo_windows/windows/test/foo_test.cpp',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Plugins does not comment if Linux tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'plugins',
- repoFullName: 'flutter/plugins',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'plugins');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/foo_linux/linux/foo.cc',
- PullRequestFile()..filename = 'packages/foo/foo_linux/linux/test/foo_test.cc',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Packages comments and labels if no tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'packages',
- repoFullName: 'flutter/packages',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'packages');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- )).called(1);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['needs tests'],
- )).called(1);
- });
-
- test('Packages do not comment or label if pr is for release branches', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kReleaseBaseRef,
- headRef: kReleaseHeadRef,
- repoName: 'packages',
- repoFullName: 'flutter/packages',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'packages');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = 'some other comment',
- ),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
-
- verifyNever(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- any,
- ));
- });
-
- test('Packages does not comment if Dart tests', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- repoName: 'packages',
- repoFullName: 'flutter/packages',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'packages');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.fromIterable(<PullRequestFile>[
- PullRequestFile()..filename = 'packages/foo/lib/foo.dart',
- PullRequestFile()..filename = 'packages/foo/test/foo_test.dart',
- ]),
- );
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Schedule tasks when pull request is closed and merged', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('closed', issueNumber, kDefaultBranchName, merged: true);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- expect(db.values.values.whereType<Commit>().length, 0);
- await tester.post(webhook);
- expect(db.values.values.whereType<Commit>().length, 1);
- });
-
- test('Does not comment about needing tests on draft pull requests.', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- isDraft: true,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer((_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'some_change.dart',
- ));
-
- await tester.post(webhook);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Will not spawn comments if they have already been made.', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent('opened', issueNumber, kDefaultBranchName);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- when(pullRequestsService.listFiles(slug, issueNumber)).thenAnswer(
- (_) => Stream<PullRequestFile>.value(
- PullRequestFile()..filename = 'packages/flutter/blah.dart',
- ),
- );
-
- when(issuesService.listCommentsByIssue(slug, issueNumber)).thenAnswer(
- (_) => Stream<IssueComment>.value(
- IssueComment()..body = config.missingTestsPullRequestMessageValue,
- ),
- );
-
- await tester.post(webhook);
-
- verify(issuesService.addLabelsToIssue(
- slug,
- issueNumber,
- <String>['framework'],
- )).called(1);
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- argThat(contains(config.missingTestsPullRequestMessageValue)),
- ));
- });
-
- test('Skips labeling or commenting on autorolls', () async {
- const int issueNumber = 123;
- request.headers.set('X-GitHub-Event', 'pull_request');
- request.body = generatePullRequestEvent(
- 'opened',
- issueNumber,
- kDefaultBranchName,
- login: 'engine-flutter-autoroll',
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- await tester.post(webhook);
-
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- verifyNever(issuesService.createComment(
- slug,
- issueNumber,
- any,
- ));
- });
-
- test('Comments on PR but does not schedule builds for unmergeable PRs', () async {
- const int issueNumber = 12345;
- request.body = generatePullRequestEvent(
- 'synchronize',
- issueNumber,
- kDefaultBranchName,
- includeCqLabel: true,
- // This PR is unmergeable (probably merge conflict)
- isMergeable: false,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- request.headers.set('X-GitHub-Event', 'pull_request');
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final RepositorySlug slug = RepositorySlug('flutter', 'flutter');
-
- await tester.post(webhook);
- verify(issuesService.createComment(slug, issueNumber, config.mergeConflictPullRequestMessage));
- });
-
- test('When synchronized, cancels existing builds and schedules new ones', () async {
- const int issueNumber = 12345;
- bool batchRequestCalled = false;
- Future<BatchResponse> _getBatchResponse() async {
- batchRequestCalled = true;
- return BatchResponse(
- responses: <Response>[
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(999, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(998, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- ],
- );
- }
-
- fakeBuildBucketClient.batchResponse = _getBatchResponse;
-
- request.body = generatePullRequestEvent('synchronize', issueNumber, kDefaultBranchName, includeCqLabel: true);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- request.headers.set('X-GitHub-Event', 'pull_request');
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final MockRepositoriesService mockRepositoriesService = MockRepositoriesService();
- when(gitHubClient.repositories).thenReturn(mockRepositoriesService);
-
- await tester.post(webhook);
- expect(batchRequestCalled, isTrue);
- });
-
- group('BuildBucket', () {
- const int issueNumber = 123;
-
- setUp(() async {
- request.headers.set('X-GitHub-Event', 'pull_request');
- });
-
- Future<void> _testActions(String action) async {
- when(issuesService.listLabelsByIssue(any, issueNumber)).thenAnswer((_) {
- return Stream<IssueLabel>.fromIterable(<IssueLabel>[
- IssueLabel()..name = 'Random Label',
- ]);
- });
-
- fakeBuildBucketClient.batchResponse = () => Future<BatchResponse>.value(
- const BatchResponse(
- responses: <Response>[
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[],
- ),
- ),
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[],
- ),
- ),
- ],
- ),
- );
-
- request.body = generatePullRequestEvent(action, 1, 'master');
-
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- await tester.post(webhook);
- }
-
- test('Edited Action works properly', () async {
- await _testActions('edited');
- });
-
- test('Opened Action works properly', () async {
- await _testActions('opened');
- });
-
- test('Ready_for_review Action works properly', () async {
- await _testActions('ready_for_review');
- });
-
- test('Reopened Action works properly', () async {
- await _testActions('reopened');
- });
-
- test('Labeled Action works properly', () async {
- await _testActions('labeled');
- });
-
- test('Synchronize Action works properly', () async {
- await _testActions('synchronize');
- });
-
- test('Comments on PR but does not schedule builds for unmergeable PRs', () async {
- when(issuesService.listCommentsByIssue(any, any)).thenAnswer((_) => Stream<IssueComment>.value(IssueComment()));
- request.body = generatePullRequestEvent(
- 'synchronize',
- issueNumber,
- kDefaultBranchName,
- includeCqLabel: true,
- // This PR is unmergeable (probably merge conflict)
- isMergeable: false,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
-
- await tester.post(webhook);
- verify(issuesService.createComment(Config.flutterSlug, issueNumber, config.mergeConflictPullRequestMessage));
- });
-
- test('When synchronized, cancels existing builds and schedules new ones', () async {
- fakeBuildBucketClient.batchResponse = () => Future<BatchResponse>.value(
- BatchResponse(
- responses: <Response>[
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(999, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- Response(
- searchBuilds: SearchBuildsResponse(
- builds: <Build>[
- generateBuild(998, name: 'Linux', status: Status.ended),
- ],
- ),
- ),
- ],
- ),
- );
-
- request.body = generatePullRequestEvent('synchronize', issueNumber, kDefaultBranchName, includeCqLabel: true);
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- final MockRepositoriesService mockRepositoriesService = MockRepositoriesService();
- when(gitHubClient.repositories).thenReturn(mockRepositoriesService);
-
- await tester.post(webhook);
- });
- });
+ test('Rejects non-POST methods with methodNotAllowed', () async {
+ expect(tester.get(webhook), throwsA(isA<MethodNotAllowed>()));
+ expect(pubsub.messages, isEmpty);
});
- group('github webhook create branch event', () {
- test('process create branch event', () async {
- request.headers.set('X-GitHub-Event', 'create');
- request.body =
- jsonEncode(generateCreateBranchEvent('flutter-2.12-candidate.4', Config.flutterSlug.fullName).toJson());
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- await tester.post(webhook);
-
- verify(branchService.branchFlutterRecipes('flutter-2.12-candidate.4'));
- });
-
- test('do not create recipe branches on non-flutter/flutter branches', () async {
- request.headers.set('X-GitHub-Event', 'create');
- request.body =
- jsonEncode(generateCreateBranchEvent('flutter-2.12-candidate.4', Config.engineSlug.fullName).toJson());
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- await tester.post(webhook);
-
- verifyNever(branchService.branchFlutterRecipes(any));
- });
+ test('Rejects missing headers', () async {
+ expect(tester.post(webhook), throwsA(isA<BadRequestException>()));
+ expect(pubsub.messages, isEmpty);
});
- group('github webhook check_run event', () {
- setUp(() {
- request.headers.set('X-GitHub-Event', 'check_run');
- });
+ test('Rejects invalid hmac', () async {
+ request.headers.set('X-GitHub-Event', 'pull_request');
+ request.headers.set('X-Hub-Signature', 'bar');
+ request.body = 'Hello, World!';
+ expect(tester.post(webhook), throwsA(isA<Forbidden>()));
+ expect(pubsub.messages, isEmpty);
+ });
- test('processes check run event', () async {
- request.body = generateCheckRunEvent();
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- await tester.post(webhook);
- });
+ test('Publishes message', () async {
+ request.headers.set('X-GitHub-Event', 'pull_request');
+ request.body = '{}';
+ final Uint8List body = utf8.encode(request.body!) as Uint8List;
+ final Uint8List key = utf8.encode(keyString) as Uint8List;
+ final String hmac = getHmac(body, key);
+ request.headers.set('X-Hub-Signature', 'sha1=$hmac');
+ await tester.post(webhook);
- test('processes completed check run event', () async {
- request.body = generateCheckRunEvent(
- action: 'completed',
- numberOfPullRequests: 0,
- );
- final Uint8List body = utf8.encode(request.body!) as Uint8List;
- final Uint8List key = utf8.encode(keyString) as Uint8List;
- final String hmac = getHmac(body, key);
- request.headers.set('X-Hub-Signature', 'sha1=$hmac');
- await tester.post(webhook);
- });
+ expect(pubsub.messages, hasLength(1));
+ final GithubWebhookMessage message = pubsub.messages.single as GithubWebhookMessage;
+ expect(message.event, 'pull_request');
+ expect(message.payload, '{}');
});
}
diff --git a/app_dart/test/src/utilities/mocks.mocks.dart b/app_dart/test/src/utilities/mocks.mocks.dart
index c40b068..0ff5fb3 100644
--- a/app_dart/test/src/utilities/mocks.mocks.dart
+++ b/app_dart/test/src/utilities/mocks.mocks.dart
@@ -1,7 +1,8 @@
-// Mocks generated by Mockito 5.2.0 from annotations
+// Mocks generated by Mockito 5.3.0 from annotations
// in cocoon_service/test/src/utilities/mocks.dart.
// Do not manually edit this file.
+// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i17;
import 'dart:convert' as _i16;
import 'dart:io' as _i15;
@@ -55,200 +56,395 @@
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
+// ignore_for_file: subtype_of_sealed_class
-class _FakeClient_0 extends _i1.Fake implements _i2.Client {}
+class _FakeClient_0 extends _i1.SmartFake implements _i2.Client {
+ _FakeClient_0(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeConfig_1 extends _i1.Fake implements _i3.Config {}
+class _FakeConfig_1 extends _i1.SmartFake implements _i3.Config {
+ _FakeConfig_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeAccessToken_2 extends _i1.Fake implements _i4.AccessToken {}
+class _FakeAccessToken_2 extends _i1.SmartFake implements _i4.AccessToken {
+ _FakeAccessToken_2(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeAccessClientProvider_3 extends _i1.Fake implements _i5.AccessClientProvider {}
+class _FakeAccessClientProvider_3 extends _i1.SmartFake implements _i5.AccessClientProvider {
+ _FakeAccessClientProvider_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeTabledataResource_4 extends _i1.Fake implements _i6.TabledataResource {}
+class _FakeTabledataResource_4 extends _i1.SmartFake implements _i6.TabledataResource {
+ _FakeTabledataResource_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeJobsResource_5 extends _i1.Fake implements _i6.JobsResource {}
+class _FakeJobsResource_5 extends _i1.SmartFake implements _i6.JobsResource {
+ _FakeJobsResource_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGerritService_6 extends _i1.Fake implements _i7.GerritService {}
+class _FakeGerritService_6 extends _i1.SmartFake implements _i7.GerritService {
+ _FakeGerritService_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRetryOptions_7 extends _i1.Fake implements _i8.RetryOptions {}
+class _FakeRetryOptions_7 extends _i1.SmartFake implements _i8.RetryOptions {
+ _FakeRetryOptions_7(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeBuild_8 extends _i1.Fake implements _i9.Build {}
+class _FakeBuild_8 extends _i1.SmartFake implements _i9.Build {
+ _FakeBuild_8(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeSearchBuildsResponse_9 extends _i1.Fake implements _i9.SearchBuildsResponse {}
+class _FakeSearchBuildsResponse_9 extends _i1.SmartFake implements _i9.SearchBuildsResponse {
+ _FakeSearchBuildsResponse_9(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeBatchResponse_10 extends _i1.Fake implements _i9.BatchResponse {}
+class _FakeBatchResponse_10 extends _i1.SmartFake implements _i9.BatchResponse {
+ _FakeBatchResponse_10(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeListBuildersResponse_11 extends _i1.Fake implements _i9.ListBuildersResponse {}
+class _FakeListBuildersResponse_11 extends _i1.SmartFake implements _i9.ListBuildersResponse {
+ _FakeListBuildersResponse_11(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitHub_12 extends _i1.Fake implements _i10.GitHub {}
+class _FakeGitHub_12 extends _i1.SmartFake implements _i10.GitHub {
+ _FakeGitHub_12(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeIssue_13 extends _i1.Fake implements _i10.Issue {}
+class _FakeIssue_13 extends _i1.SmartFake implements _i10.Issue {
+ _FakeIssue_13(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeIssueComment_14 extends _i1.Fake implements _i10.IssueComment {}
+class _FakeIssueComment_14 extends _i1.SmartFake implements _i10.IssueComment {
+ _FakeIssueComment_14(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeIssueLabel_15 extends _i1.Fake implements _i10.IssueLabel {}
+class _FakeIssueLabel_15 extends _i1.SmartFake implements _i10.IssueLabel {
+ _FakeIssueLabel_15(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeMilestone_16 extends _i1.Fake implements _i10.Milestone {}
+class _FakeMilestone_16 extends _i1.SmartFake implements _i10.Milestone {
+ _FakeMilestone_16(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGithubChecksUtil_17 extends _i1.Fake implements _i11.GithubChecksUtil {}
+class _FakeGithubChecksUtil_17 extends _i1.SmartFake implements _i11.GithubChecksUtil {
+ _FakeGithubChecksUtil_17(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCheckRunConclusion_18 extends _i1.Fake implements _i10.CheckRunConclusion {}
+class _FakeCheckRunConclusion_18 extends _i1.SmartFake implements _i10.CheckRunConclusion {
+ _FakeCheckRunConclusion_18(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCheckRunStatus_19 extends _i1.Fake implements _i10.CheckRunStatus {}
+class _FakeCheckRunStatus_19 extends _i1.SmartFake implements _i10.CheckRunStatus {
+ _FakeCheckRunStatus_19(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCheckSuite_20 extends _i1.Fake implements _i10.CheckSuite {}
+class _FakeCheckSuite_20 extends _i1.SmartFake implements _i10.CheckSuite {
+ _FakeCheckSuite_20(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCheckRun_21 extends _i1.Fake implements _i10.CheckRun {}
+class _FakeCheckRun_21 extends _i1.SmartFake implements _i10.CheckRun {
+ _FakeCheckRun_21(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePullRequest_22 extends _i1.Fake implements _i10.PullRequest {}
+class _FakePullRequest_22 extends _i1.SmartFake implements _i10.PullRequest {
+ _FakePullRequest_22(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitReference_23 extends _i1.Fake implements _i10.GitReference {}
+class _FakeGitReference_23 extends _i1.SmartFake implements _i10.GitReference {
+ _FakeGitReference_23(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRateLimit_24 extends _i1.Fake implements _i10.RateLimit {}
+class _FakeRateLimit_24 extends _i1.SmartFake implements _i10.RateLimit {
+ _FakeRateLimit_24(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitBlob_25 extends _i1.Fake implements _i10.GitBlob {}
+class _FakeGitBlob_25 extends _i1.SmartFake implements _i10.GitBlob {
+ _FakeGitBlob_25(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitCommit_26 extends _i1.Fake implements _i10.GitCommit {}
+class _FakeGitCommit_26 extends _i1.SmartFake implements _i10.GitCommit {
+ _FakeGitCommit_26(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitTag_27 extends _i1.Fake implements _i10.GitTag {}
+class _FakeGitTag_27 extends _i1.SmartFake implements _i10.GitTag {
+ _FakeGitTag_27(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitTree_28 extends _i1.Fake implements _i10.GitTree {}
+class _FakeGitTree_28 extends _i1.SmartFake implements _i10.GitTree {
+ _FakeGitTree_28(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeDefaultPolicies_29 extends _i1.Fake implements _i12.DefaultPolicies {}
+class _FakeDefaultPolicies_29 extends _i1.SmartFake implements _i12.DefaultPolicies {
+ _FakeDefaultPolicies_29(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeLink_30 extends _i1.Fake implements _i12.Link {}
+class _FakeLink_30 extends _i1.SmartFake implements _i12.Link {
+ _FakeLink_30(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGraphQLCache_31 extends _i1.Fake implements _i13.GraphQLCache {}
+class _FakeGraphQLCache_31 extends _i1.SmartFake implements _i13.GraphQLCache {
+ _FakeGraphQLCache_31(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeQueryManager_32 extends _i1.Fake implements _i12.QueryManager {}
+class _FakeQueryManager_32 extends _i1.SmartFake implements _i12.QueryManager {
+ _FakeQueryManager_32(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGraphQLClient_33 extends _i1.Fake implements _i14.GraphQLClient {}
+class _FakeGraphQLClient_33 extends _i1.SmartFake implements _i14.GraphQLClient {
+ _FakeGraphQLClient_33(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeObservableQuery_34<TParsed> extends _i1.Fake implements _i12.ObservableQuery<TParsed> {}
+class _FakeObservableQuery_34<TParsed> extends _i1.SmartFake implements _i12.ObservableQuery<TParsed> {
+ _FakeObservableQuery_34(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeQueryResult_35<TParsed extends Object?> extends _i1.Fake implements _i12.QueryResult<TParsed> {}
+class _FakeQueryResult_35<TParsed extends Object?> extends _i1.SmartFake implements _i12.QueryResult<TParsed> {
+ _FakeQueryResult_35(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeDuration_36 extends _i1.Fake implements Duration {}
+class _FakeDuration_36 extends _i1.SmartFake implements Duration {
+ _FakeDuration_36(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeHttpClientRequest_37 extends _i1.Fake implements _i15.HttpClientRequest {}
+class _FakeHttpClientRequest_37 extends _i1.SmartFake implements _i15.HttpClientRequest {
+ _FakeHttpClientRequest_37(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeUri_38 extends _i1.Fake implements Uri {}
+class _FakeUri_38 extends _i1.SmartFake implements Uri {
+ _FakeUri_38(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeHttpHeaders_39 extends _i1.Fake implements _i15.HttpHeaders {}
+class _FakeHttpHeaders_39 extends _i1.SmartFake implements _i15.HttpHeaders {
+ _FakeHttpHeaders_39(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeHttpClientResponse_40 extends _i1.Fake implements _i15.HttpClientResponse {}
+class _FakeHttpClientResponse_40 extends _i1.SmartFake implements _i15.HttpClientResponse {
+ _FakeHttpClientResponse_40(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeEncoding_41 extends _i1.Fake implements _i16.Encoding {}
+class _FakeEncoding_41 extends _i1.SmartFake implements _i16.Encoding {
+ _FakeEncoding_41(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeSocket_42 extends _i1.Fake implements _i15.Socket {}
+class _FakeSocket_42 extends _i1.SmartFake implements _i15.Socket {
+ _FakeSocket_42(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeStreamSubscription_43<T> extends _i1.Fake implements _i17.StreamSubscription<T> {}
+class _FakeStreamSubscription_43<T> extends _i1.SmartFake implements _i17.StreamSubscription<T> {
+ _FakeStreamSubscription_43(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeJobCancelResponse_44 extends _i1.Fake implements _i6.JobCancelResponse {}
+class _FakeJobCancelResponse_44 extends _i1.SmartFake implements _i6.JobCancelResponse {
+ _FakeJobCancelResponse_44(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeJob_45 extends _i1.Fake implements _i6.Job {}
+class _FakeJob_45 extends _i1.SmartFake implements _i6.Job {
+ _FakeJob_45(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGetQueryResultsResponse_46 extends _i1.Fake implements _i6.GetQueryResultsResponse {}
+class _FakeGetQueryResultsResponse_46 extends _i1.SmartFake implements _i6.GetQueryResultsResponse {
+ _FakeGetQueryResultsResponse_46(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeJobList_47 extends _i1.Fake implements _i6.JobList {}
+class _FakeJobList_47 extends _i1.SmartFake implements _i6.JobList {
+ _FakeJobList_47(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeQueryResponse_48 extends _i1.Fake implements _i6.QueryResponse {}
+class _FakeQueryResponse_48 extends _i1.SmartFake implements _i6.QueryResponse {
+ _FakeQueryResponse_48(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeBuildBucketClient_49 extends _i1.Fake implements _i18.BuildBucketClient {}
+class _FakeBuildBucketClient_49 extends _i1.SmartFake implements _i18.BuildBucketClient {
+ _FakeBuildBucketClient_49(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePubSub_50 extends _i1.Fake implements _i19.PubSub {}
+class _FakePubSub_50 extends _i1.SmartFake implements _i19.PubSub {
+ _FakePubSub_50(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeClientContext_51 extends _i1.Fake implements _i20.ClientContext {}
+class _FakeClientContext_51 extends _i1.SmartFake implements _i20.ClientContext {
+ _FakeClientContext_51(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeProcess_52 extends _i1.Fake implements _i15.Process {}
+class _FakeProcess_52 extends _i1.SmartFake implements _i15.Process {
+ _FakeProcess_52(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeProcessResult_53 extends _i1.Fake implements _i15.ProcessResult {}
+class _FakeProcessResult_53 extends _i1.SmartFake implements _i15.ProcessResult {
+ _FakeProcessResult_53(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePullRequestMerge_54 extends _i1.Fake implements _i10.PullRequestMerge {}
+class _FakePullRequestMerge_54 extends _i1.SmartFake implements _i10.PullRequestMerge {
+ _FakePullRequestMerge_54(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePullRequestComment_55 extends _i1.Fake implements _i10.PullRequestComment {}
+class _FakePullRequestComment_55 extends _i1.SmartFake implements _i10.PullRequestComment {
+ _FakePullRequestComment_55(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePullRequestReview_56 extends _i1.Fake implements _i10.PullRequestReview {}
+class _FakePullRequestReview_56 extends _i1.SmartFake implements _i10.PullRequestReview {
+ _FakePullRequestReview_56(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepository_57 extends _i1.Fake implements _i10.Repository {}
+class _FakeRepository_57 extends _i1.SmartFake implements _i10.Repository {
+ _FakeRepository_57(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeLicenseDetails_58 extends _i1.Fake implements _i10.LicenseDetails {}
+class _FakeLicenseDetails_58 extends _i1.SmartFake implements _i10.LicenseDetails {
+ _FakeLicenseDetails_58(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeLanguageBreakdown_59 extends _i1.Fake implements _i10.LanguageBreakdown {}
+class _FakeLanguageBreakdown_59 extends _i1.SmartFake implements _i10.LanguageBreakdown {
+ _FakeLanguageBreakdown_59(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeBranch_60 extends _i1.Fake implements _i10.Branch {}
+class _FakeBranch_60 extends _i1.SmartFake implements _i10.Branch {
+ _FakeBranch_60(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCommitComment_61 extends _i1.Fake implements _i10.CommitComment {}
+class _FakeCommitComment_61 extends _i1.SmartFake implements _i10.CommitComment {
+ _FakeCommitComment_61(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepositoryCommit_62 extends _i1.Fake implements _i10.RepositoryCommit {}
+class _FakeRepositoryCommit_62 extends _i1.SmartFake implements _i10.RepositoryCommit {
+ _FakeRepositoryCommit_62(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitHubComparison_63 extends _i1.Fake implements _i10.GitHubComparison {}
+class _FakeGitHubComparison_63 extends _i1.SmartFake implements _i10.GitHubComparison {
+ _FakeGitHubComparison_63(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitHubFile_64 extends _i1.Fake implements _i10.GitHubFile {}
+class _FakeGitHubFile_64 extends _i1.SmartFake implements _i10.GitHubFile {
+ _FakeGitHubFile_64(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepositoryContents_65 extends _i1.Fake implements _i10.RepositoryContents {}
+class _FakeRepositoryContents_65 extends _i1.SmartFake implements _i10.RepositoryContents {
+ _FakeRepositoryContents_65(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeContentCreation_66 extends _i1.Fake implements _i10.ContentCreation {}
+class _FakeContentCreation_66 extends _i1.SmartFake implements _i10.ContentCreation {
+ _FakeContentCreation_66(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeHook_67 extends _i1.Fake implements _i10.Hook {}
+class _FakeHook_67 extends _i1.SmartFake implements _i10.Hook {
+ _FakeHook_67(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePublicKey_68 extends _i1.Fake implements _i10.PublicKey {}
+class _FakePublicKey_68 extends _i1.SmartFake implements _i10.PublicKey {
+ _FakePublicKey_68(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepositoryPages_69 extends _i1.Fake implements _i10.RepositoryPages {}
+class _FakeRepositoryPages_69 extends _i1.SmartFake implements _i10.RepositoryPages {
+ _FakeRepositoryPages_69(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePageBuild_70 extends _i1.Fake implements _i10.PageBuild {}
+class _FakePageBuild_70 extends _i1.SmartFake implements _i10.PageBuild {
+ _FakePageBuild_70(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRelease_71 extends _i1.Fake implements _i10.Release {}
+class _FakeRelease_71 extends _i1.SmartFake implements _i10.Release {
+ _FakeRelease_71(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeReleaseAsset_72 extends _i1.Fake implements _i10.ReleaseAsset {}
+class _FakeReleaseAsset_72 extends _i1.SmartFake implements _i10.ReleaseAsset {
+ _FakeReleaseAsset_72(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeContributorParticipation_73 extends _i1.Fake implements _i10.ContributorParticipation {}
+class _FakeContributorParticipation_73 extends _i1.SmartFake implements _i10.ContributorParticipation {
+ _FakeContributorParticipation_73(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepositoryStatus_74 extends _i1.Fake implements _i10.RepositoryStatus {}
+class _FakeRepositoryStatus_74 extends _i1.SmartFake implements _i10.RepositoryStatus {
+ _FakeRepositoryStatus_74(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCombinedRepositoryStatus_75 extends _i1.Fake implements _i10.CombinedRepositoryStatus {}
+class _FakeCombinedRepositoryStatus_75 extends _i1.SmartFake implements _i10.CombinedRepositoryStatus {
+ _FakeCombinedRepositoryStatus_75(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeReleaseNotes_76 extends _i1.Fake implements _i10.ReleaseNotes {}
+class _FakeReleaseNotes_76 extends _i1.SmartFake implements _i10.ReleaseNotes {
+ _FakeReleaseNotes_76(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeTableDataInsertAllResponse_77 extends _i1.Fake implements _i6.TableDataInsertAllResponse {}
+class _FakeTableDataInsertAllResponse_77 extends _i1.SmartFake implements _i6.TableDataInsertAllResponse {
+ _FakeTableDataInsertAllResponse_77(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeTableDataList_78 extends _i1.Fake implements _i6.TableDataList {}
+class _FakeTableDataList_78 extends _i1.SmartFake implements _i6.TableDataList {
+ _FakeTableDataList_78(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeUser_79 extends _i1.Fake implements _i10.User {}
+class _FakeUser_79 extends _i1.SmartFake implements _i10.User {
+ _FakeUser_79(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCurrentUser_80 extends _i1.Fake implements _i10.CurrentUser {}
+class _FakeCurrentUser_80 extends _i1.SmartFake implements _i10.CurrentUser {
+ _FakeCurrentUser_80(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeEntry_81<T> extends _i1.Fake implements _i21.Entry<T> {}
+class _FakeEntry_81<T> extends _i1.SmartFake implements _i21.Entry<T> {
+ _FakeEntry_81(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeCache_82<T> extends _i1.Fake implements _i21.Cache<T> {}
+class _FakeCache_82<T> extends _i1.SmartFake implements _i21.Cache<T> {
+ _FakeCache_82(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeActivityService_83 extends _i1.Fake implements _i10.ActivityService {}
+class _FakeActivityService_83 extends _i1.SmartFake implements _i10.ActivityService {
+ _FakeActivityService_83(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeAuthorizationsService_84 extends _i1.Fake implements _i10.AuthorizationsService {}
+class _FakeAuthorizationsService_84 extends _i1.SmartFake implements _i10.AuthorizationsService {
+ _FakeAuthorizationsService_84(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGistsService_85 extends _i1.Fake implements _i10.GistsService {}
+class _FakeGistsService_85 extends _i1.SmartFake implements _i10.GistsService {
+ _FakeGistsService_85(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeGitService_86 extends _i1.Fake implements _i10.GitService {}
+class _FakeGitService_86 extends _i1.SmartFake implements _i10.GitService {
+ _FakeGitService_86(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeIssuesService_87 extends _i1.Fake implements _i10.IssuesService {}
+class _FakeIssuesService_87 extends _i1.SmartFake implements _i10.IssuesService {
+ _FakeIssuesService_87(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeMiscService_88 extends _i1.Fake implements _i10.MiscService {}
+class _FakeMiscService_88 extends _i1.SmartFake implements _i10.MiscService {
+ _FakeMiscService_88(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeOrganizationsService_89 extends _i1.Fake implements _i10.OrganizationsService {}
+class _FakeOrganizationsService_89 extends _i1.SmartFake implements _i10.OrganizationsService {
+ _FakeOrganizationsService_89(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakePullRequestsService_90 extends _i1.Fake implements _i10.PullRequestsService {}
+class _FakePullRequestsService_90 extends _i1.SmartFake implements _i10.PullRequestsService {
+ _FakePullRequestsService_90(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeRepositoriesService_91 extends _i1.Fake implements _i10.RepositoriesService {}
+class _FakeRepositoriesService_91 extends _i1.SmartFake implements _i10.RepositoriesService {
+ _FakeRepositoriesService_91(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeSearchService_92 extends _i1.Fake implements _i10.SearchService {}
+class _FakeSearchService_92 extends _i1.SmartFake implements _i10.SearchService {
+ _FakeSearchService_92(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeUrlShortenerService_93 extends _i1.Fake implements _i10.UrlShortenerService {}
+class _FakeUrlShortenerService_93 extends _i1.SmartFake implements _i10.UrlShortenerService {
+ _FakeUrlShortenerService_93(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeUsersService_94 extends _i1.Fake implements _i10.UsersService {}
+class _FakeUsersService_94 extends _i1.SmartFake implements _i10.UsersService {
+ _FakeUsersService_94(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeChecksService_95 extends _i1.Fake implements _i10.ChecksService {}
+class _FakeChecksService_95 extends _i1.SmartFake implements _i10.ChecksService {
+ _FakeChecksService_95(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
-class _FakeResponse_96 extends _i1.Fake implements _i2.Response {}
+class _FakeResponse_96 extends _i1.SmartFake implements _i2.Response {
+ _FakeResponse_96(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
+}
/// A class which mocks [AccessClientProvider].
///
@@ -262,7 +458,9 @@
_i17.Future<_i2.Client> createAccessClient(
{List<String>? scopes = const [r'https://www.googleapis.com/auth/cloud-platform']}) =>
(super.noSuchMethod(Invocation.method(#createAccessClient, [], {#scopes: scopes}),
- returnValue: Future<_i2.Client>.value(_FakeClient_0())) as _i17.Future<_i2.Client>);
+ returnValue: _i17.Future<_i2.Client>.value(
+ _FakeClient_0(this, Invocation.method(#createAccessClient, [], {#scopes: scopes}))))
+ as _i17.Future<_i2.Client>);
}
/// A class which mocks [AccessTokenService].
@@ -274,10 +472,14 @@
}
@override
- _i3.Config get config => (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1()) as _i3.Config);
+ _i3.Config get config =>
+ (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1(this, Invocation.getter(#config)))
+ as _i3.Config);
@override
_i17.Future<_i4.AccessToken> createAccessToken() => (super.noSuchMethod(Invocation.method(#createAccessToken, []),
- returnValue: Future<_i4.AccessToken>.value(_FakeAccessToken_2())) as _i17.Future<_i4.AccessToken>);
+ returnValue:
+ _i17.Future<_i4.AccessToken>.value(_FakeAccessToken_2(this, Invocation.method(#createAccessToken, []))))
+ as _i17.Future<_i4.AccessToken>);
}
/// A class which mocks [BigqueryService].
@@ -289,28 +491,31 @@
}
@override
- _i5.AccessClientProvider get accessClientProvider =>
- (super.noSuchMethod(Invocation.getter(#accessClientProvider), returnValue: _FakeAccessClientProvider_3())
- as _i5.AccessClientProvider);
+ _i5.AccessClientProvider get accessClientProvider => (super.noSuchMethod(Invocation.getter(#accessClientProvider),
+ returnValue: _FakeAccessClientProvider_3(this, Invocation.getter(#accessClientProvider)))
+ as _i5.AccessClientProvider);
@override
_i17.Future<_i6.TabledataResource> defaultTabledata() => (super.noSuchMethod(Invocation.method(#defaultTabledata, []),
- returnValue: Future<_i6.TabledataResource>.value(_FakeTabledataResource_4()))
+ returnValue: _i17.Future<_i6.TabledataResource>.value(
+ _FakeTabledataResource_4(this, Invocation.method(#defaultTabledata, []))))
as _i17.Future<_i6.TabledataResource>);
@override
_i17.Future<_i6.JobsResource> defaultJobs() => (super.noSuchMethod(Invocation.method(#defaultJobs, []),
- returnValue: Future<_i6.JobsResource>.value(_FakeJobsResource_5())) as _i17.Future<_i6.JobsResource>);
+ returnValue:
+ _i17.Future<_i6.JobsResource>.value(_FakeJobsResource_5(this, Invocation.method(#defaultJobs, []))))
+ as _i17.Future<_i6.JobsResource>);
@override
_i17.Future<List<_i23.BuilderStatistic>> listBuilderStatistic(String? projectId,
{int? limit = 100, String? bucket = r'prod'}) =>
(super.noSuchMethod(Invocation.method(#listBuilderStatistic, [projectId], {#limit: limit, #bucket: bucket}),
- returnValue: Future<List<_i23.BuilderStatistic>>.value(<_i23.BuilderStatistic>[]))
+ returnValue: _i17.Future<List<_i23.BuilderStatistic>>.value(<_i23.BuilderStatistic>[]))
as _i17.Future<List<_i23.BuilderStatistic>>);
@override
_i17.Future<List<_i23.BuilderRecord>> listRecentBuildRecordsForBuilder(String? projectId,
{String? builder, int? limit}) =>
(super.noSuchMethod(
Invocation.method(#listRecentBuildRecordsForBuilder, [projectId], {#builder: builder, #limit: limit}),
- returnValue: Future<List<_i23.BuilderRecord>>.value(<_i23.BuilderRecord>[]))
+ returnValue: _i17.Future<List<_i23.BuilderRecord>>.value(<_i23.BuilderRecord>[]))
as _i17.Future<List<_i23.BuilderRecord>>);
}
@@ -323,25 +528,29 @@
}
@override
- _i3.Config get config => (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1()) as _i3.Config);
+ _i3.Config get config =>
+ (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1(this, Invocation.getter(#config)))
+ as _i3.Config);
@override
- _i7.GerritService get gerritService =>
- (super.noSuchMethod(Invocation.getter(#gerritService), returnValue: _FakeGerritService_6()) as _i7.GerritService);
+ _i7.GerritService get gerritService => (super.noSuchMethod(Invocation.getter(#gerritService),
+ returnValue: _FakeGerritService_6(this, Invocation.getter(#gerritService))) as _i7.GerritService);
@override
- _i8.RetryOptions get retryOptions =>
- (super.noSuchMethod(Invocation.getter(#retryOptions), returnValue: _FakeRetryOptions_7()) as _i8.RetryOptions);
+ _i8.RetryOptions get retryOptions => (super.noSuchMethod(Invocation.getter(#retryOptions),
+ returnValue: _FakeRetryOptions_7(this, Invocation.getter(#retryOptions))) as _i8.RetryOptions);
@override
_i17.Future<void> handleCreateRequest(_i25.CreateEvent? createEvent) =>
(super.noSuchMethod(Invocation.method(#handleCreateRequest, [createEvent]),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<void> branchFlutterRecipes(String? branch) =>
(super.noSuchMethod(Invocation.method(#branchFlutterRecipes, [branch]),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
- _i17.Future<List<Map<String, String>>> getStableBetaDevBranches({_i10.GitHub? github, _i10.RepositorySlug? slug}) =>
- (super.noSuchMethod(Invocation.method(#getStableBetaDevBranches, [], {#github: github, #slug: slug}),
- returnValue: Future<List<Map<String, String>>>.value(<Map<String, String>>[]))
+ _i17.Future<List<Map<String, String>>> getReleaseBranches({_i10.GitHub? github, _i10.RepositorySlug? slug}) =>
+ (super.noSuchMethod(Invocation.method(#getReleaseBranches, [], {#github: github, #slug: slug}),
+ returnValue: _i17.Future<List<Map<String, String>>>.value(<Map<String, String>>[]))
as _i17.Future<List<Map<String, String>>>);
}
@@ -361,39 +570,49 @@
String get buildBucketBuilderUri =>
(super.noSuchMethod(Invocation.getter(#buildBucketBuilderUri), returnValue: '') as String);
@override
- _i2.Client get httpClient =>
- (super.noSuchMethod(Invocation.getter(#httpClient), returnValue: _FakeClient_0()) as _i2.Client);
+ _i2.Client get httpClient => (super.noSuchMethod(Invocation.getter(#httpClient),
+ returnValue: _FakeClient_0(this, Invocation.getter(#httpClient))) as _i2.Client);
@override
_i17.Future<_i9.Build> scheduleBuild(_i9.ScheduleBuildRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds'}) =>
(super.noSuchMethod(Invocation.method(#scheduleBuild, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.Build>.value(_FakeBuild_8())) as _i17.Future<_i9.Build>);
+ returnValue: _i17.Future<_i9.Build>.value(
+ _FakeBuild_8(this, Invocation.method(#scheduleBuild, [request], {#buildBucketUri: buildBucketUri}))))
+ as _i17.Future<_i9.Build>);
@override
_i17.Future<_i9.SearchBuildsResponse> searchBuilds(_i9.SearchBuildsRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds'}) =>
(super.noSuchMethod(Invocation.method(#searchBuilds, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.SearchBuildsResponse>.value(_FakeSearchBuildsResponse_9()))
+ returnValue: _i17.Future<_i9.SearchBuildsResponse>.value(_FakeSearchBuildsResponse_9(
+ this, Invocation.method(#searchBuilds, [request], {#buildBucketUri: buildBucketUri}))))
as _i17.Future<_i9.SearchBuildsResponse>);
@override
_i17.Future<_i9.BatchResponse> batch(_i9.BatchRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds'}) =>
(super.noSuchMethod(Invocation.method(#batch, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.BatchResponse>.value(_FakeBatchResponse_10())) as _i17.Future<_i9.BatchResponse>);
+ returnValue: _i17.Future<_i9.BatchResponse>.value(
+ _FakeBatchResponse_10(this, Invocation.method(#batch, [request], {#buildBucketUri: buildBucketUri}))))
+ as _i17.Future<_i9.BatchResponse>);
@override
_i17.Future<_i9.Build> cancelBuild(_i9.CancelBuildRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds'}) =>
(super.noSuchMethod(Invocation.method(#cancelBuild, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.Build>.value(_FakeBuild_8())) as _i17.Future<_i9.Build>);
+ returnValue: _i17.Future<_i9.Build>.value(
+ _FakeBuild_8(this, Invocation.method(#cancelBuild, [request], {#buildBucketUri: buildBucketUri}))))
+ as _i17.Future<_i9.Build>);
@override
_i17.Future<_i9.Build> getBuild(_i9.GetBuildRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds'}) =>
(super.noSuchMethod(Invocation.method(#getBuild, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.Build>.value(_FakeBuild_8())) as _i17.Future<_i9.Build>);
+ returnValue: _i17.Future<_i9.Build>.value(
+ _FakeBuild_8(this, Invocation.method(#getBuild, [request], {#buildBucketUri: buildBucketUri}))))
+ as _i17.Future<_i9.Build>);
@override
_i17.Future<_i9.ListBuildersResponse> listBuilders(_i9.ListBuildersRequest? request,
{String? buildBucketUri = r'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builders'}) =>
(super.noSuchMethod(Invocation.method(#listBuilders, [request], {#buildBucketUri: buildBucketUri}),
- returnValue: Future<_i9.ListBuildersResponse>.value(_FakeListBuildersResponse_11()))
+ returnValue: _i17.Future<_i9.ListBuildersResponse>.value(_FakeListBuildersResponse_11(
+ this, Invocation.method(#listBuilders, [request], {#buildBucketUri: buildBucketUri}))))
as _i17.Future<_i9.ListBuildersResponse>);
@override
void close() => super.noSuchMethod(Invocation.method(#close, []), returnValueForMissingStub: null);
@@ -416,13 +635,14 @@
@override
_i17.Future<_i27.Uint8List> get([_i17.Future<_i27.Uint8List?> Function()? create, Duration? ttl]) =>
(super.noSuchMethod(Invocation.method(#get, [create, ttl]),
- returnValue: Future<_i27.Uint8List>.value(_i27.Uint8List(0))) as _i17.Future<_i27.Uint8List>);
+ returnValue: _i17.Future<_i27.Uint8List>.value(_i27.Uint8List(0))) as _i17.Future<_i27.Uint8List>);
@override
_i17.Future<void> purge({int? retries = 0}) => (super.noSuchMethod(Invocation.method(#purge, [], {#retries: retries}),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<_i27.Uint8List?> set(_i27.Uint8List? value, [Duration? ttl]) =>
- (super.noSuchMethod(Invocation.method(#set, [value, ttl]), returnValue: Future<_i27.Uint8List?>.value())
+ (super.noSuchMethod(Invocation.method(#set, [value, ttl]), returnValue: _i17.Future<_i27.Uint8List?>.value())
as _i17.Future<_i27.Uint8List?>);
}
@@ -436,7 +656,8 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
_i17.Stream<_i10.Issue> listAll(
{int? milestoneNumber,
@@ -456,7 +677,7 @@
#perPage: perPage,
#labels: labels
}),
- returnValue: Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
+ returnValue: _i17.Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
@override
_i17.Stream<_i10.Issue> listByUser(
{int? milestoneNumber,
@@ -476,7 +697,7 @@
#perPage: perPage,
#labels: labels
}),
- returnValue: Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
+ returnValue: _i17.Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
@override
_i17.Stream<_i10.Issue> listByOrg(String? org,
{int? milestoneNumber,
@@ -498,7 +719,7 @@
#perPage: perPage,
#labels: labels
}),
- returnValue: Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
+ returnValue: _i17.Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
@override
_i17.Stream<_i10.Issue> listByRepo(_i10.RepositorySlug? slug,
{int? milestoneNumber,
@@ -520,109 +741,127 @@
#perPage: perPage,
#labels: labels
}),
- returnValue: Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
+ returnValue: _i17.Stream<_i10.Issue>.empty()) as _i17.Stream<_i10.Issue>);
@override
_i17.Stream<_i10.Reaction> listReactions(_i10.RepositorySlug? slug, int? issueNumber, {_i10.ReactionType? content}) =>
(super.noSuchMethod(Invocation.method(#listReactions, [slug, issueNumber], {#content: content}),
- returnValue: Stream<_i10.Reaction>.empty()) as _i17.Stream<_i10.Reaction>);
+ returnValue: _i17.Stream<_i10.Reaction>.empty()) as _i17.Stream<_i10.Reaction>);
@override
_i17.Future<_i10.Issue> edit(_i10.RepositorySlug? slug, int? issueNumber, _i10.IssueRequest? issue) =>
(super.noSuchMethod(Invocation.method(#edit, [slug, issueNumber, issue]),
- returnValue: Future<_i10.Issue>.value(_FakeIssue_13())) as _i17.Future<_i10.Issue>);
+ returnValue: _i17.Future<_i10.Issue>.value(
+ _FakeIssue_13(this, Invocation.method(#edit, [slug, issueNumber, issue])))) as _i17.Future<_i10.Issue>);
@override
- _i17.Future<_i10.Issue> get(_i10.RepositorySlug? slug, int? issueNumber) =>
- (super.noSuchMethod(Invocation.method(#get, [slug, issueNumber]),
- returnValue: Future<_i10.Issue>.value(_FakeIssue_13())) as _i17.Future<_i10.Issue>);
+ _i17.Future<_i10.Issue> get(_i10.RepositorySlug? slug, int? issueNumber) => (super.noSuchMethod(
+ Invocation.method(#get, [slug, issueNumber]),
+ returnValue: _i17.Future<_i10.Issue>.value(_FakeIssue_13(this, Invocation.method(#get, [slug, issueNumber]))))
+ as _i17.Future<_i10.Issue>);
@override
- _i17.Future<_i10.Issue> create(_i10.RepositorySlug? slug, _i10.IssueRequest? issue) =>
- (super.noSuchMethod(Invocation.method(#create, [slug, issue]),
- returnValue: Future<_i10.Issue>.value(_FakeIssue_13())) as _i17.Future<_i10.Issue>);
+ _i17.Future<_i10.Issue> create(_i10.RepositorySlug? slug, _i10.IssueRequest? issue) => (super.noSuchMethod(
+ Invocation.method(#create, [slug, issue]),
+ returnValue: _i17.Future<_i10.Issue>.value(_FakeIssue_13(this, Invocation.method(#create, [slug, issue]))))
+ as _i17.Future<_i10.Issue>);
@override
_i17.Stream<_i10.User> listAssignees(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listAssignees, [slug]), returnValue: Stream<_i10.User>.empty())
+ (super.noSuchMethod(Invocation.method(#listAssignees, [slug]), returnValue: _i17.Stream<_i10.User>.empty())
as _i17.Stream<_i10.User>);
@override
_i17.Future<bool> isAssignee(_i10.RepositorySlug? slug, String? repoName) =>
- (super.noSuchMethod(Invocation.method(#isAssignee, [slug, repoName]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#isAssignee, [slug, repoName]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.IssueComment> listCommentsByIssue(_i10.RepositorySlug? slug, int? issueNumber) =>
(super.noSuchMethod(Invocation.method(#listCommentsByIssue, [slug, issueNumber]),
- returnValue: Stream<_i10.IssueComment>.empty()) as _i17.Stream<_i10.IssueComment>);
+ returnValue: _i17.Stream<_i10.IssueComment>.empty()) as _i17.Stream<_i10.IssueComment>);
@override
- _i17.Stream<_i10.IssueComment> listCommentsByRepo(_i10.RepositorySlug? slug) => (super
- .noSuchMethod(Invocation.method(#listCommentsByRepo, [slug]), returnValue: Stream<_i10.IssueComment>.empty())
- as _i17.Stream<_i10.IssueComment>);
+ _i17.Stream<_i10.IssueComment> listCommentsByRepo(_i10.RepositorySlug? slug) =>
+ (super.noSuchMethod(Invocation.method(#listCommentsByRepo, [slug]),
+ returnValue: _i17.Stream<_i10.IssueComment>.empty()) as _i17.Stream<_i10.IssueComment>);
@override
- _i17.Future<_i10.IssueComment> getComment(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#getComment, [slug, id]),
- returnValue: Future<_i10.IssueComment>.value(_FakeIssueComment_14())) as _i17.Future<_i10.IssueComment>);
+ _i17.Future<_i10.IssueComment> getComment(_i10.RepositorySlug? slug, int? id) => (super.noSuchMethod(
+ Invocation.method(#getComment, [slug, id]),
+ returnValue: _i17.Future<_i10.IssueComment>.value(
+ _FakeIssueComment_14(this, Invocation.method(#getComment, [slug, id])))) as _i17.Future<_i10.IssueComment>);
@override
_i17.Future<_i10.IssueComment> createComment(_i10.RepositorySlug? slug, int? issueNumber, String? body) =>
(super.noSuchMethod(Invocation.method(#createComment, [slug, issueNumber, body]),
- returnValue: Future<_i10.IssueComment>.value(_FakeIssueComment_14())) as _i17.Future<_i10.IssueComment>);
+ returnValue: _i17.Future<_i10.IssueComment>.value(
+ _FakeIssueComment_14(this, Invocation.method(#createComment, [slug, issueNumber, body]))))
+ as _i17.Future<_i10.IssueComment>);
@override
_i17.Future<_i10.IssueComment> updateComment(_i10.RepositorySlug? slug, int? id, String? body) =>
(super.noSuchMethod(Invocation.method(#updateComment, [slug, id, body]),
- returnValue: Future<_i10.IssueComment>.value(_FakeIssueComment_14())) as _i17.Future<_i10.IssueComment>);
+ returnValue: _i17.Future<_i10.IssueComment>.value(
+ _FakeIssueComment_14(this, Invocation.method(#updateComment, [slug, id, body]))))
+ as _i17.Future<_i10.IssueComment>);
@override
_i17.Future<bool> deleteComment(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#deleteComment, [slug, id]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteComment, [slug, id]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.IssueLabel> listLabels(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listLabels, [slug]), returnValue: Stream<_i10.IssueLabel>.empty())
+ (super.noSuchMethod(Invocation.method(#listLabels, [slug]), returnValue: _i17.Stream<_i10.IssueLabel>.empty())
as _i17.Stream<_i10.IssueLabel>);
@override
- _i17.Future<_i10.IssueLabel> getLabel(_i10.RepositorySlug? slug, String? name) =>
- (super.noSuchMethod(Invocation.method(#getLabel, [slug, name]),
- returnValue: Future<_i10.IssueLabel>.value(_FakeIssueLabel_15())) as _i17.Future<_i10.IssueLabel>);
+ _i17.Future<_i10.IssueLabel> getLabel(_i10.RepositorySlug? slug, String? name) => (super.noSuchMethod(
+ Invocation.method(#getLabel, [slug, name]),
+ returnValue:
+ _i17.Future<_i10.IssueLabel>.value(_FakeIssueLabel_15(this, Invocation.method(#getLabel, [slug, name]))))
+ as _i17.Future<_i10.IssueLabel>);
@override
_i17.Future<_i10.IssueLabel> createLabel(_i10.RepositorySlug? slug, String? name, String? color) =>
(super.noSuchMethod(Invocation.method(#createLabel, [slug, name, color]),
- returnValue: Future<_i10.IssueLabel>.value(_FakeIssueLabel_15())) as _i17.Future<_i10.IssueLabel>);
+ returnValue: _i17.Future<_i10.IssueLabel>.value(
+ _FakeIssueLabel_15(this, Invocation.method(#createLabel, [slug, name, color]))))
+ as _i17.Future<_i10.IssueLabel>);
@override
_i17.Future<_i10.IssueLabel> editLabel(_i10.RepositorySlug? slug, String? name, String? color) =>
(super.noSuchMethod(Invocation.method(#editLabel, [slug, name, color]),
- returnValue: Future<_i10.IssueLabel>.value(_FakeIssueLabel_15())) as _i17.Future<_i10.IssueLabel>);
+ returnValue: _i17.Future<_i10.IssueLabel>.value(
+ _FakeIssueLabel_15(this, Invocation.method(#editLabel, [slug, name, color]))))
+ as _i17.Future<_i10.IssueLabel>);
@override
_i17.Future<bool> deleteLabel(_i10.RepositorySlug? slug, String? name) =>
- (super.noSuchMethod(Invocation.method(#deleteLabel, [slug, name]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteLabel, [slug, name]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.IssueLabel> listLabelsByIssue(_i10.RepositorySlug? slug, int? issueNumber) =>
(super.noSuchMethod(Invocation.method(#listLabelsByIssue, [slug, issueNumber]),
- returnValue: Stream<_i10.IssueLabel>.empty()) as _i17.Stream<_i10.IssueLabel>);
+ returnValue: _i17.Stream<_i10.IssueLabel>.empty()) as _i17.Stream<_i10.IssueLabel>);
@override
_i17.Future<List<_i10.IssueLabel>> addLabelsToIssue(
_i10.RepositorySlug? slug, int? issueNumber, List<String>? labels) =>
(super.noSuchMethod(Invocation.method(#addLabelsToIssue, [slug, issueNumber, labels]),
- returnValue: Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[])) as _i17.Future<List<_i10.IssueLabel>>);
+ returnValue: _i17.Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[]))
+ as _i17.Future<List<_i10.IssueLabel>>);
@override
_i17.Future<List<_i10.IssueLabel>> replaceLabelsForIssue(
_i10.RepositorySlug? slug, int? issueNumber, List<String>? labels) =>
(super.noSuchMethod(Invocation.method(#replaceLabelsForIssue, [slug, issueNumber, labels]),
- returnValue: Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[])) as _i17.Future<List<_i10.IssueLabel>>);
+ returnValue: _i17.Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[]))
+ as _i17.Future<List<_i10.IssueLabel>>);
@override
_i17.Future<bool> removeLabelForIssue(_i10.RepositorySlug? slug, int? issueNumber, String? label) =>
(super.noSuchMethod(Invocation.method(#removeLabelForIssue, [slug, issueNumber, label]),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Future<bool> removeAllLabelsForIssue(_i10.RepositorySlug? slug, int? issueNumber) =>
(super.noSuchMethod(Invocation.method(#removeAllLabelsForIssue, [slug, issueNumber]),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Stream<_i10.Milestone> listMilestones(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listMilestones, [slug]), returnValue: Stream<_i10.Milestone>.empty())
+ (super.noSuchMethod(Invocation.method(#listMilestones, [slug]), returnValue: _i17.Stream<_i10.Milestone>.empty())
as _i17.Stream<_i10.Milestone>);
@override
_i17.Future<_i10.Milestone> createMilestone(_i10.RepositorySlug? slug, _i10.CreateMilestone? request) =>
(super.noSuchMethod(Invocation.method(#createMilestone, [slug, request]),
- returnValue: Future<_i10.Milestone>.value(_FakeMilestone_16())) as _i17.Future<_i10.Milestone>);
+ returnValue: _i17.Future<_i10.Milestone>.value(
+ _FakeMilestone_16(this, Invocation.method(#createMilestone, [slug, request]))))
+ as _i17.Future<_i10.Milestone>);
@override
_i17.Future<bool> deleteMilestone(_i10.RepositorySlug? slug, int? number) =>
- (super.noSuchMethod(Invocation.method(#deleteMilestone, [slug, number]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ (super.noSuchMethod(Invocation.method(#deleteMilestone, [slug, number]),
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
}
/// A class which mocks [GithubChecksService].
@@ -634,14 +873,15 @@
}
@override
- _i3.Config get config => (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1()) as _i3.Config);
+ _i3.Config get config =>
+ (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1(this, Invocation.getter(#config)))
+ as _i3.Config);
@override
set config(_i3.Config? _config) =>
super.noSuchMethod(Invocation.setter(#config, _config), returnValueForMissingStub: null);
@override
- _i11.GithubChecksUtil get githubChecksUtil =>
- (super.noSuchMethod(Invocation.getter(#githubChecksUtil), returnValue: _FakeGithubChecksUtil_17())
- as _i11.GithubChecksUtil);
+ _i11.GithubChecksUtil get githubChecksUtil => (super.noSuchMethod(Invocation.getter(#githubChecksUtil),
+ returnValue: _FakeGithubChecksUtil_17(this, Invocation.getter(#githubChecksUtil))) as _i11.GithubChecksUtil);
@override
set githubChecksUtil(_i11.GithubChecksUtil? _githubChecksUtil) =>
super.noSuchMethod(Invocation.setter(#githubChecksUtil, _githubChecksUtil), returnValueForMissingStub: null);
@@ -649,23 +889,25 @@
_i17.Future<void> handleCheckSuite(
_i10.PullRequest? pullRequest, _i25.CheckSuiteEvent? checkSuiteEvent, _i29.Scheduler? scheduler) =>
(super.noSuchMethod(Invocation.method(#handleCheckSuite, [pullRequest, checkSuiteEvent, scheduler]),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<bool> updateCheckStatus(_i30.BuildPushMessage? buildPushMessage, _i31.LuciBuildService? luciBuildService,
_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#updateCheckStatus, [buildPushMessage, luciBuildService, slug]),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
String getGithubSummary(String? summary) =>
(super.noSuchMethod(Invocation.method(#getGithubSummary, [summary]), returnValue: '') as String);
@override
_i10.CheckRunConclusion conclusionForResult(_i30.Result? result) =>
- (super.noSuchMethod(Invocation.method(#conclusionForResult, [result]), returnValue: _FakeCheckRunConclusion_18())
+ (super.noSuchMethod(Invocation.method(#conclusionForResult, [result]),
+ returnValue: _FakeCheckRunConclusion_18(this, Invocation.method(#conclusionForResult, [result])))
as _i10.CheckRunConclusion);
@override
- _i10.CheckRunStatus statusForResult(_i30.Status? status) =>
- (super.noSuchMethod(Invocation.method(#statusForResult, [status]), returnValue: _FakeCheckRunStatus_19())
- as _i10.CheckRunStatus);
+ _i10.CheckRunStatus statusForResult(_i30.Status? status) => (super.noSuchMethod(
+ Invocation.method(#statusForResult, [status]),
+ returnValue: _FakeCheckRunStatus_19(this, Invocation.method(#statusForResult, [status]))) as _i10.CheckRunStatus);
}
/// A class which mocks [GithubChecksUtil].
@@ -680,12 +922,14 @@
_i17.Future<Map<String, _i10.CheckRun>> allCheckRuns(
_i10.GitHub? gitHubClient, _i25.CheckSuiteEvent? checkSuiteEvent) =>
(super.noSuchMethod(Invocation.method(#allCheckRuns, [gitHubClient, checkSuiteEvent]),
- returnValue: Future<Map<String, _i10.CheckRun>>.value(<String, _i10.CheckRun>{}))
+ returnValue: _i17.Future<Map<String, _i10.CheckRun>>.value(<String, _i10.CheckRun>{}))
as _i17.Future<Map<String, _i10.CheckRun>>);
@override
_i17.Future<_i10.CheckSuite> getCheckSuite(_i10.GitHub? gitHubClient, _i10.RepositorySlug? slug, int? checkSuiteId) =>
(super.noSuchMethod(Invocation.method(#getCheckSuite, [gitHubClient, slug, checkSuiteId]),
- returnValue: Future<_i10.CheckSuite>.value(_FakeCheckSuite_20())) as _i17.Future<_i10.CheckSuite>);
+ returnValue: _i17.Future<_i10.CheckSuite>.value(
+ _FakeCheckSuite_20(this, Invocation.method(#getCheckSuite, [gitHubClient, slug, checkSuiteId]))))
+ as _i17.Future<_i10.CheckSuite>);
@override
_i17.Future<void> updateCheckRun(_i3.Config? cocoonConfig, _i10.RepositorySlug? slug, _i10.CheckRun? checkRun,
{_i10.CheckRunStatus? status = _i10.CheckRunStatus.queued,
@@ -695,18 +939,22 @@
(super.noSuchMethod(
Invocation.method(#updateCheckRun, [cocoonConfig, slug, checkRun],
{#status: status, #conclusion: conclusion, #detailsUrl: detailsUrl, #output: output}),
- returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<_i10.CheckRun> getCheckRun(_i3.Config? cocoonConfig, _i10.RepositorySlug? slug, int? id) =>
(super.noSuchMethod(Invocation.method(#getCheckRun, [cocoonConfig, slug, id]),
- returnValue: Future<_i10.CheckRun>.value(_FakeCheckRun_21())) as _i17.Future<_i10.CheckRun>);
+ returnValue: _i17.Future<_i10.CheckRun>.value(
+ _FakeCheckRun_21(this, Invocation.method(#getCheckRun, [cocoonConfig, slug, id]))))
+ as _i17.Future<_i10.CheckRun>);
@override
_i17.Future<_i10.CheckRun> createCheckRun(
_i3.Config? cocoonConfig, _i10.RepositorySlug? slug, String? sha, String? name,
{_i10.CheckRunOutput? output}) =>
(super.noSuchMethod(Invocation.method(#createCheckRun, [cocoonConfig, slug, sha, name], {#output: output}),
- returnValue: Future<_i10.CheckRun>.value(_FakeCheckRun_21())) as _i17.Future<_i10.CheckRun>);
+ returnValue: _i17.Future<_i10.CheckRun>.value(_FakeCheckRun_21(
+ this, Invocation.method(#createCheckRun, [cocoonConfig, slug, sha, name], {#output: output}))))
+ as _i17.Future<_i10.CheckRun>);
}
/// A class which mocks [GithubService].
@@ -719,17 +967,18 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
_i17.Future<List<_i10.RepositoryCommit>> listCommits(
_i10.RepositorySlug? slug, String? branch, int? lastCommitTimestampMills) =>
(super.noSuchMethod(Invocation.method(#listCommits, [slug, branch, lastCommitTimestampMills]),
- returnValue: Future<List<_i10.RepositoryCommit>>.value(<_i10.RepositoryCommit>[]))
+ returnValue: _i17.Future<List<_i10.RepositoryCommit>>.value(<_i10.RepositoryCommit>[]))
as _i17.Future<List<_i10.RepositoryCommit>>);
@override
_i17.Future<List<_i10.PullRequest>> listPullRequests(_i10.RepositorySlug? slug, String? branch) =>
(super.noSuchMethod(Invocation.method(#listPullRequests, [slug, branch]),
- returnValue: Future<List<_i10.PullRequest>>.value(<_i10.PullRequest>[]))
+ returnValue: _i17.Future<List<_i10.PullRequest>>.value(<_i10.PullRequest>[]))
as _i17.Future<List<_i10.PullRequest>>);
@override
_i17.Future<_i10.PullRequest> createPullRequest(_i10.RepositorySlug? slug,
@@ -738,21 +987,29 @@
String? commitMessage,
_i10.GitReference? baseRef,
List<_i10.CreateGitTreeEntry>? entries}) =>
- (super.noSuchMethod(
- Invocation.method(#createPullRequest, [slug],
- {#title: title, #body: body, #commitMessage: commitMessage, #baseRef: baseRef, #entries: entries}),
- returnValue: Future<_i10.PullRequest>.value(_FakePullRequest_22())) as _i17.Future<_i10.PullRequest>);
+ (super.noSuchMethod(Invocation.method(#createPullRequest, [slug], {#title: title, #body: body, #commitMessage: commitMessage, #baseRef: baseRef, #entries: entries}),
+ returnValue: _i17.Future<_i10.PullRequest>.value(_FakePullRequest_22(
+ this,
+ Invocation.method(#createPullRequest, [
+ slug
+ ], {
+ #title: title,
+ #body: body,
+ #commitMessage: commitMessage,
+ #baseRef: baseRef,
+ #entries: entries
+ })))) as _i17.Future<_i10.PullRequest>);
@override
_i17.Future<void> assignReviewer(_i10.RepositorySlug? slug, {int? pullRequestNumber, String? reviewer}) =>
(super.noSuchMethod(
Invocation.method(#assignReviewer, [slug], {#pullRequestNumber: pullRequestNumber, #reviewer: reviewer}),
- returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<List<_i10.Issue>> listIssues(_i10.RepositorySlug? slug,
{List<String>? labels, String? state = r'open'}) =>
(super.noSuchMethod(Invocation.method(#listIssues, [slug], {#labels: labels, #state: state}),
- returnValue: Future<List<_i10.Issue>>.value(<_i10.Issue>[])) as _i17.Future<List<_i10.Issue>>);
+ returnValue: _i17.Future<List<_i10.Issue>>.value(<_i10.Issue>[])) as _i17.Future<List<_i10.Issue>>);
@override
_i17.Future<_i10.Issue>? getIssue(_i10.RepositorySlug? slug, {int? issueNumber}) =>
(super.noSuchMethod(Invocation.method(#getIssue, [slug], {#issueNumber: issueNumber}))
@@ -760,38 +1017,47 @@
@override
_i17.Future<void> assignIssue(_i10.RepositorySlug? slug, {int? issueNumber, String? assignee}) =>
(super.noSuchMethod(Invocation.method(#assignIssue, [slug], {#issueNumber: issueNumber, #assignee: assignee}),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<_i10.Issue> createIssue(_i10.RepositorySlug? slug,
{String? title, String? body, List<String>? labels, String? assignee}) =>
(super.noSuchMethod(
Invocation.method(#createIssue, [slug], {#title: title, #body: body, #labels: labels, #assignee: assignee}),
- returnValue: Future<_i10.Issue>.value(_FakeIssue_13())) as _i17.Future<_i10.Issue>);
+ returnValue: _i17.Future<_i10.Issue>.value(_FakeIssue_13(
+ this,
+ Invocation.method(
+ #createIssue, [slug], {#title: title, #body: body, #labels: labels, #assignee: assignee})))) as _i17
+ .Future<_i10.Issue>);
@override
_i17.Future<_i10.IssueComment?> createComment(_i10.RepositorySlug? slug, {int? issueNumber, String? body}) =>
(super.noSuchMethod(Invocation.method(#createComment, [slug], {#issueNumber: issueNumber, #body: body}),
- returnValue: Future<_i10.IssueComment?>.value()) as _i17.Future<_i10.IssueComment?>);
+ returnValue: _i17.Future<_i10.IssueComment?>.value()) as _i17.Future<_i10.IssueComment?>);
@override
_i17.Future<List<_i10.IssueLabel>> replaceLabelsForIssue(_i10.RepositorySlug? slug,
{int? issueNumber, List<String>? labels}) =>
(super.noSuchMethod(
- Invocation.method(#replaceLabelsForIssue, [slug], {#issueNumber: issueNumber, #labels: labels}),
- returnValue: Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[])) as _i17.Future<List<_i10.IssueLabel>>);
+ Invocation.method(#replaceLabelsForIssue, [slug], {#issueNumber: issueNumber, #labels: labels}),
+ returnValue: _i17.Future<List<_i10.IssueLabel>>.value(<_i10.IssueLabel>[]))
+ as _i17.Future<List<_i10.IssueLabel>>);
@override
_i17.Future<List<String>> listFiles(_i10.PullRequest? pullRequest) =>
(super.noSuchMethod(Invocation.method(#listFiles, [pullRequest]),
- returnValue: Future<List<String>>.value(<String>[])) as _i17.Future<List<String>>);
+ returnValue: _i17.Future<List<String>>.value(<String>[])) as _i17.Future<List<String>>);
@override
_i17.Future<String> getFileContent(_i10.RepositorySlug? slug, String? path) =>
- (super.noSuchMethod(Invocation.method(#getFileContent, [slug, path]), returnValue: Future<String>.value(''))
+ (super.noSuchMethod(Invocation.method(#getFileContent, [slug, path]), returnValue: _i17.Future<String>.value(''))
as _i17.Future<String>);
@override
_i17.Future<_i10.GitReference> getReference(_i10.RepositorySlug? slug, String? ref) =>
(super.noSuchMethod(Invocation.method(#getReference, [slug, ref]),
- returnValue: Future<_i10.GitReference>.value(_FakeGitReference_23())) as _i17.Future<_i10.GitReference>);
+ returnValue: _i17.Future<_i10.GitReference>.value(
+ _FakeGitReference_23(this, Invocation.method(#getReference, [slug, ref]))))
+ as _i17.Future<_i10.GitReference>);
@override
_i17.Future<_i10.RateLimit> getRateLimit() => (super.noSuchMethod(Invocation.method(#getRateLimit, []),
- returnValue: Future<_i10.RateLimit>.value(_FakeRateLimit_24())) as _i17.Future<_i10.RateLimit>);
+ returnValue: _i17.Future<_i10.RateLimit>.value(_FakeRateLimit_24(this, Invocation.method(#getRateLimit, []))))
+ as _i17.Future<_i10.RateLimit>);
}
/// A class which mocks [GitService].
@@ -804,60 +1070,80 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
- _i17.Future<_i10.GitBlob> getBlob(_i10.RepositorySlug? slug, String? sha) =>
- (super.noSuchMethod(Invocation.method(#getBlob, [slug, sha]),
- returnValue: Future<_i10.GitBlob>.value(_FakeGitBlob_25())) as _i17.Future<_i10.GitBlob>);
+ _i17.Future<_i10.GitBlob> getBlob(_i10.RepositorySlug? slug, String? sha) => (super.noSuchMethod(
+ Invocation.method(#getBlob, [slug, sha]),
+ returnValue: _i17.Future<_i10.GitBlob>.value(_FakeGitBlob_25(this, Invocation.method(#getBlob, [slug, sha]))))
+ as _i17.Future<_i10.GitBlob>);
@override
_i17.Future<_i10.GitBlob> createBlob(_i10.RepositorySlug? slug, _i10.CreateGitBlob? blob) =>
(super.noSuchMethod(Invocation.method(#createBlob, [slug, blob]),
- returnValue: Future<_i10.GitBlob>.value(_FakeGitBlob_25())) as _i17.Future<_i10.GitBlob>);
+ returnValue:
+ _i17.Future<_i10.GitBlob>.value(_FakeGitBlob_25(this, Invocation.method(#createBlob, [slug, blob]))))
+ as _i17.Future<_i10.GitBlob>);
@override
- _i17.Future<_i10.GitCommit> getCommit(_i10.RepositorySlug? slug, String? sha) =>
- (super.noSuchMethod(Invocation.method(#getCommit, [slug, sha]),
- returnValue: Future<_i10.GitCommit>.value(_FakeGitCommit_26())) as _i17.Future<_i10.GitCommit>);
+ _i17.Future<_i10.GitCommit> getCommit(_i10.RepositorySlug? slug, String? sha) => (super.noSuchMethod(
+ Invocation.method(#getCommit, [slug, sha]),
+ returnValue:
+ _i17.Future<_i10.GitCommit>.value(_FakeGitCommit_26(this, Invocation.method(#getCommit, [slug, sha]))))
+ as _i17.Future<_i10.GitCommit>);
@override
_i17.Future<_i10.GitCommit> createCommit(_i10.RepositorySlug? slug, _i10.CreateGitCommit? commit) =>
(super.noSuchMethod(Invocation.method(#createCommit, [slug, commit]),
- returnValue: Future<_i10.GitCommit>.value(_FakeGitCommit_26())) as _i17.Future<_i10.GitCommit>);
+ returnValue: _i17.Future<_i10.GitCommit>.value(
+ _FakeGitCommit_26(this, Invocation.method(#createCommit, [slug, commit]))))
+ as _i17.Future<_i10.GitCommit>);
@override
_i17.Future<_i10.GitReference> getReference(_i10.RepositorySlug? slug, String? ref) =>
(super.noSuchMethod(Invocation.method(#getReference, [slug, ref]),
- returnValue: Future<_i10.GitReference>.value(_FakeGitReference_23())) as _i17.Future<_i10.GitReference>);
+ returnValue: _i17.Future<_i10.GitReference>.value(
+ _FakeGitReference_23(this, Invocation.method(#getReference, [slug, ref]))))
+ as _i17.Future<_i10.GitReference>);
@override
_i17.Stream<_i10.GitReference> listReferences(_i10.RepositorySlug? slug, {String? type}) =>
(super.noSuchMethod(Invocation.method(#listReferences, [slug], {#type: type}),
- returnValue: Stream<_i10.GitReference>.empty()) as _i17.Stream<_i10.GitReference>);
+ returnValue: _i17.Stream<_i10.GitReference>.empty()) as _i17.Stream<_i10.GitReference>);
@override
_i17.Future<_i10.GitReference> createReference(_i10.RepositorySlug? slug, String? ref, String? sha) =>
(super.noSuchMethod(Invocation.method(#createReference, [slug, ref, sha]),
- returnValue: Future<_i10.GitReference>.value(_FakeGitReference_23())) as _i17.Future<_i10.GitReference>);
+ returnValue: _i17.Future<_i10.GitReference>.value(
+ _FakeGitReference_23(this, Invocation.method(#createReference, [slug, ref, sha]))))
+ as _i17.Future<_i10.GitReference>);
@override
_i17.Future<_i10.GitReference> editReference(_i10.RepositorySlug? slug, String? ref, String? sha,
{bool? force = false}) =>
(super.noSuchMethod(Invocation.method(#editReference, [slug, ref, sha], {#force: force}),
- returnValue: Future<_i10.GitReference>.value(_FakeGitReference_23())) as _i17.Future<_i10.GitReference>);
+ returnValue: _i17.Future<_i10.GitReference>.value(
+ _FakeGitReference_23(this, Invocation.method(#editReference, [slug, ref, sha], {#force: force}))))
+ as _i17.Future<_i10.GitReference>);
@override
_i17.Future<bool> deleteReference(_i10.RepositorySlug? slug, String? ref) =>
- (super.noSuchMethod(Invocation.method(#deleteReference, [slug, ref]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteReference, [slug, ref]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
- _i17.Future<_i10.GitTag> getTag(_i10.RepositorySlug? slug, String? sha) =>
- (super.noSuchMethod(Invocation.method(#getTag, [slug, sha]),
- returnValue: Future<_i10.GitTag>.value(_FakeGitTag_27())) as _i17.Future<_i10.GitTag>);
+ _i17.Future<_i10.GitTag> getTag(_i10.RepositorySlug? slug, String? sha) => (super.noSuchMethod(
+ Invocation.method(#getTag, [slug, sha]),
+ returnValue: _i17.Future<_i10.GitTag>.value(_FakeGitTag_27(this, Invocation.method(#getTag, [slug, sha]))))
+ as _i17.Future<_i10.GitTag>);
@override
- _i17.Future<_i10.GitTag> createTag(_i10.RepositorySlug? slug, _i10.CreateGitTag? tag) =>
- (super.noSuchMethod(Invocation.method(#createTag, [slug, tag]),
- returnValue: Future<_i10.GitTag>.value(_FakeGitTag_27())) as _i17.Future<_i10.GitTag>);
+ _i17.Future<_i10.GitTag> createTag(_i10.RepositorySlug? slug, _i10.CreateGitTag? tag) => (super.noSuchMethod(
+ Invocation.method(#createTag, [slug, tag]),
+ returnValue: _i17.Future<_i10.GitTag>.value(_FakeGitTag_27(this, Invocation.method(#createTag, [slug, tag]))))
+ as _i17.Future<_i10.GitTag>);
@override
_i17.Future<_i10.GitTree> getTree(_i10.RepositorySlug? slug, String? sha, {bool? recursive = false}) =>
(super.noSuchMethod(Invocation.method(#getTree, [slug, sha], {#recursive: recursive}),
- returnValue: Future<_i10.GitTree>.value(_FakeGitTree_28())) as _i17.Future<_i10.GitTree>);
+ returnValue: _i17.Future<_i10.GitTree>.value(
+ _FakeGitTree_28(this, Invocation.method(#getTree, [slug, sha], {#recursive: recursive}))))
+ as _i17.Future<_i10.GitTree>);
@override
_i17.Future<_i10.GitTree> createTree(_i10.RepositorySlug? slug, _i10.CreateGitTree? tree) =>
(super.noSuchMethod(Invocation.method(#createTree, [slug, tree]),
- returnValue: Future<_i10.GitTree>.value(_FakeGitTree_28())) as _i17.Future<_i10.GitTree>);
+ returnValue:
+ _i17.Future<_i10.GitTree>.value(_FakeGitTree_28(this, Invocation.method(#createTree, [slug, tree]))))
+ as _i17.Future<_i10.GitTree>);
}
/// A class which mocks [GraphQLClient].
@@ -869,20 +1155,22 @@
}
@override
- _i12.DefaultPolicies get defaultPolicies =>
- (super.noSuchMethod(Invocation.getter(#defaultPolicies), returnValue: _FakeDefaultPolicies_29())
- as _i12.DefaultPolicies);
+ _i12.DefaultPolicies get defaultPolicies => (super.noSuchMethod(Invocation.getter(#defaultPolicies),
+ returnValue: _FakeDefaultPolicies_29(this, Invocation.getter(#defaultPolicies))) as _i12.DefaultPolicies);
@override
set defaultPolicies(_i12.DefaultPolicies? _defaultPolicies) =>
super.noSuchMethod(Invocation.setter(#defaultPolicies, _defaultPolicies), returnValueForMissingStub: null);
@override
- _i12.Link get link => (super.noSuchMethod(Invocation.getter(#link), returnValue: _FakeLink_30()) as _i12.Link);
+ _i12.Link get link =>
+ (super.noSuchMethod(Invocation.getter(#link), returnValue: _FakeLink_30(this, Invocation.getter(#link)))
+ as _i12.Link);
@override
_i13.GraphQLCache get cache =>
- (super.noSuchMethod(Invocation.getter(#cache), returnValue: _FakeGraphQLCache_31()) as _i13.GraphQLCache);
+ (super.noSuchMethod(Invocation.getter(#cache), returnValue: _FakeGraphQLCache_31(this, Invocation.getter(#cache)))
+ as _i13.GraphQLCache);
@override
- _i12.QueryManager get queryManager =>
- (super.noSuchMethod(Invocation.getter(#queryManager), returnValue: _FakeQueryManager_32()) as _i12.QueryManager);
+ _i12.QueryManager get queryManager => (super.noSuchMethod(Invocation.getter(#queryManager),
+ returnValue: _FakeQueryManager_32(this, Invocation.getter(#queryManager))) as _i12.QueryManager);
@override
set queryManager(_i12.QueryManager? _queryManager) =>
super.noSuchMethod(Invocation.setter(#queryManager, _queryManager), returnValueForMissingStub: null);
@@ -895,36 +1183,48 @@
(super.noSuchMethod(
Invocation.method(#copyWith, [],
{#link: link, #cache: cache, #defaultPolicies: defaultPolicies, #alwaysRebroadcast: alwaysRebroadcast}),
- returnValue: _FakeGraphQLClient_33()) as _i14.GraphQLClient);
+ returnValue: _FakeGraphQLClient_33(
+ this,
+ Invocation.method(#copyWith, [], {
+ #link: link,
+ #cache: cache,
+ #defaultPolicies: defaultPolicies,
+ #alwaysRebroadcast: alwaysRebroadcast
+ }))) as _i14.GraphQLClient);
@override
_i12.ObservableQuery<TParsed> watchQuery<TParsed>(_i12.WatchQueryOptions<TParsed>? options) =>
- (super.noSuchMethod(Invocation.method(#watchQuery, [options]), returnValue: _FakeObservableQuery_34<TParsed>())
+ (super.noSuchMethod(Invocation.method(#watchQuery, [options]),
+ returnValue: _FakeObservableQuery_34<TParsed>(this, Invocation.method(#watchQuery, [options])))
as _i12.ObservableQuery<TParsed>);
@override
_i12.ObservableQuery<TParsed> watchMutation<TParsed>(_i12.WatchQueryOptions<TParsed>? options) =>
- (super.noSuchMethod(Invocation.method(#watchMutation, [options]), returnValue: _FakeObservableQuery_34<TParsed>())
+ (super.noSuchMethod(Invocation.method(#watchMutation, [options]),
+ returnValue: _FakeObservableQuery_34<TParsed>(this, Invocation.method(#watchMutation, [options])))
as _i12.ObservableQuery<TParsed>);
@override
_i17.Future<_i12.QueryResult<TParsed>> query<TParsed>(_i12.QueryOptions<TParsed>? options) =>
(super.noSuchMethod(Invocation.method(#query, [options]),
- returnValue: Future<_i12.QueryResult<TParsed>>.value(_FakeQueryResult_35<TParsed>()))
+ returnValue: _i17.Future<_i12.QueryResult<TParsed>>.value(
+ _FakeQueryResult_35<TParsed>(this, Invocation.method(#query, [options]))))
as _i17.Future<_i12.QueryResult<TParsed>>);
@override
_i17.Future<_i12.QueryResult<TParsed>> mutate<TParsed>(_i12.MutationOptions<TParsed>? options) =>
(super.noSuchMethod(Invocation.method(#mutate, [options]),
- returnValue: Future<_i12.QueryResult<TParsed>>.value(_FakeQueryResult_35<TParsed>()))
+ returnValue: _i17.Future<_i12.QueryResult<TParsed>>.value(
+ _FakeQueryResult_35<TParsed>(this, Invocation.method(#mutate, [options]))))
as _i17.Future<_i12.QueryResult<TParsed>>);
@override
_i17.Stream<_i12.QueryResult<TParsed>> subscribe<TParsed>(_i12.SubscriptionOptions<TParsed>? options) =>
(super.noSuchMethod(Invocation.method(#subscribe, [options]),
- returnValue: Stream<_i12.QueryResult<TParsed>>.empty()) as _i17.Stream<_i12.QueryResult<TParsed>>);
+ returnValue: _i17.Stream<_i12.QueryResult<TParsed>>.empty()) as _i17.Stream<_i12.QueryResult<TParsed>>);
@override
_i17.Future<_i12.QueryResult<TParsed>> fetchMore<TParsed>(_i12.FetchMoreOptions? fetchMoreOptions,
{_i12.QueryOptions<TParsed>? originalOptions, _i12.QueryResult<TParsed>? previousResult}) =>
(super.noSuchMethod(
Invocation.method(
#fetchMore, [fetchMoreOptions], {#originalOptions: originalOptions, #previousResult: previousResult}),
- returnValue: Future<_i12.QueryResult<TParsed>>.value(_FakeQueryResult_35<TParsed>()))
+ returnValue: _i17.Future<_i12.QueryResult<TParsed>>.value(_FakeQueryResult_35<TParsed>(
+ this, Invocation.method(#fetchMore, [fetchMoreOptions], {#originalOptions: originalOptions, #previousResult: previousResult}))))
as _i17.Future<_i12.QueryResult<TParsed>>);
@override
Map<String, dynamic>? readQuery(_i12.Request? request, {bool? optimistic = true}) =>
@@ -957,8 +1257,8 @@
}
@override
- Duration get idleTimeout =>
- (super.noSuchMethod(Invocation.getter(#idleTimeout), returnValue: _FakeDuration_36()) as Duration);
+ Duration get idleTimeout => (super.noSuchMethod(Invocation.getter(#idleTimeout),
+ returnValue: _FakeDuration_36(this, Invocation.getter(#idleTimeout))) as Duration);
@override
set idleTimeout(Duration? _idleTimeout) =>
super.noSuchMethod(Invocation.setter(#idleTimeout, _idleTimeout), returnValueForMissingStub: null);
@@ -997,67 +1297,77 @@
@override
_i17.Future<_i15.HttpClientRequest> open(String? method, String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#open, [method, host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#open, [method, host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> openUrl(String? method, Uri? url) =>
(super.noSuchMethod(Invocation.method(#openUrl, [method, url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#openUrl, [method, url]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> get(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#get, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#get, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> getUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#getUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
- as _i17.Future<_i15.HttpClientRequest>);
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#getUrl, [url])))) as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> post(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#post, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#post, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> postUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#postUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
- as _i17.Future<_i15.HttpClientRequest>);
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#postUrl, [url])))) as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> put(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#put, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#put, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> putUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#putUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
- as _i17.Future<_i15.HttpClientRequest>);
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#putUrl, [url])))) as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> delete(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#delete, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#delete, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> deleteUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#deleteUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#deleteUrl, [url]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> patch(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#patch, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#patch, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> patchUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#patchUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#patchUrl, [url]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> head(String? host, int? port, String? path) =>
(super.noSuchMethod(Invocation.method(#head, [host, port, path]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#head, [host, port, path]))))
as _i17.Future<_i15.HttpClientRequest>);
@override
_i17.Future<_i15.HttpClientRequest> headUrl(Uri? url) => (super.noSuchMethod(Invocation.method(#headUrl, [url]),
- returnValue: Future<_i15.HttpClientRequest>.value(_FakeHttpClientRequest_37()))
- as _i17.Future<_i15.HttpClientRequest>);
+ returnValue: _i17.Future<_i15.HttpClientRequest>.value(
+ _FakeHttpClientRequest_37(this, Invocation.method(#headUrl, [url])))) as _i17.Future<_i15.HttpClientRequest>);
@override
void addCredentials(Uri? url, String? realm, _i15.HttpClientCredentials? credentials) => super
.noSuchMethod(Invocation.method(#addCredentials, [url, realm, credentials]), returnValueForMissingStub: null);
@@ -1107,27 +1417,29 @@
@override
String get method => (super.noSuchMethod(Invocation.getter(#method), returnValue: '') as String);
@override
- Uri get uri => (super.noSuchMethod(Invocation.getter(#uri), returnValue: _FakeUri_38()) as Uri);
+ Uri get uri =>
+ (super.noSuchMethod(Invocation.getter(#uri), returnValue: _FakeUri_38(this, Invocation.getter(#uri))) as Uri);
@override
- _i15.HttpHeaders get headers =>
- (super.noSuchMethod(Invocation.getter(#headers), returnValue: _FakeHttpHeaders_39()) as _i15.HttpHeaders);
+ _i15.HttpHeaders get headers => (super.noSuchMethod(Invocation.getter(#headers),
+ returnValue: _FakeHttpHeaders_39(this, Invocation.getter(#headers))) as _i15.HttpHeaders);
@override
List<_i15.Cookie> get cookies =>
(super.noSuchMethod(Invocation.getter(#cookies), returnValue: <_i15.Cookie>[]) as List<_i15.Cookie>);
@override
_i17.Future<_i15.HttpClientResponse> get done => (super.noSuchMethod(Invocation.getter(#done),
- returnValue: Future<_i15.HttpClientResponse>.value(_FakeHttpClientResponse_40()))
+ returnValue:
+ _i17.Future<_i15.HttpClientResponse>.value(_FakeHttpClientResponse_40(this, Invocation.getter(#done))))
as _i17.Future<_i15.HttpClientResponse>);
@override
- _i16.Encoding get encoding =>
- (super.noSuchMethod(Invocation.getter(#encoding), returnValue: _FakeEncoding_41()) as _i16.Encoding);
+ _i16.Encoding get encoding => (super.noSuchMethod(Invocation.getter(#encoding),
+ returnValue: _FakeEncoding_41(this, Invocation.getter(#encoding))) as _i16.Encoding);
@override
set encoding(_i16.Encoding? _encoding) =>
super.noSuchMethod(Invocation.setter(#encoding, _encoding), returnValueForMissingStub: null);
@override
_i17.Future<_i15.HttpClientResponse> close() => (super.noSuchMethod(Invocation.method(#close, []),
- returnValue: Future<_i15.HttpClientResponse>.value(_FakeHttpClientResponse_40()))
- as _i17.Future<_i15.HttpClientResponse>);
+ returnValue: _i17.Future<_i15.HttpClientResponse>.value(
+ _FakeHttpClientResponse_40(this, Invocation.method(#close, [])))) as _i17.Future<_i15.HttpClientResponse>);
@override
void abort([Object? exception, StackTrace? stackTrace]) =>
super.noSuchMethod(Invocation.method(#abort, [exception, stackTrace]), returnValueForMissingStub: null);
@@ -1150,11 +1462,12 @@
super.noSuchMethod(Invocation.method(#addError, [error, stackTrace]), returnValueForMissingStub: null);
@override
_i17.Future<dynamic> addStream(_i17.Stream<List<int>>? stream) =>
- (super.noSuchMethod(Invocation.method(#addStream, [stream]), returnValue: Future<dynamic>.value())
+ (super.noSuchMethod(Invocation.method(#addStream, [stream]), returnValue: _i17.Future<dynamic>.value())
as _i17.Future<dynamic>);
@override
_i17.Future<dynamic> flush() =>
- (super.noSuchMethod(Invocation.method(#flush, []), returnValue: Future<dynamic>.value()) as _i17.Future<dynamic>);
+ (super.noSuchMethod(Invocation.method(#flush, []), returnValue: _i17.Future<dynamic>.value())
+ as _i17.Future<dynamic>);
}
/// A class which mocks [HttpClientResponse].
@@ -1185,8 +1498,8 @@
(super.noSuchMethod(Invocation.getter(#redirects), returnValue: <_i15.RedirectInfo>[])
as List<_i15.RedirectInfo>);
@override
- _i15.HttpHeaders get headers =>
- (super.noSuchMethod(Invocation.getter(#headers), returnValue: _FakeHttpHeaders_39()) as _i15.HttpHeaders);
+ _i15.HttpHeaders get headers => (super.noSuchMethod(Invocation.getter(#headers),
+ returnValue: _FakeHttpHeaders_39(this, Invocation.getter(#headers))) as _i15.HttpHeaders);
@override
List<_i15.Cookie> get cookies =>
(super.noSuchMethod(Invocation.getter(#cookies), returnValue: <_i15.Cookie>[]) as List<_i15.Cookie>);
@@ -1194,154 +1507,162 @@
bool get isBroadcast => (super.noSuchMethod(Invocation.getter(#isBroadcast), returnValue: false) as bool);
@override
_i17.Future<int> get length =>
- (super.noSuchMethod(Invocation.getter(#length), returnValue: Future<int>.value(0)) as _i17.Future<int>);
+ (super.noSuchMethod(Invocation.getter(#length), returnValue: _i17.Future<int>.value(0)) as _i17.Future<int>);
@override
_i17.Future<bool> get isEmpty =>
- (super.noSuchMethod(Invocation.getter(#isEmpty), returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ (super.noSuchMethod(Invocation.getter(#isEmpty), returnValue: _i17.Future<bool>.value(false))
+ as _i17.Future<bool>);
@override
_i17.Future<List<int>> get first =>
- (super.noSuchMethod(Invocation.getter(#first), returnValue: Future<List<int>>.value(<int>[]))
+ (super.noSuchMethod(Invocation.getter(#first), returnValue: _i17.Future<List<int>>.value(<int>[]))
as _i17.Future<List<int>>);
@override
_i17.Future<List<int>> get last =>
- (super.noSuchMethod(Invocation.getter(#last), returnValue: Future<List<int>>.value(<int>[]))
+ (super.noSuchMethod(Invocation.getter(#last), returnValue: _i17.Future<List<int>>.value(<int>[]))
as _i17.Future<List<int>>);
@override
_i17.Future<List<int>> get single =>
- (super.noSuchMethod(Invocation.getter(#single), returnValue: Future<List<int>>.value(<int>[]))
+ (super.noSuchMethod(Invocation.getter(#single), returnValue: _i17.Future<List<int>>.value(<int>[]))
as _i17.Future<List<int>>);
@override
_i17.Future<_i15.HttpClientResponse> redirect([String? method, Uri? url, bool? followLoops]) =>
(super.noSuchMethod(Invocation.method(#redirect, [method, url, followLoops]),
- returnValue: Future<_i15.HttpClientResponse>.value(_FakeHttpClientResponse_40()))
+ returnValue: _i17.Future<_i15.HttpClientResponse>.value(
+ _FakeHttpClientResponse_40(this, Invocation.method(#redirect, [method, url, followLoops]))))
as _i17.Future<_i15.HttpClientResponse>);
@override
_i17.Future<_i15.Socket> detachSocket() => (super.noSuchMethod(Invocation.method(#detachSocket, []),
- returnValue: Future<_i15.Socket>.value(_FakeSocket_42())) as _i17.Future<_i15.Socket>);
+ returnValue: _i17.Future<_i15.Socket>.value(_FakeSocket_42(this, Invocation.method(#detachSocket, []))))
+ as _i17.Future<_i15.Socket>);
@override
_i17.Stream<List<int>> asBroadcastStream(
{void Function(_i17.StreamSubscription<List<int>>)? onListen,
void Function(_i17.StreamSubscription<List<int>>)? onCancel}) =>
(super.noSuchMethod(Invocation.method(#asBroadcastStream, [], {#onListen: onListen, #onCancel: onCancel}),
- returnValue: Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
+ returnValue: _i17.Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
@override
_i17.StreamSubscription<List<int>> listen(void Function(List<int>)? onData,
{Function? onError, void Function()? onDone, bool? cancelOnError}) =>
(super.noSuchMethod(
- Invocation.method(#listen, [onData], {#onError: onError, #onDone: onDone, #cancelOnError: cancelOnError}),
- returnValue: _FakeStreamSubscription_43<List<int>>()) as _i17.StreamSubscription<List<int>>);
+ Invocation.method(#listen, [onData], {#onError: onError, #onDone: onDone, #cancelOnError: cancelOnError}),
+ returnValue: _FakeStreamSubscription_43<List<int>>(
+ this,
+ Invocation.method(
+ #listen, [onData], {#onError: onError, #onDone: onDone, #cancelOnError: cancelOnError})))
+ as _i17.StreamSubscription<List<int>>);
@override
_i17.Stream<List<int>> where(bool Function(List<int>)? test) =>
- (super.noSuchMethod(Invocation.method(#where, [test]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#where, [test]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Stream<S> map<S>(S Function(List<int>)? convert) =>
- (super.noSuchMethod(Invocation.method(#map, [convert]), returnValue: Stream<S>.empty()) as _i17.Stream<S>);
+ (super.noSuchMethod(Invocation.method(#map, [convert]), returnValue: _i17.Stream<S>.empty()) as _i17.Stream<S>);
@override
_i17.Stream<E> asyncMap<E>(_i17.FutureOr<E> Function(List<int>)? convert) =>
- (super.noSuchMethod(Invocation.method(#asyncMap, [convert]), returnValue: Stream<E>.empty()) as _i17.Stream<E>);
+ (super.noSuchMethod(Invocation.method(#asyncMap, [convert]), returnValue: _i17.Stream<E>.empty())
+ as _i17.Stream<E>);
@override
_i17.Stream<E> asyncExpand<E>(_i17.Stream<E>? Function(List<int>)? convert) =>
- (super.noSuchMethod(Invocation.method(#asyncExpand, [convert]), returnValue: Stream<E>.empty())
+ (super.noSuchMethod(Invocation.method(#asyncExpand, [convert]), returnValue: _i17.Stream<E>.empty())
as _i17.Stream<E>);
@override
_i17.Stream<List<int>> handleError(Function? onError, {bool Function(dynamic)? test}) =>
(super.noSuchMethod(Invocation.method(#handleError, [onError], {#test: test}),
- returnValue: Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
+ returnValue: _i17.Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
@override
_i17.Stream<S> expand<S>(Iterable<S> Function(List<int>)? convert) =>
- (super.noSuchMethod(Invocation.method(#expand, [convert]), returnValue: Stream<S>.empty()) as _i17.Stream<S>);
+ (super.noSuchMethod(Invocation.method(#expand, [convert]), returnValue: _i17.Stream<S>.empty())
+ as _i17.Stream<S>);
@override
_i17.Future<dynamic> pipe(_i17.StreamConsumer<List<int>>? streamConsumer) =>
- (super.noSuchMethod(Invocation.method(#pipe, [streamConsumer]), returnValue: Future<dynamic>.value())
+ (super.noSuchMethod(Invocation.method(#pipe, [streamConsumer]), returnValue: _i17.Future<dynamic>.value())
as _i17.Future<dynamic>);
@override
_i17.Stream<S> transform<S>(_i17.StreamTransformer<List<int>, S>? streamTransformer) =>
- (super.noSuchMethod(Invocation.method(#transform, [streamTransformer]), returnValue: Stream<S>.empty())
+ (super.noSuchMethod(Invocation.method(#transform, [streamTransformer]), returnValue: _i17.Stream<S>.empty())
as _i17.Stream<S>);
@override
_i17.Future<List<int>> reduce(List<int> Function(List<int>, List<int>)? combine) =>
- (super.noSuchMethod(Invocation.method(#reduce, [combine]), returnValue: Future<List<int>>.value(<int>[]))
+ (super.noSuchMethod(Invocation.method(#reduce, [combine]), returnValue: _i17.Future<List<int>>.value(<int>[]))
as _i17.Future<List<int>>);
@override
_i17.Future<S> fold<S>(S? initialValue, S Function(S, List<int>)? combine) =>
- (super.noSuchMethod(Invocation.method(#fold, [initialValue, combine]), returnValue: Future<S>.value(null))
+ (super.noSuchMethod(Invocation.method(#fold, [initialValue, combine]), returnValue: _i17.Future<S>.value(null))
as _i17.Future<S>);
@override
_i17.Future<String> join([String? separator = r'']) =>
- (super.noSuchMethod(Invocation.method(#join, [separator]), returnValue: Future<String>.value(''))
+ (super.noSuchMethod(Invocation.method(#join, [separator]), returnValue: _i17.Future<String>.value(''))
as _i17.Future<String>);
@override
_i17.Future<bool> contains(Object? needle) =>
- (super.noSuchMethod(Invocation.method(#contains, [needle]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#contains, [needle]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<dynamic> forEach(void Function(List<int>)? action) =>
- (super.noSuchMethod(Invocation.method(#forEach, [action]), returnValue: Future<dynamic>.value())
+ (super.noSuchMethod(Invocation.method(#forEach, [action]), returnValue: _i17.Future<dynamic>.value())
as _i17.Future<dynamic>);
@override
_i17.Future<bool> every(bool Function(List<int>)? test) =>
- (super.noSuchMethod(Invocation.method(#every, [test]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#every, [test]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<bool> any(bool Function(List<int>)? test) =>
- (super.noSuchMethod(Invocation.method(#any, [test]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#any, [test]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<R> cast<R>() =>
- (super.noSuchMethod(Invocation.method(#cast, []), returnValue: Stream<R>.empty()) as _i17.Stream<R>);
+ (super.noSuchMethod(Invocation.method(#cast, []), returnValue: _i17.Stream<R>.empty()) as _i17.Stream<R>);
@override
- _i17.Future<List<List<int>>> toList() =>
- (super.noSuchMethod(Invocation.method(#toList, []), returnValue: Future<List<List<int>>>.value(<List<int>>[]))
- as _i17.Future<List<List<int>>>);
+ _i17.Future<List<List<int>>> toList() => (super.noSuchMethod(Invocation.method(#toList, []),
+ returnValue: _i17.Future<List<List<int>>>.value(<List<int>>[])) as _i17.Future<List<List<int>>>);
@override
_i17.Future<Set<List<int>>> toSet() =>
- (super.noSuchMethod(Invocation.method(#toSet, []), returnValue: Future<Set<List<int>>>.value(<List<int>>{}))
+ (super.noSuchMethod(Invocation.method(#toSet, []), returnValue: _i17.Future<Set<List<int>>>.value(<List<int>>{}))
as _i17.Future<Set<List<int>>>);
@override
_i17.Future<E> drain<E>([E? futureValue]) =>
- (super.noSuchMethod(Invocation.method(#drain, [futureValue]), returnValue: Future<E>.value(null))
+ (super.noSuchMethod(Invocation.method(#drain, [futureValue]), returnValue: _i17.Future<E>.value(null))
as _i17.Future<E>);
@override
_i17.Stream<List<int>> take(int? count) =>
- (super.noSuchMethod(Invocation.method(#take, [count]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#take, [count]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Stream<List<int>> takeWhile(bool Function(List<int>)? test) =>
- (super.noSuchMethod(Invocation.method(#takeWhile, [test]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#takeWhile, [test]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Stream<List<int>> skip(int? count) =>
- (super.noSuchMethod(Invocation.method(#skip, [count]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#skip, [count]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Stream<List<int>> skipWhile(bool Function(List<int>)? test) =>
- (super.noSuchMethod(Invocation.method(#skipWhile, [test]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#skipWhile, [test]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Stream<List<int>> distinct([bool Function(List<int>, List<int>)? equals]) =>
- (super.noSuchMethod(Invocation.method(#distinct, [equals]), returnValue: Stream<List<int>>.empty())
+ (super.noSuchMethod(Invocation.method(#distinct, [equals]), returnValue: _i17.Stream<List<int>>.empty())
as _i17.Stream<List<int>>);
@override
_i17.Future<List<int>> firstWhere(bool Function(List<int>)? test, {List<int> Function()? orElse}) =>
(super.noSuchMethod(Invocation.method(#firstWhere, [test], {#orElse: orElse}),
- returnValue: Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
+ returnValue: _i17.Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
@override
_i17.Future<List<int>> lastWhere(bool Function(List<int>)? test, {List<int> Function()? orElse}) =>
(super.noSuchMethod(Invocation.method(#lastWhere, [test], {#orElse: orElse}),
- returnValue: Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
+ returnValue: _i17.Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
@override
_i17.Future<List<int>> singleWhere(bool Function(List<int>)? test, {List<int> Function()? orElse}) =>
(super.noSuchMethod(Invocation.method(#singleWhere, [test], {#orElse: orElse}),
- returnValue: Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
+ returnValue: _i17.Future<List<int>>.value(<int>[])) as _i17.Future<List<int>>);
@override
_i17.Future<List<int>> elementAt(int? index) =>
- (super.noSuchMethod(Invocation.method(#elementAt, [index]), returnValue: Future<List<int>>.value(<int>[]))
+ (super.noSuchMethod(Invocation.method(#elementAt, [index]), returnValue: _i17.Future<List<int>>.value(<int>[]))
as _i17.Future<List<int>>);
@override
_i17.Stream<List<int>> timeout(Duration? timeLimit, {void Function(_i17.EventSink<List<int>>)? onTimeout}) =>
(super.noSuchMethod(Invocation.method(#timeout, [timeLimit], {#onTimeout: onTimeout}),
- returnValue: Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
+ returnValue: _i17.Stream<List<int>>.empty()) as _i17.Stream<List<int>>);
}
/// A class which mocks [JobsResource].
@@ -1355,16 +1676,20 @@
@override
_i17.Future<_i6.JobCancelResponse> cancel(String? projectId, String? jobId, {String? location, String? $fields}) =>
(super.noSuchMethod(Invocation.method(#cancel, [projectId, jobId], {#location: location, #$fields: $fields}),
- returnValue: Future<_i6.JobCancelResponse>.value(_FakeJobCancelResponse_44()))
+ returnValue: _i17.Future<_i6.JobCancelResponse>.value(_FakeJobCancelResponse_44(
+ this, Invocation.method(#cancel, [projectId, jobId], {#location: location, #$fields: $fields}))))
as _i17.Future<_i6.JobCancelResponse>);
@override
_i17.Future<void> delete(String? projectId, String? jobId, {String? location, String? $fields}) =>
(super.noSuchMethod(Invocation.method(#delete, [projectId, jobId], {#location: location, #$fields: $fields}),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<_i6.Job> get(String? projectId, String? jobId, {String? location, String? $fields}) =>
(super.noSuchMethod(Invocation.method(#get, [projectId, jobId], {#location: location, #$fields: $fields}),
- returnValue: Future<_i6.Job>.value(_FakeJob_45())) as _i17.Future<_i6.Job>);
+ returnValue: _i17.Future<_i6.Job>.value(_FakeJob_45(
+ this, Invocation.method(#get, [projectId, jobId], {#location: location, #$fields: $fields}))))
+ as _i17.Future<_i6.Job>);
@override
_i17.Future<_i6.GetQueryResultsResponse> getQueryResults(String? projectId, String? jobId,
{String? location,
@@ -1374,6 +1699,19 @@
int? timeoutMs,
String? $fields}) =>
(super.noSuchMethod(
+ Invocation.method(#getQueryResults, [
+ projectId,
+ jobId
+ ], {
+ #location: location,
+ #maxResults: maxResults,
+ #pageToken: pageToken,
+ #startIndex: startIndex,
+ #timeoutMs: timeoutMs,
+ #$fields: $fields
+ }),
+ returnValue: _i17.Future<_i6.GetQueryResultsResponse>.value(_FakeGetQueryResultsResponse_46(
+ this,
Invocation.method(#getQueryResults, [
projectId,
jobId
@@ -1384,18 +1722,23 @@
#startIndex: startIndex,
#timeoutMs: timeoutMs,
#$fields: $fields
- }),
- returnValue: Future<_i6.GetQueryResultsResponse>.value(_FakeGetQueryResultsResponse_46()))
- as _i17.Future<_i6.GetQueryResultsResponse>);
+ })))) as _i17.Future<_i6.GetQueryResultsResponse>);
@override
_i17.Future<_i6.Job> insert(_i6.Job? request, String? projectId,
{String? $fields,
_i6.UploadOptions? uploadOptions = _i6.UploadOptions.defaultOptions,
_i6.Media? uploadMedia}) =>
- (super.noSuchMethod(
- Invocation.method(#insert, [request, projectId],
- {#$fields: $fields, #uploadOptions: uploadOptions, #uploadMedia: uploadMedia}),
- returnValue: Future<_i6.Job>.value(_FakeJob_45())) as _i17.Future<_i6.Job>);
+ (super.noSuchMethod(Invocation.method(#insert, [request, projectId], {#$fields: $fields, #uploadOptions: uploadOptions, #uploadMedia: uploadMedia}),
+ returnValue: _i17.Future<_i6.Job>.value(_FakeJob_45(
+ this,
+ Invocation.method(#insert, [
+ request,
+ projectId
+ ], {
+ #$fields: $fields,
+ #uploadOptions: uploadOptions,
+ #uploadMedia: uploadMedia
+ })))) as _i17.Future<_i6.Job>);
@override
_i17.Future<_i6.JobList> list(String? projectId,
{bool? allUsers,
@@ -1421,11 +1764,27 @@
#stateFilter: stateFilter,
#$fields: $fields
}),
- returnValue: Future<_i6.JobList>.value(_FakeJobList_47())) as _i17.Future<_i6.JobList>);
+ returnValue: _i17.Future<_i6.JobList>.value(_FakeJobList_47(
+ this,
+ Invocation.method(#list, [
+ projectId
+ ], {
+ #allUsers: allUsers,
+ #maxCreationTime: maxCreationTime,
+ #maxResults: maxResults,
+ #minCreationTime: minCreationTime,
+ #pageToken: pageToken,
+ #parentJobId: parentJobId,
+ #projection: projection,
+ #stateFilter: stateFilter,
+ #$fields: $fields
+ })))) as _i17.Future<_i6.JobList>);
@override
_i17.Future<_i6.QueryResponse> query(_i6.QueryRequest? request, String? projectId, {String? $fields}) =>
(super.noSuchMethod(Invocation.method(#query, [request, projectId], {#$fields: $fields}),
- returnValue: Future<_i6.QueryResponse>.value(_FakeQueryResponse_48())) as _i17.Future<_i6.QueryResponse>);
+ returnValue: _i17.Future<_i6.QueryResponse>.value(
+ _FakeQueryResponse_48(this, Invocation.method(#query, [request, projectId], {#$fields: $fields}))))
+ as _i17.Future<_i6.QueryResponse>);
}
/// A class which mocks [LuciBuildService].
@@ -1437,55 +1796,56 @@
}
@override
- _i18.BuildBucketClient get buildBucketClient =>
- (super.noSuchMethod(Invocation.getter(#buildBucketClient), returnValue: _FakeBuildBucketClient_49())
- as _i18.BuildBucketClient);
+ _i18.BuildBucketClient get buildBucketClient => (super.noSuchMethod(Invocation.getter(#buildBucketClient),
+ returnValue: _FakeBuildBucketClient_49(this, Invocation.getter(#buildBucketClient))) as _i18.BuildBucketClient);
@override
set buildBucketClient(_i18.BuildBucketClient? _buildBucketClient) =>
super.noSuchMethod(Invocation.setter(#buildBucketClient, _buildBucketClient), returnValueForMissingStub: null);
@override
- _i3.Config get config => (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1()) as _i3.Config);
+ _i3.Config get config =>
+ (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1(this, Invocation.getter(#config)))
+ as _i3.Config);
@override
set config(_i3.Config? _config) =>
super.noSuchMethod(Invocation.setter(#config, _config), returnValueForMissingStub: null);
@override
- _i11.GithubChecksUtil get githubChecksUtil =>
- (super.noSuchMethod(Invocation.getter(#githubChecksUtil), returnValue: _FakeGithubChecksUtil_17())
- as _i11.GithubChecksUtil);
+ _i11.GithubChecksUtil get githubChecksUtil => (super.noSuchMethod(Invocation.getter(#githubChecksUtil),
+ returnValue: _FakeGithubChecksUtil_17(this, Invocation.getter(#githubChecksUtil))) as _i11.GithubChecksUtil);
@override
set githubChecksUtil(_i11.GithubChecksUtil? _githubChecksUtil) =>
super.noSuchMethod(Invocation.setter(#githubChecksUtil, _githubChecksUtil), returnValueForMissingStub: null);
@override
- _i7.GerritService get gerritService =>
- (super.noSuchMethod(Invocation.getter(#gerritService), returnValue: _FakeGerritService_6()) as _i7.GerritService);
+ _i7.GerritService get gerritService => (super.noSuchMethod(Invocation.getter(#gerritService),
+ returnValue: _FakeGerritService_6(this, Invocation.getter(#gerritService))) as _i7.GerritService);
@override
set gerritService(_i7.GerritService? _gerritService) =>
super.noSuchMethod(Invocation.setter(#gerritService, _gerritService), returnValueForMissingStub: null);
@override
_i19.PubSub get pubsub =>
- (super.noSuchMethod(Invocation.getter(#pubsub), returnValue: _FakePubSub_50()) as _i19.PubSub);
+ (super.noSuchMethod(Invocation.getter(#pubsub), returnValue: _FakePubSub_50(this, Invocation.getter(#pubsub)))
+ as _i19.PubSub);
@override
_i17.Future<List<List<_i9.Request>>> shard(List<_i9.Request>? requests, int? max) =>
(super.noSuchMethod(Invocation.method(#shard, [requests, max]),
- returnValue: Future<List<List<_i9.Request>>>.value(<List<_i9.Request>>[]))
+ returnValue: _i17.Future<List<List<_i9.Request>>>.value(<List<_i9.Request>>[]))
as _i17.Future<List<List<_i9.Request>>>);
@override
_i17.Future<Iterable<_i9.Build>> getTryBuilds(_i10.RepositorySlug? slug, String? sha, String? builderName) =>
(super.noSuchMethod(Invocation.method(#getTryBuilds, [slug, sha, builderName]),
- returnValue: Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
+ returnValue: _i17.Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
@override
_i17.Future<Iterable<_i9.Build>> getProdBuilds(_i10.RepositorySlug? slug, String? commitSha, String? builderName) =>
(super.noSuchMethod(Invocation.method(#getProdBuilds, [slug, commitSha, builderName]),
- returnValue: Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
+ returnValue: _i17.Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
@override
_i17.Future<Iterable<_i9.Build>> getBuilds(_i10.RepositorySlug? slug, String? commitSha, String? builderName,
String? bucket, Map<String, List<String>>? tags) =>
(super.noSuchMethod(Invocation.method(#getBuilds, [slug, commitSha, builderName, bucket, tags]),
- returnValue: Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
+ returnValue: _i17.Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
@override
_i17.Future<Map<String?, _i9.Build?>> tryBuildsForPullRequest(_i10.PullRequest? pullRequest) =>
(super.noSuchMethod(Invocation.method(#tryBuildsForPullRequest, [pullRequest]),
- returnValue: Future<Map<String?, _i9.Build?>>.value(<String?, _i9.Build?>{}))
+ returnValue: _i17.Future<Map<String?, _i9.Build?>>.value(<String?, _i9.Build?>{}))
as _i17.Future<Map<String?, _i9.Build?>>);
@override
_i17.Future<List<_i33.Target>> scheduleTryBuilds(
@@ -1493,41 +1853,43 @@
(super.noSuchMethod(
Invocation.method(#scheduleTryBuilds, [],
{#targets: targets, #pullRequest: pullRequest, #checkSuiteEvent: checkSuiteEvent}),
- returnValue: Future<List<_i33.Target>>.value(<_i33.Target>[])) as _i17.Future<List<_i33.Target>>);
+ returnValue: _i17.Future<List<_i33.Target>>.value(<_i33.Target>[])) as _i17.Future<List<_i33.Target>>);
@override
_i17.Future<void> cancelBuilds(_i10.PullRequest? pullRequest, String? reason) =>
(super.noSuchMethod(Invocation.method(#cancelBuilds, [pullRequest, reason]),
- returnValue: Future<void>.value(), returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<List<_i9.Build?>> failedBuilds(_i10.PullRequest? pullRequest, List<_i33.Target>? targets) =>
(super.noSuchMethod(Invocation.method(#failedBuilds, [pullRequest, targets]),
- returnValue: Future<List<_i9.Build?>>.value(<_i9.Build?>[])) as _i17.Future<List<_i9.Build?>>);
+ returnValue: _i17.Future<List<_i9.Build?>>.value(<_i9.Build?>[])) as _i17.Future<List<_i9.Build?>>);
@override
_i17.Future<bool> rescheduleBuild(
{String? commitSha, String? builderName, _i30.BuildPushMessage? buildPushMessage}) =>
(super.noSuchMethod(
Invocation.method(#rescheduleBuild, [],
{#commitSha: commitSha, #builderName: builderName, #buildPushMessage: buildPushMessage}),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Future<bool> rescheduleUsingCheckRunEvent(_i34.CheckRunEvent? checkRunEvent) =>
(super.noSuchMethod(Invocation.method(#rescheduleUsingCheckRunEvent, [checkRunEvent]),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
- _i17.Future<_i9.Build> getTryBuildById(String? id, {String? fields}) =>
- (super.noSuchMethod(Invocation.method(#getTryBuildById, [id], {#fields: fields}),
- returnValue: Future<_i9.Build>.value(_FakeBuild_8())) as _i17.Future<_i9.Build>);
+ _i17.Future<_i9.Build> getTryBuildById(String? id, {String? fields}) => (super.noSuchMethod(
+ Invocation.method(#getTryBuildById, [id], {#fields: fields}),
+ returnValue: _i17.Future<_i9.Build>.value(
+ _FakeBuild_8(this, Invocation.method(#getTryBuildById, [id], {#fields: fields})))) as _i17.Future<_i9.Build>);
@override
_i17.Future<Set<String>> getAvailableBuilderSet({String? project = r'flutter', String? bucket = r'prod'}) =>
(super.noSuchMethod(Invocation.method(#getAvailableBuilderSet, [], {#project: project, #bucket: bucket}),
- returnValue: Future<Set<String>>.value(<String>{})) as _i17.Future<Set<String>>);
+ returnValue: _i17.Future<Set<String>>.value(<String>{})) as _i17.Future<Set<String>>);
@override
_i17.Future<void> schedulePostsubmitBuilds(
{_i35.Commit? commit, List<_i36.Tuple<_i33.Target, _i37.Task, int>>? toBeScheduled}) =>
(super.noSuchMethod(
Invocation.method(#schedulePostsubmitBuilds, [], {#commit: commit, #toBeScheduled: toBeScheduled}),
- returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i17.Future<void>);
+ returnValue: _i17.Future<void>.value(),
+ returnValueForMissingStub: _i17.Future<void>.value()) as _i17.Future<void>);
@override
_i17.Future<bool> checkRerunBuilder(
{_i35.Commit? commit,
@@ -1545,7 +1907,7 @@
#tags: tags,
#ignoreChecks: ignoreChecks
}),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
}
/// A class which mocks [LuciService].
@@ -1558,21 +1920,21 @@
}
@override
- _i18.BuildBucketClient get buildBucketClient =>
- (super.noSuchMethod(Invocation.getter(#buildBucketClient), returnValue: _FakeBuildBucketClient_49())
- as _i18.BuildBucketClient);
+ _i18.BuildBucketClient get buildBucketClient => (super.noSuchMethod(Invocation.getter(#buildBucketClient),
+ returnValue: _FakeBuildBucketClient_49(this, Invocation.getter(#buildBucketClient))) as _i18.BuildBucketClient);
@override
- _i3.Config get config => (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1()) as _i3.Config);
+ _i3.Config get config =>
+ (super.noSuchMethod(Invocation.getter(#config), returnValue: _FakeConfig_1(this, Invocation.getter(#config)))
+ as _i3.Config);
@override
- _i20.ClientContext get clientContext =>
- (super.noSuchMethod(Invocation.getter(#clientContext), returnValue: _FakeClientContext_51())
- as _i20.ClientContext);
+ _i20.ClientContext get clientContext => (super.noSuchMethod(Invocation.getter(#clientContext),
+ returnValue: _FakeClientContext_51(this, Invocation.getter(#clientContext))) as _i20.ClientContext);
@override
_i17.Future<Map<_i39.BranchLuciBuilder, Map<String, List<_i39.LuciTask>>>> getBranchRecentTasks(
{List<_i39.LuciBuilder>? builders, bool? requireTaskName = false}) =>
(super.noSuchMethod(
Invocation.method(#getBranchRecentTasks, [], {#builders: builders, #requireTaskName: requireTaskName}),
- returnValue: Future<Map<_i39.BranchLuciBuilder, Map<String, List<_i39.LuciTask>>>>.value(
+ returnValue: _i17.Future<Map<_i39.BranchLuciBuilder, Map<String, List<_i39.LuciTask>>>>.value(
<_i39.BranchLuciBuilder, Map<String, List<_i39.LuciTask>>>{}))
as _i17.Future<Map<_i39.BranchLuciBuilder, Map<String, List<_i39.LuciTask>>>>);
@override
@@ -1583,19 +1945,18 @@
_i17.Future<List<_i9.Build>> getBuildsForBuilderList(List<_i39.LuciBuilder>? builders,
{bool? requireTaskName = false}) =>
(super.noSuchMethod(Invocation.method(#getBuildsForBuilderList, [builders], {#requireTaskName: requireTaskName}),
- returnValue: Future<List<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<List<_i9.Build>>);
+ returnValue: _i17.Future<List<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<List<_i9.Build>>);
@override
_i17.Future<Map<_i39.LuciBuilder, List<_i39.LuciTask>>> getRecentTasks(
{List<_i39.LuciBuilder>? builders, bool? requireTaskName = false}) =>
(super.noSuchMethod(
- Invocation.method(#getRecentTasks, [], {#builders: builders, #requireTaskName: requireTaskName}),
- returnValue:
- Future<Map<_i39.LuciBuilder, List<_i39.LuciTask>>>.value(<_i39.LuciBuilder, List<_i39.LuciTask>>{}))
- as _i17.Future<Map<_i39.LuciBuilder, List<_i39.LuciTask>>>);
+ Invocation.method(#getRecentTasks, [], {#builders: builders, #requireTaskName: requireTaskName}),
+ returnValue: _i17.Future<Map<_i39.LuciBuilder, List<_i39.LuciTask>>>.value(
+ <_i39.LuciBuilder, List<_i39.LuciTask>>{})) as _i17.Future<Map<_i39.LuciBuilder, List<_i39.LuciTask>>>);
@override
_i17.Future<Iterable<_i9.Build>> getBuilds(bool? requireTaskName, List<_i39.LuciBuilder>? builders) =>
(super.noSuchMethod(Invocation.method(#getBuilds, [requireTaskName, builders]),
- returnValue: Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
+ returnValue: _i17.Future<Iterable<_i9.Build>>.value(<_i9.Build>[])) as _i17.Future<Iterable<_i9.Build>>);
}
/// A class which mocks [ProcessManager].
@@ -1623,7 +1984,17 @@
#runInShell: runInShell,
#mode: mode
}),
- returnValue: Future<_i15.Process>.value(_FakeProcess_52())) as _i17.Future<_i15.Process>);
+ returnValue: _i17.Future<_i15.Process>.value(_FakeProcess_52(
+ this,
+ Invocation.method(#start, [
+ command
+ ], {
+ #workingDirectory: workingDirectory,
+ #environment: environment,
+ #includeParentEnvironment: includeParentEnvironment,
+ #runInShell: runInShell,
+ #mode: mode
+ })))) as _i17.Future<_i15.Process>);
@override
_i17.Future<_i15.ProcessResult> run(List<Object>? command,
{String? workingDirectory,
@@ -1643,7 +2014,18 @@
#stdoutEncoding: stdoutEncoding,
#stderrEncoding: stderrEncoding
}),
- returnValue: Future<_i15.ProcessResult>.value(_FakeProcessResult_53())) as _i17.Future<_i15.ProcessResult>);
+ returnValue: _i17.Future<_i15.ProcessResult>.value(_FakeProcessResult_53(
+ this,
+ Invocation.method(#run, [
+ command
+ ], {
+ #workingDirectory: workingDirectory,
+ #environment: environment,
+ #includeParentEnvironment: includeParentEnvironment,
+ #runInShell: runInShell,
+ #stdoutEncoding: stdoutEncoding,
+ #stderrEncoding: stderrEncoding
+ })))) as _i17.Future<_i15.ProcessResult>);
@override
_i15.ProcessResult runSync(List<Object>? command,
{String? workingDirectory,
@@ -1663,7 +2045,18 @@
#stdoutEncoding: stdoutEncoding,
#stderrEncoding: stderrEncoding
}),
- returnValue: _FakeProcessResult_53()) as _i15.ProcessResult);
+ returnValue: _FakeProcessResult_53(
+ this,
+ Invocation.method(#runSync, [
+ command
+ ], {
+ #workingDirectory: workingDirectory,
+ #environment: environment,
+ #includeParentEnvironment: includeParentEnvironment,
+ #runInShell: runInShell,
+ #stdoutEncoding: stdoutEncoding,
+ #stderrEncoding: stderrEncoding
+ }))) as _i15.ProcessResult);
@override
bool canRun(dynamic executable, {String? workingDirectory}) =>
(super.noSuchMethod(Invocation.method(#canRun, [executable], {#workingDirectory: workingDirectory}),
@@ -1683,7 +2076,8 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
_i17.Stream<_i10.PullRequest> list(_i10.RepositorySlug? slug,
{int? pages,
@@ -1695,60 +2089,69 @@
(super.noSuchMethod(
Invocation.method(#list, [slug],
{#pages: pages, #base: base, #direction: direction, #head: head, #sort: sort, #state: state}),
- returnValue: Stream<_i10.PullRequest>.empty()) as _i17.Stream<_i10.PullRequest>);
+ returnValue: _i17.Stream<_i10.PullRequest>.empty()) as _i17.Stream<_i10.PullRequest>);
@override
- _i17.Future<_i10.PullRequest> get(_i10.RepositorySlug? slug, int? number) =>
- (super.noSuchMethod(Invocation.method(#get, [slug, number]),
- returnValue: Future<_i10.PullRequest>.value(_FakePullRequest_22())) as _i17.Future<_i10.PullRequest>);
+ _i17.Future<_i10.PullRequest> get(_i10.RepositorySlug? slug, int? number) => (super.noSuchMethod(
+ Invocation.method(#get, [slug, number]),
+ returnValue:
+ _i17.Future<_i10.PullRequest>.value(_FakePullRequest_22(this, Invocation.method(#get, [slug, number]))))
+ as _i17.Future<_i10.PullRequest>);
@override
_i17.Future<_i10.PullRequest> create(_i10.RepositorySlug? slug, _i10.CreatePullRequest? request) =>
(super.noSuchMethod(Invocation.method(#create, [slug, request]),
- returnValue: Future<_i10.PullRequest>.value(_FakePullRequest_22())) as _i17.Future<_i10.PullRequest>);
+ returnValue: _i17.Future<_i10.PullRequest>.value(
+ _FakePullRequest_22(this, Invocation.method(#create, [slug, request]))))
+ as _i17.Future<_i10.PullRequest>);
@override
_i17.Future<_i10.PullRequest> edit(_i10.RepositorySlug? slug, int? number,
{String? title, String? body, String? state, String? base}) =>
(super.noSuchMethod(
- Invocation.method(#edit, [slug, number], {#title: title, #body: body, #state: state, #base: base}),
- returnValue: Future<_i10.PullRequest>.value(_FakePullRequest_22())) as _i17.Future<_i10.PullRequest>);
+ Invocation.method(#edit, [slug, number], {#title: title, #body: body, #state: state, #base: base}),
+ returnValue: _i17.Future<_i10.PullRequest>.value(_FakePullRequest_22(this,
+ Invocation.method(#edit, [slug, number], {#title: title, #body: body, #state: state, #base: base}))))
+ as _i17.Future<_i10.PullRequest>);
@override
_i17.Stream<_i10.RepositoryCommit> listCommits(_i10.RepositorySlug? slug, int? number) =>
(super.noSuchMethod(Invocation.method(#listCommits, [slug, number]),
- returnValue: Stream<_i10.RepositoryCommit>.empty()) as _i17.Stream<_i10.RepositoryCommit>);
+ returnValue: _i17.Stream<_i10.RepositoryCommit>.empty()) as _i17.Stream<_i10.RepositoryCommit>);
@override
_i17.Stream<_i10.PullRequestFile> listFiles(_i10.RepositorySlug? slug, int? number) =>
(super.noSuchMethod(Invocation.method(#listFiles, [slug, number]),
- returnValue: Stream<_i10.PullRequestFile>.empty()) as _i17.Stream<_i10.PullRequestFile>);
+ returnValue: _i17.Stream<_i10.PullRequestFile>.empty()) as _i17.Stream<_i10.PullRequestFile>);
@override
_i17.Stream<_i10.PullRequestReview> listReviews(_i10.RepositorySlug? slug, int? number) =>
(super.noSuchMethod(Invocation.method(#listReviews, [slug, number]),
- returnValue: Stream<_i10.PullRequestReview>.empty()) as _i17.Stream<_i10.PullRequestReview>);
+ returnValue: _i17.Stream<_i10.PullRequestReview>.empty()) as _i17.Stream<_i10.PullRequestReview>);
@override
_i17.Future<bool> isMerged(_i10.RepositorySlug? slug, int? number) =>
- (super.noSuchMethod(Invocation.method(#isMerged, [slug, number]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#isMerged, [slug, number]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<_i10.PullRequestMerge> merge(_i10.RepositorySlug? slug, int? number, {String? message}) =>
(super.noSuchMethod(Invocation.method(#merge, [slug, number], {#message: message}),
- returnValue: Future<_i10.PullRequestMerge>.value(_FakePullRequestMerge_54()))
+ returnValue: _i17.Future<_i10.PullRequestMerge>.value(
+ _FakePullRequestMerge_54(this, Invocation.method(#merge, [slug, number], {#message: message}))))
as _i17.Future<_i10.PullRequestMerge>);
@override
_i17.Stream<_i10.PullRequestComment> listCommentsByPullRequest(_i10.RepositorySlug? slug, int? number) =>
(super.noSuchMethod(Invocation.method(#listCommentsByPullRequest, [slug, number]),
- returnValue: Stream<_i10.PullRequestComment>.empty()) as _i17.Stream<_i10.PullRequestComment>);
+ returnValue: _i17.Stream<_i10.PullRequestComment>.empty()) as _i17.Stream<_i10.PullRequestComment>);
@override
- _i17.Stream<_i10.PullRequestComment> listComments(_i10.RepositorySlug? slug) => (super
- .noSuchMethod(Invocation.method(#listComments, [slug]), returnValue: Stream<_i10.PullRequestComment>.empty())
- as _i17.Stream<_i10.PullRequestComment>);
+ _i17.Stream<_i10.PullRequestComment> listComments(_i10.RepositorySlug? slug) =>
+ (super.noSuchMethod(Invocation.method(#listComments, [slug]),
+ returnValue: _i17.Stream<_i10.PullRequestComment>.empty()) as _i17.Stream<_i10.PullRequestComment>);
@override
_i17.Future<_i10.PullRequestComment> createComment(
_i10.RepositorySlug? slug, int? number, _i10.CreatePullRequestComment? comment) =>
(super.noSuchMethod(Invocation.method(#createComment, [slug, number, comment]),
- returnValue: Future<_i10.PullRequestComment>.value(_FakePullRequestComment_55()))
+ returnValue: _i17.Future<_i10.PullRequestComment>.value(
+ _FakePullRequestComment_55(this, Invocation.method(#createComment, [slug, number, comment]))))
as _i17.Future<_i10.PullRequestComment>);
@override
_i17.Future<_i10.PullRequestReview> createReview(_i10.RepositorySlug? slug, _i10.CreatePullRequestReview? review) =>
(super.noSuchMethod(Invocation.method(#createReview, [slug, review]),
- returnValue: Future<_i10.PullRequestReview>.value(_FakePullRequestReview_56()))
+ returnValue: _i17.Future<_i10.PullRequestReview>.value(
+ _FakePullRequestReview_56(this, Invocation.method(#createReview, [slug, review]))))
as _i17.Future<_i10.PullRequestReview>);
}
@@ -1762,42 +2165,48 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
_i17.Stream<_i10.Repository> listRepositories(
{String? type = r'owner', String? sort = r'full_name', String? direction = r'asc'}) =>
(super.noSuchMethod(Invocation.method(#listRepositories, [], {#type: type, #sort: sort, #direction: direction}),
- returnValue: Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
+ returnValue: _i17.Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
@override
_i17.Stream<_i10.Repository> listUserRepositories(String? user,
{String? type = r'owner', String? sort = r'full_name', String? direction = r'asc'}) =>
(super.noSuchMethod(
Invocation.method(#listUserRepositories, [user], {#type: type, #sort: sort, #direction: direction}),
- returnValue: Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
+ returnValue: _i17.Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
@override
_i17.Stream<_i10.Repository> listOrganizationRepositories(String? org, {String? type = r'all'}) =>
(super.noSuchMethod(Invocation.method(#listOrganizationRepositories, [org], {#type: type}),
- returnValue: Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
+ returnValue: _i17.Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
@override
_i17.Stream<_i10.Repository> listPublicRepositories({int? limit = 50, DateTime? since}) =>
(super.noSuchMethod(Invocation.method(#listPublicRepositories, [], {#limit: limit, #since: since}),
- returnValue: Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
+ returnValue: _i17.Stream<_i10.Repository>.empty()) as _i17.Stream<_i10.Repository>);
@override
_i17.Future<_i10.Repository> createRepository(_i10.CreateRepository? repository, {String? org}) =>
(super.noSuchMethod(Invocation.method(#createRepository, [repository], {#org: org}),
- returnValue: Future<_i10.Repository>.value(_FakeRepository_57())) as _i17.Future<_i10.Repository>);
+ returnValue: _i17.Future<_i10.Repository>.value(
+ _FakeRepository_57(this, Invocation.method(#createRepository, [repository], {#org: org}))))
+ as _i17.Future<_i10.Repository>);
@override
_i17.Future<_i10.LicenseDetails> getLicense(_i10.RepositorySlug? slug) => (super.noSuchMethod(
Invocation.method(#getLicense, [slug]),
- returnValue: Future<_i10.LicenseDetails>.value(_FakeLicenseDetails_58())) as _i17.Future<_i10.LicenseDetails>);
+ returnValue: _i17.Future<_i10.LicenseDetails>.value(
+ _FakeLicenseDetails_58(this, Invocation.method(#getLicense, [slug])))) as _i17.Future<_i10.LicenseDetails>);
@override
- _i17.Future<_i10.Repository> getRepository(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#getRepository, [slug]),
- returnValue: Future<_i10.Repository>.value(_FakeRepository_57())) as _i17.Future<_i10.Repository>);
+ _i17.Future<_i10.Repository> getRepository(_i10.RepositorySlug? slug) => (super.noSuchMethod(
+ Invocation.method(#getRepository, [slug]),
+ returnValue:
+ _i17.Future<_i10.Repository>.value(_FakeRepository_57(this, Invocation.method(#getRepository, [slug]))))
+ as _i17.Future<_i10.Repository>);
@override
- _i17.Stream<_i10.Repository> getRepositories(List<_i10.RepositorySlug>? slugs) =>
- (super.noSuchMethod(Invocation.method(#getRepositories, [slugs]), returnValue: Stream<_i10.Repository>.empty())
- as _i17.Stream<_i10.Repository>);
+ _i17.Stream<_i10.Repository> getRepositories(List<_i10.RepositorySlug>? slugs) => (super
+ .noSuchMethod(Invocation.method(#getRepositories, [slugs]), returnValue: _i17.Stream<_i10.Repository>.empty())
+ as _i17.Stream<_i10.Repository>);
@override
_i17.Future<_i10.Repository> editRepository(_i10.RepositorySlug? slug,
{String? name,
@@ -1819,146 +2228,178 @@
#hasWiki: hasWiki,
#hasDownloads: hasDownloads
}),
- returnValue: Future<_i10.Repository>.value(_FakeRepository_57())) as _i17.Future<_i10.Repository>);
+ returnValue: _i17.Future<_i10.Repository>.value(_FakeRepository_57(
+ this,
+ Invocation.method(#editRepository, [
+ slug
+ ], {
+ #name: name,
+ #description: description,
+ #homepage: homepage,
+ #private: private,
+ #hasIssues: hasIssues,
+ #hasWiki: hasWiki,
+ #hasDownloads: hasDownloads
+ })))) as _i17.Future<_i10.Repository>);
@override
_i17.Future<bool> deleteRepository(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#deleteRepository, [slug]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteRepository, [slug]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.Contributor> listContributors(_i10.RepositorySlug? slug, {bool? anon = false}) =>
(super.noSuchMethod(Invocation.method(#listContributors, [slug], {#anon: anon}),
- returnValue: Stream<_i10.Contributor>.empty()) as _i17.Stream<_i10.Contributor>);
+ returnValue: _i17.Stream<_i10.Contributor>.empty()) as _i17.Stream<_i10.Contributor>);
@override
_i17.Stream<_i10.Team> listTeams(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listTeams, [slug]), returnValue: Stream<_i10.Team>.empty())
+ (super.noSuchMethod(Invocation.method(#listTeams, [slug]), returnValue: _i17.Stream<_i10.Team>.empty())
as _i17.Stream<_i10.Team>);
@override
_i17.Future<_i10.LanguageBreakdown> listLanguages(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#listLanguages, [slug]),
- returnValue: Future<_i10.LanguageBreakdown>.value(_FakeLanguageBreakdown_59()))
+ returnValue: _i17.Future<_i10.LanguageBreakdown>.value(
+ _FakeLanguageBreakdown_59(this, Invocation.method(#listLanguages, [slug]))))
as _i17.Future<_i10.LanguageBreakdown>);
@override
_i17.Stream<_i10.Tag> listTags(_i10.RepositorySlug? slug, {int? page = 1, int? pages, int? perPage = 30}) =>
(super.noSuchMethod(Invocation.method(#listTags, [slug], {#page: page, #pages: pages, #perPage: perPage}),
- returnValue: Stream<_i10.Tag>.empty()) as _i17.Stream<_i10.Tag>);
+ returnValue: _i17.Stream<_i10.Tag>.empty()) as _i17.Stream<_i10.Tag>);
@override
_i17.Stream<_i10.Branch> listBranches(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listBranches, [slug]), returnValue: Stream<_i10.Branch>.empty())
+ (super.noSuchMethod(Invocation.method(#listBranches, [slug]), returnValue: _i17.Stream<_i10.Branch>.empty())
as _i17.Stream<_i10.Branch>);
@override
_i17.Future<_i10.Branch> getBranch(_i10.RepositorySlug? slug, String? branch) =>
(super.noSuchMethod(Invocation.method(#getBranch, [slug, branch]),
- returnValue: Future<_i10.Branch>.value(_FakeBranch_60())) as _i17.Future<_i10.Branch>);
+ returnValue:
+ _i17.Future<_i10.Branch>.value(_FakeBranch_60(this, Invocation.method(#getBranch, [slug, branch]))))
+ as _i17.Future<_i10.Branch>);
@override
_i17.Stream<_i10.Collaborator> listCollaborators(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listCollaborators, [slug]), returnValue: Stream<_i10.Collaborator>.empty())
- as _i17.Stream<_i10.Collaborator>);
+ (super.noSuchMethod(Invocation.method(#listCollaborators, [slug]),
+ returnValue: _i17.Stream<_i10.Collaborator>.empty()) as _i17.Stream<_i10.Collaborator>);
@override
_i17.Future<bool> isCollaborator(_i10.RepositorySlug? slug, String? user) =>
- (super.noSuchMethod(Invocation.method(#isCollaborator, [slug, user]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#isCollaborator, [slug, user]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
- _i17.Future<bool> addCollaborator(_i10.RepositorySlug? slug, String? user) =>
- (super.noSuchMethod(Invocation.method(#addCollaborator, [slug, user]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ _i17.Future<bool> addCollaborator(_i10.RepositorySlug? slug, String? user) => (super
+ .noSuchMethod(Invocation.method(#addCollaborator, [slug, user]), returnValue: _i17.Future<bool>.value(false))
+ as _i17.Future<bool>);
@override
_i17.Future<bool> removeCollaborator(_i10.RepositorySlug? slug, String? user) =>
- (super.noSuchMethod(Invocation.method(#removeCollaborator, [slug, user]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ (super.noSuchMethod(Invocation.method(#removeCollaborator, [slug, user]),
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Stream<_i10.CommitComment> listSingleCommitComments(_i10.RepositorySlug? slug, _i10.RepositoryCommit? commit) =>
(super.noSuchMethod(Invocation.method(#listSingleCommitComments, [slug, commit]),
- returnValue: Stream<_i10.CommitComment>.empty()) as _i17.Stream<_i10.CommitComment>);
+ returnValue: _i17.Stream<_i10.CommitComment>.empty()) as _i17.Stream<_i10.CommitComment>);
@override
- _i17.Stream<_i10.CommitComment> listCommitComments(_i10.RepositorySlug? slug) => (super
- .noSuchMethod(Invocation.method(#listCommitComments, [slug]), returnValue: Stream<_i10.CommitComment>.empty())
- as _i17.Stream<_i10.CommitComment>);
+ _i17.Stream<_i10.CommitComment> listCommitComments(_i10.RepositorySlug? slug) =>
+ (super.noSuchMethod(Invocation.method(#listCommitComments, [slug]),
+ returnValue: _i17.Stream<_i10.CommitComment>.empty()) as _i17.Stream<_i10.CommitComment>);
@override
_i17.Future<_i10.CommitComment> createCommitComment(_i10.RepositorySlug? slug, _i10.RepositoryCommit? commit,
{String? body, String? path, int? position, int? line}) =>
- (super.noSuchMethod(
- Invocation.method(
- #createCommitComment, [slug, commit], {#body: body, #path: path, #position: position, #line: line}),
- returnValue: Future<_i10.CommitComment>.value(_FakeCommitComment_61())) as _i17.Future<_i10.CommitComment>);
+ (super.noSuchMethod(Invocation.method(#createCommitComment, [slug, commit], {#body: body, #path: path, #position: position, #line: line}),
+ returnValue: _i17.Future<_i10.CommitComment>.value(_FakeCommitComment_61(
+ this,
+ Invocation.method(#createCommitComment, [slug, commit],
+ {#body: body, #path: path, #position: position, #line: line})))) as _i17.Future<_i10.CommitComment>);
@override
_i17.Future<_i10.CommitComment> getCommitComment(_i10.RepositorySlug? slug, {int? id}) =>
(super.noSuchMethod(Invocation.method(#getCommitComment, [slug], {#id: id}),
- returnValue: Future<_i10.CommitComment>.value(_FakeCommitComment_61())) as _i17.Future<_i10.CommitComment>);
+ returnValue: _i17.Future<_i10.CommitComment>.value(
+ _FakeCommitComment_61(this, Invocation.method(#getCommitComment, [slug], {#id: id}))))
+ as _i17.Future<_i10.CommitComment>);
@override
_i17.Future<_i10.CommitComment> updateCommitComment(_i10.RepositorySlug? slug, {int? id, String? body}) =>
(super.noSuchMethod(Invocation.method(#updateCommitComment, [slug], {#id: id, #body: body}),
- returnValue: Future<_i10.CommitComment>.value(_FakeCommitComment_61())) as _i17.Future<_i10.CommitComment>);
+ returnValue: _i17.Future<_i10.CommitComment>.value(
+ _FakeCommitComment_61(this, Invocation.method(#updateCommitComment, [slug], {#id: id, #body: body}))))
+ as _i17.Future<_i10.CommitComment>);
@override
_i17.Future<bool> deleteCommitComment(_i10.RepositorySlug? slug, {int? id}) =>
(super.noSuchMethod(Invocation.method(#deleteCommitComment, [slug], {#id: id}),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Stream<_i10.RepositoryCommit> listCommits(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listCommits, [slug]), returnValue: Stream<_i10.RepositoryCommit>.empty())
- as _i17.Stream<_i10.RepositoryCommit>);
+ (super.noSuchMethod(Invocation.method(#listCommits, [slug]),
+ returnValue: _i17.Stream<_i10.RepositoryCommit>.empty()) as _i17.Stream<_i10.RepositoryCommit>);
@override
_i17.Future<_i10.RepositoryCommit> getCommit(_i10.RepositorySlug? slug, String? sha) =>
(super.noSuchMethod(Invocation.method(#getCommit, [slug, sha]),
- returnValue: Future<_i10.RepositoryCommit>.value(_FakeRepositoryCommit_62()))
+ returnValue: _i17.Future<_i10.RepositoryCommit>.value(
+ _FakeRepositoryCommit_62(this, Invocation.method(#getCommit, [slug, sha]))))
as _i17.Future<_i10.RepositoryCommit>);
@override
_i17.Future<String> getCommitDiff(_i10.RepositorySlug? slug, String? sha) =>
- (super.noSuchMethod(Invocation.method(#getCommitDiff, [slug, sha]), returnValue: Future<String>.value(''))
+ (super.noSuchMethod(Invocation.method(#getCommitDiff, [slug, sha]), returnValue: _i17.Future<String>.value(''))
as _i17.Future<String>);
@override
_i17.Future<_i10.GitHubComparison> compareCommits(_i10.RepositorySlug? slug, String? refBase, String? refHead) =>
(super.noSuchMethod(Invocation.method(#compareCommits, [slug, refBase, refHead]),
- returnValue: Future<_i10.GitHubComparison>.value(_FakeGitHubComparison_63()))
+ returnValue: _i17.Future<_i10.GitHubComparison>.value(
+ _FakeGitHubComparison_63(this, Invocation.method(#compareCommits, [slug, refBase, refHead]))))
as _i17.Future<_i10.GitHubComparison>);
@override
_i17.Future<_i10.GitHubFile> getReadme(_i10.RepositorySlug? slug, {String? ref}) =>
(super.noSuchMethod(Invocation.method(#getReadme, [slug], {#ref: ref}),
- returnValue: Future<_i10.GitHubFile>.value(_FakeGitHubFile_64())) as _i17.Future<_i10.GitHubFile>);
+ returnValue: _i17.Future<_i10.GitHubFile>.value(
+ _FakeGitHubFile_64(this, Invocation.method(#getReadme, [slug], {#ref: ref}))))
+ as _i17.Future<_i10.GitHubFile>);
@override
_i17.Future<_i10.RepositoryContents> getContents(_i10.RepositorySlug? slug, String? path, {String? ref}) =>
(super.noSuchMethod(Invocation.method(#getContents, [slug, path], {#ref: ref}),
- returnValue: Future<_i10.RepositoryContents>.value(_FakeRepositoryContents_65()))
+ returnValue: _i17.Future<_i10.RepositoryContents>.value(
+ _FakeRepositoryContents_65(this, Invocation.method(#getContents, [slug, path], {#ref: ref}))))
as _i17.Future<_i10.RepositoryContents>);
@override
- _i17.Future<_i10.ContentCreation> createFile(_i10.RepositorySlug? slug, _i10.CreateFile? file) => (super.noSuchMethod(
- Invocation.method(#createFile, [slug, file]),
- returnValue: Future<_i10.ContentCreation>.value(_FakeContentCreation_66())) as _i17.Future<_i10.ContentCreation>);
+ _i17.Future<_i10.ContentCreation> createFile(_i10.RepositorySlug? slug, _i10.CreateFile? file) =>
+ (super.noSuchMethod(Invocation.method(#createFile, [slug, file]),
+ returnValue: _i17.Future<_i10.ContentCreation>.value(
+ _FakeContentCreation_66(this, Invocation.method(#createFile, [slug, file]))))
+ as _i17.Future<_i10.ContentCreation>);
@override
_i17.Future<_i10.ContentCreation> updateFile(
_i10.RepositorySlug? slug, String? path, String? message, String? content, String? sha, {String? branch}) =>
(super.noSuchMethod(Invocation.method(#updateFile, [slug, path, message, content, sha], {#branch: branch}),
- returnValue: Future<_i10.ContentCreation>.value(_FakeContentCreation_66()))
+ returnValue: _i17.Future<_i10.ContentCreation>.value(_FakeContentCreation_66(
+ this, Invocation.method(#updateFile, [slug, path, message, content, sha], {#branch: branch}))))
as _i17.Future<_i10.ContentCreation>);
@override
_i17.Future<_i10.ContentCreation> deleteFile(
_i10.RepositorySlug? slug, String? path, String? message, String? sha, String? branch) =>
(super.noSuchMethod(Invocation.method(#deleteFile, [slug, path, message, sha, branch]),
- returnValue: Future<_i10.ContentCreation>.value(_FakeContentCreation_66()))
+ returnValue: _i17.Future<_i10.ContentCreation>.value(
+ _FakeContentCreation_66(this, Invocation.method(#deleteFile, [slug, path, message, sha, branch]))))
as _i17.Future<_i10.ContentCreation>);
@override
_i17.Future<String?> getArchiveLink(_i10.RepositorySlug? slug, String? ref, {String? format = r'tarball'}) =>
(super.noSuchMethod(Invocation.method(#getArchiveLink, [slug, ref], {#format: format}),
- returnValue: Future<String?>.value()) as _i17.Future<String?>);
+ returnValue: _i17.Future<String?>.value()) as _i17.Future<String?>);
@override
_i17.Stream<_i10.Repository> listForks(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listForks, [slug]), returnValue: Stream<_i10.Repository>.empty())
+ (super.noSuchMethod(Invocation.method(#listForks, [slug]), returnValue: _i17.Stream<_i10.Repository>.empty())
as _i17.Stream<_i10.Repository>);
@override
_i17.Future<_i10.Repository> createFork(_i10.RepositorySlug? slug, [_i10.CreateFork? fork]) =>
(super.noSuchMethod(Invocation.method(#createFork, [slug, fork]),
- returnValue: Future<_i10.Repository>.value(_FakeRepository_57())) as _i17.Future<_i10.Repository>);
+ returnValue: _i17.Future<_i10.Repository>.value(
+ _FakeRepository_57(this, Invocation.method(#createFork, [slug, fork])))) as _i17.Future<_i10.Repository>);
@override
_i17.Stream<_i10.Hook> listHooks(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listHooks, [slug]), returnValue: Stream<_i10.Hook>.empty())
+ (super.noSuchMethod(Invocation.method(#listHooks, [slug]), returnValue: _i17.Stream<_i10.Hook>.empty())
as _i17.Stream<_i10.Hook>);
@override
_i17.Future<_i10.Hook> getHook(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#getHook, [slug, id]), returnValue: Future<_i10.Hook>.value(_FakeHook_67()))
+ (super.noSuchMethod(Invocation.method(#getHook, [slug, id]),
+ returnValue: _i17.Future<_i10.Hook>.value(_FakeHook_67(this, Invocation.method(#getHook, [slug, id]))))
as _i17.Future<_i10.Hook>);
@override
- _i17.Future<_i10.Hook> createHook(_i10.RepositorySlug? slug, _i10.CreateHook? hook) =>
- (super.noSuchMethod(Invocation.method(#createHook, [slug, hook]),
- returnValue: Future<_i10.Hook>.value(_FakeHook_67())) as _i17.Future<_i10.Hook>);
+ _i17.Future<_i10.Hook> createHook(_i10.RepositorySlug? slug, _i10.CreateHook? hook) => (super.noSuchMethod(
+ Invocation.method(#createHook, [slug, hook]),
+ returnValue: _i17.Future<_i10.Hook>.value(_FakeHook_67(this, Invocation.method(#createHook, [slug, hook]))))
+ as _i17.Future<_i10.Hook>);
@override
_i17.Future<_i10.Hook> editHook(_i10.RepositorySlug? slug, _i10.Hook? hookToEdit,
{String? configUrl,
@@ -1983,156 +2424,196 @@
#removeEvents: removeEvents,
#active: active
}),
- returnValue: Future<_i10.Hook>.value(_FakeHook_67())) as _i17.Future<_i10.Hook>);
+ returnValue: _i17.Future<_i10.Hook>.value(_FakeHook_67(
+ this,
+ Invocation.method(#editHook, [
+ slug,
+ hookToEdit
+ ], {
+ #configUrl: configUrl,
+ #configContentType: configContentType,
+ #configSecret: configSecret,
+ #configInsecureSsl: configInsecureSsl,
+ #events: events,
+ #addEvents: addEvents,
+ #removeEvents: removeEvents,
+ #active: active
+ })))) as _i17.Future<_i10.Hook>);
@override
_i17.Future<bool> testPushHook(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#testPushHook, [slug, id]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#testPushHook, [slug, id]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<bool> pingHook(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#pingHook, [slug, id]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#pingHook, [slug, id]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<bool> deleteHook(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#deleteHook, [slug, id]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteHook, [slug, id]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.PublicKey> listDeployKeys(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listDeployKeys, [slug]), returnValue: Stream<_i10.PublicKey>.empty())
+ (super.noSuchMethod(Invocation.method(#listDeployKeys, [slug]), returnValue: _i17.Stream<_i10.PublicKey>.empty())
as _i17.Stream<_i10.PublicKey>);
@override
_i17.Future<_i10.PublicKey> getDeployKey(_i10.RepositorySlug? slug, {int? id}) =>
(super.noSuchMethod(Invocation.method(#getDeployKey, [slug], {#id: id}),
- returnValue: Future<_i10.PublicKey>.value(_FakePublicKey_68())) as _i17.Future<_i10.PublicKey>);
+ returnValue: _i17.Future<_i10.PublicKey>.value(
+ _FakePublicKey_68(this, Invocation.method(#getDeployKey, [slug], {#id: id}))))
+ as _i17.Future<_i10.PublicKey>);
@override
_i17.Future<_i10.PublicKey> createDeployKey(_i10.RepositorySlug? slug, _i10.CreatePublicKey? key) =>
(super.noSuchMethod(Invocation.method(#createDeployKey, [slug, key]),
- returnValue: Future<_i10.PublicKey>.value(_FakePublicKey_68())) as _i17.Future<_i10.PublicKey>);
+ returnValue: _i17.Future<_i10.PublicKey>.value(
+ _FakePublicKey_68(this, Invocation.method(#createDeployKey, [slug, key]))))
+ as _i17.Future<_i10.PublicKey>);
@override
_i17.Future<bool> deleteDeployKey({_i10.RepositorySlug? slug, _i10.PublicKey? key}) =>
(super.noSuchMethod(Invocation.method(#deleteDeployKey, [], {#slug: slug, #key: key}),
- returnValue: Future<bool>.value(false)) as _i17.Future<bool>);
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Future<_i10.RepositoryCommit> merge(_i10.RepositorySlug? slug, _i10.CreateMerge? merge) =>
(super.noSuchMethod(Invocation.method(#merge, [slug, merge]),
- returnValue: Future<_i10.RepositoryCommit>.value(_FakeRepositoryCommit_62()))
+ returnValue: _i17.Future<_i10.RepositoryCommit>.value(
+ _FakeRepositoryCommit_62(this, Invocation.method(#merge, [slug, merge]))))
as _i17.Future<_i10.RepositoryCommit>);
@override
- _i17.Future<_i10.RepositoryPages> getPagesInfo(_i10.RepositorySlug? slug) => (super.noSuchMethod(
- Invocation.method(#getPagesInfo, [slug]),
- returnValue: Future<_i10.RepositoryPages>.value(_FakeRepositoryPages_69())) as _i17.Future<_i10.RepositoryPages>);
+ _i17.Future<_i10.RepositoryPages> getPagesInfo(_i10.RepositorySlug? slug) =>
+ (super.noSuchMethod(Invocation.method(#getPagesInfo, [slug]),
+ returnValue: _i17.Future<_i10.RepositoryPages>.value(
+ _FakeRepositoryPages_69(this, Invocation.method(#getPagesInfo, [slug]))))
+ as _i17.Future<_i10.RepositoryPages>);
@override
_i17.Stream<_i10.PageBuild> listPagesBuilds(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listPagesBuilds, [slug]), returnValue: Stream<_i10.PageBuild>.empty())
+ (super.noSuchMethod(Invocation.method(#listPagesBuilds, [slug]), returnValue: _i17.Stream<_i10.PageBuild>.empty())
as _i17.Stream<_i10.PageBuild>);
@override
- _i17.Future<_i10.PageBuild> getLatestPagesBuild(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#getLatestPagesBuild, [slug]),
- returnValue: Future<_i10.PageBuild>.value(_FakePageBuild_70())) as _i17.Future<_i10.PageBuild>);
+ _i17.Future<_i10.PageBuild> getLatestPagesBuild(_i10.RepositorySlug? slug) => (super.noSuchMethod(
+ Invocation.method(#getLatestPagesBuild, [slug]),
+ returnValue: _i17.Future<_i10.PageBuild>.value(
+ _FakePageBuild_70(this, Invocation.method(#getLatestPagesBuild, [slug])))) as _i17.Future<_i10.PageBuild>);
@override
_i17.Stream<_i10.Release> listReleases(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listReleases, [slug]), returnValue: Stream<_i10.Release>.empty())
+ (super.noSuchMethod(Invocation.method(#listReleases, [slug]), returnValue: _i17.Stream<_i10.Release>.empty())
as _i17.Stream<_i10.Release>);
@override
_i17.Future<_i10.Release> getLatestRelease(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#getLatestRelease, [slug]),
- returnValue: Future<_i10.Release>.value(_FakeRelease_71())) as _i17.Future<_i10.Release>);
+ returnValue:
+ _i17.Future<_i10.Release>.value(_FakeRelease_71(this, Invocation.method(#getLatestRelease, [slug]))))
+ as _i17.Future<_i10.Release>);
@override
- _i17.Future<_i10.Release> getReleaseById(_i10.RepositorySlug? slug, int? id) =>
- (super.noSuchMethod(Invocation.method(#getReleaseById, [slug, id]),
- returnValue: Future<_i10.Release>.value(_FakeRelease_71())) as _i17.Future<_i10.Release>);
+ _i17.Future<_i10.Release> getReleaseById(_i10.RepositorySlug? slug, int? id) => (super.noSuchMethod(
+ Invocation.method(#getReleaseById, [slug, id]),
+ returnValue:
+ _i17.Future<_i10.Release>.value(_FakeRelease_71(this, Invocation.method(#getReleaseById, [slug, id]))))
+ as _i17.Future<_i10.Release>);
@override
_i17.Future<_i10.Release> getReleaseByTagName(_i10.RepositorySlug? slug, String? tagName) =>
(super.noSuchMethod(Invocation.method(#getReleaseByTagName, [slug, tagName]),
- returnValue: Future<_i10.Release>.value(_FakeRelease_71())) as _i17.Future<_i10.Release>);
+ returnValue: _i17.Future<_i10.Release>.value(
+ _FakeRelease_71(this, Invocation.method(#getReleaseByTagName, [slug, tagName]))))
+ as _i17.Future<_i10.Release>);
@override
_i17.Future<_i10.Release> createRelease(_i10.RepositorySlug? slug, _i10.CreateRelease? createRelease,
{bool? getIfExists = true}) =>
(super.noSuchMethod(Invocation.method(#createRelease, [slug, createRelease], {#getIfExists: getIfExists}),
- returnValue: Future<_i10.Release>.value(_FakeRelease_71())) as _i17.Future<_i10.Release>);
+ returnValue: _i17.Future<_i10.Release>.value(_FakeRelease_71(
+ this, Invocation.method(#createRelease, [slug, createRelease], {#getIfExists: getIfExists}))))
+ as _i17.Future<_i10.Release>);
@override
_i17.Future<_i10.Release> editRelease(_i10.RepositorySlug? slug, _i10.Release? releaseToEdit,
{String? tagName, String? targetCommitish, String? name, String? body, bool? draft, bool? preRelease}) =>
- (super.noSuchMethod(
- Invocation.method(#editRelease, [
- slug,
- releaseToEdit
- ], {
- #tagName: tagName,
- #targetCommitish: targetCommitish,
- #name: name,
- #body: body,
- #draft: draft,
- #preRelease: preRelease
- }),
- returnValue: Future<_i10.Release>.value(_FakeRelease_71())) as _i17.Future<_i10.Release>);
+ (super.noSuchMethod(Invocation.method(#editRelease, [slug, releaseToEdit], {#tagName: tagName, #targetCommitish: targetCommitish, #name: name, #body: body, #draft: draft, #preRelease: preRelease}),
+ returnValue: _i17.Future<_i10.Release>.value(_FakeRelease_71(
+ this,
+ Invocation.method(#editRelease, [
+ slug,
+ releaseToEdit
+ ], {
+ #tagName: tagName,
+ #targetCommitish: targetCommitish,
+ #name: name,
+ #body: body,
+ #draft: draft,
+ #preRelease: preRelease
+ })))) as _i17.Future<_i10.Release>);
@override
- _i17.Future<bool> deleteRelease(_i10.RepositorySlug? slug, _i10.Release? release) =>
- (super.noSuchMethod(Invocation.method(#deleteRelease, [slug, release]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ _i17.Future<bool> deleteRelease(_i10.RepositorySlug? slug, _i10.Release? release) => (super
+ .noSuchMethod(Invocation.method(#deleteRelease, [slug, release]), returnValue: _i17.Future<bool>.value(false))
+ as _i17.Future<bool>);
@override
_i17.Stream<_i10.ReleaseAsset> listReleaseAssets(_i10.RepositorySlug? slug, _i10.Release? release) =>
(super.noSuchMethod(Invocation.method(#listReleaseAssets, [slug, release]),
- returnValue: Stream<_i10.ReleaseAsset>.empty()) as _i17.Stream<_i10.ReleaseAsset>);
+ returnValue: _i17.Stream<_i10.ReleaseAsset>.empty()) as _i17.Stream<_i10.ReleaseAsset>);
@override
_i17.Future<_i10.ReleaseAsset> getReleaseAsset(_i10.RepositorySlug? slug, _i10.Release? release, {int? assetId}) =>
(super.noSuchMethod(Invocation.method(#getReleaseAsset, [slug, release], {#assetId: assetId}),
- returnValue: Future<_i10.ReleaseAsset>.value(_FakeReleaseAsset_72())) as _i17.Future<_i10.ReleaseAsset>);
+ returnValue: _i17.Future<_i10.ReleaseAsset>.value(_FakeReleaseAsset_72(
+ this, Invocation.method(#getReleaseAsset, [slug, release], {#assetId: assetId}))))
+ as _i17.Future<_i10.ReleaseAsset>);
@override
_i17.Future<_i10.ReleaseAsset> editReleaseAsset(_i10.RepositorySlug? slug, _i10.ReleaseAsset? assetToEdit,
{String? name, String? label}) =>
(super.noSuchMethod(Invocation.method(#editReleaseAsset, [slug, assetToEdit], {#name: name, #label: label}),
- returnValue: Future<_i10.ReleaseAsset>.value(_FakeReleaseAsset_72())) as _i17.Future<_i10.ReleaseAsset>);
+ returnValue: _i17.Future<_i10.ReleaseAsset>.value(_FakeReleaseAsset_72(
+ this, Invocation.method(#editReleaseAsset, [slug, assetToEdit], {#name: name, #label: label}))))
+ as _i17.Future<_i10.ReleaseAsset>);
@override
_i17.Future<bool> deleteReleaseAsset(_i10.RepositorySlug? slug, _i10.ReleaseAsset? asset) =>
- (super.noSuchMethod(Invocation.method(#deleteReleaseAsset, [slug, asset]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ (super.noSuchMethod(Invocation.method(#deleteReleaseAsset, [slug, asset]),
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Future<List<_i10.ReleaseAsset>> uploadReleaseAssets(
_i10.Release? release, Iterable<_i10.CreateReleaseAsset>? createReleaseAssets) =>
(super.noSuchMethod(Invocation.method(#uploadReleaseAssets, [release, createReleaseAssets]),
- returnValue: Future<List<_i10.ReleaseAsset>>.value(<_i10.ReleaseAsset>[]))
+ returnValue: _i17.Future<List<_i10.ReleaseAsset>>.value(<_i10.ReleaseAsset>[]))
as _i17.Future<List<_i10.ReleaseAsset>>);
@override
_i17.Future<List<_i10.ContributorStatistics>> listContributorStats(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#listContributorStats, [slug]),
- returnValue: Future<List<_i10.ContributorStatistics>>.value(<_i10.ContributorStatistics>[]))
+ returnValue: _i17.Future<List<_i10.ContributorStatistics>>.value(<_i10.ContributorStatistics>[]))
as _i17.Future<List<_i10.ContributorStatistics>>);
@override
_i17.Stream<_i10.YearCommitCountWeek> listCommitActivity(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#listCommitActivity, [slug]),
- returnValue: Stream<_i10.YearCommitCountWeek>.empty()) as _i17.Stream<_i10.YearCommitCountWeek>);
+ returnValue: _i17.Stream<_i10.YearCommitCountWeek>.empty()) as _i17.Stream<_i10.YearCommitCountWeek>);
@override
_i17.Stream<_i10.WeeklyChangesCount> listCodeFrequency(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#listCodeFrequency, [slug]),
- returnValue: Stream<_i10.WeeklyChangesCount>.empty()) as _i17.Stream<_i10.WeeklyChangesCount>);
+ returnValue: _i17.Stream<_i10.WeeklyChangesCount>.empty()) as _i17.Stream<_i10.WeeklyChangesCount>);
@override
_i17.Future<_i10.ContributorParticipation> getParticipation(_i10.RepositorySlug? slug) =>
(super.noSuchMethod(Invocation.method(#getParticipation, [slug]),
- returnValue: Future<_i10.ContributorParticipation>.value(_FakeContributorParticipation_73()))
+ returnValue: _i17.Future<_i10.ContributorParticipation>.value(
+ _FakeContributorParticipation_73(this, Invocation.method(#getParticipation, [slug]))))
as _i17.Future<_i10.ContributorParticipation>);
@override
_i17.Stream<_i10.PunchcardEntry> listPunchcard(_i10.RepositorySlug? slug) =>
- (super.noSuchMethod(Invocation.method(#listPunchcard, [slug]), returnValue: Stream<_i10.PunchcardEntry>.empty())
- as _i17.Stream<_i10.PunchcardEntry>);
+ (super.noSuchMethod(Invocation.method(#listPunchcard, [slug]),
+ returnValue: _i17.Stream<_i10.PunchcardEntry>.empty()) as _i17.Stream<_i10.PunchcardEntry>);
@override
_i17.Stream<_i10.RepositoryStatus> listStatuses(_i10.RepositorySlug? slug, String? ref) =>
(super.noSuchMethod(Invocation.method(#listStatuses, [slug, ref]),
- returnValue: Stream<_i10.RepositoryStatus>.empty()) as _i17.Stream<_i10.RepositoryStatus>);
+ returnValue: _i17.Stream<_i10.RepositoryStatus>.empty()) as _i17.Stream<_i10.RepositoryStatus>);
@override
_i17.Future<_i10.RepositoryStatus> createStatus(_i10.RepositorySlug? slug, String? ref, _i10.CreateStatus? request) =>
(super.noSuchMethod(Invocation.method(#createStatus, [slug, ref, request]),
- returnValue: Future<_i10.RepositoryStatus>.value(_FakeRepositoryStatus_74()))
+ returnValue: _i17.Future<_i10.RepositoryStatus>.value(
+ _FakeRepositoryStatus_74(this, Invocation.method(#createStatus, [slug, ref, request]))))
as _i17.Future<_i10.RepositoryStatus>);
@override
_i17.Future<_i10.CombinedRepositoryStatus> getCombinedStatus(_i10.RepositorySlug? slug, String? ref) =>
(super.noSuchMethod(Invocation.method(#getCombinedStatus, [slug, ref]),
- returnValue: Future<_i10.CombinedRepositoryStatus>.value(_FakeCombinedRepositoryStatus_75()))
+ returnValue: _i17.Future<_i10.CombinedRepositoryStatus>.value(
+ _FakeCombinedRepositoryStatus_75(this, Invocation.method(#getCombinedStatus, [slug, ref]))))
as _i17.Future<_i10.CombinedRepositoryStatus>);
@override
_i17.Future<_i10.ReleaseNotes> generateReleaseNotes(_i10.CreateReleaseNotes? crn) =>
(super.noSuchMethod(Invocation.method(#generateReleaseNotes, [crn]),
- returnValue: Future<_i10.ReleaseNotes>.value(_FakeReleaseNotes_76())) as _i17.Future<_i10.ReleaseNotes>);
+ returnValue: _i17.Future<_i10.ReleaseNotes>.value(
+ _FakeReleaseNotes_76(this, Invocation.method(#generateReleaseNotes, [crn]))))
+ as _i17.Future<_i10.ReleaseNotes>);
}
/// A class which mocks [TabledataResource].
@@ -2148,7 +2629,8 @@
_i6.TableDataInsertAllRequest? request, String? projectId, String? datasetId, String? tableId,
{String? $fields}) =>
(super.noSuchMethod(Invocation.method(#insertAll, [request, projectId, datasetId, tableId], {#$fields: $fields}),
- returnValue: Future<_i6.TableDataInsertAllResponse>.value(_FakeTableDataInsertAllResponse_77()))
+ returnValue: _i17.Future<_i6.TableDataInsertAllResponse>.value(_FakeTableDataInsertAllResponse_77(
+ this, Invocation.method(#insertAll, [request, projectId, datasetId, tableId], {#$fields: $fields}))))
as _i17.Future<_i6.TableDataInsertAllResponse>);
@override
_i17.Future<_i6.TableDataList> list(String? projectId, String? datasetId, String? tableId,
@@ -2165,7 +2647,19 @@
#startIndex: startIndex,
#$fields: $fields
}),
- returnValue: Future<_i6.TableDataList>.value(_FakeTableDataList_78())) as _i17.Future<_i6.TableDataList>);
+ returnValue: _i17.Future<_i6.TableDataList>.value(_FakeTableDataList_78(
+ this,
+ Invocation.method(#list, [
+ projectId,
+ datasetId,
+ tableId
+ ], {
+ #maxResults: maxResults,
+ #pageToken: pageToken,
+ #selectedFields: selectedFields,
+ #startIndex: startIndex,
+ #$fields: $fields
+ })))) as _i17.Future<_i6.TableDataList>);
}
/// A class which mocks [UsersService].
@@ -2178,11 +2672,12 @@
@override
_i10.GitHub get github =>
- (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12()) as _i10.GitHub);
+ (super.noSuchMethod(Invocation.getter(#github), returnValue: _FakeGitHub_12(this, Invocation.getter(#github)))
+ as _i10.GitHub);
@override
- _i17.Future<_i10.User> getUser(String? name) =>
- (super.noSuchMethod(Invocation.method(#getUser, [name]), returnValue: Future<_i10.User>.value(_FakeUser_79()))
- as _i17.Future<_i10.User>);
+ _i17.Future<_i10.User> getUser(String? name) => (super.noSuchMethod(Invocation.method(#getUser, [name]),
+ returnValue: _i17.Future<_i10.User>.value(_FakeUser_79(this, Invocation.method(#getUser, [name]))))
+ as _i17.Future<_i10.User>);
@override
_i17.Future<_i10.CurrentUser> editCurrentUser(
{String? name,
@@ -2192,80 +2687,86 @@
String? location,
bool? hireable,
String? bio}) =>
- (super.noSuchMethod(
- Invocation.method(#editCurrentUser, [], {
- #name: name,
- #email: email,
- #blog: blog,
- #company: company,
- #location: location,
- #hireable: hireable,
- #bio: bio
- }),
- returnValue: Future<_i10.CurrentUser>.value(_FakeCurrentUser_80())) as _i17.Future<_i10.CurrentUser>);
+ (super
+ .noSuchMethod(Invocation.method(#editCurrentUser, [], {#name: name, #email: email, #blog: blog, #company: company, #location: location, #hireable: hireable, #bio: bio}),
+ returnValue: _i17.Future<_i10.CurrentUser>.value(_FakeCurrentUser_80(
+ this,
+ Invocation.method(#editCurrentUser, [], {
+ #name: name,
+ #email: email,
+ #blog: blog,
+ #company: company,
+ #location: location,
+ #hireable: hireable,
+ #bio: bio
+ })))) as _i17.Future<_i10.CurrentUser>);
@override
- _i17.Stream<_i10.User> getUsers(List<String>? names, {int? pages}) => (super
- .noSuchMethod(Invocation.method(#getUsers, [names], {#pages: pages}), returnValue: Stream<_i10.User>.empty())
- as _i17.Stream<_i10.User>);
+ _i17.Stream<_i10.User> getUsers(List<String>? names, {int? pages}) =>
+ (super.noSuchMethod(Invocation.method(#getUsers, [names], {#pages: pages}),
+ returnValue: _i17.Stream<_i10.User>.empty()) as _i17.Stream<_i10.User>);
@override
_i17.Future<_i10.CurrentUser> getCurrentUser() => (super.noSuchMethod(Invocation.method(#getCurrentUser, []),
- returnValue: Future<_i10.CurrentUser>.value(_FakeCurrentUser_80())) as _i17.Future<_i10.CurrentUser>);
+ returnValue:
+ _i17.Future<_i10.CurrentUser>.value(_FakeCurrentUser_80(this, Invocation.method(#getCurrentUser, []))))
+ as _i17.Future<_i10.CurrentUser>);
@override
_i17.Future<bool> isUser(String? name) =>
- (super.noSuchMethod(Invocation.method(#isUser, [name]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#isUser, [name]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.User> listUsers({int? pages, int? since}) =>
(super.noSuchMethod(Invocation.method(#listUsers, [], {#pages: pages, #since: since}),
- returnValue: Stream<_i10.User>.empty()) as _i17.Stream<_i10.User>);
+ returnValue: _i17.Stream<_i10.User>.empty()) as _i17.Stream<_i10.User>);
@override
_i17.Stream<_i10.UserEmail> listEmails() =>
- (super.noSuchMethod(Invocation.method(#listEmails, []), returnValue: Stream<_i10.UserEmail>.empty())
+ (super.noSuchMethod(Invocation.method(#listEmails, []), returnValue: _i17.Stream<_i10.UserEmail>.empty())
as _i17.Stream<_i10.UserEmail>);
@override
_i17.Stream<_i10.UserEmail> addEmails(List<String>? emails) =>
- (super.noSuchMethod(Invocation.method(#addEmails, [emails]), returnValue: Stream<_i10.UserEmail>.empty())
+ (super.noSuchMethod(Invocation.method(#addEmails, [emails]), returnValue: _i17.Stream<_i10.UserEmail>.empty())
as _i17.Stream<_i10.UserEmail>);
@override
_i17.Future<bool> deleteEmails(List<String>? emails) =>
- (super.noSuchMethod(Invocation.method(#deleteEmails, [emails]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#deleteEmails, [emails]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.User> listUserFollowers(String? user) =>
- (super.noSuchMethod(Invocation.method(#listUserFollowers, [user]), returnValue: Stream<_i10.User>.empty())
+ (super.noSuchMethod(Invocation.method(#listUserFollowers, [user]), returnValue: _i17.Stream<_i10.User>.empty())
as _i17.Stream<_i10.User>);
@override
_i17.Future<bool> isFollowingUser(String? user) =>
- (super.noSuchMethod(Invocation.method(#isFollowingUser, [user]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#isFollowingUser, [user]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<bool> isUserFollowing(String? user, String? target) =>
- (super.noSuchMethod(Invocation.method(#isUserFollowing, [user, target]), returnValue: Future<bool>.value(false))
- as _i17.Future<bool>);
+ (super.noSuchMethod(Invocation.method(#isUserFollowing, [user, target]),
+ returnValue: _i17.Future<bool>.value(false)) as _i17.Future<bool>);
@override
_i17.Future<bool> followUser(String? user) =>
- (super.noSuchMethod(Invocation.method(#followUser, [user]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#followUser, [user]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Future<bool> unfollowUser(String? user) =>
- (super.noSuchMethod(Invocation.method(#unfollowUser, [user]), returnValue: Future<bool>.value(false))
+ (super.noSuchMethod(Invocation.method(#unfollowUser, [user]), returnValue: _i17.Future<bool>.value(false))
as _i17.Future<bool>);
@override
_i17.Stream<_i10.User> listCurrentUserFollowers() =>
- (super.noSuchMethod(Invocation.method(#listCurrentUserFollowers, []), returnValue: Stream<_i10.User>.empty())
+ (super.noSuchMethod(Invocation.method(#listCurrentUserFollowers, []), returnValue: _i17.Stream<_i10.User>.empty())
as _i17.Stream<_i10.User>);
@override
_i17.Stream<_i10.User> listCurrentUserFollowing() =>
- (super.noSuchMethod(Invocation.method(#listCurrentUserFollowing, []), returnValue: Stream<_i10.User>.empty())
+ (super.noSuchMethod(Invocation.method(#listCurrentUserFollowing, []), returnValue: _i17.Stream<_i10.User>.empty())
as _i17.Stream<_i10.User>);
@override
_i17.Stream<_i10.PublicKey> listPublicKeys([String? userLogin]) =>
- (super.noSuchMethod(Invocation.method(#listPublicKeys, [userLogin]), returnValue: Stream<_i10.PublicKey>.empty())
- as _i17.Stream<_i10.PublicKey>);
+ (super.noSuchMethod(Invocation.method(#listPublicKeys, [userLogin]),
+ returnValue: _i17.Stream<_i10.PublicKey>.empty()) as _i17.Stream<_i10.PublicKey>);
@override
- _i17.Future<_i10.PublicKey> createPublicKey(_i10.CreatePublicKey? key) =>
- (super.noSuchMethod(Invocation.method(#createPublicKey, [key]),
- returnValue: Future<_i10.PublicKey>.value(_FakePublicKey_68())) as _i17.Future<_i10.PublicKey>);
+ _i17.Future<_i10.PublicKey> createPublicKey(_i10.CreatePublicKey? key) => (super.noSuchMethod(
+ Invocation.method(#createPublicKey, [key]),
+ returnValue:
+ _i17.Future<_i10.PublicKey>.value(_FakePublicKey_68(this, Invocation.method(#createPublicKey, [key]))))
+ as _i17.Future<_i10.PublicKey>);
}
/// A class which mocks [Cache].
@@ -2277,20 +2778,20 @@
}
@override
- _i21.Entry<_i27.Uint8List> operator [](String? key) =>
- (super.noSuchMethod(Invocation.method(#[], [key]), returnValue: _FakeEntry_81<_i27.Uint8List>())
- as _i21.Entry<_i27.Uint8List>);
+ _i21.Entry<_i27.Uint8List> operator [](String? key) => (super.noSuchMethod(Invocation.method(#[], [key]),
+ returnValue: _FakeEntry_81<_i27.Uint8List>(this, Invocation.method(#[], [key]))) as _i21.Entry<_i27.Uint8List>);
@override
- _i21.Cache<_i27.Uint8List> withPrefix(String? prefix) =>
- (super.noSuchMethod(Invocation.method(#withPrefix, [prefix]), returnValue: _FakeCache_82<_i27.Uint8List>())
- as _i21.Cache<_i27.Uint8List>);
+ _i21.Cache<_i27.Uint8List> withPrefix(String? prefix) => (super.noSuchMethod(Invocation.method(#withPrefix, [prefix]),
+ returnValue: _FakeCache_82<_i27.Uint8List>(this, Invocation.method(#withPrefix, [prefix])))
+ as _i21.Cache<_i27.Uint8List>);
@override
_i21.Cache<S> withCodec<S>(_i16.Codec<S, _i27.Uint8List>? codec) =>
- (super.noSuchMethod(Invocation.method(#withCodec, [codec]), returnValue: _FakeCache_82<S>()) as _i21.Cache<S>);
+ (super.noSuchMethod(Invocation.method(#withCodec, [codec]),
+ returnValue: _FakeCache_82<S>(this, Invocation.method(#withCodec, [codec]))) as _i21.Cache<S>);
@override
- _i21.Cache<_i27.Uint8List> withTTL(Duration? ttl) =>
- (super.noSuchMethod(Invocation.method(#withTTL, [ttl]), returnValue: _FakeCache_82<_i27.Uint8List>())
- as _i21.Cache<_i27.Uint8List>);
+ _i21.Cache<_i27.Uint8List> withTTL(Duration? ttl) => (super.noSuchMethod(Invocation.method(#withTTL, [ttl]),
+ returnValue: _FakeCache_82<_i27.Uint8List>(this, Invocation.method(#withTTL, [ttl])))
+ as _i21.Cache<_i27.Uint8List>);
}
/// A class which mocks [GitHub].
@@ -2307,52 +2808,53 @@
@override
String get endpoint => (super.noSuchMethod(Invocation.getter(#endpoint), returnValue: '') as String);
@override
- _i2.Client get client => (super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient_0()) as _i2.Client);
+ _i2.Client get client =>
+ (super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient_0(this, Invocation.getter(#client)))
+ as _i2.Client);
@override
- _i10.ActivityService get activity =>
- (super.noSuchMethod(Invocation.getter(#activity), returnValue: _FakeActivityService_83())
- as _i10.ActivityService);
+ _i10.ActivityService get activity => (super.noSuchMethod(Invocation.getter(#activity),
+ returnValue: _FakeActivityService_83(this, Invocation.getter(#activity))) as _i10.ActivityService);
@override
- _i10.AuthorizationsService get authorizations =>
- (super.noSuchMethod(Invocation.getter(#authorizations), returnValue: _FakeAuthorizationsService_84())
- as _i10.AuthorizationsService);
+ _i10.AuthorizationsService get authorizations => (super.noSuchMethod(Invocation.getter(#authorizations),
+ returnValue: _FakeAuthorizationsService_84(this, Invocation.getter(#authorizations)))
+ as _i10.AuthorizationsService);
@override
_i10.GistsService get gists =>
- (super.noSuchMethod(Invocation.getter(#gists), returnValue: _FakeGistsService_85()) as _i10.GistsService);
+ (super.noSuchMethod(Invocation.getter(#gists), returnValue: _FakeGistsService_85(this, Invocation.getter(#gists)))
+ as _i10.GistsService);
@override
_i10.GitService get git =>
- (super.noSuchMethod(Invocation.getter(#git), returnValue: _FakeGitService_86()) as _i10.GitService);
+ (super.noSuchMethod(Invocation.getter(#git), returnValue: _FakeGitService_86(this, Invocation.getter(#git)))
+ as _i10.GitService);
@override
- _i10.IssuesService get issues =>
- (super.noSuchMethod(Invocation.getter(#issues), returnValue: _FakeIssuesService_87()) as _i10.IssuesService);
+ _i10.IssuesService get issues => (super.noSuchMethod(Invocation.getter(#issues),
+ returnValue: _FakeIssuesService_87(this, Invocation.getter(#issues))) as _i10.IssuesService);
@override
_i10.MiscService get misc =>
- (super.noSuchMethod(Invocation.getter(#misc), returnValue: _FakeMiscService_88()) as _i10.MiscService);
+ (super.noSuchMethod(Invocation.getter(#misc), returnValue: _FakeMiscService_88(this, Invocation.getter(#misc)))
+ as _i10.MiscService);
@override
- _i10.OrganizationsService get organizations =>
- (super.noSuchMethod(Invocation.getter(#organizations), returnValue: _FakeOrganizationsService_89())
- as _i10.OrganizationsService);
+ _i10.OrganizationsService get organizations => (super.noSuchMethod(Invocation.getter(#organizations),
+ returnValue: _FakeOrganizationsService_89(this, Invocation.getter(#organizations))) as _i10.OrganizationsService);
@override
- _i10.PullRequestsService get pullRequests =>
- (super.noSuchMethod(Invocation.getter(#pullRequests), returnValue: _FakePullRequestsService_90())
- as _i10.PullRequestsService);
+ _i10.PullRequestsService get pullRequests => (super.noSuchMethod(Invocation.getter(#pullRequests),
+ returnValue: _FakePullRequestsService_90(this, Invocation.getter(#pullRequests))) as _i10.PullRequestsService);
@override
- _i10.RepositoriesService get repositories =>
- (super.noSuchMethod(Invocation.getter(#repositories), returnValue: _FakeRepositoriesService_91())
- as _i10.RepositoriesService);
+ _i10.RepositoriesService get repositories => (super.noSuchMethod(Invocation.getter(#repositories),
+ returnValue: _FakeRepositoriesService_91(this, Invocation.getter(#repositories))) as _i10.RepositoriesService);
@override
- _i10.SearchService get search =>
- (super.noSuchMethod(Invocation.getter(#search), returnValue: _FakeSearchService_92()) as _i10.SearchService);
+ _i10.SearchService get search => (super.noSuchMethod(Invocation.getter(#search),
+ returnValue: _FakeSearchService_92(this, Invocation.getter(#search))) as _i10.SearchService);
@override
- _i10.UrlShortenerService get urlShortener =>
- (super.noSuchMethod(Invocation.getter(#urlShortener), returnValue: _FakeUrlShortenerService_93())
- as _i10.UrlShortenerService);
+ _i10.UrlShortenerService get urlShortener => (super.noSuchMethod(Invocation.getter(#urlShortener),
+ returnValue: _FakeUrlShortenerService_93(this, Invocation.getter(#urlShortener))) as _i10.UrlShortenerService);
@override
_i10.UsersService get users =>
- (super.noSuchMethod(Invocation.getter(#users), returnValue: _FakeUsersService_94()) as _i10.UsersService);
+ (super.noSuchMethod(Invocation.getter(#users), returnValue: _FakeUsersService_94(this, Invocation.getter(#users)))
+ as _i10.UsersService);
@override
- _i10.ChecksService get checks =>
- (super.noSuchMethod(Invocation.getter(#checks), returnValue: _FakeChecksService_95()) as _i10.ChecksService);
+ _i10.ChecksService get checks => (super.noSuchMethod(Invocation.getter(#checks),
+ returnValue: _FakeChecksService_95(this, Invocation.getter(#checks))) as _i10.ChecksService);
@override
_i17.Future<T> getJSON<S, T>(String? path,
{int? statusCode,
@@ -2372,7 +2874,7 @@
#convert: convert,
#preview: preview
}),
- returnValue: Future<T>.value(null)) as _i17.Future<T>);
+ returnValue: _i17.Future<T>.value(null)) as _i17.Future<T>);
@override
_i17.Future<T> postJSON<S, T>(String? path,
{int? statusCode,
@@ -2423,7 +2925,7 @@
#body: body,
#preview: preview
}),
- returnValue: Future<T>.value(null)) as _i17.Future<T>);
+ returnValue: _i17.Future<T>.value(null)) as _i17.Future<T>);
@override
_i17.Future<T> patchJSON<S, T>(String? path,
{int? statusCode,
@@ -2445,7 +2947,7 @@
#body: body,
#preview: preview
}),
- returnValue: Future<T>.value(null)) as _i17.Future<T>);
+ returnValue: _i17.Future<T>.value(null)) as _i17.Future<T>);
@override
_i17.Future<T> requestJson<S, T>(String? method, String? path,
{int? statusCode,
@@ -2468,7 +2970,7 @@
#body: body,
#preview: preview
}),
- returnValue: Future<T>.value(null)) as _i17.Future<T>);
+ returnValue: _i17.Future<T>.value(null)) as _i17.Future<T>);
@override
_i17.Future<_i2.Response> request(String? method, String? path,
{Map<String, String>? headers,
@@ -2477,19 +2979,20 @@
int? statusCode,
void Function(_i2.Response)? fail,
String? preview}) =>
- (super.noSuchMethod(
- Invocation.method(#request, [
- method,
- path
- ], {
- #headers: headers,
- #params: params,
- #body: body,
- #statusCode: statusCode,
- #fail: fail,
- #preview: preview
- }),
- returnValue: Future<_i2.Response>.value(_FakeResponse_96())) as _i17.Future<_i2.Response>);
+ (super.noSuchMethod(Invocation.method(#request, [method, path], {#headers: headers, #params: params, #body: body, #statusCode: statusCode, #fail: fail, #preview: preview}),
+ returnValue: _i17.Future<_i2.Response>.value(_FakeResponse_96(
+ this,
+ Invocation.method(#request, [
+ method,
+ path
+ ], {
+ #headers: headers,
+ #params: params,
+ #body: body,
+ #statusCode: statusCode,
+ #fail: fail,
+ #preview: preview
+ })))) as _i17.Future<_i2.Response>);
@override
void handleStatusCode(_i2.Response? response) =>
super.noSuchMethod(Invocation.method(#handleStatusCode, [response]), returnValueForMissingStub: null);
diff --git a/app_dart/test/src/utilities/webhook_generators.dart b/app_dart/test/src/utilities/webhook_generators.dart
index def75e7..67f6429 100644
--- a/app_dart/test/src/utilities/webhook_generators.dart
+++ b/app_dart/test/src/utilities/webhook_generators.dart
@@ -4,33 +4,65 @@
import 'dart:convert';
+import 'package:cocoon_service/protos.dart' as pb;
+import 'package:cocoon_service/src/model/luci/push_message.dart';
import 'package:cocoon_service/src/service/config.dart';
+import 'package:github/github.dart';
import 'package:github/hooks.dart';
-String generatePullRequestEvent(
+PushMessage generateGithubWebhookMessage({
+ String event = 'pull_request',
+ String action = 'merged',
+ int number = 123,
+ String baseRef = kDefaultBranchName,
+ String login = 'dash',
+ String headRef = 'abc',
+ bool isDraft = false,
+ bool merged = false,
+ bool mergeable = true,
+ RepositorySlug? slug,
+}) {
+ final String data = (pb.GithubWebhookMessage.create()
+ ..event = event
+ ..payload = _generatePullRequestEvent(
+ action,
+ number,
+ baseRef,
+ login: login,
+ headRef: headRef,
+ isDraft: isDraft,
+ merged: merged,
+ isMergeable: mergeable,
+ slug: slug,
+ ))
+ .writeToJson();
+ return PushMessage(data: data, messageId: 'abc123');
+}
+
+String _generatePullRequestEvent(
String action,
int number,
String baseRef, {
+ RepositorySlug? slug,
String login = 'flutter',
String headRef = 'wait_for_reassemble',
bool includeCqLabel = false,
bool isDraft = false,
bool merged = false,
- String repoFullName = 'flutter/flutter',
- String repoName = 'flutter',
bool isMergeable = true,
-}) =>
- '''{
+}) {
+ slug ??= Config.flutterSlug;
+ return '''{
"action": "$action",
"number": $number,
"pull_request": {
- "url": "https://api.github.com/repos/$repoFullName/pulls/$number",
+ "url": "https://api.github.com/repos/${slug.fullName}/pulls/$number",
"id": 294034,
"node_id": "MDExOlB1bGxSZXF1ZXN0Mjk0MDMzODQx",
- "html_url": "https://github.com/$repoFullName/pull/$number",
- "diff_url": "https://github.com/$repoFullName/pull/$number.diff",
- "patch_url": "https://github.com/$repoFullName/pull/$number.patch",
- "issue_url": "https://api.github.com/repos/$repoFullName/issues/$number",
+ "html_url": "https://github.com/${slug.fullName}/pull/$number",
+ "diff_url": "https://github.com/${slug.fullName}/pull/$number.diff",
+ "patch_url": "https://github.com/${slug.fullName}/pull/$number.patch",
+ "issue_url": "https://api.github.com/repos/${slug.fullName}/issues/$number",
"number": $number,
"state": "open",
"locked": false,
@@ -70,7 +102,7 @@
{
"id": 487496476,
"node_id": "MDU6TGFiZWw0ODc0OTY0NzY=",
- "url": "https://api.github.com/repos/$repoFullName/labels/cla:%20yes",
+ "url": "https://api.github.com/repos/${slug.fullName}/labels/cla:%20yes",
"name": "cla: yes",
"color": "ffffff",
"default": false
@@ -78,7 +110,7 @@
{
"id": 284437560,
"node_id": "MDU6TGFiZWwyODQ0Mzc1NjA=",
- "url": "https://api.github.com/repos/$repoFullName/labels/framework",
+ "url": "https://api.github.com/repos/${slug.fullName}/labels/framework",
"name": "framework",
"color": "207de5",
"default": false
@@ -87,25 +119,25 @@
{
"id": 283480100,
"node_id": "MDU6TGFiZWwyODM0ODAxMDA=",
- "url": "https://api.github.com/repos/$repoFullName/labels/tool",
+ "url": "https://api.github.com/repos/${slug.fullName}/labels/tool",
"color": "5319e7",
"default": false
},''' : ''}
{
"id": 283480100,
"node_id": "MDU6TGFiZWwyODM0ODAxMDA=",
- "url": "https://api.github.com/repos/$repoFullName/labels/tool",
+ "url": "https://api.github.com/repos/${slug.fullName}/labels/tool",
"name": "tool",
"color": "5319e7",
"default": false
}
],
"milestone": null,
- "commits_url": "https://api.github.com/repos/$repoFullName/pulls/$number/commits",
- "review_comments_url": "https://api.github.com/repos/$repoFullName/pulls/$number/comments",
- "review_comment_url": "https://api.github.com/repos/$repoFullName/pulls/comments{/number}",
- "comments_url": "https://api.github.com/repos/$repoFullName/issues/$number/comments",
- "statuses_url": "https://api.github.com/repos/$repoFullName/statuses/be6ff099a4ee56e152a5fa2f37edd10f79d1269a",
+ "commits_url": "https://api.github.com/repos/${slug.fullName}/pulls/$number/commits",
+ "review_comments_url": "https://api.github.com/repos/${slug.fullName}/pulls/$number/comments",
+ "review_comment_url": "https://api.github.com/repos/${slug.fullName}/pulls/comments{/number}",
+ "comments_url": "https://api.github.com/repos/${slug.fullName}/issues/$number/comments",
+ "statuses_url": "https://api.github.com/repos/${slug.fullName}/statuses/be6ff099a4ee56e152a5fa2f37edd10f79d1269a",
"head": {
"label": "$login:$headRef",
"ref": "$headRef",
@@ -133,8 +165,8 @@
"repo": {
"id": 131232406,
"node_id": "MDEwOlJlcG9zaXRvcnkxMzEyMzI0MDY=",
- "name": "$repoName",
- "full_name": "$repoFullName",
+ "name": "${slug.name}",
+ "full_name": "${slug.fullName}",
"private": false,
"owner": {
"login": "flutter",
@@ -156,53 +188,53 @@
"type": "User",
"site_admin": false
},
- "html_url": "https://github.com/$repoFullName",
+ "html_url": "https://github.com/${slug.fullName}",
"description": "Flutter makes it easy and fast to build beautiful mobile apps.",
"fork": true,
- "url": "https://api.github.com/repos/$repoFullName",
- "forks_url": "https://api.github.com/repos/$repoFullName/forks",
- "keys_url": "https://api.github.com/repos/$repoFullName/keys{/key_id}",
- "collaborators_url": "https://api.github.com/repos/$repoFullName/collaborators{/collaborator}",
- "teams_url": "https://api.github.com/repos/$repoFullName/teams",
- "hooks_url": "https://api.github.com/repos/$repoFullName/hooks",
- "issue_events_url": "https://api.github.com/repos/$repoFullName/issues/events{/number}",
- "events_url": "https://api.github.com/repos/$repoFullName/events",
- "assignees_url": "https://api.github.com/repos/$repoFullName/assignees{/user}",
- "branches_url": "https://api.github.com/repos/$repoFullName/branches{/branch}",
- "tags_url": "https://api.github.com/repos/$repoFullName/tags",
- "blobs_url": "https://api.github.com/repos/$repoFullName/git/blobs{/sha}",
- "git_tags_url": "https://api.github.com/repos/$repoFullName/git/tags{/sha}",
- "git_refs_url": "https://api.github.com/repos/$repoFullName/git/refs{/sha}",
- "trees_url": "https://api.github.com/repos/$repoFullName/git/trees{/sha}",
- "statuses_url": "https://api.github.com/repos/$repoFullName/statuses/{sha}",
- "languages_url": "https://api.github.com/repos/$repoFullName/languages",
- "stargazers_url": "https://api.github.com/repos/$repoFullName/stargazers",
- "contributors_url": "https://api.github.com/repos/$repoFullName/contributors",
- "subscribers_url": "https://api.github.com/repos/$repoFullName/subscribers",
- "subscription_url": "https://api.github.com/repos/$repoFullName/subscription",
- "commits_url": "https://api.github.com/repos/$repoFullName/commits{/sha}",
- "git_commits_url": "https://api.github.com/repos/$repoFullName/git/commits{/sha}",
- "comments_url": "https://api.github.com/repos/$repoFullName/comments{/number}",
- "issue_comment_url": "https://api.github.com/repos/$repoFullName/issues/comments{/number}",
- "contents_url": "https://api.github.com/repos/$repoFullName/contents/{+path}",
- "compare_url": "https://api.github.com/repos/$repoFullName/compare/{base}...{head}",
- "merges_url": "https://api.github.com/repos/$repoFullName/merges",
- "archive_url": "https://api.github.com/repos/$repoFullName/{archive_format}{/ref}",
- "downloads_url": "https://api.github.com/repos/$repoFullName/downloads",
- "issues_url": "https://api.github.com/repos/$repoFullName/issues{/number}",
- "pulls_url": "https://api.github.com/repos/$repoFullName/pulls{/number}",
- "milestones_url": "https://api.github.com/repos/$repoFullName/milestones{/number}",
- "notifications_url": "https://api.github.com/repos/$repoFullName/notifications{?since,all,participating}",
- "labels_url": "https://api.github.com/repos/$repoFullName/labels{/name}",
- "releases_url": "https://api.github.com/repos/$repoFullName/releases{/id}",
- "deployments_url": "https://api.github.com/repos/$repoFullName/deployments",
+ "url": "https://api.github.com/repos/${slug.fullName}",
+ "forks_url": "https://api.github.com/repos/${slug.fullName}/forks",
+ "keys_url": "https://api.github.com/repos/${slug.fullName}/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/${slug.fullName}/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/${slug.fullName}/teams",
+ "hooks_url": "https://api.github.com/repos/${slug.fullName}/hooks",
+ "issue_events_url": "https://api.github.com/repos/${slug.fullName}/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/${slug.fullName}/events",
+ "assignees_url": "https://api.github.com/repos/${slug.fullName}/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/${slug.fullName}/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/${slug.fullName}/tags",
+ "blobs_url": "https://api.github.com/repos/${slug.fullName}/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/${slug.fullName}/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/${slug.fullName}/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/${slug.fullName}/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/${slug.fullName}/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/${slug.fullName}/languages",
+ "stargazers_url": "https://api.github.com/repos/${slug.fullName}/stargazers",
+ "contributors_url": "https://api.github.com/repos/${slug.fullName}/contributors",
+ "subscribers_url": "https://api.github.com/repos/${slug.fullName}/subscribers",
+ "subscription_url": "https://api.github.com/repos/${slug.fullName}/subscription",
+ "commits_url": "https://api.github.com/repos/${slug.fullName}/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/${slug.fullName}/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/${slug.fullName}/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/${slug.fullName}/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/${slug.fullName}/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/${slug.fullName}/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/${slug.fullName}/merges",
+ "archive_url": "https://api.github.com/repos/${slug.fullName}/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/${slug.fullName}/downloads",
+ "issues_url": "https://api.github.com/repos/${slug.fullName}/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/${slug.fullName}/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/${slug.fullName}/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/${slug.fullName}/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/${slug.fullName}/labels{/name}",
+ "releases_url": "https://api.github.com/repos/${slug.fullName}/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/${slug.fullName}/deployments",
"created_at": "2018-04-27T02:03:08Z",
"updated_at": "2019-06-27T06:56:59Z",
"pushed_at": "2019-07-03T19:40:11Z",
- "git_url": "git://github.com/$repoFullName.git",
- "ssh_url": "git@github.com:$repoFullName.git",
- "clone_url": "https://github.com/$repoFullName.git",
- "svn_url": "https://github.com/$repoFullName",
+ "git_url": "git://github.com/${slug.fullName}.git",
+ "ssh_url": "git@github.com:${slug.fullName}.git",
+ "clone_url": "https://github.com/${slug.fullName}.git",
+ "svn_url": "https://github.com/${slug.fullName}",
"homepage": "https://flutter.io",
"size": 94508,
"stargazers_count": 1,
@@ -258,8 +290,8 @@
"repo": {
"id": 31792824,
"node_id": "MDEwOlJlcG9zaXRvcnkzMTc5MjgyNA==",
- "name": "$repoName",
- "full_name": "$repoFullName",
+ "name": "${slug.name}",
+ "full_name": "${slug.fullName}",
"private": false,
"owner": {
"login": "flutter",
@@ -281,53 +313,53 @@
"type": "Organization",
"site_admin": false
},
- "html_url": "https://github.com/$repoFullName",
+ "html_url": "https://github.com/${slug.fullName}",
"description": "Flutter makes it easy and fast to build beautiful mobile apps.",
"fork": false,
- "url": "https://api.github.com/repos/$repoFullName",
- "forks_url": "https://api.github.com/repos/$repoFullName/forks",
- "keys_url": "https://api.github.com/repos/$repoFullName/keys{/key_id}",
- "collaborators_url": "https://api.github.com/repos/$repoFullName/collaborators{/collaborator}",
- "teams_url": "https://api.github.com/repos/$repoFullName/teams",
- "hooks_url": "https://api.github.com/repos/$repoFullName/hooks",
- "issue_events_url": "https://api.github.com/repos/$repoFullName/issues/events{/number}",
- "events_url": "https://api.github.com/repos/$repoFullName/events",
- "assignees_url": "https://api.github.com/repos/$repoFullName/assignees{/user}",
- "branches_url": "https://api.github.com/repos/$repoFullName/branches{/branch}",
- "tags_url": "https://api.github.com/repos/$repoFullName/tags",
- "blobs_url": "https://api.github.com/repos/$repoFullName/git/blobs{/sha}",
- "git_tags_url": "https://api.github.com/repos/$repoFullName/git/tags{/sha}",
- "git_refs_url": "https://api.github.com/repos/$repoFullName/git/refs{/sha}",
- "trees_url": "https://api.github.com/repos/$repoFullName/git/trees{/sha}",
- "statuses_url": "https://api.github.com/repos/$repoFullName/statuses/{sha}",
- "languages_url": "https://api.github.com/repos/$repoFullName/languages",
- "stargazers_url": "https://api.github.com/repos/$repoFullName/stargazers",
- "contributors_url": "https://api.github.com/repos/$repoFullName/contributors",
- "subscribers_url": "https://api.github.com/repos/$repoFullName/subscribers",
- "subscription_url": "https://api.github.com/repos/$repoFullName/subscription",
- "commits_url": "https://api.github.com/repos/$repoFullName/commits{/sha}",
- "git_commits_url": "https://api.github.com/repos/$repoFullName/git/commits{/sha}",
- "comments_url": "https://api.github.com/repos/$repoFullName/comments{/number}",
- "issue_comment_url": "https://api.github.com/repos/$repoFullName/issues/comments{/number}",
- "contents_url": "https://api.github.com/repos/$repoFullName/contents/{+path}",
- "compare_url": "https://api.github.com/repos/$repoFullName/compare/{base}...{head}",
- "merges_url": "https://api.github.com/repos/$repoFullName/merges",
- "archive_url": "https://api.github.com/repos/$repoFullName/{archive_format}{/ref}",
- "downloads_url": "https://api.github.com/repos/$repoFullName/downloads",
- "issues_url": "https://api.github.com/repos/$repoFullName/issues{/number}",
- "pulls_url": "https://api.github.com/repos/$repoFullName/pulls{/number}",
- "milestones_url": "https://api.github.com/repos/$repoFullName/milestones{/number}",
- "notifications_url": "https://api.github.com/repos/$repoFullName/notifications{?since,all,participating}",
- "labels_url": "https://api.github.com/repos/$repoFullName/labels{/name}",
- "releases_url": "https://api.github.com/repos/$repoFullName/releases{/id}",
- "deployments_url": "https://api.github.com/repos/$repoFullName/deployments",
+ "url": "https://api.github.com/repos/${slug.fullName}",
+ "forks_url": "https://api.github.com/repos/${slug.fullName}/forks",
+ "keys_url": "https://api.github.com/repos/${slug.fullName}/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/${slug.fullName}/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/${slug.fullName}/teams",
+ "hooks_url": "https://api.github.com/repos/${slug.fullName}/hooks",
+ "issue_events_url": "https://api.github.com/repos/${slug.fullName}/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/${slug.fullName}/events",
+ "assignees_url": "https://api.github.com/repos/${slug.fullName}/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/${slug.fullName}/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/${slug.fullName}/tags",
+ "blobs_url": "https://api.github.com/repos/${slug.fullName}/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/${slug.fullName}/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/${slug.fullName}/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/${slug.fullName}/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/${slug.fullName}/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/${slug.fullName}/languages",
+ "stargazers_url": "https://api.github.com/repos/${slug.fullName}/stargazers",
+ "contributors_url": "https://api.github.com/repos/${slug.fullName}/contributors",
+ "subscribers_url": "https://api.github.com/repos/${slug.fullName}/subscribers",
+ "subscription_url": "https://api.github.com/repos/${slug.fullName}/subscription",
+ "commits_url": "https://api.github.com/repos/${slug.fullName}/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/${slug.fullName}/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/${slug.fullName}/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/${slug.fullName}/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/${slug.fullName}/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/${slug.fullName}/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/${slug.fullName}/merges",
+ "archive_url": "https://api.github.com/repos/${slug.fullName}/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/${slug.fullName}/downloads",
+ "issues_url": "https://api.github.com/repos/${slug.fullName}/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/${slug.fullName}/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/${slug.fullName}/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/${slug.fullName}/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/${slug.fullName}/labels{/name}",
+ "releases_url": "https://api.github.com/repos/${slug.fullName}/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/${slug.fullName}/deployments",
"created_at": "2015-03-06T22:54:58Z",
"updated_at": "2019-07-04T02:08:44Z",
"pushed_at": "2019-07-04T02:03:04Z",
- "git_url": "git://github.com/$repoFullName.git",
- "ssh_url": "git@github.com:$repoFullName.git",
- "clone_url": "https://github.com/$repoFullName.git",
- "svn_url": "https://github.com/$repoFullName",
+ "git_url": "git://github.com/${slug.fullName}.git",
+ "ssh_url": "git@github.com:${slug.fullName}.git",
+ "clone_url": "https://github.com/${slug.fullName}.git",
+ "svn_url": "https://github.com/${slug.fullName}",
"homepage": "https://flutter.dev",
"size": 65507,
"stargazers_count": 68944,
@@ -358,28 +390,28 @@
},
"_links": {
"self": {
- "href": "https://api.github.com/repos/$repoFullName/pulls/$number"
+ "href": "https://api.github.com/repos/${slug.fullName}/pulls/$number"
},
"html": {
- "href": "https://github.com/$repoFullName/pull/$number"
+ "href": "https://github.com/${slug.fullName}/pull/$number"
},
"issue": {
- "href": "https://api.github.com/repos/$repoFullName/issues/$number"
+ "href": "https://api.github.com/repos/${slug.fullName}/issues/$number"
},
"comments": {
- "href": "https://api.github.com/repos/$repoFullName/issues/$number/comments"
+ "href": "https://api.github.com/repos/${slug.fullName}/issues/$number/comments"
},
"review_comments": {
- "href": "https://api.github.com/repos/$repoFullName/pulls/$number/comments"
+ "href": "https://api.github.com/repos/${slug.fullName}/pulls/$number/comments"
},
"review_comment": {
- "href": "https://api.github.com/repos/$repoFullName/pulls/comments{/number}"
+ "href": "https://api.github.com/repos/${slug.fullName}/pulls/comments{/number}"
},
"commits": {
- "href": "https://api.github.com/repos/$repoFullName/pulls/$number/commits"
+ "href": "https://api.github.com/repos/${slug.fullName}/pulls/$number/commits"
},
"statuses": {
- "href": "https://api.github.com/repos/$repoFullName/statuses/deadbeef"
+ "href": "https://api.github.com/repos/${slug.fullName}/statuses/deadbeef"
}
},
"author_association": "MEMBER",
@@ -400,8 +432,8 @@
"repository": {
"id": 1868532,
"node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=",
- "name": "$repoName",
- "full_name": "$repoFullName",
+ "name": "${slug.name}",
+ "full_name": "${slug.fullName}",
"private": false,
"owner": {
"login": "flutter",
@@ -423,53 +455,53 @@
"type": "User",
"site_admin": false
},
- "html_url": "https://github.com/$repoFullName",
+ "html_url": "https://github.com/${slug.fullName}",
"description": null,
"fork": false,
- "url": "https://api.github.com/repos/$repoFullName",
- "forks_url": "https://api.github.com/repos/$repoFullName/forks",
- "keys_url": "https://api.github.com/repos/$repoFullName/keys{/key_id}",
- "collaborators_url": "https://api.github.com/repos/$repoFullName/collaborators{/collaborator}",
- "teams_url": "https://api.github.com/repos/$repoFullName/teams",
- "hooks_url": "https://api.github.com/repos/$repoFullName/hooks",
- "issue_events_url": "https://api.github.com/repos/$repoFullName/issues/events{/number}",
- "events_url": "https://api.github.com/repos/$repoFullName/events",
- "assignees_url": "https://api.github.com/repos/$repoFullName/assignees{/user}",
- "branches_url": "https://api.github.com/repos/$repoFullName/branches{/branch}",
- "tags_url": "https://api.github.com/repos/$repoFullName/tags",
- "blobs_url": "https://api.github.com/repos/$repoFullName/git/blobs{/sha}",
- "git_tags_url": "https://api.github.com/repos/$repoFullName/git/tags{/sha}",
- "git_refs_url": "https://api.github.com/repos/$repoFullName/git/refs{/sha}",
- "trees_url": "https://api.github.com/repos/$repoFullName/git/trees{/sha}",
- "statuses_url": "https://api.github.com/repos/$repoFullName/statuses/{sha}",
- "languages_url": "https://api.github.com/repos/$repoFullName/languages",
- "stargazers_url": "https://api.github.com/repos/$repoFullName/stargazers",
- "contributors_url": "https://api.github.com/repos/$repoFullName/contributors",
- "subscribers_url": "https://api.github.com/repos/$repoFullName/subscribers",
- "subscription_url": "https://api.github.com/repos/$repoFullName/subscription",
- "commits_url": "https://api.github.com/repos/$repoFullName/commits{/sha}",
- "git_commits_url": "https://api.github.com/repos/$repoFullName/git/commits{/sha}",
- "comments_url": "https://api.github.com/repos/$repoFullName/comments{/number}",
- "issue_comment_url": "https://api.github.com/repos/$repoFullName/issues/comments{/number}",
- "contents_url": "https://api.github.com/repos/$repoFullName/contents/{+path}",
- "compare_url": "https://api.github.com/repos/$repoFullName/compare/{base}...{head}",
- "merges_url": "https://api.github.com/repos/$repoFullName/merges",
- "archive_url": "https://api.github.com/repos/$repoFullName/{archive_format}{/ref}",
- "downloads_url": "https://api.github.com/repos/$repoFullName/downloads",
- "issues_url": "https://api.github.com/repos/$repoFullName/issues{/number}",
- "pulls_url": "https://api.github.com/repos/$repoFullName/pulls{/number}",
- "milestones_url": "https://api.github.com/repos/$repoFullName/milestones{/number}",
- "notifications_url": "https://api.github.com/repos/$repoFullName/notifications{?since,all,participating}",
- "labels_url": "https://api.github.com/repos/$repoFullName/labels{/name}",
- "releases_url": "https://api.github.com/repos/$repoFullName/releases{/id}",
- "deployments_url": "https://api.github.com/repos/$repoFullName/deployments",
+ "url": "https://api.github.com/repos/${slug.fullName}",
+ "forks_url": "https://api.github.com/repos/${slug.fullName}/forks",
+ "keys_url": "https://api.github.com/repos/${slug.fullName}/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/${slug.fullName}/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/${slug.fullName}/teams",
+ "hooks_url": "https://api.github.com/repos/${slug.fullName}/hooks",
+ "issue_events_url": "https://api.github.com/repos/${slug.fullName}/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/${slug.fullName}/events",
+ "assignees_url": "https://api.github.com/repos/${slug.fullName}/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/${slug.fullName}/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/${slug.fullName}/tags",
+ "blobs_url": "https://api.github.com/repos/${slug.fullName}/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/${slug.fullName}/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/${slug.fullName}/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/${slug.fullName}/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/${slug.fullName}/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/${slug.fullName}/languages",
+ "stargazers_url": "https://api.github.com/repos/${slug.fullName}/stargazers",
+ "contributors_url": "https://api.github.com/repos/${slug.fullName}/contributors",
+ "subscribers_url": "https://api.github.com/repos/${slug.fullName}/subscribers",
+ "subscription_url": "https://api.github.com/repos/${slug.fullName}/subscription",
+ "commits_url": "https://api.github.com/repos/${slug.fullName}/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/${slug.fullName}/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/${slug.fullName}/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/${slug.fullName}/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/${slug.fullName}/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/${slug.fullName}/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/${slug.fullName}/merges",
+ "archive_url": "https://api.github.com/repos/${slug.fullName}/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/${slug.fullName}/downloads",
+ "issues_url": "https://api.github.com/repos/${slug.fullName}/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/${slug.fullName}/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/${slug.fullName}/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/${slug.fullName}/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/${slug.fullName}/labels{/name}",
+ "releases_url": "https://api.github.com/repos/${slug.fullName}/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/${slug.fullName}/deployments",
"created_at": "2019-05-15T15:19:25Z",
"updated_at": "2019-05-15T15:19:27Z",
"pushed_at": "2019-05-15T15:20:32Z",
- "git_url": "git://github.com/$repoFullName.git",
- "ssh_url": "git@github.com:$repoFullName.git",
- "clone_url": "https://github.com/$repoFullName.git",
- "svn_url": "https://github.com/$repoFullName",
+ "git_url": "git://github.com/${slug.fullName}.git",
+ "ssh_url": "git@github.com:${slug.fullName}.git",
+ "clone_url": "https://github.com/${slug.fullName}.git",
+ "svn_url": "https://github.com/${slug.fullName}",
"homepage": null,
"size": 0,
"stargazers_count": 0,
@@ -512,12 +544,13 @@
"site_admin": false
}
}''';
+}
-String generateCheckRunEvent({
+PushMessage generateCheckRunEvent({
String action = 'created',
int numberOfPullRequests = 1,
}) {
- String body = '''{
+ String data = '''{
"action": "$action",
"check_run": {
"id": 128620228,
@@ -684,7 +717,7 @@
"pull_requests": [''';
for (int i = 0; i < numberOfPullRequests; i++) {
- body += '''{
+ data += '''{
"url": "https://api.github.com/repos/flutter/flutter/pulls/2",
"id": 279147437,
"number": ${i + 2},
@@ -708,10 +741,10 @@
}
}''';
if (i < numberOfPullRequests - 1) {
- body += ',';
+ data += ',';
}
}
- body += '''],
+ data += '''],
"deployment": {
"url": "https://api.github.com/repos/flutter/flutter/deployments/326191728",
"id": 326191728,
@@ -841,7 +874,23 @@
"site_admin": false
}
}''';
- return body;
+ final pb.GithubWebhookMessage message = pb.GithubWebhookMessage(
+ event: 'check_run',
+ payload: data,
+ );
+ return PushMessage(
+ data: message.writeToJson(),
+ messageId: 'abc123',
+ );
+}
+
+PushMessage generateCreateBranchMessage(String branchName, String repository, {bool forked = false}) {
+ final CreateEvent createEvent = generateCreateBranchEvent(branchName, repository, forked: forked);
+ final pb.GithubWebhookMessage message = pb.GithubWebhookMessage(
+ event: 'create',
+ payload: jsonEncode(createEvent),
+ );
+ return PushMessage(data: message.writeToJson(), messageId: 'abc123');
}
CreateEvent generateCreateBranchEvent(String branchName, String repository, {bool forked = false}) =>