examples/bug_system.rb
# frozen_string_literal: true
require_relative "../lib/finite_machine"
class User
attr_accessor :name
def initialize(name)
@name = name
end
end
class Manager < User
attr_accessor :developers
def initialize(name)
super
@developers = []
end
def manages(developer)
@developers << developer
end
def assign(bug)
developer = @developers.first
bug.assign
developer.bug = bug
end
end
class Tester < User
def report(bug)
bug.report
end
def reopen(bug)
bug.reopen
end
end
class Developer < User
attr_accessor :bug
def work_on
bug.start
end
def resolve
bug.close
end
end
class BugSystem
attr_accessor :managers
def initialize(managers = [])
@managers = managers
end
def notify_manager(bug)
manager = @managers.first
puts "Notifying #{manager.name.inspect} about #{bug.name.inspect}"
manager.assign(bug)
end
end
class BugStatus < FiniteMachine::Definition
alias_target :bug
event :report, :none => :new
event :assign, :new => :assigned
event :start, :assigned => :in_progress
event :close, [:in_progress, :reopened] => :resolved
event :reopen, :resolved => :reopened
on_enter :new do |event|
bug.notify_manager
end
end
class Bug
attr_reader :name
attr_reader :priority
attr_reader :status
# fake belongs_to relationship
attr_accessor :bug_system
def initialize(name, priority)
@name = name
@priority = priority
@status = BugStatus.new(self)
end
def report
status.report
end
def assign
status.assign
end
def start
status.start
end
def close
status.close
end
def reopen
status.reopen
end
def notify_manager
bug_system.notify_manager(self)
end
end
tester = Tester.new("John")
manager = Manager.new("David")
developer = Developer.new("Piotr")
manager.manages(developer)
bug_system = BugSystem.new([manager])
bug = Bug.new(:trojan, :high)
bug.bug_system = bug_system
puts "A BUG's LIFE"
puts "#1 #{bug.status.current}"
tester.report(bug)
puts "#2 #{bug.status.current}"
developer.work_on
puts "#3 #{bug.status.current}"
developer.resolve
puts "#4 #{bug.status.current}"
tester.reopen(bug)
puts "#5 #{bug.status.current}"
developer.resolve
puts "#6 #{bug.status.current}"