// Copyright 2020 Dart Mockito authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

class RealClass {
  // Non-nullable parameters
  String? nonNullableParam(int x) => 'Real';
  String? nonNullableParam2<T>(int x) => 'Real';
  String? nonNullableParam3<T extends Object>(T x) => 'Real';
  String? operator +(int x) => 'Real';

  // Non-nullable return types
  int nonNullableReturn(int? x) => 0;
  T nonNullableReturn2<T>(T t) => t;
  Future<int> nonNullableFutureReturn(int? x) => Future.value(0);
  int get getter => 0;

  // Methods which are not manually mocked in `MockedClass`
  String? notMockedNonNullableParam(int x) => 'Real';
  int notMockedNonNullableReturn() => 0;
}

class MockedClass extends Mock implements RealClass {
  @override
  String? nonNullableParam(int? x) =>
      super.noSuchMethod(Invocation.method(#nonNullableParam, [x])) as String?;

  @override
  String? nonNullableParam2<T>(int? x) =>
      super.noSuchMethod(Invocation.genericMethod(#nonNullableParam2, [T], [x]))
          as String?;

  @override
  String? nonNullableParam3<T extends Object>(T? x) =>
      super.noSuchMethod(Invocation.genericMethod(#nonNullableParam3, [T], [x]))
          as String?;

  @override
  String? operator +(int? x) =>
      super.noSuchMethod(Invocation.method(#+, [x])) as String?;

  @override
  int nonNullableReturn(int? x) =>
      super.noSuchMethod(Invocation.method(#nonNullableReturn, [x]),
          returnValue: 1) as int;

  // A generic return type is very tricky to work with in a manually mocked
  // method. What value can be passed as the second argument to
  // `super.noSuchMethod` which will always act as a non-nullable T? We
  // "require" a named parameter, `sentinal` as this value. The named parameter
  // is optional, so that the override is still legal.
  @override
  T nonNullableReturn2<T>(T? x, {T? sentinal}) =>
      super.noSuchMethod(Invocation.method(#nonNullableReturn2, [x]),
          returnValue: sentinal!) as T;

  @override
  Future<int> nonNullableFutureReturn(int? x) =>
      super.noSuchMethod(Invocation.method(#nonNullableFutureReturn, [x]),
          returnValue: Future.value(1)) as Future<int>;

  @override
  int get getter =>
      super.noSuchMethod(Invocation.getter(#getter), returnValue: 1) as int;
}

void main() {
  late MockedClass mock;

  setUp(() {
    mock = MockedClass();
  });

  tearDown(() {
    // In some of the tests that expect an Error to be thrown, Mockito's
    // global state can become invalid. Reset it.
    resetMockitoState();
  });

  group('when()', () {
    test(
        'cannot operate on method with non-nullable params without a manual '
        'mock', () {
      // Normally this use of `any` would be a static error. To push forward to
      // reveal the runtime error, we cast as int.
      expect(
          () => when(mock.notMockedNonNullableParam(any as int))
              .thenReturn('Mock'),
          throwsA(TypeMatcher<TypeError>()));
    });

    test(
        'cannot operate on method with non-nullable return type without a '
        'manual mock', () {
      expect(() => when(mock.notMockedNonNullableReturn()).thenReturn(7),
          throwsA(TypeMatcher<TypeError>()));
    });

    test('should mock method with non-nullable params', () {
      when(mock.nonNullableParam(42)).thenReturn('Mock');
      expect(mock.nonNullableParam(43), isNull);
      expect(mock.nonNullableParam(42), equals('Mock'));
    });

    test(
        'should mock method with non-nullable params with "any" argument '
        'matcher', () {
      when(mock.nonNullableParam(any)).thenReturn('Mock');
      expect(mock.nonNullableParam(100), equals('Mock'));
      expect(mock.nonNullableParam(101), equals('Mock'));
    });

    test(
        'should mock generic method with non-nullable params with "any" '
        'argument matcher', () {
      when(mock.nonNullableParam2(any)).thenReturn('Mock');
      expect(mock.nonNullableParam2(100), equals('Mock'));
      expect(mock.nonNullableParam2(101), equals('Mock'));
    });

    test(
        'should mock generic method with non-nullable generic params with '
        '"any" argument matcher', () {
      when(mock.nonNullableParam3<int>(any)).thenReturn('Mock');
      expect(mock.nonNullableParam3<int>(100), equals('Mock'));
      expect(mock.nonNullableParam3<int>(101), equals('Mock'));
    });

    test('should mock operator with non-nullable param', () {
      when(mock + any).thenReturn('Mock');
      expect(mock + 42, equals('Mock'));
    });

    test('should mock method with non-nullable return type', () {
      when(mock.nonNullableReturn(42)).thenReturn(7);
      expect(mock.nonNullableReturn(42), equals(7));
    });

    test('should mock generic method with non-nullable return type', () {
      when(mock.nonNullableReturn2(42, sentinal: 99)).thenReturn(7);
      expect(mock.nonNullableReturn2(42, sentinal: 99), equals(7));
    });

    test('should mock method with non-nullable Future return type', () async {
      when(mock.nonNullableFutureReturn(42)).thenAnswer((_) async => 7);
      expect(await mock.nonNullableFutureReturn(42), equals(7));
    });

    test('should mock getter', () {
      when(mock.getter).thenReturn(7);
      expect(mock.getter, equals(7));
    });
  });

  group('real calls', () {
    test(
        'should throw a TypeError on a call to a function with a non-nullable '
        'return type without a matching stub', () {
      expect(
          () => mock.nonNullableReturn(43), throwsA(TypeMatcher<TypeError>()));
    });

    test(
        'should throw a NoSuchMethodError on a call without a matching stub, '
        'using `throwOnMissingStub` behavior', () {
      throwOnMissingStub(mock);
      expect(() => mock.nonNullableReturn(43),
          throwsA(TypeMatcher<MissingStubError>()));
    });
  });

  group('verify()', () {
    test('should verify method with non-nullable params', () {
      mock.nonNullableParam(42);
      verify(mock.nonNullableParam(42)).called(1);
    });

    test(
        'should verify method with non-nullable params with "any" argument '
        'matcher', () {
      mock.nonNullableParam(42);
      verify(mock.nonNullableParam(any)).called(1);
    });

    test('should verify method with non-nullable return type', () {
      when(mock.nonNullableReturn(42)).thenReturn(7);
      mock.nonNullableReturn(42);
      verify(mock.nonNullableReturn(42)).called(1);
    });
  });

  group('verifyNever()', () {
    test('should verify method with non-nullable params', () {
      mock.nonNullableParam(42);
      verifyNever(mock.nonNullableParam(43));
    });

    test(
        'should verify method with non-nullable params with "any" argument '
        'matcher', () {
      verifyNever(mock.nonNullableParam(any));
    });

    test('should verify method with non-nullable return type', () {
      verifyNever(mock.nonNullableReturn(42));
    });
  });
}
