/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.commons.text.similarity;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;

import java.util.Arrays;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * Unit tests for {@link org.apache.commons.text.similarity.EditDistanceFrom}.
 *
 * @param <R> The {@link EditDistance} return type.
 */
@RunWith(Parameterized.class)
public class ParameterizedEditDistanceFromTest<R> {

    private final EditDistance<R> editDistance;
    private final CharSequence left;
    private final CharSequence right;
    private final R distance;

    public ParameterizedEditDistanceFromTest(
        final EditDistance<R> editDistance,
        final CharSequence left, final CharSequence right,
        final R distance) {

        this.editDistance = editDistance;
        this.left = left;
        this.right = right;
        this.distance = distance;
    }

    @Parameters
    public static Iterable<Object[]> parameters() {
        return Arrays.asList( new Object[][] {

            /* TODO: When SANDBOX-491 is ready, add a few FuzzyScore tests. */

            { new HammingDistance(), "Sam I am.", "Ham I am.", 1 },
            { new HammingDistance(), "Japtheth, Ham, Shem", "Japtheth, HAM, Shem", 2 },
            { new HammingDistance(), "Hamming", "Hamming", 0 },

            { new JaroWrinklerDistance(), "elephant", "hippo", 0.44 },
            { new JaroWrinklerDistance(), "hippo", "elephant",  0.44 },
            { new JaroWrinklerDistance(), "hippo", "zzzzzzzz", 0.0 },

            /* TODO: When SANDBOX-491 is ready, add a few limited/threshold tests. */
            { new LevenshteinDistance(), "Apache", "a patchy", 4 },
            { new LevenshteinDistance(), "go", "no go", 3 },
            { new LevenshteinDistance(), "go", "go", 0 },

            {
                new EditDistance<Boolean>() {
                    public Boolean apply(CharSequence left, CharSequence right) {
                        return left == right || (left != null && left.equals(right));
                    }
                },
                "Bob's your uncle.",
                "Every good boy does fine.",
                false
            }

        } );
    }

    @Test
    public void test() {
        EditDistanceFrom<R> editDistanceFrom = new EditDistanceFrom<R>(editDistance, left);
        assertThat(editDistanceFrom.apply(right), equalTo(distance));
    }

}
