blob: 115ce1162c2b77b479e6937d05281e33b84efbf6 [file] [log] [blame]
// 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.
/// @assertion Stream<T> distinct([bool equals(T previous, T next)])
/// If a broadcast stream is listened to more than once, each subscription
/// will individually perform the equals test.
/// @description Checks that [equals] is called for each subscription.
/// @issue #29638
/// @author a.semenov@unipro.ru
library distinct_A03_t01;
import "dart:async";
import "../../../Utils/expect.dart";
class Key<T> {
T previous;
T next;
Key(this.previous, this.next);
bool operator ==(other) =>
(other is Key) &&
other.previous == this.previous &&
other.next == this.next;
int get hashCode {
return previous.hashCode ^ next.hashCode;
}
String toString() {
return "[$previous,$next]";
}
}
Future<List<T>> subscribe<T>(Stream<T> stream) {
Completer<List<T>> completer = new Completer<List<T>>();
List<T> received = [];
stream.listen((T event) {
received.add(event);
}, onDone: () {
completer.complete(received);
});
return completer.future;
}
void check<T>(Stream<T> s) {
Map<Key<T>, int> equalsLog = new Map<Key<T>, int>();
bool equals(T p, T n) {
Key<T> key = new Key<T>(p, n);
equalsLog[key] = 1 + equalsLog.putIfAbsent(key, () => 0);
return p == n;
}
asyncStart();
Stream<T> d = s.asBroadcastStream().distinct(equals);
Future.wait([subscribe(d), subscribe(d), subscribe(d)])
.then((List<List<T>> result) {
result.forEach((received) => Expect.listEquals(result[0], received));
equalsLog.values.forEach((v) => Expect.equals(3, v));
asyncEnd();
});
}
void test(CreateStreamFunction create) {
check(create([]));
check(create([1, 2, 4, 3]));
check(create([1, 2, 2, 3]));
check(create(["a", "b", null, null]));
}