@Test
  public void shouldNotTrackViolationIfDifferentRule() {
    Violation newViolation = newViolation("message", 1, 50, "checksum1");
    RuleFailureModel referenceViolation = newReferenceViolation("message", 1, 51, "checksum1");

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation));
    assertThat(mapping.get(newViolation), is(nullValue()));
    assertThat(newViolation.isNew(), is(true));
  }
  @Test
  public void shouldCreateNewViolationWhenSameRuleSameMessageButDifferentLineAndChecksum() {
    Violation newViolation = newViolation("message", 1, 50, "checksum1");
    RuleFailureModel referenceViolation = newReferenceViolation("message", 2, 50, "checksum2");

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation));
    assertThat(mapping.get(newViolation), is(nullValue()));
    assertThat(newViolation.isNew(), is(true));
  }
  /** See https://jira.codehaus.org/browse/SONAR-2812 */
  @Test
  public void sameChecksumAndRuleButDifferentLineAndDifferentMessage() {
    Violation newViolation = newViolation("new message", 1, 50, "checksum1");
    RuleFailureModel referenceViolation = newReferenceViolation("old message", 2, 50, "checksum1");

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation));
    assertThat(mapping.get(newViolation), equalTo(referenceViolation));
    assertThat(newViolation.isNew(), is(false));
  }
  @Test
  public void shouldIgnoreReferenceMeasureWithoutChecksum() {
    Violation newViolation = newViolation("message", 1, 50, null);
    RuleFailureModel referenceViolation = newReferenceViolation("message", 1, 51, null);

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation));
    assertThat(mapping.get(newViolation), is(nullValue()));
    assertThat(newViolation.isNew(), is(true));
  }
  @Test
  public void shouldSetDateOfNewViolations() {
    Violation newViolation = newViolation("message", 1, 50, "checksum");
    assertThat(newViolation.getCreatedAt(), nullValue());

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Collections.<RuleFailureModel>emptyList());
    assertThat(mapping.size(), is(0));
    assertThat(newViolation.getCreatedAt(), is(analysisDate));
    assertThat(newViolation.isNew(), is(true));
  }
  @Test
  public void shouldCompareViolationsWithDatabaseFormat() {
    // violation messages are trimmed and can be abbreviated when persisted in database.
    // Comparing violation messages must use the same format.
    Violation newViolation = newViolation(" message ", 1, 50, "checksum1");
    RuleFailureModel referenceViolation =
        newReferenceViolation("       message       ", 1, 50, "checksum2");

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation));
    assertThat(mapping.get(newViolation), equalTo(referenceViolation));
    assertThat(newViolation.isNew(), is(false));
  }
  @Test
  public void shouldCopyDateWhenNotNew() {
    Violation newViolation = newViolation("message", 1, 50, "checksum");
    RuleFailureModel referenceViolation = newReferenceViolation("", 1, 50, "checksum");
    Date referenceDate = DateUtils.parseDate("2009-05-18");
    referenceViolation.setCreatedAt(referenceDate);
    assertThat(newViolation.getCreatedAt(), nullValue());

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation),
            Lists.<RuleFailureModel>newArrayList(referenceViolation));
    assertThat(mapping.size(), is(1));
    assertThat(newViolation.getCreatedAt(), is(referenceDate));
    assertThat(newViolation.isNew(), is(false));
  }
  @Test
  public void checksumShouldHaveGreaterPriorityThanLine() {
    RuleFailureModel referenceViolation1 = newReferenceViolation("message", 1, 50, "checksum1");
    RuleFailureModel referenceViolation2 = newReferenceViolation("message", 3, 50, "checksum2");

    Violation newViolation1 = newViolation("message", 3, 50, "checksum1");
    Violation newViolation2 = newViolation("message", 5, 50, "checksum2");

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation1, newViolation2),
            Lists.newArrayList(referenceViolation1, referenceViolation2));
    assertThat(mapping.get(newViolation1), equalTo(referenceViolation1));
    assertThat(newViolation1.isNew(), is(false));
    assertThat(mapping.get(newViolation2), equalTo(referenceViolation2));
    assertThat(newViolation2.isNew(), is(false));
  }
  @Test
  public void permanentIdShouldBeThePrioritaryFieldToCheck() {
    RuleFailureModel referenceViolation1 =
        newReferenceViolation("message", 10, 1, "checksum1").setPermanentId(100);
    RuleFailureModel referenceViolation2 =
        newReferenceViolation("message", 18, 1, "checksum2").setPermanentId(200);
    Violation newViolation =
        newViolation("message", 10, 1, "checksum1"); // exactly the fields of referenceViolation1
    newViolation.setPermanentId(200);

    Map<Violation, RuleFailureModel> mapping =
        decorator.mapViolations(
            Lists.newArrayList(newViolation),
            Lists.newArrayList(referenceViolation1, referenceViolation2));

    assertThat(mapping.get(newViolation), equalTo(referenceViolation2)); // same permanent id
    assertThat(newViolation.isNew(), is(false));
  }