// Mocks generated by Mockito 5.2.0 from annotations
// in webview_flutter_wkwebview/example/ios/.symlinks/plugins/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i3;

import 'package:mockito/mockito.dart' as _i1;
import 'package:webview_flutter_wkwebview/src/common/web_kit.pigeon.dart'
    as _i4;

import '../common/test_web_kit.pigeon.dart' as _i2;

// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// 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_parenthesis
// ignore_for_file: camel_case_types

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

  @override
  void createFromWebsiteDataStore(
          int? identifier, int? websiteDataStoreIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#createFromWebsiteDataStore,
              [identifier, websiteDataStoreIdentifier]),
          returnValueForMissingStub: null);
  @override
  _i3.Future<void> setCookie(int? identifier, _i4.NSHttpCookieData? cookie) =>
      (super.noSuchMethod(Invocation.method(#setCookie, [identifier, cookie]),
          returnValue: Future<void>.value(),
          returnValueForMissingStub: Future<void>.value()) as _i3.Future<void>);
}

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

  @override
  void create(int? identifier) =>
      super.noSuchMethod(Invocation.method(#create, [identifier]),
          returnValueForMissingStub: null);
}

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

  @override
  void createFromWebViewConfiguration(
          int? identifier, int? configurationIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#createFromWebViewConfiguration,
              [identifier, configurationIdentifier]),
          returnValueForMissingStub: null);
  @override
  void setJavaScriptEnabled(int? identifier, bool? enabled) =>
      super.noSuchMethod(
          Invocation.method(#setJavaScriptEnabled, [identifier, enabled]),
          returnValueForMissingStub: null);
}

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

  @override
  void create(int? identifier) =>
      super.noSuchMethod(Invocation.method(#create, [identifier]),
          returnValueForMissingStub: null);
}

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

  @override
  void create(int? identifier) =>
      super.noSuchMethod(Invocation.method(#create, [identifier]),
          returnValueForMissingStub: null);
}

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

  @override
  void createFromWebViewConfiguration(
          int? identifier, int? configurationIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#createFromWebViewConfiguration,
              [identifier, configurationIdentifier]),
          returnValueForMissingStub: null);
  @override
  void addScriptMessageHandler(
          int? identifier, int? handlerIdentifier, String? name) =>
      super.noSuchMethod(
          Invocation.method(
              #addScriptMessageHandler, [identifier, handlerIdentifier, name]),
          returnValueForMissingStub: null);
  @override
  void removeScriptMessageHandler(int? identifier, String? name) =>
      super.noSuchMethod(
          Invocation.method(#removeScriptMessageHandler, [identifier, name]),
          returnValueForMissingStub: null);
  @override
  void removeAllScriptMessageHandlers(int? identifier) => super.noSuchMethod(
      Invocation.method(#removeAllScriptMessageHandlers, [identifier]),
      returnValueForMissingStub: null);
  @override
  void addUserScript(int? identifier, _i4.WKUserScriptData? userScript) => super
      .noSuchMethod(Invocation.method(#addUserScript, [identifier, userScript]),
          returnValueForMissingStub: null);
  @override
  void removeAllUserScripts(int? identifier) =>
      super.noSuchMethod(Invocation.method(#removeAllUserScripts, [identifier]),
          returnValueForMissingStub: null);
}

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

  @override
  void create(int? identifier) =>
      super.noSuchMethod(Invocation.method(#create, [identifier]),
          returnValueForMissingStub: null);
  @override
  void createFromWebView(int? identifier, int? webViewIdentifier) =>
      super.noSuchMethod(
          Invocation.method(
              #createFromWebView, [identifier, webViewIdentifier]),
          returnValueForMissingStub: null);
  @override
  void setAllowsInlineMediaPlayback(int? identifier, bool? allow) =>
      super.noSuchMethod(
          Invocation.method(#setAllowsInlineMediaPlayback, [identifier, allow]),
          returnValueForMissingStub: null);
  @override
  void setMediaTypesRequiringUserActionForPlayback(
          int? identifier, List<_i4.WKAudiovisualMediaTypeEnumData?>? types) =>
      super.noSuchMethod(
          Invocation.method(#setMediaTypesRequiringUserActionForPlayback,
              [identifier, types]),
          returnValueForMissingStub: null);
}

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

  @override
  void create(int? identifier, int? configurationIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#create, [identifier, configurationIdentifier]),
          returnValueForMissingStub: null);
  @override
  void setUIDelegate(int? identifier, int? uiDelegateIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#setUIDelegate, [identifier, uiDelegateIdentifier]),
          returnValueForMissingStub: null);
  @override
  void setNavigationDelegate(
          int? identifier, int? navigationDelegateIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#setNavigationDelegate,
              [identifier, navigationDelegateIdentifier]),
          returnValueForMissingStub: null);
  @override
  String? getUrl(int? identifier) =>
      (super.noSuchMethod(Invocation.method(#getUrl, [identifier])) as String?);
  @override
  double getEstimatedProgress(int? identifier) => (super.noSuchMethod(
      Invocation.method(#getEstimatedProgress, [identifier]),
      returnValue: 0.0) as double);
  @override
  void loadRequest(int? identifier, _i4.NSUrlRequestData? request) =>
      super.noSuchMethod(Invocation.method(#loadRequest, [identifier, request]),
          returnValueForMissingStub: null);
  @override
  void loadHtmlString(int? identifier, String? string, String? baseUrl) =>
      super.noSuchMethod(
          Invocation.method(#loadHtmlString, [identifier, string, baseUrl]),
          returnValueForMissingStub: null);
  @override
  void loadFileUrl(int? identifier, String? url, String? readAccessUrl) =>
      super.noSuchMethod(
          Invocation.method(#loadFileUrl, [identifier, url, readAccessUrl]),
          returnValueForMissingStub: null);
  @override
  void loadFlutterAsset(int? identifier, String? key) => super.noSuchMethod(
      Invocation.method(#loadFlutterAsset, [identifier, key]),
      returnValueForMissingStub: null);
  @override
  bool canGoBack(int? identifier) =>
      (super.noSuchMethod(Invocation.method(#canGoBack, [identifier]),
          returnValue: false) as bool);
  @override
  bool canGoForward(int? identifier) =>
      (super.noSuchMethod(Invocation.method(#canGoForward, [identifier]),
          returnValue: false) as bool);
  @override
  void goBack(int? identifier) =>
      super.noSuchMethod(Invocation.method(#goBack, [identifier]),
          returnValueForMissingStub: null);
  @override
  void goForward(int? identifier) =>
      super.noSuchMethod(Invocation.method(#goForward, [identifier]),
          returnValueForMissingStub: null);
  @override
  void reload(int? identifier) =>
      super.noSuchMethod(Invocation.method(#reload, [identifier]),
          returnValueForMissingStub: null);
  @override
  String? getTitle(int? identifier) =>
      (super.noSuchMethod(Invocation.method(#getTitle, [identifier]))
          as String?);
  @override
  void setAllowsBackForwardNavigationGestures(int? identifier, bool? allow) =>
      super.noSuchMethod(
          Invocation.method(
              #setAllowsBackForwardNavigationGestures, [identifier, allow]),
          returnValueForMissingStub: null);
  @override
  void setCustomUserAgent(int? identifier, String? userAgent) =>
      super.noSuchMethod(
          Invocation.method(#setCustomUserAgent, [identifier, userAgent]),
          returnValueForMissingStub: null);
  @override
  _i3.Future<Object?> evaluateJavaScript(
          int? identifier, String? javaScriptString) =>
      (super.noSuchMethod(
          Invocation.method(
              #evaluateJavaScript, [identifier, javaScriptString]),
          returnValue: Future<Object?>.value()) as _i3.Future<Object?>);
}

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

  @override
  void createFromWebViewConfiguration(
          int? identifier, int? configurationIdentifier) =>
      super.noSuchMethod(
          Invocation.method(#createFromWebViewConfiguration,
              [identifier, configurationIdentifier]),
          returnValueForMissingStub: null);
  @override
  void createDefaultDataStore(int? identifier) => super.noSuchMethod(
      Invocation.method(#createDefaultDataStore, [identifier]),
      returnValueForMissingStub: null);
  @override
  _i3.Future<bool> removeDataOfTypes(
          int? identifier,
          List<_i4.WKWebsiteDataTypeEnumData?>? dataTypes,
          double? modificationTimeInSecondsSinceEpoch) =>
      (super.noSuchMethod(
          Invocation.method(#removeDataOfTypes,
              [identifier, dataTypes, modificationTimeInSecondsSinceEpoch]),
          returnValue: Future<bool>.value(false)) as _i3.Future<bool>);
}
