Baking cakes with CakePHP.

  • Bugfix release for the OpenID component & an example application

    Last week I received a mail from a user of the OpenID component in which he described that it wasn’t possible to login with OpenIDs from claimID and Blogger. After some debugging I found the reason for this problem: a bug in the isOpenIDResponse() method. The method only recognized responses from providers using OpenID 2.0, but not from providers still using the older OpenID 1.x… So, if you are using this method in your code, please upgrade to the latest version (v2010-07-17).

    I also got asked whether there is an example application that shows the usage of the OpenID component. As I already use a very simple application to test the component manually, I pushed this application to GitHub (you can see the application in action on http://openid-example.42dh.com/). I hope this will make it easier for some of you to get started with the OpenID component.

    0 comments

  • Grouping “constants” with JavaScript

    A while ago I wrote about how you can group related constants in PHP5 by using a constants class:

    class MyConstants {
        const AA = 'value';
        const BB = 'another value';
    }
    
    echo MyConstants::AA; // output: value
    

    Now, while experimenting with JavaScript (or more precisely with Node.js) I got some constants in my code I wanted to organize with such a constants class. My first, albeit naive, approach looked like:

    var sys = require('sys');
    
    function MyConstants() {
        const AA = 'value';
        const BB = 'another value';
    }
    
    sys.puts(MyConstants.AA); // output: undefined
    

    However, as you can see, this doesn’t work. One reason is that const “[c]reates a constant that can be global or local to the function in which it is declared.”. So it isn’t possible to create a constants class like I imagined…

    This means we have to emulate a constants class by using static properties and relying on the naming convention that names of constants are uppercased (i.e. the “constants” are technically not constants and their value can be changed):

    var sys = require('sys');
    
    function MyConstants() {
    }
    
    MyConstants.AA = 'value';
    MyConstants.BB = 'another value';
    
    sys.puts(MyConstants.AA); // output: value
    

    If there is a better approach, please let me know.

    5 comments

  • OpenID component v2010-05-19 released

    As mentioned in the title, I released a new version of the OpenID component today. It’s a maintenance release: the only change is an update of the bundled PHP OpenID library from version 2.1.2 to 2.2.2. With this change you no longer have to patch the OpenID library if you are working with PHP 5.3.

    To update, simply replace the OpenID component and the content of the “vendors/Auth” folder (and its subfolders) with the files from the zip archive.

    You can download the new version from Github.

    3 comments

  • Sassy CSS

    Those who follow me on Twitter probably know about my love-hate relationship with CSS. To ease the pain of working with CSS I switched to Compass, a stylesheet authoring framework. With Compass, you write the stylesheets in Sass (Syntactically Awesome Stylesheets) instead of CSS. Sass is basically CSS without brackets and semicolons, as you can see in this example from the Sass website:

    h1
      height: 118px
      margin-top: 1em
    
    .tagline
      font-size: 26px
      text-align: right
    

    However, with the upcoming Sass 3 (it is planned to be released on May 10, 2010) a new format gets introduced: SCSS (Sassy CSS). It is a superset of CSS, i.e. each CSS file is automatically a SCSS file (you simply have to change the file extension from “css” to “scss”). So the example from above in SCSS is just plain CSS:

    h1 {
      height: 118px;
      margin-top: 1em;
    }
    
    .tagline {
      font-size: 26px;
      text-align: right;
    }
    

    Not that exciting, isn’t it?

    Where SCSS shines is when it comes to the integration of the Sass features (nesting, variables, and mixins) into this format. The devs did a very good job to make it feel like those features are native CSS.

    Let’s have a look at some examples.

    Nesting:

    #header {
      background: gray;
      a {
        background: white;
        color: black;
      }
    }
    

    Variables:

    $background_color: gray;
    
    #header {
      background: $background_color;
    }
    

    Mixins:

    @mixin red_border($border_width) {
      border: $border_width solid red;
    }
    
    #box_a {
      @include red_border(5px);
    }
    
    #box_b {
      @include red_border(10px);
    }
    

    Personally I really like the new SCSS format, and I can only recommend to try it out for yourself.

    10 comments

  • Speed up your tests with Hydra

    Nowadays most computers come with more than one processor. And so it makes sense to use the additional processing power to speed up your tests by distributing them across the available processors.

    One tool that helps with this is Hydra. It allows you to distribute tests across multiple processors and machines, and currently supports the Test::Unit, Cucumber, and RSpec frameworks. In this article I will focus on running Cucumber tests on a single machine.

    As Hydra is distributed as a Ruby Gem its installation is pretty simple:

    gem install hydra
    

    After that, you have to add Hydra to the Rakefile of the respective project. And you have to specify the Cucumber task and the files it should use.

    # Rakefile
    require 'hydra'
    require 'hydra/tasks'
    
    Hydra::TestTask.new('hydra:cucumber') do |t|
      t.add_files 'features/**/*.feature'
    end
    

    As last step you have to create a “hydra.yml” file in the “config” folder of your project. Here you define whether the tests should run locally, and how many runners Hydra should start. Runners correspond to processors, and so the setting below is for a dual core machine.

    # config/hydra.yml
    workers:
      - type: local
        runners: 2
    

    With everything set up, you can now run the tests with the following command:

    $ RAILS_ENV=test rake hydra:cucumber
    

    To verify whether there is really a speed gain when running the tests in this way you have to do some kind of a benchmark (see the example below), because running something on multiple processors doesn’t necessarily mean it is faster…

    Happy testing!
     


    For my (unscientific) benchmark I ran my test suite (consisting of 12 files with 43 scenarios and 193 steps) with the following commands five times and averaged the results:

    $ time cucumber features
    $ time rake cucumber
    $ time RAILS_ENV=test rake hydra:cucumber
    

    In the first scenario I ran the benchmark with no other user applications running, i.e. both processors were available for the task at hand. From the results you can see that using Hydra in such a scenario is the fastest solution.

    cucumber: 24.1s
    cucumber with rake: 31.4s
    hydra:cucumber: 22.4s
    

    In the second scenario I ran the benchmark in a typical development environment with many open applications, i.e. around 1.5 processors were available. This time, using Hydra is not the fastest solution, the overhead is bigger than the speed gain from having more than one processor .

    cucumber: 25.9s
    cucumber with rake: 34.3s
    hydra:cucumber: 30.6s
    

    4 comments

© daniel hofstetter. Licensed under a Creative Commons License