package org.eclipse.nebula.widgets.nattable.core.layer

import java.io.Serializable
import java.util.List
import org.eclipse.nebula.widgets.nattable.core.layer.axis.Axis

import static org.junit.Assert.*

import static extension org.eclipse.nebula.widgets.nattable.core.layer.axis.AxisInvariants.*

class AxisTest {
	
	def static testAxis(Axis axis, List<? extends Serializable> expectedIds, List<Integer> expectedPixels) {
		testAxis("", axis, expectedIds, expectedPixels)
	}
	
	def static testAxis(String axisName, Axis axis, List<? extends Serializable> expectedIds, List<Integer> expectedPixels) {
		// Segment count
		assertEquals('''«axisName» getSegmentCount''', expectedIds.size, axis.segmentCount)
		
		// Start pixel of segment position
		for (segmentPosition : 0 .. axis.segmentCount)
			assertEquals('''«axisName» getStartPixelOfSegmentPosition(«segmentPosition»)''', expectedPixels.get(segmentPosition), axis.getStartPixelOfSegmentPosition(segmentPosition))
		
		// Segment position of pixel location
		assertEquals('''«axisName» < range getSegmentPositionOfPixelLocation(«expectedPixels.get(0) - 1»)''', -1, axis.getSegmentPositionOfPixelLocation(expectedPixels.get(0) - 1))
		for (segmentPosition : 0 ..< axis.segmentCount) {
			val pixelLocation = expectedPixels.get(segmentPosition)
			assertEquals('''«axisName» getSegmentPositionOfPixelLocation(«pixelLocation»)''', segmentPosition, axis.getSegmentPositionOfPixelLocation(pixelLocation))
		}
		assertEquals('''«axisName» > range getSegmentPositionOfPixelLocation(«axis.pixelSize»)''', axis.segmentCount, axis.getSegmentPositionOfPixelLocation(axis.pixelSize))
		
		// Id of segment position
		for (segmentPosition : 0 ..< axis.segmentCount)
			assertEquals('''«axisName» getIdOfSegmentPosition(«segmentPosition»)''', expectedIds.get(segmentPosition), axis.getIdOfSegmentPosition(segmentPosition))

		// Segment position of id
		for (segmentId : expectedIds)
			assertEquals('''«axisName» getSegmentPositionOfId(«segmentId»)''', expectedIds.indexOf(segmentId), axis.getSegmentPositionOfId(segmentId))
		
		// Pixel size
		assertEquals('''«axisName» pixelSize''', expectedPixels.get(expectedPixels.size - 1) - expectedPixels.get(0), axis.pixelSize)
	}
	
}