View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.api;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertTrue;
25  import static org.junit.Assert.fail;
26  
27  import java.lang.reflect.Field;
28  import java.lang.reflect.InvocationTargetException;
29  
30  import org.apache.commons.beanutils.ConversionException;
31  import org.apache.commons.beanutils.ConvertUtilsBean;
32  import org.apache.commons.beanutils.Converter;
33  import org.junit.Test;
34  import org.powermock.reflect.Whitebox;
35  
36  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
37  import com.puppycrawl.tools.checkstyle.DefaultContext;
38  
39  public class AutomaticBeanTest {
40  
41      @Test
42      public void testConfigureNoSuchAttribute() {
43          final TestBean testBean = new TestBean();
44          final DefaultConfiguration conf = new DefaultConfiguration("testConf");
45          conf.addAttribute("NonExistent", "doesn't matter");
46          try {
47              testBean.configure(conf);
48              fail("Exception is expected");
49          }
50          catch (CheckstyleException ex) {
51              final String expected = "Property 'NonExistent' in module ";
52              assertNull("Exceptions cause should be null", ex.getCause());
53              assertTrue("Invalid exception message, should start with: " + expected,
54                      ex.getMessage().startsWith(expected));
55          }
56      }
57  
58      @Test
59      public void testConfigureNoSuchAttribute2() {
60          final TestBean testBean = new TestBean();
61          final DefaultConfiguration conf = new DefaultConfiguration("testConf");
62          conf.addAttribute("privateField", "doesn't matter");
63          try {
64              testBean.configure(conf);
65              fail("Exception is expected");
66          }
67          catch (CheckstyleException ex) {
68              final String expected = "Property 'privateField' in module ";
69              assertNull("Exceptions cause should be null", ex.getCause());
70              assertTrue("Invalid exception message, should start with: " + expected,
71                      ex.getMessage().startsWith(expected));
72          }
73      }
74  
75      @Test
76      public void testSetupChildFromBaseClass() throws CheckstyleException {
77          final TestBean testBean = new TestBean();
78          testBean.configure(new DefaultConfiguration("bean config"));
79          testBean.setupChild(null);
80          try {
81              testBean.setupChild(new DefaultConfiguration("dummy"));
82              fail("Exception expected");
83          }
84          catch (CheckstyleException ex) {
85              final String expectedMessage = "dummy is not allowed as a child in bean config. "
86                      + "Please review 'Parent Module' section for this Check"
87                      + " in web documentation if Check is standard.";
88              assertEquals("Invalid exception message", expectedMessage, ex.getMessage());
89          }
90      }
91  
92      @Test
93      public void testSetupInvalidChildFromBaseClass() throws Exception {
94          final TestBean testBean = new TestBean();
95          final DefaultConfiguration parentConf = new DefaultConfiguration("parentConf");
96          final DefaultConfiguration childConf = new DefaultConfiguration("childConf");
97          final Field field = AutomaticBean.class.getDeclaredField("configuration");
98          field.setAccessible(true);
99          field.set(testBean, parentConf);
100 
101         try {
102             testBean.setupChild(childConf);
103             fail("expecting checkstyle exception");
104         }
105         catch (CheckstyleException ex) {
106             assertEquals("expected exception", "childConf is not allowed as a "
107                             + "child in parentConf. Please review 'Parent Module' section "
108                             + "for this Check in web documentation if Check is standard.",
109                     ex.getMessage());
110         }
111     }
112 
113     @Test
114     public void testContextualizeInvocationTargetException() {
115         final TestBean testBean = new TestBean();
116         final DefaultContext context = new DefaultContext();
117         context.add("exceptionalMethod", 123.0f);
118         try {
119             testBean.contextualize(context);
120             fail("InvocationTargetException is expected");
121         }
122         catch (CheckstyleException ex) {
123             final String expected = "Cannot set property ";
124             assertTrue("Invalid exception cause, should be: InvocationTargetException",
125                     ex.getCause() instanceof InvocationTargetException);
126             assertTrue("Invalid exception message, should start with: " + expected,
127                     ex.getMessage().startsWith(expected));
128         }
129     }
130 
131     @Test
132     public void testContextualizeConversionException() {
133         final TestBean testBean = new TestBean();
134         final DefaultContext context = new DefaultContext();
135         context.add("val", "some string");
136         try {
137             testBean.contextualize(context);
138             fail("InvocationTargetException is expected");
139         }
140         catch (CheckstyleException ex) {
141             final String expected = "illegal value ";
142             assertTrue("Invalid exception cause, should be: ConversionException",
143                     ex.getCause() instanceof ConversionException);
144             assertTrue("Invalid exception message, should start with: " + expected,
145                     ex.getMessage().startsWith(expected));
146         }
147     }
148 
149     @Test
150     public void testTestBean() {
151         final TestBean testBean = new TestBean();
152         testBean.setVal(0);
153         testBean.setWrong("wrongVal");
154         testBean.assignPrivateFieldSecretly(null);
155         try {
156             testBean.setExceptionalMethod("someValue");
157             fail("exception expected");
158         }
159         catch (IllegalStateException ex) {
160             assertEquals("Invalid exception message",
161                     "null,wrongVal,0,someValue", ex.getMessage());
162         }
163     }
164 
165     @Test
166     public void testRegisterIntegralTypes() throws Exception {
167         final ConvertUtilsBeanStub convertUtilsBean = new ConvertUtilsBeanStub();
168         Whitebox.invokeMethod(AutomaticBean.class, "registerIntegralTypes", convertUtilsBean);
169         assertEquals("Number of converters registered differs from expected",
170                 81, convertUtilsBean.getRegisterCount());
171     }
172 
173     private static class ConvertUtilsBeanStub extends ConvertUtilsBean {
174 
175         private int registerCount;
176 
177         @Override
178         public void register(Converter converter, Class<?> clazz) {
179             super.register(converter, clazz);
180             registerCount++;
181         }
182 
183         public int getRegisterCount() {
184             return registerCount;
185         }
186     }
187 
188     private static class TestBean extends AutomaticBean {
189 
190         private String privateField;
191 
192         private String wrong;
193 
194         private int val;
195 
196         public void setWrong(String wrong) {
197             this.wrong = wrong;
198         }
199 
200         public void setVal(int val) {
201             this.val = val;
202         }
203 
204         public void assignPrivateFieldSecretly(String input) {
205             privateField = input;
206         }
207 
208         public void setExceptionalMethod(String value) {
209             throw new IllegalStateException(privateField + "," + wrong + "," + val + "," + value);
210         }
211 
212         @Override
213         protected void finishLocalSetup() throws CheckstyleException {
214             // No code by default
215         }
216 
217     }
218 }