/*
 * 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 com.speedment.runtime.field.internal.comparator;

import com.speedment.runtime.config.identifier.ColumnIdentifier;
import com.speedment.runtime.field.ByteField;
import com.speedment.runtime.field.comparator.FieldComparator;
import com.speedment.runtime.field.comparator.NullOrder;
import com.speedment.runtime.typemapper.TypeMapper;
import java.util.Objects;
import java.util.Random;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

/**
 *
 * @author Per Minborg
 */
public class ByteFieldComparatorImplTest {

    ByteFieldComparatorImpl<ByteValue, Byte> instance;

    @Before
    public void setUp() {
        instance = new ByteFieldComparatorImpl<>(ByteValue.BYTE);
    }

    @Test
    public void testGetField() {
        final ByteField<ByteValue, Byte> expResult = ByteValue.BYTE;
        final ByteField<ByteValue, Byte> result = instance.getField();
        assertEquals(expResult, result);
    }

    @Test
    public void testGetNullOrder() {
        final NullOrder expResult = NullOrder.NONE;
        final NullOrder result = instance.getNullOrder();
        assertEquals(expResult, result);
    }

    @Test
    public void testIsReversed() {
        boolean expResult = false;
        boolean result = instance.isReversed();
        assertEquals(expResult, result);
    }

    @Test
    public void testReversed() {
        final FieldComparator<ByteValue, Byte> expResult = new ByteFieldComparatorImpl<>(ByteValue.BYTE, true);
        final FieldComparator<ByteValue, Byte> result = instance.reversed();
        assertEquals(expResult, result);
        assertTrue(result.isReversed());
    }

    @Test
    public void testCompareSimple() {
        final ByteValue first = ByteValue.of((byte) 0);
        final ByteValue second = ByteValue.of((byte) 1);
        int expResult = -1;
        int result = instance.compare(first, second);
        assertEquals(expResult, result);
    }

    @Test
    public void testCompareABunch() {
        final Random rnd = new Random();

        final byte[] bytes = new byte[2];
        for (int i = 0; i < 100_000; i++) {
            rnd.nextBytes(bytes);
            final ByteValue first = ByteValue.of(bytes[0]);
            final ByteValue second = ByteValue.of(bytes[1]);
            final int expResult = signum(Byte.compare(first.getByte(), second.getByte()));
            final int result = signum(instance.compare(first, second));
            assertEquals(expResult, result);
        }
    }

    private int signum(int b) {
        if (b == 0) {
            return 0;
        }
        if (b > 0) {
            return 1;
        }
        return -1;
    }

    @Test
    public void testHashCode() {
        final int expResult = new ByteFieldComparatorImpl<>(ByteValue.BYTE, false).reversed().reversed().hashCode();
        final int result = instance.hashCode();
        assertEquals(expResult, result);
    }

    @Test
    public void testEquals() {
        final ByteFieldComparatorImpl<ByteValue, Byte> result = new ByteFieldComparatorImpl<>(ByteValue.BYTE, false);
        assertEquals(instance, result);
    }

    @Test
    public void testToString() {
        final String result = instance.toString();
        assertNotNull(result);
    }

    private interface ByteValue {

        byte getByte();

        ByteValue setByte(byte value);

        final ColumnIdentifier BYTE_IDENTIFIER = new ColumnIdentifier<ByteValue>() {
            @Override
            public String getDbmsName() {
                return "db0";
            }

            @Override
            public String getSchemaName() {
                return "schema";
            }

            @Override
            public String getTableName() {
                return "byte_value";
            }

            @Override
            public String getColumnName() {
                return "byte";
            }

        };

        final ByteField<ByteValue, Byte> BYTE = ByteField.create(
            BYTE_IDENTIFIER,
            ByteValue::getByte,
            ByteValue::setByte,
            TypeMapper.identity(),
            false
        );

        static ByteValue of(byte value) {
            return new ByteValueImpl(value);
        }

    }

    private static class ByteValueImpl implements ByteValue {

        private byte value;

        public ByteValueImpl(byte value) {
            this.value = value;
        }

        @Override
        public byte getByte() {
            return value;
        }

        @Override
        public ByteValue setByte(byte value) {
            this.value = value;
            return this;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof ByteValue)) {
                return false;
            }
            ByteValue that = (ByteValue) obj;
            return this.getByte() == that.getByte();
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(value);
        }

        @Override
        public String toString() {
            return Byte.toString(value);
        }

    }

}

@@ -570,16 +570,51 @@
 Random;%0A
+import java.util.stream.IntStream;%0A
 import s
@@ -2199,13 +2199,19 @@
 areA
-Bunch
+llTheThings
 () %7B
@@ -2223,162 +2223,171 @@
     
-final Random rnd = new Random();%0A%0A        final byte%5B%5D bytes = new byte%5B2%5D;%0A        for (int i = 0; i %3C 100_000; i++) %7B%0A            rnd.nextBytes(bytes);%0A
+IntStream.rangeClosed(Byte.MIN_VALUE, Byte.MAX_VALUE).forEach(first -%3E %7B%0A            IntStream.rangeClosed(Byte.MIN_VALUE, Byte.MAX_VALUE).forEach(second -%3E %7B%0A    
     
@@ -2407,32 +2407,41 @@
  ByteValue first
+ByteValue
  = ByteValue.of(
@@ -2444,19 +2444,27 @@
 .of(
+(
 byte
-s%5B0%5D);%0A
+) first);%0A    
     
@@ -2485,32 +2485,41 @@
 ByteValue second
+ByteValue
  = ByteValue.of(
@@ -2522,19 +2522,27 @@
 .of(
+(
 byte
-s%5B1%5D);%0A
+) second);%0A   
     
@@ -2541,32 +2541,33 @@
 %0A               
+ 
 final int expRes
@@ -2597,16 +2597,25 @@
 re(first
+ByteValue
 .getByte
@@ -2624,16 +2624,25 @@
 , second
+ByteValue
 .getByte
@@ -2651,32 +2651,36 @@
 ));%0A            
+  
+  
 final int result
@@ -2711,24 +2711,42 @@
 re(first
-, second
+ByteValue, secondByteValue
 ));%0A    
@@ -2745,32 +2745,36 @@
 ));%0A            
+ 
+   
 assertEquals(exp
@@ -2794,25 +2794,43 @@
 t);%0A        
-%7D
+    %7D);%0A        %7D);
 %0A    %7D%0A%0A    

Improve test to be exhaustive