How to get a locale specific date time value in C++

This took me a few hours of searching [c++, culture, locale specific, date time,....]

setlocale is your buddy here. There are sub categories - constants prefixed with LC_. You can change the locale for just date time for example.
setlocale when called with a NULL value for the second param returns the current locale set for the category [first param]
For different format strings, check MSDN for "strftime". %c, %x are formatstrings that take current locale into consideration.

This code snippet runs under VS20005. Tweak as per taste..
e.g. If you modify your locale - Control Panel > Regional Settings > Locale / Language to French

CString sCurrentLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");

CString strCurrentTime = CTime::GetCurrentTime().Format(_T("Generated : %#c"));
// produces "Generated : jeudi 31 janvier 2008 20:21:07"

setlocale(LC_ALL, sCurrentLocale );
strCurrentTime = CTime::GetCurrentTime().Format(_T("Generated : %#c"));
// produces "Generated : Thursday, January 31, 2008 20:23:08"

Show Me The Money-8.2 - Round 2 with fitnesse

Now lets get our acceptance tests to pass too. It’s time for ScrawnyBalboa vs Fitnesse Round2! Let’s open up the wiki and see what we made the last time. We need to update the path directive since we changed the project folder when we downgraded the rails version. We don’t need the date coz that would auto-set to be the creation date

!define COMMAND_PATTERN {ruby -I %p "L:/ruby_home/lib/ruby/gems/1.8/gems/fit-1.1/bin/FitServer.rb" -v}
!path "L:/Gishu/Ruby/Rails/ShowMeTheMoney"

# Lucky Charm : Sample Test Fixture to check if Ruby FitServer is reachable
!|eg.ArithmeticFixture|
|x|y|+|-|*|/|
|1|1|2|0|1|1|

!|fit.ActionFixture|
|start|AcceptanceTests.EnterInflowRecords|
|enter|inflow|PayDay|5000|
|check|currentBalance|5000|
|enter|inflow|Interest|1000|
|check|currentBalance|6000|
|enter|inflow|PayDay|5000|
|check|currentBalance|11000|
Ok so let’s run this. The table looks self-explanatory. We are adding three credit entries and verifying the balance. Now that reminds us we didn’t implement the currentBalance tracking part! Make a note of that Ok so let’s write the Fit fixture code.

file: ShowMeTheMoneu\AcceptanceTests\enter_inflow_records.rb

module AcceptanceTests
class EnterInflowRecords < Fit::Fixture
def inflow dateCreated, sDescription, fAmount
end
def inflow= inflowObject
end
def current_balance
return 0
end
end
end
Now click on test in the wiki. It says inflow= method is called but missing. Strange. I add some trace lines to figure out what is going on. Turns out the inflow= method is being called with only the description param. It looks to me that that there can only be a max of three columns ever in an action fixture table. Let’s modify our test table like this
!|fit.ActionFixture|
|start|AcceptanceTests.EnterInflowRecords|
|enter|description|PayDay|
|enter|amount|5000|

|press|addEntry|

|check|currentBalance|5000|

|enter|description|Interest|

|enter|amount|1000.50|

|press|addEntry|

|check|currentBalance|6000.50|

|enter|description|PayDay|

|enter|amount|5000|
|press|addEntry|

|check|currentBalance|11000.50|
So now lets get that fixture working ..
require File.dirname(__FILE__) + '/../test/test_helper'
require 'inflow_controller'
require 'fit/fixture'

class RailsHelper < Test::Unit::TestCase
def setup
@controller = InflowController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_dummy
end
end
module AcceptanceTests
class EnterInflowRecords < Fit::Fixture

attr_accessor :description, :amount
def initialize
@helper = RailsHelper.new("test_dummy")
@helper.setup
end
def addEntry
@helper.get :new
@helper.post :create, :credit => {:description => @description, :amount => @amount}
end
def current_balance
return Credit.count
end
end
end


Whoa! Lot of code there.
  • Since Rails has spoilt me.. I resorted to sneaky ways to glue my application code to the Fit table. The get and post methods are added to the Test::Unit::TestCase by Rails. Since our fixture has to inherit from Fit::Fixture, I turned to composition.. created a dummy test case derivation as a member of the fixture. Distilled out the essential things.. and it works!
  • Also current_balance as of now returns number of records in Credit table so that we know if the deal is going through (not what it should be doing but we will get to that).
Click Test to see it fail. And fail it does.
We’re seeing that record count is 2 + expected. We have 2 records in our fixture. Is that it ? A trace says Yes. So we stick in a Credit.delete_all in the test helper setup and we’re good! Now lets go after the current_balance implementation. We don’t have a controller page for it. For now let’s do the simplest thing that works… keep it in Credit itself as a class method. This test took me sometime.. I used assert_equal initially, then made a detour into coercing both arguments to same value and finally reached : ‘Remember when comparing 2 float values, use assert_in_delta’. Now it looks simple

file: \ShowMeTheMoney\test\unit\credit_test.rb

DELTA = 0.001 #tolerance  
def test_currentBalance
assert_in_delta totalAmountOfAllCreditEntries, Credit.currentBalance, DELTA, "Imbalance"
test_create
assert_in_delta totalAmountOfAllCreditEntries, Credit.currentBalance, DELTA, "Imbalance"
end

def totalAmountOfAllCreditEntries
obResultModels = Credit.find_by_sql("select sum(amount) as totalAmount from credits")
obResultModels[0].attributes["totalAmount"].to_f
end

file: \ShowMeTheMoney\app\models\credit.rb

def Credit.currentBalance
fCurrentBalance = 0
Credit.find(:all).each{|entry| fCurrentBalance += entry.amount}
fCurrentBalance
end


Ok now let’s get that acceptance test to pass. We correct current_balance method in enter_inflow_records.rb

def current_balance
Credit.currentBalance
end


And just like that Balboa lands one. Our first passing acceptance test!!

Next we can go on to implement the RowFixture table. But before that we need to incorporate deletes also into the above table. Hmm we need to spend more time thinking about our acceptance tests. We add some more steps to the above table to simulate the user choosing to delete the last record (hey everyone makes mistakes) and verifying that the current balance is still correct.

!|fit.ActionFixture|
|start|AcceptanceTests.EnterInflowRecords|

|check|currentBalance|11000.50|

|enter|select_entry|3|

|press|delete|

|check|currentBalance|6000.50|

We add some more steps to the above table to simulate the user choosing to delete the last record (hey everyone makes mistakes) and verifying that the current balance is still correct. We update the fixture code to deal with the new steps.

This gave me a bit of a fight.
  1. I initially used selectEntry as the table method to mark a record for deletion. Creating accessor :select_entry => undefined method ‘selectEntry’. Creating an accessor :selectEntry didn’t work => fit server wasn’t able to find select_entry=. In the end I just settled with select_entry in the html table.
  2. I initially implemented delete as shown below. This didn’t work – the record was not deleted.
    def delete
@helper.post :destroy, :id => @select_entry.to_i
end


Little spying around lead to ‘Record#1 doesn’t mean id#1’ Well that just skipped my mind. However that’s a good thing coz we now have another test that we missed – trying to delete a record via manually editing the url. Make a note. I add the Record# to Record id lookup and..

    def delete
@helper.post :destroy, :id => getID_ForSelectedEntry
end
def getID_ForSelectedEntry
obSelectedEntry = Credit.find(:all, :order => "id")[@select_entry.to_i - 1]
obSelectedEntry.id
end
Ta da!









Show Me The Money-8.1 - Finishing up validation

Iteration#1 : Day 8/10

Lets look at our iteration burndown. No points earned since we are still not complete.. we have Deleting Credit Entries and some UI polishing to do.
It shows that
  • Unless there is a time warp in the near future, we aren’t going to make it.
  • Do we have a problem. We aren’t going as fast as we hoped to. (The light trendline. Found Chart > Add Trendline… in Excel. Yay!). We could attribute some of that to the new tools and their learning curves.
On that challenging note, we begin our day.
We need to write the controller tests for validations. Test first as ever… rails doesn’t let us do much… it’s all taken care of! I’m coining a term for that -- ATCO

file: \ShowMeTheMoney\test\functional\inflow_controller_test.rb

  def test_createEntryWithNoDescription
[nil, " "].each{|value|
test_new
post :create, :credit => {:description => value, :amount => 120.23 }

assert_response :success
assert_template 'inflow/new'

assert_errors_on_page
assert_equal @numberOfFixtureRecords, Credit.count
}
end

def test_createEntryWithNilZeroOrNegativeAmount
[nil, 0, -4.5].each {|value|
test_new
post :create, :credit => {:description => "Salary", :amount => value }

assert_response :success
assert_template 'inflow/new'

assert_errors_on_page
assert_equal @numberOfFixtureRecords, Credit.count
}
end


assert_errors_on_page is a custom assertion added to test_helper.rb, that checks if there is an error div tag on the rendered view

file: \ShowMeTheMoney\test\test_helper.rb

class Test::Unit::TestCase
...

#custom assertions
def assert_errors_on_page
assert_tag :tag => 'div', :attributes => {:class => 'fieldWithErrors'}
end
end


All Green! So now we can move on to delete or destroy as Rails calls it. ATCO!!

file:\ShowMeTheMoney\test\unit\credit_test.rb

  def test_destroy
assert_nothing_raised { getFirstEntry }

getFirstEntry.destroy

assert_raise (ActiveRecord::RecordNotFound) { getFirstEntry }
end


file: \ShowMeTheMoney\test\functional\inflow_controller_test.rb

  def test_destroy
firstEntryID = credits(:salary_credit_entry).id
assert_nothing_raised { Credit.find(firstEntryID) }

post :destroy, :id => firstEntryID
assert_response :redirect
assert_redirected_to :action => 'list'

assert_raise(ActiveRecord::RecordNotFound) { Credit.find(firstEntryID) }
end

So there we have it. I think we have all we need for this story except the spiffy UI.

Show Me The Money-7 - At a Canter

Iteration#1 : Day 7/10

Lets start with some ‘functional’ a.ka. controller RETRIEVE tests now. Rails at our service as always, has a test stub awaiting..
Whoa! Whole lot of default tests in there. Let me see if they pass out of the box. No. All 8 fail with exceptions.
Lets comment out all the tests and take them one at a time. Lets take the functionality of listing existing records first to the block..

file:
ShowMeTheMoney\test\functional\inflow_controller_test.rb

class InflowControllerTest < Test::Unit::TestCase
fixtures :credits

def setup
@controller = InflowController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_list
get :list

assert_response :success
assert_not_nil assigns(:credits)
assert_equal 2, assigns(:credits).size
assert_template 'list'
end



To run my tests, I’m going to switch to rake. So I type in rake at the project dir and it’ll run all my model and controller tests they say. And it’s true! All Green!
Ok. Next we test if the default index action redirects to list. For that we just uncomment the test_index default test, which checks if the controller “does a list” when the index method is invoked. Green!
Now we move on to ADD.
First we verify the new action by uncommenting default test_new. Green!
Next we verify if we can add a new test by uncommenting test_create. Borriinng! This isn’t fair Rails is taking the fun outta this by doing everything… even writing my tests. I might as well watch some TV if I’m not needed here. Red! We have a red.. seems like it’s time to call in.. ME!
All Green! Spent 5 mins trying to determine the id of the newly created record.. before resorting to SQL to help me get the new record itself.
Let’s take a break!

  def test_create
test_new
numberOfCreditEntries = Credit.count
sDescription = 'my bank'
fAmount = 250000
post :create, :credit => {:description => sDescription, :amount => fAmount}

assert_response :redirect
assert_redirected_to :action => 'list'

assert_equal numberOfCreditEntries + 1, Credit.count
obCreditEntry = Credit.find( :first, :order => 'id DESC')
assert_equal sDescription, obCreditEntry.description
assert_equal fAmount, obCreditEntry.amount
end

VALIDATION
Alright, but what about the devious user’s who shall try to break our sacred system. What if he tries to save with no description or.. no amount?
So we write our concern as a model Test in credit_test.rb
def test_saveWithNoDescriptionFails
obCredit = Credit.find(1)
obCredit.description = " "

assert !obCredit.save, "Record saved without description!"
assert_equal 1, obCredit.errors.count
assert_equal "X", obCredit.errors.on(:description)
end

Red! The “X” is to check what the std error message is for validates_presence_of validator on the console when the test fails.
1) Failure:
test_saveWithNoDescriptionFails (CreditTest) [test/unit/credit_test.rb:37]:
Record saved without description!.
is not true.

3 tests, 12 assertions, 1 failures, 0 errors
So we add our tiny line to the Credit class
class Credit < ActiveRecord::Base
validates_presence_of :description
end


The next run tells us that the correct error message is “can’t be blank”. Obvious.. sheesh! Update our test. Green!

One more to check that amount is numeric, another to test that the amount is always positive. We also extracted a method to fetch the first record.
Adding the Is positive test broke the earlier Is numeric test. But a little tweaking and we’re in the green
file: ShowMeTheMoney\test\unit\credit_test.rb

def test_saveWithNoAmountFails
obCredit = getFirstEntry
obCredit.amount = " "

assert !obCredit.save, "Record saved with non-numeric amount!"
assert_equal 1, obCredit.errors.count
assert_equal "is not a number", obCredit.errors.on(:amount)
end

def test_saveWithZeroAmountFails
obCredit = getFirstEntry
obCredit.amount = 0

assert !obCredit.save, "Credit of amount 0 saved"
assert_equal 1, obCredit.errors.count
assert_equal "should be greater than 0", obCredit.errors.on(:amount)
end

private
def getFirstEntry
Credit.find(1)
end


credit.rb
class Credit < ActiveRecord::Base
validates_presence_of :description
validates_numericality_of :amount

protected
def validate
if (errors.on(:amount).nil?) && (amount <= 0)
errors.add(:amount, "should be greater than 0")
end
end
end


What happens if amount is assigned a nil value? Modified saveWithNoAmountFails and confirmed that it is caught and handled with an error message. Revert.

End of Day7


















Show Me The Money-6 - On Rails.. Toot! Toot!!

Iteration#1 : Day 6/10

The Story So Far: Alright, its been rough weather.
But now we got all that behind us and we can TDD our way to the end of the first story. Yup we’re on rails! Well I get the book again and rush thru Mike Clark's most excellent Chap12."Task T: Testing" for the nth time.

First we need to clone the structure from dev database to our test database. We can reuse the sql file (smart move!)
>mysql money_test <db\Create.sql -u gishu -p
We take Creation of credit enties first. MVC.. Model first.
Rails being helpful as always should have already created the test class file when we generated the scaffold.
CREATE
Well lets see if we can write a test to add a new credit entry.. Some chipping away here n there and we have..

file:
L:\gishu\ruby\Rails\ShowMeTheMoney\test\unit\credit_test.rb

require File.dirname(__FILE__) + '/../test_helper'

class CreditTest < Test::Unit::TestCase
#fixtures :credits

def setup
Credit.delete_all
end
def test_create
obCreditEntry = Credit.new
obCreditEntry.description = 'Payday'
obCreditEntry.amount = 5000
assert obCreditEntry.save, obCreditEntry.errors.full_messages.join("; ")

assert_equal 1, Credit.count
obCreditEntry.reload

assert_not_nil obCreditEntry.id
assert_not_nil obCreditEntry.created_at
assert_equal 'Payday', obCreditEntry.description
assert_equal 5000, obCreditEntry.amount
end
end


  1. first I had to comment out the fixtures directive because we are not using it yet. And it was blowing up with some exception on a test run. (Later found out it was due to the default fixture file was incomplete)
  2. The setup method blows away all the records in our table.
  3. test_create first adds a record, reloads the record data and verifies the create operation. All set for a test run
L:\Gishu\Ruby\Rails\ShowMeTheMoney>ruby test\unit\credit_test.rb
Loaded suite test/unit/credit_test
Started
.
Finished in 0.157 seconds.

1 tests, 6 assertions, 0 failures, 0 errors
Hey! We did not have to do anything to make it pass. Rails made the code pass. Anyway we should refactor – value duplication in the test. Introduce local vars
sDescription = 'Payday'
fAmount = 5000

RETRIEVE
Lets write one to verify that we can retrieve multiple stored records. Although it is taken care of by the previous test.. lets write one to be sure.
This time we will use Rails fixtures i.e. YAML (text) files whose contents are loaded into the test database for snappy testing.
So let’s edit it (auto-created like most things in Rails). Make sure you don't use tabs and indent using spaces.

file:
L:\gishu\ruby\Rails\ShowMeTheMoney\test\fixtures\credits.yml
salary_credit_entry:
id: 1
created_at: 2008-01-19 00:00:00
description: salary
amount: 15000
interest_credit_entry:
id: 2
created_at: 2008-01-20 00:00:00
description: interest
amount: 1000.50

You uncomment the magic-drippin’ line, which blows away the test DB, adds the two new records and loads them up into instance variables for us to use
fixtures :credits
And write a new test case
def test_retrieve
obCredit = Credit.find(1)
assert_kind_of Credit, obCredit
assert_equal @salary_credit_entry.id, obCredit.id
assert_equal @salary_credit_entry.description, obCredit.description
assert_equal @salary_credit_entry.amount, obCredit.amount
assert_equal @salary_credit_entry.created_at, obCredit.created_at
end


And we need to comment out the existing setup and test_create methods temporarily – they need to be updated to work with the rails fixture. So lets run the test case
test_retrieve(CreditTest):
RuntimeError: Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
test/unit/credit_test.rb:33:in `test_retrieve'
Some console trace lines later, I find that the records are being added to the test DB but the @credits hash and @salary_credit_entry are nil. NO! That can't be... the book says otherwise.
I’m beginning to think this project is jinxed.. however a little sleuthing turns this Mike Clark’s
(most excellent again) post up … Change in Rails defaults (test_helper.rb) again!
Apparently they switched on transactional fixtures and removed auto-created instance variables to make the unit tests go faster.
We can (always configure and) turn them back on using
self.use_instantiated_fixtures = true
OR
Update our test cases like this (and I didn’t need the _before_type_cast tricks like the book says)
def test_retrieve
obCredit = Credit.find(1)
assert_kind_of Credit, obCredit
assert_equal credits(:salary_credit_entry).id, obCredit.id
assert_equal credits(:salary_credit_entry).description, obCredit.description
assert_equal credits(:salary_credit_entry).amount, obCredit.amount
assert_equal credits(:salary_credit_entry).created_at, obCredit.created_at
end

That passes. Now to get the first test to work with fixtures.. we don’t need the setup method and I update the expected record account to 1 + 2 fixture records. That's all - ALL GREEN!



































Show Me The Money-5 - Feeling lucky today??

Iteration#1 : Day 5/10

Hmmm... I'm not getting the right vibe from our acceptance test.
An inflow entry would have a Date and a Description in addition to the amount. Our AccTest does not seem to indicate that.

Seems like we should be replacing our current table, with an ActionFixture+RowFixture combo. (Not its not a ploy to get the remaining fixture types into this example.)

An ActionFixture would simulate how the user would use an imaginary system, adding records one at a time.

The RowFixture would verify that all the inflow records have been persisted. Hmm.. I’ll quickly write up the tables and write the fixtures later post implementation of this feature. (I know I’ll be ambushed again. I’m gonna lie on the couch and get my strength back.. too much fitnesse for now.)

File: http://localhost:2345/ShowMeTheMoneyMain.TestsForTrackingInflowsS6

!define COMMAND_PATTERN {ruby -I %p "L:/ruby_home/lib/ruby/gems/1.8/gems/fit-1.1/bin/FitServer.rb" -v}
!path "L:/Gishu/Ruby/Rails/ShowMeTheMoney"

# Lucky Charm : Sample Test Fixture to check if Ruby FitServer is reachable
!|eg.ArithmeticFixture|
|x|y|+|-|*|/|
|1|1|2|0|1|1|

#!|AcceptanceTests.TestTrackInflows|
#|amountReceived|currentBalance()|
#|100|100|
#|500|600|
#|1200|1800|

!|fit.ActionFixture|
|start|EnterInflowRecords|
|enter|inflow|2008-01-13|PayDay|5000|
|check|currentBalance|5000|
|enter|inflow|2008-01-15|Interest|1000|
|check|currentBalance|6000|
|enter|inflow|2008-02-13|PayDay|5000|
|check|currentBalance|11000|

!|GetInflowRecords|
|receivedOn|description|amount|
|2008-01-13|PayDay|5000|
|2008-01-15|Interest|1000|
|inflow|2008-02-13|PayDay|5000|
Let take a look at our schedule..
We get 1 point each for 'Iteration planning',‘Setting up Fitnesse’ and ‘Write Acceptance Tests’. Making the tests pass would be part of the implementation task.
Burndown charts are brutally honest. The Y axis shows ideal hours pending (We now have 13 ideal hours of work left in this iteration) The X axis shows days into the iteration (We are at end of Day 4). We can easily create one from our iteration plan and the items we have completed.
As of now looks like we'll slightly overshoot.

So lets get cracking.. I’m upbeat.. feeling lucky today
First thing, the UI. The inflow record as mentioned before has 3 fields. From the CRUD (Create, Retrieve, Update and Delete) - we would need Create for sure. So lets start with that first.

Switch to our rails project dir.
First create our DB called money. Rails uses 3 DBs for different purposes as shown below.
I’m sloppy and impatient. After some mistakes and furious rectification.. Now I have to drop the Db and create it again. This time, we’ll put in a text file to save typing if something like this happens again.

File: ShowMeTheMoney/db/CreateDB.sql

drop database if exists money_development;
drop database if exists money_test;
drop database if exists money_production;
create database money_development;
create database money_test;
create database money_production;
grant all on money_development.* to 'gishu'@'localhost' identified by 'kaChing';
grant all on money_test.* to 'gishu'@'localhost';
grant all on money_production.* to 'gishu'@'localhost';

Now lets create the table. We’ll call it ‘credits’. So once again, we create a file DB\Create.sql like in the book.

File: ShowMeTheMoney/db/Create.sql

drop table if exists credits;
create table credits (
id int not null auto_increment,
created_at datetime not null,
description varchar(100) not null,
amount decimal(10,2) not null,
primary key (id)
);
Note: created_at is a special name which will get Rails to update that column auto-magically with the time of record creation. See Pg 227 of AWDWR First Ed

Next get it into the db, at the command prompt
  • >mysql -u gishu -p money_development
Now edit the config\database.yml file to help rails find-n-use our 3 DBs, modify each of the three groups in there as shown below.

File: ShowMeTheMoney/db/config.yml

development:
adapter: mysql
database:
money_development
host:
localhost
username:

password:
Now we run the Rails generate script to auto-create our classes. Rails 2.0.2 says it needs gem 0.9.4+ So lets get in from the online store
  • >gem update --system
  • >ruby script/generate scaffold Credit Inflow

Now it says --- "wrong number of arguments (1 for 2)"
We’re nearing the straw that will break this camel’s back. It’s times like these I’m relieved I don’t have a gun. Google Google.. Oh my god Rails 2.0 has real sharp horns – so much for ‘No surprises’. Scaffolding has been banished to an on-demand plugin! The only good blog-post (by Fairleads) I find recommends going back to 1.2 if you need to work with old tutorials / books etc.
Since I don't have the luxury of learning rails 2.0 just yet... You don’t have to ask me again.. Excuse me while I rollback my dev environment. Rails 1.2.6 it is. Install, create project, run scaffold generator.
“Can't connect to MySQL server on 'server' (10061)”

Just Great ! I guess I wasn’t that lucky today after all.
MySql though has great docs - http://dev.mysql.com/doc/refman/5.0/en/can-not-connect-to-server.html
Trying all those diagnostic steps showed me a diff. My port setting is 3307 not 3306 as in the doc. Edit database.yml, Add port: 3307 to all 3 groups. Restart Webrick.
Run scaffold generator again. Done. Browse to http://localhost:3000/Inflow and I can See! I can see the blessed view!!
Phew! That's it for today.. .

Show Me The Money-4 - Light at the end of the AccTest Tunnel

Iteration#1 : Day 3/10

The day is lost.. after quite a bit of grappling with RubyFit and Fitnesse.. all I get is 2 Exceptions and some command line output captured.. and I don’t see what the problem is. Error reporting has scope and need for improvement.
[I switch OFF the project clock. Overtime.. just this once!!]
Time to hit the forums after lots of fiddling with the paths and what nots.. (Days pass waiting for someone to answer … no answers.)


Let me go over the material that I have again with a fine-comb.
First stop Ron’s article. Most of it looks ok.. I’m doing it right. Wait.. the wise ron has worked in small steps.. He has a small wiki table to test something that comes along with the Ruby Fit Server implementation. So if that thing turns out green, I can be assured that Fitnesse is able to talk to my copy of Ruby FitServer. So I copy the table right out of Ron’s article and paste it into my Fitnesse test page..
!define COMMAND_PATTERN {ruby -v -I %p "L:/ruby_home/lib/ruby/gems/1.8/gems/fit-1.1/bin/FitServer.rb"}
!path "L:/Gishu/Ruby/ShowMeTheMoney"

!|eg.ArithmeticFixture|
|x|y|+|-|*|/|
|1|1|2|0|1|1|

!|AcceptanceTests.TestTrackInflows|
|amountReceived|currentBalance()|
|100|100|
|500|600|
|1200|1800|

Save and Click the test button and lets see what happens.. fingers crossed.

Now you tell me!! As we can see the ArithmeticFixture comes out all green.. conclusion Ruby FitServer is reachable. Now all of a sudden, we have all the information telling us what is wrong.. Strange. Spend another 20 mins trying to make it see the fixture by twisting the path directive this way and that … editing FitServer.rb to print out Ruby’s $LOAD_PATH variable to see if my directory has made it to the FitServer. All OK.. but “no cigar”.

I take a crack at it the next day. I scan material on the Ruby FitServer’s home page http://fit.rubyforge.org/basics.html
and BAM!
“In RubyFIT, that also is the name of the file containing the fixture, where the camel cased words are lied without capital letters and separated by underscores. Programmers can start creating a file named calculate_discount.rb and writing the skeleton of the CalculateDiscount fixture:”

Both Ron and Cory used one-word fixture names like People and Division… they don’t call em experts for nothing. RubyFit like Rails uses this internal conversion scheme of converting camelCase words to camel_case words
So I quickly go and rename my Ruby File from TestTrackInflows to test_track_inflows.rb
Click Test and now I get an error saying that my method ‘amount_received=’ is undefined. Ahh.. more of the same. Change the method names so that we have…

require 'fit/column_fixture'

module AcceptanceTests

class TestTrackInflows < Fit::ColumnFixture
attr_reader :balance
attr_accessor :amount_received
def initialize
@balance = 0
end
def current_balance
@balance
end
end

end


Re-test and we have red-hot ignition! WooHoo… please excuse me while I do that once again. WOO HOO !!!

It’ll be a while till I glue my application code to the test-table. So we’ll fake out the first result and see if we get a small green.. just to keep our spirits high. Sneaky tweak to the fixture method

def current_balance
#@balance
100
end
Sure enough!! We have a green. Rollback that temp hack.

Its time.. to do the victory jig.

Update:

Iteration#1 : Day 4/10

I’m penalizing one day to reflect reality. I did spend an awful amount of time trying to get all this running.






Show Me The Money - 3 - Fitnesse + Fit + Ruby oh my!

Iteration#1 Day 2/10

So lets start with Task : writing the acceptance tests for story#6 - tracking inflows
Voice of Customer (VOC) : Basically I'd be getting bags of money from different sources and it should add up to my current balance
Is that detailed enough? Lets find out by writing some executable specs a.k.a. acceptance tests to expose any hidden reqs. For that we need to get Fitnesse running with Ruby. That's another non-story task that we have. We already have fitnesse downloaded last time. Now we need to install a FitServer for Ruby.
  • d:\>gem install fit
I start the Fitnesse server by double clicking my (port- modified) run.bat file under the Fitnesse folder. Fire up a browser and verify it is up - http://localhost:2345

Next create a Main page for our Acc tests. Edit the URL to "http//localhost:2345/ShowMeTheMoneyMain"

Now click on the link show to create this page.
Now I need to add a comment - a quick search gets me this page. Yes the Fitnesse wiki has a Search button on the left just like Edit.. its not seen on the online version (to prevent web spiders apps) but its activated on your local copy of the wiki pages. I need to prefix the line with a # for a comment. Lets call the first page. TestsForTrackingInflowsS6. So we type that in and hit Save.
#This is the Main Page with links to all the acceptance tests for the app to track my money better
#
# ShowMeTheMoney
# ^TestsForTrackingInflowsS6
Now before we create the TestsForTrackingInflowS6 subwiki page, We need to mark this page as a Test Suite. We do that by opening up the page Properties (Button on the left), check the Suite property and click ‘Save Properties’. Now we click on the question mark link after the TestsForTrackingInflowsS6 to create the subwiki page. Here’s where we start writing our tests. VOC: Well its pretty simple, Every time I receive an amount, my current balance must be incremented by the same amount. Dev: Let me quickly write that up
!|TestTrackInflows|
!|AcceptanceTests.TestTrackInflows|
|amountReceived|currentBalance()|
|100|100|
|500|600|
|1200|1800|
Dev: Is this what we mean ?
VOC: Yup.

Ok so I save the page. Bid adieu to the customer for now.
We also need to check the Test property in Page Properties. Wait a sec, its already showing a Test button – seems like subwiki pages under a suite page have their Test property set by default... Cool. Lets try clicking that shiny blue button.
Dirty Yellow. "Could not find fixture : AccTestTrackInflows"

Ok. So lets create that ruby fixture – the glue between the wiki tests and our application code. A ColumnFixture should do the trick. Hmm.. seems like the
Ruby variant has some quirks of its own.
  • We need to rename the fixture as X.Y e.g.AcceptanceTests.TestTrackInflows.
  • Create a directory called X e.g. AcceptanceTests and place the ruby class file under it.
  • The class should be within a module under the same name as the parent folder - X has to be a module and Y a class within the module as seen in the example below
So we do all that. Phew! I create a folder under the rails project dir. Open up SCITE and create the fixture class - L:\Gishu\Ruby\ShowMeTheMoney\AcceptanceTests\TestTrackInflows.rb

require 'fit/column_fixture'

module AcceptanceTests

class TestTrackInflows < Fit::ColumnFixture
attr_reader :balance
attr_accessor :amountReceived
def initialize
@balance = 0
end
def currentBalance
@balance
end
end

end


Next we need to make Fitnesse run the Ruby Fit Server instead of the default one that talks Java. This is the page we need to read for details. (Thanks Andy D.)
We need to define the COMMAND_PATTERN as follows
Now I need to help the Wiki page find the fixture. I do that with the following directive at the top of the TestTrackingInflowsS5 page.
!define COMMAND_PATTERN {ruby -I %p "L:\ruby_home\lib\ruby\gems\1.8\gems\fit-1.1\bin\FitServer.rb" -v}
!path "L:\Gishu\Ruby\ShowMeTheMoney"

But the darn thing won’t work.

[Update: Cory Foy found out that the -v option must be at the "end" of the COMMAND pattern. See http://www.nabble.com/Re%3A-Re%3A-Trouble-getting-Fitnesse-to-play-with-Ruby-FIT-server-p14782769.html
]









Show Me The Money - 2

Iteration Day 1/10
First step we need some version control and a CIS...
the book mentioned a project named DamageControl but that looks like it has closed shop for now. Some more surfing... CIA.. Cerebrus.. CruiseControl.rb aha!
I download the latest cruisecontrolrb-1.2.1.tgz, that along with the Getting Started page
was all that I needed.
I created a rails project on my machine with
  • l:\Gishu\Ruby>rails ShowMeTheMoney
then used Tortoise SVN to import the folder into the repository. You could also do it manually with
  • l:\Gishu\Ruby\ShowMeTheMoney> svn import -m "First Rails App into Version Control" svn://babybox/ShowMeTheMoney/trunk
Next I add a proj to cruisecontrol.rb with
  • D:\cruisecontrolrb-1.2.1>cruise add ShowMeTheMoney --url svn://babybox/ShowMeTheMoney/trunk
and start up the webrick server with
  • D:\cruisecontrolrb-1.2.1>cruise start
Yup that's what it says.. should work.. but didn’t. WWOOTB – won’t work out of the box.
Crazy gem of activesupport won't load.. seems like it wont load the gem version that comes along with cruisecontrol.rb.. Precious time is lost reinstalling various components, trying mailing lists and basically trying to beat the thing into submission.

[Many days later.. inertia is a leech]
And I make the mistake of waiting for cc.rb to be operational. Suddenly one day on my way back from work.. I have a pair of stunning revelations just like that
#1: There is nothing to build like in C#/Java
#2: I only need a CIS to run all the tests and inform me if someone breaks the build. Since I'm the only one working, I just have to watch myself.

I can proceed without cc.rb working right now. Now wiser and 1 day of our iteration time later, I trudge on to start ‘delivering value’.. we gotta start with that sometime soon if we want to be 'agile'.

[Alexey V. spent some time trying to get a handle on this thing.. ruby versions, gem versions, stack traces,... all in vain.]

Show Me The Money - 1

So once again I embark on another exploratory voyage to scratch an itch ..

I have trouble tracking my money. Frankly because it is too boring..
Some time back, I attended a leadership course that had a module on Finance.. and predictably I went through it like greased lightning.. I resolved to diligently go through those notes soon. Still haven't :)
Now that I know a bit about cashflow and balance sheets, I would like to create them.. and since it sucks the joy out of me.. I'd rather like someone else to do it for me... my computer. Nothing too fancy.. just basic stuff.

Around the same time, I get enchanted with Rails.. So it's time to put my knowledge to the sword. And since I don't want this to be too easy, I'm going to practice what I read in Mike Cohn's book on Agile Estimation.

So I'm going to try to be as agile as I possibly can and get a working application and lots of learning out of this. I christen this app - ShowMeTheMoney like Cuba Gooding yelled out in Jerry Maguire.

Since I do this in my personal off-office time, we need to scale down time units
1 day => 2 hrs of real time
1 Iteration (2 weeks - 10 days) => 20 hrs of real time

So I come with the list of stories for this app as seen in Sheet#1

I play a bit of "planning poker" (with myself due to constraints) to come up with the story point estimates.. Looks like 14 story points in all.

So quickly let's ask the customer (Me again) to see which ones is most important to him. I pick 6, 1 and 2 to allow me to enter receipts and expenditures as that constitutes a working product.

Lets break this down into itsy bitsy tasks first. Thats seen in Sheet 3. We come with an estimate of 27 ideal hrs including some project preparation tasks like setting up a build server.
I'd like to keep some slack since I'm dealing with new tech here. So we'd plan for 15 hours of work in the first iteration - 75% utilization. I choose to leave out of Story#2 - Group expenses by category for now; we'll have a usable app tracking my transactions and we can build in categorization later.

So we're aiming for 2 story points this iteration. This is our initial velocity. Dividing total number of story points (14) by velocity (2), gives us 7 iterations. Since this is the start of the project, we're not too confident of this estimate.. so it would be wise to state this estimate as a range - multiplying 7 by 0.6 and 1.6,

Release Plan
Our initial estimate is 4 to 11 iterations. We're not saying 4 or 11 but rather that it may take that much time. Only results from actual iterations will help us improve our estimate and narrow down this range.

[A few hours later]
I finished reading Pragmatic Project Automation and strafed again thru Pragmatic Version Control. Let's begin..