/******************************************************************************* * Copyright 2014 Analog Devices, Inc. * * Licensed 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 com.analog.lyric.dimple.test.options; import static org.junit.Assert.*; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Set; import org.junit.Test; import com.analog.lyric.dimple.environment.DimpleEnvironment; import com.analog.lyric.dimple.options.DimpleOptionRegistry; import com.analog.lyric.dimple.options.DimpleOptions; import com.analog.lyric.dimple.test.DimpleTestBase; import com.analog.lyric.options.IOptionKey; import com.analog.lyric.options.OptionKey; import com.analog.lyric.options.OptionKeys; import com.google.common.reflect.ClassPath; /** * * @since 0.07 * @author Christopher Barber */ public class TestDimpleOptions extends DimpleTestBase { /** * Test contents of {@link DimpleOptionRegistry} and {@link DimpleOptions} classes. * <p> * Makes sure that options are not accidentally omitted because they have mis-matched * name or are not declared "public static final". * <p> * @since 0.07 */ @Test public void test() throws IllegalAccessException { DimpleOptionRegistry registry = DimpleEnvironment.active().optionRegistry(); Set<IOptionKey<?>> allKeys = new HashSet<IOptionKey<?>>(); for (IOptionKey<?> key : registry) { assertSame(key, registry.get(OptionKey.canonicalName(key))); assertSame(key, registry.get(OptionKey.qualifiedName(key))); assertSame(key, registry.asKey(key)); assertSame(key, registry.asKey(OptionKey.qualifiedName(key))); assertTrue(allKeys.add(key)); } Set<Class<?>> optionDeclarers = new HashSet<Class<?>>(); Set<IOptionKey<?>> allKeys2 = new HashSet<IOptionKey<?>>(); for (OptionKeys keys : registry.getOptionKeys()) { assertTrue(keys.size() > 0); for (IOptionKey<?> key : keys.values()) { assertTrue(allKeys2.add(key)); } Class<?> declaringClass = keys.declaringClass(); optionDeclarers.add(declaringClass); for (Field field : declaringClass.getDeclaredFields()) { if (IOptionKey.class.isAssignableFrom(field.getType())) { final int modifiers = field.getModifiers(); assertTrue(Modifier.isFinal(modifiers)); assertTrue(Modifier.isPublic(modifiers)); assertTrue(Modifier.isStatic(modifiers)); IOptionKey<?> key = (IOptionKey<?>)field.get(declaringClass); assertEquals(field.getName(), key.name()); assertSame(key, registry.get(OptionKey.qualifiedName(key))); assertSame(declaringClass, key.getDeclaringClass()); } } } // Look for option declarations that are not automatically included in the registry. try { String errorMessage = ""; ClassPath dimpleClassPath = ClassPath.from(DimpleOptionRegistry.class.getClassLoader()); Set<ClassPath.ClassInfo> dimpleClassInfo = dimpleClassPath.getTopLevelClassesRecursive("com.analog.lyric.dimple"); for (ClassPath.ClassInfo info : dimpleClassInfo) { String packageName = info.getPackageName(); if (packageName.startsWith("com.analog.lyric.dimple.test") || packageName.startsWith("com.analog.lyric.dimple.jsproxy")) { // Skip test packages continue; } Class<?> dimpleClass = info.load(); OptionKeys keys = OptionKeys.declaredInClass(dimpleClass); if (!keys.isEmpty()) { if (!optionDeclarers.contains(dimpleClass)) { errorMessage += String.format("%s not in DimpleRegistry\n", keys.declaringClass().getName()); } } } if (!errorMessage.isEmpty()) { // When this fails, either add the class in the constructor of DimpleOptionRegistry or // remove the option declarations if they are not used. fail(errorMessage); } } catch (IOException ex) { fail(ex.toString()); } // TODO check for missing option keys assertEquals(allKeys, allKeys2); } }