@Test
public void supportsCycles() {

    // list-of-map-of-string-to-list-of-...
    StringShape string = StringShape.builder()
            .id("ns.foo#String")
            .build();
    MemberShape key = MemberShape.builder()
            .id("ns.foo#Map$key")
            .target(string.getId())
            .build();
    MemberShape value = MemberShape.builder()
            .id("ns.foo#Map$value")
            .target("ns.foo#List") // cycles here
            .build();
    MapShape map = MapShape.builder()
            .id("ns.foo#Map")
            .key(key)
            .value(value)
            .build();
    MemberShape listMember = MemberShape.builder()
            .id("ns.foo#List$member")
            .target(map.getId())
            .build();
    ListShape list = ListShape.builder()
            .id("ns.foo#List")
            .member(listMember)
            .build();
    Walker walker = new Walker(Model.builder()
            .addShape(list)
            .addShape(listMember)
            .addShape(map)
            .addShape(key)
            .addShape(value)
            .addShape(string)
            .build());
    Set<Shape> connected = walker.walkShapes(listMember);
    assertThat(connected, containsInAnyOrder(list, listMember, map, key, value, string));
}