Skip to content

Commit

Permalink
feat: Add DuplicateRowConstraint with unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
r4tylmz committed Oct 7, 2024
1 parent 0cd5351 commit 25e17ce
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,43 @@

import com.r4tylmz.betterpoi.annotation.BPSheet;
import com.r4tylmz.betterpoi.constraint.RowConstraint;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class DuplicateRowConstraint implements RowConstraint {
DataFormatter dataFormatter = new DataFormatter();

private String hashRow(Row row, int colSize) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < colSize; i++) {
Cell cell = row.getCell(i);
if (cell != null) {
sb.append(dataFormatter.formatCellValue(cell));
sb.append("###;###");
}
}
return sb.toString();
}

@Override
public Map<Integer, String> validate(Sheet sheet, BPSheet bpSheet) {
// TODO: Implement this method to validate the row.
return Collections.emptyMap();
Set<String> rowSet = new HashSet<>();
Map<Integer, String> rowViolationMap = new HashMap<>();
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row != null && rowSet.contains(hashRow(row, bpSheet.columns().length))) {
rowViolationMap.put(i, String.format("Duplicate row found at row %d", i + 1));
} else {
rowSet.add(hashRow(row, bpSheet.columns().length));
}
}
return rowViolationMap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.r4tylmz.betterpoi.validation.row;

import com.r4tylmz.betterpoi.annotation.BPColumn;
import com.r4tylmz.betterpoi.annotation.BPSheet;
import com.r4tylmz.betterpoi.test.EmployeeWorkbookTest;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.Map;

import static org.junit.Assert.assertEquals;

public class DuplicateRowConstraintTest extends EmployeeWorkbookTest {

private final String errorMessage = "Duplicate row found at row %d";
private DuplicateRowConstraint duplicateRowConstraint;

@Before
public void createRowDuplicateConstraint() throws Exception {
duplicateRowConstraint = new DuplicateRowConstraint();
}

private void createSheetWithHeaders(String[] headers) {
Row row = getRow(headers.length);
for (int i = 0; i < headers.length; i++) {
row.getCell(i).setCellValue(headers[i]);
}
}

private Sheet getSheetWithHeaders(String[] headers) {
createSheetWithHeaders(headers);
return workbook.getSheet("testSheet");
}

@Test
public void validate_duplicateRow() {
String[] headers = {"header1", "header2", "header3"};
Sheet sheet = getSheetWithHeaders(headers);
BPSheet bpSheet = Mockito.mock(BPSheet.class);
BPColumn bpColumn1 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn1.headerTitle()).thenReturn("header1");
BPColumn bpColumn2 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn2.headerTitle()).thenReturn("header2");
BPColumn bpColumn3 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn3.headerTitle()).thenReturn("header3");

BPColumn[] bpColumns = {bpColumn1, bpColumn2, bpColumn3};
Mockito.when(bpSheet.columns()).thenReturn(bpColumns);

Row row1 = sheet.createRow(1);
for (int i = 0; i < headers.length; i++) {
Cell cell = row1.createCell(i);
cell.setCellValue("random value" + i);
}
Row row2 = sheet.createRow(2);
for (int i = 0; i < headers.length; i++) {
Cell cell = row2.createCell(i);
cell.setCellValue("random value" + i);
}

Map<Integer, String> errorMap = duplicateRowConstraint.validate(sheet, bpSheet);
assertEquals(1, errorMap.size());
assertEquals(String.format(errorMessage, 3), errorMap.get(2));
}

@Test
public void validate_emptySheet() {
Sheet sheet = workbook.createSheet("testSheet");
BPSheet bpSheet = Mockito.mock(BPSheet.class);
BPColumn bpColumn1 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn1.headerTitle()).thenReturn("header1");
BPColumn bpColumn2 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn2.headerTitle()).thenReturn("header2");
BPColumn bpColumn3 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn3.headerTitle()).thenReturn("header3");

BPColumn[] bpColumns = {bpColumn1, bpColumn2, bpColumn3};
Mockito.when(bpSheet.columns()).thenReturn(bpColumns);

Map<Integer, String> errorMap = duplicateRowConstraint.validate(sheet, bpSheet);
assertEquals(0, errorMap.size());
}

@Test
public void validate_noDuplicateRow() {
String[] headers = {"header1", "header2", "header3"};
Sheet sheet = getSheetWithHeaders(headers);
BPSheet bpSheet = Mockito.mock(BPSheet.class);
BPColumn bpColumn1 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn1.headerTitle()).thenReturn("header1");
BPColumn bpColumn2 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn2.headerTitle()).thenReturn("header2");
BPColumn bpColumn3 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn3.headerTitle()).thenReturn("header3");

BPColumn[] bpColumns = {bpColumn1, bpColumn2, bpColumn3};
Mockito.when(bpSheet.columns()).thenReturn(bpColumns);

Row row1 = sheet.createRow(1);
for (int i = 0; i < headers.length; i++) {
Cell cell = row1.createCell(i);
cell.setCellValue("random value" + i);
}
Row row2 = sheet.createRow(2);
for (int i = 0; i < headers.length; i++) {
Cell cell = row2.createCell(i);
cell.setCellValue("value" + i);
}

Map<Integer, String> errorMap = duplicateRowConstraint.validate(sheet, bpSheet);
assertEquals(0, errorMap.size());
}

@Test
public void validate_singleRow() {
String[] headers = {"header1", "header2", "header3"};
Sheet sheet = getSheetWithHeaders(headers);
BPSheet bpSheet = Mockito.mock(BPSheet.class);
BPColumn bpColumn1 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn1.headerTitle()).thenReturn("header1");
BPColumn bpColumn2 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn2.headerTitle()).thenReturn("header2");
BPColumn bpColumn3 = Mockito.mock(BPColumn.class);
Mockito.when(bpColumn3.headerTitle()).thenReturn("header3");

BPColumn[] bpColumns = {bpColumn1, bpColumn2, bpColumn3};
Mockito.when(bpSheet.columns()).thenReturn(bpColumns);

Row row1 = sheet.createRow(1);
for (int i = 0; i < headers.length; i++) {
Cell cell = row1.createCell(i);
cell.setCellValue("random value" + i);
}

Map<Integer, String> errorMap = duplicateRowConstraint.validate(sheet, bpSheet);
assertEquals(0, errorMap.size());
}
}

0 comments on commit 25e17ce

Please sign in to comment.