package com.fasterxml.jackson.databind.deser;

import com.fasterxml.jackson.databind.*;

/**
 * Simple unit tests to verify that it is possible to handle
 * potentially cyclic structures, as long as object graph itself
 * is not cyclic. This is the case for directed hierarchies like
 * trees and DAGs.
 */
public class TestCyclicTypes
    extends BaseMapTest
{
    /*
    /**********************************************************
    /* Helper bean classes
    /**********************************************************
     */

    static class Bean
    {
        Bean _next;
        String _name;

        public Bean() { }

        public void setNext(Bean b) { _next = b; }
        public void setName(String n) { _name = n; }

    }

    static class LinkA {
        public LinkB next;
    }

    static class LinkB {
        private LinkA a;

        public void setA(LinkA a) { this.a = a; }
        public LinkA getA() { return a; }
    }

    static class GenericLink<T> {
        public GenericLink<T> next;
    }

    static class StringLink extends GenericLink<String> {
    }

    /*
    /**********************************************************
    /* Unit tests
    /**********************************************************
     */

    public void testLinked() throws Exception
    {
        Bean first = new ObjectMapper().readValue
            ("{\"name\":\"first\", \"next\": { "
             +" \"name\":\"last\", \"next\" : null }}",
             Bean.class);

        assertNotNull(first);
        assertEquals("first", first._name);
        Bean last = first._next;
        assertNotNull(last);
        assertEquals("last", last._name);
        assertNull(last._next);
    }

    public void testLinkedGeneric() throws Exception
    {
        StringLink link = new ObjectMapper().readValue
            ("{\"next\":null}", StringLink.class);
        assertNotNull(link);
        assertNull(link.next);
    }

    public void testCycleWith2Classes() throws Exception
    {
        LinkA a = new ObjectMapper().readValue("{\"next\":{\"a\":null}}", LinkA.class);
        assertNotNull(a.next);
        LinkB b = a.next;
        assertNull(b.a);
    }
}

@@ -40,16 +40,78 @@
 deser;%0A%0A
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;%0A
 import c
@@ -1145,24 +1145,239 @@
 g%3E %7B%0A    %7D%0A%0A
+    static class Selfie382 %7B%0A        public int id;%0A%0A        @JsonIgnoreProperties(%7B %22parent%22, %22ignoredRef%22 %7D)%0A        public Selfie382 parent;%0A        %0A        public Selfie382(int id) %7B this.id = id; %7D%0A    %7D%0A    %0A
     /*%0A    /
@@ -1522,24 +1522,85 @@
 **%0A     */%0A%0A
+    private final ObjectMapper MAPPER = objectMapper();%0A    %0A
     public v
@@ -1660,34 +1660,22 @@
 first = 
-new ObjectMapper()
+MAPPER
 .readVal
@@ -2115,49 +2115,24 @@
 k = 
-new ObjectMapper().readValue%0A            
+MAPPER.readValue
 (%22%7B%5C
@@ -2318,26 +2318,14 @@
 a = 
-new ObjectMapper()
+MAPPER
 .rea
@@ -2460,10 +2460,441 @@
 ;%0A    %7D%0A
+%0A    // %5BIssue#382%5D: Should be possible to ignore cyclic ref%0A    public void testIgnoredCycle() throws Exception%0A    %7B%0A        Selfie382 self1 = new Selfie382(1);%0A        Selfie382 self2 = new Selfie382(2);%0A        self1.parent = self2;%0A        self2.parent = self1;%0A        String json = MAPPER.writeValueAsString(self1);%0A        assertNotNull(json);%0A        assertEquals(aposToQuotes(%22%7B'id':1,'parent':%7B'id':2%7D%7D%22), json);%0A    %7D%0A%0A
 %7D%0A

Add a unit test wrt #382