/*
 * LensKit, an open source recommender systems toolkit.
 * Copyright 2010-2014 LensKit Contributors.  See CONTRIBUTORS.md.
 * Work on LensKit has been funded by the National Science Foundation under
 * grants IIS 05-34939, 08-08692, 08-12148, and 10-17697.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.grouplens.lenskit.util.test;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;

import java.io.*;

/**
 * @author <a href="http://www.grouplens.org">GroupLens Research</a>
 */
public class LineCountMatcher extends BaseMatcher<File> {
    private final Matcher<? extends Integer> lineCount;

    public LineCountMatcher(Matcher<? extends Integer> m) {
        lineCount = m;
    }

    @Override
    public boolean matches(Object o) {
        return o instanceof File && lineCount.matches(getLineCount((File) o));
    }

    private int getLineCount(File file) {
        try (Reader reader = new FileReader(file);
             BufferedReader lines = new BufferedReader(reader)) {
            int n = 0;
            while (lines.readLine() != null) {
                n++;
            }
            return n;
        } catch (FileNotFoundException ex) {
            throw new RuntimeException("file " + file + " not found", ex);
        } catch (IOException ex) {
            throw new RuntimeException("error reading file " + file, ex);
        }
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("file with line count ")
                   .appendDescriptionOf(lineCount);
    }

    @Override
    public void describeMismatch(Object item, Description description) {
        if (item instanceof File) {
            int lines = getLineCount((File) item);
            description.appendText("had " + lines + " lines");
        } else {
            description.appendText("was non-file object " + item);
        }
    }
}

@@ -1028,16 +1028,58 @@
 .test;%0A%0A
+import com.google.common.base.Throwables;%0A
 import o
@@ -1516,24 +1516,42 @@
 Object o) %7B%0A
+        try %7B%0A    
         retu
@@ -1617,16 +1617,173 @@
 e) o));%0A
+        %7D catch (FileNotFoundException e) %7B%0A            return false;%0A        %7D catch (IOException e) %7B%0A            throw Throwables.propagate(e);%0A        %7D%0A
     %7D%0A%0A 
@@ -1816,24 +1816,43 @@
 t(File file)
+ throws IOException
  %7B%0A        t
@@ -2090,237 +2090,8 @@
  n;%0A
-        %7D catch (FileNotFoundException ex) %7B%0A            throw new RuntimeException(%22file %22 + file + %22 not found%22, ex);%0A        %7D catch (IOException ex) %7B%0A            throw new RuntimeException(%22error reading file %22 + file, ex);%0A
     
@@ -2405,24 +2405,46 @@
 eof File) %7B%0A
+            try %7B%0A    
             
@@ -2474,32 +2474,36 @@
 t((File) item);%0A
+    
             desc
@@ -2549,16 +2549,234 @@
 ines%22);%0A
+            %7D catch (FileNotFoundException e) %7B%0A                description.appendText(%22did not exist%22);%0A            %7D catch (IOException e) %7B%0A                description.appendText(%22could not be read%22);%0A            %7D%0A
         

Remove RuntimeException throws in lenskit-test