// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart test program testing that NoSuchMethod is properly called.

// @dart = 2.9

import "package:expect/expect.dart";

class Cat {
  bool eatFood(String food) => true;
  String scratch(String furniture) => 'purr';
  String mood;
}

class MockCat implements Cat {
  dynamic noSuchMethod(Invocation invocation) {
    var arg = invocation.positionalArguments[0];
    return arg is String && arg.isNotEmpty;
  }
}

class MockCat2 extends MockCat {
  // this apparently works.
  noSuchMethod(_);
}

class MockCat3 extends MockCat2 implements Cat {
  bool eatFood(String food, {double amount});
  String scratch(String furniture, [String furniture2]);

  dynamic noSuchMethod(Invocation invocation) {
    if (invocation.memberName == #scratch) {
      return invocation.positionalArguments.join(',');
    }

    return (invocation.positionalArguments[0] as String).isNotEmpty &&
        invocation.namedArguments[#amount] > 0.5;
  }
}

class MockWithGenerics {
  List<Type> doStuff<T>(T t);

  noSuchMethod(i) => (i as dynamic).typeArguments;
}

class MockWithGetterSetter {
  get getter;
  set setter(value);

  Invocation invocation;
  noSuchMethod(i) {
    invocation = i;
  }
}

class Callable {
  int call() => 1;
  int m() => 2;
}

class MockCallable implements Callable {
  noSuchMethod(i) => i.memberName == #call ? 42 : 0;
}

void main() {
  MockCat mock = new MockCat();
  Expect.isTrue((mock as dynamic).eatFood("cat food"));
  Expect.isFalse(mock.eatFood(""));
  mock.mood = 'sleepy';
  (mock as dynamic).mood = 'playful';
  Expect.throwsTypeError(() {
    (mock as dynamic).mood = 42;
  });

  // In strong mode this will be a runtime type error:
  // bool is not a String. VM will fail with noSuchMethod +.
  Expect.throws(() => mock.scratch("couch") + '');

  var mock2 = new MockCat2();
  Expect.isTrue(mock2.eatFood("cat food"));

  var mock3 = new MockCat3();
  Expect.isTrue(mock3.eatFood("cat food", amount: 0.9));
  Expect.isFalse(mock3.eatFood("cat food", amount: 0.3));
  Expect.equals("chair,null", mock3.scratch("chair"));
  Expect.equals("chair,couch", mock3.scratch("chair", "couch"));
  Expect.equals("chair,null", mock3.scratch("chair", null));
  Expect.equals("chair,", mock3.scratch("chair", ""));

  var g = new MockWithGenerics();
  Expect.listEquals([int], g.doStuff(42));
  Expect.listEquals([num], g.doStuff<num>(42));
  Expect.listEquals([String], g.doStuff('hi'));

  var s = new MockWithGetterSetter();
  s.getter;
  Expect.equals(0, s.invocation.positionalArguments.length);
  Expect.isTrue(s.invocation.isGetter);
  Expect.isFalse(s.invocation.isSetter);
  Expect.isFalse(s.invocation.isMethod);
  s.setter = 42;
  Expect.equals(42, s.invocation.positionalArguments.single);
  Expect.isFalse(s.invocation.isGetter);
  Expect.isTrue(s.invocation.isSetter);
  Expect.isFalse(s.invocation.isMethod);

  testMockTearoffs();
  testMockCallable();
  testMockCallableTearoff();
}

testMockCallable() {
  Callable call = new MockCallable();
  Expect.equals(42, call());
  Expect.equals(42, (call as dynamic)());
  Expect.equals(0, call.m());
  Expect.equals(0, (call as dynamic).m());
}

testMockCallableTearoff() {
  var mock = new MockCallable();
  Function f = mock;
  Expect.equals(42, f());
  Expect.equals(42, (f as dynamic)());
  Expect.equals(f, mock.call);
  Expect.equals(f.call, mock.call);
  Expect.equals((f as dynamic).call, mock.call);
  Expect.equals(f.call, (mock as dynamic).call);
}

typedef bool EatFoodType(String food);

testMockTearoffs() {
  var mock2 = new MockCat2();
  var eat = mock2.eatFood;
  var eat2 = (mock2 as dynamic).eatFood;

  Expect.isTrue(eat is EatFoodType, 'eat is EatFoodType');
  Expect.isTrue(eat2 is EatFoodType, 'eat2 is EatFoodType');
  Expect.equals(eat, eat2, 'eat == eat2');
  Expect.isTrue(eat.runtimeType == eat2.runtimeType,
      'eat.runtimeType == eat2.runtimeType');

  Expect.isTrue(eat("cat food"), 'eat("cat food")');
  Expect.isFalse(eat(""), 'eat("")');
  Expect.isTrue(eat2("cat food"), 'eat2("cat food")');
  Expect.isFalse(eat2(""), 'eat2("")');

  var g = new MockWithGenerics();
  var doStuff = g.doStuff;
  var doStuff2 = (g as dynamic).doStuff;

  Expect.equals(doStuff, doStuff2, 'doStuff == doStuff2');
  Expect.equals(doStuff.runtimeType, doStuff2.runtimeType,
      'doStuff.runtimeType == doStuff2.runtimeType');

  Expect.listEquals([int], doStuff(42));
  Expect.listEquals([num], doStuff<num>(42));
  Expect.listEquals([String], doStuff('hi'));

  // no inference happens because `doStuff2` is dynamic.
  Expect.listEquals([num], doStuff2<num>(42));
  expectIsDynamicOrObject(List types) {
    Expect.equals(1, types.length);
    var t = types[0];
    // TODO(jmesserly): allows either type because of
    // https://github.com/dart-lang/sdk/issues/32483
    Expect.isTrue(t == dynamic || t == Object, '$t == dynamic || $t == Object');
  }

  expectIsDynamicOrObject(doStuff2(42));
  expectIsDynamicOrObject(doStuff2('hi'));
}
