The amazing adventures of Doug Hughes

Archive for July, 2007

Unit Testing Anybody?

So, here I am being the good developer and attempting to put together a series of unit tests for a project (the generic data validation engine is actually very close!). I have always appreciated the concept of unit testing and I have no problem doing it for simple little test cases. Where it always tends to get left by the road side is when I run into one of those more complex scenarios that does not fit the mold.

There was just such an occasion last week and I still have not found a way around it – at least one that I like. So, here is the scenario. I have an object whose init method accepts an optional path to an XML configuration file and if received, parses that configuration file into an internal data structure which is a fairly complex series of nested structures and arrays. All is well and good until I went to write a couple of unit tests for this …. I know I should have written them first, but at least they are being written!

The problem is, as part of this XML parsing/conversion process, the object in question is generating unique identifiers and inserting them into the data structure. These unique identifiers are UUIDs, so you can probably start to see the issue already. The way I was going about testing this piece functionality was to pass in an example XML file to the init method, capture the resulting data structure, and then compare it against a manually created data structure. However, as the conversion process generates unique identifiers on the fly, I can’t mimic those exact same identifiers in my manually created data structure and thus the test fails.

One suggestion I had was to rewrite the process of creating these identifiers so that if I passed in a test flag, then it would generate the identifier in a way that could be replicated. While this could work, the fact that I am having to go back and introduce more logic and bend my code just for testing purposes does not sound right.

So, before I toss unit testing aside once again, does anybody have any bright ideas on how you might test functionality like this?

ColdFusion 8 has arrived!

Adobe has released the latest version of ColdFusion, ColdFusion 8 (Scorpio) today. After a lot of testing, it is finally ready to go. This release marks yet another big step in the continued growth of one of the best application development languages out there.

So what is so great about this version? For me, it is the fact that there is nothing really big in it. If you look at the release notes and new features lists, there is tons of new stuff there, but it is all fairly small – a new tag here and there type thing. Instead of some really big, grand new feature set, Adobe has focused on what developer’s have been saying and asking for – and they have delivered. There are so many little things that will make it much easier and faster to develop powerful applications using ColdFusion.

So, if you have not heard of ColdFusion before or of ColdFusion 8, jump over to Adobe and take a look. It is quite impressive.

Scottish ColdFusion User Group Preso

I will be giving a presentation to the Scottish ColdFusion User Group (SCFUG) this evening/afternoon (depending on where you live) at 8:PM GMT (3:00 PM EDT).

The presentation will be on Filtering and Sorting Data in Flex 2.

For more details, visit the SCFUG web site.

Hope to see you there!

Ant Can Mail Stuff

On a project we are working on,one thing we needed to do was set up some Ant tasks for deployment to staging and production environments. For the most part, its pretty straightforward, grab latest from SVN repo and then use Ant to replace some text in the main configuration file.

The entire process can take some time, so I looked for some sort of an alert or notification that I could use to signal the job was done. That is when I discovered the <mail> tag in Ant.

That’s right, among all the cool things Ant can do, it can send e-mails, even with attachments if you’d like, and like most things in Ant, once you understand the syntax, its pretty easy.

First, you will need to download 2 .jar files from Sun and place them in the lid directory of your Ant install. These files are mail.jar and activation.jar . (These links will send you to the pages to download entire packages, but all you need are the 2 .jar files in {ANT_HOME}lib) the syntax for the mail tag is pretty straight forward.

<mail mailhost="your mail server" password="password" subject="Subject" user="username">
    <from address="who its from"/>
    <to address="who its to"/>
    <message>Your message goes here</message>
</mail>

If your mail server does not require SMTP authorization, you can leave out the user and password attributes of the mail tag,

For more information on the mail task and it attributes, check out the documentation here.

The more I play around with it, the more I like Ant.

Alagad Is Hiring another Senior Developer (Or Two)

Well, it’s that time again. Alagad is hiring! I’m hoping to find one or two extremely talented Flex and ColdFusion programmers to join my team of developers. The people I’m looking for will have a lot of strong experience with enterprise development.

So, if you’re a senior developer who wants to get paid generously to work from home, please waste no time in applying.

Here are some finer details of what I’m looking for:

Languages

My team works primarily with the Adobe toolset. That is, ColdFusion, Flex and Air. Experience with LCDS would be a big bonus too.

We also do some fairly involved JavaScript and AJAX work. Advanced experience with Microsoft SQL is also necessary.

I wouldn’t be surprised to see some work related to Java and Hibernate in the future. I really need someone who solidly understands software development and who could, if the need was there, quickly learn something new and move forward with it.

Virtually all the work we do here is Object Oriented. You need to understand OOP, design patterns, and more to be productive.

Obviously HTML, CSS and XML go almost without saying.

Frameworks

On a day to day basis we use ModelGlue, ColdSpring and Reactor for ColdFusion. We’re also actively building new frameworks to fit other niches. As for Flex, Cainrgorm or Model-Glue Flex is a big bonus. And for Javascript we’ve been using a lot of jQuery as well as the YUI and Spry too.

Authoring

I need someone who can talk and write professionally. When you’re speaking with clients you must sound professional and intelligent. Also, you’ll be required to write at least one technical blog entry per week and the occasional article for CFDJ, FAQU, or devnet. You may even be asked to do the occasional user group presentation or talk at a conference. (All of this is on company time You work, I pay.)

Other Skills

There’s a good chance that I could throw just about anything at you. I need you to be able to roll with it. For example, sometimes I might need you to be able to take a PSD or jpeg image and turn it into clean CSS and HTML. So, some experience with Photoshop or Fireworks would be a big help.

Mindset

I’m looking for someone with a great attitude. My goal is to be the best employer any one of my employees has ever had. If you’re too jaded to believe that I’m earnest (if not a little idealistic), please look somewhere else.

I’m going to be finding ways to expand the compensation package to include profit sharing. For this to work well, I believe that we’ll all need to be committed. If you can come to the table with the appropriate brains and enthusiasm, we can all do well.

The Bottom Line

I can sum this up in one phrase: You’ve got to be smart and get things done.

So, why would you want to work with me?

Well, as I said above, I’m striving to be the best employer in the Adobe toolset market. Alagad is, however, a small business. So, I need to be really creative in how I try to be the best I can be. Here’s what I offer right now:

Hourly Pay

Are you sick of working 60 hours a week but being paid for 40? Well, first off, I rarely ask for any more than 40 hours in a week. But, if you do work more than 40 I’ll pay you for every hour you work!

Work from Home

All of Alagad’s employees work from home, wherever they are. Alagad has no real central office. This allows you to work wherever you want: Home, in bed, at the coffee shop, on an airplane. It doesn’t matter to me.

What this means is that you get more time for yourself and your family. Alagad doesn’t require that you pay for the expenses and time of a commute.

Flexible Schedule

At Alagad we’re less concerned with the hours you’re in the office than that you get your work done. That’s not to say that we don’t want to talk to you during the day, but if you want to cut out early in the afternoon we simply don’t care. Do you need to pick you kid up from school? No problem. Life is full of interruptions. We don’t mind, so long as you get your work done!

Generous PTO

Because we pay hourly, we’re able to do some novel things with your PTO plan. From day one you will earn PTO. For each hour you work you get an additional 7.5% that goes into your PTO account. This means that in an average 160 hour month you’ll earn 12 hours of PTO. And, because this is calculated based on the number of hours you work, the more you work, the more you get in PTO.

You can take your PTO whenever you want or you can collect it. PTO time never expires. We quite literally put this time in the bank for you. You can collect PTO for your entire career with Alagad. And, when you leave you’ll get any left over time in a check.

Also, one of the stranger things we do here is that we do not offer any holiday days off. These are already factored into your PTO. Really, we’re not being so presumptuous as to assume you want to take particular days off. If you’d rather not take Labor Day off, we won’t make you. But if you would like to take, say, your birthday off, you can! It’s up to you.

Health Insurance Stipend

Any small business owner can tell you that paying for Health Insurance is a huge burden. Also, no one is ever really satisfied with group health plans. So, at Alagad, we decided not to do group insurance. Instead, we let you (and help you) find insurance on your own. It’s really not that hard and, believe it or not, it’s cheaper than most group plans.

Once you’ve arranged for insurance we’ll then pay a stipend of $200 per month if you’re single and $400 if you’re married or in a domestic partnership. In most cases this is about 50% of health insurance costs. We can even arrange for all of your health insurance costs to be tax free.

I you want to work for Alagad, please put together a nice cover letter and resume and send it to me at dhughes(at)Alagad(dot)com. And, this is important, please include the word “salamander” in your email subject. If you don’t include it, I won’t get your resume. Extra points will be given for creativity!

Reason #526 Why I Like Model-Glue

I make no secret that I like love Model-Glue. I will admit, if you do not have a decent grasp on Object-Oriented processes, Model-Glue might seem a bit over complicated, but sometimes it just saves so much time and effort.

One example of this happened yesterday. I am working on a project that uses Model-Glue. There was a requirements change for one part of the application. It wasn’t anything major. I needed to remove something that was appearing on one particular page, and move it to a different page. Now, if your application is well-architected, this will be an easy process, however, in this instance, I did not even need to move any ColdFusion code. All I had to do was move some XML blocks from one <event-handler> to another and re-initialize the application.

Here is what the original <event-handler> looked like, the snippets we are concerned about are in bold.

<event-handler name="DisplayEnd">
    <broadcasts>
        <message name="CheckIfLoggedIn">
            <argument name="redirectToEvent" value="LoginForm"/>
        </message>
        <message name="NeedToGetPageManager"/>
        <message name="NeedMessage">
            <argument name="message" value="End"/>
        </message>
        <message name="NeedGraphicId">
            <argument name="grahicId" value="End"/>
        </message>
	   <message name="NeedAudioMessage">
            <argument name="audioMessageType" value="ending"/>
		</message>
    </broadcasts>
    <views>
        <include name="topContent" template="display/dspMessageText.cfm"/>
        <include name="bottomContent" template="display/dspMessageGraphic.cfm"/>
        <span style="font-weight: bold;"><include name="audioMessage" template="display/dspAudioMsg.cfm"/>
        </span>
    </views>
    <results>
        <result do="DisplayLayout"/>
    </results>
</event-handler>

What the highlighted bits of XML tell us is that when an event named ‘DisplayEnd’ is called, such as http://www.mysite.com?event=displayEnd, certain messages get broadcast, including ‘NeedAudioMessage’. When that message is broadcast, we are also passing along an argument with the name of ‘audioMessageType’ and a value of ‘ending’. (This is available inside of any Model-Glue controller by using arguments.event.getArgument(‘audioMessageType’). Lastly, it tells us that, among others, we are including a ColdFusion page named dspAudioMsg.cfm.

I will not get into the particulars of the code that exists inside of the controller, it merely checks certain conditions and then simply adds a value to the event if an audio message should be displayed.

The change was that instead of displaying this audio message on the DisplayEnd page, the client wanted it to be displayed on the GoalMet page. All I needed to do was remove the 2 highlighted XML blocks from the original <event-handler>, and move them into the new one. Since the logic that determined whether or not we needed an audio message had not changed, there was no need to change any of the ColdFusion code. The XML looked like this:

<event-handler name="GoalMet">
    <broadcasts>
        <message name="CheckIfLoggedIn">
            <argument name="redirectToEvent" value="LoginForm"/>
        </message>
        <message name="NeedToGetPageManager"/>
        <message name="NeedMessage">
            <argument name="message" value="Congratulatory"/>
        </message>
        <message name="NeedGraphicId">
            <argument name="grahicId" value="Congratulatory"/>
        </message>
        <message name="NeedAudioMessage">
            <argument name="audioMessageType" value="ending"/>
        </message>
    </broadcasts>
    <views>
        <include name="topContent" template="display/dspMessageText.cfm"/>
        <include name="bottomContent" template="display/dspMessageGraphic.cfm">
            <value name="xeNext" value="index.cfm?event=DaisyEnd"/>
        </include>
        <span style="font-weight: bold;"><include name="audioMessage" template="display/dspAudioMsg.cfm"/></span>
    </views>
    <results>
        <result do="DisplayLayout"/>
    </results>
</event-handler>
<event-handler name="DisplayEnd">
    <broadcasts>
        <message name="CheckIfLoggedIn">
            <argument name="redirectToEvent" value="LoginForm"/>
        </message>
        <message name="NeedToGetPageManager"/>
        <message name="NeedMessage">
            <argument name="message" value="End"/>
        </message>
        <message name="NeedGraphicId">
            <argument name="grahicId" value="End"/>
        </message>
    </broadcasts>
    <views>
        <include name="topContent" template="display/dspMessageText.cfm"/>
        <include name="bottomContent" template="display/dspMessageGraphic.cfm"/>
    </views>
    <results>
        <result do="DisplayLayout"/>
    </results>
</event-handler>

Now, as long as the same conditions are met, we will get an audio message in the GoalMet event rather than the DisplayEnd event, all without writing or changing one line of CF code.

JSON Support in Scorpio

ColdFusion 8 (Scorpio) is right around the corner and for me, the greatest thing about this release is that there is nothing really big in it. The whole release is little stuff tailored to the developer allowing us to better plug ColdFusion into virtually any scenario. One of these features is the addition of native JSON support. This is all of about three new functions, but it could be a very big time saver.

What is JSON?

The Wikipedia definition of JSON is a “lightweight computer data interchange format. It is a text-based, human-readable format for representing objects and other data structures and is mainly used to transmit such structured data over a network connection (in a process called serialization).”

In other words, JSON is a data format, like XML, that is used to send data from one system to another. The difference is that JSON is a data only format whereas XML is a document and data format. This means that XML is much more complete, but at the same time, much more verbose and complex. For example, take a look at the following XML snippet that might describe an individual contact in a contact book.

<contact>
    <firstname>John</firstname>
    <lastname>Doe</lastname>
    <address>
        <street>123 Somewhere</street>
        <city>San Jose</city>
        <state>California</state>
        <zipcode>12345</zipcode>
	</address>
	<phonenumbers>
		<phone>123-123-1234</phone>
		<phone>234-234-2345</phone>
	</phonenumbers>
</contact>

If you read through that, there is a lot of text and information there just to describe a simple contact record. Now, take a look at the JSON example that includes the exact same information.

{
    "contact": {
            "firstname": "John",
            "lastname": "Doe",
            "address": {
                    "street": "123 Somewhwere",
                    "city": "San Jose",
                    "state": "California""zipcode": "12345"
            },
            "phonenumbers": ["123-123-1234", "234-234-2345"]
    }
}

The JSON string is easier to read, much shorter (about 80 characters), and has an even bigger benefit. When you are dealing web services, you must be able to decipher the XML data received from a web service on the client-side. This typically requires invoking some sort of parser and then using very long and complex DOM of xPath strings to access individual pieces of data. With JSON, none of that is needed. JSON is JavaScript syntax, so you just perform a quick “evaluate” on it and you have a set of nested structures and arrays.

What does this do for ColdFusion?

With todays emphasis on rich internet applications, ColdFusion development is shifting more and more into the middle tier of the application. We are writing remote ColdFusion components that will exchange data with rich user interfaces now instead of writing CFML pages that display HTML. This means more web services (remote access cfcs) and more data exchange, which in the past meant XML. However, many of the AJAX and RIA libraries out there support JSON data as well. With ColdFusion 7 and before though, this meant having some sort of middle man interface that could take ColdFusion data structures and parse them into a JSON string and vice versa. It worked, but now we have something much simpler.

ColdFusion 8 is introducing two new functions . serializeJSON and deserializeJSON. All these functions do is translate ColdFusion data types into JSON data and back again . extremely simple. Take a look at an example:

It is as simple as that. The deserializeJSON function is just as easy give it a string containing JSON data and out you get a ColdFusion data structure that you can work with as usual. One thing to take note of, there is a bit of confusion regarding the case of the keys generated by the JSON functions. The documentation states that all keys are converted to upper case as JavaScript is case sensitive, which is what you see above. However, in playing a bit, it looks like keys in the lower levels of a nested structure dont get converted, so you may have to do some investigation here once the final release of ColdFusion 8 comes out to see what things look like.

The second part of the new JSON functionality comes into play with remote function calls. Previously with CFCs, there is a returnType attribute, which as is expected, specifies the data type of the value being returned from the function. With ColdFusion 8, there is a new attribute called returnFormat which only applies to remote access components and functions and works in conjunction with the returnType attribute. This attribute takes three different values:

  • Plain
  • WDDX
  • JSON

The “Plain” value returns the result as a plain text string. This obviously only works if the returnType is a simple value that ColdFusion can represent as a string . a boolean, date, guid, number, string, uuid, or XML. The “WDDX” value returns the result in WDDX format and the “JSON” value returns the result in JSON format.

What this means is that now we can have AJAX calls made to remote CFCs which can then return JSON formatted data directly without any middle conversion layer.

Wrap Up

This has been a pretty quick overview of this functionality which is not exactly real complex. The real benefit lies in the fact that it makes life as a developer that much easier which is what I like so much about this release.

Tag Cloud