/*
 * Java Genetic Algorithm Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
 */
package org.jenetics.internal.util;

import static org.jenetics.internal.util.IndexSorter.indexes;
import static org.jenetics.internal.util.array.revert;

import java.util.Arrays;
import java.util.Random;

import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @version <em>$Date: 2014-08-26 $</em>
 */
public class IndexSorterTest {

    private static double[] sort(final IndexSorter sorter, final double[] values) {
        final int[] indexes = sorter.sort(values, indexes(values.length));

        final double[] result = new double[values.length];
        for (int i = 0; i < result.length; ++i) {
            result[i] = values[indexes[i]];
        }
        return result;
    }

    private static double[] sort(final double[] values) {
        final double[] result = values.clone();
        Arrays.sort(result);
        return result;
    }

    @Test(dataProvider = "specialArray")
    public void sortSpecial(final double[] values) {
        final double[] indexSortedValues = sort(new HeapSorter(), values);
        final double[] indexSortedValues2 = sort(new InsertionSorter(), values);
        Assert.assertEquals(indexSortedValues, indexSortedValues2);

        final String actual = Arrays.toString(indexSortedValues);
        final String expected = Arrays.toString(sort(values));

        Assert.assertEquals(actual, expected);
    }

    @DataProvider(name = "specialArray")
    public Object[][] specialArray() {
        return new Object[][] {
            {new double[]{0.0, 0.0, 0.0, 0.0, 1.0}},
            {new double[]{1.0, 0.0, 0.0, 0.0, 0.0}},
            {new double[]{1.0, 0.0, 0.0, 0.0, 1.0}},
            {new double[]{2.0, 0.0, 1.0, 1.0, 1.0}}
        };
    }

    @Test(dataProvider = "sorters")
    public void sortRandomValues(final IndexSorter sorter, final Integer size) {
        final double[] values = new Random().doubles(size).toArray();

        final String actual = Arrays.toString(sort(sorter, values));
        final String expected = Arrays.toString(sort(values));
        Assert.assertEquals(actual, expected);
    }

	@Test(dataProvider = "sorters")
	public void sortAscSortedValues(final IndexSorter sorter, final Integer size) {
		final double[] values = new Random().doubles(size).toArray();
		Arrays.sort(values);

        final String actual = Arrays.toString(sort(sorter, values));
        final String expected = Arrays.toString(sort(values));
        Assert.assertEquals(actual, expected);
	}

	@Test(dataProvider = "sorters")
	public void sortDescSortedValues(final IndexSorter sorter, final Integer size) {
		final double[] values = new Random().doubles(size).toArray();
		Arrays.sort(values);
		revert(values);

        final String actual = Arrays.toString(sort(sorter, values));
        final String expected = Arrays.toString(sort(values));
        Assert.assertEquals(actual, expected);
	}

	@DataProvider(name = "sorters")
	public Object[][] sorters() {
		return new Object[][] {
            {new InsertionSorter(), 1},
            {new InsertionSorter(), 2},
            {new InsertionSorter(), 3},
            {new InsertionSorter(), 5},
            {new InsertionSorter(), 33},
			{new HeapSorter(), 1},
			{new HeapSorter(), 2},
			{new HeapSorter(), 3},
			{new HeapSorter(), 5},
			{new HeapSorter(), 11},
			{new HeapSorter(), 1000},
			{new HeapSorter(), 10_000}
		};
	}

}

@@ -2055,37 +2055,48 @@
         
-final String actual =
+Assert.assertEquals(%0A           
  Arrays.
@@ -2118,25 +2118,25 @@
 ortedValues)
-;
+,
 %0A        fin
@@ -2132,39 +2132,19 @@
         
-final String expected =
+   
  Arrays.
@@ -2165,18 +2165,16 @@
 values))
-;%0A
 %0A       
@@ -2178,44 +2178,8 @@
     
-Assert.assertEquals(actual, expected
 );%0A 
@@ -2719,38 +2719,40 @@
 %0A%0A        final 
-String
+double%5B%5D
  actual = Arrays
@@ -2745,32 +2745,16 @@
 ctual = 
-Arrays.toString(
 sort(sor
@@ -2757,33 +2757,32 @@
 (sorter, values)
-)
 ;%0A        final 
@@ -2773,38 +2773,40 @@
 ;%0A        final 
-String
+double%5B%5D
  expected = Arra
@@ -2801,32 +2801,16 @@
 ected = 
-Arrays.toString(
 sort(val
@@ -2805,33 +2805,32 @@
 d = sort(values)
-)
 ;%0A        Assert
@@ -3077,38 +3077,40 @@
 %0A%0A        final 
-String
+double%5B%5D
  actual = Arrays
@@ -3103,32 +3103,16 @@
 ctual = 
-Arrays.toString(
 sort(sor
@@ -3115,33 +3115,32 @@
 (sorter, values)
-)
 ;%0A        final 
@@ -3131,38 +3131,40 @@
 ;%0A        final 
-String
+double%5B%5D
  expected = Arra
@@ -3159,32 +3159,16 @@
 ected = 
-Arrays.toString(
 sort(val
@@ -3163,33 +3163,32 @@
 d = sort(values)
-)
 ;%0A        Assert
@@ -3459,22 +3459,24 @@
   final 
-String
+double%5B%5D
  actual 
@@ -3477,32 +3477,16 @@
 ctual = 
-Arrays.toString(
 sort(sor
@@ -3493,25 +3493,24 @@
 ter, values)
-)
 ;%0A        fi
@@ -3513,22 +3513,24 @@
   final 
-String
+double%5B%5D
  expecte
@@ -3533,32 +3533,16 @@
 ected = 
-Arrays.toString(
 sort(val
@@ -3545,17 +3545,16 @@
 (values)
-)
 ;%0A      

Improve testing.