This is an automated email from the ASF dual-hosted git repository.
delei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fesod.git
The following commit(s) were added to refs/heads/main by this push:
new 1fb95727 test: add tests for EscapeHexCellWriteHandler (#1001)
1fb95727 is described below
commit 1fb95727b222f141b3ca30a19aa8a17a2a39803b
Author: Nikita Kuprins <[email protected]>
AuthorDate: Sat Aug 15 14:46:00 2026 +0300
test: add tests for EscapeHexCellWriteHandler (#1001)
* test: add tests for escape-hex-write-handler
* fix: give the escape-hex round-trip its own class and tag
* fix: read the round-trip csv as utf-8
* fix: mock the cell instead of a real workbook
* test: cover the non-SXSSF cell branch
---------
Co-authored-by: ian zhang <[email protected]>
Co-authored-by: DeleiGuo <[email protected]>
---
.../EscapeHexCellWriteHandlerRoundTripTest.java | 84 ++++++++++++++
.../handler/EscapeHexCellWriteHandlerTest.java | 124 +++++++++++++++++++++
2 files changed, 208 insertions(+)
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerRoundTripTest.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerRoundTripTest.java
new file mode 100644
index 00000000..6227dca3
--- /dev/null
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerRoundTripTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.fesod.sheet.write.handler;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.fesod.sheet.FesodSheet;
+import org.apache.fesod.sheet.testkit.Tags;
+import org.apache.fesod.sheet.testkit.base.AbstractExcelTest;
+import org.apache.fesod.sheet.testkit.enums.ExcelFormat;
+import org.apache.fesod.sheet.testkit.params.ExcelFormatSource;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.xssf.streaming.SXSSFCell;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+
+@Tag(Tags.ROUND_TRIP)
+class EscapeHexCellWriteHandlerRoundTripTest extends AbstractExcelTest {
+
+ private File writeEscapedWorkbook(ExcelFormat format) throws IOException {
+ File file = createTempFile("escape-hex", format);
+ List<List<String>> rows = new ArrayList<>();
+ rows.add(Collections.singletonList("_xB9f0_ and _x1234_"));
+
+ FesodSheet.write(file)
+ .excelType(format.toExcelTypeEnum())
+
.head(Collections.singletonList(Collections.singletonList("value")))
+ .registerWriteHandler(new EscapeHexCellWriteHandler())
+ .sheet("escape")
+ .doWrite(rows);
+ return file;
+ }
+
+ private String readBackFirstDataValue(File file, ExcelFormat format)
throws IOException {
+ if (format == ExcelFormat.CSV) {
+ try (BufferedReader reader =
Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
+ reader.readLine(); // header
+ return reader.readLine();
+ }
+ }
+ try (Workbook workbook = WorkbookFactory.create(file)) {
+ return
workbook.getSheetAt(0).getRow(1).getCell(0).getStringCellValue();
+ }
+ }
+
+ /**
+ * Writes a file with the handler registered and reads it back: the caller
must see the literal they typed.
+ *
+ * <p>All three formats expect the same value, for different reasons. On
XLSX the handler escapes the sequence
+ * and POI's reader decodes that escape away again. On XLS and CSV the
handler never fires, since it only
+ * touches {@link SXSSFCell}, so there was nothing to undo.
+ */
+ @ParameterizedTest(name = "[{index}] {0} round-trips the literal hex
sequence")
+ @ExcelFormatSource
+ void
registeredOnAWrite_keepsLiteralHexSequencesIntactAcrossFormats(ExcelFormat
format) throws IOException {
+ File file = writeEscapedWorkbook(format);
+ Assertions.assertEquals("_xB9f0_ and _x1234_",
readBackFirstDataValue(file, format));
+ }
+}
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerTest.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerTest.java
new file mode 100644
index 00000000..f751594e
--- /dev/null
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/write/handler/EscapeHexCellWriteHandlerTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.fesod.sheet.write.handler;
+
+import org.apache.fesod.sheet.enums.CellDataTypeEnum;
+import org.apache.fesod.sheet.metadata.data.WriteCellData;
+import org.apache.fesod.sheet.testkit.Tags;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.xssf.streaming.SXSSFCell;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.Mockito;
+
+@Tag(Tags.UNIT)
+class EscapeHexCellWriteHandlerTest {
+
+ private final EscapeHexCellWriteHandler handler = new
EscapeHexCellWriteHandler();
+
+ /**
+ * The handler only checks that the cell is an {@link SXSSFCell} and never
reads from it, so a mock is all it
+ * needs.
+ */
+ private final SXSSFCell cell = Mockito.mock(SXSSFCell.class);
+
+ /**
+ * Runs the handler over a string cell and returns the value it left
behind.
+ */
+ private String escape(String input) {
+ WriteCellData<?> cellData = new WriteCellData<>(input);
+ handler.afterCellDataConverted(null, null, cellData, cell, null, 0,
Boolean.FALSE);
+ return cellData.getStringValue();
+ }
+
+ @ParameterizedTest(name = "[{index}] {0} -> {1}")
+ @CsvSource(
+ delimiter = '|',
+ value = {
+ "_xB9f0_|_x005F_xB9f0_",
+ "abc_x0041_|abc_x005F_x0041_",
+ "_x0041__x0042_|_x005F_x0041__x005F_x0042_",
+ "_xB9f0_ and _x1234_ and _xABCD_|_x005F_xB9f0_ and
_x005F_x1234_ and _x005F_xABCD_",
+ // 3 below check for partially valid cases - 1st format is
valid, 2nd is invalid.
+ "_x1234_ _xGHIJ_|_x005F_x1234_ _xGHIJ_",
+ "_x0041__x12|_x005F_x0041__x12",
+ "_x0041__x12345|_x005F_x0041__x12345",
+ })
+ void afterCellDataConverted_escapesEveryValidHexPattern(String input,
String expected) {
+ Assertions.assertEquals(expected, escape(input));
+ }
+
+ @ParameterizedTest(name = "[{index}] {0} is left alone")
+ @ValueSource(
+ strings = {
+ "normalString",
+ "_x12345_", // seventh character is not underscore
+ "_x0041", // one character short of a complete pattern
+ "_x00G1_", // a non-hex character
+ "_x_x0041", // an unterminated pattern
+ "", // empty input must not trip the scan
+ "_x00é1_", // a non-ASCII character
+ "_X1234_", // uppercase X
+ })
+ void afterCellDataConverted_leavesInvalidPatternsUntouched(String input) {
+ Assertions.assertEquals(input, escape(input));
+ }
+
+ /**
+ * Escaping is not idempotent: an already-escaped literal is escaped again
+ */
+ @Test
+ void afterCellDataConverted_escapesAnAlreadyEscapedSequenceAgain() {
+ Assertions.assertEquals("_x005F_x005F_x0041_",
escape("_x005F_x0041_"));
+ }
+
+ @Test
+ void afterCellDataConverted_ignoresNonStringCellData() {
+ WriteCellData<?> cellData = new
WriteCellData<>(CellDataTypeEnum.ERROR, "_x0041_");
+
+ handler.afterCellDataConverted(null, null, cellData, cell, null, 0,
Boolean.FALSE);
+
+ Assertions.assertEquals("_x0041_", cellData.getStringValue());
+ }
+
+ @Test
+ void afterCellDataConverted_ignoresNonSxssfCells() {
+ WriteCellData<?> cellData = new WriteCellData<>("_x0041_");
+
+ handler.afterCellDataConverted(null, null, cellData,
Mockito.mock(HSSFCell.class), null, 0, Boolean.FALSE);
+
+ Assertions.assertEquals("_x0041_", cellData.getStringValue());
+ }
+
+ @Test
+ void afterCellDataConverted_toleratesNullCellDataAndNullStringValue() {
+ WriteCellData<?> emptyStringData = new
WriteCellData<>(CellDataTypeEnum.STRING);
+
+ Assertions.assertDoesNotThrow(
+ () -> handler.afterCellDataConverted(null, null, null, cell,
null, 0, Boolean.FALSE));
+ Assertions.assertDoesNotThrow(
+ () -> handler.afterCellDataConverted(null, null,
emptyStringData, cell, null, 0, Boolean.FALSE));
+ Assertions.assertNull(emptyStringData.getStringValue());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]