/******************************************************************************* * 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.events; import static org.junit.Assert.*; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.nio.charset.Charset; import java.util.List; import org.eclipse.jdt.annotation.Nullable; import org.junit.Test; import com.analog.lyric.dimple.environment.DimpleEnvironment; import com.analog.lyric.dimple.events.DimpleEvent; import com.analog.lyric.dimple.events.DimpleEventListener; import com.analog.lyric.dimple.events.DimpleEventLogger; import com.analog.lyric.dimple.events.IDimpleEventSource; import com.analog.lyric.dimple.events.IModelEventSource; import com.analog.lyric.dimple.model.core.FactorAddEvent; import com.analog.lyric.dimple.model.core.FactorGraph; import com.analog.lyric.dimple.model.domains.DiscreteDomain; import com.analog.lyric.dimple.model.variables.Discrete; import com.analog.lyric.dimple.test.DimpleTestBase; import com.google.common.io.Files; /** * Unit test for {@link DimpleEventLogger} * * @since 0.06 * @author Christopher Barber */ @SuppressWarnings({"null", "deprecation"}) public class TestDimpleEventLogger extends DimpleTestBase { @Test public void test() throws IOException { final DimpleEnvironment env = DimpleEnvironment.active(); assertNull(env.getEventListener()); DimpleEventLogger logger = new DimpleEventLogger(); assertTrue(logger.isClear()); assertSame(System.err, logger.out()); assertEquals(0, logger.verbosity()); assertNull(logger.file()); assertTrue(logger.isOpen()); assertSame(env, logger.getEnvironment()); logger.close(); assertFalse(logger.isOpen()); assertNull(logger.out()); logger.clear(); logger.open(System.out); assertTrue(logger.isOpen()); assertSame(System.out, logger.out()); File tmpFile = null; try { tmpFile = File.createTempFile("TestDimpleEventLogger", ".txt"); tmpFile.deleteOnExit(); logger.open(tmpFile); assertTrue(logger.isOpen()); assertSame(tmpFile, logger.file()); logger.out().println("test"); assertFile(tmpFile, "test"); logger.close(); assertFalse(logger.isOpen()); logger.open(tmpFile); logger.out().println("foo"); assertFile(tmpFile, "test", "foo"); logger.open(tmpFile, false); logger.out().println("barf"); assertFile(tmpFile, "barf"); } finally { logger.close(); if (tmpFile != null) { assertTrue(tmpFile.delete()); } } // Force line separator character used by PrintStream to be \n to avoid problems on Windows. System.setProperty("line.separator", "\n"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); PrintStream out = new PrintStream(bos); logger.open(out); assertTrue(logger.isOpen()); assertSame(out, logger.out()); assertNull(logger.file()); assertTrue(logger.logEntries().isEmpty()); FactorGraph fg = new FactorGraph(); assertNull(fg.getEventListener()); Discrete d = new Discrete(DiscreteDomain.bit()); fg.addVariables(d); assertTrue(logger.isClear()); logger.log(TestEvent.class); // no effect assertTrue(logger.isClear()); logger.log(TestEvent.class, fg); assertFalse(logger.isClear()); DimpleEventListener listener = env.getEventListener(); assertSame(listener, fg.getEventListener()); listener.raiseEvent(new TestEvent(fg)); List<DimpleEventLogger.LogEntry> entries = logger.logEntries(); assertEquals(1, entries.size()); assertEquals(fg, entries.get(0).eventSource()); assertEquals(TestEvent.class, entries.get(0).eventClass()); assertEquals("verbosity=0\n", bos.toString()); bos.reset(); logger.verbosity(1); assertEquals(1, logger.verbosity()); listener.raiseEvent(new TestEvent(fg)); assertEquals("TestEvent: verbosity=1\n", bos.toString()); bos.reset(); logger.close(); assertTrue(fg.getEventListener().isListeningFor(TestEvent.class, fg)); listener.raiseEvent(new TestEvent(fg)); assertEquals("", bos.toString()); bos.reset(); logger.clear(); assertTrue(logger.logEntries().isEmpty()); assertTrue(logger.isClear()); assertNull(fg.getEventListener()); assertFalse(listener.isListeningFor(TestEvent.class, fg)); // Make sure that logger will not replace an existing listener with the default listener listener = new DimpleEventListener(); listener.block(FactorAddEvent.class, true, fg); fg.setEventListener(listener); logger.log(TestEvent.class, fg); assertTrue(listener.isListeningFor(TestEvent.class, fg)); assertSame(listener, fg.getEventListener()); assertFalse(listener.isDefault()); entries = logger.logEntries(); assertEquals(1, entries.size()); assertSame(TestEvent.class, entries.get(0).eventClass()); logger.open(out = new PrintStream(bos)); listener.raiseEvent(new TestEvent(fg)); assertEquals("TestEvent: verbosity=1\n", bos.toString()); bos.reset(); assertEquals(0, logger.unlog(TestEvent.class, d)); assertEquals(0, logger.unlog(DimpleEvent.class, fg)); assertEquals(1, logger.unlog(TestEvent.class, fg)); assertEquals(0, logger.logEntries().size()); logger.log(TestEvent.class, d); logger.log(TestEvent.class, fg); assertEquals(2, logger.logEntries().size()); logger.clear(); assertEquals(0, logger.logEntries().size()); assertSame(listener, fg.getEventListener()); logger.log(TestEvent.class, d); assertTrue(listener.isListeningFor(TestEvent.class, d)); fg.setEventListener(null); assertTrue(listener.isListeningFor(TestEvent.class, d)); // No entry removed because listener has changed. assertEquals(0, logger.unlog(TestEvent.class, d)); assertEquals(1, logger.logEntries().size()); logger.clear(); } private static class TestEvent extends DimpleEvent { private static final long serialVersionUID = 1L; TestEvent(IDimpleEventSource source) { super(source); } @Override protected void printDetails(PrintStream out, int verbosity) { out.format("verbosity=%d", verbosity); } @Override public @Nullable IModelEventSource getModelObject() { IDimpleEventSource src = getSource(); return src != null ? src.getModelEventSource() : null; } } private void assertFile(File file, String ... expectedLines) throws IOException { List<String> actualLines = Files.readLines(file, Charset.defaultCharset()); assertArrayEquals(expectedLines, actualLines.toArray()); } }