| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.felix.converter.impl; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.net.URL; |
| import java.time.LocalDate; |
| import java.time.LocalDateTime; |
| import java.time.LocalTime; |
| import java.time.OffsetDateTime; |
| import java.time.OffsetTime; |
| import java.time.ZonedDateTime; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.LinkedHashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.UUID; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.service.converter.Adapter; |
| import org.osgi.service.converter.ConversionException; |
| import org.osgi.service.converter.TypeReference; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotSame; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| public class ConverterServiceTest { |
| private ConverterService converter; |
| |
| @Before |
| public void setUp() { |
| converter = new ConverterService(); |
| } |
| |
| @After |
| public void tearDown() { |
| converter = null; |
| } |
| |
| @Test |
| public void testSimpleConversions() { |
| // Conversions to String |
| assertEquals("abc", converter.convert("abc").to(String.class)); |
| assertEquals("true", converter.convert(Boolean.TRUE).to(String.class)); |
| assertEquals("c", converter.convert('c').to(String.class)); |
| assertEquals("123", converter.convert(123).to(String.class)); |
| assertEquals("" + Long.MAX_VALUE, converter.convert(Long.MAX_VALUE).to(String.class)); |
| assertEquals("12.3", converter.convert(12.3f).to(String.class)); |
| assertEquals("12.345", converter.convert(12.345d).to(String.class)); |
| assertEquals(null, converter.convert(null).to(String.class)); |
| assertEquals(null, converter.convert(Collections.emptyList()).to(String.class)); |
| |
| String bistr = "999999999999999999999"; // more than Long.MAX_VALUE |
| assertEquals(bistr, converter.convert(new BigInteger(bistr)).to(String.class)); |
| |
| // Conversions to boolean |
| assertTrue(converter.convert("true").to(boolean.class)); |
| assertTrue(converter.convert("TRUE").to(boolean.class)); |
| assertTrue(converter.convert('x').to(boolean.class)); |
| assertTrue(converter.convert(Long.MIN_VALUE).to(boolean.class)); |
| assertTrue(converter.convert(72).to(boolean.class)); |
| assertFalse(converter.convert("false").to(boolean.class)); |
| assertFalse(converter.convert("bleh").to(boolean.class)); |
| assertFalse(converter.convert((char) 0).to(boolean.class)); |
| assertFalse(converter.convert(null).to(boolean.class)); |
| assertFalse(converter.convert(Collections.emptyList()).to(boolean.class)); |
| |
| // Converstions to integer |
| assertEquals(Integer.valueOf(123), converter.convert("123").to(int.class)); |
| assertEquals(1, (int) converter.convert(true).to(int.class)); |
| assertEquals(0, (int) converter.convert(false).to(int.class)); |
| |
| // Conversions to Class |
| assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(Class.class)); |
| assertNull(converter.convert(null).to(Class.class)); |
| assertNull(converter.convert(Collections.emptyList()).to(Class.class)); |
| |
| assertEquals(Integer.valueOf(123), converter.convert("123").to(Integer.class)); |
| assertEquals(Long.valueOf(123), converter.convert("123").to(Long.class)); |
| assertEquals('1', (char) converter.convert("123").to(Character.class)); |
| assertEquals('Q', (char) converter.convert(null).defaultValue('Q').to(Character.class)); |
| assertEquals((char) 123, (char) converter.convert(123L).to(Character.class)); |
| assertEquals(Byte.valueOf((byte) 123), converter.convert("123").to(Byte.class)); |
| assertEquals(Float.valueOf("12.3"), converter.convert("12.3").to(Float.class)); |
| assertEquals(Double.valueOf("12.3"), converter.convert("12.3").to(Double.class)); |
| } |
| |
| enum TestEnum { FOO, BAR, BLAH, FALSE, X}; |
| @Test |
| public void testEnums() { |
| assertEquals(TestEnum.BLAH, converter.convert("BLAH").to(TestEnum.class)); |
| assertEquals(TestEnum.X, converter.convert('X').to(TestEnum.class)); |
| assertEquals(TestEnum.FALSE, converter.convert(false).to(TestEnum.class)); |
| assertEquals(TestEnum.BAR, converter.convert(1).to(TestEnum.class)); |
| assertNull(converter.convert(null).to(TestEnum.class)); |
| assertNull(converter.convert(Collections.emptySet()).to(TestEnum.class)); |
| } |
| |
| @Test |
| public void testIdentialTarget() { |
| Object o = new Object(); |
| assertSame(o, converter.convert(o).to(Object.class)); |
| |
| Thread t = new Thread(); // No converter available |
| assertSame(t, converter.convert(t).to(Thread.class)); |
| assertSame(t, converter.convert(t).to(Runnable.class)); |
| assertSame(t, converter.convert(t).to(Object.class)); |
| |
| Thread st = new Thread() {}; // Subclass of Thread |
| assertSame(st, converter.convert(st).to(Thread.class)); |
| } |
| |
| @Test |
| public void testFromUnknownDataTypeViaString() { |
| class MyClass { |
| @Override |
| public String toString() { |
| return "1234"; |
| } |
| }; |
| MyClass o = new MyClass(); |
| |
| assertEquals(1234, (int) converter.convert(o).to(int.class)); |
| assertEquals("1234", converter.convert(o).to(String.class)); |
| } |
| |
| @Test |
| public void testToUnknownViaStringCtor() { |
| class MyClass { |
| @Override |
| public String toString() { |
| return "http://127.0.0.1:1234/blah"; |
| } |
| }; |
| MyClass o = new MyClass(); |
| |
| URL url = converter.convert(o).to(URL.class); |
| assertEquals("http://127.0.0.1:1234/blah", url.toString()); |
| assertEquals("http", url.getProtocol()); |
| assertEquals("127.0.0.1", url.getHost()); |
| assertEquals(1234, url.getPort()); |
| assertEquals("/blah", url.getPath()); |
| |
| assertNull(converter.convert(null).to(URL.class)); |
| assertNull(converter.convert(Collections.emptyList()).to(URL.class)); |
| } |
| |
| @Test |
| public void testFromMultiToSingle() { |
| assertEquals("abc", converter.convert(Collections.singleton("abc")).to(String.class)); |
| assertEquals("abc", converter.convert(Arrays.asList("abc", "def", "ghi")).to(String.class)); |
| assertEquals(42, (int) converter.convert(Arrays.asList("42", "17")).to(Integer.class)); |
| MyClass2 mc = converter.convert(new String[] {"xxx", "yyy", "zzz"}).to(MyClass2.class); |
| assertEquals("xxx", mc.toString()); |
| MyClass2[] arr = new MyClass2[] {new MyClass2("3.1412"), new MyClass2("6.2824")}; |
| assertEquals(Float.valueOf(3.1412f), Float.valueOf(converter.convert(arr).to(float.class))); |
| } |
| |
| @Test |
| public void testFromListToSet() { |
| List<Object> l = new ArrayList<>(Arrays.asList("A", 'B', 333)); |
| |
| Set<?> s = converter.convert(l).to(Set.class); |
| assertEquals(3, s.size()); |
| |
| for (Object o : s) { |
| Object expected = l.remove(0); |
| assertEquals(expected, o); |
| } |
| } |
| |
| @Test |
| public void testFromGenericSetToLinkedList() { |
| Set<Integer> s = new LinkedHashSet<>(); |
| s.add(123); |
| s.add(456); |
| |
| LinkedList<String> ll = converter.convert(s).to(new TypeReference<LinkedList<String>>() {}); |
| assertEquals(Arrays.asList("123", "456"), ll); |
| } |
| |
| @Test |
| public void testFromArrayToGenericOrderPreservingSet() { |
| String[] sa = {"567", "-765", "0", "-900"}; |
| |
| // Returned set should be order preserving |
| Set<Long> s = converter.convert(sa).to(new TypeReference<Set<Long>>() {}); |
| |
| List<String> sl = new ArrayList<>(Arrays.asList(sa)); |
| for (long l : s) { |
| long expected = Long.parseLong(sl.remove(0)); |
| assertEquals(expected, l); |
| } |
| } |
| |
| @Test |
| public void testFromSetToArray() { |
| Set<Integer> s = new LinkedHashSet<>(); |
| s.add(Integer.MIN_VALUE); |
| |
| long[] la = converter.convert(s).to(long[].class); |
| assertEquals(1, la.length); |
| assertEquals(Integer.MIN_VALUE, la[0]); |
| } |
| |
| @Test |
| public void testStringArrayToIntegerArray() { |
| String[] sa = {"999", "111", "-909"}; |
| Integer[] ia = converter.convert(sa).to(Integer[].class); |
| assertEquals(3, ia.length); |
| assertArrayEquals(new Integer[] {999, 111, -909}, ia); |
| } |
| |
| @Test |
| public void testCharArrayConversion() { |
| char[] ca = converter.convert(new int[] {9,8,7}).to(char[].class); |
| assertArrayEquals(new char[] {9,8,7}, ca); |
| Character[] ca2 = converter.convert((long) 17).to(Character[].class); |
| assertArrayEquals(new Character[] {(char)17}, ca2); |
| char[] ca3 = converter.convert(new short[] {257}).to(char[].class); |
| assertArrayEquals(new char[] {257}, ca3); |
| char c = converter.convert(new char[] {'x', 'y'}).to(char.class); |
| assertEquals('x', c); |
| char[] ca4a = {'x', 'y'}; |
| char[] ca4b = converter.convert(ca4a).to(char[].class); |
| assertArrayEquals(new char [] {'x', 'y'}, ca4b); |
| assertNotSame("Should have created a new instance", ca4a, ca4b); |
| } |
| |
| @Test |
| public void testLongCollectionConversion() { |
| long[] l = converter.convert(Long.MAX_VALUE).to(long[].class); |
| assertArrayEquals(new long[] {Long.MAX_VALUE}, l); |
| Long[] l2 = converter.convert(Long.MAX_VALUE).to(Long[].class); |
| assertArrayEquals(new Long[] {Long.MAX_VALUE}, l2); |
| List<Long> ll = converter.convert(new long[] {Long.MIN_VALUE, Long.MAX_VALUE}).to(new TypeReference<List<Long>>() {}); |
| assertEquals(Arrays.asList(Long.MIN_VALUE, Long.MAX_VALUE), ll); |
| List<Long> ll2 = converter.convert(Arrays.asList(123, 345)).to(new TypeReference<List<Long>>() {}); |
| assertEquals(Arrays.asList(123L, 345L), ll2); |
| |
| } |
| |
| @Test |
| public void testExceptionDefaultValue() { |
| assertEquals(42, (int) converter.convert("haha").defaultValue(42).to(int.class)); |
| assertNull(converter.convert("haha").defaultValue(null).to(int.class)); |
| try { |
| converter.convert("haha").to(int.class); |
| fail("Should have thrown an exception"); |
| } catch (ConversionException ex) { |
| // good |
| } |
| } |
| |
| @Test |
| public void testStandardStringArrayConversion() { |
| String[] sa = {"A", "B"}; |
| assertEquals("A", converter.convert(sa).toString()); |
| assertEquals("A", converter.convert(sa).to(String.class)); |
| |
| String[] sa2 = {"A"}; |
| assertArrayEquals(sa2, converter.convert("A").to(String[].class)); |
| } |
| |
| @Test |
| public void testCustomStringArrayConverstion() { |
| Adapter adapter = converter.getAdapter(); |
| adapter.rule(String[].class, String.class, |
| v -> Stream.of(v).collect(Collectors.joining(",")), |
| v -> v.split(",")); |
| |
| String[] sa = {"A", "B"}; |
| assertEquals("A,B", adapter.convert(sa).to(String.class)); |
| assertArrayEquals(sa, adapter.convert("A,B").to(String[].class)); |
| } |
| |
| @Test |
| public void testUUIDConversion() { |
| ConverterService cs = new ConverterService(); |
| UUID uuid = UUID.randomUUID(); |
| String s = cs.convert(uuid).to(String.class); |
| assertTrue("UUID should be something", s.length() > 0); |
| UUID uuid2 = cs.convert(s).to(UUID.class); |
| assertEquals(uuid, uuid2); |
| } |
| |
| @Test |
| public void testPatternConversion() { |
| String p = "\\S*"; |
| Pattern pattern = converter.convert(p).to(Pattern.class); |
| Matcher matcher = pattern.matcher("hi"); |
| assertTrue(matcher.matches()); |
| String p2 = converter.convert(pattern).to(String.class); |
| assertEquals(p, p2); |
| } |
| |
| @Test |
| public void testLocalDateTime() { |
| LocalDateTime ldt = LocalDateTime.now(); |
| String s = converter.convert(ldt).to(String.class); |
| assertTrue(s.length() > 0); |
| LocalDateTime ldt2 = converter.convert(s).to(LocalDateTime.class); |
| assertEquals(ldt, ldt2); |
| } |
| |
| @Test |
| public void testLocalDate() { |
| LocalDate ld = LocalDate.now(); |
| String s = converter.convert(ld).to(String.class); |
| assertTrue(s.length() > 0); |
| LocalDate ld2 = converter.convert(s).to(LocalDate.class); |
| assertEquals(ld, ld2); |
| } |
| |
| @Test |
| public void testLocalTime() { |
| LocalTime lt = LocalTime.now(); |
| String s = converter.convert(lt).to(String.class); |
| assertTrue(s.length() > 0); |
| LocalTime lt2 = converter.convert(s).to(LocalTime.class); |
| assertEquals(lt, lt2); |
| } |
| |
| @Test |
| public void testOffsetDateTime() { |
| OffsetDateTime ot = OffsetDateTime.now(); |
| String s = converter.convert(ot).to(String.class); |
| assertTrue(s.length() > 0); |
| OffsetDateTime ot2 = converter.convert(s).to(OffsetDateTime.class); |
| assertEquals(ot, ot2); |
| } |
| |
| @Test |
| public void testOffsetTime() { |
| OffsetTime ot = OffsetTime.now(); |
| String s = converter.convert(ot).to(String.class); |
| assertTrue(s.length() > 0); |
| OffsetTime ot2 = converter.convert(s).to(OffsetTime.class); |
| assertEquals(ot, ot2); |
| } |
| |
| @Test |
| public void testZonedDateTime() { |
| ZonedDateTime zdt = ZonedDateTime.now(); |
| String s = converter.convert(zdt).to(String.class); |
| assertTrue(s.length() > 0); |
| ZonedDateTime zdt2 = converter.convert(s).to(ZonedDateTime.class); |
| assertEquals(zdt, zdt2); |
| } |
| |
| @Test |
| public void testDefaultValue() { |
| long l = converter.convert(null).defaultValue("12").to(Long.class); |
| assertEquals(12L, l); |
| } |
| |
| static class MyClass2 { |
| private final String value; |
| public MyClass2(String v) { |
| value = v; |
| } |
| |
| @Override |
| public String toString() { |
| return value; |
| } |
| } |
| } |