/** * Given: * <pre> * b: 1 2 3 4 1 2 3 4 1 2 3 4 * c: 1 2 3 4 * a: 1 2 3 5 * </pre> * Expected: * <pre> * a-b-b-b-c (1 2 3) * </pre> */ @Test public void example2() { CloneIndex index = createIndex( newBlocks("b", "1 2 3 4 1 2 3 4 1 2 3 4"), newBlocks("c", "1 2 3 4")); Block[] fileBlocks = newBlocks("a", "1 2 3 5"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(1)); assertThat(result, hasCloneGroup(3, newClonePart("a", 0, 3), newClonePart("b", 0, 3), newClonePart("b", 4, 3), newClonePart("b", 8, 3), newClonePart("c", 0, 3))); }
protected static Block[] newBlocks(String resourceId, String hashes) { List<Block> result = new ArrayList<>(); int indexInFile = 0; for (int i = 0; i < hashes.length(); i += 2) { Block block = newBlock(resourceId, new ByteArray("0" + hashes.charAt(i)), indexInFile); result.add(block); indexInFile++; } return result.toArray(new Block[result.size()]); }
/** * Given: file with repeated hashes * Expected: only one query of index for each unique hash */ @Test public void only_one_query_of_index_for_each_unique_hash() { CloneIndex index = spy(createIndex()); Block[] fileBlocks = newBlocks("a", "1 2 1 2"); detect(index, fileBlocks); verify(index).getBySequenceHash(new ByteArray("01")); verify(index).getBySequenceHash(new ByteArray("02")); verifyNoMoreInteractions(index); }
CloneIndex cloneIndex = createIndex(); Block.Builder block = Block.builder() .setResourceId("a") block.setBlockHash(new ByteArray("1".getBytes())).setIndexInFile(2).build() }; List<CloneGroup> clones = detect(cloneIndex, fileBlocks); print(clones); assertThat(clones.size(), is(1)); Iterator<CloneGroup> clonesIterator = clones.iterator();
/** * Given: empty list of blocks for file * Expected: {@link Collections#EMPTY_LIST} */ @Test public void shouldReturnEmptyListWhenNoBlocksForFile() { List<CloneGroup> result = detect(null, new Block[0]); assertThat(result, sameInstance(Collections.EMPTY_LIST)); }
/** * Given: * <pre> * b: 1 2 3 4 * a: 1 2 3 * </pre> * Expected clone which ends at the end of file "a": * <pre> * a-b (1 2 3) * </pre> */ @Test public void problemWithEndOfFile() { CloneIndex cloneIndex = createIndex( newBlocks("b", "1 2 3 4")); Block[] fileBlocks = newBlocks("a", "1 2 3"); List<CloneGroup> clones = detect(cloneIndex, fileBlocks); print(clones); assertThat(clones.size(), is(1)); assertThat(clones, hasCloneGroup(3, newClonePart("a", 0, 3), newClonePart("b", 0, 3))); }
/** * Given: * <pre> * a: 1 2 3 * b: 1 2 4 * a: 1 2 5 * </pre> * Expected: * <pre> * a-b (1 2) - instead of "a-a-b", which will be the case if file from index not ignored * </pre> */ @Test public void fileAlreadyInIndex() { CloneIndex index = createIndex( newBlocks("a", "1 2 3"), newBlocks("b", "1 2 4")); // Note about blocks with hashes "3", "4" and "5": those blocks here in order to not face another problem - with EOF (see separate test) Block[] fileBlocks = newBlocks("a", "1 2 5"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(1)); assertThat(result, hasCloneGroup(2, newClonePart("a", 0, 2), newClonePart("b", 0, 2))); }
/** * Test for problem, which was described in original paper - same clone would be reported twice. * Given: * <pre> * a: 1 2 3 1 2 4 * </pre> * Expected only one clone: * <pre> * a-a (1 2) * </pre> */ @Test public void clonesInFileItself() { CloneIndex index = createIndex(); Block[] fileBlocks = newBlocks("a", "1 2 3 1 2 4"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(1)); assertThat(result, hasCloneGroup(2, newClonePart("a", 0, 2), newClonePart("a", 3, 2))); }
/** * Given: * <pre> * a: 2 3 4 5 * b: 3 4 * c: 1 2 3 4 5 6 * </pre> * Expected: * <pre> * c-a (2 3 4 5) * c-a-b (3 4) * </pre> */ @Test public void exampleFromPaperWithModifiedResourceIds() { CloneIndex cloneIndex = createIndex( newBlocks("a", "2 3 4 5"), newBlocks("b", "3 4")); Block[] fileBlocks = newBlocks("c", "1 2 3 4 5 6"); List<CloneGroup> clones = detect(cloneIndex, fileBlocks); print(clones); assertThat(clones.size(), is(2)); assertThat(clones, hasCloneGroup(4, newClonePart("c", 1, 4), newClonePart("a", 0, 4))); assertThat(clones, hasCloneGroup(2, newClonePart("c", 2, 2), newClonePart("a", 1, 2), newClonePart("b", 0, 2))); }
/** * Given: * <pre> * y: 2 3 4 5 * z: 3 4 * x: 1 2 3 4 5 6 * </pre> * Expected: * <pre> * x-y (2 3 4 5) * x-y-z (3 4) * </pre> */ @Test public void exampleFromPaper() { CloneIndex index = createIndex( newBlocks("y", "2 3 4 5"), newBlocks("z", "3 4")); Block[] fileBlocks = newBlocks("x", "1 2 3 4 5 6"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertEquals(2, result.size()); assertThat(result, hasCloneGroup(4, newClonePart("x", 1, 4), newClonePart("y", 0, 4))); assertThat(result, hasCloneGroup(2, newClonePart("x", 2, 2), newClonePart("y", 1, 2), newClonePart("z", 0, 2))); }
/** * Given: * <pre> * b: 1 2 1 2 * a: 1 2 1 * </pre> * Expected: * <pre> * a-b-b (1 2) * a-b (1 2 1) * </pre> * "a-a-b-b (1)" should not be reported, because fully covered by "a-b (1 2 1)" */ @Test public void covered() { CloneIndex index = createIndex( newBlocks("b", "1 2 1 2")); Block[] fileBlocks = newBlocks("a", "1 2 1"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(2)); assertThat(result, hasCloneGroup(3, newClonePart("a", 0, 3), newClonePart("b", 0, 3))); assertThat(result, hasCloneGroup(2, newClonePart("a", 0, 2), newClonePart("b", 0, 2), newClonePart("b", 2, 2))); }
/** * Given: * <pre> * b: 1 2 1 2 1 2 1 * a: 1 2 1 2 1 2 * </pre> * Expected: * <pre> * a-b-b (1 2 1 2 1) - note that there is overlapping among parts for "b" * a-b (1 2 1 2 1 2) * </pre> */ @Test public void problemWithNestedCloneGroups() { CloneIndex index = createIndex( newBlocks("b", "1 2 1 2 1 2 1")); Block[] fileBlocks = newBlocks("a", "1 2 1 2 1 2"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(2)); assertThat(result, hasCloneGroup(6, newClonePart("a", 0, 6), newClonePart("b", 0, 6))); assertThat(result, hasCloneGroup(5, newClonePart("a", 0, 5), newClonePart("b", 0, 5), newClonePart("b", 2, 5))); }
CloneIndex index = createIndex( newBlocks("b", "3 4 5 6"), newBlocks("c", "5 6 7")); Block[] fileBlocks = newBlocks("a", "1 2 3 4 5 6 7 8 9"); List<CloneGroup> result = detect(index, fileBlocks); print(result); assertThat(result.size(), is(3)); newClonePart("a", 2, 4), newClonePart("b", 0, 4))); newClonePart("a", 4, 3), newClonePart("c", 0, 3))); newClonePart("a", 4, 2), newClonePart("b", 2, 2), newClonePart("c", 0, 2)));