// Path: src/main/java/io/aif/language/common/IRegexpCooker.java
// public interface IRegexpCooker {
// 
//   String prepareRegexp(final List<Character> characters);
// }
// 
// Path: src/main/java/io/aif/language/common/ISplitter.java
// @FunctionalInterface
// public interface ISplitter<T1, T2> extends Function<T1, List<T2>> {
// 
//   public List<T2> split(final T1 target);
// 
//   @Override
//   public default List<T2> apply(final T1 t1) {
//     return split(t1);
//   }
// }
// 
// Path: src/main/java/io/aif/language/token/separator/ITokenSeparatorExtractor.java
// public interface ITokenSeparatorExtractor extends IExtractor<String, List<Character>> {
//   final ISettings settings = Guice.createInjector(new SettingsModule()).getInstance(ISettings.class);
//   public static enum Type {
// 
//     PREDEFINED(new PredefinedTokenSeparatorExtractor(settings)),
//     PROBABILITY(new ProbabilityBasedTokenSeparatorExtractor());
// 
//     private final ITokenSeparatorExtractor instance;
// 
//     private Type(final ITokenSeparatorExtractor instance) {
//       this.instance = instance;
//     }
// 
//     public ITokenSeparatorExtractor getInstance() {
//       return instance;
//     }
// 
//   }
// 
// }


import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import io.aif.language.common.IRegexpCooker;
import io.aif.language.common.ISplitter;
import io.aif.language.token.separator.ITokenSeparatorExtractor;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

    // asserts
    assertEquals(expectedResult, actualResult);

    // verify
    verify(mockTokenSeparatorExtractor, times(1)).extract(inputText);
  }

  @Test(groups = "unit-tests")
  public void testSplitWhenSplittersFound() throws Exception {

    // input parameter
    final String inputText = "token1  token2";

    // mocks
    final Optional<List<Character>> mockOptionalsSplitCharacters =
        Optional.of(Arrays.asList(' ', '\n'));

    final ITokenSeparatorExtractor mockTokenSeparatorExtractor =
        mock(ITokenSeparatorExtractor.class);
    when(mockTokenSeparatorExtractor.extract(eq(inputText)))
        .thenReturn(mockOptionalsSplitCharacters);

    final IRegexpCooker mockRegexpCooker = mock(IRegexpCooker.class);
    when(mockRegexpCooker.prepareRegexp(eq(Arrays.asList(' ', '\n')))).thenReturn("[ \n]+");

    // expected result
    final List<String> expectedResult = Arrays.asList("token1", "token2");

    // creating instances
// Path: src/main/java/io/aif/language/common/IRegexpCooker.java
// public interface IRegexpCooker {
// 
//   String prepareRegexp(final List<Character> characters);
// }
// 
// Path: src/main/java/io/aif/language/common/ISplitter.java
// @FunctionalInterface
// public interface ISplitter<T1, T2> extends Function<T1, List<T2>> {
// 
//   public List<T2> split(final T1 target);
// 
//   @Override
//   public default List<T2> apply(final T1 t1) {
//     return split(t1);
//   }
// }
// 
// Path: src/main/java/io/aif/language/token/separator/ITokenSeparatorExtractor.java
// public interface ITokenSeparatorExtractor extends IExtractor<String, List<Character>> {
//   final ISettings settings = Guice.createInjector(new SettingsModule()).getInstance(ISettings.class);
//   public static enum Type {
// 
//     PREDEFINED(new PredefinedTokenSeparatorExtractor(settings)),
//     PROBABILITY(new ProbabilityBasedTokenSeparatorExtractor());
// 
//     private final ITokenSeparatorExtractor instance;
// 
//     private Type(final ITokenSeparatorExtractor instance) {
//       this.instance = instance;
//     }
// 
//     public ITokenSeparatorExtractor getInstance() {
//       return instance;
//     }
// 
//   }
// 
// }


// Path: src/test/unit/java/io/aif/language/token/TokenizerTest.java
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import io.aif.language.common.IRegexpCooker;
import io.aif.language.common.ISplitter;
import io.aif.language.token.separator.ITokenSeparatorExtractor;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


    // asserts
    assertEquals(expectedResult, actualResult);

    // verify
    verify(mockTokenSeparatorExtractor, times(1)).extract(inputText);
  }

  @Test(groups = "unit-tests")
  public void testSplitWhenSplittersFound() throws Exception {

    // input parameter
    final String inputText = "token1  token2";

    // mocks
    final Optional<List<Character>> mockOptionalsSplitCharacters =
        Optional.of(Arrays.asList(' ', '\n'));

    final ITokenSeparatorExtractor mockTokenSeparatorExtractor =
        mock(ITokenSeparatorExtractor.class);
    when(mockTokenSeparatorExtractor.extract(eq(inputText)))
        .thenReturn(mockOptionalsSplitCharacters);

    final IRegexpCooker mockRegexpCooker = mock(IRegexpCooker.class);
    when(mockRegexpCooker.prepareRegexp(eq(Arrays.asList(' ', '\n')))).thenReturn("[ \n]+");

    // expected result
    final List<String> expectedResult = Arrays.asList("token1", "token2");

    // creating instances
    final ISplitter<String, String> tokenSplitter =