View Javadoc
1   /*
2    * The baseCode project
3    * 
4    * Copyright (c) 2006 University of British Columbia
5    * 
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   *
18   */
19  package ubic.basecode.util;
20  
21  import java.io.BufferedReader;
22  import java.io.BufferedWriter;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileOutputStream;
26  import java.io.FileReader;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.InputStreamReader;
30  import java.io.OutputStreamWriter;
31  import java.io.StringReader;
32  import java.util.ArrayList;
33  import java.util.Collection;
34  import java.util.List;
35  
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  import cern.colt.list.DoubleArrayList;
40  import cern.colt.matrix.DoubleMatrix1D;
41  import cern.colt.matrix.DoubleMatrix2D;
42  import ubic.basecode.dataStructure.matrix.DoubleMatrix;
43  
44  /**
45   * Tools to help make regression testing easier, but also useful for other purposes.
46   * 
47   * @author pavlidis
48   * 
49   */
50  public class RegressionTesting {
51  
52      private static Logger log = LoggerFactory.getLogger( RegressionTesting.class );
53  
54      /**
55       * @param expected
56       * @param actual
57       * @param tolerance permitted delta between the values
58       */
59      public static boolean closeEnough( double[] expected, double[] actual, double tolerance ) {
60          if ( expected.length != actual.length ) return false;
61  
62          for ( int i = 0; i < expected.length; i++ ) {
63              if ( Math.abs( expected[i] - actual[i] ) > tolerance ) {
64                  log.error( "Expected " + expected[i] + " got " + actual[i] + " at " + i );
65                  return false;
66              }
67          }
68          return true;
69  
70      }
71  
72      // private String resourcePath = "";
73  
74      /**
75       * Test whether two DoubleArrayLists are 'close enough' to call equal.
76       * 
77       * @param expected
78       * @param actual
79       * @param tolerance
80       * @return
81       */
82      public static boolean closeEnough( DoubleArrayList expected, DoubleArrayList actual, double tolerance ) {
83          if ( expected.size() != actual.size() ) return false;
84  
85          for ( int i = 0; i < expected.size(); i++ ) {
86              if ( Math.abs( expected.get( i ) - actual.get( i ) ) > tolerance ) return false;
87          }
88          return true;
89      }
90  
91      /**
92       * Test whether two AbstractNamedDoubleMatrix are 'close enough' to call equal.
93       * 
94       * @param expected
95       * @param actual
96       * @param tolerance
97       * @return try if all the values in both matrices are within 'tolerance' of each other.
98       */
99      public static boolean closeEnough( DoubleMatrix<?, ?> expected, DoubleMatrix<?, ?> actual, double tolerance ) {
100         if ( expected.rows() != actual.rows() || expected.columns() != actual.columns() ) {
101             log.error( "Unequal rows and/or columns" );
102             return false;
103         }
104 
105         for ( int i = 0; i < expected.rows(); i++ ) {
106             for ( int j = 0; j < expected.columns(); j++ ) {
107                 if ( Math.abs( expected.get( i, j ) - actual.get( i, j ) ) > tolerance ) {
108                     log.error( "Expected: " + expected.get( i, j ) + ", actual=" + actual.get( i, j ) );
109                     return false;
110                 }
111             }
112         }
113         return true;
114     }
115 
116     /**
117      * @param expected
118      * @param actual
119      * @param tolerance
120      * @return
121      */
122     public static boolean closeEnough( DoubleMatrix1D expected, DoubleMatrix1D actual, double tolerance ) {
123         return closeEnough(expected.toArray(), actual.toArray(), tolerance );
124     }
125 
126     public static boolean closeEnough( DoubleMatrix2D a, DoubleMatrix2D b, double tolerance ) {
127         if ( a.rows() != b.rows() || a.columns() != b.columns() ) return false;
128 
129         for ( int i = 0; i < a.rows(); i++ ) {
130             for ( int j = 0; j < a.columns(); j++ ) {
131                 if ( Math.abs( a.get( i, j ) - b.get( i, j ) ) > tolerance ) return false;
132             }
133         }
134         return true;
135     }
136 
137     /**
138      * Test whether two object arrays are the same.
139      * 
140      * @param a
141      * @param b
142      * @return
143      */
144     public static boolean closeEnough( Object[] a, Object[] b ) {
145         if ( a.length != b.length ) {
146             return false;
147         }
148 
149         for ( int i = 0; i < a.length; i++ ) {
150             if ( !a[i].equals( b[i] ) ) {
151                 return false;
152             }
153         }
154         return true;
155     }
156 
157     /**
158      * Test whether two collections contain the same items.
159      * 
160      * @param a
161      * @param b
162      * @return
163      */
164     public static boolean containsSame( Collection<? extends Object> a, Collection<? extends Object> b ) {
165         if ( a.size() != b.size() ) return false;
166 
167         if ( !a.containsAll( b ) ) return false;
168 
169         return true;
170     }
171 
172     /**
173      * Test whether two double arrays contain the same items in any order (tolerance is ZERO)
174      * 
175      * @param a
176      * @param b
177      * @return
178      */
179     public static boolean containsSame( double[] a, double[] b ) {
180         if ( a.length != b.length ) return false;
181 
182         List<Double> av = new ArrayList<Double>( a.length );
183         List<Double> bv = new ArrayList<Double>( b.length );
184         for ( int i = 0; i < b.length; i++ ) {
185             av.add( new Double( a[i] ) );
186             bv.add( new Double( b[i] ) );
187         }
188 
189         return av.containsAll( bv );
190     }
191 
192     /**
193      * Test whether two object arrays contain the same items in any order. The arrays are treated as Sets - repeats are
194      * not considered.
195      * 
196      * @param a
197      * @param b
198      * @return
199      */
200     public static boolean containsSame( Object[] a, Object[] b ) {
201         if ( a.length != b.length ) return false;
202 
203         List<Object> av = new ArrayList<Object>( a.length );
204         List<Object> bv = new ArrayList<Object>( b.length );
205 
206         for ( int i = 0; i < b.length; i++ ) {
207             av.add( a[i] );
208             bv.add( b[i] );
209         }
210 
211         return av.containsAll( bv );
212 
213     }
214 
215     /**
216      * @param file
217      * @return
218      * @throws IOException
219      */
220     public static String readTestResult( File file ) throws IOException {
221         BufferedReader buf = new BufferedReader( new FileReader( file ) );
222         String line = "";
223         StringBuffer testOutput = new StringBuffer( line );
224         while ( ( line = buf.readLine() ) != null ) {
225             testOutput.append( line + "\n" );
226         }
227         buf.close();
228         return testOutput.toString();
229     }
230 
231     /**
232      * @param istream
233      * @return
234      * @throws IOException
235      */
236     public static String readTestResult( InputStream istream ) throws IOException {
237         if ( istream == null ) {
238             throw new IllegalStateException( "Null stream" );
239         }
240 
241         BufferedReader buf = new BufferedReader( new InputStreamReader( istream ) );
242         String line = "";
243         StringBuffer testOutput = new StringBuffer( line );
244         while ( ( line = buf.readLine() ) != null ) {
245             testOutput.append( line + "\n" );
246         }
247         buf.close();
248         return testOutput.toString();
249     }
250 
251     /**
252      * @param resourceName
253      * @return the contents of the resource as a String
254      * @throws IOException
255      */
256     public static String readTestResult( String resourceName ) throws IOException {
257         InputStream istream = RegressionTesting.class.getResourceAsStream( resourceName );
258 
259         if ( istream == null ) return null;
260 
261         String result = readTestResult( istream );
262         istream.close();
263         return result;
264 
265     }
266 
267     /**
268      * @throws IOException
269      * @param fileName - the full path of the file to be read.
270      * @return
271      */
272     @SuppressWarnings("resource")
273     public static String readTestResultFromFile( String fileName ) throws IOException {
274         InputStream is = new FileInputStream( fileName );
275         return readTestResult( is );
276     }
277 
278     /**
279      * Test whether two double arrays contain the same items in the same order
280      * 
281      * @param a
282      * @param b
283      * @return
284      */
285     public static boolean sameArray( int[] a, int[] b ) {
286         if ( a.length != b.length ) return false;
287         for ( int i = 0; i < b.length; i++ ) {
288             if ( b[i] != a[i] ) return false;
289         }
290         return true;
291     }
292 
293     public static void writeTestResult( String result, String fileName ) throws IOException {
294 
295         BufferedWriter buf = new BufferedWriter(
296                 new OutputStreamWriter( new FileOutputStream( new File( fileName ) ) ) );
297         BufferedReader resultBuf = new BufferedReader( new StringReader( result ) );
298 
299         String line = null;
300         while ( ( line = resultBuf.readLine() ) != null ) {
301             buf.write( line + "\n" );
302         }
303         buf.close();
304         resultBuf.close();
305     }
306 
307     private RegressionTesting() { /* block instantiation */
308     }
309 
310     /**
311      * Convenience for using Stuart D. Gathman's Diff.
312      * 
313      * @param expected String
314      * @param actual String
315      * @return String edit list
316      */
317     /**
318      * public static String regress( String expected, String actual ) { Diff diff = new Diff( new Object[] {expected} ,
319      * new Object[] {actual} ); Diff.change script = diff.diff_2( false ); DiffPrint.Base p = new
320      * DiffPrint.UnifiedPrint( new Object[] {expected} , new Object[] {actual} ); StringWriter wtr = new StringWriter();
321      * p.setOutput( wtr ); p.print_script( script ); return wtr.toString(); }
322      */
323 
324 }