Mar 19
MockBox can have many amazing uses. One well documented use is in assistance
in creating complicated unit tests insuring you are only testing one small unit of work, it can be used for many other interesting use cases.
One of the ways we find MockBox useful during our development cycle at Computer Know How is to Mock objects we haven't had the time to complete yet, but we do know what we expect as response. This allows us to continue development without waiting for the piece of something we haven't done yet slow us down, but keep the method calls exactly as they will be in when the object is complete.
So, how do you use MockBox outside of the context of a unit test? Well, its easy.
Inside a ColdBox application.
//get an instance of mockbox to use for mocking things not 100% built yet inside a ColdBox app
mockBox = createObject("component","coldbox.system.testing.MockBox").init();
Outside a ColdBox application.
//get an instance of mockbox to use for mocking things not 100% built yet outside a ColdBox app.
mockBox = createObject("component","mockbox.system.testing.MockBox").init();
Now that MockBox is initialized, we can start mocking objects. Lets say we have a User Object that we haven't had time to build yet. Right now it looks really advanced with lots of cool properties and functions that we spent a ton of time on. Something like this.
cfcomponent hint="I am the User ORM cfc"
/cfcomponent
Read more...
Mar 18
I am preparing to release the M5 milestone for ColdBox 3.0.0 and I am really amazed at how simple ColdBox 3 is becoming not only in syntax but in principle. I am really excited about this release as it is a push forward in ALL areas of development. Lots of modularity and re-architecture has gone into the core and the results have been amazing. A speed and performance improvement of over 20-30% from 2.6.4 on same code bases have usually been seen and that is without adding the speed of engines like Railo and CF9.
Not only that, we have made our motto: simplicity. That is why in this release (M5), you will see that we now have inheritless objects. All objects used within ColdBox are now simple CFCs that are mixed in or decorated at runtime by the engine. Not only that, the engine can discover the family type of the object and choose to decorate it or not. We have even added the ability to override and call virtual methods and thus giving the resemblance of inheritance. Anyways, too much information, but let's look at some cool code now.
Event Handler:
/**
* Cool simple component with few actions
* @cache true
* @cacheTimeout 45
*/
component{
function index(event){
var rc = event.getCollection();
rc.welcome = "Hi There";
event.setView("simple.index");
}
function sayHello(event){
return "Rendering a simple message baby!";
}
function renderHello(event){
event.renderData(data="<h1>Welcome to my world!</h1>");
}
}
Cool! Simple enough, 1 action sets a variable and sets a view for rendering, another view returns a string to be rendered and the third action uses renderdata to marshal data back to the screen. Easy enough hugh?
Plugins:
Plugins can also be now ANY CFC, no matter where it comes from, ColdBox will use it. Just drop it in the plugins convention folder and use! Also, simple CFCs.
/**
* My Awesome printing plugin
* @singleton true
*/
component{
/**
* @inject
*/
property name="dateService";
function init(){
setPluginAuthor("Luis Majano");
setPluginVersion("1.0");
setPluginDescription("A cool awesome printing module");
return this;
}
function printToday(dateFormat, timeFormat){
return dateService.getNow(argumentCollection=arguments);
}
}
Is that cool or what, no inheritance, cool annotations for persistance and dependency injection. So what about interceptors? The same man, what you think, we just tease you a bit.
/**
* My awesome AOP interceptor
*/
component{
/**
* @eventPattern ^(users?|security|admin)
*/
function preProcess(event,interceptData){
getPlugin("Timer").start("Processing-#event.getCurrentEvent()#");
}
/**
* @eventPattern ^(users?|security|admin)
*/
function postProcess(event,interceptData){
getPlugin("Timer").stop("Processing-#event.getCurrentEvent()#");
}
/**
* @interceptionPoint
*/
function onMyException(event, interceptData){
}
}
Now this is even more awesome, you can now define an annotation called "eventPattern" which is a regular expression that matches against the incoming event string. If it does, then it calls the interception point, else it ignores it. In this case, I will do AOP timing for events that start with "users,user,security,admin". Not only that you can also create an annotation called "interceptionPoint" and that tells the platform to register this method as a custom observation or interception point.
Ok everybody, more interesting posts about 3.0.0 are coming as development continues. Also, we have now almost fully documented all the new features and compatibilities in our new wiki:
Update: For all CF8 code snippets
<cfcomponent output="false" cache="true" cacheTimeout="45">
<cffunction name="index" output="false">
<cfargument name="event">
<cfscript>
var rc = event.getCollection();
rc.welcome = "Hi There";
event.setView("simple.index");
</cfscript>
</cffunction>
<cffunction name="sayHello" output="false">
<cfargument name="event">
<cfreturn "Rendering a simple message baby!">
</cffunction>
<cffunction name="renderHello" output="false">
<cfargument name="event">
<cfset event.renderData(data="<h1>Welcome to my world!</h1>")>
</cffunction>
</cfcomponent>
<cfcomponent output="false" singleton="true">
<cfproperty name="dateService" inject>
<cffunction name="init" output="false" returnType="any">
<cfscript>
setPluginAuthor("Luis Majano");
setPluginVersion("1.0");
setPluginDescription("A cool awesome printing module");
return this;
</cfscript>
</cffunction>
<cffunction name="printToday" returnType="any" output="false">
<cfargument name="dateFormat">
<cfargument name="timeFormat">
<cfreturn dateService.getNow(argumentCollection=arguments)>
</cffunction>
</cfcomponent>
<cfcomponent output="false">
<cffunction name="preProcess" output="false" eventPattern="^(users?|security|admin)">
<cfargument name="event">
<cfargument name="interceptData">
<cfset getPlugin("Timer").start("Processing-#event.getCurrentEvent()#")>
</cffunction>
<cffunction name="postProcess" output="false" eventPattern="^(users?|security|admin)">
<cfargument name="event">
<cfargument name="interceptData">
<cfset getPlugin("Timer").stop("Processing-#event.getCurrentEvent()#")>
</cffunction>
<cffunction name="onMyException" output="false" interceptionPoint="true">
<cfargument name="event">
<cfargument name="interceptData">
</cffunction>
</cfcomponent>
Mar 2
I was working more with Coldfusion 9 ORM and found another small caveat I thought I would share. When working with a relationship that is filtered, the implicit "has[property]", the has does not take into account the filter. The implicit get works as expected however. Consider the following persistent cfc...
Read more...
Oct 16
We did a hands on workshop at our Inland Empire User group yesterday in Pomona, California. We had fun installing CF9, Adobe CF Builder and ColdBox 3 Beta. We managed to build a simple task manager with all the new nice ORM features and coldbox 3.0.0 features. So if you are interested in seeing the workshop online, here is the recording: http://adobechats.adobe.acrobat.com/p79504808/.
If you would like to download the workshop assets, go to our IECFUG resources page to download it.
Jul 22
I have been asked quite a few times why not make a ColdBox lite
version where you can only have the basics? Well, not many people now
that this already exists. Therefore, I am linking to the SimpleMVC
template you can use if you are just starting with ColdBox. This
template is just the basic ColdBox conventions and a few settings,
that's it. This template will ease you in to ColdBox MVC development.
Once you are comfortable with just the basics of how to build apps with
conventions you can always add on and start brining in extra features
from the Coldbox Platform like: caching, logging, AOP, interceptors,
feed integrations, security, etc. However, you won't feel as
intimidated as if you where starting with a huge settings file.
The reason of having all the settings listed out is to tell the
developer that there are all these settings you can use. It is also
hard to create templates when everybody's level and approach is
different. However, this can be overwhelming to entry level users,
therefore we are now including the SimpleMVC template in the coldbox
downloads to come or you can download it from here now: http://www.coldbox.org/downloads/simpleMVC.zip (3.0 template)
So let's do a simple ColdBox for Newbies guide:
Read more...