The Harmonious Programmer

The Harmonious Programmer

Covering a symphony of technical and sometimes off-topic subjects

  • Home
  • Adobe ColdFusion 9 on Mac Lion - Fix for cfdocument and Hanging Admin

    • 19 Jan 2012
    • 6 Responses
    •  views
    • Adobe CFML Mac Mach-II
    • Edit
    • Delete
    • Tags
    • Autopost

    First let me start off that I am not a Mac owner and therefore please keep this in mind.

    One of the issues with ACF9 on Mac OSX Lion is the use of the java.awt package to get items like the list of available printers.  The AWT package is just a wrapper for a packages that are native on the target operating system.  In this case, there are bugs in the apple.awt.CToolkit class that is the problem on MAC.

    We were having an issue with Mach-II 1.9 hanging on MAC Lion recently and we narrowed it done to our use of java.awt.Toolkit.  You can indicate to the JVM that you want to use the sun.awt.* package instead which appears to have fixed the issue for Mach-II 1.9 for Mac OSX Lion users.  The positive side effect is that it fixed the hung "Info" page in the CFIDE as well.

    You probably already have headless=true in your jvm.config file, however you need another directive to use a different awt toolkit otherwise the JVM will default the buggy apple.awt toolkit.

    Let me know if this fixes other ACF9 issues on Mac OSX Lion like cfdocument.

    -Djava.awt.headless=true
    -Dawt.toolkit=sun.awt.HToolkit

    Update 1: This appears to have fixed generating PDFs using cfdocument as well.

    Update 2: I'd like to thank Sumit Verma at Ten24Web for spending 4 hours nailing down that AWT was causing an issue in Mach-II 1.9. This is what led me down the right path to this JVM config argument change.

    Update 3: Typically it is "CF9/runtime/bin/jvm.config" where CF9 is the location you installed CF.  Be sure to make a back up copy of the jvm.config in case you foo bar something.

    • Tweet
  • cf.Objective() 2011 - 2nd Annual Google Map - Places to Eat, Drink or Things to Do

    • 11 May 2011
    • 0 Responses
    •  views
    • CFML Conferences cfobjective
    • Edit
    • Delete
    • Tags
    • Autopost


    View cf.Objective 2011 - Things Close By in a larger map

    Let me know if you want to add anything on the map.  I'll add you as a collaborator!

    • Tweet
  • ColdFusion Weekly - Advice from the Past

    • 6 Apr 2011
    • 2 Responses
    •  views
    • Advice CFML Podcast
    • Edit
    • Delete
    • Tags
    • Autopost

    Matt and I decied to move the ColdFusion Weekly to an archive on Posterous this week.  So I decided to listen to our last show while we ere chatting on IM and this little gem came across my ears.  I decided to transcribe it because it's worth it's weight in gold.  Bear in mind that this show is from June 2008 which is nearly three years ago.  I guess things haven't changed at all.

    Matt: This timing is kinda interesting with the growing pains that are going on right now. It is obviously with all the open source going on, very - as people know from stuff I said -- it's a great time to be a CFML developer. We all need to figure this stuff out together. Some of the final things I'd like to say is that I hope that after people calm down a bit and that everybody can just be nice to each other. I'll just say that...

    Peter: You know there is plenty of space out there.  We're not fighting for same square foot of land...

    Matt: Yea, and the CFML community has always been a great community and we will continue to do that...  The other thing I'm starting to realize is and that is probably why you'll see me participating in blog comments less... I'm getting to the point with that a lot of people are say things that they might not otherwise say to you if you were in person...

    Peter: Yea, whether your name is attached to your comment or not, there is a little additional bit of anonymity when it comes to commenting -- even if your name is there... just because you don't have to deal with somebody getting up in your face.

    Matt: Right, so I guess I would say -- try to think about as if you were talking with people in person.  There is a lot of misunderstanding because of text communication -- everybody knows this -- there is no nuance to it and you don't know how people are delivering that message.  This is just one of the things that causes things to spin out of control like they have a bit recently.  Like I said, it's a fantastic time to be in this [CFML] world.  It's only going to get better for everybody involved.

    ColdFusion Weekly - Version 3.09 - CFExit - 9:20-11:07

    • Tweet
  • Checking Bytes of Content-Length Header against the Content Body in CFML / ColdFusion

    • 3 Feb 2011
    • 0 Responses
    •  views
    • API CFML HTTP REST
    • Edit
    • Delete
    • Tags
    • Autopost
    Sometimes you need to check to see if the POST or PUT content body is contains the same number of bytes indicated in the content-length header.  Remember that the content-length value is the number of bytes not the length of the content body string.  Depending on the character set encoding, some characters in the content body may have more than 1-byte per character.  It's ultra important to remember that when you check the content body against the value in the content-length header.  Also, you should only check the number of bytes when the request is of HTTP method PUT or POST as there is not content body for GET and DELETE requests.

    The sample below tries to decipher the charset from the content-type header (if available).  Most REST / SOAP APIs require that all POST and PUT requests have content-type header in which the charset is usually a component value.  If your API doesn't require one, you may consider making that a requirement for POST and PUT operations.

    Example

     <cffunction name="performContentLengthChecks" access="private" returntype="false" output="false"
        hint="Performs content-length header and body checks.">
     
        <cfset var content = GetHttpRequestData().content />
        <cfset var headers = GetHttpRequestData().headers />
        <cfset var contentType = "" />
        <cfset var charset = "ISO-8859-1" />
       
        <cfif StructKeyExists(headers, "Content-Type")>
            <cfset contentType = headers["ContentType"] />
           
            <!--- Find a charset in example "application/xml; charset=UTF-8"--->
            <cfif ListLen(contentType, ";") GTE 2>
                <cfset charset = Trim(ListGetAt(ListGetAt(contentType, 2, ";"), 2, "=")) />
            </cfif>
        </cfif>
       
        <!--- Check that the content-length header was sent --->
        <cfif NOT StructKeyExists(headers, "Content-Length")>
            <cfthrow type="MissingContentLength" />
        <!--- Check that the number of bytes in the content-length header of the raw content equals the header value --->
        <cfelseif headers["Content-Length"] NEQ Len(content.getBytes(charset))>
            <cfthrow type="IncompleteBody" />
        </cfif>       
     </cffunction>
     
    • Tweet
  • OpenCF Summit: What It Is, and What It Isn't (via OpenCF Summit)

    • 8 Dec 2010
    • 1 Response
    •  views
    • CFML Conferences Open Source
    • Edit
    • Delete
    • Tags
    • Autopost

    Several people emailed me today about the latest episode of the CFHour podcast, in which the hosts spend a good chunk of time at the end of the show talking about OpenCF Summit and open source in general.

    Although in my opinion a great deal of what was said on the podcast was quite ill informed, which I suppose isn’t surprising given that they didn’t contact us to get any information about OpenCF Summit, it did get me thinking that we need to do a better job of sharing with everyone what’s behind OpenCF Summit, the focus of the event, and the goals we have for OpenCF Summit participants.

    Please consider this to be the beginning of the discussion. If something needs additional clarification, or if you have any ideas at all about what you think we could doing better, we absolutely appreciate any feedback you can give us.

    We are relying on you to help us make OpenCF Summit the event you want it to be, and the event that the CFML community needs it to be.

    OpenCF Summit is …


    1. Focused on educating CFML developers about free software and open source.

    Even though
    free software and open source have been major forces in the software industry for over 25 years, as a general rule we still see a lot of misunderstanding and misinformation about these topics in the CFML community. This was the #1 reason for creating OpenCF Summit that came up in our early discussions about the event.

    The people involved with OpenCF Summit are extremely passionate about free and open source software so we want to do everything we can to help people understand these topics better, and these are big enough and important enough topics that in our opinion they can’t be adequately covered at existing CFML events.

    We want OpenCF Summit participants to see the tremendous personal and professional benefits of being involved with free software projects. We want participants to inspire each other to take the plunge and contribute to open source projects. And we also want participants to learn about the business aspects of open source from people who live in this world every day.

    To help reach these goals we’re planning on having a volunteer table staffed by the

    Free Software Foundation to talk to attendees about free software, and we’ll have presentations about the various philosophies behind free software and open source, and free software licenses, from people who know these topics inside and out.

    And of course Mura, Railo, and aw2.0 will have a lot to say about open source as it relates to business.

    We cover this topic in more detail below, but it’s important to understand that OpenCF Summit is not focused exclusively on the open source CFML engines. The CFML community as a whole will benefit from being better informed about, and increasing its participation in, free software and open source, regardless of anyone’s CFML engine of preference.

    2. A place to gather with fellow CFML developers and discuss the important issues facing our community.

    Above All, OpenCF Summit is a CFML Conference

    Regardless of the name of the event or its specific focus, at the end of the day OpenCF Summit is a CFML conference.

    If you’ve been to other CFML conferences you know that not only are CFML developers some of the smartest, nicest, and most giving people you’ll ever meet, they also know how to have a damn good time. OpenCF Summit will be no exception on any of these points, and I’m already looking forward to all the great conversations I’m going to have with all of you at the event.

    In addition, we feel in-person settings are the best venue for facilitating open discussions of issues and helping us all work together to solve them. Mailing lists, Twitter, IM, blogs, and the like are great, but they’re simply no substitute for getting together face-to-face with people that share your interests and passions.

    I always return home from events like cf.Objective() and BFusion with my brain overflowing with ideas and inspiration. We can’t get too much of this in the CFML community.

    Challenges Can Only Be Overcome When You Face Them Directly

    The people involved with planning OpenCF Summit have been doing CFML development for many, many years. I personally have been doing CFML for about 14 years now, and like many of you we’ve seen the ebbs and flows in the CFML world.

    We see the technology we love get slighted, passed over, even derided, and we all want to do what we can to help both defend CFML as well as grow its popularity.

    Let’s be honest: CFML is currently facing some of the greatest challenges it’s ever faced. Ignoring them won’t make them go away, and if we start turning against each other, we really are in trouble.  Finger pointing, he said / she said, and accusations of broken promises are wasted time that could be better spent doing positive things for the community.

    New applications, language features, and general innovation are what will attract new developers to the CFML community.  Drawn out brawls over who’s “right” will do nothing but drive people away.

    The good news is that even with these increasing challenges, we’re also in the best position we’ve ever been to overcome them. With open source, our collective brain power, and the fantastic technology that is CFML there’s nothing we can’t overcome. We simply have to focus on the collective goals that benefit us all instead of dwelling on our minor differences.

    3. A place where you can learn from, get hands-on help from, and code alongside your favorite CFML developers.

    Face-to-Face Time is Worth a $1000/hr

    Obviously at this point we don’t know who all will be attending (if you haven’t registered yet, why not do it now!), but given what we do already know about who will be at OpenCF Summit, and given the fact that registration tops out at about 120 people, you’ll have plenty of opportunities to pull people aside and ask those questions you’ve always wanted to ask but maybe didn’t have time to write up in an email or a blog comment. And nothing beats sitting down with someone in person, cracking open those laptops, and sticking with the issue until you really understand it.

    Help Desk: Sometimes a Second Mind Does the Trick

    We’re also planning a volunteer help desk that will be running throughout the event so people can get help with their toughest programming or configuration problems, so if you want to offer your help in your area of expertise, consider yourself recruited! Don’t think you have to be some uber guru in order to be the person that saves the day for a fellow developer; we all have our own areas of expertise, and we want to foster sharing as much as possible at OpenCF Summit.

    Hackfest: Work on an Application That Will Help a Charity / Public Service Organization

    Finally, we’re planning a hackfest that will be going on throughout the event, the end result of which will be an application that will be donated to a worthy charity or public service organization in the Dallas area. This is your opportunity to write code with people you may never work with in a “day job,” and writing an application together is one of the best way for programmers to learn from one another.

    4. A place where you can have a direct voice in shaping the future of CFML.

    Have you ever wanted to sit down in person with the people behind OpenBD, Railo, or your favorite open source CFML project? Or maybe you have an idea for a new feature in the CFML engines that you simply can’t explain well without literally showing someone what you mean.

    At OpenCF Summit, you can. Of course all open source projects have mailing lists, but there’s simply no substitute for having face-to-face back and forth when it comes to brainstorming on all the cool stuff you’d like to see CFML be able to do in the future. You’ll be talking directly to the developers on the open source engines and other open source projects, so your voice will absolutely be heard.

    OpenCF Summit isn’t ...


    1. We aren’t focused solely on open source CFML engines.

    OpenCF Summit is extremely appreciative of the support we’re receiving from all of our our generous sponsors, two of whom are Railo and aw2.0 (which for those of you who don’t know is the company behind Open BlueDragon).

    Because the major development in open source CFML in the last two years is the availability of open source CFML engines on which to run all the great open source CFML applications, educating participants about Railo and Open BlueDragon will be an important part of the conference.

    But this certainly isn’t the only focus, so if people have that impression we haven’t done a good job of explaining OpenCF Summit. As stated above, the major focus if we had to choose only one is educating people about free and open source software as a philosophy, as a way to license software, as a great career move, and as the powerful underpinnings of business.

    2. We aren’t anti-Adobe or in any way exclusionary.

    Everyone (yes, everyone!) is welcome to attend OpenCF Summit. We have an open topic suggestion and call for proposals application (which incidentally we shared with cf.Objective()) that lets you see suggestions and proposals immediately as they’re submitted, and lets you vote for and comment on the topics submitted as well. Anyone can submit any topic they like.

    People who want to learn more about free software and open source should attend OpenCF Summit regardless of their CFML engine of choice. Even if you take the CFML engines out of the picture, free and open source software is vital to the future of CFML. If we as a community can build killer open source applications that just happen to be in CFML that’s a powerful way to spread CFML outside the community.

    We also encourage people who are skeptical about the open source CFML engines and the role they play in the future of CFML to attend. We want to hear your opinions and learn from your perspectives because it will only make the CFML community stronger as a whole.

    “The Future of CFML”: A Clarification

    A Little Backstory

    What seemed to irk one of the hosts of the CFHour podcast the most is a BOF we have on the OpenCF Summit schedule entitled “The Future of CFML.” This is a joint BOF with OpenBD and Railo in which, as the title indicates, the topic will be the future of CFML as a language and platform.

    We intend this to be a session in which OpenCF Summit participants can voice their opinions about anything and everything related to the future of CFML, from language syntax, features, and functionality to higher-level topics like  where CFML is going in relation to cloud computing and other trends in the web development world.

    I agree that there’s a missing player here. Let me be completely honest and open about why Adobe is not currently on the schedule.

    We’ve had a lot of discussions about the role Adobe might or might not play in OpenCF Summit as we’ve been planning the event. I hope it’s no surprise to anyone that given the focus of the event it didn’t make sense for us to approach Adobe to be a sponsor of OpenCF Summit.

    Also, based on a hallway discussion a couple of OpenCF Summit steering committee members had with an Adobe employee at cf.Objective() 2010, it was our assumption--right or wrong--that if we did approach Adobe about sponsorship they would likely decline.

    I trust even our critics will be able to see the logic behind our line of thinking on this. Even if you don’t agree with the logic (which could well be flawed), please don’t drum up a conspiracy where there isn’t one.

    We Failed to Address This at the Right Time

    Where we failed, and I personally take responsibility for this, is once Adobe wasn’t in our minds as a potential sponsor of OpenCF Summit, considering other ways to approach them and see how they might want to participate fell by the wayside.

    It’s something that was in the back of my mind but with all the other details related to planning the conference, it didn’t get addressed in a timely fashion. Please bear in mind that this is the first year for OpenCF Summit so some details--large and small--do slip through the cracks.

    We see now how this might appear deliberately exclusionary. That was never our intent, and for that we apologize.

    We Welcome Adobe to Participate

    We welcome Adobe to participate in OpenCF Summit if they’re willing.

    While we haven’t yet thought through specifically what “participation” would mean (and we’re very interested to hear Adobe’s thoughts on how this might work), this is our open invitation to representatives from Adobe to participate in OpenCF Summit.

    Rest assured that we will also be contacting folks from Adobe directly in the event they don’t read this rather lengthy blog post. ;-)

    I for one think it would be unbelievably beneficial to have the people behind the three CFML engines all in the same place at the same time, not only so they could talk openly about some of the issues all the engines are facing, but also so OpenCF Summit attendees can interact with representatives from all three engines in person, simultaneously.

    Hope That Helps!

    This post covers a lot of issues that we should have addressed quite some time ago, so we hope it helps people understand the reasoning behind the creation of OpenCF Summit and our goals for the event.

    If you have comments feel free to add them to this post, or if it’s something you’d rather discuss with us directly, email info@opencfsummit.org and we’ll be more than happy to have a conversation with you.

    Hope to see you all at OpenCF Summit in February! Go register now and help us out by telling a friend to do the same!

    via blog.opencfsummit.org

    • Tweet
  • Unit Testing Custom Tags with MXUnit

    • 21 Sep 2010
    • 2 Responses
    •  views
    • CFML MXUnit Mach-II Open Source Unit Testing
    • Edit
    • Delete
    • Tags
    • Autopost
    Introduction

    We love MXUnit at work and at Mach-II to unit test our components and to do integration testing.  In Mach-II Simplicity (1.8), a big feature was our form and view custom tag libraries.  These features made developing the UI (view) layer of your application easier and less prone to error.  Why would you write this kind of form with manual data binding:

     <form method="post" encType="multipart/form-data" action="#BuildUrl('processUser')#">
             <h4>First Name</h4>
             <p><input id="firstName" value="#event.getArg('user').getFirstName()#" type="text" name="firstName"/></p>
             <h4>Last Name</h4>
             <p><input id="lastName" value="#event.getArg('user').getLastName()#" type="text" name="lastName"/></p>
             <p><input type="submit" value="Save Changes" /></p>
     </form>
     

    When you could just write this and have auto binding:

     <cfimport prefix="form" taglib="/MachII/customtags/form" />
     <form:form actionEvent="processUser" bind="user">
             <h4>First Name</h4>
             <p><form:input path="firstName" /></p>
             <h4>Last Name</h4>
             <p><form:input path="lastName" /></p>
             <p><form:button value="Save Changes" /></p>
     </form:form>
     

    Our First Pass Testing Solution and Failures

    What this brings up is that a lot of complex logic is now inside of custom tags*.  How do you test custom tags?  For the most part, a lot of the logic in custom tags should be about output and not data manipulation.  MXUnit makes it easy to compare data if the results are simple values, structs, arrays, queries, etc.  However, the output from a custom tag is not just a simple string like "abc123" but more a complex string with nesting of tags and relationships between tags (for example a "select" and "option").

    When we first started down this path of testing our custom tag libraries, we started by doing straight up text comparisons:

     <form:form actionEvent="something" bind="${event.user}">
                 <cfsavecontent variable="output"><form:input path="firstName" /></cfsavecontent>
     </form:form>
     <cfset assertTrue(output EQ '<input id="firstName" value="#event.getArg('user').getFirstName()#" type="text" name="firstName"/>') />
     

    This was simple but lead to an easy break down down the line.  There were two sticking points:

    1) Our custom tag library has a "tag writer" relies a lot on looping over a struct of tag attributes .  As we all know in CFML, we cannot rely on the order of iteration of a struct.  So while assertion works on OpendBD it sometime failed on ACF8 because we were relying on the custom tag to ouput the tag attributes in the same order as our assertion string.  In all reality, the browser does not care about the order of the tag attributes and neither should our unit test.  The flexibility of the unit test was strongly coupled to string as a whole; not the individual parts.

    2) It is hard to test relationships such as <select> and <option> tags in straigh string comparison.

    2) Maintaining the unit tests becomes painful because of the first and second point.

    These limitations were all deal breaker after just a week of trying to get tests to run all the time.  So on to find another solution that is less coupled to the straight string comparisons.

    Our Second Pass Testing Solution and Failures

    Ok, let's test individual parts like the value of an attribute using RegEx or Find() built-in functions:

     <form:form actionEvent="something" bind="${event.user}">
                 <cfsavecontent variable="output"><form:input path="firstName" /></cfsavecontent>
     </form:form>
     <cfset assertTrue(Find("value="farrell"', output)) />
     <!--- More assertions --->
     

    This works, but it is still extremely clumsy having to check for each attribute and we still cannot check the parent child relationships of tags like <select> and <option>.

    Our Third Pass Testing Solution and Ultimate Successful Approach

    How do you solve this predicament? We "sort of" solved problem #1, but #2 and #3 are still unsolved in my book.  Let's think about what the custom tag is outputting.  Hmm...our custom tag library output XHTML compliant code and there are many tools available to use to leverage XML .  So for all of you who think XML is bad, wrong and decitful -- it's time to eat your words. Luckily for us, MXUnit has a built-in assertion called assertXPath() that fits this use case perfect.

    I know you're tired of me jabbering about how we got here so you'll want to see some code right?  Bare in mind that the Mach-II custom tags do some interaction with what is happening in a Mach-II request so we had fun setting up a fake request so the object required by the tag are in memory.  For the sake of brevity, I'm going to leave that setup code out of my examples however you can always see them in the Mach-II SVN repository (the joys of open source) if you want to learn more.

    Let's look at testing a simple text input:

     <cffunction name="testInput" access="public" returntype="void" output="false"
         hint="Test basic 'input' tag.">
     
         <cfset var output = "" />
         <cfset var xml = "" />
         <cfset var node = "" />
         <cfset var bean = CreateObject("component", "MachII.tests.dummy.User").init() />
         <cfset var event = variables.appManager.getRequestManager().getRequestHandler().getEventContext().getCurrentEvent() />
     
         <!--- Add data to the the bean and set to the event so we can do binding --->
         <cfset bean.setFavoriteColor("red") />
         <cfset bean.setLastName("Farrell") />
         <cfset event.setArg("user", bean) />
     
         <cfsavecontent variable="output">
             <root>
                 <form:form actionEvent="something" bind="${event.user}">
                     <form:input path="favoriteColor" />
                     <form:input path="lastName" />
                 </form:form>
             </root>
         </cfsavecontent>
     
         <cfset xml = XmlParse(output) />
         <cfset debug(output) />
     
         <cfset node = assertXPath('/root/form/input[@type="text" and @value="red" and @id="favoriteColor"]', xml) />
         <cfset node = assertXPath('/root/form/input[@type="text" and @value="Farrell" and @id="lastName"]', xml) />
     </cffunction>
     

    All XML documents require a "root" node of some sort.  In HTML, it's the <html> tag so in our unit test we just used <root> so XMLParse() wouldn't choke on the code.  We also want to check that the "id" attribute and the "value" attributes are what is expected and we can easily do that in our XPath assertion string.

    Ok, so that's a simple example.  What about something more complex?  Let's look at how we test our <form:radiogroup> tag.  This tag takes a collection (lists, struct, array, array of structs or queries) and turns them into a group of radio buttons based off a template:

     <cffunction name="testRadiogroupWithQueries" access="public" returntype="void" output="false"
         hint="Test basic 'radiogroup' tag.">
     
         <cfset var output = "" />
         <cfset var xml = "" />
         <cfset var node = "" />
         <cfset var bean = CreateObject("component", "MachII.tests.dummy.User").init() />
         <cfset var event = variables.appManager.getRequestManager().getRequestHandler().getEventContext().getCurrentEvent() />
         <cfset var colors = QueryNew("v,l") />
     
         <!--- Add data to the the bean and set to the event so we can do binding --->
         <cfset bean.setFavoriteColor("red") />
         <cfset event.setArg("user", bean) />
     
         <!--- Test with simple array --->
         <cfset QueryAddRow(colors) />
         <cfset QuerySetCell(colors, "v", "red") />
         <cfset QuerySetCell(colors, "l", "Big Red") />
         <cfset QueryAddRow(colors) />
         <cfset QuerySetCell(colors, "v", "green") />
         <cfset QuerySetCell(colors, "l", "Giant Green") />
         <cfset QueryAddRow(colors) />
         <cfset QuerySetCell(colors, "v", "brown") />
         <cfset QuerySetCell(colors, "l", "Bad Brown") />
     
         <cfsavecontent variable="output">
             <root>
                 <form:form actionEvent="something" bind="${event.user}">
                     <form:radiogroup path="favoriteColor" items="#colors#" labelCol="l" valueCol="v">
                         <label for="${output.id}">${output.radio} <span>${output.label}</span></label>
                     </form:radiogroup>
                 </form:form>
             </root>
         </cfsavecontent>
     
         <cfset xml = XmlParse(output) />
         <cfset debug(node) />
         <cfset debug(output) />
     
         <cfset node = assertXPath('/root/form/label/input[@type="radio" and @value="red" and @id="favoriteColor_red" and @checked="checked"]', xml) />
         <cfset node = assertXPath('/root/form/label/input[@type="radio" and @value="green" and @id="favoriteColor_green"]', xml) />
         <cfset node = assertXPath('/root/form/label/input[@type="radio" and @value="brown" and @id="favoriteColor_brown"]', xml) />
         <cfset node = assertXPath('/root/form/label[@for="favoriteColor_red"]/span', xml, "Big Red") />
         <cfset node = assertXPath('/root/form/label[@for="favoriteColor_green"]/span', xml, "Giant Green") />
         <cfset node = assertXPath('/root/form/label[@for="favoriteColor_brown"]/span', xml, "Bad Brown") />
     </cffunction>
     

    As you can see, we setup some test data and pass that to the "items" attribute of the <form:radiogroup> custom tag.  The tag doesn't know which columns to use for the value or for the label so we indicate that.  Let's take a closer look at the template that is being used:

     <label for="${output.id}"><span>${output.label}</span> ${output.radio}</label>
     

    This template is interated over (i.e. looped over) for each item in the query.  We use a simple placeholder syntax of ${} to indicate where the radio and label are outputted (other computed attributes like the "id" are also available).  Our assertations in this case not only test for tags heirarchy and tag attributes, but the inner text of tags.  In this case, we need to test that the value of "${output.label}" that is displayed is correct (not the actual <label> tag).  We wrapped a <span> around it so we can easily find it with our XPath assertion.  Also, when testing for the "${output.label}" we need to make sure we're grabbing the right one so the XPath searches that the <span> is inside of a <label> with the correct "for" attribute.

    In Closing

    Testing custom tags with MXUnit is easy if you figure out the right plan of attack and after three iterations to our testing strategy -- we found one that works.  I'd be happy to hear if people have suggestions on improving how custom tag output can be tested with MXUnit, however at this point I think this solution is rather slick and leverages XML/XPath without the need for any custom assertions to be written in MXUnit.

    Now no code should go un-tested including custom tags.  This is especially true in something like Mach-II which is a community asset and having unit tests makes the software a better product.  So now go forth and unit test your custom tag libraries!

    * Sidebar: For performance, we used straight up custom tags with a "UDF"-like function library instead of having custom tags call CFCs.  Our basic testing at the time showed that CFCs were 10-15 times slower than the custom tag with "UDF"-like function library (included via a cfinclude).

    • Tweet
  • CFML Function - createDatetimeFromHttpTimeString()

    • 11 Aug 2010
    • 2 Responses
    •  views
    • CFML Open Source Sharing
    • Edit
    • Delete
    • Tags
    • Autopost

    Working with HTTP time strings should be easier to CFML / ColdFusion,
    but there is no built-in function that will create a CFML date/time from
    a UTC HTTP time string. So here is the UDF that can help you work with
    HTTP time string in native CFML date/time functions. I didn't check
    cflib.org first, but I really couldn't check it out of professional
    courtesy because I was writing this function for open source project and
    I didn't want to deal with attribution / license stuff (yes, I'm lazy).

    
    
    <cffunction name="createDatetimeFromHttpTimeString" access="public" returntype="date" output="false"
        hint="Creates an UTC datetime from an HTTP time string.">
        <cfargument name="httpTimeString" type="string" required="true"
            hint="An HTTP time string in the format of '11 Aug 2010 17:58:48 GMT'." />
    
        <cfset var rawArray = ListToArray(ListLast(arguments.httpTimeString, ","), " ") />
        <cfset var rawTimePart = ListToArray(rawArray[4], ":") />
        
        <cfreturn CreateDatetime(rawArray[3], DateFormat("#rawArray[2]#/1/2000", "m"), rawArray[1], rawTimePart[1], rawTimePart[2], rawTimePart[3]) />
    </cffunction>
    
    
    


    Enjoy!

    • Tweet
  • FuseboxFramework.com Domains Are Going Away Soon...

    • 5 Aug 2010
    • 23 Responses
    •  views
    • CFML Help Open Source
    • Edit
    • Delete
    • Tags
    • Autopost
    Where did you get those URLs? The fuseboxframework.com domains are going
    away soon (because no one in the Fusebox community was interested in
    taking them on - and they expire in two weeks).
    via groups.google.com (a comment by Sean Corfield)

    This is in reference the domain being used by the what appears to be the "defunct" FuseNG project that forked from the Fusebox project. While these aren't the main fusebox.org domains, this prompted me to look at the status of the main Fusebox project.

    I was surprised to learn that the last stable release for Fusebox was in March 2008 (version 5.5.1). Has it really been that long? It will be 2.5 years ago in just about a month or so without a release is stunning. Time flies.  Also, I quickly checked the Fusebox Trac site. Only one new ticket other than spam tickets has been filed or commented on in the past 6 months and that one ticket is just a question on syntax (it should have been sent to a list).  What is the state of Fusebox these days? Is TeraTech really "driving Fusebox forward and you can expect to see major improvements to the web site and the documentation in due course"? I don't see evidence of it on the site.

    What really saddens me is the state of the CFML community. Have people not learned to pitch in and help their open source projects? Clearly not because there is still the glut of new one-man projects that never leave the ground or barely hover. CFML community members need to band to together instead of re-inventing the wheel. They need to learn to contribute (which I'd say that 99.9% of them do not) and realize that there is only a handful of people contributing to their open source project of choice. You don't have to pay for software with money; you can pay with your time, talent and expertise. Contributing does not always mean code but help on lists, documentation, sample applications, etc. There are so many things to do on open source project other than the next generation of code.

    This is a call to arms! If you use open source, donate some time back to it or you might sadly find yourself with a defunct project and no maintainer there to help you. The great news is you can save yourself by contributing your time now. I urge all CFMLers to donate just 30 minutes a week to ONE project of your choice (if you don't know what to do, contact the maintainers -- I'm sure they have a laundry list of things to do). Just 2 hours a month would change the state of affairs in the CFML community and propel our language forward.

    • Tweet
  • CFML Advisory Committee -- My Thoughts

    • 24 Jul 2010
    • 1 Response
    •  views
    • CFML Open Source Software Development
    • Edit
    • Delete
    • Tags
    • Autopost

    As for the narrative of what happened to the demise of the committee, it isn't worth my time to comment on it.  It is what it was and I have nothing if any real interest to add to what has already been said by Adam, Matt and Sean.  My resignation letter clearly explains my resignation:

    http://blog.maestropublishing.com/open-cfml-advisory-committee-resignation-lett

    In his blog post, Adam alludes to some inside knowledge on my life and the demands on my time.  Adam has absolutely no understanding or knowledge of my daily life and demands. It is rather imprudent and extremely rude to make assumptions and presume some alternate agenda.  This is the issue I take with Adam's post.  Straight from my resignation letter: "it has become increasingly difficult for me to contribute sufficiently to the CFML specification process".  I spent a lot of time over a period of a couple months debating my resignation.  In the end, I felt I did not have the time to serve the CFML community in a manner that did justice to the committee as a CFML *community* representative.

    • Tweet
  • OpenBD (CFML) on Google App Engine - Live Meeting June 8th, 2010 at 7pm ET

    • 8 Jun 2010
    • 0 Responses
    •  views
    • CFML Google App Engine Open BlueDragon Presentations
    • Edit
    • Delete
    • Tags
    • Autopost

    Just wanted to quickly blog that Matt Woodward and I are presenting on OpenBD on Google App Engine tonight at the Mid-Michigan CFUG at 7pm ET (about 30 minutes from the time of this posting).

    Where: http://breeze.msu.edu/mmcfuggoogle  (Enter as guest)

    When: June 8th, 2010 - 7pm ET

    Description:

    If you want to take advantage of the power of cloud computing but want to focus on applications instead of server infrastructure, you owe it to yourself to check out Google App Engine. Google App Engine lets you deploy applications to Google's infrastructure with the push of a button, and the best part is that for many applications it's entirely free of cost.

    In this presentation we'll discuss both the benefits and downsides of living in the cloud, outline how Google App Engine differs from other cloud solutions, and demonstrate how to build and deploy a simple CFML application to Google App Engine using Open BlueDragon, which is the only CFML engine compatible with Google App Engine.

    If you're interested in running your CFML applications in the cloud come get in on the ground floor, because with a few simple tips and tricks, it's all clear skies.

    • Tweet
  • « Previous 1 2 3 Next »
  • About

    Hailing from the frigid tundra of Minnesota, Peter J. Farrell has a Bachelor of Music degree from the Peabody Institute at the Johns Hopkins University in Baltimore, Maryland.

    While studying music, Peter took his life-long interest with computers to a new level and started learning about web development technologies. He has been working with CFML since 2001 and is the lead developer of the Mach-II framework.

    Peter is a Senior Technologist for GreatBizTools, a human resources consulting firm. He and his wife, Allyson, live together in Minneapolis, Minnesota.

    326619 Views
  • Archive

    • 2012 (4)
      • January (4)
    • 2011 (10)
      • August (1)
      • May (4)
      • April (3)
      • March (1)
      • February (1)
    • 2010 (58)
      • December (1)
      • November (1)
      • October (1)
      • September (3)
      • August (4)
      • July (1)
      • June (4)
      • May (12)
      • April (15)
      • March (3)
      • February (5)
      • January (8)
    • 2009 (38)
      • December (14)
      • November (22)
      • October (2)

    Get Updates

    Subscribe via RSS
    TwitterFacebookLaconi.ca/Identi.caLinkedInFlickr
  • Resources

    • Lyla Captcha for CFML
    • Rooibos Bean Generator
    • Mach-II Framework for CFML
    • Presentations