mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
add compare tool
This commit is contained in:
+1
-2
@@ -19,13 +19,12 @@
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.swing.gui;
|
||||
package org.diylc.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IView;
|
||||
|
||||
public class DummyView implements IView {
|
||||
@@ -3,6 +3,7 @@ package org.diylc.common;
|
||||
import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||
import org.diylc.plugins.chatbot.service.ChatbotService;
|
||||
import org.diylc.plugins.cloud.service.CloudService;
|
||||
import org.diylc.plugins.compare.service.CompareService;
|
||||
import org.diylc.presenter.DrawingManager;
|
||||
|
||||
public interface IServiceManager {
|
||||
@@ -11,6 +12,8 @@ public interface IServiceManager {
|
||||
|
||||
ChatbotService getChatbotService();
|
||||
|
||||
CompareService getCompareService();
|
||||
|
||||
MessageDispatcher<EventType> getMessageDispatcher();
|
||||
|
||||
DrawingManager getDrawingManager();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.diylc.plugins.compare.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record CompareResults(boolean matches, List<ConnectionDiff> connectionDiffs, List<ComponentDiff> componentDiffs) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.diylc.plugins.compare.model;
|
||||
|
||||
public record ComponentDiff(
|
||||
String componentName,
|
||||
boolean presentInCurrent
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.diylc.plugins.compare.model;
|
||||
|
||||
public record ConnectionDiff(
|
||||
String fromComponent,
|
||||
String fromNodeName,
|
||||
String toComponent,
|
||||
String toNodeName,
|
||||
boolean presentInCurrent
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package org.diylc.plugins.compare.service;
|
||||
|
||||
import org.diylc.appframework.miscutils.InMemoryConfigurationManager;
|
||||
import org.diylc.common.DummyView;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.netlist.Group;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.netlist.NetlistException;
|
||||
import org.diylc.plugins.compare.model.ConnectionDiff;
|
||||
import org.diylc.plugins.compare.model.ComponentDiff;
|
||||
import org.diylc.plugins.compare.model.CompareResults;
|
||||
import org.diylc.presenter.Presenter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CompareService {
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public CompareService(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
}
|
||||
|
||||
public CompareResults compareWith(File file) {
|
||||
Presenter presenter = new Presenter(new DummyView(), InMemoryConfigurationManager.getInstance());
|
||||
presenter.loadProjectFromFile(file.getAbsolutePath());
|
||||
try {
|
||||
List<Netlist> otherNetlists = presenter.extractNetlists(false);
|
||||
List<Netlist> thisNetlists = plugInPort.extractNetlists(false);
|
||||
if (otherNetlists.size() != 1 || thisNetlists.size() != 1) {
|
||||
return new CompareResults(false, List.of(), List.of());
|
||||
}
|
||||
return compare(thisNetlists.get(0), otherNetlists.get(0));
|
||||
} catch (NetlistException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public CompareResults compare(Netlist netlist1, Netlist netlist2) {
|
||||
// Get all groups from both netlists
|
||||
Set<Group> groups1 = netlist1.getGroups();
|
||||
Set<Group> groups2 = netlist2.getGroups();
|
||||
|
||||
// Build lists of differences
|
||||
List<ConnectionDiff> connectionDiffs = new ArrayList<>();
|
||||
List<ComponentDiff> componentDiffs = new ArrayList<>();
|
||||
|
||||
// Helper to get a unique string for a node
|
||||
java.util.function.Function<Node, String> nodeKey = node ->
|
||||
node.getComponent().getName() + ":" + node.getComponent().getControlPointNodeName(node.getPointIndex());
|
||||
|
||||
// Get all component names from both netlists
|
||||
Set<String> components1 = netlist1.getComponents().stream()
|
||||
.map(component -> component.getName())
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> components2 = netlist2.getComponents().stream()
|
||||
.map(component -> component.getName())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// Find components that are only in netlist1
|
||||
for (String component : components1) {
|
||||
if (!components2.contains(component)) {
|
||||
componentDiffs.add(new ComponentDiff(component, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Find components that are only in netlist2
|
||||
for (String component : components2) {
|
||||
if (!components1.contains(component)) {
|
||||
componentDiffs.add(new ComponentDiff(component, false));
|
||||
}
|
||||
}
|
||||
|
||||
// For each group in netlist1, check if it exists in netlist2
|
||||
for (Group group1 : groups1) {
|
||||
boolean groupFound = false;
|
||||
for (Group group2 : groups2) {
|
||||
if (areGroupsEqual(group1, group2)) {
|
||||
groupFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!groupFound) {
|
||||
// If group not found, add connection differences for each pair of nodes
|
||||
List<Node> nodes = new ArrayList<>(group1.getNodes());
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
Node node = nodes.get(i);
|
||||
for (int j = i + 1; j < nodes.size(); j++) {
|
||||
Node otherNode = nodes.get(j);
|
||||
connectionDiffs.add(new ConnectionDiff(
|
||||
node.getComponent().getName(),
|
||||
node.getComponent().getControlPointNodeName(node.getPointIndex()),
|
||||
otherNode.getComponent().getName(),
|
||||
otherNode.getComponent().getControlPointNodeName(otherNode.getPointIndex()),
|
||||
true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each group in netlist2, check if it exists in netlist1
|
||||
for (Group group2 : groups2) {
|
||||
boolean groupFound = false;
|
||||
for (Group group1 : groups1) {
|
||||
if (areGroupsEqual(group1, group2)) {
|
||||
groupFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!groupFound) {
|
||||
// If group not found, add connection differences for each pair of nodes
|
||||
List<Node> nodes = new ArrayList<>(group2.getNodes());
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
Node node = nodes.get(i);
|
||||
for (int j = i + 1; j < nodes.size(); j++) {
|
||||
Node otherNode = nodes.get(j);
|
||||
connectionDiffs.add(new ConnectionDiff(
|
||||
node.getComponent().getName(),
|
||||
node.getComponent().getControlPointNodeName(node.getPointIndex()),
|
||||
otherNode.getComponent().getName(),
|
||||
otherNode.getComponent().getControlPointNodeName(otherNode.getPointIndex()),
|
||||
false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connectionDiffs.isEmpty() && componentDiffs.isEmpty()) {
|
||||
return new CompareResults(true, List.of(), List.of());
|
||||
}
|
||||
return new CompareResults(false, connectionDiffs, componentDiffs);
|
||||
}
|
||||
|
||||
private boolean areGroupsEqual(Group group1, Group group2) {
|
||||
if (group1.getNodes().size() != group2.getNodes().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper to get a unique string for a node
|
||||
java.util.function.Function<Node, String> nodeKey = node ->
|
||||
node.getComponent().getName() + ":" + node.getComponent().getControlPointNodeName(node.getPointIndex());
|
||||
|
||||
Set<String> group1Keys = group1.getNodes().stream()
|
||||
.map(nodeKey)
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> group2Keys = group2.getNodes().stream()
|
||||
.map(nodeKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return group1Keys.equals(group2Keys);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.diylc.plugins.compare.util;
|
||||
|
||||
import org.diylc.plugins.compare.model.CompareResults;
|
||||
import org.diylc.plugins.compare.model.ConnectionDiff;
|
||||
import org.diylc.plugins.compare.model.ComponentDiff;
|
||||
|
||||
public class CompareResultsHtmlReport {
|
||||
|
||||
public static String generateReport(CompareResults results) {
|
||||
StringBuilder html = new StringBuilder();
|
||||
html.append("<!DOCTYPE html>\n");
|
||||
html.append("<html>\n");
|
||||
html.append("<head>\n");
|
||||
html.append("<style>\n");
|
||||
html.append("body { font-family: Arial, sans-serif; margin: 20px; color: black; }\n");
|
||||
html.append("table { border-collapse: collapse; width: 100%; margin-top: 10px; }\n");
|
||||
html.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }\n");
|
||||
html.append("th { background-color: #f2f2f2; }\n");
|
||||
html.append(".result { font-size: 18px; }\n");
|
||||
html.append("h2 { font-size: 14px; margin-top: 20px; }\n");
|
||||
html.append("</style>\n");
|
||||
html.append("</head>\n");
|
||||
html.append("<body>\n");
|
||||
|
||||
// Start with bold results
|
||||
if (results.matches()) {
|
||||
html.append("<p class=\"result\"><strong>The circuits match exactly.</strong></p>\n");
|
||||
} else {
|
||||
html.append("<p class=\"result\"><strong>The circuits do not match.</strong></p>\n");
|
||||
}
|
||||
|
||||
if (!results.matches()) {
|
||||
if (!results.componentDiffs().isEmpty()) {
|
||||
html.append("<h2>Component Differences</h2>\n");
|
||||
html.append("<table>\n");
|
||||
html.append("<tr><th>Component</th><th>Status</th></tr>\n");
|
||||
|
||||
for (ComponentDiff diff : results.componentDiffs()) {
|
||||
html.append("<tr>\n");
|
||||
html.append("<td>").append(diff.componentName()).append("</td>\n");
|
||||
html.append("<td>");
|
||||
html.append(diff.presentInCurrent() ? "Missing in target circuit" : "Extra in target circuit");
|
||||
html.append("</td>\n");
|
||||
html.append("</tr>\n");
|
||||
}
|
||||
|
||||
html.append("</table>\n");
|
||||
}
|
||||
|
||||
if (!results.connectionDiffs().isEmpty()) {
|
||||
html.append("<h2>Connection Differences</h2>\n");
|
||||
html.append("<table>\n");
|
||||
html.append("<tr><th>From Component</th><th>From Node</th><th>To Component</th><th>To Node</th><th>Status</th></tr>\n");
|
||||
|
||||
for (ConnectionDiff diff : results.connectionDiffs()) {
|
||||
html.append("<tr>\n");
|
||||
html.append("<td>").append(diff.fromComponent()).append("</td>\n");
|
||||
html.append("<td>").append(diff.fromNodeName()).append("</td>\n");
|
||||
html.append("<td>").append(diff.toComponent()).append("</td>\n");
|
||||
html.append("<td>").append(diff.toNodeName()).append("</td>\n");
|
||||
html.append("<td>");
|
||||
html.append(diff.presentInCurrent() ? "Missing in target circuit" : "Extra in target circuit");
|
||||
html.append("</td>\n");
|
||||
html.append("</tr>\n");
|
||||
}
|
||||
|
||||
html.append("</table>\n");
|
||||
}
|
||||
}
|
||||
|
||||
html.append("</body>\n");
|
||||
html.append("</html>");
|
||||
|
||||
return html.toString();
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ import org.diylc.netlist.NetlistBuilder;
|
||||
import org.diylc.netlist.NetlistException;
|
||||
import org.diylc.plugins.chatbot.service.ChatbotService;
|
||||
import org.diylc.plugins.cloud.service.CloudService;
|
||||
import org.diylc.plugins.compare.service.CompareService;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.test.DIYTest;
|
||||
import org.diylc.test.Snapshot;
|
||||
@@ -2831,6 +2832,16 @@ public class Presenter implements IPlugInPort {
|
||||
return chatbotService;
|
||||
}
|
||||
|
||||
private CompareService compareService;
|
||||
|
||||
@Override
|
||||
public CompareService getCompareService() {
|
||||
if (compareService == null) {
|
||||
compareService = new CompareService(this);
|
||||
}
|
||||
return compareService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageDispatcher<EventType> getMessageDispatcher() {
|
||||
return messageDispatcher;
|
||||
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
package org.diylc.plugins.compare.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.netlist.Group;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.plugins.compare.model.ConnectionDiff;
|
||||
import org.diylc.plugins.compare.model.ComponentDiff;
|
||||
import org.diylc.plugins.compare.model.CompareResults;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CompareServiceTest {
|
||||
|
||||
private CompareService compareService;
|
||||
private IPlugInPort mockPlugInPort;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mockPlugInPort = mock(IPlugInPort.class);
|
||||
compareService = new CompareService(mockPlugInPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_IdenticalNetlists() {
|
||||
Map<String, IDIYComponent<?>> componentMap = new HashMap<>();
|
||||
Netlist netlist1 = createNetlist(componentMap, "Component1", "Node1", "Component2", "Node2");
|
||||
Netlist netlist2 = createNetlist(componentMap, "Component1", "Node1", "Component2", "Node2");
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(results.matches());
|
||||
assertTrue(results.connectionDiffs().isEmpty());
|
||||
assertTrue(results.componentDiffs().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MissingConnectionsInSecondNetlist() {
|
||||
Map<String, IDIYComponent<?>> componentMap1 = new HashMap<>();
|
||||
Map<String, IDIYComponent<?>> componentMap2 = new HashMap<>();
|
||||
// Group will have 3 nodes
|
||||
Netlist netlist1 = createNetlist(componentMap1, "Component1", "Node1", "Component2", "Node2", "Component3", "Node3");
|
||||
Netlist netlist2 = createNetlist(componentMap2, "Component1", "Node1"); // Missing group with 2 nodes
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(!results.matches());
|
||||
// 2 components missing in second netlist = 2 component diffs
|
||||
assertEquals(2, results.componentDiffs().size());
|
||||
// 3 nodes = 3 connections (1-2, 1-3, 2-3)
|
||||
assertEquals(3, results.connectionDiffs().size());
|
||||
|
||||
// Verify all component diffs are from first netlist
|
||||
assertTrue(results.componentDiffs().stream().allMatch(ComponentDiff::presentInCurrent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MissingConnectionsInFirstNetlist() {
|
||||
Map<String, IDIYComponent<?>> componentMap1 = new HashMap<>();
|
||||
Map<String, IDIYComponent<?>> componentMap2 = new HashMap<>();
|
||||
// Group will have 3 nodes
|
||||
Netlist netlist1 = createNetlist(componentMap1, "Component1", "Node1");
|
||||
Netlist netlist2 = createNetlist(componentMap2, "Component1", "Node1", "Component2", "Node2", "Component3", "Node3");
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(!results.matches());
|
||||
// 2 components missing in first netlist = 2 component diffs
|
||||
assertEquals(2, results.componentDiffs().size());
|
||||
// 2 nodes = 1 connection (2-3)
|
||||
assertEquals(1, results.connectionDiffs().size());
|
||||
|
||||
// Verify all component diffs are from second netlist
|
||||
assertTrue(results.componentDiffs().stream().noneMatch(ComponentDiff::presentInCurrent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_CompletelyDifferentNetlists() {
|
||||
Map<String, IDIYComponent<?>> componentMap1 = new HashMap<>();
|
||||
Map<String, IDIYComponent<?>> componentMap2 = new HashMap<>();
|
||||
Netlist netlist1 = createNetlist(componentMap1, "Component1", "Node1", "Component2", "Node2");
|
||||
Netlist netlist2 = createNetlist(componentMap2, "Component3", "Node3", "Component4", "Node4");
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(!results.matches());
|
||||
// 4 components missing (2 in each netlist) = 4 component diffs
|
||||
assertEquals(4, results.componentDiffs().size());
|
||||
// 2 connections in each netlist = 2 connection diffs
|
||||
assertEquals(2, results.connectionDiffs().size());
|
||||
|
||||
// Verify differences from first netlist
|
||||
List<ComponentDiff> firstNetlistComponentDiffs = results.componentDiffs().stream()
|
||||
.filter(ComponentDiff::presentInCurrent)
|
||||
.toList();
|
||||
assertEquals(2, firstNetlistComponentDiffs.size());
|
||||
|
||||
// Verify differences from second netlist
|
||||
List<ComponentDiff> secondNetlistComponentDiffs = results.componentDiffs().stream()
|
||||
.filter(diff -> !diff.presentInCurrent())
|
||||
.toList();
|
||||
assertEquals(2, secondNetlistComponentDiffs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MultipleGroups_Identical() {
|
||||
Map<String, IDIYComponent<?>> componentMap = new HashMap<>();
|
||||
|
||||
// Create first netlist with two groups
|
||||
Netlist netlist1 = new Netlist(new ArrayList<>());
|
||||
netlist1.add(createGroup(componentMap, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist1.add(createGroup(componentMap, "Component3", "Node3", "Component4", "Node4"));
|
||||
|
||||
// Create second netlist with same groups
|
||||
Netlist netlist2 = new Netlist(new ArrayList<>());
|
||||
netlist2.add(createGroup(componentMap, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist2.add(createGroup(componentMap, "Component3", "Node3", "Component4", "Node4"));
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(results.matches());
|
||||
assertTrue(results.connectionDiffs().isEmpty());
|
||||
assertTrue(results.componentDiffs().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MultipleGroups_DifferentOrder() {
|
||||
Map<String, IDIYComponent<?>> componentMap = new HashMap<>();
|
||||
|
||||
// Create first netlist with two groups
|
||||
Netlist netlist1 = new Netlist(new ArrayList<>());
|
||||
netlist1.add(createGroup(componentMap, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist1.add(createGroup(componentMap, "Component3", "Node3", "Component4", "Node4"));
|
||||
|
||||
// Create second netlist with same groups but in different order
|
||||
Netlist netlist2 = new Netlist(new ArrayList<>());
|
||||
netlist2.add(createGroup(componentMap, "Component3", "Node3", "Component4", "Node4"));
|
||||
netlist2.add(createGroup(componentMap, "Component1", "Node1", "Component2", "Node2"));
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(results.matches());
|
||||
assertTrue(results.connectionDiffs().isEmpty());
|
||||
assertTrue(results.componentDiffs().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MultipleGroups_ExtraGroup() {
|
||||
Map<String, IDIYComponent<?>> componentMap1 = new HashMap<>();
|
||||
Map<String, IDIYComponent<?>> componentMap2 = new HashMap<>();
|
||||
// Each group has 2 nodes
|
||||
Netlist netlist1 = new Netlist(new ArrayList<>());
|
||||
netlist1.add(createGroup(componentMap1, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist1.add(createGroup(componentMap1, "Component3", "Node3", "Component4", "Node4"));
|
||||
Netlist netlist2 = new Netlist(new ArrayList<>());
|
||||
netlist2.add(createGroup(componentMap2, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist2.add(createGroup(componentMap2, "Component3", "Node3", "Component4", "Node4"));
|
||||
netlist2.add(createGroup(componentMap2, "Component5", "Node5", "Component6", "Node6"));
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(!results.matches());
|
||||
// 2 components in extra group = 2 component diffs
|
||||
assertEquals(2, results.componentDiffs().size());
|
||||
// 1 connection in extra group = 1 connection diff
|
||||
assertEquals(1, results.connectionDiffs().size());
|
||||
|
||||
// Verify all component diffs are from second netlist
|
||||
assertTrue(results.componentDiffs().stream().noneMatch(ComponentDiff::presentInCurrent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare_MultipleGroups_DifferentConnections() {
|
||||
Map<String, IDIYComponent<?>> componentMap1 = new HashMap<>();
|
||||
Map<String, IDIYComponent<?>> componentMap2 = new HashMap<>();
|
||||
// Each group has 2 nodes
|
||||
Netlist netlist1 = new Netlist(new ArrayList<>());
|
||||
netlist1.add(createGroup(componentMap1, "Component1", "Node1", "Component2", "Node2"));
|
||||
netlist1.add(createGroup(componentMap1, "Component3", "Node3", "Component4", "Node4"));
|
||||
Netlist netlist2 = new Netlist(new ArrayList<>());
|
||||
netlist2.add(createGroup(componentMap2, "Component1", "Node1", "Component3", "Node3"));
|
||||
netlist2.add(createGroup(componentMap2, "Component2", "Node2", "Component4", "Node4"));
|
||||
|
||||
CompareResults results = compareService.compare(netlist1, netlist2);
|
||||
|
||||
assertTrue(!results.matches());
|
||||
// No component diffs since all components exist in both netlists
|
||||
assertEquals(0, results.componentDiffs().size());
|
||||
// 2 connections in each group = 4 connection diffs
|
||||
assertEquals(4, results.connectionDiffs().size());
|
||||
}
|
||||
|
||||
private Netlist createNetlist(Map<String, IDIYComponent<?>> componentMap, String... componentNodePairs) {
|
||||
Netlist netlist = new Netlist(new ArrayList<>());
|
||||
netlist.add(createGroup(componentMap, componentNodePairs));
|
||||
return netlist;
|
||||
}
|
||||
|
||||
private Group createGroup(Map<String, IDIYComponent<?>> componentMap, String... componentNodePairs) {
|
||||
Group group = new Group();
|
||||
|
||||
for (int i = 0; i < componentNodePairs.length; i += 2) {
|
||||
String componentName = componentNodePairs[i];
|
||||
String nodeName = componentNodePairs[i + 1];
|
||||
|
||||
IDIYComponent<?> component = componentMap.computeIfAbsent(componentName, name -> {
|
||||
IDIYComponent<?> c = mock(IDIYComponent.class);
|
||||
when(c.getName()).thenReturn(name);
|
||||
when(c.getControlPointNodeName(0)).thenReturn(nodeName);
|
||||
when(c.getControlPointCount()).thenReturn(1);
|
||||
when(c.getControlPoint(0)).thenReturn(new Point2D.Double(0, 0));
|
||||
when(c.isControlPointSticky(0)).thenReturn(true);
|
||||
when(c.toString()).thenReturn(name);
|
||||
return c;
|
||||
});
|
||||
// For the same component name, update the node name for this instance
|
||||
when(component.getControlPointNodeName(0)).thenReturn(nodeName);
|
||||
Node node = new Node(component, 0);
|
||||
group.getNodes().add(node);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,7 @@ import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import javax.swing.Icon;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.swing.actions.analyze.AiAnalyzeAction;
|
||||
import org.diylc.swing.actions.analyze.HighlightConnectedAreasAction;
|
||||
import org.diylc.swing.actions.analyze.*;
|
||||
import org.diylc.swingframework.IDrawingProvider;
|
||||
|
||||
import org.diylc.common.INetlistAnalyzer;
|
||||
@@ -36,9 +35,7 @@ import org.diylc.swing.actions.ExportGerberAction;
|
||||
import org.diylc.swing.actions.ExportPNGAction;
|
||||
import org.diylc.swing.actions.FindAction;
|
||||
import org.diylc.swing.actions.FlexibleLeadsAction;
|
||||
import org.diylc.swing.actions.analyze.GenerateNetlistAction;
|
||||
import org.diylc.swing.actions.RenumberAction;
|
||||
import org.diylc.swing.actions.analyze.SummarizeNetlistAction;
|
||||
import org.diylc.swing.actions.ThemeAction;
|
||||
import org.diylc.swing.actions.ToggleAction;
|
||||
import org.diylc.swing.actions.edit.BringToFrontAction;
|
||||
@@ -280,6 +277,10 @@ public class ActionFactory {
|
||||
return new AiAnalyzeAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
public CompareAction createCompareAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
return new CompareAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
public SummarizeNetlistAction createSummarizeNetlistAction(IPlugInPort plugInPort,
|
||||
ISwingUI swingUI, INetlistAnalyzer summarizer, boolean includeSwitches) {
|
||||
return new SummarizeNetlistAction(plugInPort, swingUI, summarizer, includeSwitches);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.diylc.swing.actions.analyze;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.plugins.compare.model.CompareResults;
|
||||
import org.diylc.plugins.compare.util.CompareResultsHtmlReport;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||
import org.diylc.swingframework.TextDialog;
|
||||
import org.diylc.utils.IconLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
|
||||
public class CompareAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public CompareAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Compare With...");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Brain.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final File file = DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(),
|
||||
null, FileFilterEnum.DIY.getExtensions()[0], null);
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
swingUI.executeBackgroundTask(new ITask<CompareResults>() {
|
||||
|
||||
@Override
|
||||
public CompareResults doInBackground() throws Exception {
|
||||
return plugInPort.getCompareService().compareWith(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage(e.getMessage(), "Circuit Comparison", ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(CompareResults res) {
|
||||
String htmlReport = CompareResultsHtmlReport.generateReport(res);
|
||||
new TextDialog(swingUI.getOwnerFrame().getRootPane(), htmlReport, "Circuit Comparison",
|
||||
new Dimension(800, 600)).setVisible(true);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,7 @@ public class AnalyzeMenuPlugin implements IPlugIn {
|
||||
// Add all menu actions to the list
|
||||
menuActions.add(actionFactory.createAiAnalyzeAction(plugInPort, swingUI));
|
||||
menuActions.add(actionFactory.createCheckProximityAction(plugInPort, swingUI));
|
||||
menuActions.add(actionFactory.createCompareAction(plugInPort, swingUI));
|
||||
menuActions.add(actionFactory.createBomAction(plugInPort));
|
||||
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, false));
|
||||
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, true));
|
||||
|
||||
@@ -21,37 +21,20 @@
|
||||
*/
|
||||
package org.diylc.swing.plugins.cloud;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.InMemoryConfigurationManager;
|
||||
import org.diylc.plugins.cloud.service.CloudService;
|
||||
import org.diylc.swingframework.ButtonDialog;
|
||||
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.plugins.cloud.service.CloudException;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.gui.DummyView;
|
||||
import org.diylc.utils.IconLoader;
|
||||
import org.diylc.swing.plugins.cloud.view.ChangePasswordDialog;
|
||||
import org.diylc.swing.plugins.cloud.view.LoginDialog;
|
||||
import org.diylc.swing.plugins.cloud.view.UploadDialog;
|
||||
import org.diylc.swing.plugins.cloud.view.UserEditDialog;
|
||||
import org.diylc.common.DummyView;
|
||||
import org.diylc.swing.plugins.cloud.view.browser.CloudBrowserFrame;
|
||||
import org.diylc.swing.plugins.cloud.view.browser.UploadManagerFrame;
|
||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||
import org.diylc.swing.plugins.cloud.actions.*;
|
||||
|
||||
public class CloudPlugIn implements IPlugIn {
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.ISimpleView;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.gui.DummyView;
|
||||
import org.diylc.common.DummyView;
|
||||
import org.diylc.swing.gui.components.HTMLTextArea;
|
||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||
import org.diylc.utils.IconLoader;
|
||||
|
||||
@@ -43,7 +43,7 @@ import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.swing.gui.DummyView;
|
||||
import org.diylc.common.DummyView;
|
||||
|
||||
/**
|
||||
* {@link JComponent} that shows preview of the selected project in {@link JFileChooser}. It's
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.diylc.appframework.miscutils.InMemoryConfigurationManager;
|
||||
|
||||
import org.diylc.DIYLCStarter;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.gui.DummyView;
|
||||
import org.diylc.common.DummyView;
|
||||
|
||||
public class BatchConverter {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user