From ad583850193f6e55a1148cc537ba30ed9c1500c2 Mon Sep 17 00:00:00 2001 From: aschenzle Date: Sat, 29 Aug 2026 23:40:31 -0700 Subject: [PATCH 1/2] DynamoDB DTOs and DSL --- .../execution/DynamoDbExecutionsDto.java | 15 ++++ .../execution/DynamoDbFailedQuery.java | 29 +++++++ .../operations/DynamoDbAttributeValueDto.java | 27 +++++++ .../DynamoDbDatabaseCommandsDto.java | 12 +++ .../operations/DynamoDbInsertionDto.java | 13 +++ .../DynamoDbInsertionResultsDto.java | 28 +++++++ .../operations/DynamoDbScalarTypeDto.java | 10 +++ .../controller/dynamodb/dsl/DynamoDbDsl.java | 81 +++++++++++++++++++ .../dynamodb/dsl/DynamoDbSequenceDsl.java | 15 ++++ .../dynamodb/dsl/DynamoDbStatementDsl.java | 23 ++++++ .../dynamodb/dsl/DynamoDbDslTest.java | 63 +++++++++++++++ 11 files changed, 316 insertions(+) create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbExecutionsDto.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbFailedQuery.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbAttributeValueDto.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbDatabaseCommandsDto.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionDto.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java create mode 100644 client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java create mode 100644 client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java create mode 100644 client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbSequenceDsl.java create mode 100644 client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java create mode 100644 client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbExecutionsDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbExecutionsDto.java new file mode 100644 index 0000000000..0d57642ac4 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbExecutionsDto.java @@ -0,0 +1,15 @@ +package org.evomaster.client.java.controller.api.dto.database.execution; + +import java.util.ArrayList; +import java.util.List; + +/** + * DynamoDB reads that can be satisfied by generated initialization data. + */ +public class DynamoDbExecutionsDto { + + public List failedQueries = new ArrayList<>(); + + public DynamoDbExecutionsDto() { + } +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbFailedQuery.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbFailedQuery.java new file mode 100644 index 0000000000..159c73bb86 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/execution/DynamoDbFailedQuery.java @@ -0,0 +1,29 @@ +package org.evomaster.client.java.controller.api.dto.database.execution; + +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbAttributeValueDto; + +import java.util.ArrayList; +import java.util.List; + +/** + * Equality constraints from a successful DynamoDB read that returned no matching item. + */ +public class DynamoDbFailedQuery { + + public String tableName; + public List attributes = new ArrayList<>(); + + public DynamoDbFailedQuery() { + } + + /** + * Creates a failed-query description. + * + * @param tableName target table + * @param attributes equality-constrained attributes + */ + public DynamoDbFailedQuery(String tableName, List attributes) { + this.tableName = tableName; + this.attributes = new ArrayList<>(attributes); + } +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbAttributeValueDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbAttributeValueDto.java new file mode 100644 index 0000000000..d405c92759 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbAttributeValueDto.java @@ -0,0 +1,27 @@ +package org.evomaster.client.java.controller.api.dto.database.operations; + +/** + * A named scalar DynamoDB attribute value. + */ +public class DynamoDbAttributeValueDto { + + public String attributeName; + public DynamoDbScalarTypeDto type; + public String value; + + public DynamoDbAttributeValueDto() { + } + + /** + * Creates an attribute value. + * + * @param attributeName attribute name + * @param type DynamoDB scalar type + * @param value string-preserved value + */ + public DynamoDbAttributeValueDto(String attributeName, DynamoDbScalarTypeDto type, String value) { + this.attributeName = attributeName; + this.type = type; + this.value = value; + } +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbDatabaseCommandsDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbDatabaseCommandsDto.java new file mode 100644 index 0000000000..17f45b5d4e --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbDatabaseCommandsDto.java @@ -0,0 +1,12 @@ +package org.evomaster.client.java.controller.api.dto.database.operations; + +import java.util.ArrayList; +import java.util.List; + +/** + * DynamoDB insertion commands sent to the controller. + */ +public class DynamoDbDatabaseCommandsDto { + + public List insertions = new ArrayList<>(); +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionDto.java new file mode 100644 index 0000000000..a6a29d5671 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionDto.java @@ -0,0 +1,13 @@ +package org.evomaster.client.java.controller.api.dto.database.operations; + +import java.util.ArrayList; +import java.util.List; + +/** + * An item to insert into a DynamoDB table. + */ +public class DynamoDbInsertionDto { + + public String tableName; + public List attributes = new ArrayList<>(); +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java new file mode 100644 index 0000000000..86f0f12142 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java @@ -0,0 +1,28 @@ +package org.evomaster.client.java.controller.api.dto.database.operations; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Results of a sequence of DynamoDB insertions. + */ +public class DynamoDbInsertionResultsDto { + + public List executionResults = new ArrayList<>(); + public Integer failedInsertionIndex; + + /** + * Records the insertion that failed while preserving earlier successes. + * + * @param insertions attempted insertions + * @param failedIndex zero-based index of the failed insertion + */ + public void handleFailedInsertion(List insertions, int failedIndex) { + executionResults = new ArrayList<>(Collections.nCopies(insertions.size(), false)); + for (int i = 0; i < failedIndex; i++) { + executionResults.set(i, true); + } + failedInsertionIndex = failedIndex; + } +} diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java new file mode 100644 index 0000000000..7438336709 --- /dev/null +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java @@ -0,0 +1,10 @@ +package org.evomaster.client.java.controller.api.dto.database.operations; + +/** + * Scalar DynamoDB attribute types supported by generated insertions. + */ +public enum DynamoDbScalarTypeDto { + S, + N, + BOOL +} diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java new file mode 100644 index 0000000000..d84705f813 --- /dev/null +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java @@ -0,0 +1,81 @@ +package org.evomaster.client.java.controller.dynamodb.dsl; + +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbAttributeValueDto; +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbInsertionDto; +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbScalarTypeDto; + +import java.util.ArrayList; +import java.util.List; + +/** + * DSL for DynamoDB insertions in generated tests. + */ +public final class DynamoDbDsl implements DynamoDbSequenceDsl, DynamoDbStatementDsl { + + private List insertions = new ArrayList<>(); + private DynamoDbInsertionDto current; + + private DynamoDbDsl() { + } + + /** + * @return a new DynamoDB insertion sequence + */ + public static DynamoDbSequenceDsl dynamoDb() { + return new DynamoDbDsl(); + } + + @Override + public DynamoDbStatementDsl insertInto(String tableName) { + checkOpen(); + if (tableName == null || tableName.isEmpty()) { + throw new IllegalArgumentException("Unspecified table"); + } + current = new DynamoDbInsertionDto(); + current.tableName = tableName; + insertions.add(current); + return this; + } + + @Override + public DynamoDbStatementDsl s(String name, String value) { + return attribute(name, DynamoDbScalarTypeDto.S, value); + } + + @Override + public DynamoDbStatementDsl n(String name, String value) { + return attribute(name, DynamoDbScalarTypeDto.N, value); + } + + @Override + public DynamoDbStatementDsl bool(String name, boolean value) { + return attribute(name, DynamoDbScalarTypeDto.BOOL, Boolean.toString(value)); + } + + @Override + public List dtos() { + checkOpen(); + List result = insertions; + insertions = null; + current = null; + return result; + } + + private DynamoDbStatementDsl attribute(String name, DynamoDbScalarTypeDto type, String value) { + checkOpen(); + if (current == null) { + throw new IllegalStateException("Call insertInto before adding attributes"); + } + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Unspecified attribute name"); + } + current.attributes.add(new DynamoDbAttributeValueDto(name, type, value)); + return this; + } + + private void checkOpen() { + if (insertions == null) { + throw new IllegalStateException("DTO was already built for this object"); + } + } +} diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbSequenceDsl.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbSequenceDsl.java new file mode 100644 index 0000000000..8b043cb8f2 --- /dev/null +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbSequenceDsl.java @@ -0,0 +1,15 @@ +package org.evomaster.client.java.controller.dynamodb.dsl; + +/** + * Entry point for a DynamoDB insertion sequence. + */ +public interface DynamoDbSequenceDsl { + + /** + * Starts an item insertion. + * + * @param tableName target table + * @return item statement + */ + DynamoDbStatementDsl insertInto(String tableName); +} diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java new file mode 100644 index 0000000000..f45f32b082 --- /dev/null +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java @@ -0,0 +1,23 @@ +package org.evomaster.client.java.controller.dynamodb.dsl; + +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbInsertionDto; + +import java.util.List; + +/** + * Fluent definition of one DynamoDB item. + */ +public interface DynamoDbStatementDsl extends DynamoDbSequenceDsl { + + /** Adds a string attribute. */ + DynamoDbStatementDsl s(String name, String value); + + /** Adds a number attribute while preserving its exact text. */ + DynamoDbStatementDsl n(String name, String value); + + /** Adds a boolean attribute. */ + DynamoDbStatementDsl bool(String name, boolean value); + + /** @return the completed insertion DTOs */ + List dtos(); +} diff --git a/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java b/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java new file mode 100644 index 0000000000..d0f28c8c39 --- /dev/null +++ b/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java @@ -0,0 +1,63 @@ +package org.evomaster.client.java.controller.dynamodb.dsl; + +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbAttributeValueDto; +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbInsertionDto; +import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbScalarTypeDto; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** Tests the DynamoDB insertion DTOs produced by the generated-test DSL. */ +public class DynamoDbDslTest { + + @Test + public void testBuildsWorldCupPlayerInsertions() { + List insertions = DynamoDbDsl.dynamoDb() + .insertInto("WorldCupPlayers") + .s("country", "Argentina") + .n("fifaId", "10") + .bool("captain", true) + .insertInto("WorldCupPlayers") + .s("country", "Brazil") + .n("fifaId", "1") + .dtos(); + + assertEquals(2, insertions.size()); + assertInsertion(insertions.get(0), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.S, "Argentina"); + assertInsertion(insertions.get(0), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.N, "10"); + assertInsertion(insertions.get(0), "WorldCupPlayers", "captain", DynamoDbScalarTypeDto.BOOL, "true"); + assertInsertion(insertions.get(1), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.S, "Brazil"); + assertInsertion(insertions.get(1), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.N, "1"); + } + + @Test + public void testRejectsIncompleteInsertionDefinitions() { + assertThrows(IllegalArgumentException.class, () -> DynamoDbDsl.dynamoDb().insertInto(null)); + assertThrows(IllegalArgumentException.class, () -> DynamoDbDsl.dynamoDb().insertInto("")); + + DynamoDbStatementDsl statement = (DynamoDbStatementDsl) DynamoDbDsl.dynamoDb(); + assertThrows(IllegalStateException.class, () -> statement.s("country", "Argentina")); + + DynamoDbStatementDsl completed = DynamoDbDsl.dynamoDb().insertInto("WorldCupPlayers"); + completed.dtos(); + assertThrows(IllegalStateException.class, () -> completed.insertInto("WorldCupPlayers")); + } + + private void assertInsertion( + DynamoDbInsertionDto insertion, + String tableName, + String attributeName, + DynamoDbScalarTypeDto type, + String value) { + assertEquals(tableName, insertion.tableName); + DynamoDbAttributeValueDto attribute = insertion.attributes.stream() + .filter(candidate -> attributeName.equals(candidate.attributeName)) + .findFirst() + .orElseThrow(() -> new AssertionError("Missing attribute " + attributeName)); + assertEquals(type, attribute.type); + assertEquals(value, attribute.value); + } +} From 43232a93170b94df24711813a6dfb5ed54742145 Mon Sep 17 00:00:00 2001 From: aschenzle Date: Fri, 4 Sep 2026 18:01:39 -0700 Subject: [PATCH 2/2] Addressing comments. --- .../DynamoDbInsertionResultsDto.java | 15 ------- .../operations/DynamoDbScalarTypeDto.java | 6 +-- .../controller/dynamodb/dsl/DynamoDbDsl.java | 39 +++++++++++----- .../dynamodb/dsl/DynamoDbStatementDsl.java | 17 +++---- .../dynamodb/dsl/DynamoDbDslTest.java | 44 ++++++++++++++----- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java index 86f0f12142..883be9a137 100644 --- a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbInsertionResultsDto.java @@ -1,7 +1,6 @@ package org.evomaster.client.java.controller.api.dto.database.operations; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** @@ -11,18 +10,4 @@ public class DynamoDbInsertionResultsDto { public List executionResults = new ArrayList<>(); public Integer failedInsertionIndex; - - /** - * Records the insertion that failed while preserving earlier successes. - * - * @param insertions attempted insertions - * @param failedIndex zero-based index of the failed insertion - */ - public void handleFailedInsertion(List insertions, int failedIndex) { - executionResults = new ArrayList<>(Collections.nCopies(insertions.size(), false)); - for (int i = 0; i < failedIndex; i++) { - executionResults.set(i, true); - } - failedInsertionIndex = failedIndex; - } } diff --git a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java index 7438336709..1698e1541f 100644 --- a/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java +++ b/client-java/controller-api/src/main/java/org/evomaster/client/java/controller/api/dto/database/operations/DynamoDbScalarTypeDto.java @@ -4,7 +4,7 @@ * Scalar DynamoDB attribute types supported by generated insertions. */ public enum DynamoDbScalarTypeDto { - S, - N, - BOOL + STRING, + NUMBER, + BOOLEAN } diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java index d84705f813..43e1e6d7ac 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDsl.java @@ -4,6 +4,7 @@ import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbInsertionDto; import org.evomaster.client.java.controller.api.dto.database.operations.DynamoDbScalarTypeDto; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -38,18 +39,24 @@ public DynamoDbStatementDsl insertInto(String tableName) { } @Override - public DynamoDbStatementDsl s(String name, String value) { - return attribute(name, DynamoDbScalarTypeDto.S, value); - } - - @Override - public DynamoDbStatementDsl n(String name, String value) { - return attribute(name, DynamoDbScalarTypeDto.N, value); - } - - @Override - public DynamoDbStatementDsl bool(String name, boolean value) { - return attribute(name, DynamoDbScalarTypeDto.BOOL, Boolean.toString(value)); + public DynamoDbStatementDsl d(String attributeName, String printableValue) { + if (printableValue == null) { + throw new IllegalArgumentException("Unspecified attribute value"); + } + if (isStringLiteral(printableValue)) { + String value = printableValue.substring(1, printableValue.length() - 1).replace("''", "'"); + return attribute(attributeName, DynamoDbScalarTypeDto.STRING, value); + } + if ("true".equalsIgnoreCase(printableValue) || "false".equalsIgnoreCase(printableValue)) { + return attribute(attributeName, DynamoDbScalarTypeDto.BOOLEAN, + Boolean.toString(Boolean.parseBoolean(printableValue))); + } + try { + new BigDecimal(printableValue); + return attribute(attributeName, DynamoDbScalarTypeDto.NUMBER, printableValue); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Unsupported DynamoDB scalar value: " + printableValue, e); + } } @Override @@ -73,6 +80,14 @@ private DynamoDbStatementDsl attribute(String name, DynamoDbScalarTypeDto type, return this; } + /** + * @param value value to inspect + * @return whether the value is enclosed in single quotes + */ + private boolean isStringLiteral(String value) { + return value.length() >= 2 && value.charAt(0) == '\'' && value.charAt(value.length() - 1) == '\''; + } + private void checkOpen() { if (insertions == null) { throw new IllegalStateException("DTO was already built for this object"); diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java index f45f32b082..e6446d949d 100644 --- a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java +++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbStatementDsl.java @@ -9,14 +9,15 @@ */ public interface DynamoDbStatementDsl extends DynamoDbSequenceDsl { - /** Adds a string attribute. */ - DynamoDbStatementDsl s(String name, String value); - - /** Adds a number attribute while preserving its exact text. */ - DynamoDbStatementDsl n(String name, String value); - - /** Adds a boolean attribute. */ - DynamoDbStatementDsl bool(String name, boolean value); + /** + * Adds a scalar attribute using its printable representation. Strings must be enclosed in single quotes, + * numbers are represented by their exact text, and booleans are represented by {@code true} or {@code false}. + * + * @param attributeName attribute name + * @param printableValue scalar value in printable form + * @return the continuation of this statement + */ + DynamoDbStatementDsl d(String attributeName, String printableValue); /** @return the completed insertion DTOs */ List dtos(); diff --git a/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java b/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java index d0f28c8c39..6ad05b8bae 100644 --- a/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java +++ b/client-java/controller/src/test/java/org/evomaster/client/java/controller/dynamodb/dsl/DynamoDbDslTest.java @@ -17,20 +17,37 @@ public class DynamoDbDslTest { public void testBuildsWorldCupPlayerInsertions() { List insertions = DynamoDbDsl.dynamoDb() .insertInto("WorldCupPlayers") - .s("country", "Argentina") - .n("fifaId", "10") - .bool("captain", true) + .d("country", "'Argentina'") + .d("fifaId", "10") + .d("captain", "true") .insertInto("WorldCupPlayers") - .s("country", "Brazil") - .n("fifaId", "1") + .d("country", "'Brazil'") + .d("fifaId", "1") .dtos(); assertEquals(2, insertions.size()); - assertInsertion(insertions.get(0), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.S, "Argentina"); - assertInsertion(insertions.get(0), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.N, "10"); - assertInsertion(insertions.get(0), "WorldCupPlayers", "captain", DynamoDbScalarTypeDto.BOOL, "true"); - assertInsertion(insertions.get(1), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.S, "Brazil"); - assertInsertion(insertions.get(1), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.N, "1"); + assertInsertion(insertions.get(0), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.STRING, "Argentina"); + assertInsertion(insertions.get(0), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.NUMBER, "10"); + assertInsertion(insertions.get(0), "WorldCupPlayers", "captain", DynamoDbScalarTypeDto.BOOLEAN, "true"); + assertInsertion(insertions.get(1), "WorldCupPlayers", "country", DynamoDbScalarTypeDto.STRING, "Brazil"); + assertInsertion(insertions.get(1), "WorldCupPlayers", "fifaId", DynamoDbScalarTypeDto.NUMBER, "1"); + } + + @Test + public void testDistinguishesQuotedWorldCupPlayerValues() { + DynamoDbInsertionDto insertion = DynamoDbDsl.dynamoDb() + .insertInto("WorldCupPlayers") + .d("shirtNumber", "'10'") + .d("captainLabel", "'true'") + .d("goals", "3e1") + .d("captain", "TRUE") + .dtos() + .get(0); + + assertInsertion(insertion, "WorldCupPlayers", "shirtNumber", DynamoDbScalarTypeDto.STRING, "10"); + assertInsertion(insertion, "WorldCupPlayers", "captainLabel", DynamoDbScalarTypeDto.STRING, "true"); + assertInsertion(insertion, "WorldCupPlayers", "goals", DynamoDbScalarTypeDto.NUMBER, "3e1"); + assertInsertion(insertion, "WorldCupPlayers", "captain", DynamoDbScalarTypeDto.BOOLEAN, "true"); } @Test @@ -39,7 +56,12 @@ public void testRejectsIncompleteInsertionDefinitions() { assertThrows(IllegalArgumentException.class, () -> DynamoDbDsl.dynamoDb().insertInto("")); DynamoDbStatementDsl statement = (DynamoDbStatementDsl) DynamoDbDsl.dynamoDb(); - assertThrows(IllegalStateException.class, () -> statement.s("country", "Argentina")); + assertThrows(IllegalStateException.class, () -> statement.d("country", "'Argentina'")); + + assertThrows(IllegalArgumentException.class, () -> DynamoDbDsl.dynamoDb() + .insertInto("WorldCupPlayers").d("country", null)); + assertThrows(IllegalArgumentException.class, () -> DynamoDbDsl.dynamoDb() + .insertInto("WorldCupPlayers").d("country", "Argentina")); DynamoDbStatementDsl completed = DynamoDbDsl.dynamoDb().insertInto("WorldCupPlayers"); completed.dtos();