From 28a12f886bfab95726a8a8f682857dca753a37bf Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sun, 6 Jul 2025 14:10:56 +0200 Subject: [PATCH 1/3] refactor: add parameterized tests for BitSwap --- .../bitmanipulation/BitSwap.java | 19 ++++- .../bitmanipulation/BitSwapTest.java | 85 +++++++++++++++++-- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java index 40b3097b1276..d8c207567ba6 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java @@ -1,12 +1,27 @@ package com.thealgorithms.bitmanipulation; +/** + * Utility class for performing bit-swapping operations on integers. + * This class cannot be instantiated. + */ public final class BitSwap { private BitSwap() { } - /* - * @brief Swaps the bits at the position posA and posB from data + + /** + * Swaps two bits at specified positions in an integer. + * + * @param data The input integer whose bits need to be swapped + * @param posA The position of the first bit (0-based, from least significant) + * @param posB The position of the second bit (0-based, from least significant) + * @return The modified value with swapped bits + * @throws IllegalArgumentException if either position is negative or ≥ 32 */ public static int bitSwap(int data, final int posA, final int posB) { + if (posA < 0 || posA >= Integer.SIZE || posB < 0 || posB >= Integer.SIZE) { + throw new IllegalArgumentException("Bit positions must be between 0 and 31"); + } + if (SingleBitOperations.getBit(data, posA) != SingleBitOperations.getBit(data, posB)) { data ^= (1 << posA) ^ (1 << posB); } diff --git a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java index 40de770e0c66..1af0171adaf5 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java @@ -2,12 +2,83 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; -public class BitSwapTest { - @Test - void testHighestSetBit() { - assertEquals(3, BitSwap.bitSwap(3, 0, 1)); - assertEquals(5, BitSwap.bitSwap(6, 0, 1)); - assertEquals(7, BitSwap.bitSwap(7, 1, 1)); +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class BitSwapTest { + + @ParameterizedTest(name = "Additional cases: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideAdditionalCases") + void testAdditionalCases(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Swap different bits: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideDifferentBitsCases") + void swapDifferentBits(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Swap same bits: data={0}, posA={1}, posB={2} should not change") + @MethodSource("provideSameBitsCases") + void swapSameBits(int data, int posA, int posB) { + assertEquals(data, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Edge cases: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideEdgeCases") + void testEdgeCases(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Invalid positions: data={0}, posA={1}, posB={2} should throw") + @MethodSource("provideInvalidPositions") + void invalidPositionThrowsException(int data, int posA, int posB) { + assertThrows(IllegalArgumentException.class, + () -> BitSwap.bitSwap(data, posA, posB)); + } + + static Stream provideAdditionalCases() { + return Stream.of( + Arguments.of(3, 0, 1, 3), + Arguments.of(6, 0, 1, 5), + Arguments.of(7, 1, 1, 7) + ); + } + + static Stream provideDifferentBitsCases() { + return Stream.of( + Arguments.of(0b01, 0, 1, 0b10) + ); + } + + static Stream provideSameBitsCases() { + return Stream.of( + Arguments.of(0b111, 0, 2), + Arguments.of(0b0, 1, 3), + Arguments.of(0b1010, 1, 3), + Arguments.of(-1, 5, 5) + ); + } + + static Stream provideEdgeCases() { + return Stream.of( + Arguments.of(Integer.MIN_VALUE, 31, 0, 1), + Arguments.of(0, 0, 31, 0) + ); + } + + static Stream provideInvalidPositions() { + return Stream.of( + Arguments.of(0, -1, 0), + Arguments.of(0, 0, 32), + Arguments.of(0, -5, 33), + Arguments.of(0, Integer.MIN_VALUE, Integer.MAX_VALUE) + ); } } From 924607a6115bb53087b846f235235a1e8a0ef01c Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sun, 6 Jul 2025 14:19:08 +0200 Subject: [PATCH 2/3] refactor: fix import formatting --- .../java/com/thealgorithms/bitmanipulation/BitSwapTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java index 1af0171adaf5..f8c58894ae26 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java @@ -1,15 +1,13 @@ package com.thealgorithms.bitmanipulation; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertThrows; - class BitSwapTest { @ParameterizedTest(name = "Additional cases: data={0}, posA={1}, posB={2} -> expected={3}") From f8ed188bee9975f128ca328b4c404d359330a9ee Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Sun, 6 Jul 2025 14:22:32 +0200 Subject: [PATCH 3/3] refactor: fix clang format issues --- .../bitmanipulation/BitSwapTest.java | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java index f8c58894ae26..9d888d056453 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java @@ -37,46 +37,26 @@ void testEdgeCases(int data, int posA, int posB, int expected) { @ParameterizedTest(name = "Invalid positions: data={0}, posA={1}, posB={2} should throw") @MethodSource("provideInvalidPositions") void invalidPositionThrowsException(int data, int posA, int posB) { - assertThrows(IllegalArgumentException.class, - () -> BitSwap.bitSwap(data, posA, posB)); + assertThrows(IllegalArgumentException.class, () -> BitSwap.bitSwap(data, posA, posB)); } static Stream provideAdditionalCases() { - return Stream.of( - Arguments.of(3, 0, 1, 3), - Arguments.of(6, 0, 1, 5), - Arguments.of(7, 1, 1, 7) - ); + return Stream.of(Arguments.of(3, 0, 1, 3), Arguments.of(6, 0, 1, 5), Arguments.of(7, 1, 1, 7)); } static Stream provideDifferentBitsCases() { - return Stream.of( - Arguments.of(0b01, 0, 1, 0b10) - ); + return Stream.of(Arguments.of(0b01, 0, 1, 0b10)); } static Stream provideSameBitsCases() { - return Stream.of( - Arguments.of(0b111, 0, 2), - Arguments.of(0b0, 1, 3), - Arguments.of(0b1010, 1, 3), - Arguments.of(-1, 5, 5) - ); + return Stream.of(Arguments.of(0b111, 0, 2), Arguments.of(0b0, 1, 3), Arguments.of(0b1010, 1, 3), Arguments.of(-1, 5, 5)); } static Stream provideEdgeCases() { - return Stream.of( - Arguments.of(Integer.MIN_VALUE, 31, 0, 1), - Arguments.of(0, 0, 31, 0) - ); + return Stream.of(Arguments.of(Integer.MIN_VALUE, 31, 0, 1), Arguments.of(0, 0, 31, 0)); } static Stream provideInvalidPositions() { - return Stream.of( - Arguments.of(0, -1, 0), - Arguments.of(0, 0, 32), - Arguments.of(0, -5, 33), - Arguments.of(0, Integer.MIN_VALUE, Integer.MAX_VALUE) - ); + return Stream.of(Arguments.of(0, -1, 0), Arguments.of(0, 0, 32), Arguments.of(0, -5, 33), Arguments.of(0, Integer.MIN_VALUE, Integer.MAX_VALUE)); } }