import sys
import os

import unittest

sys.path.append(os.path.abspath('../'))
from menu import Node

class NodeTests(unittest.TestCase):

	def setUp(self):
		"""Before each test case"""
		
	def tearDown(self):
		"""After each test case"""
		
		
	def test_Path(self):
		"""Node.Path() should return all of the Node's ancestors' shortcuts 
		(except the root Node) concatenated.
		
		"""
		
		root = Node()
		
		child = Node()
		child.shortcut = 'child'
		child.parent = root
		root.children.append(child)
		
		descendant = Node()
		descendant.shortcut = 'descendant'
		descendant.parent = child
		child.children.append(descendant)
		
		
		self.assertEquals(root.Path(), '', '[root].Path() should return "".')
		
		self.assertEquals(child.Path(), 'child', 
			'[child].Path() should return "child".')
			
		self.assertEquals(descendant.Path(), 'childdescendant',
			'[descendant].Path() should return "childdescendant".')
		
		
	def test_Resolve(self):
		""" Node.Resolve(path) should take a path and return the sub-Node it
		references.
		
		"""
		
		root = Node()
		child = Node()
		descendant = Node()
		noise = Node() # An extra node to make sure selection is working.
		
		child.shortcut = 'ch'
		root.children.append(child)
		child.parent = root
		
		noise.shortcut = 'ch not used' # Make sure it doesn't match this,
		root.children.append(noise)
		noise.parent = root
		
		descendant.shortcut = 'desc'
		child.children.append(descendant)
		descendant.parent = child
		
		
		# Should get an error if looking for a sub-Node that doesn't exist
		self.assertRaises(LookupError, root.Resolve, 'not valid')
		
		# Return a child of root (no recursion)
		self.assertEquals(root.Resolve('ch'), child, 
			'Not finding a child Node.')
		
		# Return a descendant of root (recursion)
		self.assertEquals(root.Resolve('chdesc'), descendant,
			'Not finding a descendant Node.')
	
	
	def test_Match(self):
		"""Node.Match(path) should return all possible matches to path within
		[path].children or [path].parent.children.
		
		"""
	
		root = Node()

		child = Node()
		child.shortcut = 'ch1'
		child.parent = root
		root.children.append(child)
		
		descendant = Node()
		descendant.shortcut = 'd1'
		descendant.parent = child
		child.children.append(descendant)
		
		descendant2 = Node()
		descendant2.shortcut = 'd2'
		descendant2.parent = child
		child.children.append(descendant2)
		
		child2 = Node()
		child2.shortcut = 'other'
		child2.parent = root
		root.children.append(child2)
		
		
		# An empty string should return all immediate children of [root].
		target = root.Match('')
		self.assertEquals(len(target), 2, 'Expected 2 results.')
		self.assertEquals(target[0], child, 'Expected [child].')
		self.assertEquals(target[1], child2, 'Expected [child2].')
		
		# "ch" should return only "ch1".
		target = root.Match('ch')
		self.assertEquals(len(target), 1, 'Expected 1 result.')
		self.assertEquals(target[0], child, 'Expected [child].')
		
		# "ch1" should return all immediate children of [child].
		target = root.Match('ch1')
		self.assertEquals(len(target), 2, 'Expected 2 results.')
		self.assertEquals(target[0], descendant, 'Expected [descendant].')
		self.assertEquals(target[1], descendant2, 'Expected [descendant2].')
		
		# "ch1d" should return both immediate children of [child].
		target = root.Match('ch1d')
		self.assertEquals(len(target), 2, 'Expected 2 results.')
		self.assertEquals(target[0], descendant, 'Expected [descendant].')
		self.assertEquals(target[1], descendant2, 'Expected [descendant2].')

		# "ch1d2" should return [descendant2].
		target = root.Match('ch1d2')
		self.assertEquals(len(target), 1, 'Expected 1 result.')
		self.assertEquals(target[0], descendant2, 'Expected [descendant2].')

		# "ch1d3" should return [].
		target = root.Match('ch1d3')
		self.assertEquals(len(target), 0)