/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ge.edu.freeuni.sdp.snake.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 *
 * @author toka
 */
public class UniverseTest {
    
    private List<Being> _population;
    private Topology _topology;
    private Universe _universe;
    
    public UniverseTest() {
    }
    
    @BeforeClass
    public static void setUpClass() {
    }
    
    @AfterClass
    public static void tearDownClass() {
    }
    
    @Before
    public void setUp() {
        _topology = mock(Topology.class);
        _population = new ArrayList<>();
        _universe = new Universe(_topology, _population);
    }
    
    @After
    public void tearDown() {
    }

    @Test
    public void moveTest() {
        fillBeingList(2);
        _universe.move();
        
        for (Being _population1 : _population) {
            verify(_population1, times(1)).move(_topology);
        }

    }
    
    @Test
    public void interactTest(){
        fillBeingList(3);
        Point p = mock(Point.class);
        for (Being pop : _population) {
            when(pop.getHead()).thenReturn(p);
            when(pop.contains(p)).thenReturn(Boolean.TRUE);
        }
        
        _universe.interact();
        
        for (Being being1 : _population)
            for (Being being2 : _population)
                if(being1 != being2)
                    verify(being1, times(1)).interactWith(being2);
    }
    
    @Test
    public void interactUntouchedTest(){
        Being being1 = mock(Being.class);
        Being being2 = mock(Being.class);
        Point head = mock(Point.class);
        
        when(being1.getHead()).thenReturn(head);
        when(being2.getHead()).thenReturn(head);
        
        when(being1.contains(head)).thenReturn(Boolean.FALSE);
        when(being2.contains(head)).thenReturn(Boolean.FALSE);
        
        _population.add(being1);
        _population.add(being2);
        
        _universe.interact();
        
        verify(being1, times(0)).interactWith(being2);
        verify(being2, times(0)).interactWith(being1);
    }
    
    @Test
    public void selfInteractTest(){
        Being being = mock(Being.class);
        when(being.getHead()).thenReturn(mock(Point.class));
        _population.add(being);
        
        _universe.interact();
        
        verify(being, times(0)).interactWith(being);   
    }
    
//    @Test
//    public void removeZombieTest(){
//        Being being1 = mock(Being.class);
//        Being being2 = mock(Being.class);
//        
//        when(being1.isAlive()).thenReturn(Boolean.FALSE);
//        when(being2.isAlive()).thenReturn(Boolean.TRUE);
//        _population.add(being1);
//        _population.add(being2);
//        
//        _universe.removeZombies();
//        
//        assertEquals(_population.size(), 1);
//        
//        verify(being1).isAlive();
//        verify(being2).isAlive();
//        assertFalse(_population.contains(being1));
//        assertTrue(_population.contains(being2));
//        
//    }
    
    @Test
    public void getExistingBeingTest(){
        Point p = new Point(0, 0);
        Being being = mock(Being.class);
        when(being.contains(p)).thenReturn(Boolean.TRUE);
        
        _population.add(being);
        
        Being result = _universe.getBeingAt(p);
        
        assertEquals(being, result);
    }
    
    @Test
    public void getMissingBeingTest(){
        Point p = new Point(0, 0);
        fillBeingList(5);
        for(Being being : _population)
            when(being.contains(p)).thenReturn(Boolean.FALSE);
                
        Being result = _universe.getBeingAt(p);

        assertEquals(null, result);
        for(Being being : _population)
            verify(being).contains(p);
    }
    
    @Test
    public void addBeingTest(){        
        Being being = mock(Being.class);
        _universe.addBeing(being);
        
        assertTrue(_population.contains(being));
    }
    
    
    private void fillBeingList(int times){
        for(int i=0; i<times; i++)
            _population.add(mock(Being.class));
    }
}

@@ -2770,26 +2770,24 @@
 %0A    %7D%0A    %0A
-//
     @Test%0A//
@@ -2784,18 +2784,16 @@
   @Test%0A
-//
     publ
@@ -2820,18 +2820,16 @@
 Test()%7B%0A
-//
         
@@ -2835,36 +2835,35 @@
  Being being1 = 
-mock
+spy
 (Being.class);%0A/
@@ -2853,34 +2853,32 @@
 y(Being.class);%0A
-//
         Being be
@@ -2876,36 +2876,35 @@
  Being being2 = 
-mock
+spy
 (Being.class);%0A/
@@ -2902,26 +2902,24 @@
 class);%0A
-//
         
 %0A//     
@@ -2914,30 +2914,63 @@
     
-%0A//        when
+assertTrue(being1.isAlive());%0A        assertTrue
 (being
-1
+2
 .isA
@@ -2980,46 +2980,50 @@
 e())
-.thenReturn(Boolean.FALSE
+;%0A        %0A        being1.kill(
 );%0A
-//
         
 when
@@ -3018,27 +3018,34 @@
         
-when
+assertFalse
 (being
-2
+1
 .isAlive
@@ -3051,37 +3051,19 @@
 e())
-.thenReturn(Boolean.TRUE);%0A//
+;%0A        %0A
     
@@ -3087,26 +3087,24 @@
 dd(being1);%0A
-//
         _pop
@@ -3124,18 +3124,16 @@
 eing2);%0A
-//
         
@@ -3125,34 +3125,32 @@
 ing2);%0A        %0A
-//
         _univers
@@ -3164,26 +3164,24 @@
 eZombies();%0A
-//
         %0A// 
@@ -3169,34 +3169,32 @@
 ies();%0A        %0A
-//
         assertEq
@@ -3222,18 +3222,16 @@
 (), 1);%0A
-//
         
@@ -3235,82 +3235,8 @@
    %0A
-//        verify(being1).isAlive();%0A//        verify(being2).isAlive();%0A//
     
@@ -3278,26 +3278,24 @@
 s(being1));%0A
-//
         asse
@@ -3332,18 +3332,16 @@
 ing2));%0A
-//
         
@@ -3345,10 +3345,8 @@
    %0A
-//
     

test Universe.removeZombies()