blob: 0bbe44b7f700e48d42426c1c1ee62fe7cbf08b85 [file] [log] [blame]
// Copyright (c) 2013, 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.
import 'dart:convert';
import 'package:expect/expect.dart';
// This test implements a new special interface that can be used to
// send data more efficiently between two converters.
abstract class MyChunkedIntSink extends ChunkedConversionSink<int> {
MyChunkedIntSink();
factory MyChunkedIntSink.from(sink) = IntAdapterSink;
factory MyChunkedIntSink.withCallback(callback) {
var sink = new ChunkedConversionSink.withCallback(callback);
return new MyChunkedIntSink.from(sink);
}
add(int i);
close();
// The special method.
specialI(i);
}
class IntAdapterSink extends MyChunkedIntSink {
final _sink;
IntAdapterSink(this._sink);
add(o) => _sink.add(o);
close() => _sink.close();
specialI(o) => add(o);
}
abstract class MyChunkedBoolSink extends ChunkedConversionSink<bool> {
MyChunkedBoolSink();
factory MyChunkedBoolSink.from(sink) = BoolAdapterSink;
factory MyChunkedBoolSink.withCallback(callback) {
var sink = new ChunkedConversionSink.withCallback(callback);
return new MyChunkedBoolSink.from(sink);
}
add(bool b);
close();
specialB(bool b);
}
class BoolAdapterSink extends MyChunkedBoolSink {
final _sink;
BoolAdapterSink(this._sink);
add(o) => _sink.add(o);
close() => _sink.close();
specialB(o) => add(o);
}
class IntBoolConverter1 extends Converter<List<int>, List<bool>> {
List<bool> convert(List<int> input) => input.map((x) => x > 0).toList();
startChunkedConversion(sink) {
if (sink is! MyChunkedBoolSink) sink = new MyChunkedBoolSink.from(sink);
return new IntBoolConverter1Sink(sink);
}
}
class BoolIntConverter1 extends Converter<List<bool>, List<int>> {
List<int> convert(List<bool> input) => input.map((x) => x ? 1 : 0).toList();
startChunkedConversion(sink) {
if (sink is! MyChunkedIntSink) sink = new MyChunkedIntSink.from(sink);
return new BoolIntConverter1Sink(sink);
}
}
int specialICounter = 0;
int specialBCounter = 0;
class IntBoolConverter1Sink extends MyChunkedIntSink {
var outSink;
IntBoolConverter1Sink(this.outSink);
add(int i) {
outSink.specialB(i > 0);
}
specialI(int i) {
specialICounter++;
add(i);
}
close() => outSink.close();
}
class BoolIntConverter1Sink extends MyChunkedBoolSink {
var outSink;
BoolIntConverter1Sink(this.outSink);
add(bool b) {
outSink.specialI(b ? 1 : 0);
}
specialB(bool b) {
specialBCounter++;
add(b);
}
close() => outSink.close();
}
class IdentityConverter extends Converter {
convert(x) => x;
startChunkedConversion(sink) {
return new IdentitySink(sink);
}
}
class IdentitySink extends ChunkedConversionSink {
final _sink;
IdentitySink(this._sink);
add(o) => _sink.add(o);
close() => _sink.close();
}
main() {
var converter1, converter2, intSink, intSink2, hasExecuted, boolSink, fused;
var converter3, fused2, sink, sink2;
// Test int->bool converter individually.
converter1 = new IntBoolConverter1();
Expect.listEquals([true, false, true], converter1.convert([2, -2, 2]));
hasExecuted = false;
boolSink = new MyChunkedBoolSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([true, false, true], value);
});
intSink = converter1.startChunkedConversion(boolSink);
intSink.add(3);
intSink.specialI(-3);
intSink.add(3);
intSink.close();
Expect.isTrue(hasExecuted);
Expect.equals(1, specialICounter);
specialICounter = 0;
hasExecuted = false;
// Test bool->int converter individually.
converter2 = new BoolIntConverter1();
Expect.listEquals([1, 0, 1], converter2.convert([true, false, true]));
hasExecuted = false;
intSink = new MyChunkedIntSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 0, 1], value);
});
boolSink = converter2.startChunkedConversion(intSink);
boolSink.specialB(true);
boolSink.add(false);
boolSink.add(true);
boolSink.close();
Expect.isTrue(hasExecuted);
Expect.equals(1, specialBCounter);
specialBCounter = 0;
hasExecuted = false;
// Test identity converter indidivually.
converter3 = new IdentityConverter();
hasExecuted = false;
sink = new ChunkedConversionSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 2, 3], value);
});
sink2 = converter3.startChunkedConversion(sink);
[1, 2, 3].forEach(sink2.add);
sink2.close();
Expect.isTrue(hasExecuted);
hasExecuted = false;
// Test fused converters.
fused = converter1.fuse(converter2);
Expect.listEquals([1, 0, 1], fused.convert([2, -2, 2]));
hasExecuted = false;
intSink2 = new MyChunkedIntSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 0, 1], value);
});
intSink = fused.startChunkedConversion(intSink2);
intSink.specialI(3);
intSink.add(-3);
intSink.add(3);
intSink.close();
Expect.isTrue(hasExecuted);
Expect.equals(3, specialBCounter);
specialBCounter = 0;
Expect.equals(1, specialICounter);
specialICounter = 0;
hasExecuted = false;
// With identity in front.
fused2 = converter3.fuse(fused);
hasExecuted = false;
intSink2 = new MyChunkedIntSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 0, 1], value);
});
sink = fused2.startChunkedConversion(intSink2);
Expect.isFalse(sink is MyChunkedIntSink);
sink.add(3);
sink.add(-3);
sink.add(3);
sink.close();
Expect.isTrue(hasExecuted);
Expect.equals(3, specialBCounter);
specialBCounter = 0;
Expect.equals(0, specialICounter);
specialICounter = 0;
hasExecuted = false;
// With identity at the end.
fused2 = fused.fuse(converter3);
hasExecuted = false;
sink = new ChunkedConversionSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 0, 1], value);
});
intSink = fused2.startChunkedConversion(sink);
Expect.isTrue(intSink is MyChunkedIntSink);
intSink.specialI(3);
intSink.add(-3);
intSink.specialI(3);
intSink.close();
Expect.isTrue(hasExecuted);
Expect.equals(3, specialBCounter);
specialBCounter = 0;
Expect.equals(2, specialICounter);
specialICounter = 0;
hasExecuted = false;
// With identity between the two converters.
fused = converter1.fuse(converter3).fuse(converter2);
Expect.listEquals([1, 0, 1], fused.convert([2, -2, 2]));
hasExecuted = false;
intSink2 = new MyChunkedIntSink.withCallback((value) {
hasExecuted = true;
Expect.listEquals([1, 0, 1], value);
});
intSink = fused.startChunkedConversion(intSink2);
intSink.specialI(3);
intSink.add(-3);
intSink.add(3);
intSink.close();
Expect.isTrue(hasExecuted);
Expect.equals(0, specialBCounter);
specialBCounter = 0;
Expect.equals(1, specialICounter);
specialICounter = 0;
hasExecuted = false;
}