com.sunsprinter.diffunit.core.comparison.AbstractFileComparer.java Source code

Java tutorial

Introduction

Here is the source code for com.sunsprinter.diffunit.core.comparison.AbstractFileComparer.java

Source

/*
 * Copyright 2012 Kevan Dunsmore.  All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.sunsprinter.diffunit.core.comparison;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import com.sunsprinter.diffunit.core.context.ITestingContext;

/**
 * AbstractFileComparer
 *
 * @author Kevan Dunsmore
 * @created 2011/11/13
 */
public abstract class AbstractFileComparer implements IFileComparer {
    private ITestingContext _testingContext;
    private Collection<File> _filesToCompare = new LinkedList<File>();

    protected Collection<File> getFilesToCompare() {
        return _filesToCompare;
    }

    protected void setFilesToCompare(final Collection<File> filesToCompare) {
        _filesToCompare = filesToCompare;
    }

    protected ITestingContext getTestingContext() {
        return _testingContext;
    }

    public void setTestingContext(final ITestingContext testingContext) {
        _testingContext = testingContext;
    }

    @Override
    public void registerFileToCompare(final File file) {
        getFilesToCompare().add(file);
    }

    @Override
    public void compareAllFiles() throws Exception {
        // Get the input location type from the annotation on the class.  If we don't have one we default to CLASSPATH.
        final DiffUnitInputLocation classInputLocationAnnotation = getTestingContext().getTestClass()
                .getAnnotation(DiffUnitInputLocation.class);
        final InputLocationType locationType = classInputLocationAnnotation == null ? InputLocationType.CLASSPATH
                : classInputLocationAnnotation.locationType();
        final String classInputLocation = classInputLocationAnnotation == null ? null
                : classInputLocationAnnotation.location();

        // Figure out the input location path by checking to see what our location type is.
        final String inputLocation;
        if (locationType == InputLocationType.CLASSPATH) {
            inputLocation = classInputLocation == null ? String.format("/%s/%s",
                    getTestingContext().getTestClass().getSimpleName(), getTestingContext().getTestName())
                    : classInputLocation;
        } else {
            inputLocation = classInputLocation == null ? String.format("src/test/resources/%s/%s",
                    getTestingContext().getTestClass().getSimpleName(), getTestingContext().getTestName())
                    : classInputLocation;
        }

        // Go through all the files we wrote and compare them against the known good ones stored in the input location.
        for (final File generatedFile : getFilesToCompare()) {
            final String knownGoodTextFileName = generatedFile.getName();
            InputStream knownGoodInputStream = null;
            InputStream generatedInputStream = null;
            try {
                final String inputStreamLocation = inputLocation + "/" + knownGoodTextFileName;
                if (locationType == InputLocationType.CLASSPATH) {

                    knownGoodInputStream = getClass().getResourceAsStream(inputStreamLocation);
                } else {
                    try {
                        knownGoodInputStream = new FileInputStream(inputStreamLocation);
                    } catch (final FileNotFoundException e) {
                        // Do nothing here.  We handle not being able to find the input file below.
                    }
                }

                if (knownGoodInputStream == null) {
                    // There's no input file.  We create a dummy one for comparison purposes.  This lets the
                    // developer see differences for all files rather than just bailing here.
                    knownGoodInputStream = new ByteArrayInputStream(
                            String.format("Input file %s not found.", inputStreamLocation).getBytes());
                }

                final Collection<String> knownGoodLines = IOUtils.readLines(knownGoodInputStream);

                generatedInputStream = new FileInputStream(generatedFile);
                final Collection<String> generatedLines = IOUtils.readLines(generatedInputStream);

                assertEqual(knownGoodLines, inputStreamLocation, locationType, generatedLines, generatedFile);
            } finally {
                IOUtils.closeQuietly(knownGoodInputStream);
                IOUtils.closeQuietly(generatedInputStream);
            }

        }
    }

    protected void assertEqual(final Collection<String> knownGoodLines, final String knownGoodPath,
            final InputLocationType knownGoodLocationType, final Collection<String> generatedLines,
            final File generatedFile) throws Exception {
        final String knownGoodFullPath;
        if (knownGoodLocationType == InputLocationType.CLASSPATH) {
            knownGoodFullPath = knownGoodPath;
        } else {
            knownGoodFullPath = new File(knownGoodPath).getAbsolutePath();
        }

        final StringBuilder errorBuilder = new StringBuilder();

        if (knownGoodLines.size() != generatedLines.size()) {
            errorBuilder
                    .append(String.format(
                            "The number of lines is different.  The known good file has %d lines.  "
                                    + "The generated file has %d lines.  ",
                            knownGoodLines.size(), generatedLines.size()));
        }

        int i = 1;
        String firstDifferenceMessage = null;
        final Iterator<String> knownGoodIterator = knownGoodLines.iterator();
        final Iterator<String> generatedIterator = generatedLines.iterator();
        while (firstDifferenceMessage == null && knownGoodIterator.hasNext() && generatedIterator.hasNext()) {
            final String knownGoodLine = knownGoodIterator.next();
            final String generatedLine = generatedIterator.next();
            if (!knownGoodLine.equals(generatedLine)) {
                firstDifferenceMessage = String.format(
                        "First difference detected at line number %d, position %d.\n\n" + "Known Good: %s\n"
                                + "Generated : %s\n",
                        i, StringUtils.indexOfDifference(knownGoodLine, generatedLine), knownGoodLine,
                        generatedLine);
            }
            i++;
        }
        if (firstDifferenceMessage != null) {
            errorBuilder.append(firstDifferenceMessage);
        }

        if (errorBuilder.length() != 0) {
            fail(String.format("Generated file %s does not match known good file %s.  %s",
                    generatedFile.getAbsolutePath(), knownGoodFullPath, errorBuilder));
        }
    }

    protected abstract void fail(final String message) throws Exception;
}