package org.jabref.logic.bst.util;

import java.util.stream.Stream;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import static org.junit.jupiter.api.Assertions.assertEquals;

/// How to create these test using Bibtex:
/// <p/>
/// Execute this charWidth.bst with the following charWidth.aux:
/// <p/>
/// <p/>
/// <code>
/// ENTRY{}{}{}
/// FUNCTION{test}
/// {
/// "i" width$ int.to.str$ write$ newline$
/// "0I~ " width$ int.to.str$ write$ newline$
/// "Hi Hi " width$ int.to.str$ write$ newline$
/// "{\oe}" width$ int.to.str$ write$ newline$
/// "Hi {\oe   }Hi " width$ int.to.str$ write$ newline$
/// }
/// READ
/// EXECUTE{test}
/// </code>
/// <p/>
/// <code>
/// \bibstyle{charWidth}
/// \citation{canh05}
/// \bibdata{test}
/// \bibcite{canh05}{CMM{$^{+}$}05}
/// </code>
class BstWidthCalculatorTest {

    @ParameterizedTest
    @MethodSource("provideTestWidth")
    void width(int i, String str) {
        assertEquals(i, BstWidthCalculator.width(str));
    }

    private static Stream<Arguments> provideTestWidth() {
        return Stream.of(
                Arguments.of(278, "i"),
                Arguments.of(1639, "0I~ "),
                Arguments.of(2612, "Hi Hi "),
                Arguments.of(778, "{\\oe}"),
                Arguments.of(3390, "Hi {\\oe   }Hi "),
                Arguments.of(444, "{\\'e}"),
                Arguments.of(19762, "Ulrich {\\\"{U}}nderwood and Ned {\\~N}et and Paul {\\={P}}ot"),
                Arguments.of(7861, "{\\'{E}}douard Masterly"),
                Arguments.of(30514, "Jonathan Meyer and Charles Louis Xavier Joseph de la Vall{\\'e}e Poussin")
        );
    }

    @ParameterizedTest
    @MethodSource("provideTestGetCharWidth")
    void getCharWidth(int i, Character c) {
        assertEquals(i, BstWidthCalculator.getCharWidth(c));
    }

    private static Stream<Arguments> provideTestGetCharWidth() {
        return Stream.of(
                Arguments.of(500, '0'),
                Arguments.of(361, 'I'),
                Arguments.of(500, '~'),
                Arguments.of(500, '}'),
                Arguments.of(278, ' ')
        );
    }
}
