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);
	}
	
	@Test public void
	pushes_and_pops_an_objects() {		
		pair = push(pair.stack, A);
		
		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);
	}
}

@@ -468,32 +468,103 @@
 ir.stack);%0A%09%7D%0A%09%0A
+%09private static interface StackFunction %7B%0A%09%09Pair eval(Stack stack);%0A%09%7D%0A
 %09@Test public vo
@@ -598,17 +598,16 @@
 cts() %7B%09
-%09
 %0A%09%09pair 
@@ -608,34 +608,130 @@
 %09pair = 
-push(pair.stack, A
+new StackFunction() %7B%0A%09%09%09public Pair eval(Stack stack) %7B%0A%09%09%09%09return stack.push(stack, A);%0A%09%09%09%7D%0A%09%09%7D.eval(pair.stack
 );%0A%09%09%0A%09%09

Isolate pops and pushes through function objects so that they can be manipulated