View Javadoc
1   package org.andromda.maven.plugin.cartridge;
2   
3   import java.io.File;
4   import java.util.List;
5   import junit.framework.TestCase;
6   import org.apache.commons.io.FileUtils;
7   import org.apache.commons.lang.StringUtils;
8   
9   /**
10   * Compares two files. It checks if both file do exist and if the contents of
11   * both files are equal.
12   *
13   * @author Chad Brandon
14   * @author Bob Fields
15   */
16  public class FileComparator
17          extends TestCase
18  {
19      private File expectedFile;
20      private File actualFile;
21      private boolean binary = false;
22      private boolean ignoreLineEndings = true;
23      private boolean ignoreWhitespace = false;
24      private List<String> ignoreLinesWithStrings = null;
25  
26      /**
27       * Constructs a new instance of the FileComparator.
28       *
29       * @param testName     the name of the test to run
30       * @param expectedFile the location of the expected file
31       * @param actualFile   the location of the actual file.
32       * @param binary       whether or not the file is binary, if it is binary contents
33       *                     of the binary are not compared as Strings but as binary files.
34       */
35      public FileComparator(
36              String testName,
37              File expectedFile,
38              File actualFile,
39              boolean binary)
40      {
41          super();
42          this.setName(testName);
43          this.expectedFile = expectedFile;
44          this.actualFile = actualFile;
45          this.binary = binary;
46      }
47  
48      /**
49       * Constructs a new instance of the FileComparator.
50       *
51       * @param testName the name of the test to run
52       * @param expectedFile the location of the expected file
53       * @param actualFile the location of the actual file.
54       * @param binary whether or not the file is binary, if it is binary contents
55       *        of the binary are not compared as Strings but as binary files.
56       * @param ignoreWhitespace Ignore whitespace in the comparison
57       * @param ignoreLineEndings Ignore Unix/Windows line ending differences \r vs \r\n
58       * @param ignoreLinesWithStrings Ignore lines containing the strings in the comparison
59       */
60      public FileComparator(
61          String testName,
62          File expectedFile,
63          File actualFile,
64          boolean binary,
65          boolean ignoreWhitespace,
66          boolean ignoreLineEndings,
67          List<String> ignoreLinesWithStrings)
68      {
69          this(testName, expectedFile, actualFile, binary);
70          this.ignoreWhitespace = ignoreWhitespace;
71          this.ignoreLineEndings = ignoreLineEndings;
72          this.ignoreLinesWithStrings = ignoreLinesWithStrings;
73      }
74  
75      /**
76       * Test if actual and expected file contents are equal.
77       */
78      public void testEquals()
79      {
80          assertTrue(
81                  "expected file <" + expectedFile.getPath() + "> doesn't exist",
82                  expectedFile.exists());
83          assertTrue(
84                  "actual file <" + actualFile.getPath() + "> doesn't exist",
85                  actualFile.exists());
86          this.testContentsEqual();
87      }
88  
89      /**
90       * Loads both the <code>actual</code> and <code>expected</code> files
91       * and tests the contents for equality.
92       */
93      protected void testContentsEqual()
94      {
95          try
96          {
97              String message = "actual file <" + actualFile + "> does not match\n";
98              if (this.binary)
99              {
100                 assertTrue(
101                         message,
102                         FileUtils.contentEquals(
103                                 expectedFile,
104                                 actualFile));
105             }
106             else
107             {
108                 String actualContents = FileUtils.readFileToString(actualFile);
109                 String expectedContents = FileUtils.readFileToString(expectedFile);
110                 //Ignore 'generated on ' date comments different between expected/actual
111                 // Sometimes it says 'Autogenerated on 04/22/2010 14:49:09-0400 by AndroMDA', sometimes it says 'Generated by ' XX cartridge
112                 // Remove the rest of the line from the comparison.
113                 if (this.ignoreLinesWithStrings != null && !this.ignoreLinesWithStrings.isEmpty())
114                 {
115                     expectedContents = removeLinesWithStrings(expectedContents, ignoreLinesWithStrings);
116                     actualContents = removeLinesWithStrings(actualContents, ignoreLinesWithStrings);
117                 }
118                 if (this.ignoreWhitespace)
119                 {
120                     expectedContents = StringUtils.remove(expectedContents, ' ');
121                     expectedContents = StringUtils.remove(expectedContents, '\t');
122                     actualContents = StringUtils.remove(actualContents, ' ');
123                     actualContents = StringUtils.remove(actualContents, '\t');
124                 }
125                 if (this.ignoreLineEndings)
126                 {
127                     expectedContents = StringUtils.remove(expectedContents, '\r');
128                     actualContents = StringUtils.remove(actualContents, '\r');
129                 }
130                 // TODO Tell me the line number where the difference is located.
131                 assertEquals(
132                         message,
133                         expectedContents.trim(),
134                         actualContents.trim());
135             }
136         }
137         catch (final Throwable throwable)
138         {
139             fail(throwable.toString());
140         }
141     }
142 
143     /**
144      * @param input
145      * @param patternList
146      * @return String input with the lines containing the string removed
147      */
148     public String removeLinesWithStrings(String input, List<String> patternList)
149     {
150         String tempString = input;
151         for (String pattern : patternList)
152         {
153             int patternIndex = tempString.indexOf(pattern);
154             while (patternIndex > 0)
155             {
156                 String temp = tempString.substring(patternIndex, tempString.length());
157                 temp = temp.substring(temp.indexOf('\n'));
158                 tempString = tempString.substring(0, patternIndex) + temp;
159                 patternIndex = tempString.indexOf(pattern);
160             }
161         }
162         return tempString;
163     }
164 
165     /**
166      * Gets the actual file being compared.
167      *
168      * @return the file being compared.
169      */
170     public File getActualFile()
171     {
172         return this.actualFile;
173     }
174 
175     /**
176      * Gets the file expected file (i.e. the file that
177      * the actual file is compared against).
178      *
179      * @return the expected file.
180      */
181     public File getExpectedFile()
182     {
183         return this.expectedFile;
184     }
185 }