1/**
2 * Copyright (c) 2008, http://www.snakeyaml.org
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.yaml.snakeyaml.constructor;
17
18import java.math.BigInteger;
19
20import junit.framework.TestCase;
21
22import org.yaml.snakeyaml.DumperOptions;
23import org.yaml.snakeyaml.Util;
24import org.yaml.snakeyaml.Yaml;
25import org.yaml.snakeyaml.error.YAMLException;
26
27public class BeanConstructorTest extends TestCase {
28
29    public void testPrimitivesConstructor() {
30        Yaml yaml = new Yaml(new Constructor(TestBean1.class));
31        String document = Util.getLocalResource("constructor/test-primitives1.yaml");
32        TestBean1 result = (TestBean1) yaml.load(document);
33        assertNotNull(result);
34        assertEquals(new Byte((byte) 1), result.getByteClass());
35        assertEquals((byte) -3, result.getBytePrimitive());
36        assertEquals(new Short((short) 0), result.getShortClass());
37        assertEquals((short) -13, result.getShortPrimitive());
38        assertEquals(new Integer(5), result.getInteger());
39        assertEquals(17, result.getIntPrimitive());
40        assertEquals("the text", result.getText());
41        assertEquals("13", result.getId());
42        assertEquals(new Long(11111111111L), result.getLongClass());
43        assertEquals(9999999999L, result.getLongPrimitive());
44        assertEquals(Boolean.TRUE, result.getBooleanClass());
45        assertTrue(result.isBooleanPrimitive());
46        assertEquals(Character.valueOf('2'), result.getCharClass());
47        assertEquals('#', result.getCharPrimitive());
48        assertEquals(new BigInteger("1234567890123456789012345678901234567890"),
49                result.getBigInteger());
50        assertEquals(new Float(2), result.getFloatClass());
51        assertEquals(new Float(3.1416), result.getFloatPrimitive());
52        assertEquals(new Double(4), result.getDoubleClass());
53        assertEquals(new Double(11200), result.getDoublePrimitive());
54        assertEquals(1199836800000L, result.getDate().getTime());
55        assertEquals("public", result.publicField);
56        //
57        DumperOptions options = new DumperOptions();
58        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
59        Yaml yamlToDump = new Yaml(options);
60        String output = yamlToDump.dump(result);
61        TestBean1 result2 = (TestBean1) yaml.load(output);
62        assertNotNull(result2);
63        TestBean1 result3 = (TestBean1) new Yaml().load(output);
64        assertNotNull(result3);
65    }
66
67    public void testNoClassConstructor() {
68        try {
69            new Yaml(new Constructor((Class<? extends Object>) null));
70            fail("Class must be provided.");
71        } catch (NullPointerException e) {
72            assertEquals("Root class must be provided.", e.getMessage());
73        }
74    }
75
76    public void testNoClassConstructorString() throws ClassNotFoundException {
77        try {
78            new Yaml(new Constructor((String) null));
79            fail("Class must be provided.");
80        } catch (NullPointerException e) {
81            assertEquals("Root type must be provided.", e.getMessage());
82        }
83    }
84
85    public void testNoClassConstructorEmptyString() throws ClassNotFoundException {
86        try {
87            new Yaml(new Constructor(" "));
88            fail("Class must be provided.");
89        } catch (YAMLException e) {
90            assertEquals("Root type must be provided.", e.getMessage());
91        }
92    }
93
94    public void testCharacter() {
95        Yaml yaml = new Yaml(new Constructor(TestBean1.class));
96        String document = "charClass: id";
97        try {
98            yaml.load(document);
99            fail("Only one char must be allowed.");
100        } catch (Exception e) {
101            assertTrue(e.getMessage(),
102                    e.getMessage().contains("Invalid node Character: 'id'; length: 2"));
103        }
104        document = "charClass: #";
105        TestBean1 bean = (TestBean1) yaml.load(document);
106        assertNull("Null must be accepted.", bean.getCharClass());
107        document = "charClass: ''";
108        bean = (TestBean1) yaml.load(document);
109        assertNull("Null must be accepted.", bean.getCharClass());
110        document = "charClass:\n";
111        bean = (TestBean1) yaml.load(document);
112        assertNull("Null must be accepted.", bean.getCharClass());
113        document = "charClass: 1\n";
114        bean = (TestBean1) yaml.load(document);
115        assertEquals(Character.valueOf('1'), bean.getCharClass());
116    }
117
118    public void testNoEmptyConstructor() {
119        Yaml yaml = new Yaml(new Constructor(TestBean2.class));
120        String document = "text: qwerty";
121        try {
122            yaml.load(document);
123            fail("No empty constructor available");
124        } catch (Exception e) {
125            assertTrue(e.getMessage(), e.getMessage().contains("NoSuchMethodException"));
126        }
127        TestBean2 bean = new TestBean2();
128        assertEquals("", bean.getText());
129    }
130
131    private class TestBean2 {
132        private String text;
133
134        public TestBean2() {
135            setText("");
136        }
137
138        public String getText() {
139            return text;
140        }
141
142        public void setText(String text) {
143            this.text = text;
144        }
145    }
146
147    public void testPrivateMethod() {
148        // TODO: Are we sure no private ????
149        Yaml yaml = new Yaml(new Constructor(TestBean2.class));
150        String document = "text: qwerty";
151        try {
152            yaml.load(document);
153            fail("Private method cannot be called.");
154        } catch (Exception e) {
155            assertTrue(e.getMessage(), e.getMessage().contains("NoSuchMethodException"));
156        }
157    }
158
159    public void testKeyNotScalar() {
160        Yaml yaml = new Yaml(new Constructor(TestBean1.class));
161        String document = "[1, 2]: qwerty";
162        try {
163            yaml.load(document);
164            fail("Keys must be scalars.");
165        } catch (Exception e) {
166            assertTrue(e.getMessage(), e.getMessage().contains("Keys must be scalars but found"));
167        }
168    }
169
170    public void testInvalidKey() {
171        Yaml yaml = new Yaml(new Constructor(TestBean1.class));
172        String document = "something: qwerty";
173        try {
174            yaml.load(document);
175            fail("Non-existing property must fail.");
176        } catch (Exception e) {
177            assertTrue(e.getMessage(),
178                    e.getMessage().contains("Unable to find property 'something'"));
179        }
180    }
181
182    public void testStaticField() {
183        Yaml yaml = new Yaml(new Constructor(TestBean1.class));
184        String document = "staticInteger: 123";
185        try {
186            yaml.load(document);
187            fail("Staic variables must not be used.");
188        } catch (Exception e) {
189            assertTrue(e.getMessage(),
190                    e.getMessage().contains("Unable to find property 'staticInteger'"));
191        }
192    }
193
194    public void testScalarContructor() {
195        Yaml yaml = new Yaml(new Constructor(Parent1.class));
196        String document = "id: 123\nchild: 25";
197        Parent1 parent = (Parent1) yaml.load(document);
198        assertEquals("123", parent.getId());
199        Child1 child = parent.getChild();
200        assertEquals(new Integer(25), child.getCode());
201    }
202
203    public void testScalarContructorException() {
204        Yaml yaml = new Yaml(new Constructor(ExceptionParent.class));
205        String document = "id: 123\nchild: 25";
206        try {
207            yaml.load(document);
208            fail("ExceptionParent should not be created.");
209        } catch (Exception e) {
210            assertTrue(
211                    e.getMessage(),
212                    e.getMessage().contains(
213                            "Can't construct a java object for scalar tag:yaml.org,2002:int"));
214        }
215    }
216
217    static public class ExceptionParent {
218        private String id;
219        private ExceptionChild child;
220
221        public String getId() {
222            return id;
223        }
224
225        public void setId(String id) {
226            this.id = id;
227        }
228
229        public ExceptionChild getChild() {
230            return child;
231        }
232
233        public void setChild(ExceptionChild child) {
234            this.child = child;
235        }
236
237    }
238
239    public static class ExceptionChild {
240        private Integer code;
241
242        public ExceptionChild(Integer code) {
243            throw new RuntimeException("ExceptionChild cannot be created.");
244        }
245
246        public Integer getCode() {
247            return code;
248        }
249    }
250}
251