// Copyright (c) 2013, 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.

library test.instantiate_abstract_class;

import 'dart:mirrors';
import 'package:expect/expect.dart';

assertInstanitationErrorOnGenerativeConstructors(classMirror) {
  classMirror.declarations.values.forEach((decl) {
    if (decl is! MethodMirror) return;
    if (!decl.isGenerativeConstructor) return;
    var args = new List(decl.parameters.length);
    Expect.throws(
        () => classMirror.newInstance(decl.constructorName, args),
        (e) => e is AbstractClassInstantiationError,
        '${decl.qualifiedName} should have failed');
  });
}

runFactoryConstructors(classMirror) {
  classMirror.declarations.values.forEach((decl) {
    if (decl is! MethodMirror) return;
    if (!decl.isFactoryConstructor) return;
    var args = new List(decl.parameters.length);
    classMirror.newInstance(decl.constructorName, args); // Should not throw.
  });
}

abstract class AbstractClass {
  AbstractClass();
  AbstractClass.named();
  factory AbstractClass.named2() => new ConcreteClass();
}

class ConcreteClass implements AbstractClass {}

main() {
  assertInstanitationErrorOnGenerativeConstructors(reflectType(num));
  assertInstanitationErrorOnGenerativeConstructors(reflectType(double));
  assertInstanitationErrorOnGenerativeConstructors(reflectType(StackTrace));

  assertInstanitationErrorOnGenerativeConstructors(reflectType(AbstractClass));
  runFactoryConstructors(reflectType(AbstractClass));
}
