diff --git a/PERF/cdm-v4.properties b/PERF/cdm-v4.properties
index 424602f3..6f88489f 100644
--- a/PERF/cdm-v4.properties
+++ b/PERF/cdm-v4.properties
@@ -216,6 +216,10 @@ spark.cdm.perfops.writeRateLimit 5000
# as Epoch milliseconds
# TIMESTAMP_STRING_FORMAT : timestamp stored in a String,
# with a custom format
+# POLYGON_TYPE : PolygonType geospatial DSE type
+# POINT_TYPE : PointType geospatial DSE type
+# LINE_STRING : LineStringType geospatial DSE type
+# DATE_RANGE : DateRange DSE type
#
# *** NOTE where there are multiple type pair options, such as with
# *** TIMESTAMP_STRING, only one can be configured at a time.
diff --git a/pom.xml b/pom.xml
index 5fb71789..278c1d57 100644
--- a/pom.xml
+++ b/pom.xml
@@ -143,6 +143,12 @@
log4j-to-slf4j
${log4j.version}
+
+ runtime
+ com.esri.geometry
+ esri-geometry-api
+ 2.2.0
+
@@ -326,7 +332,7 @@
LINE
MISSEDCOUNT
- 3073
+ 3085
diff --git a/src/main/java/com/datastax/cdm/cql/codec/CodecFactory.java b/src/main/java/com/datastax/cdm/cql/codec/CodecFactory.java
index b0c484f2..24a71104 100644
--- a/src/main/java/com/datastax/cdm/cql/codec/CodecFactory.java
+++ b/src/main/java/com/datastax/cdm/cql/codec/CodecFactory.java
@@ -1,6 +1,10 @@
package com.datastax.cdm.cql.codec;
import com.datastax.cdm.properties.PropertyHelper;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.LineStringCodec;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PointCodec;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PolygonCodec;
+import com.datastax.dse.driver.internal.core.type.codec.time.DateRangeCodec;
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import java.util.Arrays;
@@ -15,6 +19,11 @@ public static List> getCodecPair(PropertyHelper propertyHelper, Cod
case DECIMAL_STRING: return Arrays.asList(new DECIMAL_StringCodec(propertyHelper), new TEXT_BigDecimalCodec(propertyHelper));
case TIMESTAMP_STRING_MILLIS: return Arrays.asList(new TIMESTAMP_StringMillisCodec(propertyHelper), new TEXTMillis_InstantCodec(propertyHelper));
case TIMESTAMP_STRING_FORMAT: return Arrays.asList(new TIMESTAMP_StringFormatCodec(propertyHelper), new TEXTFormat_InstantCodec(propertyHelper));
+ case POLYGON_TYPE: return Arrays.asList(new PolygonCodec());
+ case POINT_TYPE: return Arrays.asList(new PointCodec());
+ case DATE_RANGE: return Arrays.asList(new DateRangeCodec());
+ case LINE_STRING: return Arrays.asList(new LineStringCodec());
+
default:
throw new IllegalArgumentException("Unknown codec: " + codec);
}
diff --git a/src/main/java/com/datastax/cdm/cql/codec/Codecset.java b/src/main/java/com/datastax/cdm/cql/codec/Codecset.java
index fe5d954f..d5ad2ee6 100644
--- a/src/main/java/com/datastax/cdm/cql/codec/Codecset.java
+++ b/src/main/java/com/datastax/cdm/cql/codec/Codecset.java
@@ -6,5 +6,9 @@ public enum Codecset {
BIGINT_STRING,
DECIMAL_STRING,
TIMESTAMP_STRING_MILLIS,
- TIMESTAMP_STRING_FORMAT
+ TIMESTAMP_STRING_FORMAT,
+ POINT_TYPE,
+ POLYGON_TYPE,
+ DATE_RANGE,
+ LINE_STRING
}
diff --git a/src/main/java/com/datastax/cdm/data/CqlData.java b/src/main/java/com/datastax/cdm/data/CqlData.java
index e5e40a6b..3141ef09 100644
--- a/src/main/java/com/datastax/cdm/data/CqlData.java
+++ b/src/main/java/com/datastax/cdm/data/CqlData.java
@@ -1,5 +1,6 @@
package com.datastax.cdm.data;
+import com.datastax.dse.driver.api.core.type.DseDataTypes;
import com.datastax.oss.driver.api.core.data.UdtValue;
import com.datastax.oss.driver.api.core.type.*;
@@ -39,6 +40,10 @@ public enum Type {
primitiveDataTypeToJavaClassMap.put(DataTypes.TIMEUUID, java.util.UUID.class);
primitiveDataTypeToJavaClassMap.put(DataTypes.COUNTER, Long.class);
primitiveDataTypeToJavaClassMap.put(DataTypes.DURATION, com.datastax.oss.driver.api.core.data.CqlDuration.class);
+ primitiveDataTypeToJavaClassMap.put(DseDataTypes.POLYGON, com.datastax.dse.driver.api.core.data.geometry.Polygon.class);
+ primitiveDataTypeToJavaClassMap.put(DseDataTypes.POINT, com.datastax.dse.driver.api.core.data.geometry.Point.class);
+ primitiveDataTypeToJavaClassMap.put(DseDataTypes.LINE_STRING, com.datastax.dse.driver.api.core.data.geometry.LineString.class);
+ primitiveDataTypeToJavaClassMap.put(DseDataTypes.DATE_RANGE, com.datastax.dse.driver.api.core.data.time.DateRange.class);
}
public static Type toType(DataType dataType) {
diff --git a/src/test/java/com/datastax/cdm/cql/codec/CodecFactoryTest.java b/src/test/java/com/datastax/cdm/cql/codec/CodecFactoryTest.java
new file mode 100644
index 00000000..45ec4838
--- /dev/null
+++ b/src/test/java/com/datastax/cdm/cql/codec/CodecFactoryTest.java
@@ -0,0 +1,114 @@
+package com.datastax.cdm.cql.codec;
+
+import com.datastax.cdm.data.MockitoExtension;
+import com.datastax.cdm.properties.PropertyHelper;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.LineStringCodec;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PointCodec;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PolygonCodec;
+import com.datastax.dse.driver.internal.core.type.codec.time.DateRangeCodec;
+import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(MockitoExtension.class)
+class CodecFactoryTest {
+ @Mock
+ private PropertyHelper propertyHelper;
+
+ @BeforeEach
+ void setUp() {
+ //Mockito.when(propertyHelper.getString("timestamp.format")).thenReturn("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForPolygonType() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.POLYGON_TYPE);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof PolygonCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForIntString() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.INT_STRING);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof INT_StringCodec);
+ assertTrue(codecs.get(1) instanceof TEXT_IntegerCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForDoubleString() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.DOUBLE_STRING);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof DOUBLE_StringCodec);
+ assertTrue(codecs.get(1) instanceof TEXT_DoubleCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForBigintString() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.BIGINT_STRING);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof BIGINT_StringCodec);
+ assertTrue(codecs.get(1) instanceof TEXT_LongCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForDecimalString() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.DECIMAL_STRING);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof DECIMAL_StringCodec);
+ assertTrue(codecs.get(1) instanceof TEXT_BigDecimalCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForTimestampStringMillis() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.TIMESTAMP_STRING_MILLIS);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof TIMESTAMP_StringMillisCodec);
+ assertTrue(codecs.get(1) instanceof TEXTMillis_InstantCodec);
+ }
+
+// @Test
+// void getCodecPair_ShouldReturnCorrectCodecsForTimestampStringFormat() {
+// Mockito.when(propertyHelper.getString("timestamp.format")).thenReturn("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+// List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.TIMESTAMP_STRING_FORMAT);
+// assertFalse(codecs.isEmpty());
+// assertTrue(codecs.get(0) instanceof TIMESTAMP_StringFormatCodec);
+// assertTrue(codecs.get(1) instanceof TEXTFormat_InstantCodec);
+// }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForPointType() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.POINT_TYPE);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof PointCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForDateRange() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.DATE_RANGE);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof DateRangeCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldReturnCorrectCodecsForLineString() {
+ List> codecs = CodecFactory.getCodecPair(propertyHelper, Codecset.LINE_STRING);
+ assertFalse(codecs.isEmpty());
+ assertTrue(codecs.get(0) instanceof LineStringCodec);
+ }
+
+ @Test
+ void getCodecPair_ShouldThrowExceptionForUnknownCodec() {
+ assertThrows(NullPointerException.class, () -> {
+ CodecFactory.getCodecPair(propertyHelper, null);
+ });
+ }
+
+}
diff --git a/src/test/java/com/datastax/cdm/cql/codec/DATERANGETYPE_CodecTest.java b/src/test/java/com/datastax/cdm/cql/codec/DATERANGETYPE_CodecTest.java
new file mode 100644
index 00000000..45c9f366
--- /dev/null
+++ b/src/test/java/com/datastax/cdm/cql/codec/DATERANGETYPE_CodecTest.java
@@ -0,0 +1,127 @@
+package com.datastax.cdm.cql.codec;
+
+import com.datastax.dse.driver.api.core.data.time.DateRange;
+import com.datastax.dse.driver.internal.core.type.codec.time.DateRangeCodec;
+import com.datastax.oss.driver.api.core.ProtocolVersion;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class DATERANGETYPE_CodecTest {
+
+ private DateRangeCodec codec;
+ private final ProtocolVersion protocolVersion = ProtocolVersion.DEFAULT;
+
+ @BeforeEach
+ void setUp() {
+ codec = new DateRangeCodec();
+ }
+
+ @Test
+ void encode_ShouldEncodeDateRangeToByteBuffer() throws ParseException {
+ String dateRangeString = "2001-01-01";
+ DateRange dateRange;
+ try {
+ dateRange = DateRange.parse(dateRangeString);
+ } catch (ParseException e) {
+ fail("Failed to parse the date range: " + e.getMessage());
+ return;
+ }
+
+ // Encode the DateRange object
+ ByteBuffer encoded = codec.encode(dateRange, protocolVersion);
+
+ // Assertions
+ assertNotNull(encoded);
+ assertTrue(encoded.remaining() > 0);
+
+ // Decode the ByteBuffer back to a DateRange and compare
+ DateRange decoded = codec.decode(encoded, protocolVersion);
+ assertEquals(dateRange, decoded);
+ }
+
+ @Test
+ void decode_ShouldDecodeByteBufferToDateRange() throws ParseException {
+ ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.DAYS);
+ String expectedFormattedDate = DateTimeFormatter.ISO_LOCAL_DATE.format(zonedDateTime);
+
+ // Create a DateRange object using a string in the expected format
+ DateRange dateRange = DateRange.parse(expectedFormattedDate);
+ String formatted = codec.format(dateRange);
+
+ // The formatted string should be surrounded by single quotes, remove them for the comparison
+ String unquotedFormatted = formatted.replace("'", "");
+ assertEquals(expectedFormattedDate, unquotedFormatted);
+ }
+
+ @Test
+ void format_ShouldFormatDateRangeToString() throws ParseException {
+ String dateRangeString = "2001-01-01"; // Adjust this string to the correct format
+ DateRange dateRange;
+ try {
+ dateRange = DateRange.parse(dateRangeString);
+ } catch (ParseException e) {
+ fail("Failed to parse the date range for setup: " + e.getMessage());
+ return;
+ }
+
+ // Format the date range using the codec
+ String formatted = codec.format(dateRange);
+ assertNotNull(formatted);
+
+ // Remove single quotes for parsing
+ String unquotedFormatted = formatted.replace("'", "");
+ DateRange parsedDateRange;
+ try {
+ parsedDateRange = DateRange.parse(unquotedFormatted);
+ } catch (ParseException e) {
+ fail("Failed to parse the formatted date range: " + e.getMessage());
+ return;
+ }
+
+ // The parsed DateRange should equal the original DateRange
+ assertEquals(dateRange, parsedDateRange);
+ }
+
+ @Test
+ void parse_ShouldParseStringToDateRange() throws ParseException {
+ String formattedDateTime = ZonedDateTime.now()
+ .withZoneSameInstant(ZoneOffset.UTC)
+ .truncatedTo(ChronoUnit.MILLIS)
+ .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+ // Enclose in single quotes as per the error message
+ String dateRangeLiteral = "'" + formattedDateTime + "'";
+
+ // Attempt to parse it using the codec
+ DateRange parsedDateRange;
+ try {
+ parsedDateRange = codec.parse(dateRangeLiteral);
+ } catch (Exception e) {
+ fail("Parsing failed with exception: " + e.getMessage());
+ return;
+ }
+
+ assertNotNull(parsedDateRange);
+ }
+
+ @Test
+ void encode_ShouldHandleNullValues() {
+ ByteBuffer result = codec.encode(null, protocolVersion);
+ assertNull(result);
+ }
+
+ @Test
+ void decode_ShouldHandleNullByteBuffer() {
+ DateRange result = codec.decode(null, protocolVersion);
+ assertNull(result);
+ }
+}
diff --git a/src/test/java/com/datastax/cdm/cql/codec/LINESTRINGTYPE_CodecTest.java b/src/test/java/com/datastax/cdm/cql/codec/LINESTRINGTYPE_CodecTest.java
new file mode 100644
index 00000000..490f79c5
--- /dev/null
+++ b/src/test/java/com/datastax/cdm/cql/codec/LINESTRINGTYPE_CodecTest.java
@@ -0,0 +1,81 @@
+package com.datastax.cdm.cql.codec;
+
+import com.datastax.cdm.data.CqlConversion;
+import com.datastax.dse.driver.api.core.data.geometry.LineString;
+import com.datastax.dse.driver.internal.core.data.geometry.DefaultLineString;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.LineStringCodec;
+import com.esri.core.geometry.ogc.OGCLineString;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.nio.ByteBuffer;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class LINESTRINGTYPE_CodecTest {
+
+ private LineStringCodec codec;
+
+ @BeforeEach
+ void setUp() {
+ codec = new LineStringCodec();
+ }
+
+ @Test
+ void encode_ShouldEncodeLineStringToByteBuffer() {
+ LineString lineString = new DefaultLineString((OGCLineString) OGCLineString.fromText("LINESTRING (30 10, 10 30, 40 40)"));
+ ByteBuffer encoded = codec.encode(lineString, CqlConversion.PROTOCOL_VERSION);
+
+ assertNotNull(encoded);
+ assertTrue(encoded.remaining() > 0);
+
+ ByteBuffer expected = codec.encode(lineString, CqlConversion.PROTOCOL_VERSION);
+ assertTrue(expected.equals(encoded));
+ }
+
+ @Test
+ void decode_ShouldDecodeByteBufferToLineString() {
+ String lineString = "LINESTRING (30 10, 10 30, 40 40)";
+ LineString expectedLineString = new DefaultLineString((OGCLineString) OGCLineString.fromText(lineString));
+ ByteBuffer byteBuffer = codec.encode(expectedLineString, CqlConversion.PROTOCOL_VERSION);
+
+ LineString actualLineString = codec.decode(byteBuffer, CqlConversion.PROTOCOL_VERSION);
+
+ assertNotNull(actualLineString);
+ String actualWkt = actualLineString.asWellKnownText();
+ assertEquals(lineString, actualWkt);
+ }
+
+ @Test
+ void format_ShouldFormatLineStringToWktString() {
+ String line = "LINESTRING (30 10, 10 30, 40 40)";
+ LineString lineString = new DefaultLineString((OGCLineString) OGCLineString.fromText(line));
+
+ String formatted = codec.format(lineString);
+ assertNotNull(formatted);
+
+ String unquotedFormatted = formatted.replace("'", "");
+ assertEquals(line, unquotedFormatted);
+ }
+
+ @Test
+ void parse_ShouldParseWktStringToLineString() {
+ String stringLineString = "LINESTRING (30 10, 10 30, 40 40)";
+ String quotedLineString = "'" + stringLineString + "'";
+ LineString parsedLineString = codec.parse(quotedLineString);
+
+ assertNotNull(parsedLineString);
+ assertEquals(stringLineString, parsedLineString.asWellKnownText());
+ }
+
+ @Test
+ void encode_ShouldHandleNullValues() {
+ ByteBuffer result = codec.encode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+
+ @Test
+ void decode_ShouldHandleNullByteBuffer() {
+ LineString result = codec.decode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+}
diff --git a/src/test/java/com/datastax/cdm/cql/codec/POINTTYPE_CodecTest.java b/src/test/java/com/datastax/cdm/cql/codec/POINTTYPE_CodecTest.java
new file mode 100644
index 00000000..f9bfc767
--- /dev/null
+++ b/src/test/java/com/datastax/cdm/cql/codec/POINTTYPE_CodecTest.java
@@ -0,0 +1,81 @@
+package com.datastax.cdm.cql.codec;
+
+import com.datastax.cdm.data.CqlConversion;
+import com.datastax.dse.driver.api.core.data.geometry.Point;
+import com.datastax.dse.driver.internal.core.data.geometry.DefaultPoint;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PointCodec;
+import com.esri.core.geometry.ogc.OGCPoint;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.nio.ByteBuffer;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class POINTTYPE_CodecTest {
+
+ private PointCodec codec;
+
+ @BeforeEach
+ void setUp() {
+ codec = new PointCodec();
+ }
+
+ @Test
+ void encode_ShouldEncodePointToByteBuffer() {
+ Point point = new DefaultPoint((OGCPoint) OGCPoint.fromText("POINT (30 10)"));
+ ByteBuffer encoded = codec.encode(point, CqlConversion.PROTOCOL_VERSION);
+
+ assertNotNull(encoded);
+ assertTrue(encoded.remaining() > 0);
+
+ ByteBuffer expected = codec.encode(point, CqlConversion.PROTOCOL_VERSION);
+ assertTrue(expected.equals(encoded));
+ }
+
+ @Test
+ void decode_ShouldDecodeByteBufferToPoint() {
+ String wkt = "POINT (30 10)";
+ Point expectedPoint = new DefaultPoint((OGCPoint) OGCPoint.fromText(wkt));
+ ByteBuffer byteBuffer = codec.encode(expectedPoint, CqlConversion.PROTOCOL_VERSION);
+
+ Point actualPoint = codec.decode(byteBuffer, CqlConversion.PROTOCOL_VERSION);
+
+ assertNotNull(actualPoint);
+ String actualWkt = actualPoint.asWellKnownText();
+ assertEquals(wkt, actualWkt);
+ }
+
+ @Test
+ void format_ShouldFormatPointToWktString() {
+ String wkt = "POINT (30 10)";
+ Point point = new DefaultPoint((OGCPoint) OGCPoint.fromText(wkt));
+
+ String formatted = codec.format(point);
+ assertNotNull(formatted);
+
+ String unquotedFormatted = formatted.replace("'", "");
+ assertEquals(wkt, unquotedFormatted);
+ }
+
+ @Test
+ void parse_ShouldParseWktStringToPoint() {
+ String stringPoint = "POINT (30 10)";
+ String quotedPoint = "'" + stringPoint + "'";
+ Point parsedPoint = codec.parse(quotedPoint);
+
+ assertNotNull(parsedPoint);
+ assertEquals(stringPoint, parsedPoint.asWellKnownText());
+ }
+
+ @Test
+ void encode_ShouldHandleNullValues() {
+ ByteBuffer result = codec.encode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+
+ @Test
+ void decode_ShouldHandleNullByteBuffer() {
+ Point result = codec.decode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+}
diff --git a/src/test/java/com/datastax/cdm/cql/codec/POLYGONTYPE_CodecTest.java b/src/test/java/com/datastax/cdm/cql/codec/POLYGONTYPE_CodecTest.java
new file mode 100644
index 00000000..22ca2723
--- /dev/null
+++ b/src/test/java/com/datastax/cdm/cql/codec/POLYGONTYPE_CodecTest.java
@@ -0,0 +1,92 @@
+package com.datastax.cdm.cql.codec;
+
+import com.datastax.cdm.data.CqlConversion;
+import com.datastax.dse.driver.api.core.data.geometry.Polygon;
+import com.datastax.dse.driver.internal.core.data.geometry.DefaultPolygon;
+import com.datastax.dse.driver.internal.core.type.codec.geometry.PolygonCodec;
+import com.esri.core.geometry.ogc.OGCPolygon;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.nio.ByteBuffer;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class POLYGONTYPE_CodecTest {
+
+ private PolygonCodec codec;
+
+ @BeforeEach
+ void setUp() {
+ codec = new PolygonCodec();
+ }
+
+ @Test
+ void encode_ShouldEncodePolygonToByteBuffer() {
+ Polygon polygon = new DefaultPolygon((OGCPolygon) OGCPolygon.fromText("POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"));
+ ByteBuffer encoded = codec.encode(polygon, CqlConversion.PROTOCOL_VERSION); // Assuming protocol version is not needed or a mock version is provided
+
+ // Assert that the result is not null
+ assertNotNull(encoded);
+
+ // Assert that the ByteBuffer is not empty
+ assertTrue(encoded.remaining() > 0);
+
+ ByteBuffer expected = codec.encode(polygon, CqlConversion.PROTOCOL_VERSION);
+ assertTrue(expected.equals(encoded));
+ }
+
+ @Test
+ void decode_ShouldDecodeByteBufferToPolygon() {
+ // Create a ByteBuffer that represents a Polygon
+ String wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))";
+ Polygon expectedPolygon = new DefaultPolygon((OGCPolygon) OGCPolygon.fromText(wkt));
+ ByteBuffer byteBuffer = codec.encode(expectedPolygon, CqlConversion.PROTOCOL_VERSION);
+
+ // Use the codec to decode this ByteBuffer into a Polygon object
+ Polygon actualPolygon = codec.decode(byteBuffer, CqlConversion.PROTOCOL_VERSION);
+
+ // Assert that the result is not null
+ assertNotNull(actualPolygon);
+
+ // Assert that the actual Polygon object is equal to the expected Polygon object
+ String actualWkt = actualPolygon.asWellKnownText();
+ assertEquals(wkt, actualWkt);
+ }
+ @Test
+ void format_ShouldFormatPolygonToWktString() {
+ String wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))";
+ Polygon polygon = new DefaultPolygon((OGCPolygon) OGCPolygon.fromText(wkt));
+
+ String formatted = codec.format(polygon);
+ assertNotNull(formatted);
+
+ String unquotedFormatted = formatted.replace("'", "");
+ assertEquals(wkt, unquotedFormatted);
+ }
+
+ @Test
+ void parse_ShouldParseWktStringToPolygon() {
+ String stringPolygon = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))";
+ String quotedPolygon = "'" + stringPolygon + "'";
+ // Parse it using the codec
+ Polygon parsedPolygon = codec.parse(quotedPolygon);
+
+ // Assert that the resulting Polygon object is as expected
+ assertNotNull(parsedPolygon);
+ assertEquals(stringPolygon, parsedPolygon.asWellKnownText());
+ }
+
+ @Test
+ void encode_ShouldHandleNullValues() {
+ // Call encode with a null Polygon
+ ByteBuffer result = codec.encode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+
+ @Test
+ void decode_ShouldHandleNullByteBuffer() {
+ // Call decode with a null ByteBuffer
+ Polygon result = codec.decode(null, CqlConversion.PROTOCOL_VERSION);
+ assertNull(result);
+ }
+}