Skip to content

Commit 055504b

Browse files
Align new tests with existing behavior from production
1 parent d7684e7 commit 055504b

14 files changed

Lines changed: 214 additions & 143 deletions

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/BeanSchemaConverterTest.java‎

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,11 @@ void mapToItem_whenNulString_doesNotCallSetterAndLeavesValueNull() {
188188
}
189189

190190
@Test
191-
@DisplayName("An unconverted Object property has no default converter")
192-
void fromBean_whenUnconvertedObject_throwsIllegalStateException() {
193-
EnhancedType<Object> type = EnhancedType.of(Object.class);
194-
191+
@DisplayName("An unconverted Object property enters the map branch and fails while reading parameters")
192+
void fromBean_whenUnconvertedObject_throwsIndexOutOfBoundsException() {
195193
assertThatThrownBy(() -> TableSchema.fromBean(ObjectBean.class))
196-
.isInstanceOf(IllegalStateException.class)
197-
.hasMessage("Converter not found for " + type);
194+
.isInstanceOf(IndexOutOfBoundsException.class)
195+
.hasMessage("Index: 0");
198196
}
199197

200198
@Test
@@ -415,13 +413,23 @@ void fromBean_whenUnsupportedListWithCustomMemberProvider_throwsForEnclosingList
415413
}
416414

417415
@Test
418-
@DisplayName("A Collection of String has no default converter")
419-
void fromBean_whenStringCollection_throwsIllegalStateException() {
420-
EnhancedType<Collection<String>> type = EnhancedType.collectionOf(String.class);
416+
@DisplayName("A Collection of String is stored as SS and read as a LinkedHashSet")
417+
void fromBean_whenStringCollection_selectsSetConverterAndReadsLinkedHashSet() {
418+
TableSchema<StringCollectionBean> schema = TableSchema.fromBean(StringCollectionBean.class);
419+
StringCollectionBean model = new StringCollectionBean();
420+
Collection<String> input = new LinkedHashSet<>();
421+
input.add("a");
422+
input.add("b");
423+
model.setValue(input);
421424

422-
assertThatThrownBy(() -> TableSchema.fromBean(StringCollectionBean.class))
423-
.isInstanceOf(IllegalStateException.class)
424-
.hasMessage("Converter not found for " + type);
425+
Map<String, AttributeValue> map = schema.itemToMap(model, true);
426+
StringCollectionBean read = schema.mapToItem(map);
427+
428+
AttributeConverter<?> converter = schema.converterForAttribute("value");
429+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
430+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
431+
assertThat(read.getValue()).isInstanceOf(LinkedHashSet.class)
432+
.containsExactly("a", "b");
425433
}
426434

427435
@Test

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProviderListTest.java‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,14 @@ void converterFor_whenListOfMapsOfDocuments_usesLThenMThenMAndReadsReconstructed
276276
}
277277

278278
@Test
279-
@DisplayName("An Object list member has no default converter")
280-
void converterFor_whenObjectListMember_throwsIllegalStateException() {
279+
@DisplayName("An Object list member enters the map branch and fails while reading parameters")
280+
void converterFor_whenObjectListMember_throwsIndexOutOfBoundsException() {
281281
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
282282
EnhancedType<List<Object>> type = EnhancedType.listOf(Object.class);
283283

284284
assertThatThrownBy(() -> provider.converterFor(type))
285-
.isInstanceOf(IllegalStateException.class)
286-
.hasMessage("Converter not found for " + type);
285+
.isInstanceOf(IndexOutOfBoundsException.class)
286+
.hasMessage("Index: 0");
287287
}
288288

289289
@Test
@@ -310,15 +310,15 @@ void converterFor_whenWildcardListMember_throwsIllegalArgumentException() {
310310
}
311311

312312
@Test
313-
@DisplayName("A nested Object list fails while looking up the inner list")
314-
void converterFor_whenNestedObjectList_throwsIllegalStateException() {
313+
@DisplayName("A nested Object list fails while reading map parameters for the inner Object")
314+
void converterFor_whenNestedObjectList_throwsIndexOutOfBoundsException() {
315315
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
316316
EnhancedType<List<Object>> innerType = EnhancedType.listOf(Object.class);
317317
EnhancedType<List<List<Object>>> type = EnhancedType.listOf(innerType);
318318

319319
assertThatThrownBy(() -> provider.converterFor(type))
320-
.isInstanceOf(IllegalStateException.class)
321-
.hasMessage("Converter not found for " + innerType);
320+
.isInstanceOf(IndexOutOfBoundsException.class)
321+
.hasMessage("Index: 0");
322322
}
323323

324324
@Test

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProviderLookupTest.java‎

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -173,26 +173,25 @@ public Optional<TableSchema<Map<String, Integer>>> tableSchema() {
173173
}
174174

175175
@Test
176-
@DisplayName("Plain Object type has no default converter")
177-
void converterFor_whenObjectType_throwsIllegalStateException() {
176+
@DisplayName("Plain Object type enters the map branch and fails while reading parameters")
177+
void converterFor_whenObjectType_throwsIndexOutOfBoundsException() {
178178
EnhancedType<Object> type = EnhancedType.of(Object.class);
179179

180180
assertThatThrownBy(() -> provider.converterFor(type))
181-
.isInstanceOf(IllegalStateException.class)
182-
.hasMessage("Converter not found for " + type);
181+
.isInstanceOf(IndexOutOfBoundsException.class)
182+
.hasMessage("Index: 0");
183183
}
184184

185185
@Test
186-
@DisplayName("A schema-bearing Object token selects and caches a document converter")
187-
void converterFor_whenObjectDocumentToken_returnsCachedDocumentAttributeConverter() {
188-
TableSchema<Object> objectSchema = unusedSchema(Object.class, Object::new);
186+
@DisplayName("A schema-bearing Object token fails while reading map parameters before the schema is read")
187+
void converterFor_whenObjectDocumentToken_throwsNullPointerExceptionBeforeReadingSchema() {
188+
TableSchema<Object> objectSchema = mock(TableSchema.class);
189189
EnhancedType<Object> type = EnhancedType.documentOf(Object.class, objectSchema);
190190

191-
AttributeConverter<Object> converter = provider.converterFor(type);
192-
193-
assertThat(converter).isInstanceOf(DocumentAttributeConverter.class);
194-
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.M);
195-
assertThat(provider.converterFor(type)).isSameAs(converter);
191+
assertThatThrownBy(() -> provider.converterFor(type))
192+
.isInstanceOf(NullPointerException.class)
193+
.satisfies(ex -> assertThat(ex.getMessage() == null || ex.getMessage().contains("null")).isTrue());
194+
verifyNoInteractions(objectSchema);
196195
}
197196

198197
@Test
@@ -269,24 +268,30 @@ public Optional<TableSchema<Set<String>>> tableSchema() {
269268
}
270269

271270
@Test
272-
@DisplayName("Collection of String has no default converter")
273-
void converterFor_whenStringCollection_throwsIllegalStateException() {
271+
@DisplayName("Collection of String enters the set branch and caches a string-set converter")
272+
void converterFor_whenStringCollection_returnsCachedSetAttributeConverter() {
274273
EnhancedType<Collection<String>> type = EnhancedType.collectionOf(String.class);
275274

276-
assertThatThrownBy(() -> provider.converterFor(type))
277-
.isInstanceOf(IllegalStateException.class)
278-
.hasMessage("Converter not found for " + type);
275+
AttributeConverter<Collection<String>> converter = provider.converterFor(type);
276+
277+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
278+
assertThat(converter.type()).isEqualTo(EnhancedType.setOf(String.class));
279+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
280+
assertThat(provider.converterFor(type)).isSameAs(converter);
279281
}
280282

281283
@Test
282-
@DisplayName("Iterable of String has no default converter")
283-
void converterFor_whenStringIterable_throwsIllegalStateException() {
284+
@DisplayName("Iterable of String enters the set branch and caches a string-set converter")
285+
void converterFor_whenStringIterable_returnsCachedSetAttributeConverter() {
284286
EnhancedType<Iterable<String>> type = new EnhancedType<Iterable<String>>() {
285287
};
286288

287-
assertThatThrownBy(() -> provider.converterFor(type))
288-
.isInstanceOf(IllegalStateException.class)
289-
.hasMessage("Converter not found for " + type);
289+
AttributeConverter<Iterable<String>> converter = provider.converterFor(type);
290+
291+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
292+
assertThat(converter.type()).isEqualTo(EnhancedType.setOf(String.class));
293+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
294+
assertThat(provider.converterFor(type)).isSameAs(converter);
290295
}
291296

292297
@Test

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProviderMapTest.java‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,14 @@ void converterFor_whenWildcardKeyMap_throwsWildcardNotExpected() {
255255
}
256256

257257
@Test
258-
@DisplayName("An Object map value has no default converter")
259-
void converterFor_whenObjectValueMap_throwsIllegalStateException() {
258+
@DisplayName("An Object map value enters the nested map branch and fails while reading parameters")
259+
void converterFor_whenObjectValueMap_throwsIndexOutOfBoundsException() {
260260
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
261261
EnhancedType<Map<String, Object>> type = EnhancedType.mapOf(String.class, Object.class);
262262

263263
assertThatThrownBy(() -> provider.converterFor(type))
264-
.isInstanceOf(IllegalStateException.class)
265-
.hasMessage("Converter not found for " + type);
264+
.isInstanceOf(IndexOutOfBoundsException.class)
265+
.hasMessage("Index: 0");
266266
}
267267

268268
@Test
@@ -496,16 +496,16 @@ void converterFor_whenCustomMapImplementation_throwsConverterNotFound() {
496496
}
497497

498498
@Test
499-
@DisplayName("A nested list of Object fails while looking up the list")
500-
void converterFor_whenNestedListOfObject_throwsIllegalStateException() {
499+
@DisplayName("A nested list of Object fails while reading map parameters for the inner Object")
500+
void converterFor_whenNestedListOfObject_throwsIndexOutOfBoundsException() {
501501
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
502502
EnhancedType<List<Object>> listType = EnhancedType.listOf(Object.class);
503503
EnhancedType<Map<String, List<Object>>> type =
504504
EnhancedType.mapOf(EnhancedType.of(String.class), listType);
505505

506506
assertThatThrownBy(() -> provider.converterFor(type))
507-
.isInstanceOf(IllegalStateException.class)
508-
.hasMessage("Converter not found for " + listType);
507+
.isInstanceOf(IndexOutOfBoundsException.class)
508+
.hasMessage("Index: 0");
509509
}
510510

511511
@Test

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProviderSetTest.java‎

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717

1818
import static org.assertj.core.api.Assertions.assertThat;
1919
import static org.assertj.core.api.Assertions.assertThatThrownBy;
20+
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.Collection;
23+
import java.util.Collections;
2224
import java.util.HashSet;
25+
import java.util.Iterator;
2326
import java.util.LinkedHashSet;
2427
import java.util.List;
2528
import java.util.Map;
@@ -241,14 +244,14 @@ void converterFor_whenBsAttributeTypeMemberSet_throwsIllegalArgumentException()
241244
}
242245

243246
@Test
244-
@DisplayName("An Object set member has no default converter")
245-
void converterFor_whenObjectMemberSet_throwsIllegalStateException() {
247+
@DisplayName("An Object set member enters the map branch and fails while reading parameters")
248+
void converterFor_whenObjectMemberSet_throwsIndexOutOfBoundsException() {
246249
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
247250
EnhancedType<Set<Object>> type = EnhancedType.setOf(Object.class);
248251

249252
assertThatThrownBy(() -> provider.converterFor(type))
250-
.isInstanceOf(IllegalStateException.class)
251-
.hasMessage("Converter not found for " + type);
253+
.isInstanceOf(IndexOutOfBoundsException.class)
254+
.hasMessage("Index: 0");
252255
}
253256

254257
@Test
@@ -275,38 +278,57 @@ void converterFor_whenWildcardSetMember_throwsIllegalArgumentException() {
275278
}
276279

277280
@Test
278-
@DisplayName("Collection of String has no default converter")
279-
void converterFor_whenStringCollection_throwsIllegalStateException() {
281+
@DisplayName("Collection of String uses set semantics and reads a LinkedHashSet")
282+
void converterFor_whenStringCollection_convertsToSsAndReadsLinkedHashSet() {
280283
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
281284
EnhancedType<Collection<String>> type = EnhancedType.collectionOf(String.class);
285+
Collection<String> input = new ArrayList<>();
286+
input.add("a");
287+
input.add("b");
282288

283-
assertThatThrownBy(() -> provider.converterFor(type))
284-
.isInstanceOf(IllegalStateException.class)
285-
.hasMessage("Converter not found for " + type);
289+
AttributeConverter<Collection<String>> converter = provider.converterFor(type);
290+
AttributeValue stored = converter.transformFrom(input);
291+
Collection<String> read = converter.transformTo(stored);
292+
293+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
294+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
295+
assertThat(stored.ss()).containsExactly("a", "b");
296+
assertThat(read).isInstanceOf(LinkedHashSet.class)
297+
.containsExactly("a", "b");
286298
}
287299

288300
@Test
289-
@DisplayName("Iterable of String has no default converter")
290-
void converterFor_whenStringIterableWithLinkedHashSet_throwsIllegalStateException() {
301+
@DisplayName("Iterable of String uses set semantics when the value is a LinkedHashSet")
302+
void converterFor_whenStringIterableWithLinkedHashSet_convertsToSsAndReadsLinkedHashSet() {
291303
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
292304
EnhancedType<Iterable<String>> type = new EnhancedType<Iterable<String>>() {
293305
};
306+
Iterable<String> input = linkedSet("a", "b");
294307

295-
assertThatThrownBy(() -> provider.converterFor(type))
296-
.isInstanceOf(IllegalStateException.class)
297-
.hasMessage("Converter not found for " + type);
308+
AttributeConverter<Iterable<String>> converter = provider.converterFor(type);
309+
AttributeValue stored = converter.transformFrom(input);
310+
Iterable<String> read = converter.transformTo(stored);
311+
312+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
313+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
314+
assertThat(stored.ss()).containsExactly("a", "b");
315+
assertThat(read).isInstanceOf(LinkedHashSet.class)
316+
.isEqualTo(linkedSet("a", "b"));
298317
}
299318

300319
@Test
301-
@DisplayName("A non-Collection Iterable has no default converter")
302-
void converterFor_whenNonCollectionIterable_throwsIllegalStateException() {
320+
@DisplayName("A non-Collection Iterable is selected as a set converter and fails while converting")
321+
void converterFor_whenNonCollectionIterable_throwsClassCastException() {
303322
DefaultAttributeConverterProvider provider = new DefaultAttributeConverterProvider();
304323
EnhancedType<Iterable<String>> type = new EnhancedType<Iterable<String>>() {
305324
};
325+
Iterable<String> input = new NonCollectionIterable();
306326

307-
assertThatThrownBy(() -> provider.converterFor(type))
308-
.isInstanceOf(IllegalStateException.class)
309-
.hasMessage("Converter not found for " + type);
327+
AttributeConverter<Iterable<String>> converter = provider.converterFor(type);
328+
329+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
330+
assertThatThrownBy(() -> converter.transformFrom(input))
331+
.isInstanceOf(ClassCastException.class);
310332
}
311333

312334
@Test
@@ -450,4 +472,11 @@ enum TestEnum {
450472

451473
static final class CustomSet<T> extends HashSet<T> {
452474
}
475+
476+
static final class NonCollectionIterable implements Iterable<String> {
477+
@Override
478+
public Iterator<String> iterator() {
479+
return Collections.singletonList("a").iterator();
480+
}
481+
}
453482
}

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/DefaultAttributeConverterProviderTest.java‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.HashMap;
2323
import java.util.List;
2424
import org.apache.logging.log4j.core.LogEvent;
25+
import org.junit.jupiter.api.DisplayName;
2526
import org.junit.jupiter.api.Test;
2627
import org.slf4j.event.Level;
2728
import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableSchema;
@@ -81,12 +82,13 @@ void findConverter_whenMapSubtypeHasSupportedEntries_throwsConverterNotFound() {
8182
}
8283

8384
@Test
84-
void findConverter_whenMapEntryValueIsObject_throwsConverterNotFound() {
85+
@DisplayName("An Object map value enters the nested map branch and fails while reading parameters")
86+
void findConverter_whenMapEntryValueIsObject_throwsIndexOutOfBoundsException() {
8587
DefaultAttributeConverterProvider provider = DefaultAttributeConverterProvider.create();
8688

8789
assertThatThrownBy(() -> provider.converterFor(EnhancedType.mapOf(String.class, Object.class)))
88-
.isInstanceOf(IllegalStateException.class)
89-
.hasMessage("Converter not found for EnhancedType(java.util.Map<java.lang.String, java.lang.Object>)");
90+
.isInstanceOf(IndexOutOfBoundsException.class)
91+
.hasMessage("Index: 0");
9092
}
9193

9294
@Test

‎services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/ImmutableSchemaConverterTest.java‎

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,11 @@ void mapToItem_whenNulString_doesNotCallBuilderValueAndLeavesValueNull() {
179179
}
180180

181181
@Test
182-
@DisplayName("An unconverted Object property has no default converter")
183-
void fromImmutableClass_whenUnconvertedObject_throwsIllegalStateException() {
184-
EnhancedType<Object> type = EnhancedType.of(Object.class);
185-
182+
@DisplayName("An unconverted Object property enters the map branch and fails while reading parameters")
183+
void fromImmutableClass_whenUnconvertedObject_throwsIndexOutOfBoundsException() {
186184
assertThatThrownBy(() -> TableSchema.fromImmutableClass(ObjectModel.class))
187-
.isInstanceOf(IllegalStateException.class)
188-
.hasMessage("Converter not found for " + type);
185+
.isInstanceOf(IndexOutOfBoundsException.class)
186+
.hasMessage("Index: 0");
189187
}
190188

191189
@Test
@@ -401,13 +399,22 @@ void fromImmutableClass_whenUnsupportedSetWithCustomMemberProvider_throwsForEncl
401399
}
402400

403401
@Test
404-
@DisplayName("A Collection of String has no default converter")
405-
void fromImmutableClass_whenStringCollection_throwsIllegalStateException() {
406-
EnhancedType<Collection<String>> type = EnhancedType.collectionOf(String.class);
402+
@DisplayName("A Collection of String is stored as SS and rebuilt as a LinkedHashSet")
403+
void fromImmutableClass_whenStringCollection_selectsSetConverterAndRebuildsLinkedHashSet() {
404+
TableSchema<StringCollectionModel> schema = TableSchema.fromImmutableClass(StringCollectionModel.class);
405+
Collection<String> input = new LinkedHashSet<>();
406+
input.add("a");
407+
input.add("b");
408+
StringCollectionModel model = StringCollectionModel.builder().value(input).build();
407409

408-
assertThatThrownBy(() -> TableSchema.fromImmutableClass(StringCollectionModel.class))
409-
.isInstanceOf(IllegalStateException.class)
410-
.hasMessage("Converter not found for " + type);
410+
Map<String, AttributeValue> map = schema.itemToMap(model, true);
411+
StringCollectionModel read = schema.mapToItem(map);
412+
413+
AttributeConverter<?> converter = schema.converterForAttribute("value");
414+
assertThat(converter).isInstanceOf(SetAttributeConverter.class);
415+
assertThat(converter.attributeValueType()).isEqualTo(AttributeValueType.SS);
416+
assertThat(read.value()).isInstanceOf(LinkedHashSet.class)
417+
.containsExactly("a", "b");
411418
}
412419

413420
@Test

0 commit comments

Comments
 (0)