refactored event bindings to expose content node events and enable true functional tests without a test framework like Selenium. Added new manualTests.html page for manual tests. One of the manual tests has already been converted to a functional test. Will add in image data url hashmaps soon so that I can compare screenshots before and after a series of actions in the functional tests

This commit is contained in:
Eric Rowell 2012-06-15 11:47:55 -07:00
parent 9b76f650f7
commit 9ec8c94701
7 changed files with 2300 additions and 2241 deletions

View File

@ -6,7 +6,7 @@ To build a development version of the library, run `thor build:dev VERSION`, whe
If you add a file in the src directory, be sure to add the filename to the filename array in the Thorfile. If you add a file in the src directory, be sure to add the filename to the filename array in the Thorfile.
#Tests #Tests
To run unit tests, open the `unitTests.html` file in the `tests/html` directory. To run functional tests, open the `functionalTests.html` file. The tests output the results to the console via `console.log()` so be sure to have it open. To run tests, open `unitTests.html`, `functionalTests.html`, or `manualTests.html` in the `tests/html` directory. Unit tests and functional tests output the results to the console via `console.log()` so be sure to have it open.
#Pull Requests #Pull Requests
I'd be happy to review any pull requests that may better the KineticJS project, in particular if you have a bug fix or a new shape (see `src/shapes` for examples). Before doing so, please first make sure that all of the unit tests and functional tests pass. I'd be happy to review any pull requests that may better the KineticJS project, in particular if you have a bug fix, enhancement, or a new shape (see `src/shapes` for examples). Before doing so, please first make sure that all of the unit tests and functional tests pass.

170
dist/kinetic-core.js vendored
View File

@ -3,7 +3,7 @@
* http://www.kineticjs.com/ * http://www.kineticjs.com/
* Copyright 2012, Eric Rowell * Copyright 2012, Eric Rowell
* Licensed under the MIT or GPL Version 2 licenses. * Licensed under the MIT or GPL Version 2 licenses.
* Date: Jun 14 2012 * Date: Jun 15 2012
* *
* Copyright (C) 2011 - 2012 by Eric Rowell * Copyright (C) 2011 - 2012 by Eric Rowell
* *
@ -1583,7 +1583,6 @@ Kinetic.Stage = function(config) {
this._id = Kinetic.GlobalObject.idCounter++; this._id = Kinetic.GlobalObject.idCounter++;
this._buildDOM(); this._buildDOM();
this._bindContentEvents(); this._bindContentEvents();
this._prepareDrag();
//change events //change events
this.on('widthChange.kinetic_reserved', function() { this.on('widthChange.kinetic_reserved', function() {
@ -1971,7 +1970,7 @@ Kinetic.Stage.prototype = {
} }
// handle touchstart // handle touchstart
if(!isDragging && this.touchStart && !this.touchMove) { else if(!isDragging && this.touchStart && !this.touchMove) {
this.touchStart = false; this.touchStart = false;
this.tapStart = true; this.tapStart = true;
shape._handleEvent('touchstart', evt); shape._handleEvent('touchstart', evt);
@ -2027,7 +2026,8 @@ Kinetic.Stage.prototype = {
} }
// handle mousemove and touchmove // handle mousemove and touchmove
else if(!isDragging && this.mouseMove) {
else if(!isDragging && this.mouseMove) {
shape._handleEvent('mousemove', evt); shape._handleEvent('mousemove', evt);
return true; return true;
} }
@ -2158,17 +2158,17 @@ else if(!isDragging && this.touchMove) {
var pubEvent = events[n]; var pubEvent = events[n];
// induce scope // induce scope
( function() { ( function() {
var event = pubEvent; var event = pubEvent;
that.content.addEventListener(event, function(evt) { that.content.addEventListener(event, function(evt) {
that['_on' + event](evt); that['_' + event](evt);
}, false); }, false);
}()); }());
} }
}, },
_onmouseover: function(evt) { _mouseover: function(evt) {
this._handleStageEvent(evt); this._handleStageEvent(evt);
}, },
_onmouseout: function(evt) { _mouseout: function(evt) {
// if there's a current target shape, run mouseout handlers // if there's a current target shape, run mouseout handlers
var targetShape = this.targetShape; var targetShape = this.targetShape;
if(targetShape) { if(targetShape) {
@ -2176,8 +2176,11 @@ else if(!isDragging && this.touchMove) {
this.targetShape = undefined; this.targetShape = undefined;
} }
this.mousePos = undefined; this.mousePos = undefined;
// end drag and drop
this._endDrag(evt);
}, },
_onmousemove: function(evt) { _mousemove: function(evt) {
//throttle mousemove //throttle mousemove
var throttle = this.attrs.throttle; var throttle = this.attrs.throttle;
var date = new Date(); var date = new Date();
@ -2190,8 +2193,11 @@ else if(!isDragging && this.touchMove) {
this.mouseUp = false; this.mouseUp = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
} }
// start drag and drop
this._startDrag(evt);
}, },
_onmousedown: function(evt) { _mousedown: function(evt) {
this.mouseDown = true; this.mouseDown = true;
this.mouseUp = false; this.mouseUp = false;
this.mouseMove = false; this.mouseMove = false;
@ -2202,14 +2208,17 @@ else if(!isDragging && this.touchMove) {
this._initDrag(); this._initDrag();
} }
}, },
_onmouseup: function(evt) { _mouseup: function(evt) {
this.mouseDown = false; this.mouseDown = false;
this.mouseUp = true; this.mouseUp = true;
this.mouseMove = false; this.mouseMove = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
this.clickStart = false; this.clickStart = false;
// end drag and drop
this._endDrag(evt);
}, },
_ontouchstart: function(evt) { _touchstart: function(evt) {
evt.preventDefault(); evt.preventDefault();
this.touchStart = true; this.touchStart = true;
this.touchEnd = false; this.touchEnd = false;
@ -2222,14 +2231,17 @@ else if(!isDragging && this.touchMove) {
this._initDrag(); this._initDrag();
} }
}, },
_ontouchend: function(evt) { _touchend: function(evt) {
this.touchStart = false; this.touchStart = false;
this.touchEnd = true; this.touchEnd = true;
this.touchMove = false; this.touchMove = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
this.tapStart = false; this.tapStart = false;
// end drag and drop
this._endDrag(evt);
}, },
_ontouchmove: function(evt) { _touchmove: function(evt) {
//throttle touchmove //throttle touchmove
var that = this; var that = this;
var throttle = this.attrs.throttle; var throttle = this.attrs.throttle;
@ -2253,6 +2265,9 @@ else if(!isDragging && this.touchMove) {
that._handleStageEvent(evt); that._handleStageEvent(evt);
}, 5); }, 5);
} }
// start drag and drop
this._startDrag(evt);
}, },
/** /**
* set mouse positon for desktop apps * set mouse positon for desktop apps
@ -2337,80 +2352,73 @@ else if(!isDragging && this.touchMove) {
go.drag.node = undefined; go.drag.node = undefined;
}, },
/** /**
* prepare drag and drop * start drag and drop
*/ */
_prepareDrag: function() { _startDrag: function(evt) {
var that = this; var that = this;
var go = Kinetic.GlobalObject;
var node = go.drag.node;
this._onContent('mousemove touchmove', function(evt) { if(node) {
var go = Kinetic.GlobalObject; var pos = that.getUserPosition();
var node = go.drag.node; var dc = node.attrs.dragConstraint;
var db = node.attrs.dragBounds;
var lastNodePos = {
x: node.attrs.x,
y: node.attrs.y
};
if(node) { // default
var pos = that.getUserPosition(); var newNodePos = {
var dc = node.attrs.dragConstraint; x: pos.x - go.drag.offset.x,
var db = node.attrs.dragBounds; y: pos.y - go.drag.offset.y
var lastNodePos = { };
x: node.attrs.x,
y: node.attrs.y
};
// default // bounds overrides
var newNodePos = { if(db.left !== undefined && newNodePos.x < db.left) {
x: pos.x - go.drag.offset.x, newNodePos.x = db.left;
y: pos.y - go.drag.offset.y }
}; if(db.right !== undefined && newNodePos.x > db.right) {
newNodePos.x = db.right;
// bounds overrides }
if(db.left !== undefined && newNodePos.x < db.left) { if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.x = db.left; newNodePos.y = db.top;
} }
if(db.right !== undefined && newNodePos.x > db.right) { if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.x = db.right; newNodePos.y = db.bottom;
}
if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.y = db.top;
}
if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.y = db.bottom;
}
node.setAbsolutePosition(newNodePos);
// constraint overrides
if(dc === 'horizontal') {
node.attrs.y = lastNodePos.y;
}
else if(dc === 'vertical') {
node.attrs.x = lastNodePos.x;
}
/*
* if dragging and dropping the stage,
* draw all of the layers
*/
if(go.drag.node.nodeType === 'Stage') {
go.drag.node.draw();
}
else {
go.drag.node.getLayer().draw();
}
if(!go.drag.moving) {
go.drag.moving = true;
// execute dragstart events if defined
go.drag.node._handleEvent('dragstart', evt);
}
// execute user defined ondragmove if defined
go.drag.node._handleEvent('dragmove', evt);
} }
}, false);
this._onContent('mouseup touchend mouseout', function(evt) { node.setAbsolutePosition(newNodePos);
that._endDrag(evt);
}); // constraint overrides
if(dc === 'horizontal') {
node.attrs.y = lastNodePos.y;
}
else if(dc === 'vertical') {
node.attrs.x = lastNodePos.x;
}
/*
* if dragging and dropping the stage,
* draw all of the layers
*/
if(go.drag.node.nodeType === 'Stage') {
go.drag.node.draw();
}
else {
go.drag.node.getLayer().draw();
}
if(!go.drag.moving) {
go.drag.moving = true;
// execute dragstart events if defined
go.drag.node._handleEvent('dragstart', evt);
}
// execute user defined ondragmove if defined
go.drag.node._handleEvent('dragmove', evt);
}
}, },
/** /**
* build dom * build dom

File diff suppressed because one or more lines are too long

View File

@ -34,7 +34,6 @@ Kinetic.Stage = function(config) {
this._id = Kinetic.GlobalObject.idCounter++; this._id = Kinetic.GlobalObject.idCounter++;
this._buildDOM(); this._buildDOM();
this._bindContentEvents(); this._bindContentEvents();
this._prepareDrag();
//change events //change events
this.on('widthChange.kinetic_reserved', function() { this.on('widthChange.kinetic_reserved', function() {
@ -422,7 +421,7 @@ Kinetic.Stage.prototype = {
} }
// handle touchstart // handle touchstart
if(!isDragging && this.touchStart && !this.touchMove) { else if(!isDragging && this.touchStart && !this.touchMove) {
this.touchStart = false; this.touchStart = false;
this.tapStart = true; this.tapStart = true;
shape._handleEvent('touchstart', evt); shape._handleEvent('touchstart', evt);
@ -478,7 +477,8 @@ Kinetic.Stage.prototype = {
} }
// handle mousemove and touchmove // handle mousemove and touchmove
else if(!isDragging && this.mouseMove) {
else if(!isDragging && this.mouseMove) {
shape._handleEvent('mousemove', evt); shape._handleEvent('mousemove', evt);
return true; return true;
} }
@ -609,17 +609,17 @@ else if(!isDragging && this.touchMove) {
var pubEvent = events[n]; var pubEvent = events[n];
// induce scope // induce scope
( function() { ( function() {
var event = pubEvent; var event = pubEvent;
that.content.addEventListener(event, function(evt) { that.content.addEventListener(event, function(evt) {
that['_on' + event](evt); that['_' + event](evt);
}, false); }, false);
}()); }());
} }
}, },
_onmouseover: function(evt) { _mouseover: function(evt) {
this._handleStageEvent(evt); this._handleStageEvent(evt);
}, },
_onmouseout: function(evt) { _mouseout: function(evt) {
// if there's a current target shape, run mouseout handlers // if there's a current target shape, run mouseout handlers
var targetShape = this.targetShape; var targetShape = this.targetShape;
if(targetShape) { if(targetShape) {
@ -627,8 +627,11 @@ else if(!isDragging && this.touchMove) {
this.targetShape = undefined; this.targetShape = undefined;
} }
this.mousePos = undefined; this.mousePos = undefined;
// end drag and drop
this._endDrag(evt);
}, },
_onmousemove: function(evt) { _mousemove: function(evt) {
//throttle mousemove //throttle mousemove
var throttle = this.attrs.throttle; var throttle = this.attrs.throttle;
var date = new Date(); var date = new Date();
@ -641,8 +644,11 @@ else if(!isDragging && this.touchMove) {
this.mouseUp = false; this.mouseUp = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
} }
// start drag and drop
this._startDrag(evt);
}, },
_onmousedown: function(evt) { _mousedown: function(evt) {
this.mouseDown = true; this.mouseDown = true;
this.mouseUp = false; this.mouseUp = false;
this.mouseMove = false; this.mouseMove = false;
@ -653,14 +659,17 @@ else if(!isDragging && this.touchMove) {
this._initDrag(); this._initDrag();
} }
}, },
_onmouseup: function(evt) { _mouseup: function(evt) {
this.mouseDown = false; this.mouseDown = false;
this.mouseUp = true; this.mouseUp = true;
this.mouseMove = false; this.mouseMove = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
this.clickStart = false; this.clickStart = false;
// end drag and drop
this._endDrag(evt);
}, },
_ontouchstart: function(evt) { _touchstart: function(evt) {
evt.preventDefault(); evt.preventDefault();
this.touchStart = true; this.touchStart = true;
this.touchEnd = false; this.touchEnd = false;
@ -673,14 +682,17 @@ else if(!isDragging && this.touchMove) {
this._initDrag(); this._initDrag();
} }
}, },
_ontouchend: function(evt) { _touchend: function(evt) {
this.touchStart = false; this.touchStart = false;
this.touchEnd = true; this.touchEnd = true;
this.touchMove = false; this.touchMove = false;
this._handleStageEvent(evt); this._handleStageEvent(evt);
this.tapStart = false; this.tapStart = false;
// end drag and drop
this._endDrag(evt);
}, },
_ontouchmove: function(evt) { _touchmove: function(evt) {
//throttle touchmove //throttle touchmove
var that = this; var that = this;
var throttle = this.attrs.throttle; var throttle = this.attrs.throttle;
@ -704,6 +716,9 @@ else if(!isDragging && this.touchMove) {
that._handleStageEvent(evt); that._handleStageEvent(evt);
}, 5); }, 5);
} }
// start drag and drop
this._startDrag(evt);
}, },
/** /**
* set mouse positon for desktop apps * set mouse positon for desktop apps
@ -788,80 +803,73 @@ else if(!isDragging && this.touchMove) {
go.drag.node = undefined; go.drag.node = undefined;
}, },
/** /**
* prepare drag and drop * start drag and drop
*/ */
_prepareDrag: function() { _startDrag: function(evt) {
var that = this; var that = this;
var go = Kinetic.GlobalObject;
var node = go.drag.node;
this._onContent('mousemove touchmove', function(evt) { if(node) {
var go = Kinetic.GlobalObject; var pos = that.getUserPosition();
var node = go.drag.node; var dc = node.attrs.dragConstraint;
var db = node.attrs.dragBounds;
var lastNodePos = {
x: node.attrs.x,
y: node.attrs.y
};
if(node) { // default
var pos = that.getUserPosition(); var newNodePos = {
var dc = node.attrs.dragConstraint; x: pos.x - go.drag.offset.x,
var db = node.attrs.dragBounds; y: pos.y - go.drag.offset.y
var lastNodePos = { };
x: node.attrs.x,
y: node.attrs.y
};
// default // bounds overrides
var newNodePos = { if(db.left !== undefined && newNodePos.x < db.left) {
x: pos.x - go.drag.offset.x, newNodePos.x = db.left;
y: pos.y - go.drag.offset.y }
}; if(db.right !== undefined && newNodePos.x > db.right) {
newNodePos.x = db.right;
// bounds overrides }
if(db.left !== undefined && newNodePos.x < db.left) { if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.x = db.left; newNodePos.y = db.top;
} }
if(db.right !== undefined && newNodePos.x > db.right) { if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.x = db.right; newNodePos.y = db.bottom;
}
if(db.top !== undefined && newNodePos.y < db.top) {
newNodePos.y = db.top;
}
if(db.bottom !== undefined && newNodePos.y > db.bottom) {
newNodePos.y = db.bottom;
}
node.setAbsolutePosition(newNodePos);
// constraint overrides
if(dc === 'horizontal') {
node.attrs.y = lastNodePos.y;
}
else if(dc === 'vertical') {
node.attrs.x = lastNodePos.x;
}
/*
* if dragging and dropping the stage,
* draw all of the layers
*/
if(go.drag.node.nodeType === 'Stage') {
go.drag.node.draw();
}
else {
go.drag.node.getLayer().draw();
}
if(!go.drag.moving) {
go.drag.moving = true;
// execute dragstart events if defined
go.drag.node._handleEvent('dragstart', evt);
}
// execute user defined ondragmove if defined
go.drag.node._handleEvent('dragmove', evt);
} }
}, false);
this._onContent('mouseup touchend mouseout', function(evt) { node.setAbsolutePosition(newNodePos);
that._endDrag(evt);
}); // constraint overrides
if(dc === 'horizontal') {
node.attrs.y = lastNodePos.y;
}
else if(dc === 'vertical') {
node.attrs.x = lastNodePos.x;
}
/*
* if dragging and dropping the stage,
* draw all of the layers
*/
if(go.drag.node.nodeType === 'Stage') {
go.drag.node.draw();
}
else {
go.drag.node.getLayer().draw();
}
if(!go.drag.moving) {
go.drag.moving = true;
// execute dragstart events if defined
go.drag.node._handleEvent('dragstart', evt);
}
// execute user defined ondragmove if defined
go.drag.node._handleEvent('dragmove', evt);
}
}, },
/** /**
* build dom * build dom

View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css"href="../base.css">
<script src="../../dist/kinetic-core.js"></script>
<script src="../js/Test.js"></script>
<script src="../js/manualTests.js"></script>
<script>
window.onload = function() {
var test = new Test();
test.run();
};
</script>
</head>
<body onmousedown="return false;"></body>
</html>

File diff suppressed because it is too large Load Diff

2063
tests/js/manualTests.js Normal file

File diff suppressed because it is too large Load Diff