// ignore_for_file: sdk_version_async_exported_from_core
// ignore_for_file: unawaited_futures
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import 'example.mocks.dart';

// Real class
class Cat {
  String? sound() => 'Meow';
  bool? eatFood(String? food, {bool? hungry}) => true;
  Future<void> chew() async => print('Chewing...');
  int? walk(List<String>? places) => 7;
  void sleep() {}
  void hunt(String? place, String? prey) {}
  int lives = 9;
}

// Fake class
class FakeCat extends Fake implements Cat {
  @override
  bool? eatFood(String? food, {bool? hungry}) {
    print('Fake eat $food');
    return true;
  }
}

@GenerateMocks([
  Cat
], customMocks: [
  MockSpec<Cat>(as: #MockCatRelaxed, returnNullOnMissingStub: true),
])
void main() {
  late Cat cat;

  setUp(() {
    // Create mock object.
    cat = MockCat();
  });

  test("Let's verify some behaviour!", () {
    // Stub a method before interacting with it.
    when(cat.sound()).thenReturn('Meow');

    // Interact with the mock object.
    cat.sound();

    // Verify the interaction.
    verify(cat.sound());
  });

  test('How about some stubbing?', () {
    try {
      cat.sound();
    } on MissingStubError {
      // Unstubbed methods throw MissingStubError.
    }

    // Unstubbed methods return null.
    expect(cat.sound(), null);

    // Stub a method before interacting with it.
    when(cat.sound()).thenReturn('Purr');
    expect(cat.sound(), 'Purr');

    // You can call it again.
    expect(cat.sound(), 'Purr');

    // Let's change the stub.
    when(cat.sound()).thenReturn('Meow');
    expect(cat.sound(), 'Meow');

    // You can stub getters.
    when(cat.lives).thenReturn(9);
    expect(cat.lives, 9);

    // You can stub a method to throw.
    when(cat.lives).thenThrow(RangeError('Boo'));
    expect(() => cat.lives, throwsRangeError);

    // We can calculate a response at call time.
    var responses = ['Purr', 'Meow'];
    when(cat.sound()).thenAnswer((_) => responses.removeAt(0));
    expect(cat.sound(), 'Purr');
    expect(cat.sound(), 'Meow');
  });

  test('Argument matchers', () {
    // You can use plain arguments themselves
    when(cat.eatFood('fish')).thenReturn(true);

    // ... including collections
    when(cat.walk(['roof', 'tree'])).thenReturn(2);

    // ... or matchers
    when(cat.eatFood(argThat(startsWith('dry')))).thenReturn(false);

    // ... or mix aguments with matchers
    when(cat.eatFood(argThat(startsWith('dry')), hungry: true))
        .thenReturn(true);
    expect(cat.eatFood('fish'), isTrue);
    expect(cat.walk(['roof', 'tree']), equals(2));
    expect(cat.eatFood('dry food'), isFalse);
    expect(cat.eatFood('dry food', hungry: true), isTrue);

    // You can also verify using an argument matcher.
    verify(cat.eatFood('fish'));
    verify(cat.walk(['roof', 'tree']));
    verify(cat.eatFood(argThat(contains('food'))));

    // You can verify setters.
    cat.lives = 9;
    verify(cat.lives = 9);

    cat.hunt('backyard', null);
    verify(cat.hunt('backyard', null)); // OK: no arg matchers.

    cat.hunt('backyard', null);
    verify(cat.hunt(argThat(contains('yard')),
        argThat(isNull))); // OK: null is wrapped in an arg matcher.
  });

  test('Named arguments', () {
    // GOOD: argument matchers include their names.
    when(cat.eatFood(any, hungry: anyNamed('hungry'))).thenReturn(true);
    when(cat.eatFood(any, hungry: argThat(isNotNull, named: 'hungry')))
        .thenReturn(false);
    when(cat.eatFood(any, hungry: captureAnyNamed('hungry'))).thenReturn(false);
    when(cat.eatFood(any, hungry: captureThat(isNotNull, named: 'hungry')))
        .thenReturn(true);
  });

  test('Verifying exact number of invocations / at least x / never', () {
    when(cat.sound()).thenReturn('Meow');

    cat.sound();
    cat.sound();
    // Exact number of invocations
    verify(cat.sound()).called(2);

    cat.sound();
    cat.sound();
    cat.sound();
    // Or using matcher
    verify(cat.sound()).called(greaterThan(1));

    // Or never called
    verifyNever(cat.eatFood(any));
  });

  test('Verification in order', () {
    when(cat.sound()).thenReturn('Meow');
    when(cat.eatFood(any)).thenReturn(true);

    cat.eatFood('Milk');
    cat.sound();
    cat.eatFood('Fish');
    verifyInOrder([cat.eatFood('Milk'), cat.sound(), cat.eatFood('Fish')]);
  });

  test('Making sure interaction(s) never happened on mock', () {
    verifyZeroInteractions(cat);
  });

  test('Finding redundant invocations', () {
    when(cat.sound()).thenReturn('Meow');

    cat.sound();
    verify(cat.sound());
    verifyNoMoreInteractions(cat);
  });

  test('Capturing arguments for further assertions', () {
    when(cat.eatFood(any)).thenReturn(true);

    // Simple capture:
    cat.eatFood('Fish');
    expect(verify(cat.eatFood(captureAny)).captured.single, 'Fish');

    // Capture multiple calls:
    cat.eatFood('Milk');
    cat.eatFood('Fish');
    expect(verify(cat.eatFood(captureAny)).captured, ['Milk', 'Fish']);

    // Conditional capture:
    cat.eatFood('Milk');
    cat.eatFood('Fish');
    expect(
        verify(cat.eatFood(captureThat(startsWith('F')))).captured, ['Fish']);
  });

  test('Waiting for an interaction', () async {
    when(cat.eatFood(any)).thenReturn(true);

    Future<void> chewHelper(Cat cat) {
      return cat.chew();
    }

    // Waiting for a call.
    chewHelper(cat);
    await untilCalled(cat.chew()); // This completes when cat.chew() is called.

    // Waiting for a call that has already happened.
    cat.eatFood('Fish');
    await untilCalled(cat.eatFood(any)); // This completes immediately.
  });

  test('Fake class', () {
    // Create a new fake Cat at runtime.
    var cat = FakeCat();

    cat.eatFood('Milk'); // Prints 'Fake eat Milk'.
    expect(() => cat.sleep(), throwsUnimplementedError);
  });

  test('Relaxed mock class', () {
    // Create a new mock Cat at runtime.
    var cat = MockCatRelaxed();

    // You can call it without stubbing.
    cat.sleep();

    // Returns null unless you stub it.
    expect(cat.sound(), null);
    expect(cat.eatFood('Milk'), null);

    verify(cat.sleep());
  });
}
