// 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.

import "package:expect/expect.dart";

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

class MockCat implements Cat {
  dynamic noSuchMethod(Invocation invocation) {
    return (invocation.positionalArguments[0] as String).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(""));

  // 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", 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();

  // TODO(jmesserly): enable these tests once we have implicit call tearoff.
  // 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([dynamic], doStuff2(42));
  Expect.listEquals([num], doStuff2<num>(42));
  Expect.listEquals([dynamic], doStuff2('hi'));
}
