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

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

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

Резултати

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

Код

class Todo
attr_reader :status, :description, :priority, :tags
def initialize status, description, priority, tags
@status = status.downcase.to_sym
@description = description
@priority = priority.downcase.to_sym
@tags = to_tag_array tags
end
def includes_tags?(tag_list)
tag_list.all? { |tag| tags.include? tag }
end
private
def to_tag_array(value)
if value.is_a?(String)
value.split(',').map &:strip
else
value
end
end
end
require 'forwardable'
class TodoList
attr_reader :todos
def initialize(todos = [])
@todos = todos
end
extend Forwardable
def_delegators :@todos,
:size, :count, :each, :find_all, :map, :to_a
def filter(criteria)
self.class.new find_all(&criteria)
end
def tasks_completed
filter(Criteria.status(:done)).size
end
def adjoin(todo_list)
self.class.new(self.to_a + todo_list.to_a)
end
def self.parse(todo_list_text)
new(todo_list_text.lines.map do |todo_line|
Todo.new *todo_line.split('|').map(&:strip)
end)
end
end
class Criteria
def initialize(condition)
@condition = condition
end
def to_proc
@condition
end
def &(criteria)
Criteria.new ->(todo) do
self.to_proc.call(todo) and criteria.to_proc.call(todo)
end
end
def |(criteria)
Criteria.new ->(todo) do
self.to_proc.call(todo) or criteria.to_proc.call(todo)
end
end
def self.tags(tag_list)
Criteria.new ->(todo) { todo.includes_tags? tag_list }
end
def self.status(value)
Criteria.new ->(todo) { todo.status == value }
end
def self.priority(value)
Criteria.new ->(todo) { todo.priority == value }
end
end

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

.......FFF.FFF.F.FFF..

Failures:

  1) TodoList supports a negation of filters
     Failure/Error: filtered = todo_list.filter !Criteria.status(:todo)
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20131107-4393-10b4dgq/solution.rb:41:in `filter'
     # /tmp/d20131107-4393-10b4dgq/spec.rb:66: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) TodoList supports simple filters combination
     Failure/Error: filtered = todo_list.filter Criteria.priority(:high) & !Criteria.tags(['development'])
     NoMethodError:
       undefined method `to_proc' for false:FalseClass
     # /tmp/d20131107-4393-10b4dgq/solution.rb:70:in `block in &'
     # /tmp/d20131107-4393-10b4dgq/solution.rb:41:in `filter'
     # /tmp/d20131107-4393-10b4dgq/spec.rb:76: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) TodoList supports complex filters combination
     Failure/Error: filtered = todo_list.filter Criteria.status(:todo) &
     NoMethodError:
       undefined method `to_proc' for false:FalseClass
     # /tmp/d20131107-4393-10b4dgq/solution.rb:70:in `block in &'
     # /tmp/d20131107-4393-10b4dgq/solution.rb:76:in `call'
     # /tmp/d20131107-4393-10b4dgq/solution.rb:76:in `block in |'
     # /tmp/d20131107-4393-10b4dgq/solution.rb:41:in `filter'
     # /tmp/d20131107-4393-10b4dgq/spec.rb:81: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) TodoList constructs an object for each task
     Failure/Error: task = todo_list.filter(Criteria.tags ['health']).first
     NoMethodError:
       undefined method `first' for #<TodoList:0xb8b4eee4>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:110: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) TodoList returns the number of the tasks todo
     Failure/Error: todo_list.tasks_todo.should eq 5
     NoMethodError:
       undefined method `tasks_todo' for #<TodoList:0xb8b4cbf8>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:119: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) TodoList returns the number of the tasks in progress
     Failure/Error: todo_list.tasks_in_progress.should eq 2
     NoMethodError:
       undefined method `tasks_in_progress' for #<TodoList:0xb8b46474>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:123: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) TodoList checks if all tasks are completed
     Failure/Error: todo_list.completed?.should eq false
     NoMethodError:
       undefined method `completed?' for #<TodoList:0xb8b418d4>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:131: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) TodoList implements Enumerable
     Failure/Error: todo_list.should be_an Enumerable
       expected #<TodoList:0xb8b2f440 @todos=[#<Todo:0xb8b30598 @status=:todo, @description="Eat spaghetti.", @priority=:high, @tags=["food", "happiness"]>, #<Todo:0xb8b30390 @status=:todo, @description="Get 8 hours of sleep.", @priority=:low, @tags=["health"]>, #<Todo:0xb8b30160 @status=:current, @description="Party animal.", @priority=:normal, @tags=["socialization"]>, #<Todo:0xb8b33504 @status=:current, @description="Grok Ruby.", @priority=:high, @tags=["development", "ruby"]>, #<Todo:0xb8b2fe2c @status=:done, @description="Have some tea.", @priority=:normal, @tags=[]>, #<Todo:0xb8b2fc60 @status=:todo, @description="Destroy Facebook and Google.", @priority=:high, @tags=["save humanity", "conspiracy"]>, #<Todo:0xb8b2f9a4 @status=:done, @description="Do the 5th Ruby challenge.", @priority=:high, @tags=["ruby course", "FMI", "development", "ruby"]>, #<Todo:0xb8b2f74c @status=:todo, @description="Find missing socks.", @priority=:low, @tags=[]>, #<Todo:0xb8b2f594 @status=:todo, @description="Occupy Sofia University.", @priority=:high, @tags=["#ДАНСwithMe", "#occupysu", "#оставка"]>]> to be a kind of Enumerable
     # /tmp/d20131107-4393-10b4dgq/spec.rb:142: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) TodoList contains tasks with the neccessary interface
     Failure/Error: task = todo_list.first
     NoMethodError:
       undefined method `first' for #<TodoList:0xb8b13f9c>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:146: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) TodoList tasks have an array of tags
     Failure/Error: todo_list.first.tags.should be_an Array
     NoMethodError:
       undefined method `first' for #<TodoList:0xb8ae7c6c>
     # /tmp/d20131107-4393-10b4dgq/spec.rb:155: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.03939 seconds
22 examples, 10 failures

Failed examples:

rspec /tmp/d20131107-4393-10b4dgq/spec.rb:65 # TodoList supports a negation of filters
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:75 # TodoList supports simple filters combination
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:80 # TodoList supports complex filters combination
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:109 # TodoList constructs an object for each task
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:118 # TodoList returns the number of the tasks todo
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:122 # TodoList returns the number of the tasks in progress
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:130 # TodoList checks if all tasks are completed
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:140 # TodoList implements Enumerable
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:145 # TodoList contains tasks with the neccessary interface
rspec /tmp/d20131107-4393-10b4dgq/spec.rb:154 # TodoList tasks have an array of tags

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

Димитър обнови решението на 06.11.2013 11:37 (преди над 10 години)

+
+class Todo
+ attr_reader :status, :description, :priority, :tags
+
+ def initialize status, description, priority, tags
+ @status = status.downcase.to_sym
+ @description = description
+ @priority = priority.downcase.to_sym
+ @tags = to_tag_array tags
+ end
+
+ def includes_tags?(tag_list)
+ tag_list.all? { |tag| tags.include? tag }
+ end
+
+ private
+
+ def to_tag_array(value)
+ if value.is_a?(String)
+ value.split(',').map &:strip
+ else
+ value
+ end
+ end
+end
+
+require 'forwardable'
+
+class TodoList
+ attr_reader :todos
+
+ def initialize(todos = [])
+ @todos = todos
+ end
+
+ extend Forwardable
+ def_delegators :@todos,
+ :size, :count, :each, :find_all, :map, :to_a
+
+ def filter(criteria)
+ self.class.new find_all(&criteria)
+ end
+
+ def tasks_completed
+ filter(Criteria.status(:done)).size
+ end
+
+ def adjoin(todo_list)
+ self.class.new(self.to_a + todo_list.to_a)
+ end
+
+ def self.parse(todo_list_text)
+ new(todo_list_text.lines.map do |todo_line|
+ Todo.new *todo_line.split('|').map(&:strip)
+ end)
+ end
+end
+
+class Criteria
+ def initialize(condition)
+ @condition = condition
+ end
+
+ def to_proc
+ @condition
+ end
+
+ def &(criteria)
+ Criteria.new ->(todo) do
+ self.to_proc.call(todo) and criteria.to_proc.call(todo)
+ end
+ end
+
+ def |(criteria)
+ Criteria.new ->(todo) do
+ self.to_proc.call(todo) or criteria.to_proc.call(todo)
+ end
+ end
+
+ def self.tags(tag_list)
+
+ Criteria.new ->(todo) { todo.includes_tags? tag_list }
+ end
+
+ def self.status(value)
+ Criteria.new ->(todo) { todo.status == value }
+ end
+
+ def self.priority(value)
+ Criteria.new ->(todo) { todo.priority == value }
+ end
+end