package com.fasterxml.jackson.databind.deser.creators;

import com.fasterxml.jackson.annotation.*;

import com.fasterxml.jackson.databind.*;

public class RequiredCreatorTest extends BaseMapTest
{
    static class FascistPoint {
        int x, y;

        @JsonCreator
        public FascistPoint(@JsonProperty(value="x", required=true) int x,
                @JsonProperty(value="y", required=false) int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    private final ObjectReader POINT_READER = objectMapper().readerFor(FascistPoint.class);
    
    public void testRequiredAnnotatedParam() throws Exception
    {
        FascistPoint p;

        // First: fine if both params passed
        p = POINT_READER.readValue(aposToQuotes("{'y':2,'x':1}"));
        assertEquals(1, p.x);
        assertEquals(2, p.y);
        p = POINT_READER.readValue(aposToQuotes("{'x':3,'y':4}"));
        assertEquals(3, p.x);
        assertEquals(4, p.y);

        // also fine if 'y' is MIA
        p = POINT_READER.readValue(aposToQuotes("{'x':3}"));
        assertEquals(3, p.x);
        assertEquals(0, p.y);

        // but not so good if 'x' missing
        try {
            POINT_READER.readValue(aposToQuotes("{'y':3}"));
            fail("Should not pass");
        } catch (JsonMappingException e) {
            verifyException(e, "Missing required creator property 'x' (index 0)");
        }
    }

    public void testRequiredGloballyParam() throws Exception
    {
        FascistPoint p;

        // as per above, ok to miss 'y' with default settings:
        p = POINT_READER.readValue(aposToQuotes("{'x':2}"));
        assertEquals(2, p.x);
        assertEquals(0, p.y);

        // but not if global checks desired
        ObjectReader r = POINT_READER.with(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES);
        try {
            r.readValue(aposToQuotes("{'x':6}"));
            fail("Should not pass");
        } catch (JsonMappingException e) {
            verifyException(e, "Missing creator property 'y' (index 1)");
        }
    }
}

@@ -472,24 +472,999 @@
    %7D%0A    %7D%0A%0A
+    // %5Bdatabind#2591%5D%0A    static class LoginUserResponse %7B%0A        private String otp;%0A%0A        private String userType;%0A%0A        @JsonCreator%0A        public LoginUserResponse(@JsonProperty(value = %22otp%22, required = true) String otp,%0A                @JsonProperty(value = %22userType%22, required = true) String userType) %7B%0A            this.otp = otp;%0A            this.userType = userType;%0A        %7D%0A%0A        public String getOtp() %7B%0A            return otp;%0A        %7D%0A%0A        public void setOtp(String otp) %7B%0A            this.otp = otp;%0A        %7D%0A%0A        public String getUserType() %7B%0A            return userType;%0A        %7D%0A%0A        public void setUserType(String userType) %7B%0A            this.userType = userType;%0A        %7D%0A    %7D%0A%0A    /*%0A    /**********************************************************************%0A    /* Test methods%0A    /**********************************************************************%0A     */%0A%0A    private final ObjectMapper MAPPER = newJsonMapper();%0A
     private 
@@ -1501,22 +1501,14 @@
 R = 
-objectMapper()
+MAPPER
 .rea
@@ -1535,20 +1535,16 @@
 class);%0A
-    
 %0A    pub
@@ -2943,32 +2943,32 @@
 gException e) %7B%0A
-
             veri
@@ -3040,11 +3040,474 @@
  %7D%0A    %7D
+%0A%0A    // %5Bdatabind#2591%5D%0A    public void testRequiredViaParameter2591() throws Exception%0A    %7B%0A        final String input = aposToQuotes(%22%7B'status':'OK', 'message':'Sent Successfully!'%7D%22);%0A        try %7B%0A            /*LoginUserResponse resp =*/ MAPPER.readValue(input, LoginUserResponse.class);%0A            fail(%22Shoud not pass%22);%0A        %7D catch (JsonMappingException e) %7B%0A            verifyException(e, %22Missing required creator property 'otp'%22);%0A        %7D%0A    %7D
 %0A%7D%0A

Add unit test (passing) for #2591