### Question:
TermEditDistance { public double getNormalizedEditDistance(String source, String target) { ImmutableList<String> sourceTerms = NamingConventions.splitToLowercaseTerms(source); ImmutableList<String> targetTerms = NamingConventions.splitToLowercaseTerms(target); double[][] costMatrix = sourceTerms.stream() .map(s -> targetTerms.stream().mapToDouble(t -> editDistanceFn.apply(s, t)).toArray()) .toArray(double[][]::new); double[][] worstCaseMatrix = sourceTerms.stream() .map(s -> s.length()) .map( s -> targetTerms.stream() .map(t -> t.length()) .mapToDouble(t -> maxDistanceFn.apply(s, t)) .toArray()) .toArray(double[][]::new); double[] sourceTermDeletionCosts = sourceTerms.stream().mapToDouble(s -> maxDistanceFn.apply(s.length(), 0)).toArray(); double[] targetTermAdditionCosts = targetTerms.stream().mapToDouble(s -> maxDistanceFn.apply(0, s.length())).toArray(); int[] assignments = new HungarianAlgorithm(costMatrix).execute(); double assignmentCost = computeCost(assignments, costMatrix, sourceTermDeletionCosts, targetTermAdditionCosts); double maxCost = computeCost(assignments, worstCaseMatrix, sourceTermDeletionCosts, targetTermAdditionCosts); return assignmentCost / maxCost; } TermEditDistance(
      BiFunction<String, String, Double> editDistanceFn,
      BiFunction<Integer, Integer, Double> maxDistanceFn);  TermEditDistance(); double getNormalizedEditDistance(String source, String target);  }### Answer:
@Test public void getNormalizedEditDistance_returnsMatch_withPermutedTerms() { TermEditDistance termEditDistance = new TermEditDistance(); String sourceIdentifier = "fooBarBaz"; String targetIdentifier = "bazFooBar"; double distance = termEditDistance.getNormalizedEditDistance(sourceIdentifier, targetIdentifier); assertThat(distance).isEqualTo(0.0); }
@Test public void getNormalizedEditDistance_isSymmetric_withExtraTerm() { TermEditDistance termEditDistance = new TermEditDistance(); String identifier = "fooBarBaz"; String otherIdentifier = "barBaz"; double distanceFwd = termEditDistance.getNormalizedEditDistance(identifier, otherIdentifier); double distanceBwd = termEditDistance.getNormalizedEditDistance(otherIdentifier, identifier); assertThat(distanceFwd).isEqualTo(distanceBwd); }
@Test public void getNormalizedEditDistance_returnsNoMatch_withDifferentTerms() { TermEditDistance termEditDistance = new TermEditDistance((s, t) -> s.equals(t) ? 0.0 : 1.0, (s, t) -> 1.0); String sourceIdentifier = "fooBar"; String targetIdentifier = "bazQux"; double distance = termEditDistance.getNormalizedEditDistance(sourceIdentifier, targetIdentifier); assertThat(distance).isEqualTo(1.0); }