From f7400eb338f8139e16eac7eacc59cce22530f962 Mon Sep 17 00:00:00 2001 From: Ant Cunningham Date: Sun, 22 Mar 2015 12:42:30 -0400 Subject: [PATCH] Updated step signature to pass state, ProgressBar, and attachment in that order; Updated tests to support and verify new signature; Renamed test case *-behaviour.js files to be more semantic now that we are testing both Path and Shape APIs; Altered glob pattern for tesetem js files so it would not pick up compiled browserify file and create an infinite loop; Updated documentation with API changes. --- README.md | 37 ++++++++++--------- src/path.js | 4 +- src/shape.js | 3 +- test/{path-behavior.js => path-behaviour.js} | 30 +++++++++++---- ...shared-behaviour.js => shape-behaviour.js} | 26 +++++++++++++ test/test-all.js | 25 ++++++++++--- testem.json | 2 +- 7 files changed, 92 insertions(+), 35 deletions(-) rename test/{path-behavior.js => path-behaviour.js} (84%) rename test/{shared-behaviour.js => shape-behaviour.js} (82%) diff --git a/README.md b/README.md index 4d9e5e6..e1a5331 100644 --- a/README.md +++ b/README.md @@ -233,11 +233,11 @@ with CSS. easing: "easeOut", // See #custom-animations section - // Built-in shape passes reference to itself as attachment - // to step function + // Built-in shape passes reference to itself and a custom attachment + // object to step function from: { color: '#eee' }, to: { color: '#000' }, - step: function(state, square) { + step: function(state, square, attachment) { square.path.setAttribute('stroke', state.color); } } @@ -291,11 +291,11 @@ progressBar.animate(0.3, { easing: "easeInOut", // See #custom-animations section - // Built-in shape passes reference to itself as attachment - // to step function + // Built-in shape passes reference to itself and a custom attachment + // object to step function from: { color: '#eee' }, to: { color: '#000' }, - step: function(state, square) { + step: function(state, square, attachment) { square.path.setAttribute('stroke', state.color); } } @@ -395,8 +395,8 @@ var path = new ProgressBar.Path(heartObject.contentDocument.querySelector('#hear // See #custom-animations section from: { color: '#eee' }, to: { color: '#000' }, - step: function(state, attachment) { - // Do any modifications to attachment attributes + step: function(state, path, attachment) { + // Do any modifications to attachment and/or path attributes } } ``` @@ -439,8 +439,8 @@ path.animate(0.3, { // See #custom-animations section from: { color: '#eee' }, to: { color: '#000' }, - step: function(state, attachment) { - // Do any modifications to attachment attributes + step: function(state, path, attachment) { + // Do any modifications to attachment and/or path attributes } } ``` @@ -515,7 +515,7 @@ Tweening engine changes defined values over time and calls step function for eac *Signature must match `from`* -* `step` Function called for each animation step. Tweened values and reference to attachment are passed as parameters. Attachment can be reference to any object you need to modify within step function. Built-in shapes pass references to their selves as attachment. Default: `function() {}`. +* `step` Function called for each animation step. Tweened values, a reference to the path or shape, and an attachment are passed as parameters. Attachment can be reference to any object you need to modify within step function. Default: `function() {}`. **This function is called multiple times per second. To make sure animations run smoothly, keep it minimal.** @@ -523,9 +523,10 @@ Tweening engine changes defined values over time and calls step function for eac For example ```javascript - function(state, attachment) { - attachment.path.setAttribute('stroke-width', state.width); - attachment.path.setAttribute('stroke', state.color); + function(state, shape, attachment) { + shape.path.setAttribute('stroke-width', state.width); + shape.path.setAttribute('stroke', state.color); + attachment.text.innerHTML = shape.value()*100; } ``` @@ -538,8 +539,8 @@ of progress bar compared to passing in `.animate()` call. Here's example code an var bar = new ProgressBar.Line('#container', { from: { color: '#000 '}, to: { color: '#888 '}, - step: function(state, bar) { - bar.setAttribute('stroke', state.color); + step: function(state, bar, attachment) { + bar.path.setAttribute('stroke', state.color); } }); ``` @@ -551,8 +552,8 @@ var bar = new ProgressBar.Line('#container', { ```javascript var bar = new ProgressBar.Line('#container', { - step: function(state, bar) { - bar.setAttribute('stroke', state.color); + step: function(state, bar, attachment) { + bar.path.setAttribute('stroke', state.color); } }); diff --git a/src/path.js b/src/path.js index 82fba9d..4521c66 100644 --- a/src/path.js +++ b/src/path.js @@ -49,7 +49,7 @@ Path.prototype.set = function set(progress) { if (utils.isFunction(step)) { var easing = this._easing(this._opts.easing); var values = this._calculateTo(progress, easing); - step(values, this._opts.attachment || this); + step(values, this._opts.shape||this, this._opts.attachment); } }; @@ -95,7 +95,7 @@ Path.prototype.animate = function animate(progress, opts, cb) { easing: shiftyEasing, step: function(state) { self._path.style.strokeDashoffset = state.offset; - opts.step(state, opts.attachment, self); + opts.step(state, opts.shape||self, opts.attachment); }, finish: function(state) { if (utils.isFunction(cb)) { diff --git a/src/shape.js b/src/shape.js index a01a405..81219d2 100644 --- a/src/shape.js +++ b/src/shape.js @@ -65,7 +65,8 @@ var Shape = function Shape(container, opts) { // this.text is also a public attribute var newOpts = utils.extend({ - attachment: this + attachment: undefined, + shape: this }, this._opts); this._progressPath = new Path(svgView.path, newOpts); }; diff --git a/test/path-behavior.js b/test/path-behaviour.js similarity index 84% rename from test/path-behavior.js rename to test/path-behaviour.js index e3134bd..da46fdd 100644 --- a/test/path-behavior.js +++ b/test/path-behaviour.js @@ -21,7 +21,7 @@ var barOpts = { duration: 800, from: {strokeOffset: 0}, to: { strokeOffset: 0 }, - step: function (state, attachment, self) { + step: function (state, self, attachment) { attachment.setAttribute(ANIM_PROP.scriptName, state[ANIM_PROP.scriptName]); } }; @@ -67,7 +67,7 @@ var destroyPath = function () { container.removeChild(svg); container.innerHTML = ''; -} +}; var afterEachCase = function() { try { @@ -80,22 +80,38 @@ var afterEachCase = function() { var pathTests = function pathTests () { - it('should pass a reference to ProgressBar.Path instance to step', function () { + it('step function should recieve a reference to ProgressBar as argument #2', function () { this.bar.animate(1, {duration: 500}); - // we only care about the third arg, for each call so we need to manually + // we only care about the second arg, for each call so we need to manually // inspect them since we dont know what state would look like var ok = true; for (var i =0; i < this.step.args.length; i++) { - if (this.step.args[i][2] !== this.bar) { + if (this.step.args[i][1] !== this.bar) { ok = false; } } - expect(ok).to.be.true; + expect(ok).to.be.true(); }); + it('step function should recieve a reference to ProgressBar as argument #3', function () { + this.bar.animate(1, {duration: 500}); + + // we only care about the third arg, for each call so we need to manually + // inspect them since we dont know what state would look like + var ok = true; + + for (var i =0; i < this.step.args.length; i++) { + if (this.step.args[i][2] !== this.attachment) { + ok = false; + } + } + + expect(ok).to.be.true(); + }); + it('set should change value', function() { this.bar.set(1); expect(this.bar.value()).to.almost.equal(1, PRECISION); @@ -144,7 +160,7 @@ var pathTests = function pathTests () { done(); }, 400); }); -} +}; module.exports = { options: barOpts, diff --git a/test/shared-behaviour.js b/test/shape-behaviour.js similarity index 82% rename from test/shared-behaviour.js rename to test/shape-behaviour.js index 0077a76..5493944 100644 --- a/test/shared-behaviour.js +++ b/test/shape-behaviour.js @@ -65,6 +65,32 @@ var sharedTests = function sharedTests() { }, 1200); }); + it('step function should recieve a reference to ProgressBar as argument #2', function () { + this.bar.animate(1, {duration: 600}); + var allCallsHaveBar = true; + + for (var i =0; i < this.step.args.length; i++) { + if (this.step.args[i][1] !== this.bar) { + allCallsHaveBar = false; + } + } + + expect(allCallsHaveBar).to.be.true(); + }); + + it('step function should recieve a reference to attachment as argument #3', function () { + this.bar.animate(1, {duration: 600}); + var allCallsHaveAttachment = true; + + for (var i =0; i < this.step.args.length; i++) { + if (this.step.args[i][2] !== this.attachment) { + allCallsHaveAttachment = false; + } + } + + expect(allCallsHaveAttachment).to.be.true(); + }); + it('stop() should stop animation', function(done) { var offset = testUtils.getComputedStyle(this.bar.path, 'stroke-dashoffset'); this.bar.animate(1, {duration: 1000}); diff --git a/test/test-all.js b/test/test-all.js index b90b198..de400bb 100644 --- a/test/test-all.js +++ b/test/test-all.js @@ -10,8 +10,8 @@ var sinon = require('sinon'); var expect = chai.expect; // https://github.com/mochajs/mocha/wiki/Shared-Behaviours -var sharedTests = require('./shared-behaviour'); -var pathTests = require('./path-behavior'); +var shapeTests = require('./shape-behaviour'); +var pathTests = require('./path-behaviour'); var ProgressBar = require("../src/main"); var utils = require('../src/utils'); @@ -27,39 +27,51 @@ var afterEachCase = function() { var barOpts = { text: { value: 'Test' }, - trailWidth: 1 + trailWidth: 1, + attachment: {"foo": "bar"} }; describe('Line', function() { beforeEach(function() { // Append progress bar to body since adding a custom HTML and div // with Karma was not that trivial compared to Testem + barOpts.step = function (state, bar, attachment) {}; this.bar = new ProgressBar.Line('body', barOpts); + this.attachment = this.bar._opts.attachment; + this.step = sinon.spy(this.bar._opts, 'step'); + }); afterEach(afterEachCase); - sharedTests(); + shapeTests(); }); describe('Circle', function() { beforeEach(function() { + barOpts.step = function (state, bar, attachment) {}; this.bar = new ProgressBar.Circle('body', barOpts); + this.attachment = this.bar._opts.attachment; + this.step = sinon.spy(this.bar._opts, 'step'); + }); afterEach(afterEachCase); - sharedTests(); + shapeTests(); }); describe('Square', function() { beforeEach(function() { + barOpts.step = function (state, bar, attachment) {}; this.bar = new ProgressBar.Square('body', barOpts); + this.attachment = this.bar._opts.attachment; + this.step = sinon.spy(this.bar._opts, 'step'); }); afterEach(afterEachCase); - sharedTests(); + shapeTests(); }); describe('Path', function () { @@ -70,6 +82,7 @@ describe('Path', function () { pathTests.options.attachment = this.path; this.bar = new ProgressBar.Path(this.path, pathTests.options); + this.attachment = this.bar._opts.attachment; this.step = sinon.spy(this.bar._opts, 'step'); }); diff --git a/testem.json b/testem.json index a638cf2..405888e 100644 --- a/testem.json +++ b/testem.json @@ -1,7 +1,7 @@ { "framework": "mocha", "src_files": [ - "test/*.js" + "test/test-*.js" ], "test_page": "test/testem.html", "routes": {