code: package morfologik.stemming;
  
  import java.nio.ByteBuffer;
  import java.nio.charset.StandardCharsets;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.assertj.core.api.Assertions;
  import org.junit.Test;
  
  import com.carrotsearch.randomizedtesting.RandomizedTest;
  import com.carrotsearch.randomizedtesting.annotations.Name;
  import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
  
  public class SequenceEncodersTest extends RandomizedTest {
      private final ISequenceEncoder coder;
  
      public SequenceEncodersTest(@Name("coder") ISequenceEncoder coder)
      {
          this.coder = coder;
      }
  
      @ParametersFactory
      public static List<Object[]> testFactory() {
          List<Object[]> encoders = new ArrayList<>();
          for (EncoderType t : EncoderType.values()) {    
              encoders.add(new Object [] {t.get()});
          }
          return encoders;
      }
  
      @Test
      public void testEncodeSuffixOnRandomSequences() {
          for (int i = 0; i < 10000; i++) {
              assertRoundtripEncode(
                  randomAsciiLettersOfLengthBetween(0, 500),
                  randomAsciiLettersOfLengthBetween(0, 500));
          }
      }
  
      @Test
      public void testEncodeSamples() {
          assertRoundtripEncode("", "");
          assertRoundtripEncode("abc", "ab");
          assertRoundtripEncode("abc", "abx");
          assertRoundtripEncode("ab", "abc");
          assertRoundtripEncode("xabc", "abc");
          assertRoundtripEncode("axbc", "abc");
          assertRoundtripEncode("axybc", "abc");
          assertRoundtripEncode("axybc", "abc");
          assertRoundtripEncode("azbc", "abcxy");
  
          assertRoundtripEncode("Niemcami", "Niemiec");
          assertRoundtripEncode("Niemiec", "Niemcami");
      }
  
      private void assertRoundtripEncode(String srcString, String dstString) {
          ByteBuffer source = ByteBuffer.wrap(srcString.getBytes(UTF8));
          ByteBuffer target = ByteBuffer.wrap(dstString.getBytes(UTF8));
  
          ByteBuffer encoded = coder.encode(ByteBuffer.allocate(randomInt(30)), source, target);
          ByteBuffer decoded = coder.decode(ByteBuffer.allocate(randomInt(30)), source, encoded);
  
          if (!decoded.equals(target)) {
              System.out.println("src: " + BufferUtils.toString(source, StandardCharsets.UTF_8));
              System.out.println("dst: " + BufferUtils.toString(target, StandardCharsets.UTF_8));
              System.out.println("enc: " + BufferUtils.toString(encoded, StandardCharsets.UTF_8));
              System.out.println("dec: " + BufferUtils.toString(decoded, StandardCharsets.UTF_8));
              Assertions.fail("Mismatch.");
          }
      }
  }
  