Wednesday, August 15, 2012

My Little Spy Function

I needed to spy on functions of an object and quickly came up with this little code to do much as i wanted.. For more advanced spying on javascript functions in your tests, consider using sinon.js or some other framework.
function Spy(funcName,obj){

 var originalFunction ;
    if(typeof obj === 'object'){
        originalFunction = obj[funcName];
    }
    else{
        originalFunction = global[funcName]
    }

 var numCalled = 0;
 var invocations = [];
 var spy = function(){
  numCalled++;
  invocations.push(arguments);
        if(typeof obj === 'object')
  return originalFunction.apply(obj,arguments);
        else
            return originalFunction.apply(global,arguments);
 }
 spy.calledOnce = function(){
  return numCalled == 1 ? true : false;
 }
 spy.times = function(num){
  return num == numCalled ? true : false ;
 }
 spy.firstCallWith = function(){
  return invocations[0];
 }
 spy.nthCallWith = function(n){
  return invocations[n-1];
 }
    if(typeof obj === 'object'){
        obj[funcName] =  spy;
    } else {
        global[funcName] =  spy;
    }
 return spy;
}
Now to spy on function emit of Dummy socket module below
var Socket = function(){
    function emit(name,message){
    }
    return {
        "emit" : emit
    }
}
exports['Line Parser not invoked since no socket is connected'] = function(test){
    test.expect(1);
    //given
    var socket = new Socket();
    var spy = new Spy("emit" , socket);
    //Run the test
    //verify the spy
    test.ok(spy.calledOnce(), "Socket.emit has been called once");

    test.done();
}

Monday, May 21, 2012

Maven in offline mode

I needed to tell maven to search my local repository only i.e maven should not try to connect to central repository.
Solution: just add -o flag like

maven -o clean install


Wednesday, April 25, 2012

Chef : Notify resource from ruby_block

Lets say for some sane/insane reason , you want to notify a resource to take some action from within ruby_block , you can accomplish it as follows


ruby_block "dummy" do
    block do
        if some_condition_is_true
           resources(:file => "create_file").run_action(:create)
        end
    end
end

file "create_file" do
         path "/tmp/test.txt"
         owner "you"
         content "dummy"
         action :nothing
end

Caveat :

       If file resource "create_file" further notifies another resource , that resource will not be notified. What i mean to say is that calling a resource from within ruby_block by using run_action method directly does not build up the notification chain . For example if file resource was as below


file "create_file" do
         path "/tmp/test.txt"
         owner "you"
         content "dummy"
         action :nothing
         notifies :run , resources(:execute => "some_script")
end
and file resource is notified from within ruby_block , then file resource will not further notify "some_script" resource.

Sunday, April 22, 2012

Game Of Life

Just finished Basic "Game Of life" simulation on HTML5 canvas. Here is the demo and here is the source code

I used kineticjs library to interact with canvas.

Thanks "this site" for button.

Monday, April 9, 2012

Nodejs Express : request.body is null

Just had an other frustration with nodejs and this time again problem with header and fault was mine since i missed Content-type header.
While writing a nodeunit test ,

exports.parseRequest = function(test){
 http = require('http')
 test.expect(1)
 options = {
  "host": "127.0.0.1",
  "port": 3000,
  "path": "/movies/",
  "method": 'POST',
  "headers" : {
   Content-Type":"application/x-www-form-urlencoded"
  }
 }  
 request = http.request(options,function(response){
  console.log("Status "+response.statusCode)
  result = ''
  response.on('data',function(chunk){
   result += chunk
  })
  response.on('end',function(){
   response.destroy() 
   test.equal(result,"Hello World", "Reponse got")
   test.done();
   
  })
 })
 request.on('error' , function (connectionException){
   console.log("ERROR occured while creating connection to localhost "+connectionException);
 })
 request.write("data=sheat");
 request.end();
}
and there you go , i missed that content-type header on line 10 above and ended up wasting 30+mins to figure out why request.body is 'undefined'. >Make the header adjust according to content , application/json etc

Friday, April 6, 2012

Nodejs : not sending host header by default


After having heard about nodejs for so long now , i decided to play with it today and unfortunately ended up in frustation when i was not able to make the below <20 lines code execute successfully.


var connection = http.createClient(80, "localhost");


var request = connection.request('GET', "/");

request.end();


request.on('response', function(response){
 
  var result = "";
  console.log(response.statusCode)
  response.on('data', function(chunk){
   result += chunk;
  })
  response.on('end', function(){
   console.log(result);
  })
  
});
 
connection.addListener('error' , function (connectionException){
 console.log("ERROR occured while calling Rotten Tomatoes Api "+connectionException);
})

I was initially making call to rottentomatoes api and was getting 400 , Bad request.
I changed hostname to localhost ( i had apache running locally) and was more frustated to see the same 400. This prompted me to check the apache error_log and this is what i was getting there

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23):

and little googling told me that nodejs does not send the host header by default [Stumped]. so i had to manually add the host header like below.
var request = connection.request('GET', "/" , {"Host":"localhost");


I am not sure but i think it should be a good idea to include some common headers by default in the request sent by nodejs.