// Mocks generated by Mockito 5.0.14 from annotations
// in metrics_center/test/skiaperf_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i2;

import 'package:gcloud/common.dart' as _i4;
import 'package:gcloud/storage.dart' as _i3;
import 'package:mockito/mockito.dart' as _i1;

// ignore_for_file: always_specify_types
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: camel_case_types
// ignore_for_file: comment_references
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_overrides
// ignore_for_file: unnecessary_parenthesis

class _FakeStreamSink_0<S> extends _i1.Fake implements _i2.StreamSink<S> {}

class _FakeObjectInfo_1 extends _i1.Fake implements _i3.ObjectInfo {}

class _FakePage_2<T> extends _i1.Fake implements _i4.Page<T> {}

class _FakeDateTime_3 extends _i1.Fake implements DateTime {}

class _FakeUri_4 extends _i1.Fake implements Uri {}

class _FakeObjectGeneration_5 extends _i1.Fake
    implements _i3.ObjectGeneration {}

class _FakeObjectMetadata_6 extends _i1.Fake implements _i3.ObjectMetadata {}

/// A class which mocks [Bucket].
///
/// See the documentation for Mockito's code generation for more information.
class MockBucket extends _i1.Mock implements _i3.Bucket {
  MockBucket() {
    _i1.throwOnMissingStub(this);
  }

  @override
  String get bucketName =>
      (super.noSuchMethod(Invocation.getter(#bucketName), returnValue: '')
          as String);
  @override
  String absoluteObjectName(String? objectName) =>
      (super.noSuchMethod(Invocation.method(#absoluteObjectName, [objectName]),
          returnValue: '') as String);
  @override
  _i2.StreamSink<List<int>> write(String? objectName,
          {int? length,
          _i3.ObjectMetadata? metadata,
          _i3.Acl? acl,
          _i3.PredefinedAcl? predefinedAcl,
          String? contentType}) =>
      (super.noSuchMethod(
              Invocation.method(#write, [
                objectName
              ], {
                #length: length,
                #metadata: metadata,
                #acl: acl,
                #predefinedAcl: predefinedAcl,
                #contentType: contentType
              }),
              returnValue: _FakeStreamSink_0<List<int>>())
          as _i2.StreamSink<List<int>>);
  @override
  _i2.Future<_i3.ObjectInfo> writeBytes(String? name, List<int>? bytes,
          {_i3.ObjectMetadata? metadata,
          _i3.Acl? acl,
          _i3.PredefinedAcl? predefinedAcl,
          String? contentType}) =>
      (super.noSuchMethod(
              Invocation.method(#writeBytes, [
                name,
                bytes
              ], {
                #metadata: metadata,
                #acl: acl,
                #predefinedAcl: predefinedAcl,
                #contentType: contentType
              }),
              returnValue: Future<_i3.ObjectInfo>.value(_FakeObjectInfo_1()))
          as _i2.Future<_i3.ObjectInfo>);
  @override
  _i2.Stream<List<int>> read(String? objectName, {int? offset, int? length}) =>
      (super.noSuchMethod(
          Invocation.method(
              #read, [objectName], {#offset: offset, #length: length}),
          returnValue: Stream<List<int>>.empty()) as _i2.Stream<List<int>>);
  @override
  _i2.Future<_i3.ObjectInfo> info(String? name) =>
      (super.noSuchMethod(Invocation.method(#info, [name]),
              returnValue: Future<_i3.ObjectInfo>.value(_FakeObjectInfo_1()))
          as _i2.Future<_i3.ObjectInfo>);
  @override
  _i2.Future<dynamic> delete(String? name) =>
      (super.noSuchMethod(Invocation.method(#delete, [name]),
          returnValue: Future<dynamic>.value()) as _i2.Future<dynamic>);
  @override
  _i2.Future<dynamic> updateMetadata(
          String? objectName, _i3.ObjectMetadata? metadata) =>
      (super.noSuchMethod(
          Invocation.method(#updateMetadata, [objectName, metadata]),
          returnValue: Future<dynamic>.value()) as _i2.Future<dynamic>);
  @override
  _i2.Stream<_i3.BucketEntry> list({String? prefix, String? delimiter}) =>
      (super.noSuchMethod(
              Invocation.method(
                  #list, [], {#prefix: prefix, #delimiter: delimiter}),
              returnValue: Stream<_i3.BucketEntry>.empty())
          as _i2.Stream<_i3.BucketEntry>);
  @override
  _i2.Future<_i4.Page<_i3.BucketEntry>> page(
          {String? prefix, String? delimiter, int? pageSize = 50}) =>
      (super.noSuchMethod(
              Invocation.method(#page, [], {
                #prefix: prefix,
                #delimiter: delimiter,
                #pageSize: pageSize
              }),
              returnValue: Future<_i4.Page<_i3.BucketEntry>>.value(
                  _FakePage_2<_i3.BucketEntry>()))
          as _i2.Future<_i4.Page<_i3.BucketEntry>>);
  @override
  String toString() => super.toString();
}

/// A class which mocks [ObjectInfo].
///
/// See the documentation for Mockito's code generation for more information.
class MockObjectInfo extends _i1.Mock implements _i3.ObjectInfo {
  MockObjectInfo() {
    _i1.throwOnMissingStub(this);
  }

  @override
  String get name =>
      (super.noSuchMethod(Invocation.getter(#name), returnValue: '') as String);
  @override
  int get length =>
      (super.noSuchMethod(Invocation.getter(#length), returnValue: 0) as int);
  @override
  DateTime get updated => (super.noSuchMethod(Invocation.getter(#updated),
      returnValue: _FakeDateTime_3()) as DateTime);
  @override
  String get etag =>
      (super.noSuchMethod(Invocation.getter(#etag), returnValue: '') as String);
  @override
  List<int> get md5Hash =>
      (super.noSuchMethod(Invocation.getter(#md5Hash), returnValue: <int>[])
          as List<int>);
  @override
  int get crc32CChecksum =>
      (super.noSuchMethod(Invocation.getter(#crc32CChecksum), returnValue: 0)
          as int);
  @override
  Uri get downloadLink => (super.noSuchMethod(Invocation.getter(#downloadLink),
      returnValue: _FakeUri_4()) as Uri);
  @override
  _i3.ObjectGeneration get generation =>
      (super.noSuchMethod(Invocation.getter(#generation),
          returnValue: _FakeObjectGeneration_5()) as _i3.ObjectGeneration);
  @override
  _i3.ObjectMetadata get metadata =>
      (super.noSuchMethod(Invocation.getter(#metadata),
          returnValue: _FakeObjectMetadata_6()) as _i3.ObjectMetadata);
  @override
  String toString() => super.toString();
}
