mocks_for_image_cache.dart 4.53 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:ui' as ui show Image;

8
import 'package:flutter/foundation.dart';
9
import 'package:flutter/painting.dart';
10 11

class TestImageInfo implements ImageInfo {
12
  const TestImageInfo(this.value, { required this.image, this.scale = 1.0, this.debugLabel });
13 14

  @override
15
  final ui.Image image;
16 17

  @override
18
  final double scale;
19

20
  @override
21
  final String? debugLabel;
22

23 24 25
  final int value;

  @override
Ian Hickson's avatar
Ian Hickson committed
26
  String toString() => '${objectRuntimeType(this, 'TestImageInfo')}($value)';
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

  @override
  TestImageInfo clone() {
    return TestImageInfo(value, image: image.clone(), scale: scale, debugLabel: debugLabel);
  }

  @override
  bool isCloneOf(ImageInfo other) {
    assert(other != null);
    return other.image.isCloneOf(image)
        && scale == scale
        && other.debugLabel == debugLabel;
  }

  @override
  void dispose() {
    image.dispose();
  }

46 47 48
  @override
  int get sizeBytes => image.height * image.width * 4;

49 50 51 52 53 54 55 56 57 58 59 60 61 62
  @override
  int get hashCode => hashValues(value, image, scale, debugLabel);

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is TestImageInfo
        && other.value == value
        && other.image.isCloneOf(image)
        && other.scale == scale
        && other.debugLabel == debugLabel;

  }
63 64
}

65
class TestImageProvider extends ImageProvider<int> {
66
  const TestImageProvider(this.key, this.imageValue, { required this.image })
67 68
      : assert(image != null);

69
  final int key;
70
  final int imageValue;
71
  final ui.Image image;
72 73

  @override
74
  Future<int> obtainKey(ImageConfiguration configuration) {
75
    return Future<int>.value(key);
76 77 78
  }

  @override
79
  ImageStreamCompleter load(int key, DecoderCallback decode) {
80
    return OneFrameImageStreamCompleter(
81
      SynchronousFuture<ImageInfo>(TestImageInfo(imageValue, image: image.clone())),
82
    );
83 84 85
  }

  @override
Ian Hickson's avatar
Ian Hickson committed
86
  String toString() => '${objectRuntimeType(this, 'TestImageProvider')}($key, $imageValue)';
87
}
88

89
class FailingTestImageProvider extends TestImageProvider {
90
  const FailingTestImageProvider(int key, int imageValue, { required ui.Image image }) : super(key, imageValue, image: image);
91 92

  @override
93
  ImageStreamCompleter load(int key, DecoderCallback decode) {
94 95 96 97
    return OneFrameImageStreamCompleter(Future<ImageInfo>.sync(() => Future<ImageInfo>.error('loading failed!')));
  }
}

98
Future<ImageInfo> extractOneFrame(ImageStream stream) {
99
  final Completer<ImageInfo> completer = Completer<ImageInfo>();
100
  late ImageStreamListener listener;
101
  listener = ImageStreamListener((ImageInfo image, bool synchronousCall) {
102 103
    completer.complete(image);
    stream.removeListener(listener);
104
  });
105 106
  stream.addListener(listener);
  return completer.future;
107
}
108

109 110
class ErrorImageProvider extends ImageProvider<ErrorImageProvider> {
  @override
111
  ImageStreamCompleter load(ErrorImageProvider key, DecoderCallback decode) {
112 113 114 115 116 117 118 119
    throw Error();
  }

  @override
  Future<ErrorImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<ErrorImageProvider>(this);
  }
}
120

121 122
class ObtainKeyErrorImageProvider extends ImageProvider<ObtainKeyErrorImageProvider> {
  @override
123
  ImageStreamCompleter load(ObtainKeyErrorImageProvider key, DecoderCallback decode) {
124 125 126 127 128 129 130 131 132
    throw Error();
  }

  @override
  Future<ObtainKeyErrorImageProvider> obtainKey(ImageConfiguration configuration) {
    throw Error();
  }
}

133 134
class LoadErrorImageProvider extends ImageProvider<LoadErrorImageProvider> {
  @override
135
  ImageStreamCompleter load(LoadErrorImageProvider key, DecoderCallback decode) {
136 137 138
    throw Error();
  }

139
  @override
140 141 142 143 144
  Future<LoadErrorImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<LoadErrorImageProvider>(this);
  }
}

145
class LoadErrorCompleterImageProvider extends ImageProvider<LoadErrorCompleterImageProvider> {
146
  @override
147
  ImageStreamCompleter load(LoadErrorCompleterImageProvider key, DecoderCallback decode) {
148
    final Completer<ImageInfo> completer = Completer<ImageInfo>.sync();
149 150
    completer.completeError(Error());
    return OneFrameImageStreamCompleter(completer.future);
151 152
  }

153
  @override
154 155 156 157 158
  Future<LoadErrorCompleterImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<LoadErrorCompleterImageProvider>(this);
  }
}

159
class TestImageStreamCompleter extends ImageStreamCompleter {
160
  void testSetImage(ui.Image image) {
161 162 163
    setImage(ImageInfo(image: image, scale: 1.0));
  }
}