code: package savi;
  
  import org.junit.jupiter.api.Test;
  import savi.StateSynchronization.CameraPerception;
  import savi.StateSynchronization.Perception;
  import savi.StateSynchronization.PerceptionSnapshot;
  import savi.StateSynchronization.TimePerception;
  
  import static org.junit.jupiter.api.Assertions.assertFalse;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  public class PerceptionSnapshotUnitTest {
  	
  	/**
  	 * Test the case where there is an empty PerceptionSnapshot
  	 * @param verbose
  	 * @return
  	 */
  	private void emptyTest() {
  		// Constructor
  		PerceptionSnapshot testSnapshot = new PerceptionSnapshot();
  
  		// addPerception
  		testSnapshot.addPerception(null);
  		
  		// Check the empty perception list
  		assertTrue(testSnapshot.getPerceptionList().size() == 0);
  		
  		// Check the empty perception list - latest version
  		assertTrue(testSnapshot.getLatestTimeStamp() == -1);
  		
  		// Check the empty perception list - list of literals
  		assertTrue(testSnapshot.getLiterals().isEmpty());
  		
  		// Check the empty perception list - toString
  		assertTrue(testSnapshot.toString().equals("[]"));
  				
  		// Check for similar perception in an empty snapshot
  		double timeStamp = 8.0;
  		Perception testPerception1 = new TimePerception(timeStamp);
  		assertTrue(testSnapshot.pullSimilarPerception(testPerception1) == null);
  		
  		// Use the copy constructor and check the list of perceptions
  		PerceptionSnapshot copiedSnahpshot = new PerceptionSnapshot(testSnapshot);
  		assertTrue(copiedSnahpshot.getPerceptionList().size() == 0);
  	}
  	
  	
  
  	private void contentTest() {
  		// Constructor
  		PerceptionSnapshot testSnapshot = new PerceptionSnapshot();
  		
  		// Make some Perceptions for testing with
  		double timeStamp = 1.0;
  		String perceptionName = new String("threat");
  		double azumuth = 2.0;
  		double elevation = 3.0;
  		double range = 4.0;
  		double moreRecentTimeStep = 2.0;
  		
  		double radius=0.0;
  		
  		Perception testPerception1 = new TimePerception(timeStamp);
  		Perception testPerception2 = new CameraPerception(perceptionName, moreRecentTimeStep, azumuth, elevation, range, radius);
  		Perception similarPerception = new CameraPerception(perceptionName, timeStamp, azumuth + 0.001, elevation, range, radius);
  		Perception differentPerception = new CameraPerception(perceptionName, timeStamp, azumuth + 10000, elevation, range, radius);
  		Perception samePerception = testPerception2.clone();
  		
  		// addPerceptions to the snapshot
  		testSnapshot.addPerception(testPerception1);
  		testSnapshot.addPerception(testPerception2);
  		
  		// Check the size of the perception list
  		assertTrue(testSnapshot.getPerceptionList().size() == 2);
  		
  		// Check the perception list - latest version
  		assertTrue(testSnapshot.getLatestTimeStamp() == moreRecentTimeStep);
  		
  		// Check the perception list - list of literals
  		assertTrue(testSnapshot.getLiterals().contains(testPerception1.getLiteral()));
  		assertTrue(testSnapshot.getLiterals().contains(testPerception2.getLiteral()));
  		assertFalse(testSnapshot.getLiterals().contains(similarPerception.getLiteral()));
  		
  		// Check the empty perception list - toString
  		assertTrue(testSnapshot.toString().equals(new String("[" + testPerception1.toString() + ", " + testPerception2.toString() + "]")));
  				
  		// Check if the same perception is there
  		assertTrue(testSnapshot.pullSimilarPerception(samePerception).equals(samePerception));
  		
  		// Check if a similar perception is there (will fail, it was removed by previous step)
  		assertTrue(testSnapshot.pullSimilarPerception(similarPerception) == null);
  		
  		// Put it back, try again
  		testSnapshot.addPerception(testPerception2);
  		assertTrue(testSnapshot.pullSimilarPerception(similarPerception).equals(testPerception2));
  		// Make sure it was removed
  		assertTrue(testSnapshot.pullSimilarPerception(similarPerception) == null);
  		
  		// Check if a completely different perception is in the list
  		testSnapshot.addPerception(testPerception2);
  		assertTrue(testSnapshot.pullSimilarPerception(differentPerception) == null);
  		
  		// Use the copy constructor and check the list of perceptions
  		PerceptionSnapshot copiedSnapshot = new PerceptionSnapshot(testSnapshot);
  		assertTrue(copiedSnapshot.getPerceptionList().size() == 2);
  		assertTrue(copiedSnapshot.getLiterals().contains(testPerception1.getLiteral()));
  		assertTrue(copiedSnapshot.getLiterals().contains(testPerception2.getLiteral()));
  		assertFalse(copiedSnapshot.getLiterals().contains(similarPerception.getLiteral()));
  		
  		// Make a new Perception, put something different in it, then addPerceptionsFromSnapshot()
  		PerceptionSnapshot snapshotToAdd = new PerceptionSnapshot();
  		snapshotToAdd.addPerception(differentPerception);
  		copiedSnapshot.addPerceptionsFromSnapshot(snapshotToAdd);
  		assertTrue(copiedSnapshot.getPerceptionList().size() == 3);
  		assertTrue(copiedSnapshot.getLiterals().contains(testPerception1.getLiteral()));
  		assertTrue(copiedSnapshot.getLiterals().contains(testPerception2.getLiteral()));
  		assertTrue(copiedSnapshot.getLiterals().contains(differentPerception.getLiteral()));
  		assertFalse(copiedSnapshot.getLiterals().contains(similarPerception.getLiteral()));
  	}
  	
  	
  	@Test
  	void test() {
  		
  		System.out.println(new String());
  		
  		// Test the case where there is an empty PerceptionSnapshot involved.
  		this.emptyTest();
  		
  		// Test a case where the PerceptionSnapshot is not empty
  		this.contentTest();
  	}
  }
  