<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xaprb &#187; unit testing</title>
	<atom:link href="http://www.xaprb.com/blog/tag/unit-testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xaprb.com/blog</link>
	<description>Stay curious!</description>
	<lastBuildDate>Thu, 09 Feb 2012 03:58:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Apsersa&#8217;s summary tool supports Adaptec and MegaRAID controllers</title>
		<link>http://www.xaprb.com/blog/2010/05/16/apsersas-summary-tool-supports-adaptec-and-megaraid-controllers/</link>
		<comments>http://www.xaprb.com/blog/2010/05/16/apsersas-summary-tool-supports-adaptec-and-megaraid-controllers/#comments</comments>
		<pubDate>Sun, 16 May 2010 18:51:17 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[Aspersa]]></category>
		<category><![CDATA[Maatkit]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Adaptec]]></category>
		<category><![CDATA[LSI Megaraid]]></category>
		<category><![CDATA[RAID]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/?p=1855</guid>
		<description><![CDATA[I spent a little time yesterday doing some things with the &#8220;summary&#8221; tool from Aspersa. I added support for summarizing status and configuration of Adaptec and LSI MegaRAID controllers. I also figured out how to write a test suite for Bash scripts, so most major parts of the tool are fully tested now. I learned [...]


<strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2010/07/10/aspersas-mysql-summary-tool/' rel='bookmark' title='Permanent Link: Aspersa&#8217;s mysql-summary tool'>Aspersa&#8217;s mysql-summary tool</a></li>
<li><a href='http://www.xaprb.com/blog/2010/02/20/mk-query-digest-now-supports-postgres-logs/' rel='bookmark' title='Permanent Link: mk-query-digest now supports Postgres logs'>mk-query-digest now supports Postgres logs</a></li>
<li><a href='http://www.xaprb.com/blog/2011/05/10/new-maatkit-tool-mk-table-usage/' rel='bookmark' title='Permanent Link: New Maatkit tool: mk-table-usage'>New Maatkit tool: mk-table-usage</a></li>
<li><a href='http://www.xaprb.com/blog/2007/11/06/mysql-heartbeat-supports-postgresql/' rel='bookmark' title='Permanent Link: MySQL Heartbeat supports PostgreSQL'>MySQL Heartbeat supports PostgreSQL</a></li>
<li><a href='http://www.xaprb.com/blog/2010/05/10/new-maatkit-tool-to-compute-index-usage/' rel='bookmark' title='Permanent Link: New Maatkit tool to compute index usage'>New Maatkit tool to compute index usage</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>I spent a little time yesterday doing some things with the &#8220;summary&#8221; tool from <a href="http://code.google.com/p/aspersa">Aspersa</a>.  I added support for summarizing status and configuration of Adaptec and LSI MegaRAID controllers.  I also figured out how to write a test suite for Bash scripts, so most major parts of the tool are fully tested now.  I learned a lot more sed and awk this weekend.</p>

<p>There is really only one way to get status of Adaptec controllers (/usr/StorMan/arcconf), but the LSI controllers can be queried through multiple tools.  I added support for MegaCli64, as long as it&#8217;s located in the usual place at /opt/MegaRAID/MegaCli/MegaCli64.  I am looking for feedback and/or help on supporting other methods of getting status from the LSI controllers, such as megarc and omreport.  If you can contribute sample output from these tools, please attach them as a file to a new issue report on the project&#8217;s issue tracker.  (Don&#8217;t paste them as text, please &#8212; formatting and whitespace will get mangled.  Tabs and spaces need to be preserved.)</p>

<p>I am slowly gaining insight into how best to write a similar summary tool for MySQL servers.  The goals of this tool are very specific &#8212; including things like diff&#8217;able output.  I&#8217;m figuring out what went wrong with Maatkit&#8217;s mk-audit tool and how to go about it differently.</p>

<p><strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2010/07/10/aspersas-mysql-summary-tool/' rel='bookmark' title='Permanent Link: Aspersa&#8217;s mysql-summary tool'>Aspersa&#8217;s mysql-summary tool</a></li>
<li><a href='http://www.xaprb.com/blog/2010/02/20/mk-query-digest-now-supports-postgres-logs/' rel='bookmark' title='Permanent Link: mk-query-digest now supports Postgres logs'>mk-query-digest now supports Postgres logs</a></li>
<li><a href='http://www.xaprb.com/blog/2011/05/10/new-maatkit-tool-mk-table-usage/' rel='bookmark' title='Permanent Link: New Maatkit tool: mk-table-usage'>New Maatkit tool: mk-table-usage</a></li>
<li><a href='http://www.xaprb.com/blog/2007/11/06/mysql-heartbeat-supports-postgresql/' rel='bookmark' title='Permanent Link: MySQL Heartbeat supports PostgreSQL'>MySQL Heartbeat supports PostgreSQL</a></li>
<li><a href='http://www.xaprb.com/blog/2010/05/10/new-maatkit-tool-to-compute-index-usage/' rel='bookmark' title='Permanent Link: New Maatkit tool to compute index usage'>New Maatkit tool to compute index usage</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2010/05/16/apsersas-summary-tool-supports-adaptec-and-megaraid-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to unit-test code that interacts with a database</title>
		<link>http://www.xaprb.com/blog/2008/08/19/how-to-unit-test-code-that-interacts-with-a-database/</link>
		<comments>http://www.xaprb.com/blog/2008/08/19/how-to-unit-test-code-that-interacts-with-a-database/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 00:47:34 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[testing a database]]></category>
		<category><![CDATA[The Rimm Kaufman Group]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/2008/08/19/how-to-unit-test-code-that-interacts-with-a-database/</guid>
		<description><![CDATA[I got some interesting comments on my previous article about unit testing Maatkit, including echoes of my own conversion to the unit-testing religion. One of the objections I&#8217;ve heard a lot about unit-testing is how it&#8217;s impossible to test code that talks to a database. &#8220;It&#8217;s too hard,&#8221; they say. &#8220;Oh, it&#8217;s easy to test [...]


<strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2006/05/16/how-to-refactor-without-rewriting-unit-tests/' rel='bookmark' title='Permanent Link: How to write unit tests for ease of refactoring'>How to write unit tests for ease of refactoring</a></li>
<li><a href='http://www.xaprb.com/blog/2008/08/18/how-maatkit-benefits-from-test-driven-development/' rel='bookmark' title='Permanent Link: How Maatkit benefits from test-driven development'>How Maatkit benefits from test-driven development</a></li>
<li><a href='http://www.xaprb.com/blog/2009/05/03/a-productivity-tip-for-test-driven-development/' rel='bookmark' title='Permanent Link: A productivity tip for test-driven development'>A productivity tip for test-driven development</a></li>
<li><a href='http://www.xaprb.com/blog/2011/11/07/when-documentation-is-code/' rel='bookmark' title='Permanent Link: When documentation is code'>When documentation is code</a></li>
<li><a href='http://www.xaprb.com/blog/2007/08/24/google-test-automation-conference-day-1/' rel='bookmark' title='Permanent Link: Google Test Automation Conference, Day 1'>Google Test Automation Conference, Day 1</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>I got some interesting comments on my previous article about <a href="http://www.xaprb.com/blog/2008/08/18/how-maatkit-benefits-from-test-driven-development/">unit testing Maatkit</a>, including echoes of my own conversion to the unit-testing religion.  One of the objections I&#8217;ve heard a lot about unit-testing is how it&#8217;s impossible to test code that talks to a database.  &#8220;It&#8217;s too hard,&#8221; they say.  &#8220;Oh, it&#8217;s easy to test a module that calculates a square root, but a database?  Way too much work!&#8221;</p>

<span id="more-556"></span>

<p><strong>Note:</strong> As commenters have pointed out, I&#8217;m not necessarily using &#8220;unit&#8221; in the agreed-upon way here.  Everything I say can be applied to ultra-pure unit testing too, but I go beyond that.  I will hold fast to my assertions about mocking though *grin*</p>

<h3>Is it really impossible or even hard?</h3>

<p>I disagree.  In one of my previous articles I said <a href="http://www.rimmkaufman.com/rkgblog/">The Rimm-Kaufman Group</a>, my previous employer, has a comprehensive unit-test suite.  When I say comprehensive I mean it: database interaction is fully tested, too.  I know because I was heavily involved in building it.  Even extremely complex things like big reports that are generated from lots of data are tested.  And believe me, sharding the databases would have been much harder without complete code coverage.  It&#8217;s really not that complicated to unit-test against a database, and it&#8217;s so worth it.  Here are some hints about how you can do this.</p>

<p>There are many ways to do it, but I&#8217;ll just describe the basics of the system I helped build.  There are several moving parts to the test suite (&#8220;<a href="http://c2.com/cgi/wiki?SmokeTest">smoke</a>&#8220;), but one of them sets a magical environment variable.  And then, all code that connects to a database server magically gets back a different database connection from the create_me_a_connection() function.  This is because there is a database connection abstraction library that respects the environment variable.  It&#8217;s really pretty simple for the most part; instead of doing DBI->connect(&#8230;) you just call this function, which is a thin wrapper that hands back a connection object.</p>

<p>This wrapper is itself unit-tested thoroughly, too.  This ensures that when some code is being run from a test, it cannot (I mean cannot!) connect to a production database, and vice versa.  There are some conventions about production and test servers that make sure the abstraction library can tell for sure.  If there&#8217;s any confusion, of course, it will die in a non-recoverable way.  Safety first.</p>

<h3>Building a good development environment</h3>

<p>Just as each developer has their own copy of the code from version control, each developer has their own private database server running on the dev machine.  There are some simple conventions that make this possible: Unix user ID plus a constant for the port number, etc.  It&#8217;s really quite easy.  The private database server is a slightly modified version of <a href="https://launchpad.net/mysql-sandbox">Giuseppe Maxia&#8217;s MySQL Sandbox tool</a>.  It can be torn down and set up afresh as desired.  It is wiped clean and re-filled at the start of every test, with a small, tightly focused dataset carefully chosen to represent the conditions the code is supposed to work with.  (Each test has its own dataset).</p>

<p>If this sounds like a system that can&#8217;t work on a large scale, well, it does.  That&#8217;s the secret sauce that I won&#8217;t reveal in this post.  (It&#8217;s my past employer after all, and I can&#8217;t go revealing everything about them can I?)  You just have to be smart about it.  When a database is central to your business, you either figure out how to get this right, or you pay the consequences in lost time and poor code quality.</p>

<p>I and the other developers there (another secret: it&#8217;s a small team; <a href="http://www.craigslist.org/">small teams build great things</a>) built several quick utilities to help develop unit tests against a database.  There are utilities to get a minimal necessary dataset for testing and dump it into a file that can be loaded by the test.  There are utilities that can migrate schemas and update the tests to match the schema changes.  And so on, and so on.  This is possible because of careful planning for testability, and really smart things like super-consistent and sensible naming conventions for database objects.  (Ruby On Rails owes a lot of its success to simple things like this, too.  Conventions are really powerful.)  Maybe I&#8217;ll write about the database naming conventions some other time &#8212; I have to credit Alan Rimm-Kaufman a lot for designing those conventions.  It was a stroke of genius.</p>

<h3>Things to avoid</h3>

<p>There are several things I <em>do not</em> recommend doing when you unit-test code that talks to a database.  I&#8217;ll just mention a couple:</p>

<ul
<li>Don&#8217;t <a href="http://c2.com/cgi/wiki?MockObject">mock</a> anything!  In general I think mocking is the devil.  Most of the mock objects I&#8217;ve ever seen reflected a propensity to <a href="http://www.xaprb.com/blog/2006/05/16/how-to-refactor-without-rewriting-unit-tests/">test an implementation instead of a behavior</a>, which is also the devil.  Write all your code to test a test instance of something real, and do not mock up a database to test against.  It is a rabbit-hole that you will not emerge from easily.</li>
<li>Never let a test connect to a production database.  Never, ever.  Worlds of hurt will follow.  Not only are you risking your production data, but what about the risk to your code?  You&#8217;re testing against things that will almost certainly change and break your tests; and you&#8217;re possibly polluting your live data with testing data and/or changing live data from the tests.</li>
<li>I also recommend developing unit tests for your current database functionality if you&#8217;re thinking about changing it much.  <a href="http://dev.mysql.com/doc/en/server-sql-mode.html">Don&#8217;t like MySQL&#8217;s lax error handling?  Plan to set the SQL_MODE to something stricter?</a>  Dive into that database abstraction library and make your tests run in strict mode first by setting SQL_MODE on every new connection that&#8217;s created when running inside a test; fix all the breakage in the test suite; feel sure that your code isn&#8217;t going to break in production.  That was easy!</li>
</ul>

<h3>Summary</h3>

<p>Once your creative juices get flowing, you&#8217;ll see tons of places your unit test suite can help you out.</p>

<p>If you&#8217;re in the Oracle or SQL Server world, or any other world where you can&#8217;t just set up and discard database instances at will due to licensing problems, you&#8217;re going to have to be a little more inventive.  But you can still do it.  (Don&#8217;t you wish you&#8217;d chosen <a href="http://www.fsf.org/">Freedom</a>?)  And unit tests are just as beneficial for apps based on Oracle as they are for MySQL.</p>

<p>Have fun!  Go forth and test some more!</p>

<p><strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2006/05/16/how-to-refactor-without-rewriting-unit-tests/' rel='bookmark' title='Permanent Link: How to write unit tests for ease of refactoring'>How to write unit tests for ease of refactoring</a></li>
<li><a href='http://www.xaprb.com/blog/2008/08/18/how-maatkit-benefits-from-test-driven-development/' rel='bookmark' title='Permanent Link: How Maatkit benefits from test-driven development'>How Maatkit benefits from test-driven development</a></li>
<li><a href='http://www.xaprb.com/blog/2009/05/03/a-productivity-tip-for-test-driven-development/' rel='bookmark' title='Permanent Link: A productivity tip for test-driven development'>A productivity tip for test-driven development</a></li>
<li><a href='http://www.xaprb.com/blog/2011/11/07/when-documentation-is-code/' rel='bookmark' title='Permanent Link: When documentation is code'>When documentation is code</a></li>
<li><a href='http://www.xaprb.com/blog/2007/08/24/google-test-automation-conference-day-1/' rel='bookmark' title='Permanent Link: Google Test Automation Conference, Day 1'>Google Test Automation Conference, Day 1</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2008/08/19/how-to-unit-test-code-that-interacts-with-a-database/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Growth limits of open-source vis-a-vis MySQL Toolkit</title>
		<link>http://www.xaprb.com/blog/2007/11/05/growth-limits-of-open-source-vis-a-vis-mysql-toolkit/</link>
		<comments>http://www.xaprb.com/blog/2007/11/05/growth-limits-of-open-source-vis-a-vis-mysql-toolkit/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 14:50:02 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[Kurt Vonnegut]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Si Chen]]></category>
		<category><![CDATA[sourceforge]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[Zmanda]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/2007/11/05/growth-limits-of-open-source-vis-a-vis-mysql-toolkit/</guid>
		<description><![CDATA[<p><a href="http://opensourcestrategies.blogspot.com/2007/10/limits-of-open-source.html">Si Chen wrote recently about the growth limits of open-source projects</a>.  He points out that as a project becomes larger, it gets harder to maintain.  I can only agree.  As the <a href="http://mysqltoolkit.sourceforge.net">MySQL Toolkit</a> project has grown, it's become significantly more work to maintain, document, and enhance.</p>


<strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2008/12/23/does-mysql-really-have-an-open-source-business-model/' rel='bookmark' title='Permanent Link: Does MySQL really have an open-source business model?'>Does MySQL really have an open-source business model?</a></li>
<li><a href='http://www.xaprb.com/blog/2008/05/14/mysql-free-software-but-not-open-source/' rel='bookmark' title='Permanent Link: MySQL: Free Software but not Open Source'>MySQL: Free Software but not Open Source</a></li>
<li><a href='http://www.xaprb.com/blog/2009/03/08/making-maatkit-more-open-source-one-step-at-a-time/' rel='bookmark' title='Permanent Link: Making Maatkit more Open Source one step at a time'>Making Maatkit more Open Source one step at a time</a></li>
<li><a href='http://www.xaprb.com/blog/2009/04/29/what-does-an-open-source-sales-model-look-like/' rel='bookmark' title='Permanent Link: What does an open source sales model look like?'>What does an open source sales model look like?</a></li>
<li><a href='http://www.xaprb.com/blog/2011/07/04/measuring-open-source-success-by-jobs/' rel='bookmark' title='Permanent Link: Measuring open-source success by jobs'>Measuring open-source success by jobs</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p><a href="http://opensourcestrategies.blogspot.com/2007/10/limits-of-open-source.html">Si Chen wrote recently about the growth limits of open-source projects</a>.  He points out that as a project becomes larger, it gets harder to maintain.  I can only agree.  As the <a href="http://code.google.com/p/maatkit">MySQL Toolkit</a> project has grown, it&#8217;s become significantly more work to maintain, document, and enhance.  (This is why I&#8217;m asking you to <a href="http://www.xaprb.com/blog/2007/10/31/mysql-table-sync-bounty-lets-do-it/">sponsor me for a week off my regular job to work on MySQL Table Sync</a>, by the way.  Please toss some money in the hat.)</p>

<p>Rewriting code so it&#8217;s testable is a major focus for me now.  Some of these tools have gotten complicated enough that I can&#8217;t keep track of all the code.  In other words, they&#8217;re collapsing under their own weight.</p>

<p>Back in the project&#8217;s humble beginnings, it seemed adequate to just copy and paste a few lines here and there; after all, these are just scripts, right?  Right.  So I&#8217;ll just copy a few lines of code that do command-line option parsing and help screens.  Hey, it turns out that several of the tools can connect to more than one server, so simple -u, -h and -p options won&#8217;t do; so I invent a DSN-like notation that lets the tools connect to an arbitrary number of servers.  Copy and paste that code, too.  It&#8217;s only ten lines &#8212; no big deal.  Pretty soon I find out that many of the standard Perl modules aren&#8217;t available, for a lot of people.  And even when they&#8217;re available, people have old versions and can&#8217;t upgrade, so I can&#8217;t rely on basic things like the <code>quote_identifier()</code> function in DBI modules; time to write my own.  Well, that&#8217;s only a single line!  Surely that&#8217;s okay to copy and paste.</p>

<p>As Kurt Vonnegut says, &#8220;So it goes.&#8221;  This is the death not only of quality, but of maintainability and extensibility.  The Right Answer &#8482; is to write everything as modules, with proper test suites, and then make the scripts as minimalistic as possible &#8212; essentially gluing the modules together with a few lines of harder-to-test code.  That&#8217;s how I&#8217;m used to working, too, but for some reason I can&#8217;t explain, it seemed okay not to work that way with this project.  That has turned out to be a big mistake, which I&#8217;m slowly correcting out of necessity.</p>

<p>But it turns out it&#8217;s not that simple, either.  I&#8217;ve gotten a lot of emails, phone calls from friends, and bug reports about how hard it is to install or update Perl, or get a CPAN module, on many systems.  It turns out that a lot of companies are rightfully suspicious about CPAN (I have a tolerate-hate relationship with it myself), and won&#8217;t let my consultant friends install or upgrade any module without a lot of red tape.  OK, you say, so bundle and distribute the modules the toolkit needs, and they can be installed locally with the toolkit.  That sounds nice, but it&#8217;s even <strong>worse</strong> for a variety of reasons.  Just to mention one: did you know that it can be a pain in the butt even to set <code>@INC</code> so a module <em>sitting in the same directory with the script</em> will be found by the script?  (Please don&#8217;t tell me how easy it is, or I&#8217;ll let you respond to the next person trying to get it to work on an obscure platform with a Perl installation from the middle ages).  Okay, I&#8217;ll mention two reasons: some Perl modules have to be compiled and customized just for the operating system you&#8217;re installing them on, or they&#8217;ll segfault (of all things)!  Don&#8217;t get me wrong, I don&#8217;t think the grass is greener on the other side; no way do I want to try writing these things in C or Java.  Perl is about as portable as it gets.</p>

<p>The net result is that I have to do a lot of little tricks to make these things standalone programs, as much as humanly possible.  I&#8217;m trying to reduce dependencies on external modules, even those that are part of core Perl.  I&#8217;m re-inventing functionality because it&#8217;s not available in all versions.  I&#8217;m writing modules that can be tested, but I&#8217;m not shipping them as separate modules; I&#8217;m basically using <code>sed</code> to copy-and-paste the module&#8217;s code into the scripts.</p>

<p>Why am I doing all this work?</p>

<p>Because it&#8217;s less work than not doing it.</p>

<p>But it is <em>significantly</em> more work than just whacking together some &#8220;scripts&#8221; and uploading them.  That&#8217;s why there is a critical mass beyond which it gets harder to grow a project.  The solution to this is to find a way to do things differently, work smarter, not harder.  The challenge is to switch the fight against the demons of bad code and maintainability so it&#8217;s on my terms.  In other words, don&#8217;t fight against these characteristics of growth; make them work for me.  I won&#8217;t say I&#8217;ve learned that lesson completely, but I&#8217;m starting.  That&#8217;s why I&#8217;m automating basically everything about this project (though for some reason I can&#8217;t get WWW::Mechanize to stay logged into Sourceforge, so I&#8217;m having a hard time automating part of the release process).</p>

<p>I&#8217;m also considering ways to provide this toolkit without taking so much out of my own pocket.  What started out as me developing tools for my employer, and them graciously agreeing to let me make them available for Sourceforge, has gone far beyond my employer&#8217;s needs now.  I can&#8217;t ask my employer to carry the weight, so it has fallen to me for a while now.  That&#8217;s okay for some period while I work out how to do it differently, but not indefinitely.  Among other things, it cuts into time I want to spend with my wife.  Charging for support has definitely crossed my mind, as has some kind of community/enterprise split (such as the one <a href="http://www.zmanda.com/">Zmanda</a> does).  I don&#8217;t want to go there yet &#8212; so I&#8217;m just asking for a week of sponsored time off work, to begin with.</p>

<p>By the way, the process of replacing copy/pasted code isn&#8217;t without its hitches.  I just found and fixed a bug in MySQL Table Checksum that I caused by moving the DSN parsing code to a module.  And someone else just reported a different bug in another tool, where it turns out the copy/pasted code wasn&#8217;t quite identical and I changed the functionality by moving it to the module.  Release early, release often.  Rely on users to <a href="http://code.google.com/p/maatkit/">find bugs and report them</a>.  So it goes.</p>

<p><strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2008/12/23/does-mysql-really-have-an-open-source-business-model/' rel='bookmark' title='Permanent Link: Does MySQL really have an open-source business model?'>Does MySQL really have an open-source business model?</a></li>
<li><a href='http://www.xaprb.com/blog/2008/05/14/mysql-free-software-but-not-open-source/' rel='bookmark' title='Permanent Link: MySQL: Free Software but not Open Source'>MySQL: Free Software but not Open Source</a></li>
<li><a href='http://www.xaprb.com/blog/2009/03/08/making-maatkit-more-open-source-one-step-at-a-time/' rel='bookmark' title='Permanent Link: Making Maatkit more Open Source one step at a time'>Making Maatkit more Open Source one step at a time</a></li>
<li><a href='http://www.xaprb.com/blog/2009/04/29/what-does-an-open-source-sales-model-look-like/' rel='bookmark' title='Permanent Link: What does an open source sales model look like?'>What does an open source sales model look like?</a></li>
<li><a href='http://www.xaprb.com/blog/2011/07/04/measuring-open-source-success-by-jobs/' rel='bookmark' title='Permanent Link: Measuring open-source success by jobs'>Measuring open-source success by jobs</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2007/11/05/growth-limits-of-open-source-vis-a-vis-mysql-toolkit/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JavaScript number-formatting library updated</title>
		<link>http://www.xaprb.com/blog/2007/06/19/javascript-number-formatting-library-updated/</link>
		<comments>http://www.xaprb.com/blog/2007/06/19/javascript-number-formatting-library-updated/#comments</comments>
		<pubDate>Wed, 20 Jun 2007 02:13:50 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[formatting]]></category>
		<category><![CDATA[format_strings]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[number formatting]]></category>
		<category><![CDATA[numberformat]]></category>
		<category><![CDATA[numbers]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/2007/06/19/javascript-number-formatting-library-updated/</guid>
		<description><![CDATA[<p>I've released a new version of my <a href="/blog/2006/01/05/javascript-number-formatting/">powerful, flexible, efficient JavaScript number-formatting library</a>, which is probably the best available. This release adds a fix for zero-padding negative numbers.</p>


<strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2007/07/15/javascript-number-formatting-library-v13-released/' rel='bookmark' title='Permanent Link: JavaScript Number Formatting Library v1.3 released'>JavaScript Number Formatting Library v1.3 released</a></li>
<li><a href='http://www.xaprb.com/blog/2007/06/25/javascript-formatting-library-update/' rel='bookmark' title='Permanent Link: JavaScript formatting library update'>JavaScript formatting library update</a></li>
<li><a href='http://www.xaprb.com/blog/2005/12/20/javascript-date-parsing/' rel='bookmark' title='Permanent Link: Javascript date parsing and formatting, Part 2'>Javascript date parsing and formatting, Part 2</a></li>
<li><a href='http://www.xaprb.com/blog/2006/05/14/javascript-date-formatting-benchmarks/' rel='bookmark' title='Permanent Link: JavaScript date formatting benchmarks'>JavaScript date formatting benchmarks</a></li>
<li><a href='http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/' rel='bookmark' title='Permanent Link: JavaScript date parsing and formatting, Part 1'>JavaScript date parsing and formatting, Part 1</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p class="download"><a href="/articles/number-functions.zip">Download number-functions</a></p>

<p>I&#8217;ve released a new version of my <a href="/blog/2006/01/05/javascript-number-formatting/">powerful, flexible, efficient JavaScript number-formatting library</a>, which is probably the best available. This release adds a fix for zero-padding negative numbers.</p>

<p>If you find bugs, please send me test cases I can use to reproduce and add to the unit test suite.  One test per line, like &#8220;input&#8221;, &#8220;format&#8221;, &#8220;expected&#8221; is best.  For example, this is a great test case:</p>

<pre>-1, "#,#.00", "-1.00"</pre>

<p>I can plug that directly into the unit test suite, run it, and if it gives back &#8220;-01.00&#8243; it will fail the test.  This makes it much easier and more convenient for me to fix bugs.</p>

<p><a href="/blog/donate/">Sponsoring</a> bug fixes wouldn&#8217;t hurt either ;-)</p>

<p><strong>Further Reading:</strong><ul><li><a href='http://www.xaprb.com/blog/2007/07/15/javascript-number-formatting-library-v13-released/' rel='bookmark' title='Permanent Link: JavaScript Number Formatting Library v1.3 released'>JavaScript Number Formatting Library v1.3 released</a></li>
<li><a href='http://www.xaprb.com/blog/2007/06/25/javascript-formatting-library-update/' rel='bookmark' title='Permanent Link: JavaScript formatting library update'>JavaScript formatting library update</a></li>
<li><a href='http://www.xaprb.com/blog/2005/12/20/javascript-date-parsing/' rel='bookmark' title='Permanent Link: Javascript date parsing and formatting, Part 2'>Javascript date parsing and formatting, Part 2</a></li>
<li><a href='http://www.xaprb.com/blog/2006/05/14/javascript-date-formatting-benchmarks/' rel='bookmark' title='Permanent Link: JavaScript date formatting benchmarks'>JavaScript date formatting benchmarks</a></li>
<li><a href='http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/' rel='bookmark' title='Permanent Link: JavaScript date parsing and formatting, Part 1'>JavaScript date parsing and formatting, Part 1</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2007/06/19/javascript-number-formatting-library-updated/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

