// Copyright (c) 2012, 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 = 2.9

// VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit
// VMOptions=--no-enable-isolate-groups

// Test properties of ports.
library PortTest;

import "package:expect/expect.dart";
import 'dart:isolate';

main() {
  testHashCode();
  testEquals();
  testMap();
}

void testHashCode() {
  ReceivePort rp0 = new ReceivePort();
  ReceivePort rp1 = new ReceivePort();
  Expect.equals(rp0.sendPort.hashCode, rp0.sendPort.hashCode);
  Expect.equals(rp1.sendPort.hashCode, rp1.sendPort.hashCode);
  rp0.close();
  rp1.close();
}

void testEquals() {
  ReceivePort rp0 = new ReceivePort();
  ReceivePort rp1 = new ReceivePort();
  Expect.equals(rp0.sendPort, rp0.sendPort);
  Expect.equals(rp1.sendPort, rp1.sendPort);
  Expect.isFalse(rp0.sendPort == rp1.sendPort);
  rp0.close();
  rp1.close();
}

void testMap() {
  ReceivePort rp0 = new ReceivePort();
  ReceivePort rp1 = new ReceivePort();
  final map = new Map<SendPort, int>();
  map[rp0.sendPort] = 42;
  map[rp1.sendPort] = 87;
  Expect.equals(map[rp0.sendPort], 42);
  Expect.equals(map[rp1.sendPort], 87);

  map[rp0.sendPort] = 99;
  Expect.equals(map[rp0.sendPort], 99);
  Expect.equals(map[rp1.sendPort], 87);

  map.remove(rp0.sendPort);
  Expect.isFalse(map.containsKey(rp0.sendPort));
  Expect.equals(map[rp1.sendPort], 87);

  map.remove(rp1.sendPort);
  Expect.isFalse(map.containsKey(rp0.sendPort));
  Expect.isFalse(map.containsKey(rp1.sendPort));

  rp0.close();
  rp1.close();
}
