require 'spec_helper' module Trajectory describe Project do let(:project) { Project.new(id: 42, name: 'foo') } it 'can be initialized with named parameters' do project.id.should == 42 project.name.should == 'foo' end it 'requires an id attribute' do expect do Project.new.id end.to raise_error(MissingAttributeError) end it 'is the same project when ids are the same' do project.should == Project.new(id: 42, name: 'bar') end context 'it has attributes accessors' do %w(archived? created_at estimated_velocity historic_velocity id keyword updated_at completed_iterations_count completed_stories_count).each do |attribute| it "'#{attribute}' accessor" do Project.new.should respond_to(attribute.to_sym) end end end it 'can sum the points of all its stories' do stories = Stories.new(double(:story, :points => 2), double(:story, :points => 10), double(:story, :points => 8)) DataStore.stub(:stories_for_project).and_return(stories) Project.new.total_points.should == 20 end it 'can evaluate remaining points' do stories = Stories.new(double(:story, :points => 2, :completed? => false), double(:story, :points => 10, :completed? => false), double(:story, :points => 8, :completed? => true)) DataStore.stub(:stories_for_project).and_return(stories) Project.new.remaining_points.should == 12 end it 'can evaluate the number of days to the end' do stories = Stories.new(double(:story, :points => 2, :completed? => false), double(:story, :points => 10, :completed? => false), double(:story, :points => 8, :completed? => false)) DataStore.stub(:stories_for_project).and_return(stories) project = Project.new(:estimated_velocity => 20) project.remaining_days.should == 7 end it 'can evaluate project end date' do stories = Stories.new(double(:story, :points => 20, :completed? => false), double(:story, :points => 10, :completed? => false), double(:story, :points => 10, :completed? => false)) DataStore.stub(:stories_for_project).and_return(stories) project = Project.new(:estimated_velocity => 20) project.estimated_end_date.should == Date.today + 14 end it 'can evaluate velocity per day' do Project.new(:estimated_velocity => 20).estimated_velocity_per_day.should == 20 / 7.0 Project.new(:estimated_velocity => 21).estimated_velocity_per_day.should == 21 / 7.0 Project.new(:estimated_velocity => 7).estimated_velocity_per_day.should == 7 / 7.0 end it 'can count the number of remaining working days' do stories = Stories.new(double(:story, :points => 2, :completed? => false), double(:story, :points => 10, :completed? => false), double(:story, :points => 8, :completed? => false)) DataStore.stub(:stories_for_project).and_return(stories) project = Project.new(:estimated_velocity => 20) project.remaining_working_days.should == 5 end it 'can estimate velocity per working day' do Project.new(:estimated_velocity => 20).estimated_velocity_per_working_day.should == 20 / 5.0 Project.new(:estimated_velocity => 21).estimated_velocity_per_working_day.should == 21 / 5.0 Project.new(:estimated_velocity => 7).estimated_velocity_per_working_day.should == 7 / 5.0 end it 'can estimate the percentage of completion' do stories = Stories.new(double(:story, :points => 1, :completed? => false), double(:story, :points => 10, :completed? => false), double(:story, :points => 9, :completed? => true)) DataStore.stub(:stories_for_project).and_return(stories) Project.new.percent_complete.should == 45.0 end it 'can return the sum of completed stories points' do stories = Stories.new(double(:story, :points => 1, :completed? => false), double(:story, :points => 10, :completed? => true), double(:story, :points => 9, :completed? => true)) DataStore.stub(:stories_for_project).and_return(stories) Project.new.accepted_points.should == 19 end it 'delegates fetching of iterations of a project to the data store' do DataStore.should_receive(:iterations_for_project).with(project) project.iterations end it 'delegates fetching of updates of a project to the data store' do since = double DataStore.should_receive(:updates_for_project).with(project, since) project.updates(since) end it 'delegates fetching of ideas of a project to the data store' do DataStore.should_receive(:ideas_for_project).with(project) project.ideas end it 'can get stories of a given iteration' do stories = double iteration = double project.stories = stories stories.should_receive(:in_iteration).with(iteration) project.stories_in_iteration(iteration) end it 'can get one of its user by id' do users = double project.users_collection = users users.should_receive(:find_by_id).with(1234) project.find_user_by_id(1234) end context 'when estimated velocity is zero' do it 'cannot estimate remaining days until the project end' do expect do Project.new(:estimated_velocity => 0).remaining_days end.to raise_error(VelocityEqualToZeroError) end it 'cannot estimate remaining working days until the project end' do expect do Project.new(:estimated_velocity => 0).remaining_working_days end.to raise_error(VelocityEqualToZeroError) end end end end