package org.codefx.demo.junit5.basics;

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

import java.util.EmptyStackException;
import java.util.Stack;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.expectThrows;

/**
 * Demonstration of JUnit 5 features (particularly nesting and naming)
 * that was taken from the <a href="http://junit-team.github.io/junit5/#nested-tests">JUnit 5 User Guide</a>. 
 */
@DisplayName("A stack")
class StackTest {

	Stack<Object> stack;

	@Test
	@DisplayName("is instantiated with new Stack()")
	void isInstantiatedWithNew() {
		new Stack<Object>();
	}

	@Nested
	@DisplayName("when new")
	class WhenNew {

		@BeforeEach
		void init() {
			stack = new Stack<Object>();
		}

		@Test
		@DisplayName("is empty")
		void isEmpty() {
			assertTrue(stack.isEmpty());
		}

		@Test
		@DisplayName("throws EmptyStackException when popped")
		void throwsExceptionWhenPopped() {
			expectThrows(EmptyStackException.class, () -> stack.pop());
		}

		@Test
		@DisplayName("throws EmptyStackException when peeked")
		void throwsExceptionWhenPeeked() {
			expectThrows(EmptyStackException.class, () -> stack.peek());
		}

		@Nested
		@DisplayName("after pushing an element")
		class AfterPushing {

			String anElement = "an element";

			@BeforeEach
			void init() {
				stack.push(anElement);
			}

			@Test
			@DisplayName("it is no longer empty")
			void isEmpty() {
				assertFalse(stack.isEmpty());
			}

			@Test
			@DisplayName("returns the element when popped and is empty")
			void returnElementWhenPopped() {
				assertEquals(anElement, stack.pop());
				assertTrue(stack.isEmpty());
			}

			@Test
			@DisplayName("returns the element when peeked but remains not empty")
			void returnElementWhenPeeked() {
				assertEquals(anElement, stack.peek());
				assertFalse(stack.isEmpty());
			}
		}
	}
}

@@ -427,19 +427,21 @@
 .assertT
-rue
+hrows
 ;%0Aimport
@@ -481,28 +481,26 @@
 ertions.
-expectThrows
+assertTrue
 ;%0A%0A/**%0A 
@@ -568,19 +568,16 @@
  naming)
-%0A *
  that wa
@@ -592,16 +592,19 @@
 from the
+%0A *
  %3Ca href
@@ -621,44 +621,66 @@
 unit
--team.github.io/junit5/#nested-tests
+.org/junit5/docs/5.0.0-M3/user-guide/#writing-tests-nested
 %22%3EJU
@@ -700,17 +700,16 @@
 ide%3C/a%3E.
- 
 %0A */%0A@Di
@@ -868,30 +868,24 @@
 %09%09new Stack%3C
-Object
 %3E();%0A%09%7D%0A%0A%09@N
@@ -951,28 +951,38 @@
 Each%0A%09%09void 
-init
+createNewStack
 () %7B%0A%09%09%09stac
@@ -995,22 +995,16 @@
 w Stack%3C
-Object
 %3E();%0A%09%09%7D
@@ -1193,37 +1193,37 @@
 enPopped() %7B%0A%09%09%09
-expec
+asser
 tThrows(EmptySta
@@ -1375,13 +1375,13 @@
 %0A%09%09%09
-expec
+asser
 tThr
@@ -1578,11 +1578,20 @@
 oid 
-ini
+pushAnElemen
 t() 
@@ -1677,32 +1677,35 @@
 pty%22)%0A%09%09%09void is
+Not
 Empty() %7B%0A%09%09%09%09as
@@ -2135,10 +2135,11 @@
 %0A%09%09%7D%0A%09%7D%0A
+%0A
 %7D%0A

Update stack test to M3