### Question:
MapJsonAdapter extends JsonAdapter<Map<K, V>> { @Override public void toJson(JsonWriter writer, Map<K, V> map) throws IOException { writer.beginObject(); for (Map.Entry<K, V> entry : map.entrySet()) { if (entry.getKey() == null) { throw new JsonDataException("Map key is null at " + writer.getPath()); } writer.promoteValueToName(); keyAdapter.toJson(writer, entry.getKey()); valueAdapter.toJson(writer, entry.getValue()); } writer.endObject(); } MapJsonAdapter(Moshi moshi, Type keyType, Type valueType); @Override void toJson(JsonWriter writer, Map<K, V> map); @Override Map<K, V> fromJson(JsonReader reader); @Override String toString(); static final Factory FACTORY; }### Answer:
@Test public void mapWithNullKeyFailsToEmit() throws Exception { Map<String, Boolean> map = new LinkedHashMap<>(); map.put(null, true); try { toJson(String.class, Boolean.class, map); fail(); } catch (JsonDataException expected) { assertThat(expected).hasMessageThat().isEqualTo("Map key is null at $."); } }
@Test public void booleanKeyTypeHasCoherentErrorMessage() { Map<Boolean, String> map = new LinkedHashMap<>(); map.put(true, ""); JsonAdapter<Map<Boolean, String>> adapter = mapAdapter(Boolean.class, String.class); try { adapter.toJson(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Boolean cannot be used as a map key in JSON at path $."); } try { adapter.toJsonValue(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Boolean cannot be used as a map key in JSON at path $."); } }
@Test public void objectKeyTypeHasCoherentErrorMessage() { Map<Key, String> map = new LinkedHashMap<>(); map.put(new Key(), ""); JsonAdapter<Map<Key, String>> adapter = mapAdapter(Key.class, String.class); try { adapter.toJson(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Object cannot be used as a map key in JSON at path $."); } try { adapter.toJsonValue(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Object cannot be " + "used as a map key in JSON at path $."); } }
@Test public void arrayKeyTypeHasCoherentErrorMessage() { Map<String[], String> map = new LinkedHashMap<>(); map.put(new String[0], ""); JsonAdapter<Map<String[], String>> adapter = mapAdapter(Types.arrayOf(String.class), String.class); try { adapter.toJson(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Array cannot be used as a map key in JSON at path $."); } try { adapter.toJsonValue(map); fail(); } catch (IllegalStateException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("Array cannot be used as a map key in JSON at path $."); } }