diff --git a/karma.conf.js b/karma.conf.js index 8fb83788..4292a77f 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -6,7 +6,9 @@ module.exports = function(config) { var mapToSrcFolder = function (path) {return ['src', path].join('/');}; var piskelScripts = require('./src/piskel-script-list.js').scripts.map(mapToSrcFolder); + piskelScripts.push('test/js/testutils/**/*.js'); piskelScripts.push('test/js/**/*.js'); + config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) diff --git a/src/js/tools/drawing/selection/BaseSelect.js b/src/js/tools/drawing/selection/BaseSelect.js index 60c61c1c..2c1aaf99 100644 --- a/src/js/tools/drawing/selection/BaseSelect.js +++ b/src/js/tools/drawing/selection/BaseSelect.js @@ -8,7 +8,7 @@ ns.BaseSelect = function() { this.secondaryToolId = pskl.tools.drawing.Move.TOOL_ID; - this.BodyRoot = $('body'); + this.bodyRoot = $('body'); // Select's first point coordinates (set in applyToolAt) this.startCol = null; @@ -81,12 +81,12 @@ if (overlay.containsPixel(col, row)) { if (this.isInSelection(col, row)) { // We're hovering the selection, show the move tool: - this.BodyRoot.addClass(this.secondaryToolId); - this.BodyRoot.removeClass(this.toolId); + this.bodyRoot.addClass(this.secondaryToolId); + this.bodyRoot.removeClass(this.toolId); } else { // We're not hovering the selection, show create selection tool: - this.BodyRoot.addClass(this.toolId); - this.BodyRoot.removeClass(this.secondaryToolId); + this.bodyRoot.addClass(this.toolId); + this.bodyRoot.removeClass(this.secondaryToolId); } } }; diff --git a/test/js/selection/SelectionManagerTest.js b/test/js/selection/SelectionManagerTest.js new file mode 100644 index 00000000..736fe984 --- /dev/null +++ b/test/js/selection/SelectionManagerTest.js @@ -0,0 +1,206 @@ +describe("SelectionManager suite", function() { + var black = '#000000'; + var red = '#ff0000'; + var transparent = Constants.TRANSPARENT_COLOR; + var B = black, R = red, T = transparent; + + // shortcuts + var toFrameGrid = test.testutils.toFrameGrid; + var frameEqualsGrid = test.testutils.frameEqualsGrid; + + // test objects + var selectionManager; + var selection; + var currentFrame; + + /** + * @Mock + */ + pskl.app.shortcutService = { + addShortcut : function () {} + }; + + /** + * @Mock + */ + var piskelController = { + getCurrentFrame : function () { + return currentFrame; + } + }; + + beforeEach(function() { + currentFrame = pskl.model.Frame.fromPixelGrid([ + [B, R, T], + [R, B, R], + [T, R, B] + ]); + + selectionManager = new pskl.selection.SelectionManager(piskelController); + selectionManager.init(); + + selection = new pskl.selection.BaseSelection(); + + selection.pixels = []; + }); + + /** + * Check a basic copy paste scenario + */ + it("copy/paste OK", function () { + console.log('[SelectionManager] copy/paste OK'); + selectMiddleLine(); + + console.log('[SelectionManager] ... copy'); + selectionManager.copy(); + + console.log('[SelectionManager] ... check selection content after copy contains correct colors'); + expect(selection.pixels.length).toBe(3); // or not to be ... lalalala ... french-only joke \o/ + checkContainsPixel(selection.pixels, 1, 0, R); + checkContainsPixel(selection.pixels, 1, 1, B); + checkContainsPixel(selection.pixels, 1, 2, R); + + console.log('[SelectionManager] ... move 1 row down'); + selection.move(0, 1); + + console.log('[SelectionManager] ... check pixels were shifted by two columns forward'); + checkContainsPixel(selection.pixels, 2, 0, R); + checkContainsPixel(selection.pixels, 2, 1, B); + checkContainsPixel(selection.pixels, 2, 2, R); + + console.log('[SelectionManager] ... paste'); + selectionManager.paste(); + + console.log('[SelectionManager] ... check last line is identical to middle line after paste'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [R, B, R], + [R, B, R] + ]); + }); + + /** + * Check a basic cut paste scenario + */ + it("cut OK", function () { + console.log('[SelectionManager] cut OK'); + selectMiddleLine(); + + console.log('[SelectionManager] ... cut'); + selectionManager.cut(); + + console.log('[SelectionManager] ... check middle line was cut in the source frame'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [T, T, T], + [T, R, B] + ]); + + console.log('[SelectionManager] ... paste'); + selectionManager.paste(); + + console.log('[SelectionManager] ... check middle line was restored by paste'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [R, B, R], + [T, R, B] + ]); + }); + + /** + * Check a copy paste scenario that goes out of the frame boundaries for copying and for pasting. + */ + it("copy/paste OK out of bounds", function () { + console.log('[SelectionManager] copy/paste OK out of bounds'); + selectMiddleLine(); + + console.log('[SelectionManager] ... move 2 columns to the right'); + selection.move(2, 0); + + console.log('[SelectionManager] ... copy out of bounds'); + selectionManager.copy(); + console.log('[SelectionManager] ... check out of bound pixels were replaced by transparent pixels'); + checkContainsPixel(selection.pixels, 1, 2, R); + checkContainsPixel(selection.pixels, 1, 3, T); + checkContainsPixel(selection.pixels, 1, 4, T); + + console.log('[SelectionManager] ... move one column to the left'); + selection.move(-1, 0); + + console.log('[SelectionManager] ... check pixels were shifted by one column back'); + checkContainsPixel(selection.pixels, 1, 1, R); + checkContainsPixel(selection.pixels, 1, 2, T); + checkContainsPixel(selection.pixels, 1, 3, T); + + console.log('[SelectionManager] ... paste out of bounds'); + selectionManager.paste(); + + console.log('[SelectionManager] ... check pixel at (1,1) is red after paste'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [R, R, R], + [T, R, B] + ]); + }); + + /** + * Check a cut paste scenario that goes out of the frame boundaries for cutting and for pasting. + */ + it("cut OK out of bounds", function () { + console.log('[SelectionManager] cut OK'); + selectMiddleLine(); + + console.log('[SelectionManager] ... move 2 columns to the right'); + selection.move(2, 0); + + console.log('[SelectionManager] ... cut out of bounds'); + selectionManager.cut(); + console.log('[SelectionManager] ... check last pixel of midle line was cut in the source frame'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [R, B, T], + [T, R, B] + ]); + + selection.move(-1, 0); + + console.log('[SelectionManager] ... paste out of bounds'); + selectionManager.paste(); + + console.log('[SelectionManager] ... check middle line final state'); + frameEqualsGrid(currentFrame, [ + [B, R, T], + [R, R, T], + [T, R, B] + ]); + }); + + // Private helpers + var createPixel = function(row, col, color) { + return { + row : row, + col : col, + color : color + }; + }; + + var selectMiddleLine = function () { + console.log('[SelectionManager] ... select middle line'); + selection.pixels.push(createPixel(1, 0)); + selection.pixels.push(createPixel(1, 1)); + selection.pixels.push(createPixel(1, 2)); + + expect(selectionManager.currentSelection).toBe(null); + console.log('[SelectionManager] ... send SELECTION_CREATED event for the test selection'); + $.publish(Events.SELECTION_CREATED, [selection]); + expect(selectionManager.currentSelection).toBe(selection); + }; + + var checkContainsPixel = function (pixels, row, col, color) { + var containsPixel = pixels.some(function (pixel) { + return pixel.row == row && pixel.col == col && pixel.color == color; + }); + expect(containsPixel).toBe(true); + }; + +}); \ No newline at end of file