diff options
| -rw-r--r-- | lib/family_tree.rb | 50 | ||||
| -rw-r--r-- | lib/relationship_manager.rb | 1 | ||||
| -rw-r--r-- | spec/family_tree_spec.rb | 140 |
3 files changed, 167 insertions, 24 deletions
diff --git a/lib/family_tree.rb b/lib/family_tree.rb index ebb2955..66af748 100644 --- a/lib/family_tree.rb +++ b/lib/family_tree.rb @@ -8,11 +8,10 @@ require_relative 'family_factory' class FamilyTree include Singleton - attr_accessor :families, :people + attr_accessor :families def initialize @families = FamilyFactory.new.create_families - @people = [] end def add_family(family) @@ -24,35 +23,38 @@ class FamilyTree end def get_relationship(name, relationship) - family = find_family(name) - - return [] if family.nil? - - if child_of_family?(family, name) - case relationship.downcase - when 'mother' - mother = find_mother(family) - return mother.is_a?(NilPerson) ? [] : [mother] - when 'father' - father = find_father(family) - return father.is_a?(NilPerson) ? [] : [father] - when 'siblings' - return find_siblings(family, name) - else - return [] - end + result = find_person_and_family(name) + person = result[:person] + family = result[:family] + + return 'PERSON_NOT_FOUND' if family.nil? || person.is_a?(NilPerson) + + case relationship.downcase + when 'mother' + mother = find_mother(family) + return 'PERSON_NOT_FOUND' if mother.is_a?(NilPerson) + + mother.name + when 'father' + father = find_father(family) + return 'PERSON_NOT_FOUND' if father.is_a?(NilPerson) + + father.name + when 'siblings' + siblings = find_siblings(family, name) + siblings.empty? ? 'NONE' : siblings.map(&:name).join(' ') + else + 'UNSUPPORTED_RELATIONSHIP' end - - [] end - def find_family(name) + def find_person_and_family(name) families.each do |family| family.children.each do |child| - return family if child.name.casecmp(name).zero? + return { person: child, family: family } if child.name.casecmp(name).zero? end end - nil + { person: NilPerson.new, family: nil } end def find_mother(family) diff --git a/lib/relationship_manager.rb b/lib/relationship_manager.rb index 4b6a4a2..08d87e1 100644 --- a/lib/relationship_manager.rb +++ b/lib/relationship_manager.rb @@ -4,6 +4,7 @@ require 'singleton' class RelationshipManager include Singleton + def link_spouses(person1, person2) # Check if either person is already linked to someone else if person1.spouse != NilPerson.new && person1.spouse != person2 diff --git a/spec/family_tree_spec.rb b/spec/family_tree_spec.rb index ba05aa3..dc91719 100644 --- a/spec/family_tree_spec.rb +++ b/spec/family_tree_spec.rb @@ -1,6 +1,146 @@ # frozen_string_literal: true require_relative '../lib/family_tree' +require_relative '../lib/person' +require_relative '../lib/family' RSpec.describe FamilyTree do + let(:mother) { Person.new('Jane', Gender::FEMALE) } + let(:father) { Person.new('John', Gender::MALE) } + let(:child1) { Person.new('Anna', Gender::FEMALE) } + let(:child2) { Person.new('Bob', Gender::MALE) } + let(:family) { Family.new(mother, father, [child1, child2]) } + + before do + # Reset FamilyTree singleton before each test + FamilyTree.instance.families.clear + end + + describe '#add_family' do + it 'adds a family to the family list' do + FamilyTree.instance.add_family(family) + expect(FamilyTree.instance.families).to include(family) + end + + it 'does not add a duplicate family' do + FamilyTree.instance.add_family(family) + FamilyTree.instance.add_family(family) + expect(FamilyTree.instance.families.count).to eq(1) + end + end + + describe '#add_child' do + it 'outputs the correct parameters when adding a child' do + expect do + FamilyTree.instance.add_child('Jane', 'Sam', + 'Male') + end.to output("Adding Child with params: Jane, Sam, Male\n").to_stdout + end + end + + describe '#get_relationship' do + before do + FamilyTree.instance.add_family(family) + end + + context 'when finding mother' do + it 'returns the mother if present' do + result = FamilyTree.instance.get_relationship('Anna', 'mother') + expect(result).to eq(mother.name) + end + + it 'returns PERSON_NOT_FOUND if the person has no mother' do + orphan_family = Family.new(NilPerson.new, father, [child1]) + FamilyTree.instance.families.clear + FamilyTree.instance.add_family(orphan_family) + + result = FamilyTree.instance.get_relationship('Anna', 'mother') + expect(result).to eq('PERSON_NOT_FOUND') + end + end + + context 'when finding father' do + it 'returns father\'s name if present' do + result = FamilyTree.instance.get_relationship('Anna', 'father') + expect(result).to eq(father.name) + end + + it 'returns PERSON_NOT_FOUND if the person has no father' do + orphan_family = Family.new(mother, NilPerson.new, [child1]) + FamilyTree.instance.families.clear + FamilyTree.instance.add_family(orphan_family) + + result = FamilyTree.instance.get_relationship('Anna', 'father') + expect(result).to eq('PERSON_NOT_FOUND') + end + end + + context 'when finding siblings' do + it 'returns the sibling\'s name if present' do + result = FamilyTree.instance.get_relationship('Anna', 'siblings') + expect(result).to eq(child2.name) + end + + it 'returns NONE if there are no siblings' do + single_child_family = Family.new(mother, father, [child1]) + FamilyTree.instance.families.clear + FamilyTree.instance.add_family(single_child_family) + + result = FamilyTree.instance.get_relationship('Anna', 'siblings') + expect(result).to eq('NONE') + end + end + + context 'when relationship type is invalid' do + it 'returns UNSUPPORTED_RELATIONSHIP' do + result = FamilyTree.instance.get_relationship('Anna', 'uncle') + expect(result).to eq('UNSUPPORTED_RELATIONSHIP') + end + end + end + + describe '#find_mother' do + it 'returns the mother if present' do + expect(FamilyTree.instance.find_mother(family)).to eq(mother) + end + + it 'returns NilPerson if no mother is present' do + orphan_family = Family.new(NilPerson.new, father, [child1]) + expect(FamilyTree.instance.find_mother(orphan_family)).to be_a(NilPerson) + end + end + + describe '#find_father' do + it 'returns the father if present' do + expect(FamilyTree.instance.find_father(family)).to eq(father) + end + + it 'returns NilPerson if no father is present' do + orphan_family = Family.new(mother, NilPerson.new, [child1]) + expect(FamilyTree.instance.find_father(orphan_family)).to be_a(NilPerson) + end + end + + describe '#find_siblings' do + it 'returns siblings in the same family' do + result = FamilyTree.instance.find_siblings(family, 'Anna') + expect(result).to eq([child2]) + end + + it 'returns empty array if there are no siblings' do + single_child_family = Family.new(mother, father, [child1]) + result = FamilyTree.instance.find_siblings(single_child_family, 'Anna') + expect(result).to eq([]) + end + end + + describe '#child_of_family?' do + it 'returns true if the person is a child of the family' do + expect(FamilyTree.instance.child_of_family?(family, 'Anna')).to be true + end + + it 'returns false if the person is not a child of the family' do + expect(FamilyTree.instance.child_of_family?(family, 'Unknown')).to be false + end + end end |
