// Path: jnetrobust-core/src/main/java/com/github/mucaho/jnetrobust/util/ShiftableBitSet.java
// public final class ShiftableBitSet {
//     private long bits;
// 
// 
//     public ShiftableBitSet(long bits) {
//         super();
//         this.bits = bits;
//     }
// 
//     public ShiftableBitSet() {
//         this.bits = 0;
//     }
// 
// 
//     public void and(long i) {
//         this.bits &= i;
//     }
// 
//     public void or(long i) {
//         this.bits |= i;
//     }
// 
//     public void xor(long i) {
//         this.bits ^= i;
//     }
// 
// 
//     public void minus(long i) {
//         this.bits -= i;
//     }
// 
//     public void plus(long i) {
//         this.bits += i;
//     }
// 
// 
//     public void set(long i) {
//         this.bits = i;
//     }
// 
//     public long get() {
//         return this.bits;
//     }
// 
//     public int getInt() {
//         return (int) bits;
//     }
// 
// 
//     public void shift(int i) {
//         if (i >= 0) {
//             this.shiftLeft(i);
//         } else {
//             this.shiftRight(-i);
//         }
//     }
// 
//     public void shiftRight(int i) {
//         bits >>>= i;
//     }
// 
//     public void shiftLeft(int i) {
//         bits <<= i;
//     }
// 
// 
//     private void setBit(int index, boolean set) {
//         if (set) {
//             bits |= LSB << index;
//         } else {
//             bits &= ~(LSB << index);
//         }
//     }
// 
//     public void setHighestBit(boolean set) {
//         this.setBit(SIZE - 1, set);
//     }
// 
//     public void setLowestBit(boolean set) {
//         this.setBit(0, set);
//     }
// 
//     public void set(int index, boolean set) {
//         if (index < 0) { // add negative index bit (shift bitset left and set bit)
//             this.shiftLeft(-index);
//             this.setLowestBit(set);
//         } else if (index < SIZE) { // set to positive 0 <= index < Size
//             this.setBit(index, set);
//         } else { // non-existing index, right shift the bitset then set the bit
//             this.shiftRight(index - SIZE + 1);
//             this.setHighestBit(set);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("%64s", Long.toBinaryString(bits));
//     }
// }
// 
// Path: jnetrobust-core/src/main/java/com/github/mucaho/jnetrobust/util/BitConstants.java
// public final class BitConstants {
//     public static final int OFFSET = 1;
//     public static final int SIZE = Long.SIZE;
//     public static final long MSB = 0x8000000000000000L;
//     public static final long LSB = 0x1L;
//     private static final long INT_MASK = 0xFFFFFFFFL;
// 
//     private BitConstants() {
//     }
// 
//     public static final long convertBits(int bits) {
//         return ((long) bits) & INT_MASK;
//     }
// 
//     public static final int convertBits(long bits) {
//         return (int) bits;
//     }
// }
// 
// Path: jnetrobust-core/src/test/java/com/github/mucaho/jnetrobust/util/TestUtils.java
// public final static long binLong(String binaryString) {
//     return Long.parseLong(binaryString, 2);
// }


import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import mockit.Deencapsulation;
import com.github.mucaho.jnetrobust.util.ShiftableBitSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import static com.github.mucaho.jnetrobust.util.BitConstants.*;
import static com.github.mucaho.jnetrobust.util.TestUtils.binLong;
import static org.junit.Assert.assertEquals;
/*
 * Copyright (c) 2014 mucaho (https://github.com/mucaho).
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package com.github.mucaho.jnetrobust.control;




@RunWith(JUnitParamsRunner.class)
public class AckBitsControlTest {

    @Test
    @Parameters
    public final void testAddToAckInt(long preBits, int inDiff, long postBits) {
        ShiftableBitSet actualBitSet = new ShiftableBitSet(preBits);
        ShiftableBitSet expectedBitSet = new ShiftableBitSet(postBits);
        AckBitsControl handler = new AckBitsControl();
        Deencapsulation.setField(handler, "ackRemoteBits", actualBitSet);

        String debug = "";
        debug += actualBitSet;
        handler.addToAck(inDiff);
        debug += ".addToAck(" + inDiff + ")";
        debug += " = " + actualBitSet;
        debug += " != " + expectedBitSet;

        assertEquals(debug, expectedBitSet.get(), actualBitSet.get());
    }

    public Collection<Object[]> parametersForTestAddToAckInt() {
        ArrayList<Object[]> list = new ArrayList<Object[]>();
        Random rng = new Random();
        long preBits;
        long postBits;
        int index;


        list.add(new Object[]{0L, 0, 0L});
        list.add(new Object[]{0L, OFFSET + SIZE, 0L});
        list.add(new Object[]{binLong("0100"), OFFSET, binLong("0101")});
// Path: jnetrobust-core/src/main/java/com/github/mucaho/jnetrobust/util/ShiftableBitSet.java
// public final class ShiftableBitSet {
//     private long bits;
// 
// 
//     public ShiftableBitSet(long bits) {
//         super();
//         this.bits = bits;
//     }
// 
//     public ShiftableBitSet() {
//         this.bits = 0;
//     }
// 
// 
//     public void and(long i) {
//         this.bits &= i;
//     }
// 
//     public void or(long i) {
//         this.bits |= i;
//     }
// 
//     public void xor(long i) {
//         this.bits ^= i;
//     }
// 
// 
//     public void minus(long i) {
//         this.bits -= i;
//     }
// 
//     public void plus(long i) {
//         this.bits += i;
//     }
// 
// 
//     public void set(long i) {
//         this.bits = i;
//     }
// 
//     public long get() {
//         return this.bits;
//     }
// 
//     public int getInt() {
//         return (int) bits;
//     }
// 
// 
//     public void shift(int i) {
//         if (i >= 0) {
//             this.shiftLeft(i);
//         } else {
//             this.shiftRight(-i);
//         }
//     }
// 
//     public void shiftRight(int i) {
//         bits >>>= i;
//     }
// 
//     public void shiftLeft(int i) {
//         bits <<= i;
//     }
// 
// 
//     private void setBit(int index, boolean set) {
//         if (set) {
//             bits |= LSB << index;
//         } else {
//             bits &= ~(LSB << index);
//         }
//     }
// 
//     public void setHighestBit(boolean set) {
//         this.setBit(SIZE - 1, set);
//     }
// 
//     public void setLowestBit(boolean set) {
//         this.setBit(0, set);
//     }
// 
//     public void set(int index, boolean set) {
//         if (index < 0) { // add negative index bit (shift bitset left and set bit)
//             this.shiftLeft(-index);
//             this.setLowestBit(set);
//         } else if (index < SIZE) { // set to positive 0 <= index < Size
//             this.setBit(index, set);
//         } else { // non-existing index, right shift the bitset then set the bit
//             this.shiftRight(index - SIZE + 1);
//             this.setHighestBit(set);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("%64s", Long.toBinaryString(bits));
//     }
// }
// 
// Path: jnetrobust-core/src/main/java/com/github/mucaho/jnetrobust/util/BitConstants.java
// public final class BitConstants {
//     public static final int OFFSET = 1;
//     public static final int SIZE = Long.SIZE;
//     public static final long MSB = 0x8000000000000000L;
//     public static final long LSB = 0x1L;
//     private static final long INT_MASK = 0xFFFFFFFFL;
// 
//     private BitConstants() {
//     }
// 
//     public static final long convertBits(int bits) {
//         return ((long) bits) & INT_MASK;
//     }
// 
//     public static final int convertBits(long bits) {
//         return (int) bits;
//     }
// }
// 
// Path: jnetrobust-core/src/test/java/com/github/mucaho/jnetrobust/util/TestUtils.java
// public final static long binLong(String binaryString) {
//     return Long.parseLong(binaryString, 2);
// }


// Path: jnetrobust-core/src/test/java/com/github/mucaho/jnetrobust/control/AckBitsControlTest.java
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import mockit.Deencapsulation;
import com.github.mucaho.jnetrobust.util.ShiftableBitSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import static com.github.mucaho.jnetrobust.util.BitConstants.*;
import static com.github.mucaho.jnetrobust.util.TestUtils.binLong;
import static org.junit.Assert.assertEquals;

/*
 * Copyright (c) 2014 mucaho (https://github.com/mucaho).
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package com.github.mucaho.jnetrobust.control;




@RunWith(JUnitParamsRunner.class)
public class AckBitsControlTest {

    @Test
    @Parameters
    public final void testAddToAckInt(long preBits, int inDiff, long postBits) {
        ShiftableBitSet actualBitSet = new ShiftableBitSet(preBits);
        ShiftableBitSet expectedBitSet = new ShiftableBitSet(postBits);
        AckBitsControl handler = new AckBitsControl();
        Deencapsulation.setField(handler, "ackRemoteBits", actualBitSet);

        String debug = "";
        debug += actualBitSet;
        handler.addToAck(inDiff);
        debug += ".addToAck(" + inDiff + ")";
        debug += " = " + actualBitSet;
        debug += " != " + expectedBitSet;

        assertEquals(debug, expectedBitSet.get(), actualBitSet.get());
    }

    public Collection<Object[]> parametersForTestAddToAckInt() {
        ArrayList<Object[]> list = new ArrayList<Object[]>();
        Random rng = new Random();
        long preBits;
        long postBits;
        int index;


        list.add(new Object[]{0L, 0, 0L});
        list.add(new Object[]{0L, OFFSET + SIZE, 0L});
        list.add(new Object[]{binLong("0100"), OFFSET, binLong("0101")});
        list.add(new Object[]{binLong("0100"), -OFFSET, binLong("1001")});