package japicmp; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import japicmp.util.CtClassBuilder; import japicmp.util.CtConstructorBuilder; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.Assertion; import org.junit.contrib.java.lang.system.ExpectedSystemExit; import org.junit.contrib.java.lang.system.LogMode; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import static japicmp.cli.JApiCli.IGNORE_MISSING_CLASSES_BY_REGEX; import static japicmp.util.JarUtil.createJarFile; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; public class JApiCmpTest { @Rule public final ExpectedSystemExit exit = ExpectedSystemExit.none(); @Rule public final ErrLogRule errLog = new ErrLogRule(LogMode.LOG_ONLY); @Rule public final OutLogRule outLog = new OutLogRule(LogMode.LOG_ONLY); @Test public void testWithoutArguments() { exit.expectSystemExitWithStatus(1); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), containsString("E: Required option".trim())); assertThatUseHelpOptionIsPrinted(); } }); JApiCmp.main(new String[]{}); } private void assertThatUseHelpOptionIsPrinted() { assertThat(outLog.getLog(), containsString(JApiCmp.USE_HELP_OR_H_FOR_MORE_INFORMATION)); } private void assertThatHelpIsPrinted() { assertThat(outLog.getLog(), containsString("NAME")); assertThat(outLog.getLog(), containsString("SYNOPSIS")); assertThat(outLog.getLog(), containsString("OPTIONS")); } @Test public void testHelp() { exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), not(containsString("E: ".trim()))); assertThatHelpIsPrinted(); } }); JApiCmp.main(new String[]{"-h"}); } @Test public void testHelpLongOption() { exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), not(containsString("E: ".trim()))); assertThatHelpIsPrinted(); } }); JApiCmp.main(new String[]{"--help"}); } @Test public void testWithNewArchiveOptionButWithoutArgument() { exit.expectSystemExitWithStatus(128); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), containsString("E: Required values for option 'pathToNewVersionJar' not provided".trim())); assertThatUseHelpOptionIsPrinted(); } }); JApiCmp.main(new String[]{"-n"}); } @Test public void testWithOldArchiveOptionButWithoutArgument() { exit.expectSystemExitWithStatus(128); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), containsString("E: Required values for option 'pathToOldVersionJar' not provided".trim())); assertThatUseHelpOptionIsPrinted(); } }); JApiCmp.main(new String[]{"-o"}); } @Test public void testWithNewArchiveOptionButWithInvalidArgument() { exit.expectSystemExitWithStatus(1); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { String errLogTrimmed = errLog.getLog().trim(); assertThat(errLogTrimmed, containsString("E: File".trim())); assertThat(errLogTrimmed, containsString("does not exist.".trim())); assertThatUseHelpOptionIsPrinted(); } }); JApiCmp.main(new String[]{"-n", "xyz.jar", "-o", "zyx.jar"}); } @Test public void testWithOldArchiveOptionButWithInvalidArgument() { exit.expectSystemExitWithStatus(1); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { String errLogTrimmed = errLog.getLog().trim(); assertThat(errLogTrimmed, containsString("E: File".trim())); assertThat(errLogTrimmed, containsString("does not exist.".trim())); assertThatUseHelpOptionIsPrinted(); } }); JApiCmp.main(new String[]{"-n", pathTo("new.jar"), "-o", "xyz.jar"}); } @Test public void testWithOldArchiveOptionAndNewArchiveOption() { exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { assertThat(errLog.getLog().trim(), not(containsString("E: ".trim()))); } }); JApiCmp.main(new String[]{"-n", pathTo("new.jar"), "-o", pathTo("old.jar")}); } private String pathTo(String jarFileName) { return Paths.get(System.getProperty("user.dir"), "src", "test", "resources", jarFileName).toString(); } static void assertListsEquals(ImmutableList<String> expected, ImmutableList<String> actual) { Joiner nlJoiner = Joiner.on("\n"); assertEquals(nlJoiner.join(expected), nlJoiner.join(actual)); } @Test public void testIgnoreMissingClassesByRegExCouldNotLoad() throws IOException, CannotCompileException { exit.expectSystemExitWithStatus(1); exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { String errLogTrimmed = errLog.getLog().trim(); assertThat(errLogTrimmed, containsString("E: Could not load 'NotExistingSuperclass'".trim())); } }); ClassPool cp = new ClassPool(true); CtClass ctClassSuperclass = CtClassBuilder.create().name("NotExistingSuperclass").addToClassPool(cp); CtConstructorBuilder.create().addToClass(ctClassSuperclass); CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassSuperclass).addToClassPool(cp); Path oldPath = Paths.get(System.getProperty("user.dir"), "target", JApiCmpTest.class.getSimpleName() + "_old.jar"); createJarFile(oldPath, ctClass); Path newPath = Paths.get(System.getProperty("user.dir"), "target", JApiCmpTest.class.getSimpleName() + "_new.jar"); createJarFile(newPath, ctClass); JApiCmp.main(new String[]{"-n", newPath.toString(), "-o", oldPath.toString()}); } @Test public void testIgnoreMissingClassesByRegExMissingAreIgnore() throws IOException, CannotCompileException { exit.checkAssertionAfterwards(new Assertion() { public void checkAssertion() { String outLog = JApiCmpTest.this.outLog.getLog().trim(); assertThat(outLog, containsString("Comparing".trim())); assertThat(outLog, containsString("WARNING: You have ignored certain classes".trim())); } }); ClassPool cp = new ClassPool(true); CtClass ctClassSuperclass = CtClassBuilder.create().name("NotExistingSuperclass").addToClassPool(cp); CtConstructorBuilder.create().addToClass(ctClassSuperclass); CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassSuperclass).addToClassPool(cp); Path oldPath = Paths.get(System.getProperty("user.dir"), "target", JApiCmpTest.class.getSimpleName() + "_old.jar"); createJarFile(oldPath, ctClass); Path newPath = Paths.get(System.getProperty("user.dir"), "target", JApiCmpTest.class.getSimpleName() + "_new.jar"); createJarFile(newPath, ctClass); JApiCmp.main(new String[]{"-n", newPath.toString(), "-o", oldPath.toString(), IGNORE_MISSING_CLASSES_BY_REGEX, ".*Superc.*"}); } }