tests update
This commit is contained in:
parent
6d6e80c762
commit
8d8c40e6a6
2 changed files with 95 additions and 30 deletions
|
@ -1,12 +1,10 @@
|
||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.service');
|
var ns = $.namespace('pskl.service');
|
||||||
|
|
||||||
var SNAPSHOT_PERIOD = 50;
|
ns.HistoryService = function (piskelController, shortcutService, deserializer) {
|
||||||
var LOAD_STATE_INTERVAL = 50;
|
this.$piskelController = piskelController || pskl.app.piskelController;
|
||||||
|
this.$shortcutService = shortcutService || pskl.app.shortcutService;
|
||||||
ns.HistoryService = function (piskelController, shortcutService) {
|
this.$deserializer = deserializer || pskl.utils.serialization.Deserializer;
|
||||||
this.piskelController = piskelController || pskl.app.piskelController;
|
|
||||||
this.shortcutService = shortcutService || pskl.app.shortcutService;
|
|
||||||
|
|
||||||
this.stateQueue = [];
|
this.stateQueue = [];
|
||||||
this.currentIndex = -1;
|
this.currentIndex = -1;
|
||||||
|
@ -18,6 +16,8 @@
|
||||||
|
|
||||||
ns.HistoryService.SNAPSHOT = 'SNAPSHOT';
|
ns.HistoryService.SNAPSHOT = 'SNAPSHOT';
|
||||||
ns.HistoryService.REPLAY = 'REPLAY';
|
ns.HistoryService.REPLAY = 'REPLAY';
|
||||||
|
ns.HistoryService.SNAPSHOT_PERIOD = 50;
|
||||||
|
ns.HistoryService.LOAD_STATE_INTERVAL = 50;
|
||||||
/**
|
/**
|
||||||
* This event alters the state (frames, layers) of the piskel. The event is triggered before the execution of associated command.
|
* This event alters the state (frames, layers) of the piskel. The event is triggered before the execution of associated command.
|
||||||
* Don't store snapshots for such events.
|
* Don't store snapshots for such events.
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
ns.HistoryService.prototype.init = function () {
|
ns.HistoryService.prototype.init = function () {
|
||||||
$.subscribe(Events.PISKEL_SAVE_STATE, this.onSaveStateEvent.bind(this));
|
$.subscribe(Events.PISKEL_SAVE_STATE, this.onSaveStateEvent.bind(this));
|
||||||
|
|
||||||
this.shortcutService.addShortcut('ctrl+Z', this.undo.bind(this));
|
this.$shortcutService.addShortcut('ctrl+Z', this.undo.bind(this));
|
||||||
this.shortcutService.addShortcut('ctrl+Y', this.redo.bind(this));
|
this.$shortcutService.addShortcut('ctrl+Y', this.redo.bind(this));
|
||||||
|
|
||||||
this.saveState({
|
this.saveState({
|
||||||
type : ns.HistoryService.SNAPSHOT
|
type : ns.HistoryService.SNAPSHOT
|
||||||
|
@ -45,17 +45,17 @@
|
||||||
|
|
||||||
var state = {
|
var state = {
|
||||||
action : stateInfo,
|
action : stateInfo,
|
||||||
frameIndex : this.piskelController.currentFrameIndex,
|
frameIndex : this.$piskelController.currentFrameIndex,
|
||||||
layerIndex : this.piskelController.currentLayerIndex
|
layerIndex : this.$piskelController.currentLayerIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
var isSnapshot = stateInfo.type === ns.HistoryService.SNAPSHOT;
|
var isSnapshot = stateInfo.type === ns.HistoryService.SNAPSHOT;
|
||||||
var isNoSnapshot = stateInfo.type === ns.HistoryService.REPLAY_NO_SNAPSHOT;
|
var isNoSnapshot = stateInfo.type === ns.HistoryService.REPLAY_NO_SNAPSHOT;
|
||||||
var isAtAutoSnapshotInterval = this.currentIndex % SNAPSHOT_PERIOD === 0 || this.saveNextAsSnapshot;
|
var isAtAutoSnapshotInterval = this.currentIndex % ns.HistoryService.SNAPSHOT_PERIOD === 0 || this.saveNextAsSnapshot;
|
||||||
if (isNoSnapshot && isAtAutoSnapshotInterval) {
|
if (isNoSnapshot && isAtAutoSnapshotInterval) {
|
||||||
this.saveNextAsSnapshot = true;
|
this.saveNextAsSnapshot = true;
|
||||||
} else if (isSnapshot || isAtAutoSnapshotInterval) {
|
} else if (isSnapshot || isAtAutoSnapshotInterval) {
|
||||||
state.piskel = this.piskelController.serialize(true);
|
state.piskel = this.$piskelController.serialize(true);
|
||||||
this.saveNextAsSnapshot = false;
|
this.saveNextAsSnapshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.isLoadStateAllowed_ = function (index) {
|
ns.HistoryService.prototype.isLoadStateAllowed_ = function (index) {
|
||||||
var timeOk = (Date.now() - this.lastLoadState) > LOAD_STATE_INTERVAL;
|
var timeOk = (Date.now() - this.lastLoadState) > ns.HistoryService.LOAD_STATE_INTERVAL;
|
||||||
var indexInRange = index >= 0 && index < this.stateQueue.length;
|
var indexInRange = index >= 0 && index < this.stateQueue.length;
|
||||||
return timeOk && indexInRange;
|
return timeOk && indexInRange;
|
||||||
};
|
};
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
}
|
}
|
||||||
var serializedPiskel = this.getSnapshotFromState_(snapshotIndex);
|
var serializedPiskel = this.getSnapshotFromState_(snapshotIndex);
|
||||||
var onPiskelLoadedCb = this.onPiskelLoaded_.bind(this, index, snapshotIndex);
|
var onPiskelLoadedCb = this.onPiskelLoaded_.bind(this, index, snapshotIndex);
|
||||||
pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, onPiskelLoadedCb);
|
this.$deserializer.deserialize(serializedPiskel, onPiskelLoadedCb);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.console.error("[CRITICAL ERROR] : Unable to load a history state.");
|
window.console.error("[CRITICAL ERROR] : Unable to load a history state.");
|
||||||
|
@ -126,8 +126,8 @@
|
||||||
|
|
||||||
ns.HistoryService.prototype.onPiskelLoaded_ = function (index, snapshotIndex, piskel) {
|
ns.HistoryService.prototype.onPiskelLoaded_ = function (index, snapshotIndex, piskel) {
|
||||||
var originalSize = this.getPiskelSize_();
|
var originalSize = this.getPiskelSize_();
|
||||||
piskel.setDescriptor(this.piskelController.piskel.getDescriptor());
|
piskel.setDescriptor(this.$piskelController.piskel.getDescriptor());
|
||||||
this.piskelController.setPiskel(piskel);
|
this.$piskelController.setPiskel(piskel);
|
||||||
|
|
||||||
for (var i = snapshotIndex + 1 ; i <= index ; i++) {
|
for (var i = snapshotIndex + 1 ; i <= index ; i++) {
|
||||||
var state = this.stateQueue[i];
|
var state = this.stateQueue[i];
|
||||||
|
@ -135,6 +135,7 @@
|
||||||
this.replayState(state);
|
this.replayState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should only do this when going backwards
|
||||||
var lastState = this.stateQueue[index+1];
|
var lastState = this.stateQueue[index+1];
|
||||||
if (lastState) {
|
if (lastState) {
|
||||||
this.setupState(lastState);
|
this.setupState(lastState);
|
||||||
|
@ -148,18 +149,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.getPiskelSize_ = function () {
|
ns.HistoryService.prototype.getPiskelSize_ = function () {
|
||||||
return this.piskelController.getWidth() + 'x' + this.piskelController.getHeight();
|
return this.$piskelController.getWidth() + 'x' + this.$piskelController.getHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.setupState = function (state) {
|
ns.HistoryService.prototype.setupState = function (state) {
|
||||||
this.piskelController.setCurrentFrameIndex(state.frameIndex);
|
this.$piskelController.setCurrentFrameIndex(state.frameIndex);
|
||||||
this.piskelController.setCurrentLayerIndex(state.layerIndex);
|
this.$piskelController.setCurrentLayerIndex(state.layerIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.replayState = function (state) {
|
ns.HistoryService.prototype.replayState = function (state) {
|
||||||
var action = state.action;
|
var action = state.action;
|
||||||
var type = action.type;
|
var type = action.type;
|
||||||
var layer = this.piskelController.getLayerAt(state.layerIndex);
|
var layer = this.$piskelController.getLayerAt(state.layerIndex);
|
||||||
var frame = layer.getFrameAt(state.frameIndex);
|
var frame = layer.getFrameAt(state.frameIndex);
|
||||||
action.scope.replay(frame, action.replay);
|
action.scope.replay(frame, action.replay);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +1,86 @@
|
||||||
describe("History Service suite", function() {
|
var callFactory = function (method) {
|
||||||
it("starts at -1", function() {
|
return {
|
||||||
var mockPiskelController = {};
|
times : function (times) {
|
||||||
var mockShortcutService = {};
|
var results = [];
|
||||||
var historyService = new pskl.service.HistoryService(mockPiskelController, mockShortcutService);
|
for (var i = 0 ; i < times ; i++) {
|
||||||
expect(historyService.currentIndex).toBe(-1);
|
results.push(method());
|
||||||
});
|
}
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
once : function () {
|
||||||
|
return method();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
it("is at 0 after init", function() {
|
describe("History Service suite", function() {
|
||||||
|
var SERIALIZED_PISKEL = 'serialized-piskel';
|
||||||
|
var historyService = null;
|
||||||
|
|
||||||
|
var getLastState = function () {
|
||||||
|
return historyService.stateQueue[historyService.currentIndex];
|
||||||
|
};
|
||||||
|
|
||||||
|
var createMockHistoryService = function () {
|
||||||
var mockPiskelController = {
|
var mockPiskelController = {
|
||||||
serialize : function () {
|
serialize : function () {
|
||||||
return 'serialized-piskel';
|
return SERIALIZED_PISKEL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var mockShortcutService = {
|
var mockShortcutService = {
|
||||||
addShortcut : function () {}
|
addShortcut : function () {}
|
||||||
};
|
};
|
||||||
var historyService = new pskl.service.HistoryService(mockPiskelController, mockShortcutService);
|
return new pskl.service.HistoryService(mockPiskelController, mockShortcutService);
|
||||||
|
};
|
||||||
|
|
||||||
|
it("starts at -1", function() {
|
||||||
|
historyService = createMockHistoryService();
|
||||||
|
expect(historyService.currentIndex).toBe(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is at 0 after init", function() {
|
||||||
|
historyService = createMockHistoryService();
|
||||||
historyService.init();
|
historyService.init();
|
||||||
expect(historyService.currentIndex).toBe(0);
|
expect(historyService.currentIndex).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var sendSaveEvents = function (type) {
|
||||||
|
return callFactory (function () {
|
||||||
|
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||||
|
type : type,
|
||||||
|
scope : {},
|
||||||
|
replay : {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
it("stores a piskel snapshot after 5 SAVE", function () {
|
||||||
|
// BEFORE
|
||||||
|
var SNAPSHOT_PERIOD_BACKUP = pskl.service.HistoryService.SNAPSHOT_PERIOD;
|
||||||
|
pskl.service.HistoryService.SNAPSHOT_PERIOD = 5;
|
||||||
|
|
||||||
|
historyService = createMockHistoryService();
|
||||||
|
historyService.init();
|
||||||
|
|
||||||
|
sendSaveEvents(pskl.service.HistoryService.REPLAY).times(5);
|
||||||
|
|
||||||
|
expect(historyService.currentIndex).toBe(5);
|
||||||
|
|
||||||
|
expect(getLastState().piskel).toBe(SERIALIZED_PISKEL);
|
||||||
|
|
||||||
|
sendSaveEvents(pskl.service.HistoryService.REPLAY).times(4);
|
||||||
|
|
||||||
|
sendSaveEvents(pskl.service.HistoryService.REPLAY_NO_SNAPSHOT).once();
|
||||||
|
expect(getLastState().piskel).toBeUndefined();
|
||||||
|
|
||||||
|
sendSaveEvents(pskl.service.HistoryService.REPLAY_NO_SNAPSHOT).once();
|
||||||
|
expect(getLastState().piskel).toBeUndefined();
|
||||||
|
|
||||||
|
sendSaveEvents(pskl.service.HistoryService.REPLAY).once();
|
||||||
|
expect(getLastState().piskel).toBe(SERIALIZED_PISKEL);
|
||||||
|
|
||||||
|
// AFTER
|
||||||
|
pskl.service.HistoryService.SNAPSHOT_PERIOD = SNAPSHOT_PERIOD_BACKUP;
|
||||||
|
|
||||||
|
})
|
||||||
});
|
});
|
Loading…
Reference in a new issue