// Copyright (c) 2014, 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.cancelable_future;

import 'dart:async';

import 'package:analyzer/src/cancelable_future.dart';
import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';

import 'reflective_tests.dart';
import 'utils.dart';

void main() {
  initializeTestEnvironment();
  runReflectiveTests(CancelableCompleterTests);
  runReflectiveTests(CancelableFutureTests);
}

@reflectiveTest
class CancelableCompleterTests {
  CancelableCompleter<Object> completer;
  int cancelCount = 0;

  void setUp() {
    completer = new CancelableCompleter<Object>(() {
      cancelCount++;
    });
  }

  Future test_cancel_after_cancel() {
    // It is permissible to cancel multiple times, but only the first
    // cancellation has any effect.
    expect(cancelCount, 0);
    completer.future.cancel();
    expect(cancelCount, 1);
    completer.future.cancel();
    expect(cancelCount, 1);
    // Make sure the future still completes with error.
    return completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(error, new isInstanceOf<FutureCanceledError>());
      // And make sure nothing else happens.
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completer.isCompleted, isFalse);
      expect(cancelCount, 1);
    });
  }

  Future test_cancel_after_chaining() {
    bool callbackInvoked = false;
    completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(callbackInvoked, isFalse);
      expect(error, new isInstanceOf<FutureCanceledError>());
      callbackInvoked = true;
    });
    expect(cancelCount, 0);
    completer.future.cancel();
    // The cancel callback should have been invoked immediately.
    expect(cancelCount, 1);
    // But the completer should remain in the "not completed" state.
    expect(completer.isCompleted, isFalse);
    // The callback should be deferred to a microtask.
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isFalse);
      expect(cancelCount, 1);
    });
  }

  Future test_cancel_after_complete() {
    Object obj = new Object();
    completer.complete(obj);
    completer.future.cancel();
    // The cancel callback should not have been invoked, because it was too
    // late to cancel.
    expect(cancelCount, 0);
    // Make sure the future still completes with the object.
    return completer.future.then((result) {
      expect(result, same(obj));
      // And make sure nothing else happens.
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 0);
    });
  }

  Future test_cancel_before_chaining() {
    completer.future.cancel();
    // The cancel callback should have been invoked immediately.
    expect(cancelCount, 1);
    // But the completer should remain in the "not completed" state.
    expect(completer.isCompleted, isFalse);
    bool callbackInvoked = false;
    completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(callbackInvoked, isFalse);
      expect(error, new isInstanceOf<FutureCanceledError>());
      callbackInvoked = true;
    });
    // The callback should be deferred to a microtask.
    expect(callbackInvoked, isFalse);
    expect(completer.isCompleted, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isFalse);
      expect(cancelCount, 1);
    });
  }

  Future test_complete_after_cancel() {
    completer.future.cancel();
    // The cancel callback should have been invoked immediately.
    expect(cancelCount, 1);
    // Completing should have no effect other than to set the isCompleted
    // flag.
    expect(completer.isCompleted, isFalse);
    Object obj = new Object();
    completer.complete(obj);
    expect(completer.isCompleted, isTrue);
    // Make sure the future still completer with error.
    return completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(error, new isInstanceOf<FutureCanceledError>());
      // And make sure nothing else happens.
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 1);
    });
  }

  Future test_complete_after_chaining() {
    Object obj = new Object();
    bool callbackInvoked = false;
    completer.future.then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    expect(completer.isCompleted, isFalse);
    // Running the event loop should have no effect since the completer hasn't
    // been completed yet.
    return pumpEventQueue().then((_) {
      completer.complete(obj);
      expect(completer.isCompleted, isTrue);
      // The callback should be deferred to a microtask.
      expect(callbackInvoked, isFalse);
    }).then((_) => pumpEventQueue()).then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 0);
    });
  }

  void test_complete_after_complete() {
    // As with an ordinary Completer, calling complete() (or completeError)
    // after calling complete() should throw an exception.
    completer.complete();
    expect(() {
      completer.complete();
    }, throws);
    expect(() {
      completer.completeError(new Object());
    }, throws);
  }

  void test_complete_after_completeError() {
    // As with an ordinary Completer, calling complete() (or completeError)
    // after calling completeError() should throw an exception.
    completer.completeError(new Object());
    expect(() {
      completer.complete();
    }, throws);
    expect(() {
      completer.completeError(new Object());
    }, throws);
    // Now absorb the error that's in the completer's future.
    completer.future.catchError((_) => null);
  }

  Future test_complete_before_chaining() {
    Object obj = new Object();
    completer.complete(obj);
    expect(completer.isCompleted, isTrue);
    bool callbackInvoked = false;
    completer.future.then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    // The callback should be deferred to a microtask.
    expect(callbackInvoked, isFalse);
    expect(completer.isCompleted, isTrue);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 0);
    });
  }

  Future test_completeError_after_cancel() {
    completer.future.cancel();
    // The cancel callback should have been invoked immediately.
    expect(cancelCount, 1);
    // Completing should have no effect other than to set the isCompleted
    // flag.
    expect(completer.isCompleted, isFalse);
    Object obj = new Object();
    completer.completeError(obj);
    expect(completer.isCompleted, isTrue);
    // Make sure the future still completes with error.
    return completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(error, new isInstanceOf<FutureCanceledError>());
      // And make sure nothing else happens.
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 1);
    });
  }

  Future test_completeError_after_chaining() {
    Object obj = new Object();
    bool callbackInvoked = false;
    completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(callbackInvoked, isFalse);
      expect(error, same(obj));
      callbackInvoked = true;
    });
    expect(completer.isCompleted, isFalse);
    // Running the event loop should have no effect since the completer hasn't
    // been completed yet.
    return pumpEventQueue().then((_) {
      completer.completeError(obj);
      expect(completer.isCompleted, isTrue);
      // The callback should be deferred to a microtask.
      expect(callbackInvoked, isFalse);
    }).then((_) => pumpEventQueue()).then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 0);
    });
  }

  Future test_completeError_before_chaining() {
    Object obj = new Object();
    completer.completeError(obj);
    expect(completer.isCompleted, isTrue);
    bool callbackInvoked = false;
    completer.future.then((_) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(callbackInvoked, isFalse);
      expect(error, same(obj));
      callbackInvoked = true;
    });
    // The callback should be deferred to a microtask.
    expect(callbackInvoked, isFalse);
    expect(completer.isCompleted, isTrue);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
      expect(completer.isCompleted, isTrue);
      expect(cancelCount, 0);
    });
  }

  void test_initialState() {
    expect(completer.isCompleted, isFalse);
    expect(cancelCount, 0);
  }
}

@reflectiveTest
class CancelableFutureTests {
  Future test_defaultConstructor_returnFuture() {
    Object obj = new Object();
    bool callbackInvoked = false;
    new CancelableFuture(() => new Future(() => obj)).then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
    });
  }

  Future test_defaultConstructor_returnValue() {
    Object obj = new Object();
    bool callbackInvoked = false;
    new CancelableFuture(() => obj).then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
    });
  }

  Future test_defaultConstructor_throwException() {
    Object obj = new Object();
    bool callbackInvoked = false;
    new CancelableFuture(() {
      throw obj;
    }).then((result) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(callbackInvoked, isFalse);
      expect(error, same(obj));
      callbackInvoked = true;
    });
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
    });
  }

  Future test_delayed_noCallback() {
    DateTime start = new DateTime.now();
    return new CancelableFuture.delayed(new Duration(seconds: 1))
        .then((result) {
      DateTime end = new DateTime.now();
      expect(result, isNull);
      expect(end.difference(start).inMilliseconds > 900, isTrue);
    });
  }

  Future test_delayed_withCallback() {
    Object obj = new Object();
    DateTime start = new DateTime.now();
    return new CancelableFuture.delayed(new Duration(seconds: 1), () {
      DateTime end = new DateTime.now();
      expect(end.difference(start).inMilliseconds > 900, isTrue);
      return obj;
    }).then((result) {
      expect(result, same(obj));
    });
  }

  Future test_error() {
    Object obj = new Object();
    return new CancelableFuture.error(obj).then((result) {
      fail('Expected error completion');
    }, onError: (error) {
      expect(error, same(obj));
    });
  }

  Future test_microtask() {
    Object obj = new Object();
    bool callbackInvoked = false;
    new CancelableFuture.microtask(() => obj).then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
    });
  }

  Future test_sync() {
    Object obj = new Object();
    bool callbackInvoked = false;
    new CancelableFuture.sync(() => obj).then((result) {
      expect(callbackInvoked, isFalse);
      expect(result, same(obj));
      callbackInvoked = true;
    }, onError: (error) {
      fail('Expected successful completion');
    });
    expect(callbackInvoked, isFalse);
    return pumpEventQueue().then((_) {
      expect(callbackInvoked, isTrue);
    });
  }

  Future test_value() {
    Object obj = new Object();
    return new CancelableFuture.value(obj).then((result) {
      expect(result, same(obj));
    }, onError: (error) {
      fail('Expected successful completion');
    });
  }
}
