I. E. Smith-Heisters
2008-Mar-14 20:55 UTC
scriptaculous unittest.js asynchronous improvement
Hi all, I just wanted to share a little improvement I just made to scriptaculous''s unittest.js, and get some feedback on further improvements in this vein. Currently, the best way unittest.js has of dealing with testing asynchronous functions is wait(). This is highly problematic because usually your tests end up waiting longer than necessary, and then sometimes your server takes too long to respond and your tests fail. If your async stuff is setup mostly, you can run it before creating the new test runner, and then create the new test runner using the async function''s callback if it has one. I''ve got a project where that works: Views.Store.update(function(){ new Test.Unit.Runner({ setup: function(){ }, teardown: function(){ }, testSidsHaveClickActions: function(){ with(this){ // test stuff }); }} }, {testlog: "testlog"}); }); This, however, doesn''t work out of the box because unittest.js uses Event.observe(window, ''load''...) to bring up the test, so if the callback is executed after window load, your SOL. Since I''m using Lowpro, it was easy to circumvent that by using Mr. Webb''s slightly different Event.onReady, which is a hook to Prototype''s new dom:loaded, with the difference that it will execute immediately if dom:loaded has already been fired. unittest.js: Test.Unit.Runner = Class.create({ initialize: function(testcases) { var options = this.options = Object.extend({ testLog: ''testlog'' }, arguments[1] || {}); options.resultsURL = this.queryParams.resultsURL; options.testLog = $(options.testLog); this.tests = this.getTests(testcases); this.currentTest = 0; this.logger = new Test.Unit.Logger(options.testLog); Event.onReady(function() { // Ensures the event fires even if onReady already happened. Requires lowpro. this.runTests.bind(this).delay(0.1); }.bind(this)); }, so that makes my life a little easier, and I thought someone else might find it useful. It''d be easy to rewrite it so it doesn''t require lowpro. Next, I''d like to rework wait() so that it can wait for an event or something so that you don''t end up having to wait longer than necessary. It''d also be handy in order to benchmark your async functions. Does anyone have tips for me going into this? I haven''t much started to look at it yet. Cheers, Ian --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Ian Smith-Heisters
2008-Mar-18 18:27 UTC
Re: scriptaculous unittest.js asynchronous improvement
So judging by the lack of response there''s not much interest in this, but I thought I''d just share my solution to the second problem in case someone is looking for this later. from http://0x09.com/content/testing-asynchronous-functions-with-scriptaculous-unittest-js testAsynchronousFunction: function(){ with(this){ var output = null; asyncFunc(function(transport){output = transport; continueTest()}); waitToFinish(function(){ assertNotNull(output); }); }} Here''s the patch: Index: unittest.js ==================================================================--- unittest.js (revision 6610) +++ unittest.js (working copy) @@ -211,10 +211,14 @@ if (!test) return this.finish(); if (!test.isWaiting) this.logger.start(test.name); test.run(); - if(test.isWaiting) { + if(test.isWaiting && this.timeToWait) { this.logger.message("Waiting for " + test.timeToWait + "ms"); setTimeout(this.runTests.bind(this), test.timeToWait || 1000); return; + } else if (test.isWaiting){ + this.logger.message("Waiting for continue event."); + document.observe(''unittest:continue'', this.runTests.bind(this)) + return; } this.logger.finish(test.status(), test.summary()); @@ -466,6 +470,16 @@ this.test = nextPart; this.timeToWait = time; }, + + waitToFinish: function(nextPart){ + this.isWaiting = true; + this.test = nextPart; + this.timeToWait = null; + }, + + continueTest: function(){ + document.fire(''unittest:continue''); + }, run: function(rethrow) { try { On Fri, Mar 14, 2008 at 1:55 PM, I. E. Smith-Heisters <i@0x09.com> wrote:> Hi all, > > I just wanted to share a little improvement I just made to > scriptaculous''s unittest.js, and get some feedback on further > improvements in this vein. > > Currently, the best way unittest.js has of dealing with testing > asynchronous functions is wait(). This is highly problematic because > usually your tests end up waiting longer than necessary, and then > sometimes your server takes too long to respond and your tests fail. > > If your async stuff is setup mostly, you can run it before creating > the new test runner, and then create the new test runner using the > async function''s callback if it has one. I''ve got a project where that > works: > > Views.Store.update(function(){ > new Test.Unit.Runner({ > setup: function(){ > }, > > teardown: function(){ > }, > > testSidsHaveClickActions: function(){ with(this){ > // test stuff > }); > }} > }, {testlog: "testlog"}); > }); > > This, however, doesn''t work out of the box because unittest.js uses > Event.observe(window, ''load''...) to bring up the test, so if the > callback is executed after window load, your SOL. Since I''m using > Lowpro, it was easy to circumvent that by using Mr. Webb''s slightly > different Event.onReady, which is a hook to Prototype''s new > dom:loaded, with the difference that it will execute immediately if > dom:loaded has already been fired. > > unittest.js: > > Test.Unit.Runner = Class.create({ > initialize: function(testcases) { > var options = this.options = Object.extend({ > testLog: ''testlog'' > }, arguments[1] || {}); > > options.resultsURL = this.queryParams.resultsURL; > options.testLog = $(options.testLog); > > this.tests = this.getTests(testcases); > this.currentTest = 0; > this.logger = new Test.Unit.Logger(options.testLog); > Event.onReady(function() { // Ensures the event fires even if > onReady already happened. Requires lowpro. > this.runTests.bind(this).delay(0.1); > }.bind(this)); > }, > > so that makes my life a little easier, and I thought someone else > might find it useful. It''d be easy to rewrite it so it doesn''t require > lowpro. > > Next, I''d like to rework wait() so that it can wait for an event or > something so that you don''t end up having to wait longer than > necessary. It''d also be handy in order to benchmark your async > functions. Does anyone have tips for me going into this? I haven''t > much started to look at it yet. > > Cheers, > Ian >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Ian Smith-Heisters
2008-Mar-18 19:37 UTC
Re: scriptaculous unittest.js asynchronous improvement
FYI, I updated it a little bit to support nesting, and a slightly different interface (wait(null) instead of waitToFinish()) On Tue, Mar 18, 2008 at 11:27 AM, Ian Smith-Heisters <i@0x09.com> wrote:> So judging by the lack of response there''s not much interest in this, > but I thought I''d just share my solution to the second problem in case > someone is looking for this later. > > from http://0x09.com/content/testing-asynchronous-functions-with-scriptaculous-unittest-js > > testAsynchronousFunction: function(){ with(this){ > var output = null; > asyncFunc(function(transport){output = transport; continueTest()}); > waitToFinish(function(){ > assertNotNull(output); > }); > }} > > Here''s the patch: > > Index: unittest.js > ==================================================================> --- unittest.js (revision 6610) > +++ unittest.js (working copy) > @@ -211,10 +211,14 @@ > if (!test) return this.finish(); > if (!test.isWaiting) this.logger.start(test.name); > test.run(); > - if(test.isWaiting) { > + if(test.isWaiting && this.timeToWait) { > this.logger.message("Waiting for " + test.timeToWait + "ms"); > setTimeout(this.runTests.bind(this), test.timeToWait || 1000); > return; > + } else if (test.isWaiting){ > + this.logger.message("Waiting for continue event."); > + document.observe(''unittest:continue'', this.runTests.bind(this)) > + return; > } > > this.logger.finish(test.status(), test.summary()); > @@ -466,6 +470,16 @@ > this.test = nextPart; > this.timeToWait = time; > }, > + > + waitToFinish: function(nextPart){ > + this.isWaiting = true; > + this.test = nextPart; > + this.timeToWait = null; > + }, > + > + continueTest: function(){ > + document.fire(''unittest:continue''); > + }, > > run: function(rethrow) { > try { > > > > > On Fri, Mar 14, 2008 at 1:55 PM, I. E. Smith-Heisters <i@0x09.com> wrote: > > Hi all, > > > > I just wanted to share a little improvement I just made to > > scriptaculous''s unittest.js, and get some feedback on further > > improvements in this vein. > > > > Currently, the best way unittest.js has of dealing with testing > > asynchronous functions is wait(). This is highly problematic because > > usually your tests end up waiting longer than necessary, and then > > sometimes your server takes too long to respond and your tests fail. > > > > If your async stuff is setup mostly, you can run it before creating > > the new test runner, and then create the new test runner using the > > async function''s callback if it has one. I''ve got a project where that > > works: > > > > Views.Store.update(function(){ > > new Test.Unit.Runner({ > > setup: function(){ > > }, > > > > teardown: function(){ > > }, > > > > testSidsHaveClickActions: function(){ with(this){ > > // test stuff > > }); > > }} > > }, {testlog: "testlog"}); > > }); > > > > This, however, doesn''t work out of the box because unittest.js uses > > Event.observe(window, ''load''...) to bring up the test, so if the > > callback is executed after window load, your SOL. Since I''m using > > Lowpro, it was easy to circumvent that by using Mr. Webb''s slightly > > different Event.onReady, which is a hook to Prototype''s new > > dom:loaded, with the difference that it will execute immediately if > > dom:loaded has already been fired. > > > > unittest.js: > > > > Test.Unit.Runner = Class.create({ > > initialize: function(testcases) { > > var options = this.options = Object.extend({ > > testLog: ''testlog'' > > }, arguments[1] || {}); > > > > options.resultsURL = this.queryParams.resultsURL; > > options.testLog = $(options.testLog); > > > > this.tests = this.getTests(testcases); > > this.currentTest = 0; > > this.logger = new Test.Unit.Logger(options.testLog); > > Event.onReady(function() { // Ensures the event fires even if > > onReady already happened. Requires lowpro. > > this.runTests.bind(this).delay(0.1); > > }.bind(this)); > > }, > > > > so that makes my life a little easier, and I thought someone else > > might find it useful. It''d be easy to rewrite it so it doesn''t require > > lowpro. > > > > Next, I''d like to rework wait() so that it can wait for an event or > > something so that you don''t end up having to wait longer than > > necessary. It''d also be handy in order to benchmark your async > > functions. Does anyone have tips for me going into this? I haven''t > > much started to look at it yet. > > > > Cheers, > > Ian > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---