blob: ae9d7c318249fb05e4664291dba2fa3ffbf2a6b1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 Fabio Zadrozny and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fabio Zadrozny - initial API and implementation - http://eclip.se/8519
*******************************************************************************/
package org.eclipse.e4.ui.macros.tests;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.core.runtime.spi.RegistryStrategy;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.macros.CancelMacroRecordingException;
import org.eclipse.e4.core.macros.EMacroService;
import org.eclipse.e4.core.macros.IMacroInstruction;
import org.eclipse.e4.core.macros.IMacroInstructionFactory;
import org.eclipse.e4.core.macros.IMacroPlaybackContext;
import org.eclipse.e4.core.macros.IMacroStateListener;
import org.eclipse.e4.core.macros.internal.MacroManager;
import org.eclipse.e4.core.macros.internal.MacroManager.StoredMacroReference;
import org.eclipse.e4.core.macros.internal.MacroServiceImplementation;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class MacroTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private static class PlaybackContext implements IMacroPlaybackContext {
public StringBuffer buffer = new StringBuffer();
public void recordPlayback(String name) {
if (buffer.length() > 0) {
buffer.append("\n");
}
buffer.append(name);
}
private final Map<Object, Object> ctx = new HashMap<>();
@Override
public Object get(String key) {
return ctx.get(key);
}
@Override
public void set(String key, Object value) {
ctx.put(key, value);
}
}
private static class DummyMacroInstruction implements IMacroInstruction {
private String fName;
public DummyMacroInstruction(String name) {
this.fName = name;
}
@Override
public void execute(IMacroPlaybackContext macroPlaybackContext) {
((PlaybackContext) macroPlaybackContext).recordPlayback(this.fName);
}
@Override
public String getId() {
return "dummy";
}
@Override
public String toString() {
return "Dummy macro instruction";
}
@Override
public Map<String, String> toMap() {
HashMap<String, String> map = new HashMap<>();
map.put("dummyKey", "dummyValue");
map.put("name", this.fName);
return map;
}
}
@Test
public void testRecordingState() throws Exception {
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
IEclipseContext eclipseContext = EclipseContextFactory.create("testRecordingState");
IExtensionRegistry extensionRegistry = RegistryFactory.createRegistry(new RegistryStrategy(null, null), "foo",
"bar");
MacroServiceImplementation macroService = new MacroServiceImplementation(eclipseContext,
extensionRegistry);
Field field = macroService.getClass().getDeclaredField("fMacroInstructionIdToFactory");
field.setAccessible(true);
field.set(macroService, macroInstructionIdToFactory);
File root = folder.getRoot();
macroService.getMacroManager().setMacrosDirectories(root);
final StringBuilder buf = new StringBuilder();
macroService.getMacroManager().addMacroStateListener(new IMacroStateListener() {
@Override
public void macroStateChanged(EMacroService macroService, StateChange stateChange) {
buf.append("rec: ").append(macroService.isRecording()).append(" play: ")
.append(macroService.isPlayingBack()).append("\n");
}
});
Assert.assertFalse(macroService.isRecording());
Assert.assertEquals("", buf.toString());
macroService.toggleMacroRecord();
Assert.assertEquals("rec: true play: false\n", buf.toString());
buf.setLength(0);
Assert.assertTrue(macroService.isRecording());
// Add something, otherwise no macro will be recorded
macroService.addMacroInstruction(new DummyMacroInstruction("test"));
macroService.toggleMacroRecord();
Assert.assertEquals("rec: false play: false\n", buf.toString());
buf.setLength(0);
Assert.assertFalse(macroService.isRecording());
PlaybackContext playbackContext = new PlaybackContext();
macroService.getMacroManager().playbackLastMacro(macroService, playbackContext, macroInstructionIdToFactory);
Assert.assertEquals("rec: false play: true\n"
+ "rec: false play: false\n", buf.toString());
buf.setLength(0);
macroService.toggleMacroRecord();
macroService.getMacroManager().playbackLastMacro(macroService, playbackContext, macroInstructionIdToFactory);
macroService.toggleMacroRecord();
Assert.assertEquals(
"rec: true play: false\n"
+ "rec: true play: true\n"
+ "rec: true play: false\n"
+ "rec: false play: false\n",
buf.toString());
}
@Test
public void testAddMacroInstructions() throws Exception {
MacroManager macroManager = new MacroManager();
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
PlaybackContext playbackContext = new PlaybackContext();
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertTrue(macroManager.isRecording());
macroManager.addMacroInstruction(new DummyMacroInstruction("macro1"));
macroManager.addMacroInstruction(new DummyMacroInstruction("macro2"));
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertFalse(macroManager.isRecording());
macroManager.playbackLastMacro(null, playbackContext, macroInstructionIdToFactory);
Assert.assertEquals("macro1\nmacro2", playbackContext.buffer.toString());
}
@Test
public void testAddMacroInstructionPriority() throws Exception {
MacroManager macroManager = new MacroManager();
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
PlaybackContext playbackContext = new PlaybackContext();
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertTrue(macroManager.isRecording());
Object ev = new Integer(1);
macroManager.addMacroInstruction(new DummyMacroInstruction("macro1"), ev, 2);
Assert.assertEquals(1, macroManager.getLengthOfMacroBeingRecorded());
macroManager.addMacroInstruction(new DummyMacroInstruction("macro2"), ev, 1); // will not replace it
Assert.assertEquals(1, macroManager.getLengthOfMacroBeingRecorded());
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertFalse(macroManager.isRecording());
macroManager.playbackLastMacro(null, playbackContext, macroInstructionIdToFactory);
Assert.assertEquals("macro1", playbackContext.buffer.toString());
}
@Test
public void testAddMacroInstructionPriority1() throws Exception {
MacroManager macroManager = new MacroManager();
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
PlaybackContext playbackContext = new PlaybackContext();
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertTrue(macroManager.isRecording());
Object ev = new Integer(1);
macroManager.addMacroInstruction(new DummyMacroInstruction("macro1"), ev, 1);
Assert.assertEquals(1, macroManager.getLengthOfMacroBeingRecorded());
macroManager.addMacroInstruction(new DummyMacroInstruction("macro2"), ev, 2); // will replace it
Assert.assertEquals(1, macroManager.getLengthOfMacroBeingRecorded());
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
Assert.assertFalse(macroManager.isRecording());
macroManager.playbackLastMacro(null, playbackContext, macroInstructionIdToFactory);
Assert.assertEquals("macro2", playbackContext.buffer.toString());
}
@Test
public void testMacroManagerSaveRestore() throws Exception {
File root = folder.getRoot();
MacroManager macroManager = new MacroManager(root);
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
createMacroWithOneDummyMacroInstruction(macroManager, macroInstructionIdToFactory);
String[] macroNames = listTemporaryMacros(root);
Assert.assertEquals(1, macroNames.length);
// Create a new macroManager (to force getting from the disk).
macroManager = new MacroManager(root);
PlaybackContext playbackContext = new PlaybackContext();
macroManager.playbackLastMacro(null, playbackContext, macroInstructionIdToFactory);
Assert.assertEquals("macro1", playbackContext.buffer.toString());
}
@Test
public void testMacroManagerMaxNumberOfMacros() throws Exception {
File root = folder.getRoot();
MacroManager macroManager = new MacroManager(root);
macroManager.setMaxNumberOfTemporaryMacros(2);
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = makeMacroInstructionIdToFactory();
createMacroWithOneDummyMacroInstruction(macroManager, macroInstructionIdToFactory);
String[] macroNames1 = listTemporaryMacros(root);
Assert.assertEquals(macroNames1.length, 1);
// Sleep to make sure that the time of the file will be different
// (otherwise, if it runs too fast, the same time could be applied to
// the first, second and last file, in which case we may remove the
// wrong one).
sleepABit();
createMacroWithOneDummyMacroInstruction(macroManager, macroInstructionIdToFactory);
String[] macroNames2 = listTemporaryMacros(root);
Assert.assertEquals(2, macroNames2.length);
HashSet<Long> times = new HashSet<>();
List<StoredMacroReference> storedMacroReferences = macroManager.listTemporaryMacroReferences(root);
for (StoredMacroReference macroReference : storedMacroReferences) {
times.add(macroReference.fLastModified);
}
Assert.assertEquals(2, times.size());
// Now, creating a new one removes the old one
sleepABit();
createMacroWithOneDummyMacroInstruction(macroManager, macroInstructionIdToFactory);
storedMacroReferences = macroManager.listTemporaryMacroReferences(root);
String[] macroNames3 = listTemporaryMacros(root);
Assert.assertEquals(2, macroNames3.length);
for (StoredMacroReference storedMacroReference : storedMacroReferences) {
times.add(storedMacroReference.fLastModified);
}
Assert.assertEquals(3, times.size());
assertNotContains(Arrays.asList(macroNames3), macroNames1[0]);
}
private void assertNotContains(Collection<String> list, String name) {
if (list.contains(name)) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Did not expect: ").append(name).append("\nTo be in:\n");
for (String string : list) {
stringBuffer.append(string).append("\n");
}
Assert.fail(stringBuffer.toString());
}
}
private void sleepABit() {
synchronized (this) {
try {
this.wait(1000); // Sleep a full second to make sure that we have a new timestamp
// on files to make test less brittle (not all systems have
// a good precision).
} catch (InterruptedException e) {
// Ignore in this case
}
}
}
protected String[] listTemporaryMacros(File root) {
String[] files = root.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".js") && name.startsWith("temp_macro");
}
});
return files;
}
protected void createMacroWithOneDummyMacroInstruction(MacroManager macroManager,
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory) throws CancelMacroRecordingException {
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
macroManager.addMacroInstruction(new DummyMacroInstruction("macro1"));
macroManager.toggleMacroRecord(null, macroInstructionIdToFactory);
}
private Map<String, IMacroInstructionFactory> makeMacroInstructionIdToFactory() {
Map<String, IMacroInstructionFactory> macroInstructionIdToFactory = new HashMap<>();
macroInstructionIdToFactory.put("dummy", new IMacroInstructionFactory() {
@Override
public IMacroInstruction create(Map<String, String> stringMap) {
if (stringMap.size() != 2) {
throw new AssertionError("Expected map size to be 2. Found: " + stringMap.size());
}
if (!stringMap.get("dummyKey").equals("dummyValue")) {
throw new AssertionError("Did not find dummyKey->dummyValue mapping.");
}
if (stringMap.get("name") == null) {
throw new AssertionError("Expected name to be defined.");
}
return new DummyMacroInstruction(stringMap.get("name"));
}
});
return macroInstructionIdToFactory;
}
}