### Question:
DefaultId implements Id { @Override public DefaultId withTag(Tag tag) { return new DefaultId(name, tags.add(tag)); } DefaultId(String name);   DefaultId(String name, ArrayTagSet tags); @Override String name(); @Override Iterable<Tag> tags(); @Override DefaultId withTag(Tag tag); @Override DefaultId withTag(String key, String value); @Override DefaultId withTags(String... ts); @Override DefaultId withTags(Tag... ts); @Override DefaultId withTags(Iterable<Tag> ts); @Override DefaultId withTags(Map<String, String> ts); @Override String getKey(int i); @Override String getValue(int i); @Override int size(); @Override Id filter(BiPredicate<String, String> predicate); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString();  }### Answer:
@Test public void withTagBooleanObjNull() { Assertions.assertThrows(NullPointerException.class, () -> { Boolean value = null; new DefaultId("test").withTag("bool", value); }); }
@Test public void withTagEnumNull() { Assertions.assertThrows(NullPointerException.class, () -> { Enum<?> value = null; new DefaultId("test").withTag("enum", value); }); }
@Test public void tagListIterator() { List<Tag> expected = new ArrayList<>(); expected.add(Tag.of("name", "foo")); expected.add(Tag.of("k1", "v1")); expected.add(Tag.of("k2", "v2")); DefaultId id = (new DefaultId("foo")).withTag("k1", "v1").withTag("k2", "v2"); List<Tag> actual = new ArrayList<>(); for (Tag t : id) { actual.add(t); } Assertions.assertEquals(expected, actual); }
@Test public void tagListForEach() { List<Tag> expected = new ArrayList<>(); expected.add(Tag.of("name", "foo")); expected.add(Tag.of("k1", "v1")); expected.add(Tag.of("k2", "v2")); DefaultId id = (new DefaultId("foo")).withTag("k1", "v1").withTag("k2", "v2"); List<Tag> actual = new ArrayList<>(); id.forEach((k, v) -> actual.add(Tag.of(k, v))); Assertions.assertEquals(expected, actual); }