MapCodecFactory implements CodecFactory { public <T> Codec<T> create(AnnotatedElement metadata, Class<T> type, ResolverContext context) { if (Map.class.isAssignableFrom(type)) { BoundList boundList = metadata.getAnnotation(BoundList.class); if (boundList != null && typeIsGuaranteedToBeEntry(boundList)) { Codec<List> listCodec = codecFactory.create(metadata, List.class, context); if (listCodec != null) { return new ListBasedMapCodec(listCodec); } else { return null; } } } return null; } MapCodecFactory(CodecFactory codecFactory); Codec<T> create(AnnotatedElement metadata, Class<T> type, ResolverContext context);  }
@Test public void shouldReturnCodecForObjectAnnotatedWithSingleType() { when(annotations.getAnnotation(BoundList.class)).thenReturn(boundList); when(delegate.create(annotations, List.class, context)).thenReturn(codec); when(boundList.type()).thenReturn((Class) Map.Entry.class); MapCodecFactory factory = new MapCodecFactory(delegate); Codec<Map> mapCodec = factory.create(annotations, Map.class, context); assertThat(mapCodec, is(not(nullValue()))); verify(delegate).create(annotations, List.class, context); verify(annotations).getAnnotation(BoundList.class); verifyNoMoreInteractions(annotations, delegate, codec); }
@Test public void shouldReturnCodecForObjectAnnotatedWithMultipleTypes() { when(annotations.getAnnotation(BoundList.class)).thenReturn(boundList); when(delegate.create(annotations, List.class, context)).thenReturn(codec); when(boundList.types()).thenReturn(new Class<?>[] { Map.Entry.class }); MapCodecFactory factory = new MapCodecFactory(delegate); Codec<Map> mapCodec = factory.create(annotations, Map.class, context); assertThat(mapCodec, is(not(nullValue()))); verify(delegate).create(annotations, List.class, context); verify(annotations).getAnnotation(BoundList.class); verifyNoMoreInteractions(annotations, delegate, codec); }
@Test public void shouldReturnCodecForObjectAnnotatedWithChoices() { when(annotations.getAnnotation(BoundList.class)).thenReturn(boundList); when(delegate.create(annotations, List.class, context)).thenReturn(codec); when(boundList.selectFrom()).thenReturn(choices); when(choices.alternatives()).thenReturn(new Choices.Choice[] { firstChoice, secondChoice }); when(firstChoice.type()).thenReturn((Class) Map.Entry.class); when(secondChoice.type()).thenReturn((Class) Map.Entry.class); MapCodecFactory factory = new MapCodecFactory(delegate); Codec<Map> mapCodec = factory.create(annotations, Map.class, context); assertThat(mapCodec, is(not(nullValue()))); verify(delegate).create(annotations, List.class, context); verify(annotations).getAnnotation(BoundList.class); verifyNoMoreInteractions(annotations, delegate, codec); }
@Test public void shouldNotReturnCodecForObjectAnnotatedWithChoicesOneOfWhichNotEntry() { when(annotations.getAnnotation(BoundList.class)).thenReturn(boundList); when(boundList.selectFrom()).thenReturn(choices); when(choices.alternatives()).thenReturn(new Choices.Choice[] { firstChoice, secondChoice }); when(firstChoice.type()).thenReturn((Class) Map.Entry.class); when(secondChoice.type()).thenReturn((Class) String.class); MapCodecFactory factory = new MapCodecFactory(delegate); Codec<Map> mapCodec = factory.create(annotations, Map.class, context); assertThat(mapCodec, is(nullValue())); verify(annotations).getAnnotation(BoundList.class); verifyNoMoreInteractions(annotations, delegate, codec); }