@Test
  public void testElementOrderIsPreservedThroughNextPointers() throws Exception {
    final Agent agent =
        setUpAndRunAgent(
            "testFromXml (state <s> ^superstate nil ^io.input-link <il>) -->"
                + "(<il> ^xml (from-xml |<ignored><a/><b/><c/><d/></ignored>|))");

    final Identifier il = agent.getInputOutput().getInputLink();
    final MatcherBuilder m = Wmes.matcher(agent);
    final Identifier xml = m.attr("xml").find(il).getValue().asIdentifier();
    assertNotNull(xml);

    final Wme[] wmes = {
      m.attr("a").find(xml), m.attr("b").find(xml), m.attr("c").find(xml), m.attr("d").find(xml)
    };
    for (int i = 0; i < wmes.length; ++i) {
      Wme wme = wmes[i];
      assertNotNull(wme);
      if (i != 0) {
        Wme prev = wmes[i - 1];
        Wme next = m.attr(DefaultWmeToXml.NEXT).find(prev);
        assertNotNull(next);
        assertSame(prev.getValue(), next.getIdentifier());
        assertSame(next.getValue(), wme.getValue());
      }
    }
  }
  @Test
  public void testMessageQueueRootIsCreated() throws Exception {
    XmlMessageQueue.newBuilder(agent.getInputOutput()).queueName("test-queue-root").create();

    agent
        .getProductions()
        .loadProduction(
            "testMessageQueueRootIsCreated (state <s> ^superstate nil ^io.input-link.test-queue-root) --> (match)");

    agent.runFor(1, RunType.DECISIONS);
    assertEquals(1, match.count);
  }
  @Test
  public void testFromXmlWithOnlyText() throws Exception {
    final Agent agent =
        setUpAndRunAgent(
            "testFromXml (state <s> ^superstate nil ^io.input-link <il>) -->"
                + "(<il> ^xml (from-xml |<ignored>This is the only text in the document</ignored>|))");

    final Identifier il = agent.getInputOutput().getInputLink();
    final MatcherBuilder m = Wmes.matcher(agent);
    final Wme xml = m.attr("xml").find(il);
    assertNotNull(xml);
    assertEquals(
        "This is the only text in the document",
        m.attr(DefaultWmeToXml.TEXT).find(xml).getValue().asString().getValue());
  }
 @Before
 public void setUp() throws Exception {
   this.agent = new Agent();
   agent.getTrace().disableAll();
   this.match = new MatchFunction();
   this.agent.getRhsFunctions().registerHandler(match);
   new CycleCountInput(this.agent.getInputOutput());
   this.agent.initialize();
 }
  @Test
  public void testFromXmlWithOnlyAttributes() throws Exception {
    final Agent agent =
        setUpAndRunAgent(
            "testFromXml (state <s> ^superstate nil ^io.input-link <il>) -->"
                + "(<il> ^xml (from-xml |<ignored name='Boo' value='Radley'/>|))");

    final Identifier il = agent.getInputOutput().getInputLink();
    final MatcherBuilder m = Wmes.matcher(agent);
    final Identifier xml = m.attr("xml").find(il).getValue().asIdentifier();
    assertNotNull(xml);
    final Wme attrs = m.attr(DefaultWmeToXml.ATTRS).find(xml);
    assertNotNull(attrs);
    assertEquals(1, Iterators.size(xml.getWmes())); // Only /attrs

    assertEquals("Boo", m.attr("name").find(attrs).getValue().asString().getValue());
    assertEquals("Radley", m.attr("value").find(attrs).getValue().asString().getValue());
  }
  @Test
  public void testFromXml() throws Exception {
    final Agent agent =
        setUpAndRunAgent(
            "testFromXml (state <s> ^superstate nil ^io.input-link <il>) -->"
                + "(<il> ^xml (from-xml |"
                + "<ignored>"
                + "<location name='Ann Arbor' population='100000'>This is some text"
                + "</location>"
                + "<person>"
                + "   <name>Bill</name>"
                + "</person>"
                + "</ignored>|))");

    final Identifier il = agent.getInputOutput().getInputLink();
    final MatcherBuilder m = Wmes.matcher(agent);
    final Identifier xml = m.attr("xml").find(il).getValue().asIdentifier();
    assertNotNull(xml);

    final Wme location = m.attr("location").find(xml);
    assertNotNull(location);
    final Wme locAttrs = m.attr(DefaultWmeToXml.ATTRS).find(location);
    assertNotNull(locAttrs);
    assertEquals("Ann Arbor", m.attr("name").find(locAttrs).getValue().asString().getValue());
    assertEquals("100000", m.attr("population").find(locAttrs).getValue().asString().getValue());

    assertEquals(
        "This is some text",
        m.attr(DefaultWmeToXml.TEXT).find(location).getValue().asString().getValue());

    final Wme person = m.attr("person").find(xml);
    assertNotNull(person);

    assertSame(person.getValue(), m.attr(DefaultWmeToXml.NEXT).find(location).getValue());

    final Wme name = m.attr("name").find(person);
    assertEquals("Bill", m.attr(DefaultWmeToXml.TEXT).find(name).getValue().asString().getValue());
  }
  @Test
  public void testDebuggerCommandCallsOpenDebuggerOnAgent() throws Exception {
    final Agent agent = new Agent("testDebuggerCommandCallsOpenDebuggerOnAgent");
    final AtomicBoolean called = new AtomicBoolean(false);
    final DebuggerProvider provider =
        new AbstractDebuggerProvider() {

          @Override
          public void openDebuggerAndWait(Agent agent) throws SoarException, InterruptedException {
            throw new UnsupportedOperationException("openDebuggerAndWait not supported");
          }

          @Override
          public void openDebugger(Agent a) throws SoarException {
            assertSame(agent, a);
            called.set(true);
          }
        };
    agent.setDebuggerProvider(provider);
    final DebuggerCommand command = new DebuggerCommand(agent);
    command.execute(DefaultSoarCommandContext.empty(), new String[] {"debugger"});
    assertTrue(called.get());
  }
  @Test
  public void testMessagesAreAddedToQueue() throws Exception {
    final XmlMessageQueue queue =
        XmlMessageQueue.newBuilder(agent.getInputOutput()).queueName("test-messages").create();

    agent
        .getProductions()
        .loadProduction(
            "checkForMessages"
                + "(state <s> ^superstate nil ^io.input-link.test-messages <r>)"
                + "(<r> ^a <a> ^b <b> ^c <c>)"
                + "(<a> ^/text |message a| ^/next <b> -^/previous)"
                + "(<b> ^/text |message b| ^/previous <a> ^/next <c>)"
                + "(<c> ^/text |message c| ^/previous <b> -^/next)"
                + "--> (match)");
    agent.runFor(1, RunType.DECISIONS);
    assertEquals(0, match.count);

    queue.add(XmlTools.parse("<a>message a</a>").getDocumentElement());
    queue.add(XmlTools.parse("<b>message b</b>").getDocumentElement());
    queue.add(XmlTools.parse("<c>message c</c>").getDocumentElement());
    agent.runFor(1, RunType.DECISIONS);
    assertEquals(1, match.count);
  }
  private Agent setUpAndRunAgent(String rule) throws Exception {
    final Agent agent = new Agent();

    agent.getTrace().disableAll();
    agent.initialize();

    agent.getProperties().set(SoarProperties.WAITSNC, true);
    agent.getProductions().loadProduction(rule);
    agent.runFor(1, RunType.DECISIONS);
    return agent;
  }
  @Test
  public void testMessagesAreRemovedFromQueueAfterTimeToLiveExpires() throws Exception {
    final XmlMessageQueue queue =
        XmlMessageQueue.newBuilder(agent.getInputOutput())
            .timeToLive(20)
            .queueName("test-messages")
            .create();

    agent.getProperties().set(SoarProperties.WAITSNC, true);
    agent
        .getProductions()
        .loadProduction(
            "checkForMessages"
                + "(state <s> ^superstate nil ^io.input-link.test-messages <r>)"
                + "(<r> ^a <a> ^b <b> ^c <c>)"
                + "(<a> ^/text |message a| ^/next <b> -^/previous)"
                + "(<b> ^/text |message b| ^/previous <a> ^/next <c>)"
                + "(<c> ^/text |message c| ^/previous <b> -^/next)"
                + "--> (match)");
    agent
        .getProductions()
        .loadProduction(
            "checkForRemoval"
                + "(state <s> ^superstate nil ^io.input-link <il>)"
                + "(<il> ^cycle-count > 2 < 24 ^test-messages <r>)"
                + "(<r> -^a -^b -^c)"
                + "-->"
                + "(match)");

    agent.runFor(1, RunType.DECISIONS);
    assertEquals(0, match.count);

    queue.add(XmlTools.parse("<a>message a</a>").getDocumentElement());
    queue.add(XmlTools.parse("<b>message b</b>").getDocumentElement());
    queue.add(XmlTools.parse("<c>message c</c>").getDocumentElement());
    agent.runFor(1, RunType.DECISIONS);
    assertEquals(1, match.count);
    agent.runFor(20, RunType.DECISIONS);
    assertEquals(2, match.count);
  }