/*
* Catroid: An on-device visual programming system for Android devices
* Copyright (C) 2010-2016 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* An additional term exception under section 7 of the GNU Affero
* General Public License, version 3, is available at
* http://developer.catrobat.org/license_additional_term
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.catrobat.catroid.test.utiltests;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.util.Log;
import org.catrobat.catroid.common.Constants;
import org.catrobat.catroid.common.DefaultProjectHandler;
import org.catrobat.catroid.common.LookData;
import org.catrobat.catroid.common.ScreenValues;
import org.catrobat.catroid.content.Project;
import org.catrobat.catroid.content.Script;
import org.catrobat.catroid.content.SingleSprite;
import org.catrobat.catroid.content.Sprite;
import org.catrobat.catroid.content.WhenScript;
import org.catrobat.catroid.content.XmlHeader;
import org.catrobat.catroid.content.bricks.Brick;
import org.catrobat.catroid.content.bricks.HideBrick;
import org.catrobat.catroid.content.bricks.SetLookBrick;
import org.catrobat.catroid.content.bricks.WaitBrick;
import org.catrobat.catroid.formulaeditor.Formula;
import org.catrobat.catroid.test.utils.TestUtils;
import org.catrobat.catroid.utils.UtilFile;
import org.catrobat.catroid.utils.Utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class UtilsTest extends AndroidTestCase {
private static final String TAG = UtilsTest.class.getSimpleName();
private final String testFileContent = "Hello, this is a Test-String";
private static final String MD5_EMPTY = "D41D8CD98F00B204E9800998ECF8427E";
private static final String MD5_CATROID = "4F982D927F4784F69AD6D6AF38FD96AD";
private static final String MD5_HELLO_WORLD = "ED076287532E86365E841E92BFC50D8C";
private static final String NEW_PROGRAM_NAME = "new name";
private File testFile;
private File copiedFile;
private Project defaultProject;
@Override
protected void setUp() throws Exception {
OutputStream outputStream = null;
TestUtils.deleteTestProjects(NEW_PROGRAM_NAME);
try {
testFile = File.createTempFile("testCopyFiles", ".txt");
if (testFile.canWrite()) {
outputStream = new FileOutputStream(testFile);
outputStream.write(testFileContent.getBytes());
outputStream.flush();
}
} catch (IOException e) {
Log.e(TAG, "File handling error", e);
} finally {
if (outputStream != null) {
outputStream.close();
}
}
super.setUp();
}
@Override
protected void tearDown() throws Exception {
if (testFile != null && testFile.exists()) {
testFile.delete();
}
if (copiedFile != null && copiedFile.exists()) {
copiedFile.delete();
}
TestUtils.deleteTestProjects(NEW_PROGRAM_NAME);
super.tearDown();
}
public void testMD5CheckSumOfFile() {
PrintWriter printWriter = null;
File tempDir = new File(Constants.TMP_PATH);
tempDir.mkdirs();
File md5TestFile = new File(Utils.buildPath(Constants.TMP_PATH, "catroid.txt"));
if (md5TestFile.exists()) {
md5TestFile.delete();
}
try {
md5TestFile.createNewFile();
assertEquals("MD5 sums are not the same for empty file", MD5_EMPTY.toLowerCase(Locale.US),
Utils.md5Checksum(md5TestFile));
printWriter = new PrintWriter(md5TestFile);
printWriter.print("catroid");
} catch (IOException e) {
Log.e(TAG, "File handling error", e);
} finally {
if (printWriter != null) {
printWriter.close();
}
}
assertEquals("MD5 sums are not the same for catroid file", MD5_CATROID.toLowerCase(Locale.US),
Utils.md5Checksum(md5TestFile));
UtilFile.deleteDirectory(tempDir);
}
public void testMD5CheckSumOfString() {
assertEquals("MD5 sums do not match!", MD5_CATROID.toLowerCase(Locale.US), Utils.md5Checksum("catroid"));
assertEquals("MD5 sums do not match!", MD5_EMPTY.toLowerCase(Locale.US), Utils.md5Checksum(""));
assertEquals("MD5 sums do not match!", MD5_HELLO_WORLD.toLowerCase(Locale.US),
Utils.md5Checksum("Hello World!"));
}
public void testBuildPath() {
String first = "/abc/abc";
String second = "/def/def/";
String result = "/abc/abc/def/def";
assertEquals(Utils.buildPath(first, second), result);
first = "/abc/abc";
second = "def/def/";
result = "/abc/abc/def/def";
assertEquals(Utils.buildPath(first, second), result);
first = "/abc/abc/";
second = "/def/def/";
result = "/abc/abc/def/def";
assertEquals(Utils.buildPath(first, second), result);
first = "/abc/abc/";
second = "def/def/";
result = "/abc/abc/def/def";
assertEquals(Utils.buildPath(first, second), result);
}
public void testDeleteSpecialCharactersFromString() {
String testString = "This:IsA-\" */ :<Very>?|Very\\\\Long_Test_String";
String newString = Utils.deleteSpecialCharactersInString(testString);
assertEquals("Strings are not equal!", "ThisIsA- VeryVeryLong_Test_String", newString);
}
public void testBuildProjectPath() {
if (!Utils.externalStorageAvailable()) {
fail("No SD card present");
}
String projectName = "test?Projekt\"1";
String expectedPath = Constants.DEFAULT_ROOT + "/test%3FProjekt%221";
assertEquals("Paths are different!", expectedPath, Utils.buildProjectPath(projectName));
}
public void testProjectSameAsStandardProject() {
ScreenValues.SCREEN_WIDTH = 480;
ScreenValues.SCREEN_HEIGHT = 800;
try {
defaultProject = DefaultProjectHandler.createAndSaveDefaultProject(NEW_PROGRAM_NAME, getContext());
} catch (IOException | IllegalArgumentException e) {
Log.e(TAG, "error creating standard project", e);
fail("error creating standard project");
}
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
addSpriteAndCompareToStandardProject();
addScriptAndCompareToStandardProject();
addBrickAndCompareToStandardProject();
changeParametersOfBricksAndCompareToStandardProject();
removeBrickAndCompareToStandardProject();
removeScriptAndCompareToStandardProject();
removeSpriteAndCompareToStandardProject();
SystemClock.sleep(1000);
}
public void testLoadProjectIfNeeded() {
Utils.saveToPreferences(getContext(), Constants.PREF_PROJECTNAME_KEY, "projectNameWhichDoesNotExist");
try {
Utils.loadProjectIfNeeded(getContext());
} catch (Exception e) {
fail("Tried to load project which should not be loadable.");
}
TestUtils.removeFromPreferences(getContext(), Constants.PREF_PROJECTNAME_KEY);
}
public void testExtractRemixUrlsOfProgramHeaderUrlFieldContainingSingleAbsoluteUrl() {
final String expectedFirstProgramRemixUrl = "https://share.catrob.at/pocketcode/program/16267";
final String remixUrlsString = expectedFirstProgramRemixUrl;
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 1, result.size());
assertEquals("Failed to extract remix URL", expectedFirstProgramRemixUrl, result.get(0));
}
public void testExtractRemixUrlsOfProgramHeaderUrlFieldContainingSingleRelativeUrl() {
final String expectedFirstProgramRemixUrl = "/pocketcode/program/3570";
final String remixUrlsString = expectedFirstProgramRemixUrl;
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 1, result.size());
assertEquals("Failed to extract remix URL", expectedFirstProgramRemixUrl, result.get(0));
}
public void testExtractRemixUrlsOfMergedProgramHeaderUrlFieldContainingTwoAbsoluteUrls() {
final String expectedFirstProgramRemixUrl = "https://share.catrob.at/pocketcode/program/16267";
final String expectedSecondProgramRemixUrl = "https://scratch.mit.edu/projects/110380057/";
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("Catrobat program");
headerOfFirstProgram.setRemixParentsUrlString(expectedFirstProgramRemixUrl);
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("Scratch program");
headerOfSecondProgram.setRemixParentsUrlString(expectedSecondProgramRemixUrl);
final String remixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 2, result.size());
assertEquals("Failed to extract URL of first program", expectedFirstProgramRemixUrl, result.get(0));
assertEquals("Failed to extract URL of second program", expectedSecondProgramRemixUrl, result.get(1));
}
public void testExtractRemixUrlsOfMergedProgramHeaderUrlFieldContainingTwoRelativeUrls() {
final String expectedFirstProgramRemixUrl = "/pocketcode/program/16267";
final String expectedSecondProgramRemixUrl = "/pocketcode/program/3570";
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("Program A");
headerOfFirstProgram.setRemixParentsUrlString(expectedFirstProgramRemixUrl);
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("Program B");
headerOfSecondProgram.setRemixParentsUrlString(expectedSecondProgramRemixUrl);
final String remixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 2, result.size());
assertEquals("Failed to extract URL of first program", expectedFirstProgramRemixUrl, result.get(0));
assertEquals("Failed to extract URL of second program", expectedSecondProgramRemixUrl, result.get(1));
}
public void testExtractRemixUrlsOfMergedProgramHeaderUrlFieldContainingNoUrls() {
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("Program A");
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("Program B");
final String remixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 0, result.size());
}
public void testExtractRemixUrlsOfMergedProgramHeaderUrlFieldContainingMultipleMixedUrls() {
final String expectedFirstProgramRemixUrl = "https://scratch.mit.edu/projects/117697631/";
final String expectedSecondProgramRemixUrl = "/pocketcode/program/3570";
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("My Scratch program");
headerOfFirstProgram.setRemixParentsUrlString(expectedFirstProgramRemixUrl);
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("The Periodic Table");
headerOfSecondProgram.setRemixParentsUrlString(expectedSecondProgramRemixUrl);
final String remixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
List<String> result = Utils.extractRemixUrlsFromString(remixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 2, result.size());
assertEquals("Failed to extract URL of first program", expectedFirstProgramRemixUrl, result.get(0));
assertEquals("Failed to extract URL of second program", expectedSecondProgramRemixUrl, result.get(1));
}
public void testExtractRemixUrlsOfRemergedProgramHeaderUrlFieldContainingMixedUrls() {
final String expectedFirstProgramRemixUrl = "https://scratch.mit.edu/projects/117697631/";
final String expectedSecondProgramRemixUrl = "/pocketcode/program/3570";
final String expectedThirdProgramRemixUrl = "https://scratch.mit.edu/projects/121648946/";
final String expectedFourthProgramRemixUrl = "https://share.catrob.at/pocketcode/program/16267";
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("My first Scratch program");
headerOfFirstProgram.setRemixParentsUrlString(expectedFirstProgramRemixUrl);
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("The Periodic Table");
headerOfSecondProgram.setRemixParentsUrlString(expectedSecondProgramRemixUrl);
final String firstMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
final XmlHeader headerOfFirstMergedProgram = new XmlHeader();
headerOfFirstMergedProgram.setProgramName("First merged Catrobat program");
headerOfFirstMergedProgram.setRemixParentsUrlString(firstMergedRemixUrlsString);
final XmlHeader headerOfThirdProgram = new XmlHeader();
headerOfThirdProgram.setProgramName("My second Scratch program");
headerOfThirdProgram.setRemixParentsUrlString(expectedThirdProgramRemixUrl);
final String secondMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstMergedProgram,
headerOfThirdProgram);
final XmlHeader headerOfSecondMergedProgram = new XmlHeader();
headerOfSecondMergedProgram.setProgramName("Second merged Catrobat program");
headerOfSecondMergedProgram.setRemixParentsUrlString(secondMergedRemixUrlsString);
final XmlHeader headerOfFourthProgram = new XmlHeader();
headerOfFourthProgram.setProgramName("My third Catrobat program");
headerOfFourthProgram.setRemixParentsUrlString(expectedFourthProgramRemixUrl);
final String finalMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfSecondMergedProgram,
headerOfFourthProgram);
List<String> result = Utils.extractRemixUrlsFromString(finalMergedRemixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 4, result.size());
assertEquals("Failed to extract URL of first program", expectedFirstProgramRemixUrl, result.get(0));
assertEquals("Failed to extract URL of second program", expectedSecondProgramRemixUrl, result.get(1));
assertEquals("Failed to extract URL of third program", expectedThirdProgramRemixUrl, result.get(2));
assertEquals("Failed to extract URL of fourth program", expectedFourthProgramRemixUrl, result.get(3));
}
public void testExtractRemixUrlsOfRemergedProgramHeaderUrlFieldContainingMissingUrls() {
final String expectedSecondProgramRemixUrl = "/pocketcode/program/3570";
final String expectedFourthProgramRemixUrl = "https://share.catrob.at/pocketcode/program/16267";
final XmlHeader headerOfFirstProgram = new XmlHeader();
headerOfFirstProgram.setProgramName("Program A");
final XmlHeader headerOfSecondProgram = new XmlHeader();
headerOfSecondProgram.setProgramName("Program B");
headerOfSecondProgram.setRemixParentsUrlString(expectedSecondProgramRemixUrl);
final String firstMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstProgram,
headerOfSecondProgram);
final XmlHeader headerOfFirstMergedProgram = new XmlHeader();
headerOfFirstMergedProgram.setProgramName("First merged program");
headerOfFirstMergedProgram.setRemixParentsUrlString(firstMergedRemixUrlsString);
final XmlHeader headerOfThirdProgram = new XmlHeader();
headerOfThirdProgram.setProgramName("Program C");
final String secondMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfFirstMergedProgram,
headerOfThirdProgram);
final XmlHeader headerOfSecondMergedProgram = new XmlHeader();
headerOfSecondMergedProgram.setProgramName("Second merged program");
headerOfSecondMergedProgram.setRemixParentsUrlString(secondMergedRemixUrlsString);
final XmlHeader headerOfFourthProgram = new XmlHeader();
headerOfFourthProgram.setProgramName("Program D");
headerOfFourthProgram.setRemixParentsUrlString(expectedFourthProgramRemixUrl);
final String finalMergedRemixUrlsString = Utils.generateRemixUrlsStringForMergedProgram(headerOfSecondMergedProgram,
headerOfFourthProgram);
List<String> result = Utils.extractRemixUrlsFromString(finalMergedRemixUrlsString);
assertEquals("Invalid number of remix URLs extracted", 2, result.size());
assertEquals("Failed to extract remix URL of second program", expectedSecondProgramRemixUrl, result.get(0));
assertEquals("Failed to extract remix URL of fourth program", expectedFourthProgramRemixUrl, result.get(1));
}
private void addSpriteAndCompareToStandardProject() {
Sprite sprite = new SingleSprite("TestSprite");
defaultProject.getDefaultScene().addSprite(sprite);
assertFalse("Failed to recognize that the project is not standard after adding a new SingleSprite",
Utils.isStandardProject(defaultProject, getContext()));
defaultProject.getDefaultScene().removeSprite(sprite);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
private void addScriptAndCompareToStandardProject() {
Sprite catroidSprite = defaultProject.getDefaultScene().getSpriteList().get(1);
WhenScript whenScript = new WhenScript();
catroidSprite.addScript(whenScript);
assertFalse("Failed to recognize that the project is not standard after adding a new script",
Utils.isStandardProject(defaultProject, getContext()));
catroidSprite.removeScript(whenScript);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
private void addBrickAndCompareToStandardProject() {
Sprite catroidSprite = defaultProject.getDefaultScene().getSpriteList().get(1);
Brick brick = new HideBrick();
Script catroidScript = catroidSprite.getScript(0);
catroidScript.addBrick(brick);
assertFalse("Failed to recognize that the project is not standard after adding a new brick",
Utils.isStandardProject(defaultProject, getContext()));
catroidScript.removeBrick(brick);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
private void changeParametersOfBricksAndCompareToStandardProject() {
Script catroidScript = defaultProject.getDefaultScene().getSpriteList().get(1).getScript(0);
ArrayList<Brick> brickList = catroidScript.getBrickList();
SetLookBrick setLookBrick = null;
WaitBrick waitBrick = null;
for (int i = 0; i < brickList.size(); i++) {
if (brickList.get(i) instanceof SetLookBrick) {
setLookBrick = (SetLookBrick) brickList.get(i);
break;
}
if (brickList.get(i) instanceof WaitBrick) {
waitBrick = (WaitBrick) brickList.get(i);
break;
}
}
if (setLookBrick != null) {
LookData oldLookData = setLookBrick.getLook();
LookData newLookData = new LookData();
setLookBrick.setLook(newLookData);
assertFalse("Failed to recognize that the project is not standard after changing the set look brick",
Utils.isStandardProject(defaultProject, getContext()));
setLookBrick.setLook(oldLookData);
assertTrue("Failed to recognize the standard project",
Utils.isStandardProject(defaultProject, getContext()));
}
if (waitBrick != null) {
Formula oldTime = waitBrick.getTimeToWait();
Formula newTimeToWait = new Formula(2345);
waitBrick.setTimeToWait(newTimeToWait);
assertFalse("Failed to recognize that the project is not standard after changing the wait brick",
Utils.isStandardProject(defaultProject, getContext()));
waitBrick.setTimeToWait(oldTime);
assertTrue("Failed to recognize the standard project",
Utils.isStandardProject(defaultProject, getContext()));
}
}
private void removeBrickAndCompareToStandardProject() {
Script catroidScript = defaultProject.getDefaultScene().getSpriteList().get(1).getScript(0);
ArrayList<Brick> brickList = catroidScript.getBrickList();
Brick brick = brickList.get(brickList.size() - 1);
brickList.remove(brickList.size() - 1);
assertFalse("Failed to recognize that the project is not standard after removing a brick",
Utils.isStandardProject(defaultProject, getContext()));
brickList.add(brick);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
private void removeScriptAndCompareToStandardProject() {
Script catroidScript = defaultProject.getDefaultScene().getSpriteList().get(1).getScript(0);
Sprite sprite = defaultProject.getDefaultScene().getSpriteList().get(1);
sprite.removeScript(catroidScript);
assertFalse("Failed to recognize that the project is not standard after removing a script",
Utils.isStandardProject(defaultProject, getContext()));
sprite.addScript(catroidScript);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
private void removeSpriteAndCompareToStandardProject() {
Sprite catroidSprite = defaultProject.getDefaultScene().getSpriteList().get(3);
int lastIndex = defaultProject.getDefaultScene().getSpriteList().size() - 1;
List<Sprite> spriteList = defaultProject.getDefaultScene().getSpriteList();
spriteList.remove(lastIndex);
assertFalse("Failed to recognize that the project is not standard after removing a sprite",
Utils.isStandardProject(defaultProject, getContext()));
spriteList.add(catroidSprite);
assertTrue("Failed to recognize the standard project", Utils.isStandardProject(defaultProject, getContext()));
}
public void testSetBitAllOnesSetIndex0To1() {
assertEquals("Setting an already set bit should not change numberToModify",
0b11111111, Utils.setBit(0b11111111, 0, 1));
}
public void testSetBitAllButOneZerosSetIndex3To1() {
assertEquals("Setting an already set bit should not change numberToModify",
0b00001000, Utils.setBit(0b00001000, 3, 1));
}
public void testSetBitAllZerosSetIndex7To0() {
assertEquals("Clearing an already cleared bit should not change numberToModify",
0b00000000, Utils.setBit(0b00000000, 7, 0));
}
public void testSetBitAllButOneOnesSetIndex4To0() {
assertEquals("Clearing an already cleared bit should not change numberToModify",
0b11011111, Utils.setBit(0b11011111, 5, 0));
}
public void testSetBitAllZerosSetIndex0To1() {
assertEquals("Didn't set bit as expected",
0b00000001, Utils.setBit(0b00000000, 0, 1));
}
public void testSetBitAllOnesSetIndex0To0() {
assertEquals("Didn't clear bit as expected",
0b11111110, Utils.setBit(0b11111111, 0, 0));
}
public void testSetBitAllZerosSetIndex7To1() {
assertEquals("Didn't set bit as expected",
0b10000000, Utils.setBit(0b00000000, 7, 1));
}
public void testSetBitAllOnesSetIndex7To0() {
assertEquals("Didn't clear bit as expected",
0b01111111, Utils.setBit(0b11111111, 7, 0));
}
public void testSetBitNegativeIndex() {
assertEquals("Negative index should not modify numberToModify",
0, Utils.setBit(0, -3, 1));
}
public void testSetBitMaxIndex() {
assertEquals("Didn't set bit as expected",
0x80000000, Utils.setBit(0x00000000, 31, 1));
}
public void testSetBitTooLargeIndex() {
assertEquals("Too large index (>=32) should not modify numberToModify",
0, Utils.setBit(0, 32, 1));
}
public void testSetBitNonbinaryValue() {
assertEquals("Any value other than 0 should set the bit specified by index",
0b00000001, Utils.setBit(0b00000000, 0, 4));
}
public void testGetBitGet0FromIndex0() {
assertEquals("Didn't get expected bit value",
0, Utils.getBit(0b11111110, 0));
}
public void testGetBitGet1FromIndex0() {
assertEquals("Didn't get expected bit value",
1, Utils.getBit(0b00000001, 0));
}
public void testGetBitGet0FromIndex7() {
assertEquals("Didn't get expected bit value",
0, Utils.getBit(0b01111111, 7));
}
public void testGetBitGet1FromIndex7() {
assertEquals("Didn't get expected bit value",
1, Utils.getBit(0b10000000, 7));
}
public void testGetBitGet0FromMaxIndex() {
assertEquals("Didn't get expected bit value",
0, Utils.getBit(0x7FFFFFFF, 31));
}
public void testGetBitGet1FromMaxIndex() {
assertEquals("Didn't get expected bit value",
1, Utils.getBit(0x80000000, 31));
}
public void testGetBitNegativeIndex() {
assertEquals("Negative index should return 0",
0, Utils.getBit(0xFFFFFFFF, -3));
}
public void testGetBitTooLargeIndex() {
assertEquals("Too large index (>=32) should return 0",
0, Utils.getBit(0xFFFFFFFF, 32));
}
}