I believe I've found a bug in DocOpAutomaton. If I create a Document Schema
that returns a non-empty list for getRequiredInitialChildren() then an
insertion operation inside the required child will fail.

The problem appears to be that advance() does not alter
"nextRequiredElement" when it should.

Is this a valid issue, or am I misunderstanding the intent of
"getRequiredInitialChildren()"?

Here's a unit test to demonstrate the problem.

================ BEGIN FILE =============================
package org.waveprotocol.wave.model.document.operation.automaton;

import java.util.Collections;
import java.util.List;

import org.waveprotocol.wave.model.document.bootstrap.BootstrapDocument;
import org.waveprotocol.wave.model.document.operation.Attributes;
import org.waveprotocol.wave.model.document.operation.BufferedDocOp;
import org.waveprotocol.wave.model.document.operation.impl.DocOpBuilder;
import org.waveprotocol.wave.model.operation.OperationException;

import com.google.inject.internal.ImmutableList;

import junit.framework.TestCase;

public class SchemaValidationTest extends TestCase {
  public void testRequiredInitialChildren() {
    DocumentSchema schema = new DocumentSchema() {

      @Override
      public List<String> getRequiredInitialChildren(String typeOrNull) {
        if (typeOrNull == null) {
          return ImmutableList.of("root");
        } else {
          return Collections.emptyList();
        }
      }

      @Override
      public boolean permitsAttribute(String type, String attributeName) {
        return false;
      }

      @Override
      public boolean permitsAttribute(String type, String attributeName,
String attributeValue) {
        return false;
      }

      @Override
      public boolean permitsChild(String parentTypeOrNull, String childType)
{
        if (parentTypeOrNull == null && childType.equals("root")) {
          return true;
        }
        return false;
      }

      @Override
      public PermittedCharacters permittedCharacters(String typeOrNull) {
        if (typeOrNull != null && typeOrNull.equals("root")) {
          return PermittedCharacters.ANY;
        }
        return PermittedCharacters.NONE;
      }

    };

    BootstrapDocument doc = new BootstrapDocument(schema);

    BufferedDocOp initial = new DocOpBuilder()
      .elementStart("root", Attributes.EMPTY_MAP)
      .elementEnd()
      .build();
    BufferedDocOp change = new DocOpBuilder()
      .retain(1)
      .characters("text")
      .retain(1)
      .build();

    try {
      doc.consume(initial);
    } catch (OperationException e) {
      fail(e.getMessage());
    }

    try {
      doc.consume(change);
    } catch (OperationException e) {
      fail(e.getMessage());
    }
  }
}
================ END FILE =============================


-Tad

-- 
You received this message because you are subscribed to the Google Groups "Wave 
Protocol" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/wave-protocol?hl=en.

Reply via email to