package edu.fiu.jtlex.data;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import edu.fiu.jtlex.data.IEvent.EventClass;

/**
 * A class that contains tests for the Event class 
 * @author arada002
 *
 */
class EventTest {
	
	
	@Nested
	@DisplayName("Testing Constructor")
	class TestConstructor{
		
		
		@Nested
		@DisplayName("if eventClass is")
		class TestEventClass{
			/**
			 * Test case ID: testClass()
			 * Purpose: Test event constructor implementation
			 * Test set up: 
			 * Test input: new Event (1, null, "word")
			 * Expected output: NullPointerException
			 */
			@Test
			@DisplayName("null")
			void testClass() {
				assertThrows(NullPointerException.class, ()-> new Event (1, null, "word"));
			}
		}
		@Nested
		@DisplayName("if eID is")
		class TestEID{
			/**
			 * Test case ID: testId()
			 * Purpose: Test event constructor implementation
			 * Test set up: 
			 * Test input: new Event (0, EventClass.ASPECTUAL, "word")
			 * Expected output: IllegalArgumentException
			 */
			@Test
			@DisplayName("0")
			void testId() {
				assertThrows(IllegalArgumentException.class, ()-> new Event (0, EventClass.ASPECTUAL, "word"));
			}
			/**
			 * Test case ID: testIdNegative()
			 * Purpose: Test event constructor implementation
			 * Test set up: 
			 * Test input: new Event (-1, EventClass.ASPECTUAL, "word")
			 * Expected output: IllegalArgumentException
			 */
			@Test
			@DisplayName("negative integer")
			void testIdNegative() {
				assertThrows(IllegalArgumentException.class, ()-> new Event (-1, EventClass.ASPECTUAL, "word"));
			}
		}
		
		
		@Nested
		@DisplayName("if stem is")
		class TestStem{
			/**
			 * Test case ID: testStem()
			 * Purpose: Test event constructor implementation
			 * Test set up: 
			 * Test input:  new Event (1, EventClass.ASPECTUAL, "    ")
			 * Expected output: IllegalArgumentException
			 */
			@Test
			@DisplayName("all whitespace")
			void testStem() {
				assertThrows(IllegalArgumentException.class, ()-> new Event (1, EventClass.ASPECTUAL, "    "));
			}
			/**
			 * Test case ID: testStemEmpty()
			 * Purpose: Test event constructor implementation when stem is empty string
			 * Test set up: 
			 * Test input:  new Event (1, EventClass.ASPECTUAL, "")
			 * Expected output: IllegalArgumentException
			 */
			@Test
			@DisplayName("an empty string")
			void testStemEmpty() {
				assertThrows(IllegalArgumentException.class, ()-> new Event (1, EventClass.ASPECTUAL, ""));
			}
		}
		
	}
	
	@Nested
	@DisplayName("Testing getters")
	class TestGetters{
		
		@Nested
		@DisplayName("getStem method")
		class TestGetStem{
			/**
			 * Test case ID: testGetStem()
			 * Purpose: Test getStem() implementation if stem needs to be trimmed 
			 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, " word word ");
			 * Test input:  " word word "
			 * Expected output: " word word "
			 */
			@Test
			@DisplayName("if stem is trimmed")
			void testGetStem() {
				Event event = new Event (1, EventClass.ASPECTUAL, " word word ");
				assertEquals(event.getStem(), "word word");
			}
			/**
			 * Test case ID: testGetStemNull()
			 * Purpose: Test getStem() implementation if stem is NULL
			 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, null);
			 * Test input: null
			 * Expected output: null
			 */
			@Test
			@DisplayName("if stem is null")
			void testGetStemNull() {
				Event event = new Event (1, EventClass.ASPECTUAL, null);
				assertEquals(event.getStem(), null);
			}
		}
		/**
		 * Test case ID: testGetEventClass()
		 * Purpose: Test getEventClass() 
		 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, null);
		 * Test input: EventClass.ASPECTUAL
		 * Expected output: EventClass.ASPECTUAL
		 */
		@Test
		@DisplayName("getEventClass method")
		void testGetEventClass() {
			Event event = new Event (1, EventClass.ASPECTUAL, null);
			assertEquals(event.getEventClass(), EventClass.ASPECTUAL);
		}
		
		@Nested
		@DisplayName("getEventId methods")
		class TestGetId{
			/**
			 * Test case ID: testGetId()
			 * Purpose: Test getId() 
			 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, null);
			 * Test input: 1
			 * Expected output: 1 (integer)
			 */
			@Test
			@DisplayName("returning int")
			void testGetEventId() {
				Event event = new Event (1, EventClass.ASPECTUAL, null);
				assertEquals(event.getId(), 1);
				}
			/**
			 * Test case ID: testGetIdStr()
			 * Purpose: Test getIdStr() 
			 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, null);
			 * Test input: 1
			 * Expected output: "e1"
			 */
			@Test
			@DisplayName("returning string")
			void testGetEventIdStr() {
				Event event = new Event (1, EventClass.ASPECTUAL, null);
				assertEquals(event.getIdStr(), "e1");
				}
		
		}
	}
	/**
	 * Test case ID: testGetId()
	 * Purpose: Test getId() 
	 * Test set up: Event event = new Event (1, EventClass.ASPECTUAL, null);
	 * Test input: event
	 * Expected output: "EVENT eid = e1 class = ASPECTUAL stem = null"
	 */
	@Test
	@DisplayName("Testing toString method")
	void testToString() {
		Event event = new Event (1, EventClass.ASPECTUAL, null);
		assertEquals(event.toString(), "EVENT eid = e1 class = ASPECTUAL stem = null");
	}
	
}
