CSS

Watchr : simple continuous testing tool

Watchr is a pretty cool and simple tool for saving developer's time.

According to the preject description, watchr is:
Agile development tool that monitors a directory tree, and triggers a user defined action whenever an observed file is modified. Its most typical use is continuous testing, and as such it is a more flexible alternative to autotest.

But moreover, Watchr can be used on every simple task that need to execute a file, like markdown generate, coffee script compile, and the syntax is so simple to add those task in watchr script.

The syntax is like:

watch 'regular expression' { |matched_file| action_for matched_file }

#listen to all file and print filename when it modified
watch('.*') {|match| puts match[1]}

#listen to ruby file and run test
watch('lib/(.*)\.rb') {|match| system("ruby test/test_#{match[1]}.rb") }

#match[0] is full filename, match[1] is filename without extname.

running under command:
watchr script_name

Continous Testing


Continous Testing is a concept born from MIT Program Analysis Group,
It improve the Test Driven Development, which is auto run the corresponding test
in TDD right after the code saved. In this way, the test time lag will be reduced to zero,
and programer won't need to run the test to know the program is work or not. Makes testing become natural behavior in development.

Refers


ihower's rails3 watchr script template
Doc generate template from watchr project itself (dog fooding)

mini BDD Framework in CoffeeScript

Rails 3.1 is default supporting Coffee-Script,

This might be controversial, but basically I think it is a right move,
since rails development philosophy is always simplify developer's life.
And coffee script sure is.


compare the following code with javascript and coffee script:
describe('spec in javascript', function(){
  it('should return true in javascript',function(){
    return 1===1;
  });
});

//in coffee script
describe 'spec in coffeescript', ->
  it 'should return true in coffeescript',->
    1 is 1

You can see how the syntax has been simplified and easy to read.

Inspired by A unit test framework in 44 lines of ruby, I want to write a test framework in coffeescript to show the good of it.

Here's the work:
dsl =
  tests : {}
  it : (description,test) ->
    @tests[description] = test
  parse:(block)->
    block.call(dsl)
    @tests

class Executor
  constructor: (@description,@tests) ->
  tests : {}
  success : 0
  fail : 0
  count : 0
  run:()->
    console.log(@description + " ::")
    @execute desc,test for desc,test of @tests
    console.log("Executed #{@count} tests: #{@success} success, #{@fail} fail")

  execute : (desc,test) ->
    test_result = test()
    if test_result is yes than @success += 1 else @fail += 1
    @count += 1
    console.log(" --"+ desc + " is "+ test_result)

exports.describe = (description,block) ->
  executor = new Executor(description,dsl.parse(block))
  executor.run()

with the following testcase

spec = require './nspec'

spec.describe 'hello coffee test', ->

  @it 'should be true', ->
    1 is 1

  @it 'should fail', ->
    1 is 2

Basically the describe function contains all tests in callback,
and will parse all the testcase by
block.call(dsl)
which inject the dsl functions as the "this" object in block, and the "it" syntax will collect the test functions to a map object.
afterward, Executor will execute all tests and print out results.

During the implementation, I can't find the way to remove that nasty @ before test function 'it'
without declaring global. I am still working on it, there's a solution that you can execute test
by calling node.js child_process "coffee spec.coffee"(from coffee-spec), but that will be too complex for this. Jasmine didn't have this problem, let me know if anyone got the answer, or I will figure it out later :p.

Foursquare API with oauth2 gem

The oauth things is pretty complex, here is some notes that may avoid you fall into the same pitfall as me.

You can read the whole spec here.

But basically, it provide a interface let website can access the user's data in other website.
User will first be redirect to that website, click confirm, and redirected back to the callback page.

In the back end, the process of server is:
1.Send request to target website for token, with the server's client_id & secret_id
2.Redirect user to authorize page with token (and callback url)
3.After user confirm, user will be redirect to the callback page with a access_token
4.Save the access_token, and free to call target server for user data.

However, using gem to manage those things seen like a smart way, but still, it may not work correctly because of some error:

#pitfall 1

Check the api is using oauth or oauth2,
which is different when choosing the oauth gem.

#pitfall 2

check the oauth_path, access_token_path is correct
the default setting of gem may not work with the api you choose.

#pitfall 3

check the api address,
in foursquare, the authorize url is : https://foursquare.com/oauth2/authorize
however, the api is not under the same subdomain, is under https://api.foursquare.com/

make sure those setting is correct, and you will feel the sweet of oauth!

here's the code with sinatra:

require 'sinatra'
require 'oauth2'

get '/auth' do
  redirect to(client.web_server.authorize_url(:redirect_uri =>
                                              "http://myhost/callback"))
end

get '/callback' do
  #make sure the access token is named "code"
  access_token = client.web_server.get_access_token(params[:code],
                                      :redirect_uri => "http://myhost/callback")
  access_token.get('https://api.foursquare.com/v2/users/self')
  # save your access token in session or db...
end

def client
  client ||= OAuth2::Client.new(
  YOUR_CLIENT_ID,YOUR_SECRET_ID,
  :site => 'https://foursquare.com',
  :authorize_path => '/oauth2/authorize',
  :access_token_path => '/oauth2/access_token')
end

HTML5 push state

Recently I was trying to make a slide pages effect, and I realize there are some obstacle to let the browser work properly on next/back page. because you can only change the #hash value of url but the real url without redirect, the old ajax problem.

But wait a minute, is the github use the ajax page slide effect and work perfectly? After a peek on the source, I found they are using the html5 pushstate api on webkit and ff4, which can let you change the url without actually redirect the page.

sample:
$(function(){
  //check if the browser support it.
  $.get('/new_page',function(data){
    if(history.pushState){
      //push the url to the browser history, with state object and title.
      history.pushState({isAjax:true},"push the state"), 'new_page');
    }
    //update the data...
  });
  //popstate event will triggered whenever the url changed
  //but the page won't reload if url is pushed into history
  //so you have to update page yourself or reload it.
  $(window).bind("popstate",function(e){
    if (e.state.isAjax) {
      //make the ajax call for update page
    }
  });
});

try it yourself by typing
history.pushState({},"test","/test:);
in your browser console, and you'll see the effect.

reference: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history