@Test
  public void testWithMultipleTargetValueResultsAndOneValueIsNull() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder()
            .callback(
                new Callable<Result[]>() {
                  @Override
                  public Result[] call() throws Exception {
                    return new Result[] {
                      new Result(1, "one", -1, -1),
                      new Result(2, "two", -1, -1),
                      new Result(null, "three", -1, -1)
                    };
                  }
                })
            .build();

    final Message msg = createMessage("the hello");

    extractor.runExtractor(msg);

    // If the extractor returns multiple results and one result value is null, all results will be
    // ignored.
    // TODO: This is the current behaviour and it is weird. Will be fixed soon.
    assertThat(msg.hasField("one")).isFalse();
    assertThat(msg.hasField("two")).isFalse();
    assertThat(msg.hasField("three")).isFalse();
  }
  @Test
  public void testWithMultipleTargetValueResults() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder()
            .callback(
                new Callable<Result[]>() {
                  @Override
                  public Result[] call() throws Exception {
                    return new Result[] {
                      new Result(1, "one", -1, -1),
                      new Result("2", "two", -1, -1),
                      new Result(3, "three", -1, -1)
                    };
                  }
                })
            .build();

    final Message msg = createMessage("the hello");

    extractor.runExtractor(msg);

    assertThat(msg.hasField("target")).isFalse();
    assertThat(msg.getField("one")).isEqualTo(1);
    assertThat(msg.getField("two")).isEqualTo("2");
    assertThat(msg.getField("three")).isEqualTo(3);
  }
  @Test
  public void testWithRegexpCondition() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder().conditionType(REGEX).conditionValue("^hello").build();

    // Extractor runs if the message matches the condition regexp.
    final Message msg1 = createMessage("hello world");

    extractor.runExtractor(msg1);

    assertThat(msg1.hasField("target")).isTrue();

    // Extractor does not run if the message does not match the condition regexp.
    final Message msg2 = createMessage("the hello");

    extractor.runExtractor(msg2);

    assertThat(msg2.hasField("target")).isFalse();
  }
  @Test
  public void testWithStringCondition() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder().conditionType(STRING).conditionValue("hello").build();

    // Extractor runs if the message contains the condition value "hello".
    final Message msg1 = createMessage("hello world");

    extractor.runExtractor(msg1);

    assertThat(msg1.hasField("target")).isTrue();

    // Extractor does not run if the message does not contain the condition value.
    final Message msg2 = createMessage("the message");

    extractor.runExtractor(msg2);

    assertThat(msg2.hasField("target")).isFalse();
  }
  @Test
  public void testRunExtractorCheckSourceValueIsString() throws Exception {
    final TestExtractor extractor = new TestExtractor.Builder().sourceField("a_field").build();

    // Extractor should not run for source field values that are not strings!
    final Message msg1 = createMessage("the message");
    msg1.addField("a_field", 1);

    extractor.runExtractor(msg1);

    assertThat(msg1.hasField("target")).isFalse();

    // The extractor should run for a source field value of type string.
    final Message msg2 = createMessage("the message");
    msg2.addField("a_field", "the source");

    extractor.runExtractor(msg2);

    assertThat(msg2.hasField("target")).isTrue();
  }
  @Test
  public void testWithOneValueOnlyResultsAndValueIsNull() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder()
            .callback(
                new Callable<Result[]>() {
                  @Override
                  public Result[] call() throws Exception {
                    return new Result[] {new Result(null, -1, -1)};
                  }
                })
            .build();

    final Message msg = createMessage("the hello");

    extractor.runExtractor(msg);

    assertThat(msg.hasField("target")).isFalse();
  }
  @Test
  public void testWithEmptyResultArray() throws Exception {
    final TestExtractor extractor =
        new TestExtractor.Builder()
            .callback(
                new Callable<Result[]>() {
                  @Override
                  public Result[] call() throws Exception {
                    return new Result[0];
                  }
                })
            .build();

    final Message msg = createMessage("the hello");

    extractor.runExtractor(msg);

    assertThat(msg.hasField("target")).isFalse();
  }