Решение на Пета задача от Алекс Николов

Обратно към всички решения

Към профила на Алекс Николов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 25 успешни тест(а)
  • 5 неуспешни тест(а)

Код

require 'digest/sha1'
class ObjectStore
def self.init(&block)
self.new(&block)
end
def initialize(&block)
@repo_branch_group = BranchGroup.new
@current_branch = @repo_branch_group.current_branch
if block_given?
instance_eval &block
end
end
def branch
@repo_branch_group
end
def add(name, object)
to_be_committed[name] = object
ReturnObject.new(true, "Added #{name} to stage.", object)
end
def commit(message)
if to_be_committed != last_committed_objects
new_commit = Commit.new(message, to_be_committed)
count = (last_committed_objects.size - to_be_committed.size).abs
commits_list.insert(0, new_commit)
@current_branch.head = new_commit
return_message = "#{message}\n\t#{count} objects changed"
ReturnObject.new(true, return_message, new_commit)
else
ReturnObject.new(false, "Nothing to commit, working directory clean.")
end
end
def remove(name)
if last_committed_objects.has_key?(name)
removed_object = to_be_committed.delete(name)
ReturnObject.new(true, "Added #{name} for removal.", removed_object)
else
ReturnObject.new(false, "Object #{name} is not committed.")
end
end
def checkout(commit_hash)
found_commit = commits_list.find { |commit| commit.hash == commit_hash }
if found_commit.nil?
ReturnObject.new(false, "Commit #{commit_hash} does not exist.")
else
@current_branch.head = found_commit
commits_list.drop_while { |commit| commit != found_commit }
message = "HEAD is now at #{commit_hash}."
ReturnObject.new(true, message, @current_branch.head)
end
end
def log
if commits_list.size == 0
message = "Branch #{current_branch_name} does not have any commits yet."
ReturnObject.new(false, message)
else
log_message = String.new
commits_list.each { |commit| log_message << commit.log_message }
ReturnObject.new(true, log_message.chomp!.chomp!)
end
end
def head
if commits_list.size == 0
message = "Branch #{current_branch_name} does not have any commits yet."
ReturnObject.new(false, message)
else
message = @current_branch.head.message
ReturnObject.new(true, message, @current_branch.head)
end
end
def get(name)
if last_committed_objects.has_key?(name)
found_object = last_committed_objects[name]
ReturnObject.new(true, "Found object #{name}.", found_object)
else
ReturnObject.new(false, "Object #{name} is not committed.")
end
end
private
def last_committed_objects
head.result.nil? ? {} : head.result.objects_hash
end
def to_be_committed
@current_branch.to_be_committed
end
def commits_list
@current_branch.commits_list
end
def branch_list
@repo_branch_group.branch_list
end
def current_branch_name
branch_list.key(@current_branch)
end
class BranchGroup
def initialize
@branch_list = Hash.new
master = Branch.new
@branch_list["master"] = master
@current_branch = master
@current_branch_name = "master"
end
attr_reader :current_branch, :branch_list
def create(branch_name)
if @branch_list.has_key?(branch_name)
ReturnObject.new(false, "Branch #{branch_name} already exists.")
else
new_branch = Branch.new(@current_branch)
@branch_list[branch_name] = new_branch
ReturnObject.new(true, "Created branch #{branch_name}.")
end
end
def checkout(branch_name)
if @branch_list.has_key?(branch_name)
@current_branch = @branch_list[branch_name]
ReturnObject.new(true, "Switched to branch #{branch_name}.")
else
ReturnObject.new(false, "Branch #{branch_name} does not exist.")
end
end
def remove(branch_name)
if @branch_list.has_key?(branch_name)
if branch_name == @branch_list.key(current_branch)
ReturnObject.new(false, "Cannot remove current branch.")
else
@branch_list.delete(branch_name)
ReturnObject.new(true, "Removed branch #{branch_name}.")
end
else
ReturnObject.new(false, "Branch #{branch_name} does not exist.")
end
end
def list
branches_name_list = String.new
@branch_list.keys.sort.each do |key|
if key == @current_branch_name
branches_name_list << "* #{key}\n"
else
branches_name_list << " #{key}\n"
end
end
ReturnObject.new(true, branches_name_list.chomp!)
end
class Branch
def initialize(copy_branch = nil)
if copy_branch.nil?
@commits_list = Array.new
@to_be_committed = Hash.new
@head = nil
else
@commits_list = copy_branch.commits_list
@to_be_committed = copy_branch.to_be_committed
@head = copy_branch.head
end
end
attr_accessor :head, :commits_list, :to_be_committed
end
end
end
class Commit
def initialize(message, new_objects)
@date = Time.now
@message = message
@hash = Digest::SHA1.hexdigest(date.to_s + message)
@objects_hash = new_objects.clone
end
attr_reader :date, :message, :hash, :objects_hash
def objects
@objects_hash.values
end
def log_message
correct_date_format = date.strftime('%a %b %-d %H:%M %Y %z')
"Commit #{hash}\nDate: #{correct_date_format}\n\n\t#{message}\n\n"
end
end
class ReturnObject
def initialize(success, message, result = nil)
@message = message
@success = success
unless result == nil
@result = result
end
end
attr_reader :message, :result
def success?
@success
end
def error?
not @success
end
end

Лог от изпълнението

........FFFF....F.............

Failures:

  1) ObjectStore can show log of changes for a single commit
     Failure/Error: expect(repo.log).to be_success("Commit #{commit_hash}\nDate: #{Time.now.strftime("%a %b %d %H:%M %Y %z")}\n\n\tSo cool!")
       expected #<ReturnObject:0x007f6b6447aa28 @message="Commit bbba31e96e9cc381f8d00720673e3e48f58aa353\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!", @success=true> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-go39tf/spec.rb:83:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) ObjectStore can show log of changes for a single commit
     Failure/Error: expect(repo.log).to be_success("Commit #{commit_hash}\nDate: #{Time.now.strftime("%a %b %d %H:%M %Y %z")}\n\n\tSo cool!")
       expected #<ReturnObject:0x007f6b6446ec50 @message="Commit bbba31e96e9cc381f8d00720673e3e48f58aa353\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!", @success=true> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-go39tf/spec.rb:92:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) ObjectStore can show log of changes for multiple commits
     Failure/Error: expect(repo.log).to be_success("Commit #{commit2_hash}\nDate: #{current_time}\n\n\tSecond commit\n\nCommit #{commit1_hash}\nDate: #{current_time}\n\n\tFirst commit")
       expected #<ReturnObject:0x007f6b6445f610 @message="Commit 3a07486310b1d17dabc01f6334fccd725e717c9d\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSecond commit\n\nCommit a1892ad07761b4e6f618627b736484058e10b5f5\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit", @success=true> to be success "Commit a6bf7130a3150d375443c25d06c1bf8077e4b4fb\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSecond commit\n\nCommit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-go39tf/spec.rb:108:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) ObjectStore shows the log for the current branch only
     Failure/Error: expect(repo.log).to be_success("Commit #{commit1_hash}\nDate: #{current_time}\n\n\tFirst commit")
       expected #<ReturnObject:0x007f6b64458770 @message="Commit 3a07486310b1d17dabc01f6334fccd725e717c9d\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSecond commit\n\nCommit a1892ad07761b4e6f618627b736484058e10b5f5\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit", @success=true> to be success "Commit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-go39tf/spec.rb:128:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) ObjectStore can switch branches
     Failure/Error: expect(repo.head).to be_success("First commit", first_commit)
       expected #<ReturnObject:0x007f6b6409f070 @message="Second commit", @success=true, @result=#<Commit:0x007f6b640d2718 @date=2016-01-11 11:55:28 +0200, @message="Second commit", @hash="3a07486310b1d17dabc01f6334fccd725e717c9d", @objects_hash={"object1"=>"content1", "object2"=>"content2"}>> to be success "First commit" and #<Commit:0x007f6b640e4760 @date=2016-01-11 11:55:28 +0200, @message="First commit", @hash="a1892ad07761b4e6f618627b736484058e10b5f5", @objects_hash={"object1"=>"content1"}>
     # /tmp/d20160111-5693-go39tf/spec.rb:163:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.03088 seconds
30 examples, 5 failures

Failed examples:

rspec /tmp/d20160111-5693-go39tf/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-go39tf/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-go39tf/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-go39tf/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-go39tf/spec.rb:153 # ObjectStore can switch branches

История (1 версия и 0 коментара)

Алекс обнови решението на 20.11.2015 21:43 (преди над 8 години)

+require 'digest/sha1'
+
+class ObjectStore
+ def self.init(&block)
+ self.new(&block)
+ end
+
+ def initialize(&block)
+ @repo_branch_group = BranchGroup.new
+ @current_branch = @repo_branch_group.current_branch
+
+ if block_given?
+ instance_eval &block
+ end
+ end
+
+ def branch
+ @repo_branch_group
+ end
+
+ def add(name, object)
+ to_be_committed[name] = object
+ ReturnObject.new(true, "Added #{name} to stage.", object)
+ end
+
+ def commit(message)
+ if to_be_committed != last_committed_objects
+ new_commit = Commit.new(message, to_be_committed)
+ count = (last_committed_objects.size - to_be_committed.size).abs
+
+ commits_list.insert(0, new_commit)
+ @current_branch.head = new_commit
+ return_message = "#{message}\n\t#{count} objects changed"
+ ReturnObject.new(true, return_message, new_commit)
+ else
+ ReturnObject.new(false, "Nothing to commit, working directory clean.")
+ end
+ end
+
+ def remove(name)
+ if last_committed_objects.has_key?(name)
+ removed_object = to_be_committed.delete(name)
+ ReturnObject.new(true, "Added #{name} for removal.", removed_object)
+ else
+ ReturnObject.new(false, "Object #{name} is not committed.")
+ end
+ end
+
+ def checkout(commit_hash)
+ found_commit = commits_list.find { |commit| commit.hash == commit_hash }
+ if found_commit.nil?
+ ReturnObject.new(false, "Commit #{commit_hash} does not exist.")
+ else
+ @current_branch.head = found_commit
+ commits_list.drop_while { |commit| commit != found_commit }
+ message = "HEAD is now at #{commit_hash}."
+ ReturnObject.new(true, message, @current_branch.head)
+ end
+ end
+
+ def log
+ if commits_list.size == 0
+ message = "Branch #{current_branch_name} does not have any commits yet."
+ ReturnObject.new(false, message)
+ else
+ log_message = String.new
+ commits_list.each { |commit| log_message << commit.log_message }
+ ReturnObject.new(true, log_message.chomp!.chomp!)
+ end
+ end
+
+ def head
+ if commits_list.size == 0
+ message = "Branch #{current_branch_name} does not have any commits yet."
+ ReturnObject.new(false, message)
+ else
+ message = @current_branch.head.message
+ ReturnObject.new(true, message, @current_branch.head)
+ end
+ end
+
+ def get(name)
+ if last_committed_objects.has_key?(name)
+ found_object = last_committed_objects[name]
+ ReturnObject.new(true, "Found object #{name}.", found_object)
+ else
+ ReturnObject.new(false, "Object #{name} is not committed.")
+ end
+ end
+
+ private
+
+ def last_committed_objects
+ head.result.nil? ? {} : head.result.objects_hash
+ end
+
+ def to_be_committed
+ @current_branch.to_be_committed
+ end
+
+ def commits_list
+ @current_branch.commits_list
+ end
+
+ def branch_list
+ @repo_branch_group.branch_list
+ end
+
+ def current_branch_name
+ branch_list.key(@current_branch)
+ end
+
+ class BranchGroup
+ def initialize
+ @branch_list = Hash.new
+ master = Branch.new
+ @branch_list["master"] = master
+ @current_branch = master
+ @current_branch_name = "master"
+ end
+
+ attr_reader :current_branch, :branch_list
+
+ def create(branch_name)
+ if @branch_list.has_key?(branch_name)
+ ReturnObject.new(false, "Branch #{branch_name} already exists.")
+ else
+ new_branch = Branch.new(@current_branch)
+ @branch_list[branch_name] = new_branch
+ ReturnObject.new(true, "Created branch #{branch_name}.")
+ end
+ end
+
+ def checkout(branch_name)
+ if @branch_list.has_key?(branch_name)
+ @current_branch = @branch_list[branch_name]
+ ReturnObject.new(true, "Switched to branch #{branch_name}.")
+ else
+ ReturnObject.new(false, "Branch #{branch_name} does not exist.")
+ end
+ end
+
+ def remove(branch_name)
+ if @branch_list.has_key?(branch_name)
+ if branch_name == @branch_list.key(current_branch)
+ ReturnObject.new(false, "Cannot remove current branch.")
+ else
+ @branch_list.delete(branch_name)
+ ReturnObject.new(true, "Removed branch #{branch_name}.")
+ end
+ else
+ ReturnObject.new(false, "Branch #{branch_name} does not exist.")
+ end
+ end
+
+ def list
+ branches_name_list = String.new
+ @branch_list.keys.sort.each do |key|
+ if key == @current_branch_name
+ branches_name_list << "* #{key}\n"
+ else
+ branches_name_list << " #{key}\n"
+ end
+ end
+ ReturnObject.new(true, branches_name_list.chomp!)
+ end
+
+ class Branch
+ def initialize(copy_branch = nil)
+ if copy_branch.nil?
+ @commits_list = Array.new
+ @to_be_committed = Hash.new
+ @head = nil
+ else
+ @commits_list = copy_branch.commits_list
+ @to_be_committed = copy_branch.to_be_committed
+ @head = copy_branch.head
+ end
+ end
+
+ attr_accessor :head, :commits_list, :to_be_committed
+ end
+ end
+end
+
+class Commit
+ def initialize(message, new_objects)
+ @date = Time.now
+ @message = message
+ @hash = Digest::SHA1.hexdigest(date.to_s + message)
+ @objects_hash = new_objects.clone
+ end
+
+ attr_reader :date, :message, :hash, :objects_hash
+
+ def objects
+ @objects_hash.values
+ end
+
+ def log_message
+ correct_date_format = date.strftime('%a %b %-d %H:%M %Y %z')
+ "Commit #{hash}\nDate: #{correct_date_format}\n\n\t#{message}\n\n"
+ end
+end
+
+class ReturnObject
+ def initialize(success, message, result = nil)
+ @message = message
+ @success = success
+
+ unless result == nil
+ @result = result
+ end
+ end
+
+ attr_reader :message, :result
+
+ def success?
+ @success
+ end
+
+ def error?
+ not @success
+ end
+end