/*
 * Copyright 2014 The Closure Compiler Authors.
 *
 * 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.javascript.jscomp;

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

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public final class UniqueIdSupplierTest {
  private UniqueIdSupplier uniqueIdSupplier;

  @Before
  public void setUp() {
    uniqueIdSupplier = new UniqueIdSupplier();
  }

  @Test
  public void testSingleCompilerInputGeneratesUniqueIds() {
    CompilerInput input = new CompilerInput(SourceFile.fromCode("tmp", "function foo() {}"));
    int fileHashCode = input.getSourceFile().getOriginalPath().hashCode();
    String inputHashString = (fileHashCode < 0) ? ("m" + -fileHashCode) : ("" + fileHashCode);

    String uniqueId1 = uniqueIdSupplier.getUniqueId(input);
    String uniqueId2 = uniqueIdSupplier.getUniqueId(input);
    assertThat(uniqueId1).isNotEmpty();
    assertThat(uniqueId2).isNotEmpty();
    assertThat(uniqueId1).isNotEqualTo(uniqueId2);
    assertThat(uniqueId1).contains(inputHashString + "$0");
    assertThat(uniqueId2).contains(inputHashString + "$1");
  }

  @Test
  public void testMultipleCompilerInputsGenerateUniqueIds() {
    CompilerInput input1 = new CompilerInput(SourceFile.fromCode("tmp1", "function foo() {}"));
    int inputHashCode1 = input1.getSourceFile().getOriginalPath().hashCode();
    String inputHashString1 =
        (inputHashCode1 < 0) ? ("m" + -inputHashCode1) : ("" + inputHashCode1);

    CompilerInput input2 = new CompilerInput(SourceFile.fromCode("tmp2", "function foo() {}"));
    int inputHashCode2 = input2.getSourceFile().getOriginalPath().hashCode();
    String inputHashString2 =
        (inputHashCode2 < 0) ? ("m" + -inputHashCode2) : ("" + inputHashCode2);

    String uniqueId1 = uniqueIdSupplier.getUniqueId(input1);
    String uniqueId2 = uniqueIdSupplier.getUniqueId(input2);
    assertThat(uniqueId1).isNotEmpty();
    assertThat(uniqueId2).isNotEmpty();
    assertThat(uniqueId1).isNotEqualTo(uniqueId2);
    assertThat(uniqueId1).contains(inputHashString1 + "$0");
    assertThat(uniqueId2).contains(inputHashString2 + "$0");
  }

  /** Ensures that unique Ids generated are the same across compiler runs */
  @Test
  public void testGeneratedIdsAreDeterministicAcrossRuns() {
    Compiler compiler1 = new Compiler();
    Compiler compiler2 = new Compiler();

    CompilerInput input1 = new CompilerInput(SourceFile.fromCode("tmp", "function foo() {}"));
    CompilerInput input2 = new CompilerInput(SourceFile.fromCode("tmp", "function foo() {}"));

    String uniqueId1 = compiler1.getUniqueIdSupplier().getUniqueId(input1);
    String differentUniqueId1 = compiler1.getUniqueIdSupplier().getUniqueId(input1);

    String uniqueId2 = compiler2.getUniqueIdSupplier().getUniqueId(input2);

    assertThat(uniqueId1).isNotEmpty();
    assertThat(uniqueId2).isNotEmpty();
    assertThat(uniqueId1)
        .isEqualTo(uniqueId2); // differnt IDs for same input with different compilers
    assertThat(uniqueId1)
        .isNotEqualTo(differentUniqueId1); // different IDs for same input with same compiler
  }
}

@@ -1715,32 +1715,1304 @@
 g + %22$1%22);%0A  %7D%0A%0A
+  @Test%0A  public void testFilePathsHavingSameHashCode_generatesConflictingNames() %7B%0A    // Strings %22FB%22 and %22Ea%22 generate the same hashcode, and consequently the same IDs.%0A    CompilerInput input1 = new CompilerInput(SourceFile.fromCode(%22FB%22, %22function foo() %7B%7D%22));%0A    CompilerInput input2 = new CompilerInput(SourceFile.fromCode(%22Ea%22, %22function foo() %7B%7D%22));%0A%0A    String uniqueId1 = uniqueIdSupplier.getUniqueId(input1);%0A    String uniqueId2 = uniqueIdSupplier.getUniqueId(input2);%0A    assertThat(uniqueId1).isNotEmpty();%0A    assertThat(uniqueId2).isNotEmpty();%0A    // TODO(b/184589799.): Fix this to generate unique IDs.%0A    assertThat(uniqueId1).isEqualTo(uniqueId2);%0A%0A    int fileHashCode1 = input1.getSourceFile().getOriginalPath().hashCode();%0A    int fileHashCode2 = input2.getSourceFile().getOriginalPath().hashCode();%0A    String inputHashString1 = (fileHashCode1 %3C 0) ? (%22m%22 + -fileHashCode1) : (%22%22 + fileHashCode1);%0A    String inputHashString2 = (fileHashCode2 %3C 0) ? (%22m%22 + -fileHashCode2) : (%22%22 + fileHashCode2);%0A    // TODO(b/184589799): Fix this to generate unique IDs.%0A    assertThat(inputHashString1).isEqualTo(inputHashString2);%0A    assertThat(uniqueId1).contains(inputHashString1 + %22$0%22);%0A    assertThat(uniqueId2).contains(inputHashString2 + %22$0%22);%0A  %7D%0A%0A
   @Test%0A  public

Add unit test to show how unique ID supplier can generate conflicting IDs