diff options
| author | Szymon Szukalski <szymon@skas.io> | 2024-10-24 21:10:57 +1100 |
|---|---|---|
| committer | Szymon Szukalski <szymon@skas.io> | 2024-10-24 21:10:57 +1100 |
| commit | 9bc26146397acb5a216e20d5eb55bb2a582fdd3e (patch) | |
| tree | 4c02f13ca30e673417870114050f7a3d653ad47d | |
| parent | 55475178a8c0e610103e37027cc0a7a387d72f91 (diff) | |
Implement key data model
- Added classes for Person, Gender, Family, FamilyTree
- Replaced FamilyTreeManager with FamilyTree
- Add FamilyFactory for seeding the initial FamilyTree for King Arthur and Queen Margaret
- Added a RelationshipManager for linking spouses correctly
- Refactored ActionFileExecutor for readability
- More test coverage
| -rw-r--r-- | data/actions.txt | 38 | ||||
| -rw-r--r-- | lib/action_file_executor.rb | 52 | ||||
| -rw-r--r-- | lib/family.rb | 43 | ||||
| -rw-r--r-- | lib/family_factory.rb | 155 | ||||
| -rw-r--r-- | lib/family_tree.rb | 68 | ||||
| -rw-r--r-- | lib/family_tree_manager.rb | 21 | ||||
| -rw-r--r-- | lib/gender.rb | 16 | ||||
| -rw-r--r-- | lib/person.rb | 57 | ||||
| -rw-r--r-- | lib/relationship_manager.rb | 21 | ||||
| -rw-r--r-- | spec/action_file_executor_spec.rb | 94 | ||||
| -rw-r--r-- | spec/family_spec.rb | 71 | ||||
| -rw-r--r-- | spec/family_tree_manager_spec.rb | 35 | ||||
| -rw-r--r-- | spec/family_tree_spec.rb | 34 |
13 files changed, 573 insertions, 132 deletions
diff --git a/data/actions.txt b/data/actions.txt index f7e1ff0..8988068 100644 --- a/data/actions.txt +++ b/data/actions.txt @@ -1,3 +1,35 @@ -ADD_CHILD Flora Minerva Female -GET_RELATIONSHIP Remus Maternal-Aunt -GET_RELATIONSHIP Minerva Siblings
\ No newline at end of file +GET_RELATIONSHIP "Queen Margaret" "Mother" +GET_RELATIONSHIP "King Arthur" "Mother" +GET_RELATIONSHIP "Bill" "Mother" +GET_RELATIONSHIP "Charlie" "Mother" +GET_RELATIONSHIP "Percy" "Mother" +GET_RELATIONSHIP "Ronald" "Mother" +GET_RELATIONSHIP "Ginerva" "Mother" +GET_RELATIONSHIP "Flora" "Mother" +GET_RELATIONSHIP "Victoire" "Mother" +GET_RELATIONSHIP "Dominique" "Mother" +GET_RELATIONSHIP "Louis" "Mother" +GET_RELATIONSHIP "Ted" "Mother" +GET_RELATIONSHIP "Remus" "Mother" +GET_RELATIONSHIP "Audrey" "Mother" +GET_RELATIONSHIP "Molly" "Mother" +GET_RELATIONSHIP "Lucy" "Mother" +GET_RELATIONSHIP "Helen" "Mother" +GET_RELATIONSHIP "Rose" "Mother" +GET_RELATIONSHIP "Hugo" "Mother" +GET_RELATIONSHIP "Malfoy" "Mother" +GET_RELATIONSHIP "Draco" "Mother" +GET_RELATIONSHIP "Aster" "Mother" +GET_RELATIONSHIP "Harry" "Mother" +GET_RELATIONSHIP "James" "Mother" +GET_RELATIONSHIP "Albus" "Mother" +GET_RELATIONSHIP "Lily" "Mother" +GET_RELATIONSHIP "Darcy" "Mother" +GET_RELATIONSHIP "William" "Mother" +GET_RELATIONSHIP "Alice" "Mother" +GET_RELATIONSHIP "Ron" "Mother" +GET_RELATIONSHIP "Ginny" "Mother" + +GET_RELATIONSHIP "Molly" "Father" + +GET_RELATIONSHIP "Bill" "Siblings"
\ No newline at end of file diff --git a/lib/action_file_executor.rb b/lib/action_file_executor.rb index 1cd3a94..49cb4b5 100644 --- a/lib/action_file_executor.rb +++ b/lib/action_file_executor.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative 'family_tree_manager' +require_relative 'family_tree' class ActionFileExecutor def initialize(file_path) @@ -11,15 +11,7 @@ class ActionFileExecutor def execute_actions File.open(@file_path, 'r') do |file| file.each_line do |line| - action, *params = line.split(' ') - case action - when 'ADD_CHILD' - FamilyTreeManager.instance.add_child(*params) - when 'GET_RELATIONSHIP' - FamilyTreeManager.instance.query_hierarchy(*params) - else - puts "Ignoring unsupported action: [#{action}]" - end + process_line(line.strip) end end end @@ -32,4 +24,44 @@ class ActionFileExecutor puts "Error: The file '#{@file_path}' does not exist." exit 1 end + + def process_line(line) + return if line.empty? || comment?(line) + + action, params = extract_action_and_params(line) + execute_action(action, params) if action + end + + def comment?(line) + line.start_with?('#') + end + + def extract_action_and_params(line) + match = line.match(/^(\S+)(.*)$/) + return unless match + + action = match[1] + params = match[2].scan(/"([^"]+)"|(\S+)/).flatten.compact + [action, params] + end + + def execute_action(action, params) + case action + when 'ADD_CHILD' + handle_add_child(*params) + when 'GET_RELATIONSHIP' + handle_get_relationship(*params) + else + puts "Ignoring unsupported action: [#{action}]" + end + end + + def handle_add_child(*params) + FamilyTree.instance.add_child(*params) + end + + def handle_get_relationship(*params) + result = FamilyTree.instance.get_relationship(*params) + puts result.empty? ? 'NONE' : result.map(&:name).join(', ') + end end diff --git a/lib/family.rb b/lib/family.rb new file mode 100644 index 0000000..2c1acca --- /dev/null +++ b/lib/family.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require_relative 'person' + +class Family + attr_reader :mother, :father, :children + + def initialize(mother = NilPerson.new, father = NilPerson.new, children = []) + raise ArgumentError, 'Mother must be female' if !mother.is_a?(NilPerson) && mother.gender != Gender::FEMALE + raise ArgumentError, 'Father must be male' if !father.is_a?(NilPerson) && father.gender != Gender::MALE + + @mother = mother + @father = father + @children = children + end + + def assign_mother(mother) + raise ArgumentError, 'Mother must be female' if mother.gender != Gender::FEMALE + + @mother = mother + end + + def assign_father(father) + raise ArgumentError, 'Father must be male' if father.gender != Gender::MALE + + @father = father + end + + def add_child(child) + @children << child unless @children.include?(child) + end + + def get_siblings(person) + @children.reject { |child| child == person } + end + + def to_s + mother_str = mother.is_a?(NilPerson) ? 'UNKNOWN' : mother.name + father_str = father.is_a?(NilPerson) ? 'UNKNOWN' : father.name + children_str = children.empty? ? 'NONE' : children.map(&:name).join(', ') + "Family: Mother: #{mother_str}, Father: #{father_str}, Children: #{children_str}" + end +end diff --git a/lib/family_factory.rb b/lib/family_factory.rb new file mode 100644 index 0000000..a42c5ea --- /dev/null +++ b/lib/family_factory.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require_relative 'family' +require_relative 'person' +require_relative 'gender' +require_relative 'relationship_manager' + +class FamilyFactory + def initialize + @people = {} + @relationship_manager = RelationshipManager.instance + end + + def create_families + [ + create_queen_margaret_and_king_arthur_family, + create_flora_and_bill_family, + create_victoire_and_ted_family, + create_percy_and_audrey_family, + create_ronald_and_helen_family, + create_malfoy_and_rose_family, + create_ginerva_and_harry_family, + create_darcy_and_james_family, + create_alice_and_albus_family + ] + end + + private + + def find_or_create_person(name, gender) + return @people[name] if @people.key?(name) + + person = Person.new(name, gender) + @people[name] = person + end + + def find_or_create_male(name) + find_or_create_person(name, Gender::MALE) + end + + def find_or_create_female(name) + find_or_create_person(name, Gender::FEMALE) + end + + def create_queen_margaret_and_king_arthur_family + queen_margaret = find_or_create_female('Queen Margaret') + king_arthur = find_or_create_male('King Arthur') + + @relationship_manager.link_spouses(queen_margaret, king_arthur) + + bill = find_or_create_male('Bill') + charlie = find_or_create_male('Charlie') + percy = find_or_create_male('Percy') + ronald = find_or_create_male('Ronald') + ginerva = find_or_create_female('Ginerva') + + Family.new(queen_margaret, king_arthur, [bill, charlie, percy, ronald, ginerva]) + end + + def create_flora_and_bill_family + bill = find_or_create_male('Bill') + flora = find_or_create_female('Flora') + + @relationship_manager.link_spouses(flora, bill) + + victoire = find_or_create_female('Victoire') + dominique = find_or_create_female('Dominique') + louis = find_or_create_male('Louis') + + Family.new(flora, bill, [victoire, dominique, louis]) + end + + def create_victoire_and_ted_family + victoire = find_or_create_female('Victoire') + ted = find_or_create_male('Ted') + + @relationship_manager.link_spouses(victoire, ted) + + remus = find_or_create_male('Remus') + + Family.new(victoire, ted, [remus]) + end + + def create_percy_and_audrey_family + percy = find_or_create_male('Percy') + audrey = find_or_create_female('Audrey') + + @relationship_manager.link_spouses(audrey, percy) + + molly = find_or_create_female('Molly') + lucy = find_or_create_female('Lucy') + + Family.new(audrey, percy, [molly, lucy]) + end + + def create_ronald_and_helen_family + ronald = find_or_create_male('Ronald') + helen = find_or_create_female('Helen') + + @relationship_manager.link_spouses(helen, ronald) + + rose = find_or_create_female('Rose') + hugo = find_or_create_male('Hugo') + + Family.new(helen, ronald, [rose, hugo]) + end + + def create_malfoy_and_rose_family + malfoy = find_or_create_male('Malfoy') + rose = find_or_create_female('Rose') + + @relationship_manager.link_spouses(rose, malfoy) + + draco = find_or_create_male('Draco') + aster = find_or_create_female('Aster') + + Family.new(rose, malfoy, [draco, aster]) + end + + def create_ginerva_and_harry_family + ginerva = find_or_create_female('Ginerva') + harry = find_or_create_male('Harry') + + @relationship_manager.link_spouses(ginerva, harry) + + james = find_or_create_male('James') + albus = find_or_create_male('Albus') + lily = find_or_create_female('Lily') + + Family.new(ginerva, harry, [james, albus, lily]) + end + + def create_darcy_and_james_family + darcy = find_or_create_female('Darcy') + james = find_or_create_male('James') + + @relationship_manager.link_spouses(darcy, james) + + william = find_or_create_male('William') + + Family.new(darcy, james, [william]) + end + + def create_alice_and_albus_family + alice = find_or_create_female('Alice') + albus = find_or_create_male('Albus') + + @relationship_manager.link_spouses(alice, albus) + + ron = find_or_create_male('Ron') + ginny = find_or_create_female('Ginny') + + Family.new(alice, albus, [ron, ginny]) + end +end diff --git a/lib/family_tree.rb b/lib/family_tree.rb index 934d32e..ebb2955 100644 --- a/lib/family_tree.rb +++ b/lib/family_tree.rb @@ -1,15 +1,79 @@ # frozen_string_literal: true +require 'singleton' + +require_relative 'person' +require_relative 'family_factory' + class FamilyTree + include Singleton + + attr_accessor :families, :people + def initialize + @families = FamilyFactory.new.create_families @people = [] end + def add_family(family) + @families << family unless @families.include?(family) + end + def add_child(*params) puts "Adding Child with params: #{params.join(', ')}" end - def query_hierarchy(*params) - puts "Querying Hierarcy with params: #{params.join(', ')}" + 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 + end + + [] + end + + def find_family(name) + families.each do |family| + family.children.each do |child| + return family if child.name.casecmp(name).zero? + end + end + nil + end + + def find_mother(family) + mother = family.mother + mother || NilPerson.new + end + + def find_father(family) + father = family.father + father || NilPerson.new + end + + def find_siblings(family, name) + family.children.reject { |child| child.name.casecmp(name).zero? } + end + + def child_of_family?(family, name) + return false unless family.is_a?(Family) + + family.children.any? do |child| + child.name.casecmp(name).zero? + end end end diff --git a/lib/family_tree_manager.rb b/lib/family_tree_manager.rb deleted file mode 100644 index 56ab992..0000000 --- a/lib/family_tree_manager.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'singleton' - -require_relative 'family_tree' - -class FamilyTreeManager - include Singleton - - def initialize - @family_tree = FamilyTree.new - end - - def add_child(*params) - @family_tree.add_child(*params) - end - - def query_hierarchy(*params) - @family_tree.query_hierarchy(*params) - end -end diff --git a/lib/gender.rb b/lib/gender.rb new file mode 100644 index 0000000..9bd3b06 --- /dev/null +++ b/lib/gender.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class Gender + MALE = 'male' + FEMALE = 'female' + + def self.all + [MALE, FEMALE] + end + + def self.valid?(gender) + return false unless gender.is_a?(String) + + all.include?(gender.downcase) + end +end diff --git a/lib/person.rb b/lib/person.rb new file mode 100644 index 0000000..a40efbe --- /dev/null +++ b/lib/person.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +class Person + attr_accessor :name, :gender, :spouse + + def initialize(name, gender, spouse = NilPerson.new) + @name = name + @gender = gender + @spouse = spouse + end + + def ==(other) + other.is_a?(Person) && name == other.name && gender == other.gender && spouse == other.spouse + end + + def eql?(other) + self == other + end + + def hash + [name, gender, spouse].hash + end + + def to_s + "#{name} (#{gender})" + end +end + +class NilPerson + def name + nil + end + + def father + self + end + + def mother + self + end + + def gender + nil + end + + def ==(other) + other.is_a?(NilPerson) + end + + def eql?(other) + self == other + end + + def to_s + '' + end +end diff --git a/lib/relationship_manager.rb b/lib/relationship_manager.rb new file mode 100644 index 0000000..4b6a4a2 --- /dev/null +++ b/lib/relationship_manager.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +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 + raise "Cannot link #{person1.name} and #{person2.name}: #{person1.name} is already linked to #{person1.spouse.name}." + end + + if person2.spouse != NilPerson.new && person2.spouse != person1 + raise "Cannot link #{person1.name} and #{person2.name}: #{person2.name} is already linked to #{person2.spouse.name}." + end + + # Link the spouses + person1.spouse = person2 + person2.spouse = person1 unless person2.is_a?(NilPerson) + end +end diff --git a/spec/action_file_executor_spec.rb b/spec/action_file_executor_spec.rb index cab34b3..ce2fa11 100644 --- a/spec/action_file_executor_spec.rb +++ b/spec/action_file_executor_spec.rb @@ -2,17 +2,16 @@ require 'tempfile' require_relative '../lib/action_file_executor' -require_relative '../lib/family_tree_manager' RSpec.describe ActionFileExecutor do let(:invalid_file_path) { 'non_existent_file.txt' } - let(:family_tree_manager) { instance_double('FamilyTreeManager') } + let(:family_tree) { instance_double('FamilyTree') } let(:tempfile) { Tempfile.new('actions.txt') } before do - allow(FamilyTreeManager).to receive(:instance).and_return(family_tree_manager) - allow(family_tree_manager).to receive(:add_child) - allow(family_tree_manager).to receive(:query_hierarchy) + allow(FamilyTree).to receive(:instance).and_return(family_tree) + allow(family_tree).to receive(:add_child) + allow(family_tree).to receive(:get_relationship).and_return([]) end after do @@ -21,6 +20,13 @@ RSpec.describe ActionFileExecutor do end describe '#initialize' do + context 'when the file exists' do + it 'initializes successfully' do + action_file_executor = ActionFileExecutor.new(tempfile.path) + expect(action_file_executor).to be_an_instance_of(ActionFileExecutor) + end + end + context 'when the file does not exist' do it 'prints an error message and exits' do expect do @@ -28,49 +34,83 @@ RSpec.describe ActionFileExecutor do end.to output("Error: The file 'non_existent_file.txt' does not exist.\n").to_stdout.and raise_error(SystemExit) end end + end - context 'when the file exists' do - it 'initializes successfully' do - tempfile.puts('ADD_CHILD Mother Child Male') + describe '#execute_actions' do + context 'with a valid file' do + before do + tempfile.write("ADD_CHILD \"Mother's Name\" \"Child's Name\"\n") + tempfile.write("# A comment\n") + tempfile.write("\n") + tempfile.write("INVALID ACTION\n") + tempfile.write("GET_RELATIONSHIP \"Mother's Name\" \"Child's Name\"\n") tempfile.rewind + end + it 'processes all lines in the file' do action_file_executor = ActionFileExecutor.new(tempfile.path) - expect(action_file_executor).to be_an_instance_of(ActionFileExecutor) + allow(action_file_executor).to receive(:process_line) + + action_file_executor.execute_actions + expect(action_file_executor).to have_received(:process_line).exactly(5).times + end + + it 'executes actions for non-empty and non-comment lines' do + action_file_executor = ActionFileExecutor.new(tempfile.path) + allow(action_file_executor).to receive(:execute_action) + + action_file_executor.execute_actions + expect(action_file_executor).to have_received(:execute_action).exactly(3).times end end end - describe '#execute_actions' do - context 'with valid actions' do - before do - tempfile.puts('ADD_CHILD Mother Child Male') - tempfile.puts('GET_RELATIONSHIP Child Maternal-Uncle') - tempfile.rewind + describe '#process_line' do + context 'with a comment line' do + it 'does not execute the action' do + action_file_executor = ActionFileExecutor.new(tempfile.path) + expect(action_file_executor.send(:process_line, '# This is a comment')).to be_nil end + end - it 'calls the add_child method on FamilyTreeManager when it encounters the ADD_CHILD action' do + context 'with an empty line' do + it 'does not execute the action' do action_file_executor = ActionFileExecutor.new(tempfile.path) - action_file_executor.execute_actions - expect(family_tree_manager).to have_received(:add_child).with('Mother', 'Child', 'Male') + expect(action_file_executor.send(:process_line, '')).to be_nil end + end + end - it 'calls the query_hierarchy method on FamilyTreeManager when it encounters the GET_RELATIONSHIP action' do + describe '#extract_action_and_params' do + it 'returns the action and params from the line' do + action_file_executor = ActionFileExecutor.new(tempfile.path) + expect(action_file_executor.send(:extract_action_and_params, + 'ADD_CHILD "Mother\'s Name" "Child\'s Name"')).to eq(['ADD_CHILD', + ["Mother's Name", + "Child's Name"]]) + end + end + + describe '#execute_action' do + context 'with the ADD_CHILD action' do + it 'calls the add_child method on FamilyTree' do action_file_executor = ActionFileExecutor.new(tempfile.path) - action_file_executor.execute_actions - expect(family_tree_manager).to have_received(:query_hierarchy).with('Child', 'Maternal-Uncle') + action_file_executor.send(:execute_action, 'ADD_CHILD', ["Mother's Name", "Child's Name"]) end end - context 'with unsupported actions' do - before do - tempfile.puts('ADD_MOTHER Child Mother') - tempfile.rewind + context 'with the GET_RELATIONSHIP action' do + it 'calls the get_relationship method on FamilyTree' do + action_file_executor = ActionFileExecutor.new(tempfile.path) + action_file_executor.send(:execute_action, 'GET_RELATIONSHIP', ["Child's Name", 'Maternal-Uncle']) end + end - it 'prints an error message when it encounters an unsupported action' do + context 'with an unsupported action' do + it 'prints an error message' do expect do action_file_executor = ActionFileExecutor.new(tempfile.path) - action_file_executor.execute_actions + action_file_executor.send(:execute_action, 'ADD_MOTHER', ["Child's Name", "Mother's Name"]) end.to output("Ignoring unsupported action: [ADD_MOTHER]\n").to_stdout end end diff --git a/spec/family_spec.rb b/spec/family_spec.rb new file mode 100644 index 0000000..7247648 --- /dev/null +++ b/spec/family_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require_relative '../lib/family' +require_relative '../lib/person' +require_relative '../lib/gender' + +RSpec.describe Family do + describe '#initialize' do + it 'creates a new family with a mother, father, and children' do + family = Family.new + expect(family.mother).to be_a(NilPerson) + expect(family.father).to be_a(NilPerson) + expect(family.children).to eq([]) + end + + it 'raises an error if the mother is not a female' do + jack = Person.new('Jack', Gender::MALE) + + expect { Family.new(jack) }.to raise_error(ArgumentError).with_message('Mother must be female') + end + + it 'raises an error if the father is not a male' do + jill = Person.new('Jill', Gender::FEMALE) + + expect { Family.new(NilPerson.new, jill) }.to raise_error(ArgumentError).with_message('Father must be male') + end + end + + describe 'assign_mother' do + it 'raises an error if the mother is not a female' do + family = Family.new + jack = Person.new('Jack', Gender::MALE) + + expect { family.assign_mother(jack) }.to raise_error(ArgumentError).with_message('Mother must be female') + end + end + + describe 'assign_father' do + it 'raises an error if the mother is not a female' do + family = Family.new + jill = Person.new('Jill', Gender::FEMALE) + + expect { family.assign_father(jill) }.to raise_error(ArgumentError).with_message('Father must be male') + end + end + + describe '#add_child' do + it 'adds a child to the family' do + family = Family.new + child = Person + + family.add_child(child) + expect(family.children).to eq([child]) + end + end + + describe '#get_siblings' do + it 'returns all siblings of a person' do + family = Family.new + child1 = Person.new('Jack', Gender::MALE) + child2 = Person.new('Jill', Gender::FEMALE) + child3 = Person.new('Phil', Gender::MALE) + + family.add_child(child1) + family.add_child(child2) + family.add_child(child3) + + expect(family.get_siblings(child1)).to eq([child2, child3]) + end + end +end diff --git a/spec/family_tree_manager_spec.rb b/spec/family_tree_manager_spec.rb deleted file mode 100644 index a1161ae..0000000 --- a/spec/family_tree_manager_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require_relative '../lib/family_tree_manager' - -RSpec.describe FamilyTreeManager do - let(:family_tree_manager) { FamilyTreeManager.instance } - let(:family_tree) { instance_double(FamilyTree) } - - before do - family_tree_manager.instance_variable_set(:@family_tree, family_tree) - end - - describe '#initialize' do - it 'creates a family tree' do - expect(family_tree_manager.instance_variable_get(:@family_tree)).to eq(family_tree) - end - end - - describe '#add_child' do - it 'is defined' do - expect(family_tree_manager).to respond_to(:add_child) - end - - it 'calls add_child on the family tree' do - expect(family_tree).to receive(:add_child).with('Child', 'Mother', 'Father') - family_tree_manager.add_child('Child', 'Mother', 'Father') - end - end - - describe '#query_hierarchy' do - it 'is defined' do - expect(family_tree_manager).to respond_to(:query_hierarchy) - end - end -end diff --git a/spec/family_tree_spec.rb b/spec/family_tree_spec.rb index 2059a89..ba05aa3 100644 --- a/spec/family_tree_spec.rb +++ b/spec/family_tree_spec.rb @@ -3,38 +3,4 @@ require_relative '../lib/family_tree' RSpec.describe FamilyTree do - describe '#initialize' do - it 'creates an empty array' do - family_tree = FamilyTree.new - expect(family_tree.instance_variable_get(:@people)).to eq([]) - end - end - - describe '#add_child' do - it 'is defined' do - family_tree = FamilyTree.new - expect(family_tree).to respond_to(:add_child) - end - - it 'prints the params' do - family_tree = FamilyTree.new - expect do - family_tree.add_child('Child', 'Mother', 'Father') - end.to output("Adding Child with params: Child, Mother, Father\n").to_stdout - end - end - - describe '#query_hierarchy' do - it 'is defined' do - family_tree = FamilyTree.new - expect(family_tree).to respond_to(:query_hierarchy) - end - - it 'prints the params' do - family_tree = FamilyTree.new - expect do - family_tree.query_hierarchy('Child') - end.to output("Querying Hierarcy with params: Child\n").to_stdout - end - end end |
