Решение на Пета задача от Пепа Симеонова

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

Към профила на Пепа Симеонова

Резултати

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

Код

require 'ostruct'
require 'digest/sha1'
class ObjectStore
attr_accessor :current_branch
def initialize
@objects = {}
@staged = []
@branches = []
@current_branch = Branch.new('master')
@branches.push(@current_branch)
end
def self.init(&block)
ObjectStore.new
end
def add(name, object)
new_object = OpenStruct.new( name: name, object: object, action: :add )
@staged.push(new_object)
return Objects.new( { new_object.name => new_object.object },
"Added #{name} to stage.",
true )
end
def remove(name)
return Objects.new( nil, "Object #{name} is not committed.",
false ) unless @objects.has_key?(name)
removed = OpenStruct.new(name: name,object: @objects[name],action: :remove)
@staged.push(removed)
return Objects.new( { removed.name => removed.object },
"Added #{name} for removal.",
true )
end
def commit(msg)
return Objects.new( nil, "Nothing to commit, working directory clean.",
false ) if @staged.empty?
@current_branch.add_commit(Commit.new(msg, @staged))
apply_changes!(@staged)
return Objects.new(
@staged.clone,
"#{msg}\n\t#{@staged.shift(@staged.size).size} objects changed",
true )
end
def checkout(commit_hash)
return Objects.new( nil, "Commit #{hash} does not exist.",
false ) unless @current_branch.has_commit?(commit_hash)
current_commit = @current_branch.checkout_commit(commit_hash)
return Objects.new(
current_commit,
"HEAD is now at #{commit_hash}.",
true )
end
def head
return Objects.new( nil,
"Branch #{branch.name} does not have any commits yet.",
false ) if @current_branch.commits.empty?
Objects.new(
@current_branch.commits.last.objects,
@current_branch.commits.last.message,
true )
end
def branch
@current_branch
end
def log
return Objects.new( nil, "Branch #{name} does not have any commits yet.",
false ) if @current_branch.commits.empty?
commits = @current_branch.commits.reverse
message = ''
commits.each do |c|
message += "Commit #{c.hash}\nDate: #{c.date}\n\n\t#{c.message}\n\n"
end
return Objects.new(
nil,
message,
true )
end
def get(name)
return Objects.new( nil,
"Object #{name} is not committed.",
false ) unless @objects.has_key?(name)
Objects.new(
@objects[name],
"Found object #{name}.",
true )
end
end
private
def apply_changes!(staged)
staged.each do |object|
if object.action == :add
@objects[object.name] = object.object
else
@objects.delete(object.name)
end
end
end
class Branch
attr_accessor :name, :commits
def initialize(name)
@name = name
@commits = []
end
def create(name)
p @current_branch
new_branch = Branch.new(name)
new_branch.commits = @commits.clone
return Objects.new( new_branch,
"Created branch #{name}.",
true )
end
def add_commit(commit)
commits.push(commit)
end
def checkout_commit(commit_hash)
index = commits.index {|commit| commit.hash == commit_hash}
commits.slice!(index + 1, commits.length)
commits.last
end
def has_commit?(commit_hash)
commits.each do |commit|
return true if commit.hash == commit_hash
end
false
end
end
class Commit
attr_reader :objects, :date, :hash, :message
alias :result :objects
def initialize(message, objects)
@message = message
@objects = []
@objects.concat(objects)
@date = Time.now.strftime "%a %b %d %H:%M %Y %z"
@hash = Digest::SHA1.hexdigest "#{@date}#{message}$"
end
end
class Objects
attr_reader :message, :result
def initialize(result = nil, message, success)
@message = message
@success = success
@result = result
end
def success?
@success
end
def error?
! @success
end
end

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

F..F....FFFnil
FFnil
nil
Fnil
.nil
Fnil
FFnil
FFFF...FFFFF

Failures:

  1) ObjectStore can add objects
     Failure/Error: expect(repo.add("object", "content")).to be_success("Added object to stage.", "content")
       expected #<Objects:0x007f95159fa388 @message="Added object to stage.", @success=true, @result={"object"=>"content"}> to be success "Added object to stage." and "content"
     # /tmp/d20160111-5693-7sn79h/spec.rb:23: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")
       expected #<Objects:0x007f95159da218 @message="Added object1 for removal.", @success=true, @result={"object1"=>"content1"}> to be success "Added object1 for removal." and "content1"
     # /tmp/d20160111-5693-7sn79h/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 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 #<Array:0x007f95155d1c70>
     # /tmp/d20160111-5693-7sn79h/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)>'

  4) 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 #<Array:0x007f95155c6a78>
     # /tmp/d20160111-5693-7sn79h/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)>'

  5) 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 [#<OpenStruct name="object1", object="content1", action=:add>]:Array
     # /tmp/d20160111-5693-7sn79h/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)>'

  6) ObjectStore shows the log for the current branch only
     Failure/Error: repo.branch.checkout("develop")
     NoMethodError:
       undefined method `checkout' for #<Branch:0x007f9515583c28>
     # /tmp/d20160111-5693-7sn79h/spec.rb:121: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 cannot show log for empty repository
     Failure/Error: expect(repo.log).to be_error("Branch master does not have any commits yet.")
     NameError:
       undefined local variable or method `name' for #<ObjectStore:0x007f9515569c38>
     # /tmp/d20160111-5693-7sn79h/solution.rb:82:in `log'
     # /tmp/d20160111-5693-7sn79h/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)>'

  8) ObjectStore can list branches
     Failure/Error: expect(repo.branch.list).to be_success("  develop\n  feature\n* master")
     NoMethodError:
       undefined method `list' for #<Branch:0x007f9515558028 @name="master", @commits=[]>
     # /tmp/d20160111-5693-7sn79h/spec.rb:140: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 cannot create branch if already exists
     Failure/Error: expect(repo.branch.create("master")).to be_error("Branch master already exists.")
       expected #<Objects:0x007f951554bcd8 @message="Created branch master.", @success=true, @result=#<Branch:0x007f951554be18 @name="master", @commits=[]>> to be error "Branch master already exists."
     # /tmp/d20160111-5693-7sn79h/spec.rb:150: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 can switch branches
     Failure/Error: expect(repo.branch.checkout("develop")).to be_success("Switched to branch develop.")
     NoMethodError:
       undefined method `checkout' for #<Branch:0x007f9515534538>
     # /tmp/d20160111-5693-7sn79h/spec.rb:158: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 switch to nonexisting branch
     Failure/Error: expect(repo.branch.checkout("develop")).to be_error("Branch develop does not exist.")
     NoMethodError:
       undefined method `checkout' for #<Branch:0x007f95154b1fc0 @name="master", @commits=[]>
     # /tmp/d20160111-5693-7sn79h/spec.rb:168: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 remove branch
     Failure/Error: expect(repo.branch.remove("develop")).to be_success("Removed branch develop.")
     NoMethodError:
       undefined method `remove' for #<Branch:0x007f95154a7958 @name="master", @commits=[]>
     # /tmp/d20160111-5693-7sn79h/spec.rb:174: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 cannot remove current branch
     Failure/Error: expect(repo.branch.remove("master")).to be_error("Cannot remove current branch.")
     NoMethodError:
       undefined method `remove' for #<Branch:0x007f95154a3768 @name="master", @commits=[]>
     # /tmp/d20160111-5693-7sn79h/spec.rb:179: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 cannot remove nonexisting branch
     Failure/Error: expect(repo.branch.remove("develop")).to be_error("Branch develop does not exist.")
     NoMethodError:
       undefined method `remove' for #<Branch:0x007f951549e218 @name="master", @commits=[]>
     # /tmp/d20160111-5693-7sn79h/spec.rb:184: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 can be initialized with block
     Failure/Error: expect(repo.head).to be_success("Second commit", $second_commit)
       expected #<Objects:0x007f95154948a8 @message="Branch master does not have any commits yet.", @success=false, @result=nil> to be success "Second commit" and nil
     # /tmp/d20160111-5693-7sn79h/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)>'

  16) ObjectStore can checkout commits
     Failure/Error: expect(repo.checkout(first_commit.hash)).to be_success("HEAD is now at #{first_commit.hash}.", first_commit)
       expected #<Objects:0x007f951526a5a0 @message="Commit -1403624451882829409 does not exist.", @success=false, @result=nil> to be success "HEAD is now at -1486600930221393298." and [#<OpenStruct name="number", object=42, action=:add>]
     # /tmp/d20160111-5693-7sn79h/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)>'

  17) ObjectStore cannot checkout commits with nonexisting hashes
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
       expected #<Objects:0x007f951525e890 @message="Commit 4547112385272974451 does not exist.", @success=false, @result=nil> to be error "Commit [not-present] does not exist."
     # /tmp/d20160111-5693-7sn79h/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)>'

  18) ObjectStore cannot checkout commits in empty repository
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
       expected #<Objects:0x007f95152569b0 @message="Commit -4555907906634091481 does not exist.", @success=false, @result=nil> to be error "Commit [not-present] does not exist."
     # /tmp/d20160111-5693-7sn79h/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)>'

  19) 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 [#<OpenStruct name="object1", object="content1", action=:add>]:Array
     # /tmp/d20160111-5693-7sn79h/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)>'

  20) 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 #<Array:0x007f951608b670>
     # /tmp/d20160111-5693-7sn79h/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.02848 seconds
30 examples, 20 failures

Failed examples:

rspec /tmp/d20160111-5693-7sn79h/spec.rb:21 # ObjectStore can add objects
rspec /tmp/d20160111-5693-7sn79h/spec.rb:38 # ObjectStore can remove objects
rspec /tmp/d20160111-5693-7sn79h/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-7sn79h/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-7sn79h/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-7sn79h/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-7sn79h/spec.rb:131 # ObjectStore cannot show log for empty repository
rspec /tmp/d20160111-5693-7sn79h/spec.rb:136 # ObjectStore can list branches
rspec /tmp/d20160111-5693-7sn79h/spec.rb:148 # ObjectStore cannot create branch if already exists
rspec /tmp/d20160111-5693-7sn79h/spec.rb:153 # ObjectStore can switch branches
rspec /tmp/d20160111-5693-7sn79h/spec.rb:166 # ObjectStore cannot switch to nonexisting branch
rspec /tmp/d20160111-5693-7sn79h/spec.rb:171 # ObjectStore can remove branch
rspec /tmp/d20160111-5693-7sn79h/spec.rb:177 # ObjectStore cannot remove current branch
rspec /tmp/d20160111-5693-7sn79h/spec.rb:182 # ObjectStore cannot remove nonexisting branch
rspec /tmp/d20160111-5693-7sn79h/spec.rb:187 # ObjectStore can be initialized with block
rspec /tmp/d20160111-5693-7sn79h/spec.rb:217 # ObjectStore can checkout commits
rspec /tmp/d20160111-5693-7sn79h/spec.rb:227 # ObjectStore cannot checkout commits with nonexisting hashes
rspec /tmp/d20160111-5693-7sn79h/spec.rb:234 # ObjectStore cannot checkout commits in empty repository
rspec /tmp/d20160111-5693-7sn79h/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-7sn79h/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

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

Пепа обнови решението на 22.11.2015 23:11 (преди над 8 години)

+require 'ostruct'
+require 'digest/sha1'
+
+
+class ObjectStore
+ attr_accessor :current_branch
+
+ def initialize
+ @objects = {}
+ @staged = []
+ @branches = []
+ @current_branch = Branch.new('master')
+ @branches.push(@current_branch)
+ end
+
+ def self.init(&block)
+ ObjectStore.new
+ end
+
+ def add(name, object)
+ new_object = OpenStruct.new( name: name, object: object, action: :add )
+ @staged.push(new_object)
+
+ return Objects.new( { new_object.name => new_object.object },
+ "Added #{name} to stage.",
+ true )
+ end
+
+ def remove(name)
+ return Objects.new( nil, "Object #{name} is not committed.",
+ false ) unless @objects.has_key?(name)
+
+ removed = OpenStruct.new(name: name,object: @objects[name],action: :remove)
+ @staged.push(removed)
+
+ return Objects.new( { removed.name => removed.object },
+ "Added #{name} for removal.",
+ true )
+ end
+
+ def commit(msg)
+ return Objects.new( nil, "Nothing to commit, working directory clean.",
+ false ) if @staged.empty?
+
+ @current_branch.add_commit(Commit.new(msg, @staged))
+ apply_changes!(@staged)
+
+ return Objects.new(
+ @staged.clone,
+ "#{msg}\n\t#{@staged.shift(@staged.size).size} objects changed",
+ true )
+ end
+
+ def checkout(commit_hash)
+ return Objects.new( nil, "Commit #{hash} does not exist.",
+ false ) unless @current_branch.has_commit?(commit_hash)
+
+ current_commit = @current_branch.checkout_commit(commit_hash)
+
+ return Objects.new(
+ current_commit,
+ "HEAD is now at #{commit_hash}.",
+ true )
+ end
+
+ def head
+ return Objects.new( nil,
+ "Branch #{branch.name} does not have any commits yet.",
+ false ) if @current_branch.commits.empty?
+
+ Objects.new(
+ @current_branch.commits.last.objects,
+ @current_branch.commits.last.message,
+ true )
+ end
+
+ def branch
+ @current_branch
+ end
+
+ def log
+ return Objects.new( nil, "Branch #{name} does not have any commits yet.",
+ false ) if @current_branch.commits.empty?
+
+ commits = @current_branch.commits.reverse
+ message = ''
+
+ commits.each do |c|
+ message += "Commit #{c.hash}\nDate: #{c.date}\n\n\t#{c.message}\n\n"
+ end
+
+ return Objects.new(
+ nil,
+ message,
+ true )
+ end
+
+ def get(name)
+ return Objects.new( nil,
+ "Object #{name} is not committed.",
+ false ) unless @objects.has_key?(name)
+ Objects.new(
+ @objects[name],
+ "Found object #{name}.",
+ true )
+ end
+end
+
+private
+
+def apply_changes!(staged)
+ staged.each do |object|
+ if object.action == :add
+ @objects[object.name] = object.object
+ else
+ @objects.delete(object.name)
+ end
+ end
+end
+
+class Branch
+
+ attr_accessor :name, :commits
+
+ def initialize(name)
+ @name = name
+ @commits = []
+ end
+
+ def create(name)
+ p @current_branch
+ new_branch = Branch.new(name)
+ new_branch.commits = @commits.clone
+
+ return Objects.new( new_branch,
+ "Created branch #{name}.",
+ true )
+ end
+
+ def add_commit(commit)
+ commits.push(commit)
+ end
+
+ def checkout_commit(commit_hash)
+ index = commits.index {|commit| commit.hash == commit_hash}
+
+ commits.slice!(index + 1, commits.length)
+ commits.last
+ end
+
+ def has_commit?(commit_hash)
+ commits.each do |commit|
+ return true if commit.hash == commit_hash
+ end
+ false
+ end
+end
+
+class Commit
+
+ attr_reader :objects, :date, :hash, :message
+
+ alias :result :objects
+
+ def initialize(message, objects)
+ @message = message
+ @objects = []
+ @objects.concat(objects)
+ @date = Time.now.strftime "%a %b %d %H:%M %Y %z"
+ @hash = Digest::SHA1.hexdigest "#{@date}#{message}$"
+ end
+end
+
+class Objects
+ attr_reader :message, :result
+
+ def initialize(result = nil, message, success)
+ @message = message
+ @success = success
+ @result = result
+ end
+
+ def success?
+ @success
+ end
+
+ def error?
+ ! @success
+ end
+end