// Copyright (c) 2015, 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_reflective_loader;

@MirrorsUsed(metaTargets: 'ReflectiveTest')
import 'dart:mirrors';
import 'dart:async';

import 'package:unittest/unittest.dart';

/**
 * Runs test methods existing in the given [type].
 *
 * Methods with names starting with `test` are run using [test] function.
 * Methods with names starting with `solo_test` are run using [solo_test] function.
 *
 * Each method is run with a new instance of [type].
 * So, [type] should have a default constructor.
 *
 * If [type] declares method `setUp`, it methods will be invoked before any test
 * method invocation.
 *
 * If [type] declares method `tearDown`, it will be invoked after any test
 * method invocation. If method returns [Future] to test some asyncronous
 * behavior, then `tearDown` will be invoked in `Future.complete`.
 */
void runReflectiveTests(Type type) {
  ClassMirror classMirror = reflectClass(type);
  if (!classMirror.metadata.any((InstanceMirror annotation) =>
  annotation.type.reflectedType == ReflectiveTest)) {
    String name = MirrorSystem.getName(classMirror.qualifiedName);
    throw new Exception('Class $name must have annotation "@reflectiveTest" '
    'in order to be run by runReflectiveTests.');
  }
  String className = MirrorSystem.getName(classMirror.simpleName);
  group(className, () {
    classMirror.instanceMembers.forEach((symbol, memberMirror) {
      // we need only methods
      if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) {
        return;
      }
      String memberName = MirrorSystem.getName(symbol);
      // test_
      if (memberName.startsWith('test_')) {
        test(memberName, () {
          return _runTest(classMirror, symbol);
        });
        return;
      }
      // solo_test_
      if (memberName.startsWith('solo_test_')) {
        solo_test(memberName, () {
          return _runTest(classMirror, symbol);
        });
      }
      // fail_test_
      if (memberName.startsWith('fail_')) {
        test(memberName, () {
          return _runFailingTest(classMirror, symbol);
        });
      }
      // solo_fail_test_
      if (memberName.startsWith('solo_fail_')) {
        solo_test(memberName, () {
          return _runFailingTest(classMirror, symbol);
        });
      }
    });
  });
}

Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
  var invocationResult = null;
  try {
    invocationResult = instanceMirror.invoke(symbol, []).reflectee;
  } on NoSuchMethodError {}
  if (invocationResult is Future) {
    return invocationResult;
  } else {
    return new Future.value(invocationResult);
  }
}

/**
 * Run a test that is expected to fail, and confirm that it fails.
 *
 * This properly handles the following cases:
 * - The test fails by throwing an exception
 * - The test returns a future which completes with an error.
 *
 * However, it does not handle the case where the test creates an asynchronous
 * callback using expectAsync(), and that callback generates a failure.
 */
Future _runFailingTest(ClassMirror classMirror, Symbol symbol) {
  return new Future(() => _runTest(classMirror, symbol)).then((_) {
    fail('Test passed - expected to fail.');
  }, onError: (_) {});
}

_runTest(ClassMirror classMirror, Symbol symbol) {
  InstanceMirror instanceMirror = classMirror.newInstance(new Symbol(''), []);
  return _invokeSymbolIfExists(instanceMirror, #setUp)
  .then((_) => instanceMirror.invoke(symbol, []).reflectee)
  .whenComplete(() => _invokeSymbolIfExists(instanceMirror, #tearDown));
}

/**
 * A marker annotation used to instruct dart2js to keep reflection information
 * for the annotated classes.
 */
class ReflectiveTest {
  const ReflectiveTest();
}

/**
 * A marker annotation used to instruct dart2js to keep reflection information
 * for the annotated classes.
 */
const ReflectiveTest reflectiveTest = const ReflectiveTest();
