This is a listing of all the source files produced till now in this iteration (Note: Some of it comes from the next couple of posts i.e. the pagination plugin. It is more of a snapshot after post ShowMeTheMoney-6
file: /test/unit/expense_test.rbrequire File.dirname(__FILE__) + '/../test_helper'
class ExpenseTest < Test::Unit::TestCase
fixtures :expenses
def setup
@firstExpense = getFirstEntry
@fixtureRecordCount = 3
end
def test_create
sDescription = 'Rent'
fAmount = 10000
obExpenseEntry = Expense.new
obExpenseEntry.description = sDescription
obExpenseEntry.amount = fAmount
assert obExpenseEntry.save, obExpenseEntry.errors.full_messages.join("; ")
assert_equal @fixtureRecordCount + 1, Expense.count
obExpenseEntry.reload
assert_not_nil obExpenseEntry.id
assert_not_nil obExpenseEntry.created_at
assert_equal sDescription, obExpenseEntry.description
assert_equal fAmount, obExpenseEntry.amount
end
def test_retrieve
assert_kind_of Expense, @firstExpense
assert_equal expenses(:rent_expense_entry).id, @firstExpense.id
assert_equal expenses(:rent_expense_entry).description, @firstExpense.description
assert_equal expenses(:rent_expense_entry).amount, @firstExpense.amount
assert_equal expenses(:rent_expense_entry).created_at, @firstExpense.created_at
end
def test_saveWithNoDescriptionFails
[nil, " "].each{|value|
@firstExpense.description = " "
assert !@firstExpense.save, "Record saved without description!"
assert_equal 1, @firstExpense.errors.count
assert_equal "can't be blank", @firstExpense.errors.on(:description)
}
end
def test_saveWithNoAmountFails
[nil, " "].each{|value|
@firstExpense.amount = value
assert !@firstExpense.save, "Record saved with non-numeric amount!"
assert_equal 1, @firstExpense.errors.count
assert_equal "is not a number", @firstExpense.errors.on(:amount)
}
end
def test_saveWithZeroOrNegativeAmountFails
[0, -24.00].each{|value|
@firstExpense.amount = value
assert !@firstExpense.save, "Credit of amount 0 saved"
assert_equal 1, @firstExpense.errors.count
assert_equal "should be greater than 0", @firstExpense.errors.on(:amount)
}
end
def test_destroy
assert_nothing_raised { getFirstEntry }
getFirstEntry.destroy
assert_raise (ActiveRecord::RecordNotFound) { getFirstEntry }
end
private
def getFirstEntry
Expense.find(1)
end
end
file: /app/models/expense.rbclass Expense < 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
file: /test/functional/outflow_controller_test.rbrequire File.dirname(__FILE__) + '/../test_helper'
require 'outflow_controller'
class OutflowController; def rescue_action(e) raise e end; end
class OutflowControllerTest < Test::Unit::TestCase
fixtures :expenses
def setup
@controller = OutflowController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@fixtureRecordCount = 3
end
def test_new
get :new
assert_response :success
assert_template 'new'
assert_not_nil assigns(:expense)
end
def test_list
get :list
assert_response :success
assert_template 'list'
assert_not_nil assigns(:expenses)
assert_equal(@fixtureRecordCount, assigns(:expenses).size )
assert_equal(3, assigns(:expenses)[0].id, "not ordered by date")
assert_equal(1, assigns(:expenses)[1].id)
assert_equal(2, assigns(:expenses)[2].id)
end
def test_index
get :index
assert_response :success
assert_template 'list'
end
def test_create
test_new
sDescription = "movies"; fAmount = 140;
post :create, :expense => {:description=>sDescription, :amount=>fAmount}
assert_response :redirect
assert_redirected_to :action => 'list'
assert_equal @fixtureRecordCount+1, Expense.count
obExpenseEntry = Expense.find(:first, :order=>'id DESC')
assert_equal(sDescription, obExpenseEntry.description)
assert_equal(fAmount, obExpenseEntry.amount)
end
def test_destroy
rentExpenseID = expenses(:rent_expense_entry).id
assert_nothing_raised { Expense.find(rentExpenseID) }
post :destroy, :id => rentExpenseID
assert_equal @fixtureRecordCount - 1, Expense.count
assert_raise(ActiveRecord::RecordNotFound) { Expense.find(rentExpenseID) }
assert_redirected_to :action=>'list'
end
end
file: /app/controllers/outflow_controller.rbclass OutflowController < ApplicationController
def list
@expenses = Expense.paginate :per_page=>10, :page=>params[:page], :order=>'created_at'
end
def index
list
render :action => 'list'
end
def new
@expense = Expense.new
end
def create
@expense = Expense.new(params[:expense])
if (@expense.save)
flash[:notice] = 'Expense entry saved'
redirect_to :action=>'list'
else
render :action=>'new'
end
end
def destroy
Expense.find(params[:id]).destroy
redirect_to :action=>'list'
end
end
file: /app/views/outflow/_form.rhtml
<%= error_messages_for(:expense) %>
<!-- Form for expense -->
<table>
<tr>
<td>
<label for='expense_created_at'>
<%= getAppString(:label_created_at) %>
</label>
</td>
<td>
<%= datetime_select 'expense', 'created_at' %>
</td>
</tr>
<tr>
<td>
<label for='expense_description'>
<%= getAppString(:label_description) %>
</label>
</td>
<td>
<%= text_field 'expense', 'description' %>
</td>
</tr>
<tr>
<td>
<label for='expense_amount'>
<%= getAppString(:label_amount) %>
</label>
</td>
<td>
<%= text_field 'expense', 'amount' %>
</td>
</tr>
</table>
file: /app/views/outflow/new.rhtml
<h1> <%= getAppString(:title_new_expense_page) %></h1>
<% form_tag :action=>'create' do %>
<%= render :partial=>'form' %>
<%= submit_tag getAppString(:label_button_add) %>
<% end %>
<%= link_to getAppString(:label_link_back), :action=>'list' %>
file: /app/views/outflow/list.rhtml
<h1><%= getAppString(:title_list_expense_page)%></h1>
<hr/>
<table class='detailsTable'>
<tr>
<th><%= getAppString(:label_created_at) %></th>
<th><%= getAppString(:label_description) %></th>
<th><%= getAppString(:label_amount) %></th>
</tr>
<% for expense in @expenses %>
<tr>
<td class='transactionDate'> <%= h( expense.created_at.strftime("%d %b %Y" ) ) %> </td>
<td class='transactionDescription'> <%= h( expense.description ) %> </td>
<td class='transactionNumeric'> <%= h( sprintf("%0.2f", expense.amount) ) %> </td>
<td class='delete'><%= button_to getAppString(:label_button_delete), \
{ :action => 'destroy', :id => expense.id },
:confirm => getAppString(:confirm_delete),
:method => :post %></td>
</tr>
<% end %>
</table>
<hr/>
<%= will_paginate @expenses %>
<%= button_to getAppString(:label_button_new), :action => 'new' %>
file: /app/helpers/application_helper.rb
module ApplicationHelper
class ResourceManager
@strings = {
:label_created_at => "Date",
:label_description => "Description",
:label_amount => "Amount",
:label_button_new => "New Entry",
:label_button_add => "Create",
:label_button_delete => "Delete",
:label_link_back => "Back",
:title_new_credit_page => "Yay! Enter credit details here..",
:title_new_expense_page => "Sigh! Enter expense details here..",
:title_list_credit_page => "Inflows",
:title_list_expense_page => "Outflows",
:confirm_delete => "Are you sure you wish to delete this ?",
}
def ResourceManager.getString( sKey )
sKey = @strings[sKey] || "Not found!";
end
end
def getAppString( stringID )
ApplicationHelper::ResourceManager.getString(stringID)
end
end