Fix tests

This commit is contained in:
Greg Spencer
2018-07-13 19:04:58 -07:00
parent bef65c610d
commit f0e5a21883
2 changed files with 77 additions and 62 deletions

View File

@ -102,6 +102,16 @@ class PaletteGenerator extends Diagnosticable {
}) async { }) async {
assert(image != null); assert(image != null);
assert(region == null || region != Rect.zero); assert(region == null || region != Rect.zero);
assert(
region == null ||
(region.topLeft.dx >= 0.0 && region.topLeft.dy >= 0.0),
'Region $region is outside the image ${image.width}x${image.height}');
assert(
region == null ||
(region.bottomRight.dx <= image.width &&
region.bottomRight.dy <= image.height),
'Region $region is outside the image ${image.width}x${image.height}');
filters ??= <PaletteFilter>[avoidRedBlackWhitePaletteFilter]; filters ??= <PaletteFilter>[avoidRedBlackWhitePaletteFilter];
maximumColorCount ??= _defaultCalculateNumberColors; maximumColorCount ??= _defaultCalculateNumberColors;
final _ColorCutQuantizer quantizer = new _ColorCutQuantizer( final _ColorCutQuantizer quantizer = new _ColorCutQuantizer(
@ -110,8 +120,9 @@ class PaletteGenerator extends Diagnosticable {
filters: filters, filters: filters,
region: region, region: region,
); );
final List<PaletteColor> colors = await quantizer.quantizedColors;
return new PaletteGenerator.fromColors( return new PaletteGenerator.fromColors(
await quantizer.quantizedColors, colors,
targets: targets, targets: targets,
); );
} }
@ -154,7 +165,12 @@ class PaletteGenerator extends Diagnosticable {
}) async { }) async {
assert(imageProvider != null); assert(imageProvider != null);
assert(timeout != null); assert(timeout != null);
assert(region == null || (region != null && size != null));
assert(region == null || region != Rect.zero); assert(region == null || region != Rect.zero);
assert(
region == null ||
(region.topLeft.dx >= 0.0 && region.topLeft.dy >= 0.0),
'Region $region is outside the image ${size.width}x${size.height}');
assert(region == null || size.contains(region.topLeft), assert(region == null || size.contains(region.topLeft),
'Region $region is outside the image $size'); 'Region $region is outside the image $size');
assert( assert(
@ -1002,23 +1018,25 @@ class _ColorVolumeBox {
class _ColorCutQuantizer { class _ColorCutQuantizer {
_ColorCutQuantizer( _ColorCutQuantizer(
ui.Image image, { this.image, {
this.maxColors = PaletteGenerator._defaultCalculateNumberColors, this.maxColors = PaletteGenerator._defaultCalculateNumberColors,
this.region, this.region,
this.filters, this.filters,
}) : assert(image != null), }) : assert(image != null),
assert(maxColors != null), assert(maxColors != null),
assert(region == null || region != Rect.zero) { assert(region == null || region != Rect.zero),
_quantizeColors(image); _paletteColors = <PaletteColor>[];
FutureOr<List<PaletteColor>> get quantizedColors async {
if (_paletteColors.isNotEmpty) {
return _paletteColors;
} else {
return _quantizeColors(image);
}
} }
Future<List<PaletteColor>> get quantizedColors async { final ui.Image image;
return _completer.future; final List<PaletteColor> _paletteColors;
}
List<PaletteColor> _paletteColors;
final Completer<List<PaletteColor>> _completer =
new Completer<List<PaletteColor>>();
final int maxColors; final int maxColors;
final Rect region; final Rect region;
@ -1111,15 +1129,15 @@ class _ColorCutQuantizer {
if (hist.length <= maxColors) { if (hist.length <= maxColors) {
// The image has fewer colors than the maximum requested, so just return // The image has fewer colors than the maximum requested, so just return
// the colors. // the colors.
_paletteColors = <PaletteColor>[]; _paletteColors.clear();
for (Color color in hist.keys) { for (Color color in hist.keys) {
_paletteColors.add(new PaletteColor(color, hist[color])); _paletteColors.add(new PaletteColor(color, hist[color]));
} }
} else { } else {
// We need use quantization to reduce the number of colors // We need use quantization to reduce the number of colors
_paletteColors = _quantizePixels(maxColors, hist); _paletteColors.clear();
_paletteColors.addAll(_quantizePixels(maxColors, hist));
} }
_completer.complete(_paletteColors);
return _paletteColors; return _paletteColors;
} }

View File

@ -5,8 +5,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui import 'dart:ui' as ui show Image, Codec, FrameInfo, instantiateImageCodec;
show Image, Codec, FrameInfo, instantiateImageCodec, ImageByteFormat;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -66,32 +65,32 @@ void main() async {
testImages[name] = await loadImage('$name.png'); testImages[name] = await loadImage('$name.png');
} }
testWidgets('PaletteGenerator works on 1-pixel wide blue image', testWidgets('Initialize the image cache', (WidgetTester tester) {
(WidgetTester tester) async { // We need to have a testWidgets test in order to initialize the image
tester.pump(); // cache for the other tests, but they timeout if they too are testWidgets
final ImageProvider image = testImages['tall_blue']; // tests.
tester.pumpWidget(const Placeholder());
});
test('PaletteGenerator works on 1-pixel wide blue image', () async {
final PaletteGenerator palette = final PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(testImages['tall_blue']);
expect(palette.paletteColors.length, equals(1)); expect(palette.paletteColors.length, equals(1));
expect(palette.paletteColors[0].color, expect(palette.paletteColors[0].color,
within<Color>(distance: 8, from: const Color(0xff0000ff))); within<Color>(distance: 8, from: const Color(0xff0000ff)));
}); });
testWidgets('PaletteGenerator works on 1-pixel high red image', test('PaletteGenerator works on 1-pixel high red image', () async {
(WidgetTester tester) async {
final ImageProvider image = testImages['wide_red'];
final PaletteGenerator palette = final PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(testImages['wide_red']);
expect(palette.paletteColors.length, equals(1)); expect(palette.paletteColors.length, equals(1));
expect(palette.paletteColors[0].color, expect(palette.paletteColors[0].color,
within<Color>(distance: 8, from: const Color(0xffff0000))); within<Color>(distance: 8, from: const Color(0xffff0000)));
}); });
testWidgets('PaletteGenerator finds dominant color and text colors', test('PaletteGenerator finds dominant color and text colors', () async {
(WidgetTester tester) async {
final ImageProvider image = testImages['dominant'];
final PaletteGenerator palette = final PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(testImages['dominant']);
expect(palette.paletteColors.length, equals(3)); expect(palette.paletteColors.length, equals(3));
expect(palette.dominantColor.color, expect(palette.dominantColor.color,
within<Color>(distance: 8, from: const Color(0xff0000ff))); within<Color>(distance: 8, from: const Color(0xff0000ff)));
@ -101,34 +100,34 @@ void main() async {
within<Color>(distance: 8, from: const Color(0xda000000))); within<Color>(distance: 8, from: const Color(0xda000000)));
}); });
testWidgets('PaletteGenerator works with regions', test('PaletteGenerator works with regions', () async {
(WidgetTester tester) async { final ImageProvider imageProvider = testImages['dominant'];
final ImageProvider image = testImages['dominant'];
Rect region = new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0); Rect region = new Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
PaletteGenerator palette = const Size size = const Size(100.0, 100.0);
await PaletteGenerator.fromImageProvider(image, region: region); PaletteGenerator palette = await PaletteGenerator.fromImageProvider(imageProvider,
region: region, size: size);
expect(palette.paletteColors.length, equals(3)); expect(palette.paletteColors.length, equals(3));
expect(palette.dominantColor.color, expect(palette.dominantColor.color,
within<Color>(distance: 8, from: const Color(0xff0000ff))); within<Color>(distance: 8, from: const Color(0xff0000ff)));
region = new Rect.fromLTRB(0.0, 0.0, 10.0, 10.0); region = new Rect.fromLTRB(0.0, 0.0, 10.0, 10.0);
palette = await PaletteGenerator.fromImageProvider(image, region: region); palette = await PaletteGenerator.fromImageProvider(imageProvider,
region: region, size: size);
expect(palette.paletteColors.length, equals(1)); expect(palette.paletteColors.length, equals(1));
expect(palette.dominantColor.color, expect(palette.dominantColor.color,
within<Color>(distance: 8, from: const Color(0xffff0000))); within<Color>(distance: 8, from: const Color(0xffff0000)));
region = new Rect.fromLTRB(0.0, 0.0, 30.0, 20.0); region = new Rect.fromLTRB(0.0, 0.0, 30.0, 20.0);
palette = await PaletteGenerator.fromImageProvider(image, region: region); palette = await PaletteGenerator.fromImageProvider(imageProvider,
region: region, size: size);
expect(palette.paletteColors.length, equals(3)); expect(palette.paletteColors.length, equals(3));
expect(palette.dominantColor.color, expect(palette.dominantColor.color,
within<Color>(distance: 8, from: const Color(0xff00ff00))); within<Color>(distance: 8, from: const Color(0xff00ff00)));
}); });
testWidgets('PaletteGenerator works as expected on a real image', test('PaletteGenerator works as expected on a real image', () async {
(WidgetTester tester) async {
final ImageProvider image = testImages['landscape'];
final PaletteGenerator palette = final PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(testImages['landscape']);
final List<PaletteColor> expectedSwatches = <PaletteColor>[ final List<PaletteColor> expectedSwatches = <PaletteColor>[
new PaletteColor(const Color(0xff3f630c), 10137), new PaletteColor(const Color(0xff3f630c), 10137),
new PaletteColor(const Color(0xff3c4b2a), 4773), new PaletteColor(const Color(0xff3c4b2a), 4773),
@ -166,28 +165,27 @@ void main() async {
expect(palette.colors.length, equals(palette.paletteColors.length)); expect(palette.colors.length, equals(palette.paletteColors.length));
}); });
testWidgets('PaletteGenerator limits max colors', test('PaletteGenerator limits max colors', () async {
(WidgetTester tester) async { final ImageProvider imageProvider = testImages['landscape'];
final ImageProvider image = testImages['landscape'];
PaletteGenerator palette = PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image, maximumColorCount: 32); await PaletteGenerator.fromImageProvider(imageProvider, maximumColorCount: 32);
expect(palette.paletteColors.length, equals(31)); expect(palette.paletteColors.length, equals(31));
palette = palette =
await PaletteGenerator.fromImageProvider(image, maximumColorCount: 1); await PaletteGenerator.fromImageProvider(imageProvider, maximumColorCount: 1);
expect(palette.paletteColors.length, equals(1)); expect(palette.paletteColors.length, equals(1));
palette = palette =
await PaletteGenerator.fromImageProvider(image, maximumColorCount: 15); await PaletteGenerator.fromImageProvider(imageProvider, maximumColorCount: 15);
expect(palette.paletteColors.length, equals(15)); expect(palette.paletteColors.length, equals(15));
}); });
testWidgets('PaletteGenerator Filters work', (WidgetTester tester) async { test('PaletteGenerator Filters work', () async {
final ImageProvider image = testImages['landscape']; final ImageProvider imageProvider = testImages['landscape'];
// First, test that supplying the default filter is the same as not supplying one. // First, test that supplying the default filter is the same as not supplying one.
List<PaletteFilter> filters = <PaletteFilter>[ List<PaletteFilter> filters = <PaletteFilter>[
avoidRedBlackWhitePaletteFilter avoidRedBlackWhitePaletteFilter
]; ];
PaletteGenerator palette = PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image, filters: filters); await PaletteGenerator.fromImageProvider(imageProvider, filters: filters);
final List<PaletteColor> expectedSwatches = <PaletteColor>[ final List<PaletteColor> expectedSwatches = <PaletteColor>[
new PaletteColor(const Color(0xff3f630c), 10137), new PaletteColor(const Color(0xff3f630c), 10137),
new PaletteColor(const Color(0xff3c4b2a), 4773), new PaletteColor(const Color(0xff3c4b2a), 4773),
@ -215,7 +213,7 @@ void main() async {
// A non-default filter works (and the default filter isn't applied too). // A non-default filter works (and the default filter isn't applied too).
filters = <PaletteFilter>[onlyBluePaletteFilter]; filters = <PaletteFilter>[onlyBluePaletteFilter];
palette = await PaletteGenerator.fromImageProvider(image, filters: filters); palette = await PaletteGenerator.fromImageProvider(imageProvider, filters: filters);
final List<PaletteColor> blueSwatches = <PaletteColor>[ final List<PaletteColor> blueSwatches = <PaletteColor>[
new PaletteColor(const Color(0xff4c5c75), 1515), new PaletteColor(const Color(0xff4c5c75), 1515),
new PaletteColor(const Color(0xff7483a1), 1505), new PaletteColor(const Color(0xff7483a1), 1505),
@ -244,7 +242,7 @@ void main() async {
// More than one filter is the intersection of the two filters. // More than one filter is the intersection of the two filters.
filters = <PaletteFilter>[onlyBluePaletteFilter, onlyCyanPaletteFilter]; filters = <PaletteFilter>[onlyBluePaletteFilter, onlyCyanPaletteFilter];
palette = await PaletteGenerator.fromImageProvider(image, filters: filters); palette = await PaletteGenerator.fromImageProvider(imageProvider, filters: filters);
final List<PaletteColor> blueGreenSwatches = <PaletteColor>[ final List<PaletteColor> blueGreenSwatches = <PaletteColor>[
new PaletteColor(const Color(0xffc8e8f8), 87), new PaletteColor(const Color(0xffc8e8f8), 87),
new PaletteColor(const Color(0xff5c6c74), 73), new PaletteColor(const Color(0xff5c6c74), 73),
@ -273,18 +271,18 @@ void main() async {
// Mutually exclusive filters return an empty palette. // Mutually exclusive filters return an empty palette.
filters = <PaletteFilter>[onlyBluePaletteFilter, onlyGreenPaletteFilter]; filters = <PaletteFilter>[onlyBluePaletteFilter, onlyGreenPaletteFilter];
palette = await PaletteGenerator.fromImageProvider(image, filters: filters); palette = await PaletteGenerator.fromImageProvider(imageProvider, filters: filters);
expect(palette.paletteColors, isEmpty); expect(palette.paletteColors, isEmpty);
expect(palette.dominantColor, isNull); expect(palette.dominantColor, isNull);
expect(palette.colors, isEmpty); expect(palette.colors, isEmpty);
}); });
testWidgets('PaletteGenerator targets work', (WidgetTester tester) async { test('PaletteGenerator targets work', () async {
final ImageProvider image = testImages['landscape']; final ImageProvider imageProvider = testImages['landscape'];
// Passing an empty set of targets works the same as passing a null targets // Passing an empty set of targets works the same as passing a null targets
// list. // list.
PaletteGenerator palette = await PaletteGenerator PaletteGenerator palette = await PaletteGenerator.fromImageProvider(imageProvider,
.fromImageProvider(image, targets: <PaletteTarget>[]); targets: <PaletteTarget>[]);
expect(palette.selectedSwatches, isNotEmpty); expect(palette.selectedSwatches, isNotEmpty);
expect(palette.vibrantColor, isNotNull); expect(palette.vibrantColor, isNotNull);
expect(palette.lightVibrantColor, isNotNull); expect(palette.lightVibrantColor, isNotNull);
@ -298,7 +296,7 @@ void main() async {
new PaletteTarget(minimumSaturation: 0.85), new PaletteTarget(minimumSaturation: 0.85),
new PaletteTarget(maximumSaturation: .25), new PaletteTarget(maximumSaturation: .25),
]; ];
palette = await PaletteGenerator.fromImageProvider(image, palette = await PaletteGenerator.fromImageProvider(imageProvider,
targets: saturationExtremeTargets); targets: saturationExtremeTargets);
expect(palette.vibrantColor, isNotNull); expect(palette.vibrantColor, isNotNull);
expect(palette.lightVibrantColor, isNotNull); expect(palette.lightVibrantColor, isNotNull);
@ -314,15 +312,14 @@ void main() async {
equals(const Color(0xff6e80a2))); equals(const Color(0xff6e80a2)));
}); });
testWidgets('PaletteGenerator produces consistent results', test('PaletteGenerator produces consistent results', () async {
(WidgetTester tester) async { final ImageProvider imageProvider = testImages['landscape'];
final ImageProvider image = testImages['landscape'];
PaletteGenerator lastPalette = PaletteGenerator lastPalette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(imageProvider);
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
final PaletteGenerator palette = final PaletteGenerator palette =
await PaletteGenerator.fromImageProvider(image); await PaletteGenerator.fromImageProvider(imageProvider);
expect(palette.paletteColors.length, lastPalette.paletteColors.length); expect(palette.paletteColors.length, lastPalette.paletteColors.length);
expect(palette.vibrantColor, equals(lastPalette.vibrantColor)); expect(palette.vibrantColor, equals(lastPalette.vibrantColor));
expect(palette.lightVibrantColor, equals(lastPalette.lightVibrantColor)); expect(palette.lightVibrantColor, equals(lastPalette.lightVibrantColor));