126 lines
3.6 KiB
Dart
126 lines
3.6 KiB
Dart
import 'dart:html' as html;
|
|
import 'package:rules_of_living/src/Simulation.dart';
|
|
import 'package:test/test.dart';
|
|
import 'package:mockito/mockito.dart';
|
|
|
|
@TestOn('browser')
|
|
import 'package:rules_of_living/src/Engine.dart';
|
|
|
|
class MockSimulation extends Mock implements Simulation {
|
|
int updateNum = 0;
|
|
bool hasChanges = false;
|
|
|
|
@override
|
|
Map<int, bool> update() {
|
|
updateNum++;
|
|
return hasChanges ? {1: true, 2: false} : {};
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
Engine sut;
|
|
setUp(() {
|
|
sut = Engine();
|
|
});
|
|
group("process", () {
|
|
setUp(() => sut.running = true);
|
|
test("errors out if updating takes too long",
|
|
() => expect(() => sut.process(5000, 10), throwsA(StackOverflowError)));
|
|
test("does not update if not enough time elapsed to pass ms per step", () {
|
|
bool result = false;
|
|
sut.stepsPerSecond = 1000;
|
|
|
|
sut.process(999, 2000,
|
|
update: () => result = true, render: (double interp) => null);
|
|
|
|
expect(result, true);
|
|
});
|
|
test("updates only when the ms per step threshold is crossed", () {
|
|
int updateNum = 0;
|
|
sut.stepsPerSecond = 1;
|
|
|
|
sut.process(1001, 2000, update: () => updateNum++);
|
|
expect(updateNum, equals(1));
|
|
});
|
|
test("updates until updateLag has been resolved", () {
|
|
int updateNum = 0;
|
|
sut.stepsPerSecond = 1;
|
|
|
|
sut.process(2999, 5000, update: () => updateNum++);
|
|
expect(updateNum, equals(2));
|
|
});
|
|
test("works without passing in update or render function arguments", () {
|
|
sut.stepsPerSecond = 1000;
|
|
expect(() => sut.process(500, 5000), isNot(throwsA(anything)));
|
|
});
|
|
});
|
|
group("update", () {
|
|
MockSimulation mockSim;
|
|
setUp(() {
|
|
mockSim = MockSimulation();
|
|
sut.simulation = mockSim;
|
|
});
|
|
test("does not error out if no simulation variable is set", () {
|
|
sut.simulation = null;
|
|
expect(() => sut.update(), isNot(throwsA(anything)));
|
|
});
|
|
test("updates simulation one tick for every time it is called", () {
|
|
sut.update();
|
|
sut.update();
|
|
sut.update();
|
|
expect(mockSim.updateNum, equals(3));
|
|
});
|
|
test("sets running to false when simulation returns no changes", () {
|
|
sut.running = true;
|
|
sut.update();
|
|
expect(sut.running, equals(false));
|
|
});
|
|
test("keeps running when simulation returns changes", () {
|
|
sut.running = true;
|
|
mockSim.hasChanges = true;
|
|
|
|
sut.update();
|
|
|
|
expect(sut.running, equals(true));
|
|
});
|
|
});
|
|
group("step", () {
|
|
MockSimulation mockSim;
|
|
setUp(() {
|
|
mockSim = MockSimulation();
|
|
sut.simulation = mockSim;
|
|
});
|
|
test("advances the simulation by one update", () {
|
|
sut.step();
|
|
expect(mockSim.updateNum, equals(1));
|
|
});
|
|
test("turns off continuous engine updates", () {
|
|
sut.running = true;
|
|
sut.step();
|
|
|
|
expect(sut.running, equals(false));
|
|
});
|
|
});
|
|
group("canvas", () {
|
|
test("Engine can be instantiated without canvas", () {
|
|
expect(sut, isNot(throwsNoSuchMethodError));
|
|
});
|
|
|
|
test("Engine does not throw errors when calling render directly", () {
|
|
// anonymous function necessary since throws can not use functions with args
|
|
expect(() => sut.render, isNot(throwsNoSuchMethodError));
|
|
});
|
|
|
|
test("Engine does not throw errors when processing without attached canvas",
|
|
() {
|
|
// anonymous function necessary since throws can not use functions with args
|
|
expect(() => sut.process, isNot(throwsNoSuchMethodError));
|
|
});
|
|
|
|
test("setCanvas allows setting a canvas for an engine at any point", () {
|
|
sut.canvas = new html.CanvasElement();
|
|
expect(sut.canvas, isNotNull);
|
|
});
|
|
});
|
|
}
|