Aliaspooryorik
ColdFusion ORM Book

cfspec has method with CF9 ORM

I've been hacking cfspec again! I'm working on a application which takes advantage of the ORM capabilities of ColdFusion 9. ColdFusion generates the getters and setters for you for each property of a persistent entity. Because of this, If you write the following test it will fail.


<cfimport taglib="/cfspec" prefix="">
<describe hint="model.foo.Bar Specification">

<beforeAll>
<cfscript>
// runs once before any "it" block

// load object but don't fire constructor
ClassInstance = CreateObject( "component", "model.foo.Bar" );

</cfscript>
</beforeAll>

<describe hint="Methods">

<it should="have a setName method">
<cfscript>
$( ClassInstance ).shouldRespondTo( "setName" );
</cfscript>
</it>

</describe>

</describe>

What cfspec does is to look at the functions information in the class metadata so it doesn't find the method you're looking for as generated methods are not reported.

You can get cfspec to recognise the method names by modifying the hasMethod function in cfspec/lib/Base.cfc. here is my modified version


<cffunction name="hasMethod" output="false">
<cfargument name="obj">
<cfargument name="methodName">
<cfset var metaData = getMetaData(obj)>
<cfset var funcs = "">
<cfset var func = "">
<cfset var properties = "" />
    
<cfloop condition="structKeyExists(metaData, 'extends')">
<cfif isDefined("metaData.functions")>
<cfset funcs = metaData.functions>
<cfloop array="#funcs#" index="func">
<cfif func.name eq methodName>
<cfreturn true>
</cfif>
</cfloop>
</cfif>
<!--- added to handle generated methods for persisted entities --->
<cfif isDefined("metaData.properties")
and isDefined("metaData.Persistent")
and metaData.Persistent>

<cfset properties = metaData.properties >
<cfloop array="#properties#" index="func">
<cfif ListFindNoCase( "remove#func.name#,#Left(methodName,3)##func.name#", methodName ) neq 0>
<cfreturn true>
</cfif>
</cfloop>
</cfif>
<!--- end of modified code --->
<cfset metaData = metaData.extends>
</cfloop>

<cfreturn false>
</cffunction>

The above works nicely, but isn't perfect. Ideally I should be checking to see if the property has a setter or getter attribute set to false. Also, I should really check for relationships & it's type for the addXYZ(), hasXYZ() and removeXYZ() methods. Maybe when I have a bit more time!

 


3 comments

  1. Nice. I have been reading about the BDD framework for Ruby called Cucumber and considered trying to do a port of it in CF. Cfspec is good enough that a port of Cucumber isn't essential.

    Do you know if CFSpec is still being developed or if its now dead? I think its a nice little framework and would be a shame if there's no active development for it.

    Comment by Alan Livie – September 06, 2010
  2. Hey Alan, I don't know if it's being actively developed at the moment, but it is pretty much feature complete. It has mocks built-in as well as the usual assertions.

    Comment by John Whish – September 06, 2010
  3. I've just found cfspec is on github github.com/adelphus/cfspec so if anyone wants to fork it and contribute they can.

    Comment by John Whish – September 06, 2010

Leave a comment

If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Please note: If you haven't commented before, then your comments will be moderated before they are displayed.

Please subscribe me to any further comments
 

Search

Wish List

Found something helpful & want to say ’thanks‘? Then visit my Amazon Wish List :)

Categories

Recent Posts