refactored context model spec to be a bit more 'rspec-ish' and to use skinny_spec and scenarios

This commit is contained in:
Simon Rozet 2008-06-23 12:56:47 +02:00
parent d62cbf4592
commit e8d1ba2633
4 changed files with 121 additions and 146 deletions

View file

@ -1,150 +1,105 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
module ContextSpecHelper
def valid_context_attributes describe Context do
{ def valid_attributes
:name => "FooBar", {:name => 'Errands'}
:position => 1, end
:hide => true,
:user_id => 1
}
end
end
describe "Context validations" do
include ContextSpecHelper
before(:each) do before(:each) do
@context = Context.new @context = Context.new
end end
it "should be valid" do it 'has many users' do
@context.attributes = valid_context_attributes Context.should have_many(:todos).
@context.should be_valid with_order('todos.completed_at DESC').
@context.save with_dependent(:delete_all).
Context.should have(4).records # 3 in fixtures 1 set up here with_include(:project)
end end
it "should have two errors with a missing name" do it_should_belong_to :user
@context.attributes = valid_context_attributes.except(:name)
@context.should_not be_valid it_should_validate_presence_of :name, 'context must have a name'
@context.should have(1).error_on(:name) it_should_validate_length_of :name, :maximum => 255,
@context.error_on(:name).should include('context must have a name') :message_too_long => 'context name must be less than 256 characters'
it_should_validate_uniqueness_of :name, 'already exists' # TODO: scope user_id
it_should_not_accept_as_valid :name, ',',
:message => "cannot contain the comma (',') character"
it 'is hidden when hide is true' do
Context.new(:hide => false).should_not be_hidden
Context.new(:hide => true).should be_hidden
end end
it "should have one error with a name of more than 255 characters" do it 'produces correct summary depending on visibility' do
@context.name = "z" * 256 Context.new(:hide => true).summary(3).should == '<p>3. Context is Hidden.</p>'
@context.should_not be_valid Context.new(:hide => false).summary(3).should == '<p>3. Context is Active.</p>'
@context.should have(1).error_on(:name)
@context.errors.on(:name).should eql("context name must be less than 256 characters")
end end
it "should have one error with name containing comma" do it 'returns name as title' do
@context.name = "Foo,Bar" Context.new(:name => 'foo').title.should == 'foo'
@context.should_not be_valid
@context.should have(1).error_on(:name)
@context.errors.on(:name).should eql("cannot contain the comma (',') character")
end
it "should have one error if name already exists for user" do
@existing_context = Context.new
@existing_context.attributes = valid_context_attributes
@existing_context.save
@context.attributes = valid_context_attributes
@context.should_not be_valid
@context.should have(1).error_on(:name)
@context.errors.on(:name).should eql("already exists")
end end
it "should have one record in Context model class" do it 'returns an instance NullContext for null_object' do
@context.name = "FooBar" Context.null_object.should be_an_instance_of(NullContext)
@context.save
Context.should have(4).records # 3 in fixture, one set up here
end
end
describe "Context model" do
fixtures :users, :todos, :contexts, :preferences
include ContextSpecHelper
it "should show hidden" do
contexts(:call).should be_hide # :hide should be true
end end
it "should be produce correct .summary text for hidden context" do it "returns feed options with description containing user's name" do
contexts(:call).summary(1).should eql("<p>1. Context is Hidden.</p>") user = mock_model(User, :display_name => 'simon')
feed_options_for_user = Context.feed_options(user)
feed_options_for_user[:title].should == 'Tracks Contexts'
feed_options_for_user[:description].should == 'Lists all the contexts for simon'
end end
it "should show not hidden" do describe 'when finding by namepart' do
contexts(:call).hide = false scenario :todos
contexts(:call).should_not be_hide # :hide should be true
end
it "should produce correct .summary text for active context" do it 'finds with exact match' do
contexts(:call).hide = false Context.find_by_namepart('errand').should == contexts(:errand)
contexts(:call).summary(1).should eql("<p>1. Context is Active.</p>") end
end
it "should return .title which matches name" do it 'finds with partial match' do
contexts(:agenda).title.should eql(contexts(:agenda).name) Context.find_by_namepart('err').should == contexts(:errand)
end end
it "should .find_by_namepart with exact match" do it 'deletes todos within context when context deleted' do
@found = Context.find_by_namepart('agenda') contexts(:call).should have(2).todos
@found.should_not eql(nil) call_todos = contexts(:call).todos
@found.id.should eql(contexts(:agenda).id) contexts(:call).destroy
end Todo.find(:all).should_not include(call_todos)
it "should .find_by_namepart with partial match" do
@found = Context.find_by_namepart('ag')
@found.should_not eql(nil)
@found.id.should eql(contexts(:agenda).id)
end
it "should return id with .to_param" do
Context.find(2).to_param.should eql("2")
end
it "should return feed options" do
opts = Context.feed_options(users(:admin_user))
opts[:title].should eql("Tracks Contexts")
opts[:description].should eql("Lists all the contexts for Admin Schmadmin")
end
it "should create null Context with .null_object" do
@empty = Context.null_object
@empty.should be_an_instance_of(NullContext)
@empty.id.should eql(nil)
@empty.name.should eql('')
end
it "should delete todos within context when context deleted" do
contexts(:agenda).todos.count.should eql(3)
agenda_todo_ids = contexts(:agenda).todos.collect{|t| t.id }
contexts(:agenda).destroy
agenda_todo_ids.each do |todo_id|
Todo.find(:all).should_not include(todo_id)
end end
end end
it "should return correct number of done todos" do describe 'when counting todos' do
contexts(:agenda).done_todos.size.should eql(1) scenario :todos
t = contexts(:agenda).not_done_todos[0]
t.complete! it 'returns correct number of completed todos' do
t.save! contexts(:call).should_not have(:any).done_todos
Context.find(contexts(:agenda)).done_todos.size.should eql(2) contexts(:call).todos.first.complete!
contexts(:call).should have(1).done_todos
end
it 'returns correct number of not done todos' do
contexts(:call).should have(2).not_done_todos
contexts(:call).todos.last.complete!
contexts(:call).should have(1).not_done_todos
end
end end
end
it "should return correct number of not done todos" do
contexts(:agenda).not_done_todos.size.should eql(2) describe NullContext do
t = contexts(:agenda).not_done_todos[0] before(:each) do
t.complete! @context = NullContext.new
t.save!
Context.find(contexts(:agenda)).not_done_todos.size.should eql(1)
end end
it 'is nil' do
@context.should be_nil
end
it 'has no id' do
@context.id.should be_nil
end
it 'has a blank name' do
@context.name.should be_blank
end
end end

View file

@ -1,4 +1,6 @@
class ContextsScenario < Scenario::Base class ContextsScenario < Scenario::Base
uses :users
def load def load
%w(Call Email Errand Someday).each_with_index do |context, index| %w(Call Email Errand Someday).each_with_index do |context, index|
create_context context, index+1 create_context context, index+1

View file

@ -1,16 +1,20 @@
class ProjectsScenario < Scenario::Base class ProjectsScenario < Scenario::Base
def load def load
['Build a working time machin', create_project :build_time_machine, 'Build a working time machine'
'Make more money than Billy Gates', create_project :make_more_money, 'Make more money than Billy Gates'
'Evict dinosaurs from the garden', create_project :evict_dinosaurs, 'Evict dinosaurs from the garden'
'Attend RailsConf'].each_with_index do |project, index| create_project :attend_railsconf, 'Attend RailsConf'
create_record :project, project.split.first.downcase.to_sym, end
:name => project,
:description => '', def create_project(identifier, name)
:position => index + 1, attributes = {
:state => 'active', :name => name,
:created_at => Time.now, :state => 'active',
:updated_at => Time.now :created_at => 4.day.ago,
end :updated_at => 1.minute.ago
}
create_model :project,
identifier || attributes[:name].split.first.downcase.to_sym,
attributes
end end
end end

View file

@ -2,15 +2,29 @@ class TodosScenario < Scenario::Base
uses :contexts, :projects, :users uses :contexts, :projects, :users
def load def load
create_record :todo, :billy, create_todo :bill,
:description => "Call Bill Gates to find out how much he makes per day", :description => 'Call Bill Gates to find out how much he makes per day',
:notes => "~", :user => :sean,
:state => 'active', :context => :call,
:created_at => 1.week.ago, :project => :make_more_money
:due => 2.weeks.from_now, create_todo :bank,
:completed_at => nil, :description => 'Call my bank',
:context => context(:call), :user => :sean,
:project_id => project_id(:make), :context => :call,
:user_id => user_id(:sean) :project => :make_more_money
end
def create_todo(identifier, options={})
context = options.delete(:context)
project = options.delete(:project)
user = options.delete(:user)
attributes = {
:state => 'active',
:created_at => 1.week.ago,
:context_id => context_id(context),
:project_id => project_id(project),
:user_id => user_id(user)
}.merge(options)
create_model :todo, identifier, attributes
end end
end end