// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.fixes;

import static com.google.common.truth.Truth.assertThat;

import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Before;
import org.junit.Test;

public class StringModifierTest extends GerritBaseTests {
  private final String originalString = "This is the original, unmodified string.";
  private StringModifier stringModifier;

  @Before
  public void setUp() {
    stringModifier = new StringModifier(originalString);
  }

  @Test
  public void singlePartIsReplaced() {
    stringModifier.replace(0, 11, "An");
    String modifiedString = stringModifier.getResult();
    assertThat(modifiedString).isEqualTo("An original, unmodified string.");
  }

  @Test
  public void twoPartsCanBeReplacedWithInsertionFirst() {
    stringModifier.replace(5, 5, "string ");
    stringModifier.replace(8, 39, "a modified version");
    String modifiedString = stringModifier.getResult();
    assertThat(modifiedString).isEqualTo("This string is a modified version.");
  }

  @Test
  public void twoPartsCanBeReplacedWithDeletionFirst() {
    stringModifier.replace(0, 8, "");
    stringModifier.replace(12, 32, "modified");
    String modifiedString = stringModifier.getResult();
    assertThat(modifiedString).isEqualTo("the modified string.");
  }

  @Test
  public void replacedPartsMayTouch() {
    stringModifier.replace(0, 8, "");
    stringModifier.replace(8, 32, "The modified");
    String modifiedString = stringModifier.getResult();
    assertThat(modifiedString).isEqualTo("The modified string.");
  }

  @Test
  public void replacedPartsMustNotOverlap() {
    stringModifier.replace(0, 9, "");
    exception.expect(StringIndexOutOfBoundsException.class);
    stringModifier.replace(8, 32, "The modified");
  }

  @Test
  public void startIndexMustNotBeGreaterThanEndIndex() {
    exception.expect(StringIndexOutOfBoundsException.class);
    stringModifier.replace(10, 9, "something");
  }

  @Test
  public void startIndexMustNotBeNegative() {
    exception.expect(StringIndexOutOfBoundsException.class);
    stringModifier.replace(-1, 9, "something");
  }

  @Test
  public void newContentCanBeInsertedAtEndOfString() {
    stringModifier.replace(
        originalString.length(), originalString.length(), " And this an addition.");
    String modifiedString = stringModifier.getResult();
    assertThat(modifiedString)
        .isEqualTo("This is the original, unmodified string. And this an addition.");
  }

  @Test
  public void startIndexMustNotBeGreaterThanLengthOfString() {
    exception.expect(StringIndexOutOfBoundsException.class);
    stringModifier.replace(originalString.length() + 1, originalString.length() + 1, "something");
  }

  @Test
  public void endIndexMustNotBeGreaterThanLengthOfString() {
    exception.expect(StringIndexOutOfBoundsException.class);
    stringModifier.replace(8, originalString.length() + 1, "something");
  }
}
