Решение на Пета задача от Димитър Терзиев

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

Към профила на Димитър Терзиев

Резултати

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

Код

require 'digest/sha1'
require "date"
class ObjectStore
def initialize
@branches = Branches.new
@state = {}
end
def self.init(&init_block)
repository = ObjectStore.new
repository.instance_eval &init_block if block_given?
repository
end
def add(name, object)
@state[name] = object
Result.new "Added #{name} to stage.", true, object
end
def remove(name)
object = @state.delete name
if object
Result.new "Added #{name} for removal", true, object
else
Result.new "Object #{name} is not committed.", false
end
end
def commit(commit_message)
if @state == branch.current_branch.state
Result.new "Nothing to commit, working directory clean.", false
else
branch.current_branch.commit_state @state, commit_message
end
end
def checkout(commit_hash)
commit = branch.current_branch.checkout(commit_hash)
if commit
Result.new "HEAD is now at #{commit_hash}.", true, commit
else
Result.new "Commit #{commit_hash} does not exist.", false
end
end
def head
head = branch.current_branch.last_commit
if head
Result.new head.message, true, head
else
branch_name = branch.current_branch_name
Result.new "Branch #{branch_name} does not have any commits yet.", false
end
end
def get(name)
object = branch.current_branch.state[name]
if object
Result.new "Found object #{name}.", true, object
else
Result.new "Object #{name} is not committed.", false
end
end
def branch
@branches
end
def log
if @branches.current_branch.commits_string
Result.new @branches.current_branch.commits_string, true
else
branch_name = @branches.current_branch_name
Result.new "Branch #{branch_name} does not have any commits yet.", false
end
end
class Branches
attr_reader :current_branch
def initialize()
@branches = {}
create "master"
@current_branch = @branches["master"]
end
def create(branch_name)
if @branches[branch_name]
Result.new "Branch #{branch_name} already exists.", false
else
@branches[branch_name] = Branch.new @current_branch
Result.new "Created branch #{branch_name}.", true
end
end
def checkout(branch_name)
if @branches[branch_name]
@current_branch = @branches[branch_name]
Result.new "Switched to branch #{branch_name}.", true
else
Result.new "Branch #{branch_name} does not exist.", false
end
end
def remove(branch_name)
if @branches[branch_name]
if @current_branch == @branches[branch_name]
Result.new "Cannot remove current branch.", false
else
@branches.delete(branch_name)
Result.new "Removed branch #{branch_name}.", true
end
else
Result.new "Branch #{branch_name} does not exist.", false
end
end
def list
branch_list = @branches.keys.sort.map do |name|
(@branches[name] == @current_branch ? "* " : " ") + name
end.join("\n")
Result.new branch_list, true
end
def current_branch_name
@branches.key @current_branch
end
class Branch
attr_reader :state, :commits
def initialize(parent = nil)
@commits, @state = parent ? [parent.commits, parent.state] : [[], {}]
end
def commit_state(state, message)
intersection = (@state.to_a | state.to_a) - (@state.to_a & state.to_a)
count = intersection.to_h.size
@state = state.dup
@commits.push(Commit.new state, message)
Result.new "#{message}\n\t#{count} objects changed", true, last_commit
end
def last_commit
@commits.last
end
def commits_string
@commits.empty? ? nil : @commits.reverse.join("\n\n")
end
def checkout(hash)
commit_index = @commits.index{|commit| commit.hash == hash}
commit_index ? (@commits = commits[0..commit_index]).last : nil
end
class Commit
attr_reader :hash, :commit_message
def initialize(state, message)
@state = state
@commit_message = message
@date = Time.now
@hash = Digest::SHA1.hexdigest "#{@date}#{@message}"
end
def date
@date
end
def message
@commit_message
end
def hash
@hash
end
def objects
@state.values
end
def to_s
format = "%a %b %d %H:%M %Y %z"
"Commit #{@hash}\nDate: #{@date.strftime format}\n\n\t#{@message}"
end
end
end
end
class Result
def initialize(message, successful, result = nil)
@message = message
@successful = successful
@result = result
end
def success?
@successful
end
def error?
! @successful
end
def result
@result
end
def message
@message
end
def to_s
message
end
end
end

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

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

Failures:

  1) ObjectStore can remove objects
     Failure/Error: expect(repo.remove("object1")).to be_success("Added object1 for removal.", "content1")
       expected #<ObjectStore::Result:0x007f6b54938688 @message="Added object1 for removal", @successful=true, @result="content1"> to be success "Added object1 for removal." and "content1"
     # /tmp/d20160111-5693-1mxw8tz/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)>'

  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 #<ObjectStore::Result:0x007f6b54542150 @message="Commit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t", @successful=true, @result=nil> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-1mxw8tz/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)>'

  3) 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 #<ObjectStore::Result:0x007f6b5450d040 @message="Commit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t", @successful=true, @result=nil> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-1mxw8tz/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)>'

  4) 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 #<ObjectStore::Result:0x007f6b544db5b8 @message="Commit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t\n\nCommit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t", @successful=true, @result=nil> 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-1mxw8tz/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)>'

  5) 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 #<ObjectStore::Result:0x007f6b544c00d8 @message="Commit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t\n\nCommit a1e78b9e0f8ae3cc42a8e995368542dc45c954ee\nDate: Mon Jan 11 11:55 2016 +0200\n\n\t", @successful=true, @result=nil> to be success "Commit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-1mxw8tz/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)>'

  6) ObjectStore can switch branches
     Failure/Error: expect(repo.head).to be_success("First commit", first_commit)
       expected #<ObjectStore::Result:0x007f6b541d7718 @message="Second commit", @successful=true, @result=#<ObjectStore::Branches::Branch::Commit:0x007f6b541ea070 @state={"object1"=>"content1", "object2"=>"content2"}, @commit_message="Second commit", @date=2016-01-11 11:55:06 +0200, @hash="a1e78b9e0f8ae3cc42a8e995368542dc45c954ee">> to be success "First commit" and #<ObjectStore::Branches::Branch::Commit:0x007f6b543a52e8 @state={"object1"=>"content1", "object2"=>"content2"}, @commit_message="First commit", @date=2016-01-11 11:55:06 +0200, @hash="a1e78b9e0f8ae3cc42a8e995368542dc45c954ee">
     # /tmp/d20160111-5693-1mxw8tz/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.03381 seconds
30 examples, 6 failures

Failed examples:

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

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

Димитър обнови решението на 19.11.2015 11:01 (преди над 8 години)

+require 'digest/sha1'
+require "date"
+class ObjectStore
+ def initialize
+ @branches = Branches.new
+ @state = {}
+ end
+
+ def self.init(&init_block)
+ repository = ObjectStore.new
+ repository.instance_eval &init_block if block_given?
+ repository
+ end
+
+ def add(name, object)
+ @state[name] = object
+ Result.new "Added #{name} to stage.", true, object
+ end
+
+ def remove(name)
+ object = @state.delete name
+ if object
+ Result.new "Added #{name} for removal", true, object
+ else
+ Result.new "Object #{name} is not committed.", false
+ end
+ end
+
+ def commit(commit_message)
+ if @state == branch.current_branch.state
+ Result.new "Nothing to commit, working directory clean.", false
+ else
+ branch.current_branch.commit_state @state, commit_message
+ end
+ end
+
+ def checkout(commit_hash)
+ commit = branch.current_branch.checkout(commit_hash)
+ if commit
+ Result.new "HEAD is now at #{commit_hash}.", true, commit
+ else
+ Result.new "Commit #{commit_hash} does not exist.", false
+ end
+ end
+
+ def head
+ head = branch.current_branch.last_commit
+ if head
+ Result.new head.message, true, head
+ else
+ branch_name = branch.current_branch_name
+ Result.new "Branch #{branch_name} does not have any commits yet.", false
+ end
+ end
+
+ def get(name)
+ object = branch.current_branch.state[name]
+ if object
+ Result.new "Found object #{name}.", true, object
+ else
+ Result.new "Object #{name} is not committed.", false
+ end
+ end
+
+ def branch
+ @branches
+ end
+
+ def log
+ if @branches.current_branch.commits_string
+ Result.new @branches.current_branch.commits_string, true
+ else
+ branch_name = @branches.current_branch_name
+ Result.new "Branch #{branch_name} does not have any commits yet.", false
+ end
+ end
+
+ class Branches
+ attr_reader :current_branch
+ def initialize()
+ @branches = {}
+ create "master"
+ @current_branch = @branches["master"]
+ end
+
+ def create(branch_name)
+ if @branches[branch_name]
+ Result.new "Branch #{branch_name} already exists.", false
+ else
+ @branches[branch_name] = Branch.new @current_branch
+ Result.new "Created branch #{branch_name}.", true
+ end
+ end
+
+ def checkout(branch_name)
+ if @branches[branch_name]
+ @current_branch = @branches[branch_name]
+ Result.new "Switched to branch #{branch_name}.", true
+ else
+ Result.new "Branch #{branch_name} does not exist.", false
+ end
+ end
+
+ def remove(branch_name)
+ if @branches[branch_name]
+ if @current_branch == @branches[branch_name]
+ Result.new "Cannot remove current branch.", false
+ else
+ @branches.delete(branch_name)
+ Result.new "Removed branch #{branch_name}.", true
+ end
+ else
+ Result.new "Branch #{branch_name} does not exist.", false
+ end
+ end
+
+ def list
+ branch_list = @branches.keys.sort.map do |name|
+ (@branches[name] == @current_branch ? "* " : " ") + name
+ end.join("\n")
+ Result.new branch_list, true
+ end
+
+ def current_branch_name
+ @branches.key @current_branch
+ end
+
+ class Branch
+ attr_reader :state, :commits
+ def initialize(parent = nil)
+ @commits, @state = parent ? [parent.commits, parent.state] : [[], {}]
+ end
+
+ def commit_state(state, message)
+ intersection = (@state.to_a | state.to_a) - (@state.to_a & state.to_a)
+ count = intersection.to_h.size
+ @state = state.dup
+ @commits.push(Commit.new state, message)
+ Result.new "#{message}\n\t#{count} objects changed", true, last_commit
+ end
+
+ def last_commit
+ @commits.last
+ end
+
+ def commits_string
+ @commits.empty? ? nil : @commits.reverse.join("\n\n")
+ end
+
+ def checkout(hash)
+ commit_index = @commits.index{|commit| commit.hash == hash}
+ commit_index ? (@commits = commits[0..commit_index]).last : nil
+ end
+
+ class Commit
+ attr_reader :hash, :commit_message
+ def initialize(state, message)
+ @state = state
+ @commit_message = message
+ @date = Time.now
+ @hash = Digest::SHA1.hexdigest "#{@date}#{@message}"
+ end
+
+ def date
+ @date
+ end
+
+ def message
+ @commit_message
+ end
+
+ def hash
+ @hash
+ end
+
+ def objects
+ @state.values
+ end
+
+ def to_s
+ format = "%a %b %d %H:%M %Y %z"
+ "Commit #{@hash}\nDate: #{@date.strftime format}\n\n\t#{@message}"
+ end
+ end
+ end
+ end
+
+ class Result
+ def initialize(message, successful, result = nil)
+ @message = message
+ @successful = successful
+ @result = result
+ end
+
+ def success?
+ @successful
+ end
+
+ def error?
+ ! @successful
+ end
+
+ def result
+ @result
+ end
+
+ def message
+ @message
+ end
+
+ def to_s
+ message
+ end
+ end
+end

Димитър обнови решението на 19.11.2015 11:08 (преди над 8 години)

require 'digest/sha1'
require "date"
class ObjectStore
def initialize
@branches = Branches.new
@state = {}
end
- def self.init(&init_block)
+ def self.init(&init_block)
repository = ObjectStore.new
repository.instance_eval &init_block if block_given?
repository
end
def add(name, object)
@state[name] = object
Result.new "Added #{name} to stage.", true, object
end
def remove(name)
object = @state.delete name
if object
- Result.new "Added #{name} for removal", true, object
+ Result.new "Added #{name} for removal", true, object
else
- Result.new "Object #{name} is not committed.", false
+ Result.new "Object #{name} is not committed.", false
end
end
def commit(commit_message)
if @state == branch.current_branch.state
Result.new "Nothing to commit, working directory clean.", false
else
branch.current_branch.commit_state @state, commit_message
end
end
def checkout(commit_hash)
commit = branch.current_branch.checkout(commit_hash)
if commit
Result.new "HEAD is now at #{commit_hash}.", true, commit
else
- Result.new "Commit #{commit_hash} does not exist.", false
+ Result.new "Commit #{commit_hash} does not exist.", false
end
end
def head
head = branch.current_branch.last_commit
if head
Result.new head.message, true, head
else
branch_name = branch.current_branch_name
- Result.new "Branch #{branch_name} does not have any commits yet.", false
+ Result.new "Branch #{branch_name} does not have any commits yet.", false
end
end
def get(name)
object = branch.current_branch.state[name]
if object
Result.new "Found object #{name}.", true, object
else
Result.new "Object #{name} is not committed.", false
end
end
def branch
@branches
end
def log
if @branches.current_branch.commits_string
Result.new @branches.current_branch.commits_string, true
else
branch_name = @branches.current_branch_name
Result.new "Branch #{branch_name} does not have any commits yet.", false
end
end
class Branches
attr_reader :current_branch
def initialize()
@branches = {}
create "master"
@current_branch = @branches["master"]
end
def create(branch_name)
if @branches[branch_name]
Result.new "Branch #{branch_name} already exists.", false
else
@branches[branch_name] = Branch.new @current_branch
Result.new "Created branch #{branch_name}.", true
end
end
def checkout(branch_name)
if @branches[branch_name]
@current_branch = @branches[branch_name]
Result.new "Switched to branch #{branch_name}.", true
else
Result.new "Branch #{branch_name} does not exist.", false
end
end
def remove(branch_name)
if @branches[branch_name]
if @current_branch == @branches[branch_name]
Result.new "Cannot remove current branch.", false
else
@branches.delete(branch_name)
Result.new "Removed branch #{branch_name}.", true
end
else
Result.new "Branch #{branch_name} does not exist.", false
end
end
def list
branch_list = @branches.keys.sort.map do |name|
(@branches[name] == @current_branch ? "* " : " ") + name
end.join("\n")
Result.new branch_list, true
end
def current_branch_name
@branches.key @current_branch
end
class Branch
attr_reader :state, :commits
def initialize(parent = nil)
@commits, @state = parent ? [parent.commits, parent.state] : [[], {}]
end
def commit_state(state, message)
intersection = (@state.to_a | state.to_a) - (@state.to_a & state.to_a)
count = intersection.to_h.size
@state = state.dup
@commits.push(Commit.new state, message)
Result.new "#{message}\n\t#{count} objects changed", true, last_commit
end
def last_commit
@commits.last
end
def commits_string
@commits.empty? ? nil : @commits.reverse.join("\n\n")
end
def checkout(hash)
commit_index = @commits.index{|commit| commit.hash == hash}
commit_index ? (@commits = commits[0..commit_index]).last : nil
end
class Commit
attr_reader :hash, :commit_message
def initialize(state, message)
@state = state
@commit_message = message
@date = Time.now
@hash = Digest::SHA1.hexdigest "#{@date}#{@message}"
end
def date
@date
end
def message
@commit_message
end
def hash
@hash
end
def objects
@state.values
end
def to_s
format = "%a %b %d %H:%M %Y %z"
"Commit #{@hash}\nDate: #{@date.strftime format}\n\n\t#{@message}"
end
end
end
end
class Result
def initialize(message, successful, result = nil)
@message = message
@successful = successful
@result = result
end
def success?
@successful
end
def error?
! @successful
end
def result
@result
end
def message
@message
end
def to_s
message
end
end
end