Skip to content

Commit

Permalink
feat: Add a closeToVector3 matcher to flame_test (#3242)
Browse files Browse the repository at this point in the history
Add a closeToVector3 matcher to flame_test
  • Loading branch information
luanpotter authored Jul 26, 2024
1 parent 1e62b34 commit 965b684
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/flame_test/lib/flame_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export 'src/close_to_aabb.dart' show closeToAabb;
export 'src/close_to_vector.dart';
export 'src/close_to_vector3.dart';
export 'src/debug_text_renderer.dart' show DebugTextRenderer;
export 'src/expect_double.dart';
export 'src/fails_assert.dart';
Expand Down
45 changes: 45 additions & 0 deletions packages/flame_test/lib/src/close_to_vector3.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math.dart';

/// Returns a matcher which checks if the argument is a 3d vector within
/// distance [epsilon] of [vector]. For example:
///
/// ```dart
/// expect(scale, closeToVector3(Vector3(2, -2, 0)));
/// expect(position, closeToVector3(expectedPosition, 1e-10));
/// ```
Matcher closeToVector3(Vector3 vector, [double epsilon = 1e-15]) {
return _IsCloseTo(vector, epsilon);
}

class _IsCloseTo extends Matcher {
const _IsCloseTo(this._value, this._epsilon);

final Vector3 _value;
final double _epsilon;

@override
bool matches(dynamic item, Map matchState) {
return (item is Vector3) && (item - _value).length <= _epsilon;
}

@override
Description describe(Description description) {
final coords = '${_value.x}, ${_value.y}, ${_value.z}';
return description.add('a Vector3 object within $_epsilon of ($coords)');
}

@override
Description describeMismatch(
dynamic item,
Description mismatchDescription,
Map matchState,
bool verbose,
) {
if (item is! Vector3) {
return mismatchDescription.add('is not an instance of Vector3');
}
final distance = (item - _value).length;
return mismatchDescription.add('is at distance $distance');
}
}
64 changes: 64 additions & 0 deletions packages/flame_test/test/close_to_vector3_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'package:flame_test/src/close_to_vector3.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math.dart';

void main() {
group('closeToVector3', () {
test('matches normally', () {
expect(Vector3.zero(), closeToVector3(Vector3(0, 0, 0)));
expect(Vector3(-14, 99, -99), closeToVector3(Vector3(-14, 99, -99)));
expect(Vector3(1e-20, -1e-16, 0), closeToVector3(Vector3(0, 0, 0)));

expect(
Vector3(1.0001, 2.0, -1.0001),
closeToVector3(Vector3(1, 2, -1), 0.01),
);
expect(Vector3(9, 10, 11), closeToVector3(Vector3.all(10), 10));
});

test('fails on type mismatch - double', () {
try {
expect(3.14, closeToVector3(Vector3.zero()));
} on TestFailure catch (e) {
expect(
e.message,
contains(
'Expected: a Vector3 object within 1e-15 of (0.0, 0.0, 0.0)',
),
);
expect(e.message, contains('Actual: <3.14>'));
expect(e.message, contains('Which: is not an instance of Vector3'));
}
});

test('fails on type mismatch - vector2', () {
try {
expect(Vector2(1, 2), closeToVector3(Vector3.zero()));
} on TestFailure catch (e) {
expect(
e.message,
contains(
'Expected: a Vector3 object within 1e-15 of (0.0, 0.0, 0.0)',
),
);
expect(e.message, contains('Actual: Vector2:<[1.0,2.0]>'));
expect(e.message, contains('Which: is not an instance of Vector3'));
}
});

test('fails on value mismatch', () {
try {
expect(Vector3(101, 217, 100), closeToVector3(Vector3(100, 220, 101)));
} on TestFailure catch (e) {
expect(
e.message,
contains(
'Expected: a Vector3 object within 1e-15 of (100.0, 220.0, 101.0)',
),
);
expect(e.message, contains('Actual: Vector3:<[101.0,217.0,100.0]>'));
expect(e.message, contains('Which: is at distance 3.3166247903554'));
}
});
});
}

0 comments on commit 965b684

Please sign in to comment.