/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.cpd; import java.io.File; import org.apache.commons.lang3.SystemUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Unit test for {@link CPD} */ public class CPDTest { private static final String BASE_TEST_RESOURCE_PATH; static { if (new File("target/clover/test-classes").exists()) { BASE_TEST_RESOURCE_PATH = "target/clover/test-classes/net/sourceforge/pmd/cpd/files/"; } else { BASE_TEST_RESOURCE_PATH = "target/test-classes/net/sourceforge/pmd/cpd/files/"; } } private CPD cpd; private boolean canTestSymLinks = false; @Before public void setup() throws Exception { CPDConfiguration theConfiguration = new CPDConfiguration(); theConfiguration.postContruct(); cpd = new CPD(theConfiguration); // Symlinks are not well supported under Windows - so the tests are // simply not executed here. canTestSymLinks = SystemUtils.IS_OS_UNIX; prepareSymLinks(); if (!canTestSymLinks) { System.err.println("*** Skipping unit tests with symlinks."); } } /** * As java doesn't support symlinks in zip files, maven does not, too. So, * we are creating the symlinks manually here before the test. * * @throws Exception * any error */ private void prepareSymLinks() throws Exception { if (canTestSymLinks) { Runtime runtime = Runtime.getRuntime(); if (!new File(BASE_TEST_RESOURCE_PATH, "symlink-for-real-file.txt").exists()) { runtime.exec(new String[] { "ln", "-s", "real-file.txt", BASE_TEST_RESOURCE_PATH + "symlink-for-real-file.txt", }).waitFor(); } if (!new File(BASE_TEST_RESOURCE_PATH, "this-is-a-broken-sym-link-for-test").exists()) { runtime.exec(new String[] { "ln", "-s", "broken-sym-link", BASE_TEST_RESOURCE_PATH + "this-is-a-broken-sym-link-for-test", }).waitFor(); } } } /** * A broken symlink (which is basically a not existing file), should be * skipped. * * @throws Exception * any error */ @Test public void testFileSectionWithBrokenSymlinks() throws Exception { if (canTestSymLinks) { NoFileAssertListener listener = new NoFileAssertListener(0); cpd.setCpdListener(listener); cpd.add(new File(BASE_TEST_RESOURCE_PATH, "this-is-a-broken-sym-link-for-test")); listener.verify(); } } /** * A file should be added only once - even if it was found twice, because of * a sym link. * * @throws Exception * any error */ @Test public void testFileAddedAsSymlinkAndReal() throws Exception { if (canTestSymLinks) { NoFileAssertListener listener = new NoFileAssertListener(1); cpd.setCpdListener(listener); cpd.add(new File(BASE_TEST_RESOURCE_PATH, "real-file.txt")); cpd.add(new File(BASE_TEST_RESOURCE_PATH, "symlink-for-real-file.txt")); listener.verify(); } } /** * Add a file with a relative path - should still be added and not be * detected as a sym link. * * @throws Exception * any error */ @Test public void testFileAddedWithRelativePath() throws Exception { NoFileAssertListener listener = new NoFileAssertListener(1); cpd.setCpdListener(listener); cpd.add(new File("./" + BASE_TEST_RESOURCE_PATH, "real-file.txt")); listener.verify(); } /** * Simple listener that fails, if to many files were added and not skipped. */ private static class NoFileAssertListener implements CPDListener { private int expectedFilesCount; private int files; NoFileAssertListener(int expectedFilesCount) { this.expectedFilesCount = expectedFilesCount; this.files = 0; } @Override public void addedFile(int fileCount, File file) { files++; if (files > expectedFilesCount) { Assert.fail("File was added! - " + file); } } @Override public void phaseUpdate(int phase) { // not needed for this test } public void verify() { Assert.assertEquals("Expected " + expectedFilesCount + " files, but " + files + " have been added.", expectedFilesCount, files); } } }