View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.cpd;
    5
    6   import java.io.File;
    7
    8   import org.apache.commons.lang3.SystemUtils;
    9   import org.junit.Assert;
    10  import org.junit.Before;
    11  import org.junit.Test;
    12
    13  /**
    14   * Unit test for {@link CPD}
    15   */
    16  public class CPDTest {
    17
    18      private static final String BASE_TEST_RESOURCE_PATH = "target/test-classes/net/sourceforge/pmd/cpd/files/";
    19      private CPD cpd;
    20
    21      private boolean canTestSymLinks = false;
    22
    23      @Before
    24      public void setup() throws Exception {
    25          CPDConfiguration theConfiguration = new CPDConfiguration(new String[] {"--language", "java",
    26                  "--minimum-tokens", "10"});
    27          cpd = new CPD(theConfiguration);
    28
    29          // Symlinks are not well supported under Windows - so the tests are simply not executed here.
    30          canTestSymLinks = SystemUtils.IS_OS_UNIX;
    31          prepareSymLinks();
    32
    33          if (!canTestSymLinks) {
    34              System.err.println("*** Skipping unit tests with symlinks.");
    35          }
    36      }
    37
    38      /**
    39       * As java doesn't support symlinks in zip files, maven does not, too.
    40       * So, we are creating the symlinks manually here before the test.
    41       * @throws Exception any error
    42       */
    43      private void prepareSymLinks() throws Exception {
    44          if (canTestSymLinks) {
    45              Runtime runtime = Runtime.getRuntime();
    46              if (!new File(BASE_TEST_RESOURCE_PATH, "symlink-for-real-file.txt").exists()) {
    47                  runtime.exec(new String[] {"ln", "-s", "real-file.txt",
    48                          BASE_TEST_RESOURCE_PATH + "symlink-for-real-file.txt"}).waitFor();
    49              }
    50              if (!new File(BASE_TEST_RESOURCE_PATH, "this-is-a-broken-sym-link-for-test").exists()) {
    51                  runtime.exec(new String[] {"ln", "-s", "broken-sym-link",
    52                          BASE_TEST_RESOURCE_PATH + "this-is-a-broken-sym-link-for-test"}).waitFor();
    53              }
    54          }
    55      }
    56
    57      /**
    58       * A broken symlink (which is basically a not existing file), should be skipped.
    59       * @throws Exception any error
    60       */
    61      @Test
    62      public void testFileSectionWithBrokenSymlinks() throws Exception {
    63          if (canTestSymLinks) {
    64              NoFileAssertListener listener = new NoFileAssertListener(0);
    65              cpd.setCpdListener(listener);
    66
    67              cpd.add(new File(BASE_TEST_RESOURCE_PATH, "this-is-a-broken-sym-link-for-test"));
    68              listener.verify();
    69          }
    70      }
    71
    72      /**
    73       * A file should be added only once - even if it was found twice, because of a sym link.
    74       * @throws Exception any error
    75       */
    76      @Test
    77      public void testFileAddedAsSymlinkAndReal() throws Exception {
    78          if (canTestSymLinks) {
    79              NoFileAssertListener listener = new NoFileAssertListener(1);
    80              cpd.setCpdListener(listener);
    81
    82              cpd.add(new File(BASE_TEST_RESOURCE_PATH, "real-file.txt"));
    83              cpd.add(new File(BASE_TEST_RESOURCE_PATH, "symlink-for-real-file.txt"));
    84              listener.verify();
    85          }
    86      }
    87
    88      /**
    89       * Add a file with a relative path - should still be added and not be detected as a sym link.
    90       * @throws Exception any error
    91       */
    92      @Test
    93      public void testFileAddedWithRelativePath() throws Exception {
    94          NoFileAssertListener listener = new NoFileAssertListener(1);
    95          cpd.setCpdListener(listener);
    96
    97          cpd.add(new File("./" + BASE_TEST_RESOURCE_PATH, "real-file.txt"));
    98          listener.verify();
    99      }
    100
    101     /**
    102      * Simple listener that fails, if to many files were added and not skipped.
    103      */
    104     private static class NoFileAssertListener implements CPDListener {
    105         private int expectedFilesCount;
    106         private int files;
    107         public NoFileAssertListener(int expectedFilesCount) {
    108             this.expectedFilesCount = expectedFilesCount;
    109             this.files = 0;
    110         }
    111         public void addedFile(int fileCount, File file) {
    112             files++;
    113             if (files > expectedFilesCount) {
    114                 Assert.fail("File was added! - " + file);
    115             }
    116         }
    117         public void phaseUpdate(int phase) {
    118             // not needed for this test
    119         }
    120         public void verify() {
    121             Assert.assertEquals("Expected " + expectedFilesCount + " files, but " + files + " have been added.",
    122                     expectedFilesCount, files);
    123         }
    124     }
    125 }