// Path: src/main/java/com/github/liblevenshtein/transducer/Position.java
// @Data
// @RequiredArgsConstructor
// public class Position implements Serializable {
// 
//   private static final long serialVersionUID = 1L;
// 
//   /**
//    * Reference to the next node in this linked-list.  The next node may be null
//    */
//   private Position next = null;
// 
//   /**
//    * Index of the dictionary term represented by this coordinate.
//    */
//   private final int termIndex;
// 
//   /**
//    * Number of accumulated errors at this coordinate.
//    */
//   private final int numErrors;
// 
//   /**
//    * Whether this position should be treated specially, such as whether it
//    * represents a tranposition, merge, or split.
//    * @return Whether this position should be treated specially.
//    */
//   public boolean isSpecial() {
//     return false;
//   }
// }
// 
// Path: src/main/java/com/github/liblevenshtein/transducer/SubsumesFunction.java
// public abstract class SubsumesFunction implements Serializable {
// 
//   private static final long serialVersionUID = 1L;
// 
//   /**
//    * Determines whether {@code lhs} subsumes {@code rhs}.
//    * @param lhs {@link Position} doing the subsumption.
//    * @param rhs {@link Position} being subsumed.
//    * @param n Length of the query term.
//    * @return {@code lhs} subsuem {@code rhs}.
//    */
//   public abstract boolean at(Position lhs, Position rhs, int n);
// 
//   /**
//    * Routines for determining whether a standard position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForStandardAlgorithm extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// 
//   /**
//    * Routines for determining whether a transposition position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForTransposition extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final boolean s = lhs.isSpecial();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       final boolean t = rhs.isSpecial();
// 
//       if (s) {
//         if (t) {
//           return i == j;
//         }
// 
//         return f == n && i == j;
//       }
// 
//       if (t) {
//         // We have two cases:
//         //
//         // Case 1: (j < i) => (j - i) = - (i - j)
//         //                 => |j - (i - 1)| = |j - i + 1|
//         //                                  = |-(i - j) + 1|
//         //                                  = |-(i - j - 1)|
//         //                                  = i - j - 1
//         //
//         // Case 1 holds, because i and j are integers, and j < i implies i is at
//         // least 1 unit greater than j, further implying that i - j - 1 is
//         // non-negative.
//         //
//         // Case 2: (j >= i) => |j - (i - 1)| = |j - i + 1| = j - i + 1
//         //
//         // Case 2 holds for the same reason case 1 does, in that j - i >= 0, and
//         // adding 1 to the difference will only strengthen its non-negativity.
//         //
//         //return Math.abs(j - (i - 1)) <= (f - e);
//         return (j < i ? i - j - 1 : j - i + 1) <= (f - e);
//       }
// 
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// 
//   /**
//    * Routines for determining whether a merge-and-split position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForMergeAndSplit extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final boolean s = lhs.isSpecial();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       final boolean t = rhs.isSpecial();
// 
//       if (s && !t) {
//         return false;
//       }
// 
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// }
// 
// Path: src/test/java/com/github/liblevenshtein/assertion/SubsumesFunctionAssertions.java
// public static SubsumesFunctionAssertions assertThat(
//     final SubsumesFunction actual) {
//   return new SubsumesFunctionAssertions(actual);
// }


import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.github.liblevenshtein.transducer.Position;
import com.github.liblevenshtein.transducer.SubsumesFunction;
import static com.github.liblevenshtein.assertion.SubsumesFunctionAssertions.assertThat;
package com.github.liblevenshtein.assertion;





public class SubsumesFunctionAssertionsTest {

  private static final int TERM_LENGTH = 4;

// Path: src/main/java/com/github/liblevenshtein/transducer/Position.java
// @Data
// @RequiredArgsConstructor
// public class Position implements Serializable {
// 
//   private static final long serialVersionUID = 1L;
// 
//   /**
//    * Reference to the next node in this linked-list.  The next node may be null
//    */
//   private Position next = null;
// 
//   /**
//    * Index of the dictionary term represented by this coordinate.
//    */
//   private final int termIndex;
// 
//   /**
//    * Number of accumulated errors at this coordinate.
//    */
//   private final int numErrors;
// 
//   /**
//    * Whether this position should be treated specially, such as whether it
//    * represents a tranposition, merge, or split.
//    * @return Whether this position should be treated specially.
//    */
//   public boolean isSpecial() {
//     return false;
//   }
// }
// 
// Path: src/main/java/com/github/liblevenshtein/transducer/SubsumesFunction.java
// public abstract class SubsumesFunction implements Serializable {
// 
//   private static final long serialVersionUID = 1L;
// 
//   /**
//    * Determines whether {@code lhs} subsumes {@code rhs}.
//    * @param lhs {@link Position} doing the subsumption.
//    * @param rhs {@link Position} being subsumed.
//    * @param n Length of the query term.
//    * @return {@code lhs} subsuem {@code rhs}.
//    */
//   public abstract boolean at(Position lhs, Position rhs, int n);
// 
//   /**
//    * Routines for determining whether a standard position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForStandardAlgorithm extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// 
//   /**
//    * Routines for determining whether a transposition position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForTransposition extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final boolean s = lhs.isSpecial();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       final boolean t = rhs.isSpecial();
// 
//       if (s) {
//         if (t) {
//           return i == j;
//         }
// 
//         return f == n && i == j;
//       }
// 
//       if (t) {
//         // We have two cases:
//         //
//         // Case 1: (j < i) => (j - i) = - (i - j)
//         //                 => |j - (i - 1)| = |j - i + 1|
//         //                                  = |-(i - j) + 1|
//         //                                  = |-(i - j - 1)|
//         //                                  = i - j - 1
//         //
//         // Case 1 holds, because i and j are integers, and j < i implies i is at
//         // least 1 unit greater than j, further implying that i - j - 1 is
//         // non-negative.
//         //
//         // Case 2: (j >= i) => |j - (i - 1)| = |j - i + 1| = j - i + 1
//         //
//         // Case 2 holds for the same reason case 1 does, in that j - i >= 0, and
//         // adding 1 to the difference will only strengthen its non-negativity.
//         //
//         //return Math.abs(j - (i - 1)) <= (f - e);
//         return (j < i ? i - j - 1 : j - i + 1) <= (f - e);
//       }
// 
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// 
//   /**
//    * Routines for determining whether a merge-and-split position subsumes another.
//    * @author Dylon Edwards
//    * @since 2.1.0
//    */
//   public static class ForMergeAndSplit extends SubsumesFunction {
// 
//     private static final long serialVersionUID = 1L;
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean at(final Position lhs, final Position rhs, final int n) {
//       final int i = lhs.termIndex();
//       final int e = lhs.numErrors();
//       final boolean s = lhs.isSpecial();
//       final int j = rhs.termIndex();
//       final int f = rhs.numErrors();
//       final boolean t = rhs.isSpecial();
// 
//       if (s && !t) {
//         return false;
//       }
// 
//       return (i < j ? j - i : i - j) <= (f - e);
//     }
//   }
// }
// 
// Path: src/test/java/com/github/liblevenshtein/assertion/SubsumesFunctionAssertions.java
// public static SubsumesFunctionAssertions assertThat(
//     final SubsumesFunction actual) {
//   return new SubsumesFunctionAssertions(actual);
// }


// Path: src/test/java/com/github/liblevenshtein/assertion/SubsumesFunctionAssertionsTest.java
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.github.liblevenshtein.transducer.Position;
import com.github.liblevenshtein.transducer.SubsumesFunction;
import static com.github.liblevenshtein.assertion.SubsumesFunctionAssertions.assertThat;

package com.github.liblevenshtein.assertion;





public class SubsumesFunctionAssertionsTest {

  private static final int TERM_LENGTH = 4;

  private final ThreadLocal<SubsumesFunction> standardSubsumes = new ThreadLocal<>();