command observers

This commit is contained in:
Tomasz Gieniusz 2012-10-19 21:11:47 +02:00
parent a4f650b760
commit b439fd234c
7 changed files with 84 additions and 34 deletions

View File

@ -7,8 +7,8 @@ class GitStats::CLI
repo_path, out_path = args
GitStats::Generator.new(repo_path, out_path) { |g|
g.git_command_observer { |command, result| puts "#{command}" }
}.generate
g.add_command_observer { |command, result| puts "#{command}" }
}.render_all
end
end

View File

@ -1,36 +1,30 @@
module GitStats
class Generator
delegate :add_command_observer, to: :@repo
delegate :render_all, to: :@view
def initialize(repo_path, out_path)
@repo_path, @out_path = repo_path, out_path
validate_paths(repo_path, out_path)
@repo = GitData::Repo.new(path: repo_path)
view_data = StatsView::ViewData.new(@repo)
@view = StatsView::View.new(view_data, out_path)
yield self if block_given?
end
def git_command_observer(&block)
@git_command_observer = block
end
def generate
validate_paths
repo = GitData::Repo.new(path: @repo_path, git_command_observer: @git_command_observer)
view_data = StatsView::ViewData.new(repo)
view = StatsView::View.new(view_data, @out_path)
view.render_all
end
private
def validate_paths
validate_repo_path
validate_out_path
def validate_paths(repo_path, out_path)
validate_repo_path(repo_path)
validate_out_path(out_path)
end
def validate_repo_path
raise ArgumentError, "#@repo_path is not a git repository" unless Dir.exists?("#@repo_path/.git")
def validate_repo_path(repo_path)
raise ArgumentError, "#{repo_path} is not a git repository" unless Dir.exists?("#{repo_path}/.git")
end
def validate_out_path
raise ArgumentError, "#@out_path is not a directory" unless Dir.exists?(@out_path)
def validate_out_path(out_path)
raise ArgumentError, "#{out_path} is not a directory" unless Dir.exists?(out_path)
end
end

View File

@ -1,8 +1,8 @@
module GitStats
module GitData
class CommandRunner
def self.run(command)
%x[#{command}]
def run(path, command)
Dir.chdir(path) { %x[#{command}] }
end
end
end

View File

@ -59,7 +59,9 @@ module GitStats
end
def run(command)
in_repo_dir { CommandRunner.run(command) }
result = command_runner.run(path, command)
invoke_command_observers(command, result)
result
end
def run_and_parse(command)
@ -67,12 +69,17 @@ module GitStats
command_parser.parse(command, result)
end
def command_runner
@command_runner ||= CommandRunner.new
end
def command_parser
@command_parser ||= CommandParser.new
end
def in_repo_dir
Dir.chdir(path) { yield }
def add_command_observer(proc=nil, &block)
command_observers << block if block_given?
command_observers << proc if proc
end
def to_s
@ -83,6 +90,15 @@ module GitStats
self.path == other.path
end
private
def command_observers
@command_observers ||= []
end
def invoke_command_observers(command, result)
command_observers.each { |o| o.call(command, result) }
end
end
end
end

View File

@ -7,7 +7,7 @@ describe GitStats::CLI do
it 'should invoke generator with console arguments given' do
generator = double('generator')
GitStats::Generator.should_receive(:new).with(repo_path, out_path).and_return(generator)
generator.should_receive(:generate)
generator.should_receive(:render_all)
subject.start(repo_path, out_path)
end

View File

@ -9,17 +9,29 @@ describe GitStats::Generator do
it 'should raise exception if given repo path is not a git repository' do
Dir.should_receive(:exists?).with("#{repo_path}/.git").and_return(false)
expect { generator.generate }.to raise_error(ArgumentError)
expect { generator }.to raise_error(ArgumentError)
end
it "should raise exception if given out directory doesn't exist" do
Dir.should_receive(:exists?).with(out_path).and_return(false)
expect { generator.generate }.to raise_error(ArgumentError)
expect { generator }.to raise_error(ArgumentError)
end
it 'should pass command observer to repo' do
repo = double('repo')
GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo)
generator = GitStats::Generator.new(repo_path, out_path)
observer = double('observer')
repo.should_receive(:add_command_observer).with(observer)
generator.add_command_observer observer
end
it 'should render all templates with view data for this repo' do
repo = double('repo')
GitStats::GitData::Repo.should_receive(:new).with(path: repo_path, git_command_observer: nil).and_return(repo)
GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo)
view_data = double('view_data')
GitStats::StatsView::ViewData.should_receive(:new).with(repo).and_return(view_data)
@ -28,6 +40,6 @@ describe GitStats::Generator do
GitStats::StatsView::View.should_receive(:new).with(view_data, out_path).and_return(view)
view.should_receive(:render_all)
generator.generate
generator.render_all
end
end

View File

@ -47,6 +47,34 @@ describe GitStats::GitData::Repo do
end
end
describe 'command observers' do
context 'should be invoked after every command' do
it 'should accept block' do
command_runner = double('command_runner')
repo = build(:repo, command_runner: command_runner)
observer = double('observer')
repo.add_command_observer { |command, result| observer.invoked(command, result) }
command_runner.should_receive(:run).with(repo.path, 'aa').and_return('bb')
observer.should_receive(:invoked).with('aa', 'bb')
repo.run('aa')
end
it 'should accept Proc' do
command_runner = double('command_runner')
repo = build(:repo, command_runner: command_runner)
observer = double('observer')
repo.add_command_observer(observer)
command_runner.should_receive(:run).with(repo.path, 'aa').and_return('bb')
observer.should_receive(:call).with('aa', 'bb')
repo.run('aa')
end
end
end
describe 'git output parsing' do
context 'invoking authors command' do
before do