Commit ca21ca5d authored by Skylot's avatar Skylot

test: rewrite Spock tests to JUnit 5

parent 6e66dc25
...@@ -40,7 +40,6 @@ allprojects { ...@@ -40,7 +40,6 @@ allprojects {
testCompile 'ch.qos.logback:logback-classic:1.2.3' testCompile 'ch.qos.logback:logback-classic:1.2.3'
testCompile 'org.hamcrest:hamcrest-library:2.1' testCompile 'org.hamcrest:hamcrest-library:2.1'
testCompile 'org.mockito:mockito-core:2.25.1' testCompile 'org.mockito:mockito-core:2.25.1'
testCompile 'org.spockframework:spock-core:1.3-groovy-2.5'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.1' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.1'
......
...@@ -54,7 +54,4 @@ public class AType<T extends IAttribute> { ...@@ -54,7 +54,4 @@ public class AType<T extends IAttribute> {
public static final AType<DeclareVariablesAttr> DECLARE_VARIABLES = new AType<>(); public static final AType<DeclareVariablesAttr> DECLARE_VARIABLES = new AType<>();
public static final AType<LoopLabelAttr> LOOP_LABEL = new AType<>(); public static final AType<LoopLabelAttr> LOOP_LABEL = new AType<>();
public static final AType<IgnoreEdgeAttr> IGNORE_EDGE = new AType<>(); public static final AType<IgnoreEdgeAttr> IGNORE_EDGE = new AType<>();
private AType() {
}
} }
package jadx.tests
import jadx.core.dex.attributes.AType
import jadx.core.dex.attributes.AttributeStorage
import jadx.core.dex.attributes.IAttribute
import spock.lang.Specification
import static jadx.core.dex.attributes.AFlag.SYNTHETIC
class TestAttributeStorage extends Specification {
AttributeStorage storage
def setup() {
storage = new AttributeStorage()
}
def "add flag"() {
when:
storage.add(SYNTHETIC)
then:
storage.contains(SYNTHETIC)
}
def "remove flag"() {
setup:
storage.add(SYNTHETIC)
when:
storage.remove(SYNTHETIC)
then:
!storage.contains(SYNTHETIC)
}
def TEST = new AType<TestAttr>()
class TestAttr implements IAttribute {
AType<TestAttr> getType() { TEST }
}
def "add attribute"() {
setup:
def attr = new TestAttr()
when:
storage.add(attr)
then:
storage.contains(TEST)
storage.get(TEST) == attr
}
def "remove attribute"() {
setup:
def attr = new TestAttr()
storage.add(attr)
when:
storage.remove(attr)
then:
!storage.contains(TEST)
storage.get(TEST) == null
}
def "remove attribute other"() {
setup:
def attr = new TestAttr()
storage.add(attr)
when:
storage.remove(new TestAttr())
then:
storage.contains(TEST)
storage.get(TEST) == attr
}
def "clear"() {
setup:
storage.add(SYNTHETIC)
storage.add(new TestAttr())
when:
storage.clear()
then:
!storage.contains(SYNTHETIC)
!storage.contains(TEST)
}
}
package jadx.tests
import spock.lang.Specification
import static jadx.core.deobf.NameMapper.isValidFullIdentifier
class TestNameMapper extends Specification {
def "test is Valid Full Identifier"() {
expect:
isValidFullIdentifier(valid)
where:
valid << [
'C',
'Cc',
'b.C',
'b.Cc',
'aAa.b.Cc',
'a.b.Cc',
'a.b.C_c',
'a.b.C$c',
'a.b.C9'
]
}
def "test is not Valid Full Identifier"() {
expect:
!isValidFullIdentifier(invalid)
where:
invalid << [
'',
'5',
'7A',
'.C',
'b.9C',
'b..C',
]
}
}
package jadx.tests
import jadx.core.dex.instructions.args.ArgType
import jadx.core.dex.nodes.parser.SignatureParser
import spock.lang.Specification
import static jadx.core.dex.instructions.args.ArgType.*
class TestSignatureParser extends Specification {
def "simple types"() {
expect:
new SignatureParser(str).consumeType() == result
where:
str | result
"" | null
"I" | INT
"[I" | array(INT)
"Ljava/lang/Object;" | OBJECT
"[Ljava/lang/Object;" | array(OBJECT)
"[[I" | array(array(INT))
}
def "generics"() {
expect:
new SignatureParser(str).consumeType() == result
where:
str | result
"TD;" | genericType("D")
"La<TV;Lb;>;" | generic("La;", genericType("V"), object("b"))
"La<Lb<Lc;>;>;" | generic("La;", generic("Lb;", object("Lc;")))
"La/b/C<Ld/E<Lf/G;>;>;" | generic("La/b/C;", generic("Ld/E;", object("Lf/G;")))
"La<TD;>.c;" | genericInner(generic("La;", genericType("D")), "c", null)
"La<TD;>.c/d;" | genericInner(generic("La;", genericType("D")), "c.d", null)
"La<Lb;>.c<TV;>;" | genericInner(generic("La;", object("Lb;")), "c", genericType("V"))
}
def "inner generic"() {
expect:
new SignatureParser(str).consumeType().getObject() == result
where:
str | result
"La<TV;>.LinkedHashIterator<Lb\$c<Ls;TV;>;>;" | "a\$LinkedHashIterator"
}
def "wildcards"() {
expect:
new SignatureParser("La<$s>;").consumeType() == generic("La;", r as ArgType[])
where:
s | r
"*" | wildcard()
"+Lb;" | wildcard(object("b"), 1)
"-Lb;" | wildcard(object("b"), -1)
"+TV;" | wildcard(genericType("V"), 1)
"-TV;" | wildcard(genericType("V"), -1)
"**" | [wildcard(), wildcard()]
"*Lb;" | [wildcard(), object("b")]
"*TV;" | [wildcard(), genericType("V")]
"TV;*" | [genericType("V"), wildcard()]
"Lb;*" | [object("b"), wildcard()]
"***" | [wildcard(), wildcard(), wildcard()]
"*Lb;*" | [wildcard(), object("b"), wildcard()]
}
def "generic map"() {
expect:
new SignatureParser(str).consumeGenericMap() == result.collectEntries { [genericType(it.key), it.value] }
where:
str | result
"" | [:]
"<T:Ljava/lang/Object;>" | ["T": []]
"<K:Ljava/lang/Object;LongType:Ljava/lang/Object;>" | ["K": [], "LongType": []]
"<ResultT:Ljava/lang/Exception;:Ljava/lang/Object;>" | ["ResultT": [object("java.lang.Exception")]]
}
def "method args"() {
when:
def argTypes = new SignatureParser("(Ljava/util/List<*>;)V").consumeMethodArgs()
then:
argTypes.size() == 1
argTypes.get(0) == generic("Ljava/util/List;", wildcard())
}
def "method args 2"() {
when:
def argTypes = new SignatureParser("(La/b/C<TT;>.d/E;)V").consumeMethodArgs()
then:
argTypes.size() == 1
def argType = argTypes.get(0)
argType.getObject().indexOf('/') == -1
argTypes.get(0) == genericInner(generic("La/b/C;", genericType("T")), "d.E", null)
}
def "generic map: bad signature"() {
when:
def map = new SignatureParser("<A:Ljava/lang/Object;B").consumeGenericMap()
then:
notThrown(NullPointerException)
map.isEmpty()
}
}
package jadx.tests
import jadx.api.JadxArgs
import jadx.core.utils.StringUtils
import spock.lang.Specification
class TestStringUtils extends Specification {
def "unescape string"() {
def args = new JadxArgs()
args.setEscapeUnicode(true)
def stringUtils = new StringUtils(args)
expect:
stringUtils.unescapeString(input) == "\"$expected\""
where:
input | expected
"" | ""
"'" | "'"
"a" | "a"
"\n" | "\\n"
"\t" | "\\t"
"\r" | "\\r"
"\b" | "\\b"
"\f" | "\\f"
"\\" | "\\\\"
"\"" | "\\\""
"\u1234" | "\\u1234"
}
def "unescape char"() {
expect:
new StringUtils(new JadxArgs()).unescapeChar(input as char) == "'$expected'"
where:
input | expected
'a' | "a"
' ' | " "
'\n' | "\\n"
'\'' | "\\\'"
'\0' | "\\u0000"
}
}
package jadx.tests;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.Test;
public class TestsTest {
@Test
public void noJUnit4Asssertions() throws IOException {
noJUnit4Asssertions(".");
noJUnit4Asssertions("../jadx-cli");
noJUnit4Asssertions("../jadx-gui");
}
private void noJUnit4Asssertions(String path) throws IOException {
Path dir = Paths.get(path, "src/test/java");
assertTrue(Files.exists(dir));
Files.walk(dir)
.filter(p -> p.getFileName().toString().endsWith(".java")
&& !p.getFileName().toString().endsWith(TestsTest.class.getSimpleName() + ".java"))
.forEach(p -> {
try {
List<String> lines = Files.readAllLines(p);
for (String line : lines) {
if (line.contains("org.junit.Assert")) {
String className = dir.relativize(p).toString();
className = className.substring(0, className.length() - ".java".length());
className = className.replace(File.separatorChar, '.');
fail("Test class " + className + " should be migrated to JUnit 5");
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
package jadx.tests.functional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.AttributeStorage;
import jadx.core.dex.attributes.IAttribute;
import static jadx.core.dex.attributes.AFlag.SYNTHETIC;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
public class AttributeStorageTest {
private AttributeStorage storage;
@BeforeEach
public void setup() {
storage = new AttributeStorage();
}
@Test
public void testAdd() {
storage.add(SYNTHETIC);
assertThat(storage.contains(SYNTHETIC), is(true));
}
@Test
public void testRemove() {
storage.add(SYNTHETIC);
storage.remove(SYNTHETIC);
assertThat(storage.contains(SYNTHETIC), is(false));
}
public static final AType<TestAttr> TEST = new AType<>();
public static class TestAttr implements IAttribute {
@Override
public AType<TestAttr> getType() {
return TEST;
}
}
@Test
public void testAddAttribute() {
TestAttr attr = new TestAttr();
storage.add(attr);
assertThat(storage.contains(TEST), is(true));
assertThat(storage.get(TEST), is(attr));
}
@Test
public void testRemoveAttribute() {
TestAttr attr = new TestAttr();
storage.add(attr);
storage.remove(attr);
assertThat(storage.contains(TEST), is(false));
assertThat(storage.get(TEST), nullValue());
}
@Test
public void testRemoveOtherAttribute() {
TestAttr attr = new TestAttr();
storage.add(attr);
storage.remove(new TestAttr());
assertThat(storage.contains(TEST), is(true));
assertThat(storage.get(TEST), is(attr));
}
@Test
public void clear() {
storage.add(SYNTHETIC);
storage.add(new TestAttr());
storage.clear();
assertThat(storage.contains(SYNTHETIC), is(false));
assertThat(storage.contains(TEST), is(false));
assertThat(storage.get(TEST), nullValue());
}
}
package jadx.tests.functional;
import org.junit.jupiter.api.Test;
import jadx.core.deobf.NameMapper;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class NameMapperTest {
@Test
public void testValidFullIdentifiers() {
String[] validNames = {
"C",
"Cc",
"b.C",
"b.Cc",
"aAa.b.Cc",
"a.b.Cc",
"a.b.C_c",
"a.b.C$c",
"a.b.C9"
};
for (String validName : validNames) {
assertThat(NameMapper.isValidFullIdentifier(validName), is(true));
}
}
@Test
public void testInvalidFullIdentifiers() {
String[] invalidNames = {
"",
"5",
"7A",
".C",
"b.9C",
"b..C",
};
for (String invalidName : invalidNames) {
assertThat(NameMapper.isValidFullIdentifier(invalidName), is(false));
}
}
}
package jadx.tests.functional;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.parser.SignatureParser;
import static jadx.core.dex.instructions.args.ArgType.INT;
import static jadx.core.dex.instructions.args.ArgType.OBJECT;
import static jadx.core.dex.instructions.args.ArgType.array;
import static jadx.core.dex.instructions.args.ArgType.generic;
import static jadx.core.dex.instructions.args.ArgType.genericInner;
import static jadx.core.dex.instructions.args.ArgType.genericType;
import static jadx.core.dex.instructions.args.ArgType.object;
import static jadx.core.dex.instructions.args.ArgType.wildcard;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
class SignatureParserTest {
@Test
public void testSimpleTypes() {
checkType("", null);
checkType("I", INT);
checkType("[I", array(INT));
checkType("Ljava/lang/Object;", OBJECT);
checkType("[Ljava/lang/Object;", array(OBJECT));
checkType("[[I", array(array(INT)));
}
private static void checkType(String str, ArgType type) {
assertThat(new SignatureParser(str).consumeType(), is(type));
}
@Test
public void testGenerics() {
checkType("TD;", genericType("D"));
checkType("La<TV;Lb;>;", generic("La;", new ArgType[]{genericType("V"), object("b")}));
checkType("La<Lb<Lc;>;>;", generic("La;", new ArgType[]{generic("Lb;", new ArgType[]{object("Lc;")})}));
checkType("La/b/C<Ld/E<Lf/G;>;>;", generic("La/b/C;", new ArgType[]{generic("Ld/E;", new ArgType[]{object("Lf/G;")})}));
checkType("La<TD;>.c;", genericInner(generic("La;", new ArgType[]{genericType("D")}), "c", null));
checkType("La<TD;>.c/d;", genericInner(generic("La;", new ArgType[]{genericType("D")}), "c.d", null));
checkType("La<Lb;>.c<TV;>;", genericInner(generic("La;", new ArgType[]{object("Lb;")}), "c", new ArgType[]{genericType("V")}));
}
@Test
public void testInnerGeneric() {
String signature = "La<TV;>.LinkedHashIterator<Lb$c<Ls;TV;>;>;";
String objectStr = new SignatureParser(signature).consumeType().getObject();
assertThat(objectStr, is("a$LinkedHashIterator"));
}
@Test
public void testWildcards() {
checkWildcards("*", wildcard());
checkWildcards("+Lb;", wildcard(object("b"), 1));
checkWildcards("-Lb;", wildcard(object("b"), -1));
checkWildcards("+TV;", wildcard(genericType("V"), 1));
checkWildcards("-TV;", wildcard(genericType("V"), -1));
checkWildcards("**", wildcard(), wildcard());
checkWildcards("*Lb;", wildcard(), object("b"));
checkWildcards("*TV;", wildcard(), genericType("V"));
checkWildcards("TV;*", genericType("V"), wildcard());
checkWildcards("Lb;*", object("b"), wildcard());
checkWildcards("***", wildcard(), wildcard(), wildcard());
checkWildcards("*Lb;*", wildcard(), object("b"), wildcard());
}
private static void checkWildcards(String w, ArgType... types) {
ArgType parsedType = new SignatureParser("La<" + w + ">;").consumeType();
ArgType expectedType = generic("La;", types);
assertThat(parsedType, is(expectedType));
}
@Test
public void testGenericMap() {
checkGenerics("");
checkGenerics("<T:Ljava/lang/Object;>", "T", emptyList());
checkGenerics("<K:Ljava/lang/Object;LongType:Ljava/lang/Object;>", "K", emptyList(), "LongType", emptyList());
checkGenerics("<ResultT:Ljava/lang/Exception;:Ljava/lang/Object;>", "ResultT", singletonList(object("java.lang.Exception")));
}
@SuppressWarnings("unchecked")
private static void checkGenerics(String g, Object... objs) {
Map<ArgType, List<ArgType>> map = new SignatureParser(g).consumeGenericMap();
Map<ArgType, List<ArgType>> expectedMap = new LinkedHashMap<>();
for (int i = 0; i < objs.length; i += 2) {
ArgType generic = genericType((String) objs[i]);
List<ArgType> list = (List<ArgType>) objs[i + 1];
expectedMap.put(generic, list);
}
assertThat(map, is(expectedMap));
}
@Test
public void testMethodArgs() {
List<ArgType> argTypes = new SignatureParser("(Ljava/util/List<*>;)V").consumeMethodArgs();
assertThat(argTypes, hasSize(1));
assertThat(argTypes.get(0), is(generic("Ljava/util/List;", new ArgType[]{wildcard()})));
}
@Test
public void testMethodArgs2() {
List<ArgType> argTypes = new SignatureParser("(La/b/C<TT;>.d/E;)V").consumeMethodArgs();
assertThat(argTypes, hasSize(1));
ArgType argType = argTypes.get(0);
assertThat(argType.getObject().indexOf('/'), is(-1));
assertThat(argType, is(genericInner(generic("La/b/C;", new ArgType[]{genericType("T")}), "d.E", null)));
}
@Test
public void testBadGenericMap() {
Map<ArgType, List<ArgType>> map = new SignatureParser("<A:Ljava/lang/Object;B").consumeGenericMap();
assertThat(map, anEmptyMap());
}
}
package jadx.tests.functional;
import org.junit.jupiter.api.Test;
import jadx.api.JadxArgs;
import jadx.core.utils.StringUtils;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
class StringUtilsTest {
private StringUtils stringUtils;
@Test
public void testStringUnescape() {
JadxArgs args = new JadxArgs();
args.setEscapeUnicode(true);
stringUtils = new StringUtils(args);
checkStringUnescape("", "");
checkStringUnescape("'", "'");
checkStringUnescape("a", "a");
checkStringUnescape("\n", "\\n");
checkStringUnescape("\t", "\\t");
checkStringUnescape("\r", "\\r");
checkStringUnescape("\b", "\\b");
checkStringUnescape("\f", "\\f");
checkStringUnescape("\\", "\\\\");
checkStringUnescape("\"", "\\\"");
checkStringUnescape("\u1234", "\\u1234");
}
private void checkStringUnescape(String input, String result) {
assertThat(stringUtils.unescapeString(input), is("\"" + result + "\""));
}
@Test
public void testCharUnescape() {
stringUtils = new StringUtils(new JadxArgs());
checkCharUnescape('a', "a");
checkCharUnescape(' ', " ");
checkCharUnescape('\n', "\\n");
checkCharUnescape('\'', "\\\'");
checkCharUnescape('\0', "\\u0000");
}
private void checkCharUnescape(char input, String result) {
assertThat(stringUtils.unescapeChar(input), is("'" + result + "'"));
}
}
package jadx.tests.integration.loops; package jadx.tests.integration.loops;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import jadx.NotYetImplemented; import jadx.NotYetImplemented;
import jadx.NotYetImplementedExtension;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
......
package jadx.gui.tests
import jadx.gui.utils.JumpManager
import jadx.gui.utils.JumpPosition
import spock.lang.Specification
class TestJumpManager extends Specification {
JumpManager jm
def setup() {
jm = new JumpManager()
}
def "empty history"() {
expect:
jm.getPrev() == null
jm.getNext() == null
}
def "empty history 2"() {
expect:
jm.getPrev() == null
jm.getNext() == null
jm.getPrev() == null
jm.getNext() == null
jm.getPrev() == null
}
def "1 element"() {
when:
jm.addPosition(Mock(JumpPosition))
then:
jm.getPrev() == null
jm.getNext() == null
}
def "2 elements"() {
when:
def mock1 = Mock(JumpPosition)
jm.addPosition(mock1)
def mock2 = Mock(JumpPosition)
jm.addPosition(mock2)
// 1 - 2@
then:
noExceptionThrown()
jm.getPrev() == mock1
jm.getPrev() == null
jm.getNext() == mock2
jm.getNext() == null
}
def "navigation"() {
expect:
def mock1 = Mock(JumpPosition)
jm.addPosition(mock1)
// 1@
def mock2 = Mock(JumpPosition)
jm.addPosition(mock2)
// 1 - 2@
jm.getPrev() == mock1
// 1@ - 2
def mock3 = Mock(JumpPosition)
jm.addPosition(mock3)
// 1 - 3@
jm.getNext() == null
jm.getPrev() == mock1
// 1@ - 3
jm.getNext() == mock3
}
def "navigation2"() {
expect:
def mock1 = Mock(JumpPosition)
jm.addPosition(mock1)
// 1@
def mock2 = Mock(JumpPosition)
jm.addPosition(mock2)
// 1 - 2@
def mock3 = Mock(JumpPosition)
jm.addPosition(mock3)
// 1 - 2 - 3@
def mock4 = Mock(JumpPosition)
jm.addPosition(mock4)
// 1 - 2 - 3 - 4@
jm.getPrev() == mock3
// 1 - 2 - 3@ - 4
jm.getPrev() == mock2
// 1 - 2@ - 3 - 4
def mock5 = Mock(JumpPosition)
jm.addPosition(mock5)
// 1 - 2 - 5@
jm.getNext() == null
jm.getNext() == null
jm.getPrev() == mock2
// 1 - 2@ - 5
jm.getPrev() == mock1
// 1@ - 2 - 5
jm.getPrev() == null
jm.getNext() == mock2
// 1 - 2@ - 5
jm.getNext() == mock5
// 1 - 2 - 5@
jm.getNext() == null
}
def "add same element"() {
when:
def mock = Mock(JumpPosition)
jm.addPosition(mock)
jm.addPosition(mock)
then:
noExceptionThrown()
jm.getPrev() == null
jm.getNext() == null
}
}
package jadx.gui.tests
import jadx.gui.utils.search.StringRef
import spock.lang.Specification
import static jadx.gui.utils.search.StringRef.fromStr
import static jadx.gui.utils.search.StringRef.subString
class TestStringRef extends Specification {
def "test substring"() {
expect:
s1.toString() == expected
s1 == fromStr(expected)
where:
s1 | expected
fromStr("a") | "a"
subString("a", 0) | "a"
subString("a", 1) | ""
subString("a", 0, 0) | ""
subString("a", 0, 1) | "a"
subString("abc", 1, 2) | "b"
subString("abc", 2) | "c"
subString("abc", 2, 3) | "c"
}
def "compare with original substring"() {
expect:
s == expected
where:
s | expected
"a".substring(0) | "a"
"a".substring(1) | ""
"a".substring(0, 0) | ""
"a".substring(0, 1) | "a"
}
def "test trim"() {
expect:
s.trim().toString() == expected
where:
s | expected
fromStr("a") | "a"
fromStr(" a ") | "a"
fromStr("\ta") | "a"
subString("a b c", 1) | "b c"
subString("a b\tc", 1, 4) | "b"
subString("a b\tc", 2, 3) | "b"
}
def "test split"() {
expect:
StringRef.split(s, d) == (expected as String[]).collect { fromStr(it) }
if (!Arrays.equals(s.split(d), (expected).toArray(new String[0]))) {
throw new IllegalArgumentException("Don't match with original split: "
+ " s='" + s + "' d='" + d
+ "', expected:" + expected + ", got: " + Arrays.toString(s.split(d)));
}
where:
s | d | expected
"abc" | "b" | ["a", "c"]
"abc" | "a" | ["", "bc"]
"abc" | "c" | ["ab"]
"abc" | "d" | ["abc"]
"abbbc" | "b" | ["a", "", "", "c"]
"abbbc" | "bb" | ["a", "bc"]
"abbbc" | "bbb" | ["a", "c"]
"abbbc" | "bbc" | ["ab"]
"abbbc" | "bbbc" | ["a"]
}
}
package jadx.gui.tests
import jadx.gui.update.VersionComparator
import spock.lang.Specification
class TestVersionsComparator extends Specification {
def "test"() {
expect:
VersionComparator.compare(s1, s2) == expected
VersionComparator.compare(s2, s1) == -expected
where:
s1 | s2 | expected
"" | "" | 0
"1" | "1" | 0
"1" | "2" | -1
"1.1" | "1.1" | 0
"0.5" | "0.5" | 0
"0.5" | "0.5.0" | 0
"0.5" | "0.5.00" | 0
"0.5" | "0.5.0.0" | 0
"0.5" | "0.5.0.1" | -1
"0.5.0" | "0.5.0" | 0
"0.5.0" | "0.5.1" | -1
"0.5" | "0.5.1" | -1
"0.4.8" | "0.5" | -1
"0.4.8" | "0.5.0" | -1
"0.4.8" | "0.6" | -1
}
}
package jadx.gui.update;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
class VersionComparatorTest {
@Test
public void testCompare() {
checkCompare("", "", 0);
checkCompare("1", "1", 0);
checkCompare("1", "2", -1);
checkCompare("1.1", "1.1", 0);
checkCompare("0.5", "0.5", 0);
checkCompare("0.5", "0.5.0", 0);
checkCompare("0.5", "0.5.00", 0);
checkCompare("0.5", "0.5.0.0", 0);
checkCompare("0.5", "0.5.0.1", -1);
checkCompare("0.5.0", "0.5.0", 0);
checkCompare("0.5.0", "0.5.1", -1);
checkCompare("0.5", "0.5.1", -1);
checkCompare("0.4.8", "0.5", -1);
checkCompare("0.4.8", "0.5.0", -1);
checkCompare("0.4.8", "0.6", -1);
}
private static void checkCompare(String a, String b, int result) {
assertThat(VersionComparator.compare(a, b), is(result));
assertThat(VersionComparator.compare(b, a), is(-result));
}
}
package jadx.gui.utils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jadx.gui.treemodel.TextNode;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
class JumpManagerTest {
private JumpManager jm;
@BeforeEach
public void setup() {
jm = new JumpManager();
}
@Test
public void testEmptyHistory() {
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), nullValue());
}
@Test
public void testEmptyHistory2() {
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), nullValue());
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), nullValue());
assertThat(jm.getPrev(), nullValue());
}
@Test
public void testOneElement() {
jm.addPosition(makeJumpPos());
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), nullValue());
}
@Test
public void testTwoElements() {
JumpPosition pos1 = makeJumpPos();
jm.addPosition(pos1);
JumpPosition pos2 = makeJumpPos();
jm.addPosition(pos2);
assertThat(jm.getPrev(), sameInstance(pos1));
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), sameInstance(pos2));
assertThat(jm.getNext(), nullValue());
}
@Test
public void testNavigation() {
JumpPosition pos1 = makeJumpPos();
jm.addPosition(pos1);
// 1@
JumpPosition pos2 = makeJumpPos();
jm.addPosition(pos2);
// 1 - 2@
assertThat(jm.getPrev(), sameInstance(pos1));
// 1@ - 2
JumpPosition pos3 = makeJumpPos();
jm.addPosition(pos3);
// 1 - 3@
assertThat(jm.getNext(), nullValue());
assertThat(jm.getPrev(), sameInstance(pos1));
// 1@ - 3
assertThat(jm.getNext(), sameInstance(pos3));
}
@Test
public void testNavigation2() {
JumpPosition pos1 = makeJumpPos();
jm.addPosition(pos1);
// 1@
JumpPosition pos2 = makeJumpPos();
jm.addPosition(pos2);
// 1 - 2@
JumpPosition pos3 = makeJumpPos();
jm.addPosition(pos3);
// 1 - 2 - 3@
JumpPosition pos4 = makeJumpPos();
jm.addPosition(pos4);
// 1 - 2 - 3 - 4@
assertThat(jm.getPrev(), sameInstance(pos3));
// 1 - 2 - 3@ - 4
assertThat(jm.getPrev(), sameInstance(pos2));
// 1 - 2@ - 3 - 4
JumpPosition pos5 = makeJumpPos();
jm.addPosition(pos5);
// 1 - 2 - 5@
assertThat(jm.getNext(), nullValue());
assertThat(jm.getNext(), nullValue());
assertThat(jm.getPrev(), sameInstance(pos2));
// 1 - 2@ - 5
assertThat(jm.getPrev(), sameInstance(pos1));
// 1@ - 2 - 5
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), sameInstance(pos2));
// 1 - 2@ - 5
assertThat(jm.getNext(), sameInstance(pos5));
// 1 - 2 - 5@
assertThat(jm.getNext(), nullValue());
}
@Test
public void addSame() {
JumpPosition pos = makeJumpPos();
jm.addPosition(pos);
jm.addPosition(pos);
assertThat(jm.getPrev(), nullValue());
assertThat(jm.getNext(), nullValue());
}
private JumpPosition makeJumpPos() {
return new JumpPosition(new TextNode(""), 0);
}
}
package jadx.gui.utils.search;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import static jadx.gui.utils.search.StringRef.fromStr;
import static jadx.gui.utils.search.StringRef.subString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
class StringRefTest {
@Test
public void testConvert() {
assertThat(fromStr("a").toString(), is("a"));
}
@Test
public void testSubstring() {
checkStr(subString("a", 0), "a");
checkStr(subString("a", 1), "");
checkStr(subString("a", 0, 0), "");
checkStr(subString("a", 0, 1), "a");
checkStr(subString("abc", 1, 2), "b");
checkStr(subString("abc", 2), "c");
checkStr(subString("abc", 2, 3), "c");
}
public static void checkStr(StringRef ref, String str) {
assertThat(ref.toString(), is(str));
assertThat(ref, is(fromStr(str)));
}
@Test
public void testTrim() {
checkTrim(fromStr("a"), "a");
checkTrim(fromStr(" a "), "a");
checkTrim(fromStr("\ta"), "a");
checkTrim(subString("a b c", 1), "b c");
checkTrim(subString("a b\tc", 1, 4), "b");
checkTrim(subString("a b\tc", 2, 3), "b");
}
private static void checkTrim(StringRef ref, String result) {
assertThat(ref.trim().toString(), is(result));
}
@Test
public void testSplit() {
checkSplit("abc", "b", "a", "c");
checkSplit("abc", "a", "", "bc");
checkSplit("abc", "c", "ab");
checkSplit("abc", "d", "abc");
checkSplit("abbbc", "b", "a", "", "", "c");
checkSplit("abbbc", "bb", "a", "bc");
checkSplit("abbbc", "bbb", "a", "c");
checkSplit("abbbc", "bbc", "ab");
checkSplit("abbbc", "bbbc", "a");
}
private static void checkSplit(String str, String splitBy, String... result) {
List<StringRef> expectedStringRegList = Arrays.stream(result).map(StringRef::fromStr).collect(Collectors.toList());
assertThat(StringRef.split(str, splitBy), is(expectedStringRegList));
// compare with original split
assertThat(str.split(splitBy), is(result));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment