Files
sdk/tests/corelib/queue_test.dart
T
lrn@google.com 554a845e4f Make List.remove return boolean.
Remove Queue implementations' remove methods, which are not in the
interface.
Added more tests for list operations.
Fixed bugs and omissions found by tests.

http://dartbug.com/10042
http://dartbug.com/10112

Review URL: https://codereview.chromium.org//14425003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@21867 260f80e4-7a28-3924-810f-c04153c831b5
2013-04-23 11:13:17 +00:00

410 lines
9.8 KiB
Dart

// 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.
library queue.test;
import "package:expect/expect.dart";
import 'dart:collection';
abstract class QueueTest {
Queue newQueue();
Queue newQueueFrom(Iterable iterable);
void testMain() {
Queue queue = newQueue();
checkQueue(queue, 0, 0);
queue.addFirst(1);
checkQueue(queue, 1, 1);
queue.addLast(10);
checkQueue(queue, 2, 11);
Expect.equals(10, queue.removeLast());
checkQueue(queue, 1, 1);
queue.addLast(10);
Expect.equals(1, queue.removeFirst());
checkQueue(queue, 1, 10);
queue.addFirst(1);
queue.addLast(100);
queue.addLast(1000);
Expect.equals(1000, queue.removeLast());
queue.addLast(1000);
checkQueue(queue, 4, 1111);
queue.removeFirst();
checkQueue(queue, 3, 1110);
int mapTest(int value) {
return value ~/ 10;
}
bool is10(int value) {
return (value == 10);
}
Queue mapped = newQueueFrom(queue.map(mapTest));
checkQueue(mapped, 3, 111);
checkQueue(queue, 3, 1110);
Expect.equals(1, mapped.removeFirst());
Expect.equals(100, mapped.removeLast());
Expect.equals(10, mapped.removeFirst());
Queue other = newQueueFrom(queue.where(is10));
checkQueue(other, 1, 10);
Expect.equals(true, queue.any(is10));
bool isInstanceOfInt(int value) {
return (value is int);
}
Expect.equals(true, queue.every(isInstanceOfInt));
Expect.equals(false, queue.every(is10));
bool is1(int value) {
return (value == 1);
}
Expect.equals(false, queue.any(is1));
queue.clear();
Expect.equals(0, queue.length);
var exception = null;
try {
queue.removeFirst();
} on StateError catch (e) {
exception = e;
}
Expect.equals(true, exception != null);
Expect.equals(0, queue.length);
exception = null;
try {
queue.removeLast();
} on StateError catch (e) {
exception = e;
}
Expect.equals(true, exception != null);
Expect.equals(0, queue.length);
queue.addFirst(1);
queue.addFirst(2);
Expect.equals(2, queue.first);
Expect.equals(1, queue.last);
queue.addLast(3);
Expect.equals(3, queue.last);
bool isGreaterThanOne(int value) {
return (value > 1);
}
other = newQueueFrom(queue.where(isGreaterThanOne));
checkQueue(other, 2, 5);
// Cycle through values without ever having large element count.
queue = newQueue();
queue.add(0);
for (int i = 0; i < 255; i++) {
queue.add(i + 1);
Expect.equals(i, queue.removeFirst());
}
Expect.equals(255, queue.removeFirst());
Expect.isTrue(queue.isEmpty);
testAddAll();
testLengthChanges();
testLarge();
testFromListToList();
}
void checkQueue(Queue queue, int expectedSize, int expectedSum) {
Expect.equals(expectedSize, queue.length);
int sum = 0;
void sumElements(int value) {
sum += value;
}
queue.forEach(sumElements);
Expect.equals(expectedSum, sum);
}
testLength(int length, Queue queue) {
Expect.equals(length, queue.length);
((length == 0) ? Expect.isTrue : Expect.isFalse)(queue.isEmpty);
}
void testAddAll() {
Set<int> set = new Set<int>.from([1, 2, 4]);
Expect.equals(3, set.length);
Queue queue1 = newQueueFrom(set);
Queue queue2 = newQueue();
Queue queue3 = newQueue();
testLength(3, queue1);
testLength(0, queue2);
testLength(0, queue3);
queue2.addAll(set);
testLength(3, queue2);
queue3.addAll(queue1);
testLength(3, queue3);
int sum = 0;
void f(e) { sum += e; };
set.forEach(f);
Expect.equals(7, sum);
sum = 0;
queue1.forEach(f);
Expect.equals(7, sum);
sum = 0;
queue2.forEach(f);
Expect.equals(7, sum);
sum = 0;
queue3.forEach(f);
Expect.equals(7, sum);
sum = 0;
set = new Set<int>.from([]);
queue1 = newQueueFrom(set);
queue2 = newQueue();
queue3 = newQueue();
queue2.addAll(set);
queue3.addAll(queue1);
Expect.equals(0, set.length);
Expect.equals(0, queue1.length);
Expect.equals(0, queue2.length);
Expect.equals(0, queue3.length);
}
void testLengthChanges() {
// Test that the length property is updated properly by
// modifications;
Queue queue = newQueue();
testLength(0, queue);
for (int i = 1; i <= 10; i++) {
queue.add(i);
testLength(i, queue);
}
for (int i = 1; i <= 10; i++) {
queue.addFirst(11 - i);
testLength(10 + i, queue);
}
for (int i = 1; i <= 10; i++) {
queue.addLast(i);
testLength(20 + i, queue);
}
queue.addAll([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
testLength(40, queue);
for (int i = 1; i <= 5; i++) {
Expect.equals(i, queue.removeFirst());
testLength(40 - i, queue);
}
for (int i = 1; i <= 5; i++) {
Expect.equals(11 - i, queue.removeLast());
testLength(35 - i, queue);
}
Expect.isTrue(queue.remove(10));
testLength(29, queue);
Expect.isFalse(queue.remove(999));
testLength(29, queue);
queue.removeWhere((x) => x == 7);
testLength(26, queue);
queue.retainWhere((x) => x != 3);
testLength(23, queue);
Expect.listEquals(
[6, 8, 9, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5],
queue.toList());
}
void testLarge() {
int N = 10000;
Set set = new Set();
Queue queue = newQueue();
Expect.isTrue(queue.isEmpty);
for (int i = 0; i < N; i++) {
queue.add(i);
set.add(i);
}
Expect.equals(N, queue.length);
Expect.isFalse(queue.isEmpty);
Iterable skip1 = queue.skip(1);
Iterable take1 = queue.take(1);
Iterable mapped = queue.map((e) => -e);
for (int i = 0; i < 500; i++) {
Expect.equals(i, take1.first);
Expect.equals(i, queue.first);
Expect.equals(-i, mapped.first);
Expect.equals(i + 1, skip1.first);
Expect.equals(i, queue.removeFirst());
Expect.equals(i + 1, take1.first);
Expect.equals(-i - 1, mapped.first);
Expect.equals(N - 1 - i, queue.last);
Expect.equals(N - 1 - i, queue.removeLast());
}
Expect.equals(N - 1000, queue.length);
Expect.isTrue(queue.remove(N >> 1));
Expect.equals(N - 1001, queue.length);
queue.clear();
Expect.equals(0, queue.length);
Expect.isTrue(queue.isEmpty);
queue.addAll(set);
Expect.equals(N, queue.length);
Expect.isFalse(queue.isEmpty);
// Iterate.
for (var element in queue) {
Expect.isTrue(set.contains(element));
}
queue.forEach((element) { Expect.isTrue(set.contains(element)); });
queue.addAll(set);
Expect.equals(N * 2, queue.length);
Expect.isFalse(queue.isEmpty);
queue.clear();
Expect.equals(0, queue.length);
Expect.isTrue(queue.isEmpty);
}
void testFromListToList() {
const int N = 256;
List list = [];
for (int i = 0; i < N; i++) {
Queue queue = newQueueFrom(list);
Expect.equals(list.length, queue.length);
List to = queue.toList();
Expect.listEquals(list, to);
queue.add(i);
list.add(i);
Expect.equals(list.length, queue.length);
to = queue.toList();
Expect.listEquals(list, to);
}
}
}
class ListQueueTest extends QueueTest {
Queue newQueue() => new ListQueue();
Queue newQueueFrom(Iterable elements) => new ListQueue.from(elements);
void testMain() {
super.testMain();
trickyTest();
}
void trickyTest() {
// Test behavior around the know growing capacities of a ListQueue.
Queue q = new ListQueue();
for (int i = 0; i < 255; i++) {
q.add(i);
}
for (int i = 0; i < 128; i++) {
Expect.equals(i, q.removeFirst());
}
q.add(255);
for (int i = 0; i < 127; i++) {
q.add(i);
}
Expect.equals(255, q.length);
// Remove element at end of internal buffer.
q.removeWhere((v) => v == 255);
// Remove element at beginning of internal buffer.
q.removeWhere((v) => v == 0);
// Remove element at both ends of internal buffer.
q.removeWhere((v) => v == 254 || v == 1);
Expect.equals(251, q.length);
Iterable i255 = new Iterable.generate(255, (x) => x);
q = new ListQueue();
q.addAll(i255);
Expect.listEquals(i255.toList(), q.toList());
q = new ListQueue();
q.addAll(i255.toList());
Expect.listEquals(i255.toList(), q.toList());
q = new ListQueue.from(i255);
for (int i = 0; i < 128; i++) q.removeFirst();
q.add(256);
q.add(0);
q.addAll(i255.toList());
Expect.equals(129 + 255, q.length);
// Test addAll that requires the queue to grow.
q = new ListQueue();
q.addAll(i255.take(35));
q.addAll(i255.skip(35).take(96));
q.addAll(i255.skip(35 + 96));
Expect.listEquals(i255.toList(), q.toList());
}
}
class DoubleLinkedQueueTest extends QueueTest {
Queue newQueue() => new DoubleLinkedQueue();
Queue newQueueFrom(Iterable elements) => new DoubleLinkedQueue.from(elements);
void testMain() {
super.testMain();
testQueueElements();
}
void testQueueElements() {
DoubleLinkedQueue<int> queue1 = new DoubleLinkedQueue<int>.from([1, 2, 4]);
DoubleLinkedQueue<int> queue2 = new DoubleLinkedQueue<int>();
queue2.addAll(queue1);
Expect.equals(queue1.length, queue2.length);
DoubleLinkedQueueEntry<int> entry1 = queue1.firstEntry();
DoubleLinkedQueueEntry<int> entry2 = queue2.firstEntry();
while (entry1 != null) {
Expect.equals(true, !identical(entry1, entry2));
entry1 = entry1.nextEntry();
entry2 = entry2.nextEntry();
}
Expect.equals(null, entry2);
}
}
main() {
new DoubleLinkedQueueTest().testMain();
new ListQueueTest().testMain();
}