Initial set of tests for flutter sprites (#3643)
* Initial set of tests for flutter sprites
This commit is contained in:
@@ -63,6 +63,12 @@ class SpriteBox extends RenderBox {
|
||||
_scheduleTick();
|
||||
}
|
||||
|
||||
@override
|
||||
void detach() {
|
||||
super.detach();
|
||||
_unscheduleTick();
|
||||
}
|
||||
|
||||
// Member variables
|
||||
|
||||
// Root node for drawing
|
||||
@@ -366,8 +372,14 @@ class SpriteBox extends RenderBox {
|
||||
|
||||
// Updates
|
||||
|
||||
int _frameCallbackId;
|
||||
|
||||
void _scheduleTick() {
|
||||
SchedulerBinding.instance.scheduleFrameCallback(_tick);
|
||||
_frameCallbackId = SchedulerBinding.instance.scheduleFrameCallback(_tick);
|
||||
}
|
||||
|
||||
void _unscheduleTick() {
|
||||
SchedulerBinding.instance.cancelFrameCallbackWithId(_frameCallbackId);
|
||||
}
|
||||
|
||||
void _tick(Duration timeStamp) {
|
||||
|
||||
213
packages/flutter_sprites/test/action_test.dart
Normal file
213
packages/flutter_sprites/test/action_test.dart
Normal file
@@ -0,0 +1,213 @@
|
||||
// Copyright 2015 The Chromium Authors. 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:ui';
|
||||
|
||||
import 'package:flutter_sprites/flutter_sprites.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
const double epsilon = 0.01;
|
||||
|
||||
void main() {
|
||||
test("Actions - ActionTween", () {
|
||||
// Tween doubles.
|
||||
double doubleValue;
|
||||
ActionTween tween = new ActionTween((double a) => doubleValue = a, 0.0, 10.0, 60.0);
|
||||
|
||||
tween.update(0.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
|
||||
tween.update(0.1);
|
||||
expect(doubleValue, closeTo(1.0, epsilon));
|
||||
|
||||
tween.update(0.5);
|
||||
expect(doubleValue, closeTo(5.0, epsilon));
|
||||
|
||||
tween.update(1.0);
|
||||
expect(doubleValue, closeTo(10.0, epsilon));
|
||||
|
||||
tween.update(1.5);
|
||||
expect(doubleValue, closeTo(15.0, epsilon));
|
||||
|
||||
tween.update(-0.5);
|
||||
expect(doubleValue, closeTo(-5.0, epsilon));
|
||||
|
||||
// Tween Points.
|
||||
Point pointValue;
|
||||
tween = new ActionTween((Point a) => pointValue = a, Point.origin, new Point(10.0, 20.0), 60.0);
|
||||
|
||||
tween.update(0.0);
|
||||
expect(pointValue.x, closeTo(0.0, epsilon));
|
||||
expect(pointValue.y, closeTo(0.0, epsilon));
|
||||
|
||||
tween.update(0.1);
|
||||
expect(pointValue.x, closeTo(1.0, epsilon));
|
||||
expect(pointValue.y, closeTo(2.0, epsilon));
|
||||
|
||||
tween.update(0.5);
|
||||
expect(pointValue.x, closeTo(5.0, epsilon));
|
||||
expect(pointValue.y, closeTo(10.0, epsilon));
|
||||
|
||||
tween.update(1.0);
|
||||
expect(pointValue.x, closeTo(10.0, epsilon));
|
||||
expect(pointValue.y, closeTo(20.0, epsilon));
|
||||
|
||||
tween.update(1.5);
|
||||
expect(pointValue.x, closeTo(15.0, epsilon));
|
||||
expect(pointValue.y, closeTo(30.0, epsilon));
|
||||
|
||||
tween.update(-0.5);
|
||||
expect(pointValue.x, closeTo(-5.0, epsilon));
|
||||
expect(pointValue.y, closeTo(-10.0, epsilon));
|
||||
|
||||
// Tween Colors.
|
||||
Color colorValue;
|
||||
tween = new ActionTween((Color a) => colorValue = a, const Color(0xff000000), const Color(0xffffffff), 60.0);
|
||||
|
||||
tween.update(0.0);
|
||||
expect(colorValue, equals(const Color(0xff000000)));
|
||||
|
||||
tween.update(0.5);
|
||||
expect(colorValue, equals(const Color(0xff7f7f7f)));
|
||||
|
||||
tween.update(1.0);
|
||||
expect(colorValue, equals(const Color(0xffffffff)));
|
||||
|
||||
tween.update(-0.5);
|
||||
expect(colorValue, equals(const Color(0xff000000)));
|
||||
|
||||
tween.update(1.5);
|
||||
expect(colorValue, equals(const Color(0xffffffff)));
|
||||
|
||||
// Tween Size.
|
||||
Size sizeValue;
|
||||
tween = new ActionTween((Size a) => sizeValue = a, Size.zero, const Size(200.0, 100.0), 60.0);
|
||||
|
||||
tween.update(0.0);
|
||||
expect(sizeValue, equals(Size.zero));
|
||||
|
||||
tween.update(1.0);
|
||||
expect(sizeValue, equals(const Size(200.0, 100.0)));
|
||||
|
||||
tween.update(0.5);
|
||||
expect(sizeValue.width, closeTo(100.0, epsilon));
|
||||
expect(sizeValue.height, closeTo(50.0, epsilon));
|
||||
|
||||
// Tween Rect.
|
||||
Rect rectValue;
|
||||
tween = new ActionTween(
|
||||
(Rect a) => rectValue = a,
|
||||
new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0),
|
||||
new Rect.fromLTWH(100.0, 100.0, 200.0, 200.0),
|
||||
60.0
|
||||
);
|
||||
|
||||
tween.update(0.0);
|
||||
expect(rectValue, equals(new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0)));
|
||||
|
||||
tween.update(1.0);
|
||||
expect(rectValue, equals(new Rect.fromLTWH(100.0, 100.0, 200.0, 200.0)));
|
||||
|
||||
tween.update(0.5);
|
||||
expect(rectValue.left, closeTo(50.0, epsilon));
|
||||
expect(rectValue.top, closeTo(50.0, epsilon));
|
||||
expect(rectValue.width, closeTo(150.0, epsilon));
|
||||
expect(rectValue.height, closeTo(150.0, epsilon));
|
||||
});
|
||||
|
||||
test("Actions - ActionRepeat", () {
|
||||
double doubleValue;
|
||||
ActionTween tween = new ActionTween((double a) => doubleValue = a, 0.0, 1.0, 60.0);
|
||||
|
||||
ActionRepeat repeat2x = new ActionRepeat(tween, 2);
|
||||
expect(repeat2x.duration, closeTo(120.0, epsilon));
|
||||
|
||||
repeat2x.update(0.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
|
||||
repeat2x.update(0.25);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
repeat2x.update(0.75);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
repeat2x.update(1.0);
|
||||
expect(doubleValue, closeTo(1.0, epsilon));
|
||||
|
||||
ActionRepeat repeat4x = new ActionRepeat(tween, 4);
|
||||
expect(repeat4x.duration, closeTo(240.0, epsilon));
|
||||
|
||||
repeat4x.update(0.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
|
||||
repeat4x.update(0.125);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
repeat4x.update(0.875);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
repeat4x.update(1.0);
|
||||
expect(doubleValue, closeTo(1.0, epsilon));
|
||||
});
|
||||
|
||||
test("Actions - ActionGroup", () {
|
||||
double value0;
|
||||
double value1;
|
||||
|
||||
ActionTween tween0 = new ActionTween((double a) => value0 = a, 0.0, 1.0, 10.0);
|
||||
ActionTween tween1 = new ActionTween((double a) => value1 = a, 0.0, 1.0, 20.0);
|
||||
|
||||
ActionGroup group = new ActionGroup([tween0, tween1]);
|
||||
expect(group.duration, closeTo(20.0, epsilon));
|
||||
|
||||
group.update(0.0);
|
||||
expect(value0, closeTo(0.0, epsilon));
|
||||
expect(value1, closeTo(0.0, epsilon));
|
||||
|
||||
group.update(0.5);
|
||||
expect(value0, closeTo(1.0, epsilon));
|
||||
expect(value1, closeTo(0.5, epsilon));
|
||||
|
||||
group.update(1.0);
|
||||
expect(value0, closeTo(1.0, epsilon));
|
||||
expect(value1, closeTo(1.0, epsilon));
|
||||
});
|
||||
|
||||
test("Actions - ActionSequence", () {
|
||||
double doubleValue;
|
||||
|
||||
ActionTween tween0 = new ActionTween((double a) => doubleValue = a, 0.0, 1.0, 4.0);
|
||||
ActionTween tween1 = new ActionTween((double a) => doubleValue = a, 1.0, 0.0, 12.0);
|
||||
|
||||
ActionSequence sequence = new ActionSequence([tween0, tween1]);
|
||||
expect(sequence.duration, closeTo(16.0, epsilon));
|
||||
|
||||
sequence.update(0.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
|
||||
sequence.update(0.125);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
sequence.update(0.25);
|
||||
expect(doubleValue, closeTo(1.0, epsilon));
|
||||
|
||||
sequence.update(1.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
});
|
||||
|
||||
test("Actions - stepping", () {
|
||||
double doubleValue;
|
||||
|
||||
ActionTween tween = new ActionTween((double a) => doubleValue = a, 0.0, 1.0, 60.0);
|
||||
|
||||
tween.step(0.0);
|
||||
expect(doubleValue, closeTo(0.0, epsilon));
|
||||
|
||||
tween.step(30.0);
|
||||
expect(doubleValue, closeTo(0.5, epsilon));
|
||||
|
||||
tween.step(30.0);
|
||||
expect(doubleValue, closeTo(1.0, epsilon));
|
||||
});
|
||||
}
|
||||
82
packages/flutter_sprites/test/constraint_test.dart
Normal file
82
packages/flutter_sprites/test/constraint_test.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2015 The Chromium Authors. 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:ui';
|
||||
|
||||
import 'package:flutter_sprites/flutter_sprites.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
const double epsilon = 0.01;
|
||||
|
||||
void main() {
|
||||
test("Constraints - ConstraintPositionToNode", () {
|
||||
Node parent = new Node();
|
||||
|
||||
Node node0 = new Node();
|
||||
Node node1 = new Node();
|
||||
|
||||
parent.addChild(node0);
|
||||
parent.addChild(node1);
|
||||
|
||||
node1.constraints = [(new ConstraintPositionToNode(node0))];
|
||||
|
||||
node0.position = const Point(100.0, 50.0);
|
||||
node1.applyConstraints(0.1);
|
||||
|
||||
expect(node1.position.x, closeTo(100.0, epsilon));
|
||||
expect(node1.position.y, closeTo(50.0, epsilon));
|
||||
});
|
||||
|
||||
test("Constraints - ConstraintRotationToNode", () {
|
||||
Node parent = new Node();
|
||||
|
||||
Node node0 = new Node();
|
||||
Node node1 = new Node()..position = const Point(0.0, 100.0);
|
||||
|
||||
parent.addChild(node0);
|
||||
parent.addChild(node1);
|
||||
|
||||
node1.constraints = [(new ConstraintRotationToNode(node0))];
|
||||
|
||||
node1.applyConstraints(0.1);
|
||||
|
||||
expect(node1.rotation, closeTo(-90.0, epsilon));
|
||||
});
|
||||
|
||||
test("Constraints - ConstraintRotationToNodeRotation", () {
|
||||
Node parent = new Node();
|
||||
|
||||
Node node0 = new Node();
|
||||
Node node1 = new Node();
|
||||
|
||||
parent.addChild(node0);
|
||||
parent.addChild(node1);
|
||||
|
||||
node1.constraints = [(new ConstraintRotationToNodeRotation(node0, baseRotation: 10.0))];
|
||||
|
||||
node0.rotation = 90.0;
|
||||
node1.applyConstraints(0.1);
|
||||
|
||||
expect(node1.rotation, closeTo(100.0, epsilon));
|
||||
});
|
||||
|
||||
test("Constraints - ConstraintRotationToMovement", () {
|
||||
Node parent = new Node();
|
||||
|
||||
Node node0 = new Node();
|
||||
|
||||
parent.addChild(node0);
|
||||
|
||||
Constraint constraint = new ConstraintRotationToMovement();
|
||||
node0.constraints = [constraint];
|
||||
|
||||
node0.position = const Point(0.0, 0.0);
|
||||
constraint.preUpdate(node0, 0.1);
|
||||
|
||||
node0.position = const Point(0.0, 100.0);
|
||||
node0.applyConstraints(0.1);
|
||||
|
||||
expect(node0.rotation, closeTo(90.0, epsilon));
|
||||
});
|
||||
}
|
||||
205
packages/flutter_sprites/test/node_test.dart
Normal file
205
packages/flutter_sprites/test/node_test.dart
Normal file
@@ -0,0 +1,205 @@
|
||||
// Copyright 2015 The Chromium Authors. 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:ui';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_sprites/flutter_sprites.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test("Node - adding and removing children", () {
|
||||
// Create root node.
|
||||
NodeWithSize rootNode = new NodeWithSize(const Size(1024.0, 1024.0));
|
||||
|
||||
expect(rootNode.spriteBox, isNull);
|
||||
expect(rootNode.children.length, equals(0));
|
||||
|
||||
// Create children.
|
||||
Node child0 = new Node();
|
||||
Node child1 = new Node();
|
||||
|
||||
expect(child0.parent, isNull);
|
||||
expect(child1.parent, isNull);
|
||||
expect(child0.spriteBox, isNull);
|
||||
expect(child1.spriteBox, isNull);
|
||||
|
||||
// Create sprite box.
|
||||
SpriteBox spriteBox = new SpriteBox(rootNode);
|
||||
expect(rootNode.spriteBox, equals(spriteBox));
|
||||
|
||||
// Add children.
|
||||
rootNode.addChild(child0);
|
||||
rootNode.addChild(child1);
|
||||
|
||||
expect(child0, isIn(rootNode.children));
|
||||
expect(child1, isIn(rootNode.children));
|
||||
expect(rootNode.children.length, equals(2));
|
||||
expect(child0.parent, equals(rootNode));
|
||||
expect(child1.parent, equals(rootNode));
|
||||
expect(child0.spriteBox, equals(spriteBox));
|
||||
expect(child1.spriteBox, equals(spriteBox));
|
||||
|
||||
// Remove one of the children.
|
||||
rootNode.removeChild(child0);
|
||||
|
||||
expect(child1, isIn(rootNode.children));
|
||||
expect(child1.parent, equals(rootNode));
|
||||
expect(rootNode.children.length, equals(1));
|
||||
expect(child0.parent, isNull);
|
||||
expect(child0.spriteBox, isNull);
|
||||
|
||||
// Add a child back in.
|
||||
rootNode.addChild(child0);
|
||||
expect(child0, isIn(rootNode.children));
|
||||
expect(child1, isIn(rootNode.children));
|
||||
expect(rootNode.children.length, equals(2));
|
||||
expect(child0.parent, equals(rootNode));
|
||||
expect(child1.parent, equals(rootNode));
|
||||
expect(child0.spriteBox, equals(spriteBox));
|
||||
expect(child1.spriteBox, equals(spriteBox));
|
||||
|
||||
// Remove all children.
|
||||
rootNode.removeAllChildren();
|
||||
expect(rootNode.children.length, equals(0));
|
||||
expect(child0.parent, isNull);
|
||||
expect(child1.parent, isNull);
|
||||
expect(child0.spriteBox, isNull);
|
||||
expect(child1.spriteBox, isNull);
|
||||
});
|
||||
|
||||
testWidgets("Node - transformations", (WidgetTester tester) {
|
||||
const double epsilon = 0.01;
|
||||
|
||||
NodeWithSize rootNode = new NodeWithSize(const Size(1024.0, 1024.0));
|
||||
tester.pumpWidget(new SpriteWidget(rootNode));
|
||||
|
||||
// Translations and transformations adding up correctly.
|
||||
Node child0 = new Node();
|
||||
child0.position = const Point(100.0, 0.0);
|
||||
rootNode.addChild(child0);
|
||||
|
||||
Node child1 = new Node();
|
||||
child1.position = const Point(200.0, 0.0);
|
||||
child0.addChild(child1);
|
||||
|
||||
Point rootPoint = rootNode.convertPointFromNode(Point.origin, child1);
|
||||
expect(rootPoint.x, closeTo(300.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(0.0, epsilon));
|
||||
|
||||
// Rotations.
|
||||
Node rotatedChild = new Node();
|
||||
rotatedChild.rotation = 90.0;
|
||||
rootNode.addChild(rotatedChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 0.0), rotatedChild);
|
||||
expect(rootPoint.x, closeTo(0.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(1.0, epsilon));
|
||||
|
||||
// Scale.
|
||||
Node scaledChild = new Node();
|
||||
scaledChild.scale = 2.0;
|
||||
rootNode.addChild(scaledChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 1.0), scaledChild);
|
||||
expect(rootPoint.x, closeTo(2.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(2.0, epsilon));
|
||||
|
||||
// Scale x-axis only.
|
||||
Node scaledXChild = new Node();
|
||||
scaledXChild.scaleX = 2.0;
|
||||
rootNode.addChild(scaledXChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 1.0), scaledXChild);
|
||||
expect(rootPoint.x, closeTo(2.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(1.0, epsilon));
|
||||
|
||||
// Scale y-axis only.
|
||||
Node scaledYChild = new Node();
|
||||
scaledYChild.scaleY = 2.0;
|
||||
rootNode.addChild(scaledYChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 1.0), scaledYChild);
|
||||
expect(rootPoint.x, closeTo(1.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(2.0, epsilon));
|
||||
|
||||
// Skew x-axis.
|
||||
Node skewedXChild = new Node();
|
||||
skewedXChild.skewX = 45.0;
|
||||
rootNode.addChild(skewedXChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 1.0), skewedXChild);
|
||||
expect(rootPoint.x, closeTo(1.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(2.0, epsilon));
|
||||
|
||||
// Skew y-axis.
|
||||
Node skewedYChild = new Node();
|
||||
skewedYChild.skewY = 45.0;
|
||||
rootNode.addChild(skewedYChild);
|
||||
|
||||
rootPoint = rootNode.convertPointFromNode(const Point(1.0, 1.0), skewedYChild);
|
||||
expect(rootPoint.x, closeTo(2.0, epsilon));
|
||||
expect(rootPoint.y, closeTo(1.0, epsilon));
|
||||
});
|
||||
|
||||
test("Node - zOrder", () {
|
||||
// Ensure zOrder takes president over order added.
|
||||
{
|
||||
Node rootNode = new Node();
|
||||
|
||||
Node node0 = new Node();
|
||||
Node node1 = new Node();
|
||||
Node node2 = new Node()..zPosition = 1.0;
|
||||
Node node3 = new Node()..zPosition = 1.0;
|
||||
|
||||
rootNode.addChild(node0);
|
||||
rootNode.addChild(node2);
|
||||
rootNode.addChild(node1);
|
||||
rootNode.addChild(node3);
|
||||
|
||||
expect(rootNode.children[0], equals(node0));
|
||||
expect(rootNode.children[1], equals(node1));
|
||||
expect(rootNode.children[2], equals(node2));
|
||||
expect(rootNode.children[3], equals(node3));
|
||||
}
|
||||
|
||||
// Test negative zOrder.
|
||||
{
|
||||
Node rootNode = new Node();
|
||||
|
||||
Node node0 = new Node()..zPosition = -1.0;;
|
||||
Node node1 = new Node();
|
||||
Node node2 = new Node()..zPosition = 1.0;
|
||||
|
||||
rootNode.addChild(node2);
|
||||
rootNode.addChild(node1);
|
||||
rootNode.addChild(node0);
|
||||
|
||||
expect(rootNode.children[0], equals(node0));
|
||||
expect(rootNode.children[1], equals(node1));
|
||||
expect(rootNode.children[2], equals(node2));
|
||||
}
|
||||
});
|
||||
|
||||
test("Node - isPointInside", () {
|
||||
Node node = new Node();
|
||||
|
||||
expect(node.isPointInside(Point.origin), equals(false));
|
||||
|
||||
NodeWithSize nodeWithSize = new NodeWithSize(const Size(10.0, 10.0));
|
||||
nodeWithSize.pivot = Point.origin;
|
||||
|
||||
expect(nodeWithSize.isPointInside(const Point(1.0, 1.0)), isTrue);
|
||||
expect(nodeWithSize.isPointInside(const Point(9.0, 9.0)), isTrue);
|
||||
expect(nodeWithSize.isPointInside(const Point(11.0, 1.0)), isFalse);
|
||||
expect(nodeWithSize.isPointInside(const Point(-1.0, -1.0)), isFalse);
|
||||
|
||||
nodeWithSize.pivot = const Point(0.5, 0.5);
|
||||
|
||||
expect(nodeWithSize.isPointInside(const Point(1.0, 1.0)), isTrue);
|
||||
expect(nodeWithSize.isPointInside(const Point(9.0, 9.0)), isFalse);
|
||||
expect(nodeWithSize.isPointInside(const Point(11.0, 1.0)), isFalse);
|
||||
expect(nodeWithSize.isPointInside(const Point(-1.0, -1.0)), isTrue);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user