summaryrefslogtreecommitdiff
path: root/lib/family_tree.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/family_tree.rb')
-rw-r--r--lib/family_tree.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/family_tree.rb b/lib/family_tree.rb
index 0909ed1..908cb65 100644
--- a/lib/family_tree.rb
+++ b/lib/family_tree.rb
@@ -4,19 +4,35 @@ require 'singleton'
require_relative 'person'
require_relative 'family_factory'
+# FamilyTree class representing a family tree.
+# This class follows the Singleton pattern to ensure there is only one instance
+# of the family tree throughout the application. It uses the FamilyFactory to
+# seed the initial family tree with predefined families.
class FamilyTree
include Singleton
attr_accessor :families
+ # Initializes the FamilyTree instance.
+ # Seeds the initial family tree using the FamilyFactory.
def initialize
@families = FamilyFactory.new.create_families
end
+ # Adds a family to the family tree.
+ #
+ # @param family [Family] The family to add.
+ # @return [void]
def add_family(family)
@families << family unless @families.include?(family)
end
+ # Adds a child to a family based on the mother's name.
+ #
+ # @param mothers_name [String] The name of the mother.
+ # @param name [String] The name of the child.
+ # @param gender [String] The gender of the child.
+ # @return [String] 'CHILD_ADDED' if the child is added successfully, 'CHILD_ADDITION_FAILED' otherwise.
def add_child(mothers_name, name, gender)
result = find_person_in_families(mothers_name)
parent_of_family = result[:parent_of_family]
@@ -30,6 +46,11 @@ class FamilyTree
'CHILD_ADDED'
end
+ # Retrieves the relationship of a person based on their name and the specified relationship.
+ #
+ # @param name [String] The name of the person.
+ # @param relationship [String] The type of relationship to retrieve.
+ # @return [String] The name(s) of the related person(s) or an appropriate message if not found.
def get_relationship(name, relationship)
result = find_person_in_families(name)
person = result[:person]
@@ -64,6 +85,11 @@ class FamilyTree
private
+ # Handles the parent relationship retrieval.
+ #
+ # @param child_of_family [Family] The family of the child.
+ # @param relationship [String] The type of parent relationship ('mother' or 'father').
+ # @return [String] The name of the parent or 'PERSON_NOT_FOUND' if not found.
def handle_parent_relationship(child_of_family, relationship)
parent = relationship == 'mother' ? child_of_family&.mother : child_of_family&.father
return 'PERSON_NOT_FOUND' if parent.nil? || parent.is_a?(NilPerson)
@@ -71,11 +97,21 @@ class FamilyTree
parent.name
end
+ # Handles the siblings relationship retrieval.
+ #
+ # @param child_of_family [Family] The family of the child.
+ # @param name [String] The name of the child.
+ # @return [String] The names of the siblings or 'NONE' if not found.
def handle_siblings_relationship(child_of_family, name)
siblings = find_siblings(child_of_family, name)
siblings.empty? ? 'NONE' : siblings.map(&:name).join(' ')
end
+ # Handles the children relationship retrieval.
+ #
+ # @param parent_of_family [Family] The family of the parent.
+ # @param relationship [String] The type of children relationship ('child', 'son', or 'daughter').
+ # @return [String] The names of the children or 'NONE' if not found.
def handle_children_relationship(parent_of_family, relationship)
return 'NONE' if parent_of_family.nil?
@@ -95,6 +131,12 @@ class FamilyTree
end
end
+ # Handles the sibling relationship retrieval for uncles and aunts.
+ #
+ # @param child_of_family [Family] The family of the child.
+ # @param type [String] The type of sibling relationship ('uncle' or 'aunt').
+ # @param side [String] The side of the family ('paternal' or 'maternal').
+ # @return [String] The names of the uncles or aunts or 'NONE' if not found.
def handle_sibling_relationship(child_of_family, type, side)
return 'NONE' if child_of_family.nil?
@@ -123,22 +165,48 @@ class FamilyTree
relatives.empty? ? 'NONE' : relatives.map(&:name).join(' ')
end
+ # Handles the uncle relationship retrieval.
+ #
+ # @param child_of_family [Family] The family of the child.
+ # @param type [String] The type of uncle relationship ('paternal' or 'maternal').
+ # @return [String] The names of the uncles or 'NONE' if not found.
def handle_uncle_relationship(child_of_family, type)
handle_sibling_relationship(child_of_family, 'uncle', type)
end
+ # Handles the aunt relationship retrieval.
+ #
+ # @param child_of_family [Family] The family of the child.
+ # @param type [String] The type of aunt relationship ('paternal' or 'maternal').
+ # @return [String] The names of the aunts or 'NONE' if not found.
def handle_aunt_relationship(child_of_family, type)
handle_sibling_relationship(child_of_family, 'aunt', type)
end
+ # Handles the sister-in-law relationship retrieval.
+ #
+ # @param person [Person] The person whose sister-in-law is to be found.
+ # @param child_of_family [Family] The family of the child.
+ # @return [String] The names of the sisters-in-law or 'NONE' if not found.
def handle_sister_in_law_relationship(person, child_of_family)
find_in_laws(person, child_of_family, Gender::FEMALE)
end
+ # Handles the brother-in-law relationship retrieval.
+ #
+ # @param person [Person] The person whose brother-in-law is to be found.
+ # @param child_of_family [Family] The family of the child.
+ # @return [String] The names of the brothers-in-law or 'NONE' if not found.
def handle_brother_in_law_relationship(person, child_of_family)
find_in_laws(person, child_of_family, Gender::MALE)
end
+ # Finds the in-laws of a person based on their gender.
+ #
+ # @param person [Person] The person whose in-laws are to be found.
+ # @param child_of_family [Family] The family of the child.
+ # @param gender [String] The gender of the in-laws to find.
+ # @return [String] The names of the in-laws or 'NONE' if not found.
def find_in_laws(person, child_of_family, gender)
in_laws = []
@@ -166,6 +234,10 @@ class FamilyTree
in_laws.empty? ? 'NONE' : in_laws.join(' ')
end
+ # Finds a person in the families by name.
+ #
+ # @param name [String] The name of the person to find.
+ # @return [Hash] A hash containing the person, parent_of_family, and child_of_family.
def find_person_in_families(name)
result = { person: NilPerson.new, parent_of_family: nil, child_of_family: nil }
@@ -195,10 +267,20 @@ class FamilyTree
result
end
+ # Finds the siblings of a person in a family.
+ #
+ # @param family [Family] The family of the person.
+ # @param name [String] The name of the person.
+ # @return [Array<Person>] An array of siblings.
def find_siblings(family, name)
family.children.reject { |child| child.name.casecmp(name).zero? }
end
+ # Checks if a person is a child of a family.
+ #
+ # @param family [Family] The family to check.
+ # @param name [String] The name of the person.
+ # @return [Boolean] True if the person is a child of the family, false otherwise.
def child_of_family?(family, name)
return false unless family.is_a?(Family)