@@ -0,0 +1,2648 @@
+package edu.washington.escience.myria.operator.apply;%0A%0Aimport static org.junit.Assert.assertEquals;%0A%0Aimport org.junit.Test;%0A%0Aimport com.google.common.collect.ImmutableList;%0A%0Aimport edu.washington.escience.myria.DbException;%0Aimport edu.washington.escience.myria.Schema;%0Aimport edu.washington.escience.myria.Type;%0Aimport edu.washington.escience.myria.expression.ConstantExpression;%0Aimport edu.washington.escience.myria.expression.Expression;%0Aimport edu.washington.escience.myria.expression.ExpressionOperator;%0Aimport edu.washington.escience.myria.expression.NgramExpression;%0Aimport edu.washington.escience.myria.expression.VariableExpression;%0Aimport edu.washington.escience.myria.operator.Apply;%0Aimport edu.washington.escience.myria.operator.TupleSource;%0Aimport edu.washington.escience.myria.storage.TupleBatch;%0Aimport edu.washington.escience.myria.storage.TupleBatchBuffer;%0Aimport edu.washington.escience.myria.util.TestEnvVars;%0A%0Apublic class ApplyNgramTest %7B%0A%0A  private static final long EXPECTED_RESULTS = 2 * TupleBatch.BATCH_SIZE + 1;%0A  private static final long NGRAM_LEN = 3;%0A  private static final long CHAR_SEQ_LEN = EXPECTED_RESULTS + NGRAM_LEN - 1;%0A%0A  @Test%0A  public void testApply() throws DbException %7B%0A    final Schema schema = Schema.ofFields(%22char_sequence%22, Type.STRING_TYPE);%0A    final Schema expectedResultSchema = Schema.ofFields(%22ngrams%22, Type.STRING_TYPE);%0A    final TupleBatchBuffer input = new TupleBatchBuffer(schema);%0A%0A    StringBuilder sb = new StringBuilder();%0A    for (int i = 0; i %3C CHAR_SEQ_LEN; ++i) %7B%0A      sb.append((char) i);%0A    %7D%0A    input.putString(0, sb.toString());%0A%0A    ImmutableList.Builder%3CExpression%3E expressions = ImmutableList.builder();%0A    ExpressionOperator colIdx = new VariableExpression(0);%0A    ExpressionOperator ngramLen = new ConstantExpression(NGRAM_LEN);%0A    ExpressionOperator split = new NgramExpression(colIdx, ngramLen);%0A    Expression expr = new Expression(%22ngrams%22, split);%0A    expressions.add(expr);%0A%0A    Apply apply = new Apply(new TupleSource(input), expressions.build());%0A    apply.open(TestEnvVars.get());%0A    long rowIdx = 0;%0A    while (!apply.eos()) %7B%0A      TupleBatch result = apply.nextReady();%0A      if (result != null) %7B%0A        assertEquals(expectedResultSchema, result.getSchema());%0A%0A        for (int batchIdx = 0; batchIdx %3C result.numTuples(); ++batchIdx, ++rowIdx) %7B%0A          char%5B%5D ngramChars = new char%5B%5D %7B(char) rowIdx, (char) (rowIdx + 1), (char) (rowIdx + 2)%7D;%0A          String ngram = new String(ngramChars);%0A          assertEquals(ngram, result.getString(0, batchIdx));%0A        %7D%0A      %7D%0A    %7D%0A    assertEquals(EXPECTED_RESULTS, rowIdx);%0A    apply.close();%0A  %7D%0A%7D%0A

add NgramExpression unit test