Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement save and restore functions on mock canvas so their effects can be tested #3

Merged
merged 1 commit into from
Nov 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 13 additions & 8 deletions lib/src/canvas_commands/transform_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,31 @@ import 'command.dart';
/// `canvas.translate()`, `canvas.rotate()`, `canvas.scale()`, or
/// `canvas.transform()`.
class TransformCommand extends CanvasCommand {
TransformCommand() : _transform = Matrix4.identity();
final Matrix4 matrix;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a public transform conflicts with the method name so I changed to matrix


final Matrix4 _transform;
TransformCommand() : matrix = Matrix4.identity();
TransformCommand.from(this.matrix);

void setFrom(Matrix4 matrix) {
this.matrix.setFrom(matrix);
}

void transform(Float64List matrix) {
_transform.multiply(Matrix4.fromFloat64List(matrix));
this.matrix.multiply(Matrix4.fromFloat64List(matrix));
}

void translate(double dx, double dy) => _transform.translate(dx, dy);
void rotate(double angle) => _transform.rotateZ(angle);
void scale(double sx, double sy) => _transform.scale(sx, sy, 1);
void translate(double dx, double dy) => matrix.translate(dx, dy);
void rotate(double angle) => matrix.rotateZ(angle);
void scale(double sx, double sy) => matrix.scale(sx, sy, 1);

@override
bool equals(TransformCommand other) {
return eq(_transform.storage, other._transform.storage);
return eq(matrix.storage, other.matrix.storage);
}

@override
String toString() {
final content = _transform.storage.map(repr).join(', ');
final content = matrix.storage.map(repr).join(', ');
return 'transform($content)';
}
}
36 changes: 29 additions & 7 deletions lib/src/mock_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:ui';

import 'package:flutter_test/flutter_test.dart';
import 'package:test/fake.dart';
import 'package:vector_math/vector_math_64.dart';

import 'assertion_mode.dart';
import 'canvas_commands/cliprect_command.dart';
Expand Down Expand Up @@ -50,11 +51,14 @@ import 'canvas_commands/transform_command.dart';
class MockCanvas extends Fake implements Canvas, Matcher {
MockCanvas({this.mode = AssertionMode.matchExactly})
: _commands = [],
_saveStack = [],
_saveCount = 0;

final AssertionMode mode;
final List<CanvasCommand> _commands;

int _saveCount;
final List<Matrix4> _saveStack;

/// The absolute tolerance used when comparing numeric quantities for
/// equality. Two numeric variables `x` and `y` are considered equal if they
Expand All @@ -78,7 +82,7 @@ class MockCanvas extends Fake implements Canvas, Matcher {

@override
Description describe(Description description) {
description.add('Canvas$_commands');
description.add('Canvas {\n${_commands.join('\n')}\n}');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just found that its much easier to read like this when there are a handful of commands

return description;
}

Expand All @@ -100,7 +104,7 @@ class MockCanvas extends Fake implements Canvas, Matcher {
final n2 = other._commands.length;
if (n1 != n2) {
return _fail(
'Canvas contains $n1 commands, but $n2 expected',
'Canvas contains $n2 commands, but $n1 expected',
matchState,
);
}
Expand Down Expand Up @@ -146,8 +150,8 @@ class MockCanvas extends Fake implements Canvas, Matcher {
});
if (idx == -1) {
return _fail(
'Expected canvas command not found: $expectedCommand. '
'Actual commands: $_commands',
'Expected canvas command not found: $expectedCommand}. '
'Actual commands:\n${_commands.join('\n')}',
matchState,
);
} else {
Expand Down Expand Up @@ -221,17 +225,35 @@ class MockCanvas extends Fake implements Canvas, Matcher {
int getSaveCount() => _saveCount;

@override
void restore() => _saveCount--;
void restore() {
_saveCount--;
final savedTransform = _saveStack.removeLast();
if (savedTransform == _currentTransform.matrix) {
return;
}
_lastTransform.setFrom(savedTransform);
}

@override
void save() => _saveCount++;
void save() {
_saveCount++;
_saveStack.add(_currentTransform.matrix.clone());
}

//#endregion

//#region Private helpers

TransformCommand get _currentTransform {
final transforms = _commands.whereType<TransformCommand>();
return transforms.isEmpty ? TransformCommand() : transforms.last;
}

bool get _isLastCommandTransform =>
_commands.isNotEmpty && _commands.last is TransformCommand;

TransformCommand get _lastTransform {
if (_commands.isNotEmpty && _commands.last is TransformCommand) {
if (_isLastCommandTransform) {
return _commands.last as TransformCommand;
}
final transform2d = TransformCommand();
Expand Down