001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math3.exception.util;
018    
019    import java.util.Locale;
020    import java.util.Arrays;
021    import java.io.IOException;
022    import java.io.ObjectOutputStream;
023    import java.io.ObjectInputStream;
024    import java.io.ByteArrayOutputStream;
025    import java.io.ByteArrayInputStream;
026    
027    import org.junit.Assert;
028    import org.junit.Test;
029    
030    /**
031     * Test for {@link ExceptionContext}.
032     * 
033     * @version $Id$
034     */
035    public class ExceptionContextTest {
036        @Test
037        public void testMessageChain() {
038            final ExceptionContext c = new ExceptionContext(new Exception("oops"));
039            final String sep = " | "; // Non-default separator.
040            final String m1 = "column index (0)";
041            c.addMessage(LocalizedFormats.COLUMN_INDEX, 0);
042            final String m2 = "got 1x2 but expected 3x4";
043            c.addMessage(LocalizedFormats.DIMENSIONS_MISMATCH_2x2, 1, 2, 3, 4);
044            final String m3 = "It didn't work out";
045            c.addMessage(LocalizedFormats.SIMPLE_MESSAGE, m3);
046    
047            Assert.assertEquals(c.getMessage(Locale.US, sep),
048                                m1 + sep + m2 + sep + m3);
049        }
050    
051        @Test
052        public void testNoArgAddMessage() {
053            final ExceptionContext c = new ExceptionContext(new Exception("hello"));
054            c.addMessage(LocalizedFormats.SIMPLE_MESSAGE);
055            Assert.assertEquals(c.getMessage(), "{0}");
056        }
057    
058        @Test
059        public void testContext() {
060            final ExceptionContext c = new ExceptionContext(new Exception("bye"));
061    
062            final String[] keys = {"Key 1", "Key 2"};
063            final Object[] values = {"Value 1", Integer.valueOf(2)};
064    
065            for (int i = 0; i < keys.length; i++) {
066                c.setValue(keys[i], values[i]);
067            }
068    
069            // Check that all keys are present.
070            Assert.assertTrue(c.getKeys().containsAll(Arrays.asList(keys)));
071    
072            // Check that all values are correctly stored.
073            for (int i = 0; i < keys.length; i++) {
074                Assert.assertEquals(values[i], c.getValue(keys[i]));
075            }
076    
077            // Check behaviour on missing key.
078            Assert.assertNull(c.getValue("xyz"));
079        }
080    
081        @Test
082        public void testSerialize()
083            throws IOException,
084                   ClassNotFoundException {
085            final ExceptionContext cOut = new ExceptionContext(new Exception("Apache"));
086            cOut.addMessage(LocalizedFormats.COLUMN_INDEX, 0);
087            cOut.setValue("Key 1", Integer.valueOf(0));
088    
089            ByteArrayOutputStream bos = new ByteArrayOutputStream();
090            ObjectOutputStream oos = new ObjectOutputStream(bos);
091            oos.writeObject(cOut);
092    
093            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
094            ObjectInputStream ois = new ObjectInputStream(bis);
095            ExceptionContext cIn = (ExceptionContext) ois.readObject();
096    
097            Assert.assertTrue(cOut.getMessage().equals(cIn.getMessage()));
098            for (String key : cIn.getKeys()) {
099                Assert.assertTrue(cOut.getValue(key).equals(cIn.getValue(key)));
100            }
101        }
102    
103        @Test
104        public void testSerializeUnserializable() throws Exception {
105            final ExceptionContext cOut = new ExceptionContext(new Exception("Apache Commons Math"));
106            cOut.addMessage(LocalizedFormats.SIMPLE_MESSAGE, "OK");
107            cOut.addMessage(LocalizedFormats.SIMPLE_MESSAGE, new Unserializable());
108            String key = "Key 1";
109            cOut.setValue(key, new Unserializable());
110    
111            {
112                ByteArrayOutputStream bos = new ByteArrayOutputStream();
113                ObjectOutputStream oos = new ObjectOutputStream(bos);
114                oos.writeObject(cOut);
115    
116                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
117                ObjectInputStream ois = new ObjectInputStream(bis);
118                ExceptionContext cIn = (ExceptionContext) ois.readObject();
119    
120                String nsObjStr = (String) cIn.getValue(key);
121                Assert.assertTrue(nsObjStr.matches(".*could not be serialized.*"));
122            }
123        }
124    
125        /**
126         * Class used by {@link #testSerializeUnserializable()}.
127         */
128        private static class Unserializable {
129            Unserializable() {}
130        }
131    }