Решение на Пета задача от Росен Тодоров

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

Към профила на Росен Тодоров

Резултати

  • 2 точки от тестове
  • 0 бонус точки
  • 2 точки общо
  • 9 успешни тест(а)
  • 21 неуспешни тест(а)

Код

require 'digest/sha1'
class ObjectStore
attr_reader :branch
def self.init(&block)
ObjectStore.new(&block)
end
def initialize(&block)
@branch = Branch.new
@current_branch = @branch.current_branch
@current_commit = {}
@directory = @branch.branches
self.instance_eval &block if block_given?
end
def add(name, object)
@current_commit[name] = object
message = "Added #{name} to stage."
Result.new(true, message, object)
end
def commit(message)
if @current_commit.empty?
message = "Nothing to commit, working directory clean."
Result.new(false, message, {})
else
date = Time.now
hash = Digest::SHA1.hexdigest "#{date}#{message}"
@directory[@current_branch][hash] = @current_commit
commit_message = "#{message}\n\t#{@current_commit.size} objects changed"
@current_commit = {}
Result.new(true, commit_message, @directory[@current_branch][hash])
end
end
end
class Branch
attr_accessor :branches, :current_branch
def initialize()
@branches = { "master" => {} }
@current_branch = "master"
end
def create(branch_name)
if @branches.member?(branch_name)
message = "Branch #{branch_name} already exists."
Result.new(false, message, {})
else
@branches[branch_name] = @branches[@current_branch]
message = "Created branch #{branch_name}."
Result.new(true, message, @branches[branch_name])
end
end
def checkout(branch_name)
if @branches.member?(branch_name)
@current_branch = branch_name
message = "Switched to branch #{branch_name}."
Result.new(true, message, {})
else
message = "Branch #{branch_name} does not exist."
Result.new(false, message, {})
end
end
def remove(branch_name)
if ! @branches.member?(branch_name)
message = "Branch #{branch_name} does not exist."
Result.new(false, message, {})
elsif @current_branch == branch_name
message = "Cannot remove current branch."
Result.new(false, message, {})
else
@branches.delete(branch_name)
message = "Removed branch #{branch_name}."
Result.new(true, message, {})
end
end
def list
message = @branches.keys
.sort
.each.map do |value|
if value == @current_branch
"* #{value}"
else
" #{value}"
end
end
.join("\n")
Result.new(true, message, {})
end
end
class Result
attr_reader :message, :result
def initialize(state, message, result)
@state = state
@message = message
@result = result
end
def success?
@state
end
def error?
! @state
end
end

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

.F.FFFFFFFFFF...F....FFFFFFFFF

Failures:

  1) ObjectStore can commit objects
     Failure/Error: expect(repo.commit("So cool!")).to be_success("So cool!\n\t2 objects changed", repo.head.result)
     NoMethodError:
       undefined method `head' for #<ObjectStore:0x007f1e3388e0e8>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:30: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 remove objects
     Failure/Error: expect(repo.remove("object1")).to be_success("Added object1 for removal.", "content1")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f1e3387cff0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:43: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 commit changes which include only removed objects
     Failure/Error: repo.remove("object2")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f1e33876da8>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:52: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 cannot remove objects that are not committed
     Failure/Error: expect(repo.remove("object2")).to be_error("Object object2 is not committed.")
     NoMethodError:
       undefined method `remove' for #<ObjectStore:0x007f1e33874710>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:60: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 show head
     Failure/Error: expect(repo.head).to be_success("There we go", last_commit)
     NoMethodError:
       undefined method `head' for #<ObjectStore:0x007f1e33871d58>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:69: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)>'

  6) ObjectStore cannot show head for empty repository
     Failure/Error: expect(repo.head).to be_error("Branch master does not have any commits yet.")
     NoMethodError:
       undefined method `head' for #<ObjectStore:0x007f1e3386ad78>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:74: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)>'

  7) ObjectStore can show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `date' for {"object1"=>"content1", "object2"=>"content2"}:Hash
     # /tmp/d20160111-5693-a6t0pz/spec.rb:82: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)>'

  8) ObjectStore can show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `date' for {"object1"=>"content1", "object2"=>"content2"}:Hash
     # /tmp/d20160111-5693-a6t0pz/spec.rb:91: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)>'

  9) ObjectStore can show log of changes for multiple commits
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `date' for {"object1"=>"content1"}:Hash
     # /tmp/d20160111-5693-a6t0pz/spec.rb:105: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)>'

  10) ObjectStore shows the log for the current branch only
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `date' for {"object1"=>"content1"}:Hash
     # /tmp/d20160111-5693-a6t0pz/spec.rb:126: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)>'

  11) ObjectStore cannot show log for empty repository
     Failure/Error: expect(repo.log).to be_error("Branch master does not have any commits yet.")
     NoMethodError:
       undefined method `log' for #<ObjectStore:0x007f1e334cc400>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:133: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)>'

  12) ObjectStore can switch branches
     Failure/Error: expect(repo.head).to be_success("Second commit", second_commit)
     NoMethodError:
       undefined method `head' for #<ObjectStore:0x007f1e3345e7c0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:161: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)>'

  13) ObjectStore can be initialized with block
     Failure/Error: expect(repo.head).to be_success("Second commit", $second_commit)
     NoMethodError:
       undefined method `head' for #<ObjectStore:0x007f1e333d8f80>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:195: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)>'

  14) ObjectStore can return objects
     Failure/Error: expect(repo.get("number")).to be_success("Found object number.", 21)
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f1e333d4bb0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:202: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)>'

  15) ObjectStore cannot return not committed objects
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f1e333c14e8>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:209: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)>'

  16) ObjectStore cannot return objects when no commits
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007f1e33346720>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:214: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)>'

  17) ObjectStore can checkout commits
     Failure/Error: expect(repo.checkout(first_commit.hash)).to be_success("HEAD is now at #{first_commit.hash}.", first_commit)
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007f1e33341018>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:223: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)>'

  18) ObjectStore cannot checkout commits with nonexisting hashes
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007f1e333353d0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:231: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)>'

  19) ObjectStore cannot checkout commits in empty repository
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007f1e3332bdd0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:236: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)>'

  20) ObjectStore can show the objects in a repo after overwriting an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1"])
     NoMethodError:
       undefined method `objects' for {"object1"=>"content1"}:Hash
     # /tmp/d20160111-5693-a6t0pz/spec.rb:243: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)>'

  21) ObjectStore can show the objects of a repo after removing an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1", "content2", "content3"])
     NoMethodError:
       undefined method `objects' for #<Hash:0x007f1e3331c8d0>
     # /tmp/d20160111-5693-a6t0pz/spec.rb:259: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.01719 seconds
30 examples, 21 failures

Failed examples:

rspec /tmp/d20160111-5693-a6t0pz/spec.rb:26 # ObjectStore can commit objects
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:38 # ObjectStore can remove objects
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:46 # ObjectStore can commit changes which include only removed objects
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:56 # ObjectStore cannot remove objects that are not committed
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:63 # ObjectStore can show head
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:72 # ObjectStore cannot show head for empty repository
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:131 # ObjectStore cannot show log for empty repository
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:153 # ObjectStore can switch branches
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:187 # ObjectStore can be initialized with block
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:198 # ObjectStore can return objects
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:205 # ObjectStore cannot return not committed objects
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:212 # ObjectStore cannot return objects when no commits
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:217 # ObjectStore can checkout commits
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:227 # ObjectStore cannot checkout commits with nonexisting hashes
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:234 # ObjectStore cannot checkout commits in empty repository
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-a6t0pz/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

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

Росен обнови решението на 23.11.2015 17:20 (преди над 8 години)

+require 'digest/sha1'
+
+class ObjectStore
+ attr_reader :branch
+
+ def self.init(&block)
+ ObjectStore.new(&block)
+ end
+
+ def initialize(&block)
+ @branch = Branch.new
+ @current_branch = @branch.current_branch
+ @current_commit = {}
+ @directory = @branch.branches
+
+ self.instance_eval &block if block_given?
+ end
+
+ def add(name, object)
+ @current_commit[name] = object
+ message = "Added #{name} to stage."
+ Result.new(true, message, object)
+ end
+
+ def commit(message)
+ if @current_commit.empty?
+ message = "Nothing to commit, working directory clean."
+ Result.new(false, message, {})
+ else
+ date = Time.now
+ hash = Digest::SHA1.hexdigest "#{date}#{message}"
+ @directory[@current_branch][hash] = @current_commit
+ commit_message = "#{message}\n\t#{@current_commit.size} objects changed"
+ @current_commit = {}
+ Result.new(true, commit_message, @directory[@current_branch][hash])
+ end
+ end
+end
+
+
+
+class Branch
+ attr_accessor :branches, :current_branch
+
+ def initialize()
+ @branches = { "master" => {} }
+ @current_branch = "master"
+ end
+
+ def create(branch_name)
+ if @branches.member?(branch_name)
+ message = "Branch #{branch_name} already exists."
+ Result.new(false, message, {})
+ else
+ @branches[branch_name] = @branches[@current_branch]
+ message = "Created branch #{branch_name}."
+ Result.new(true, message, @branches[branch_name])
+ end
+ end
+
+ def checkout(branch_name)
+ if @branches.member?(branch_name)
+ @current_branch = branch_name
+ message = "Switched to branch #{branch_name}."
+ Result.new(true, message, {})
+ else
+ message = "Branch #{branch_name} does not exist."
+ Result.new(false, message, {})
+ end
+ end
+
+ def remove(branch_name)
+ if ! @branches.member?(branch_name)
+ message = "Branch #{branch_name} does not exist."
+ Result.new(false, message, {})
+ elsif @current_branch == branch_name
+ message = "Cannot remove current branch."
+ Result.new(false, message, {})
+ else
+ @branches.delete(branch_name)
+ message = "Removed branch #{branch_name}."
+ Result.new(true, message, {})
+ end
+ end
+
+ def list
+ message = @branches.keys
+ .sort
+ .each.map do |value|
+ if value == @current_branch
+ "* #{value}"
+ else
+ " #{value}"
+ end
+ end
+ .join("\n")
+ Result.new(true, message, {})
+ end
+end
+
+
+class Result
+ attr_reader :message, :result
+
+ def initialize(state, message, result)
+ @state = state
+ @message = message
+ @result = result
+ end
+
+ def success?
+ @state
+ end
+
+ def error?
+ ! @state
+ end
+end