aboutsummaryrefslogtreecommitdiff
path: root/dexlib2/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'dexlib2/src/test')
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/DexEntryFinderTest.java6
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/builder/LocatedItemsTest.java46
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/pool/RollbackTest.java4
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/CallSiteTest.java135
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/DexDataWriterTest.java1
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterSleb128Test.java1
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterTest.java4
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterUleb128Test.java1
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/JumboStringConversionTest.java4
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/writer/NakedByteArrayOutputStream.java44
-rw-r--r--dexlib2/src/test/java/org/jf/util/AbstractForwardSequentialListTest.java214
-rw-r--r--dexlib2/src/test/java/org/jf/util/IndentingWriterTest.java51
-rw-r--r--dexlib2/src/test/java/org/jf/util/NumberUtilsTest.java128
-rw-r--r--dexlib2/src/test/java/org/jf/util/StringWrapperTest.java153
14 files changed, 778 insertions, 14 deletions
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/DexEntryFinderTest.java b/dexlib2/src/test/java/org/jf/dexlib2/DexEntryFinderTest.java
index 610d3c76..9994e188 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/DexEntryFinderTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/DexEntryFinderTest.java
@@ -31,8 +31,8 @@
package org.jf.dexlib2;
-import com.beust.jcommander.internal.Maps;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.jf.dexlib2.DexFileFactory.DexEntryFinder;
import org.jf.dexlib2.DexFileFactory.DexFileNotFoundException;
import org.jf.dexlib2.DexFileFactory.MultipleMatchingDexEntriesException;
@@ -223,9 +223,5 @@ public class DexEntryFinderTest {
}
return null;
}
-
- @Nonnull @Override public Opcodes getOpcodes() {
- return Opcodes.getDefault();
- }
}
}
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/builder/LocatedItemsTest.java b/dexlib2/src/test/java/org/jf/dexlib2/builder/LocatedItemsTest.java
new file mode 100644
index 00000000..a1947997
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/dexlib2/builder/LocatedItemsTest.java
@@ -0,0 +1,46 @@
+package org.jf.dexlib2.builder;
+
+import com.google.common.collect.Sets;
+import org.jf.dexlib2.builder.debug.BuilderLineNumber;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocatedItemsTest {
+
+ private List<BuilderDebugItem> createItems(int count) {
+ List<BuilderDebugItem> items = new ArrayList<>();
+ for(int i = 0; i < count; ++i) {
+ items.add(new BuilderLineNumber(i));
+ }
+ return items;
+ }
+
+ private void doTestMergeIntoKeepsOrderOfDebugItems(int countLocation1, int countLocation2) {
+ MethodLocation location1 = new MethodLocation(null, 123, 1);
+ MethodLocation location2 = new MethodLocation(null, 456, 2);
+
+ List<BuilderDebugItem> items1 = createItems(countLocation1);
+ List<BuilderDebugItem> items2 = createItems(countLocation2);
+ location1.getDebugItems().addAll(items1);
+ location2.getDebugItems().addAll(items2);
+
+ location1.mergeInto(location2);
+
+ Assert.assertEquals(Sets.newHashSet(), location1.getDebugItems());
+ // items1 appear BEFORE items2
+ List<BuilderDebugItem> expectedItems = new ArrayList<>(items1);
+ expectedItems.addAll(items2);
+ Assert.assertEquals(expectedItems, new ArrayList<>(location2.getDebugItems()));
+ }
+
+ @Test
+ public void testMergeIntoKeepsOrderOfDebugItems() {
+ doTestMergeIntoKeepsOrderOfDebugItems(2, 2);
+ doTestMergeIntoKeepsOrderOfDebugItems(0, 0);
+ doTestMergeIntoKeepsOrderOfDebugItems(0, 2);
+ doTestMergeIntoKeepsOrderOfDebugItems(2, 0);
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/pool/RollbackTest.java b/dexlib2/src/test/java/org/jf/dexlib2/pool/RollbackTest.java
index 6074de14..87473bbf 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/pool/RollbackTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/pool/RollbackTest.java
@@ -84,7 +84,7 @@ public class RollbackTest {
dexPool.internClass(class2);
dexPool.reset();
dexPool.writeTo(dataStore);
- dexFile1 = new RawDexFile(Opcodes.getDefault(), dataStore.getData());
+ dexFile1 = new RawDexFile(Opcodes.getDefault(), dataStore.getBuffer());
}
RawDexFile dexFile2;
@@ -93,7 +93,7 @@ public class RollbackTest {
DexPool dexPool = new DexPool(Opcodes.getDefault());
dexPool.internClass(class1);
dexPool.writeTo(dataStore);
- dexFile2 = new RawDexFile(Opcodes.getDefault(), dataStore.getData());
+ dexFile2 = new RawDexFile(Opcodes.getDefault(), dataStore.getBuffer());
}
List<MapItem> mapItems1 = dexFile1.getMapItems();
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/CallSiteTest.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/CallSiteTest.java
new file mode 100644
index 00000000..c909fb28
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/CallSiteTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib2.writer;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.jf.dexlib2.*;
+import org.jf.dexlib2.builder.MethodImplementationBuilder;
+import org.jf.dexlib2.builder.instruction.BuilderInstruction35c;
+import org.jf.dexlib2.iface.ClassDef;
+import org.jf.dexlib2.iface.DexFile;
+import org.jf.dexlib2.iface.Method;
+import org.jf.dexlib2.iface.instruction.Instruction;
+import org.jf.dexlib2.iface.instruction.formats.Instruction35c;
+import org.jf.dexlib2.iface.reference.CallSiteReference;
+import org.jf.dexlib2.immutable.ImmutableClassDef;
+import org.jf.dexlib2.immutable.ImmutableDexFile;
+import org.jf.dexlib2.immutable.ImmutableMethod;
+import org.jf.dexlib2.immutable.ImmutableMethodImplementation;
+import org.jf.dexlib2.immutable.instruction.ImmutableInstruction35c;
+import org.jf.dexlib2.immutable.reference.ImmutableCallSiteReference;
+import org.jf.dexlib2.immutable.reference.ImmutableMethodHandleReference;
+import org.jf.dexlib2.immutable.reference.ImmutableMethodProtoReference;
+import org.jf.dexlib2.immutable.reference.ImmutableMethodReference;
+import org.jf.dexlib2.writer.builder.BuilderCallSiteReference;
+import org.jf.dexlib2.writer.builder.BuilderMethod;
+import org.jf.dexlib2.writer.builder.DexBuilder;
+import org.jf.dexlib2.writer.io.FileDataStore;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+public class CallSiteTest {
+ @Test
+ public void testPoolCallSite() throws IOException {
+ ClassDef class1 = new ImmutableClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null,
+ null, null,
+ Lists.<Method>newArrayList(
+ new ImmutableMethod("Lcls1", "method1",
+ ImmutableList.of(), "V", AccessFlags.PUBLIC.getValue(), null,
+ new ImmutableMethodImplementation(10, ImmutableList.of(
+ new ImmutableInstruction35c(Opcode.INVOKE_CUSTOM, 0, 0, 0, 0, 0, 0,
+ new ImmutableCallSiteReference("call_site_1",
+ new ImmutableMethodHandleReference(MethodHandleType.INVOKE_STATIC,
+ new ImmutableMethodReference("Lcls1", "loader",
+ ImmutableList.of("Ljava/lang/invoke/Lookup;",
+ "Ljava/lang/String;",
+ "Ljava/lang/invoke/MethodType;"),
+ "Ljava/lang/invoke/CallSite;")),
+ "someMethod", new ImmutableMethodProtoReference(ImmutableList.of(), "V"), ImmutableList.of()))
+ ), null, null))));
+
+ File tempFile = File.createTempFile("dex", ".dex");
+ DexFileFactory.writeDexFile(tempFile.getPath(),
+ new ImmutableDexFile(Opcodes.forArtVersion(111), ImmutableList.of(class1)));
+
+ verifyDexFile(DexFileFactory.loadDexFile(tempFile, Opcodes.forArtVersion(111)));
+ }
+
+ @Test
+ public void testBuilderCallSite() throws IOException {
+ DexBuilder dexBuilder = new DexBuilder(Opcodes.forArtVersion(111));
+
+ BuilderCallSiteReference callSite = dexBuilder.internCallSite(new ImmutableCallSiteReference("call_site_1",
+ new ImmutableMethodHandleReference(
+ MethodHandleType.INVOKE_STATIC,
+ new ImmutableMethodReference("Lcls1", "loader", ImmutableList.of("Ljava/lang/invoke/Lookup;",
+ "Ljava/lang/String;",
+ "Ljava/lang/invoke/MethodType;"),
+ "Ljava/lang/invoke/CallSite;")),
+ "someMethod",
+ new ImmutableMethodProtoReference(ImmutableList.of(), "V"), ImmutableList.of()));
+
+ MethodImplementationBuilder methodImplementationBuilder = new MethodImplementationBuilder(10);
+ methodImplementationBuilder.addInstruction(new BuilderInstruction35c(Opcode.INVOKE_CUSTOM, 0, 0, 0, 0, 0, 0,
+ callSite));
+
+ BuilderMethod method = dexBuilder.internMethod("Lcls1", "method1", null, "V", 0, ImmutableSet.of(),
+ methodImplementationBuilder.getMethodImplementation());
+ dexBuilder.internClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null,
+ ImmutableSet.of(), null,
+ ImmutableList.of(method));
+
+ File tempFile = File.createTempFile("dex", ".dex");
+ dexBuilder.writeTo(new FileDataStore(tempFile));
+
+ verifyDexFile(DexFileFactory.loadDexFile(tempFile, Opcodes.forArtVersion(111)));
+ }
+
+ private void verifyDexFile(DexFile dexFile) {
+ Assert.assertEquals(1, dexFile.getClasses().size());
+ ClassDef cls = Lists.newArrayList(dexFile.getClasses()).get(0);
+ Assert.assertEquals("Lcls1;", cls.getType());
+ Assert.assertEquals(1, Lists.newArrayList(cls.getMethods()).size());
+ Method method = Iterators.getNext(cls.getMethods().iterator(), null);
+ Assert.assertEquals("method1", method.getName());
+ Assert.assertEquals(1, Lists.newArrayList(method.getImplementation().getInstructions()).size());
+ Instruction instruction = Lists.newArrayList(method.getImplementation().getInstructions().iterator()).get(0);
+ Assert.assertEquals(Opcode.INVOKE_CUSTOM, instruction.getOpcode());
+ Assert.assertTrue(((Instruction35c) instruction).getReference() instanceof CallSiteReference);
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexDataWriterTest.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexDataWriterTest.java
index fee32d89..7ef574c1 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexDataWriterTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexDataWriterTest.java
@@ -34,7 +34,6 @@ package org.jf.dexlib2.writer;
import junit.framework.Assert;
import org.jf.dexlib2.ValueType;
import org.jf.util.ExceptionWithContext;
-import org.jf.util.NakedByteArrayOutputStream;
import org.junit.Before;
import org.junit.Test;
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterSleb128Test.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterSleb128Test.java
index b41cf461..ffcf96b7 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterSleb128Test.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterSleb128Test.java
@@ -32,7 +32,6 @@
package org.jf.dexlib2.writer;
import junit.framework.Assert;
-import org.jf.util.NakedByteArrayOutputStream;
import org.junit.Test;
import java.io.IOException;
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterTest.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterTest.java
index bf55e37f..fb65934f 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterTest.java
@@ -77,7 +77,7 @@ public class DexWriterTest {
throw new RuntimeException(ex);
}
- DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getData());
+ DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getBuffer());
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(dbClassDef);
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
@@ -117,7 +117,7 @@ public class DexWriterTest {
throw new RuntimeException(ex);
}
- DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getData());
+ DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getBuffer());
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(dbClassDef);
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterUleb128Test.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterUleb128Test.java
index bf993bcd..4fb1acb3 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterUleb128Test.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/DexWriterUleb128Test.java
@@ -32,7 +32,6 @@
package org.jf.dexlib2.writer;
import junit.framework.Assert;
-import org.jf.util.NakedByteArrayOutputStream;
import org.junit.Test;
import java.io.IOException;
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/JumboStringConversionTest.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/JumboStringConversionTest.java
index 340b1fa1..c64f3b29 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/writer/JumboStringConversionTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/JumboStringConversionTest.java
@@ -92,7 +92,7 @@ public class JumboStringConversionTest {
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
- DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getData());
+ DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getBuffer());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);
@@ -189,7 +189,7 @@ public class JumboStringConversionTest {
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
- DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getData());
+ DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getBuffer());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/writer/NakedByteArrayOutputStream.java b/dexlib2/src/test/java/org/jf/dexlib2/writer/NakedByteArrayOutputStream.java
new file mode 100644
index 00000000..ea1e6d72
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/dexlib2/writer/NakedByteArrayOutputStream.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib2.writer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * A ByteArrayOutputStream that lets you grab its protected bits.
+ */
+public class NakedByteArrayOutputStream extends ByteArrayOutputStream {
+ public byte[] getBuffer() throws IOException {
+ return buf;
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/util/AbstractForwardSequentialListTest.java b/dexlib2/src/test/java/org/jf/util/AbstractForwardSequentialListTest.java
new file mode 100644
index 00000000..6b52320d
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/util/AbstractForwardSequentialListTest.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2012, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.util;
+
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.annotation.Nonnull;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+public class AbstractForwardSequentialListTest {
+ private List<Integer> list;
+
+ @Before
+ public void setup() {
+ list = new AbstractForwardSequentialList<Integer>() {
+ @Nonnull @Override public Iterator<Integer> iterator() {
+ return new Iterator<Integer>() {
+ private int index = 0;
+
+ @Override public boolean hasNext() {
+ return index < 100;
+ }
+
+ @Override public Integer next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return index++;
+ }
+
+ @Override public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override public int size() {
+ return 100;
+ }
+ };
+ }
+
+ private void testForwardIterationImpl(ListIterator<Integer> iter) {
+ Assert.assertFalse(iter.hasPrevious());
+
+ for (int i=0; i<100; i++) {
+ Assert.assertEquals(i, iter.nextIndex());
+ Assert.assertEquals(i-1, iter.previousIndex());
+
+ Assert.assertTrue(iter.hasNext());
+
+ Assert.assertEquals(i, iter.next().intValue());
+ Assert.assertTrue(iter.hasPrevious());
+ }
+
+ Assert.assertFalse(iter.hasNext());
+ Assert.assertEquals(iter.nextIndex(), 100);
+ Assert.assertEquals(iter.previousIndex(), 99);
+ }
+
+ @Test
+ public void testForwardIteration() {
+ testForwardIterationImpl(list.listIterator());
+ }
+
+ private void testReverseIterationImpl(ListIterator<Integer> iter) {
+ Assert.assertFalse(iter.hasNext());
+
+ for (int i=99; i>=0; i--) {
+ Assert.assertEquals(i+1, iter.nextIndex());
+ Assert.assertEquals(i, iter.previousIndex());
+
+ Assert.assertTrue(iter.hasPrevious());
+
+ Assert.assertEquals(i, iter.previous().intValue());
+ Assert.assertTrue(iter.hasNext());
+ }
+
+ Assert.assertFalse(iter.hasPrevious());
+ Assert.assertEquals(0, iter.nextIndex());
+ Assert.assertEquals(-1, iter.previousIndex());
+ }
+
+ @Test
+ public void testReverseIteration() {
+ testReverseIterationImpl(list.listIterator(100));
+ }
+
+ @Test
+ public void testAlternatingIteration() {
+ ListIterator<Integer> iter = list.listIterator(50);
+
+ for (int i=0; i<10; i++) {
+ Assert.assertTrue(iter.hasNext());
+ Assert.assertTrue(iter.hasPrevious());
+ Assert.assertEquals(50, iter.nextIndex());
+ Assert.assertEquals(49, iter.previousIndex());
+
+ Assert.assertEquals(50, iter.next().intValue());
+
+ Assert.assertTrue(iter.hasNext());
+ Assert.assertTrue(iter.hasPrevious());
+ Assert.assertEquals(51, iter.nextIndex());
+ Assert.assertEquals(50, iter.previousIndex());
+
+ Assert.assertEquals(50, iter.previous().intValue());
+ }
+ }
+
+ @Test
+ public void testAlternatingIteration2() {
+ ListIterator<Integer> iter = list.listIterator(0);
+
+ for (int i=0; i<10; i++) {
+ testForwardIterationImpl(iter);
+ testReverseIterationImpl(iter);
+ }
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testNegativeIndex() {
+ list.listIterator(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testLargeIndex() {
+ list.listIterator(101);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testLargeIndex2() {
+ list.listIterator(1000000);
+ }
+
+ @Test
+ public void testForwardIterationException() {
+ // note: no "expected = NoSuchElementException", because we want to make sure the exception occurs only during
+ // the last call to next()
+
+ ListIterator<Integer> iter = list.listIterator(0);
+ for (int i=0; i<100; i++) {
+ iter.next();
+ }
+ try {
+ iter.next();
+ } catch (NoSuchElementException ex) {
+ return;
+ }
+ Assert.fail();
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testForwardIterationException2() {
+ ListIterator<Integer> iter = list.listIterator(100);
+ iter.next();
+ }
+
+ @Test
+ public void testReverseIterationException() {
+ // note: no "expected = NoSuchElementException", because we want to make sure the exception occurs only during
+ // the last call to previous()
+
+ ListIterator<Integer> iter = list.listIterator(100);
+ for (int i=0; i<100; i++) {
+ iter.previous();
+ }
+ try {
+ iter.previous();
+ } catch (NoSuchElementException ex) {
+ return;
+ }
+ Assert.fail();
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testReverseIterationException2() {
+ ListIterator<Integer> iter = list.listIterator(0);
+ iter.previous();
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/util/IndentingWriterTest.java b/dexlib2/src/test/java/org/jf/util/IndentingWriterTest.java
new file mode 100644
index 00000000..457262b5
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/util/IndentingWriterTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2013, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.util;
+
+import junit.framework.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class IndentingWriterTest {
+ @Test
+ public void testPrintSignedLongAsDec() throws IOException {
+ StringWriter stringWriter = new StringWriter();
+ IndentingWriter writer = new IndentingWriter(stringWriter);
+
+ writer.printUnsignedIntAsDec(-1);
+ writer.close();
+
+ Assert.assertEquals("4294967295", stringWriter.toString());
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/util/NumberUtilsTest.java b/dexlib2/src/test/java/org/jf/util/NumberUtilsTest.java
new file mode 100644
index 00000000..a059c87d
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/util/NumberUtilsTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2013, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.util;
+
+import junit.framework.Assert;
+import org.junit.Test;
+
+public class NumberUtilsTest {
+ @Test
+ public void isLikelyFloatTest() {
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1.23f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1.0f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(Float.NaN)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(Float.NEGATIVE_INFINITY)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(Float.POSITIVE_INFINITY)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1e-30f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1000f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(-1f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(-5f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1.3333f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(4.5f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(.1f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(50000f)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(Float.MAX_VALUE)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits((float)Math.PI)));
+ Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits((float)Math.E)));
+
+ Assert.assertTrue(NumberUtils.isLikelyFloat(2139095039));
+
+
+ // Float.MIN_VALUE is equivalent to integer value 1 - this should be detected as an integer
+ //Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(Float.MIN_VALUE)));
+
+ // This one doesn't quite work. It has a series of 2 0's, but that is probably not enough to strip off normally
+ //Assert.assertTrue(NumberUtils.isLikelyFloat(Float.floatToRawIntBits(1.33333f)));
+
+ Assert.assertFalse(NumberUtils.isLikelyFloat(0));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(1));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(10));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(100));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(1000));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(1024));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(1234));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(-5));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(-13));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(-123));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(20000000));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(2000000000));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(-2000000000));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(Integer.MAX_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(Integer.MIN_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(Short.MIN_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyFloat(Short.MAX_VALUE));
+ }
+
+ @Test
+ public void isLikelyDoubleTest() {
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1.23f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1.0f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Double.NaN)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Double.NEGATIVE_INFINITY)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Double.POSITIVE_INFINITY)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1e-30f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1000f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(-1f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(-5f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1.3333f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(1.33333f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(4.5f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(.1f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(50000f)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Double.MAX_VALUE)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Math.PI)));
+ Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Math.E)));
+
+ // Double.MIN_VALUE is equivalent to integer value 1 - this should be detected as an integer
+ //Assert.assertTrue(NumberUtils.isLikelyDouble(Double.doubleToRawLongBits(Double.MIN_VALUE)));
+
+ Assert.assertFalse(NumberUtils.isLikelyDouble(0));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(1));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(10));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(100));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(1000));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(1024));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(1234));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(-5));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(-13));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(-123));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(20000000));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(2000000000));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(-2000000000));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(Integer.MAX_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(Integer.MIN_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(Short.MIN_VALUE));
+ Assert.assertFalse(NumberUtils.isLikelyDouble(Short.MAX_VALUE));
+ }
+}
diff --git a/dexlib2/src/test/java/org/jf/util/StringWrapperTest.java b/dexlib2/src/test/java/org/jf/util/StringWrapperTest.java
new file mode 100644
index 00000000..94c79142
--- /dev/null
+++ b/dexlib2/src/test/java/org/jf/util/StringWrapperTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2013, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.util;
+
+import com.google.common.collect.Lists;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+public class StringWrapperTest {
+ @Test
+ public void testWrapStringByWords() {
+ validateResult2(new String[]{"abc", "abcdef", "abcdef"},
+ "abc\nabcdefabcdef", 6);
+
+ validateResult2(new String[]{"abc", "abcdef", " ", "abcdef"},
+ "abc\nabcdef abcdef", 6);
+
+ validateResult2(new String[]{"abc", "abcde ", "fabcde", "f"},
+ "abc\nabcde fabcdef", 6);
+
+ validateResult2(new String[]{"abc def ghi ", "kjl mon pqr ", "stu vwx yz"},
+ "abc def ghi kjl mon pqr stu vwx yz", 14);
+
+ validateResult2(new String[]{"abcdefg", "hikjlmo", "npqrstu", "vwxyz"},
+ "abcdefghikjlmonpqrstuvwxyz", 7);
+
+ validateResult2(new String[]{"abc", "defhig"},
+ "abc\ndefhig", 20);
+ }
+
+ @Test
+ public void testWrapString() {
+ validateResult(
+ new String[]{"abc", "abcdef", "abcdef"},
+ StringWrapper.wrapString("abc\nabcdefabcdef", 6, null));
+
+ validateResult(
+ new String[]{"abc"},
+ StringWrapper.wrapString("abc", 6, new String[3]));
+
+ validateResult(
+ new String[]{"abc"},
+ StringWrapper.wrapString("abc", 6, new String[0]));
+
+ validateResult(
+ new String[]{"abc"},
+ StringWrapper.wrapString("abc", 6, new String[1]));
+
+ validateResult(
+ new String[]{""},
+ StringWrapper.wrapString("", 6, new String[3]));
+
+ validateResult(
+ new String[]{"abcdef"},
+ StringWrapper.wrapString("abcdef", 6, new String[3]));
+
+ validateResult(
+ new String[]{"abcdef", "abcdef"},
+ StringWrapper.wrapString("abcdef\nabcdef", 6, new String[3]));
+
+ validateResult(
+ new String[]{"abc", "", "def"},
+ StringWrapper.wrapString("abc\n\ndef", 6, new String[3]));
+
+ validateResult(
+ new String[]{"", "abcdef"},
+ StringWrapper.wrapString("\nabcdef", 6, new String[3]));
+
+ validateResult(
+ new String[]{"", "", "abcdef"},
+ StringWrapper.wrapString("\n\nabcdef", 6, new String[3]));
+
+ validateResult(
+ new String[]{"", "", "abcdef"},
+ StringWrapper.wrapString("\n\nabcdef", 6, new String[4]));
+
+ validateResult(
+ new String[]{"", "", "abcdef", ""},
+ StringWrapper.wrapString("\n\nabcdef\n\n", 6, new String[4]));
+
+ validateResult(
+ new String[]{"", "", "abcdef", "a", ""},
+ StringWrapper.wrapString("\n\nabcdefa\n\n", 6, new String[4]));
+
+ validateResult(
+ new String[]{"", "", "abcdef", "a", ""},
+ StringWrapper.wrapString("\n\nabcdefa\n\n", 6, new String[0]));
+
+ validateResult(
+ new String[]{"", "", "abcdef", "a", ""},
+ StringWrapper.wrapString("\n\nabcdefa\n\n", 6, new String[5]));
+
+ validateResult(
+ new String[]{"", "", "a", "b", "c", "d", "e", "f", "a", ""},
+ StringWrapper.wrapString("\n\nabcdefa\n\n", 1, new String[5]));
+ }
+
+ public static void validateResult(String[] expected, String[] actual) {
+ Assert.assertTrue(actual.length >= expected.length);
+
+ int i;
+ for (i=0; i<actual.length; i++) {
+ if (actual[i] == null) {
+ Assert.assertTrue(i == expected.length);
+ return;
+ }
+ Assert.assertTrue(i < expected.length);
+ Assert.assertEquals(expected[i], actual[i]);
+ }
+ }
+
+ public static void validateResult2(String[] expected, String textToWrap, int maxWidth) {
+ List<String> result = Lists.newArrayList(StringWrapper.wrapStringOnBreaks(textToWrap, maxWidth));
+
+ Assert.assertEquals(expected.length, result.size());
+ int i;
+ for (i=0; i<result.size(); i++) {
+ Assert.assertTrue(i < expected.length);
+ Assert.assertEquals(expected[i], result.get(i));
+ }
+ }
+}