Решение на Втора задача от Илия Тобов

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

Към профила на Илия Тобов

Резултати

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

Код

class TodoList
include Enumerable
attr_reader :tasks
def self.parse(text)
tasks = text.each_line.map do |line|
Task.new(*line.split('|').map(&:strip))
end
new tasks
end
def initialize(tasks)
@tasks = tasks
end
def each(&block)
@tasks.each(&block)
end
def filter(criteria)
TodoList.new @tasks.select { |task| criteria.met_by? task }
end
def adjoin(other)
TodoList.new(tasks + other.tasks)
end
alias | adjoin
def tasks_todo
(filter Criteria.status(:todo)).tasks.size
end
def tasks_in_progress
(filter Criteria.status(:current)).tasks.size
end
def tasks_completed
(filter Criteria.status(:done)).tasks.size
end
def completed?
tasks.size == tasks_completed
end
end
class Task
attr_reader :status, :description, :priority, :tags
def initialize(status, description, priority, tags = nil)
@status = status.downcase.to_sym
@description = description
@priority = priority.downcase.to_sym
@tags = tags.split(", ") unless tags.nil?
end
def status
@status
end
def priority
@priority
end
def description
@description
end
def tags
@tags
end
end
class Criteria
def self.status(status)
AttributeMatch.new :status, status
end
def self.priority(priority)
AttributeMatch.new :priority, priority
end
def self.tags(tags)
TagsMatch.new tags
end
end
class AttributeMatch
def initialize(attribute, value)
@attribute = attribute
@value = value
end
def met_by?(task)
task.send(@attribute) == @value
end
end
class TagsMatches
def initialize(tags)
@tags = tags
end
def met_by?(task)
@tags.all? { |tag| task.tags.include? tag }
end
end

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

..FFFFFFFFFF.........F

Failures:

  1) TodoList filters tasks by tag
     Failure/Error: todo_list.filter(Criteria.tags %w[food]).map(&:description).should =~ ['Eat spaghetti.']
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/spec.rb:36: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 filters tasks by multiple tags
     Failure/Error: todo_list.filter(Criteria.tags %w[development ruby]).map(&:description).should =~ [
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/spec.rb:40: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 filtering by multiple tags matches only tasks with all the tags
     Failure/Error: todo_list.filter(Criteria.tags %w[development FMI]).map(&:description).should =~ ['Do the 5th Ruby challenge.']
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/spec.rb:47: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 supports a conjuction of filters
     Failure/Error: filtered = todo_list.filter Criteria.status(:todo) & Criteria.priority(:high)
     NoMethodError:
       undefined method `&' for #<AttributeMatch:0xb8d673e8 @attribute=:status, @value=:todo>
     # /tmp/d20131107-4393-19cu0ze/spec.rb:51: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 supports a disjunction of filters
     Failure/Error: filtered = todo_list.filter Criteria.status(:done) | Criteria.priority(:low)
     NoMethodError:
       undefined method `|' for #<AttributeMatch:0xb8d65228 @attribute=:status, @value=:done>
     # /tmp/d20131107-4393-19cu0ze/spec.rb:56: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 supports a negation of filters
     Failure/Error: filtered = todo_list.filter !Criteria.status(:todo)
     NoMethodError:
       undefined method `met_by?' for false:FalseClass
     # /tmp/d20131107-4393-19cu0ze/solution.rb:23:in `block in filter'
     # /tmp/d20131107-4393-19cu0ze/solution.rb:23:in `select'
     # /tmp/d20131107-4393-19cu0ze/solution.rb:23:in `filter'
     # /tmp/d20131107-4393-19cu0ze/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)>'

  7) TodoList supports simple filters combination
     Failure/Error: filtered = todo_list.filter Criteria.priority(:high) & !Criteria.tags(['development'])
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/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)>'

  8) TodoList supports complex filters combination
     Failure/Error: Criteria.priority(:high) |
     NoMethodError:
       undefined method `&' for #<AttributeMatch:0xb8b448e0 @attribute=:status, @value=:todo>
     # /tmp/d20131107-4393-19cu0ze/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)>'

  9) TodoList can be adjoined with another to-do list
     Failure/Error: development = todo_list.filter Criteria.tags(['development'])
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/spec.rb:97: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 constructs an object for each task
     Failure/Error: task = todo_list.filter(Criteria.tags ['health']).first
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/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)>'

  11) TodoList creates a new object on filter
     Failure/Error: todo_list.filter(Criteria.tags %w[wtf]).should_not equal todo_list
     NameError:
       uninitialized constant Criteria::TagsMatch
     # /tmp/d20131107-4393-19cu0ze/solution.rb:86:in `tags'
     # /tmp/d20131107-4393-19cu0ze/spec.rb:173: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.10113 seconds
22 examples, 11 failures

Failed examples:

rspec /tmp/d20131107-4393-19cu0ze/spec.rb:35 # TodoList filters tasks by tag
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:39 # TodoList filters tasks by multiple tags
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:46 # TodoList filtering by multiple tags matches only tasks with all the tags
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:50 # TodoList supports a conjuction of filters
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:55 # TodoList supports a disjunction of filters
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:65 # TodoList supports a negation of filters
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:75 # TodoList supports simple filters combination
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:80 # TodoList supports complex filters combination
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:96 # TodoList can be adjoined with another to-do list
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:109 # TodoList constructs an object for each task
rspec /tmp/d20131107-4393-19cu0ze/spec.rb:172 # TodoList creates a new object on filter

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

Илия обнови решението на 06.11.2013 16:47 (преди над 10 години)

+class TodoList
+ include Enumerable
+
+ attr_reader :tasks
+
+ def self.parse(text)
+ tasks = text.each_line.map do |line|
+ Task.new(*line.split('|').map(&:strip))
+ end
+
+ new tasks
+ end
+
+ def initialize(tasks)
+ @tasks = tasks
+ end
+
+ def each(&block)
+ @tasks.each(&block)
+ end
+
+ def filter(criteria)
+ TodoList.new @tasks.select { |task| criteria.met_by? task }
+ end
+
+ def adjoin(other)
+ TodoList.new(tasks + other.tasks)
+ end
+
+ alias | adjoin
+
+ def tasks_todo
+ (filter Criteria.status(:todo)).tasks.size
+ end
+
+ def tasks_in_progress
+ (filter Criteria.status(:current)).tasks.size
+ end
+
+ def tasks_completed
+ (filter Criteria.status(:done)).tasks.size
+ end
+
+ def completed?
+ tasks.size == tasks_completed
+ end
+end
+
+class Task
+ attr_reader :status, :description, :priority, :tags
+
+ def initialize(status, description, priority, tags = nil)
+ @status = status.downcase.to_sym
+ @description = description
+ @priority = priority.downcase.to_sym
+ @tags = tags.split(", ") unless tags.nil?
+ end
+
+ def status
+ @status
+ end
+
+ def priority
+ @priority
+ end
+
+ def description
+ @description
+ end
+
+ def tags
+ @tags
+ end
+end
+
+class Criteria
+ def self.status(status)
+ AttributeMatch.new :status, status
+ end
+
+ def self.priority(priority)
+ AttributeMatch.new :priority, priority
+ end
+
+ def self.tags(tags)
+ TagsMatch.new tags
+ end
+end
+
+class AttributeMatch
+ def initialize(attribute, value)
+ @attribute = attribute
+ @value = value
+ end
+
+ def met_by?(task)
+ task.send(@attribute) == @value
+ end
+end
+
+class TagsMatches
+ def initialize(tags)
+ @tags = tags
+ end
+
+ def met_by?(task)
+ @tags.all? { |tag| task.tags.include? tag }
+ end
+end