package monads;

import static org.junit.Assert.assertEquals;
import static monads.Stack.*;
import static monads.Pair.*;

import org.junit.Test;

public class StackTest {
	
	private static final Object A = new Object();
	private static final Object B = new Object();

	private Pair pair = pair(empty());

	@Test public void
	starts_empty() {
		assertEquals(empty(), pair.stack);
	}
	
	@Test(expected = Exception.class) public void
	forbids_pop_when_empty() {
		pop(pair.stack);
	}
	
	private static interface StackFunction {
		Pair eval(Stack stack);
	}
	@Test public void
	pushes_and_pops_an_objects() {	
		pair = new StackFunction() {
			public Pair eval(Stack stack) {
				return stack.push(stack, A);
			}
		}.eval(pair.stack);
		
		pair = pop(pair.stack);
		assertEquals(A, pair.value);
		assertEquals(empty(), pair.stack);
	}
	
	@Test public void
	pops_objects_in_reverse_push_order() {
		pair = push(pair.stack, A);
		pair = push(pair.stack, B);
		
		pair = pop(pair.stack);
		assertEquals(B, pair.value);

		pair = pop(pair.stack);
		assertEquals(A, pair.value);

		assertEquals(empty(), pair.stack);
	}
}

@@ -552,71 +552,266 @@
 %09%7D%0A%09
-@Test public void%0A%09pushes_and_pops_an_objects() %7B%09%0A%09%09pair = new
+private static class StackPush implements StackFunction %7B%0A%09%09private Object value;%0A%0A%09%09public StackPush(Object value) %7B%0A%09%09%09this.value = value;%0A%09%09%7D%0A%0A%09%09public Pair eval(Stack stack) %7B%0A%09%09%09return push(stack, value);%0A%09%09%7D%0A%09%7D%0A%09private static class StackPop implements
  Sta
@@ -820,22 +820,19 @@
 Function
-()
  %7B%0A
-%09
 %09%09public
@@ -864,46 +864,113 @@
 %0A%09%09%09
-%09
 return 
-stack.push
+pop
 (stack
-, A
 );%0A%09%09
+%7D%0A
 %09%7D%0A%09
-%09%7D
+%0A%09@Test public void%0A%09pushes_and_pops_an_objects() %7B%09%0A%09%09pair = new StackPush(A)
 .eva
@@ -984,19 +984,16 @@
 stack);%0A
-%09%09%0A
 %09%09pair =
@@ -985,35 +985,51 @@
 tack);%0A%09%09pair = 
-pop
+new StackPop().eval
 (pair.stack);%0A%09%09
@@ -1018,32 +1018,33 @@
 al(pair.stack);%0A
+%0A
 %09%09assertEquals(A

Create real StackFunction classes for stack operations