diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..8553a0fb --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,52 @@ +name: Java CI Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Run Tests + run: mvn test + + # Generate and report coverage without failing + - name: Generate Coverage Report + run: mvn jacoco:report + + - name: Report Coverage + run: | + COVERAGE=$(mvn jacoco:report | grep -oP 'Total coverage: \K[0-9.]+' || echo "unknown") + echo "Current test coverage: $COVERAGE%" + + - name: Upload Coverage Report + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: target/site/jacoco/ + retention-days: 5 + + # Optional: Comment test results on PR + - name: Add Test Results Comment + uses: marocchino/sticky-pull-request-comment@v2 + if: github.event_name == 'pull_request' + with: + message: | + ### Test Results Summary + ✅ Tests completed + 📊 Coverage: ${{ env.COVERAGE }}% + + Coverage report available in workflow artifacts diff --git a/README.md b/README.md index fe2e10a4..74634af5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ DIY Layout Creator (DIYLC) is a specialized software tool designed for hobbyists
  • group components together and treat them as one, e.g. move, edit or delete
  • export the output to image, PDF or printer
  • export PCB trace mask suitable for toner transfer
  • -
  • export the circuit to a SPICE compatible netlist (beta)
  • +
  • export PCB designs to Gerber for fabrication
  • create a Bill of Materials as a part of the project or export it to few different file formats
  • analyze guitar wirings and show detailed pickup configuration in each switch configuration
  • zoom in/out feature
  • diff --git a/diylc/.DS_Store b/diylc/.DS_Store index 9caebd44..ba7e385a 100644 Binary files a/diylc/.DS_Store and b/diylc/.DS_Store differ diff --git a/diylc/.github/workflows/test.yml b/diylc/.github/workflows/test.yml new file mode 100644 index 00000000..0b7d7c72 --- /dev/null +++ b/diylc/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test Build + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + path: diy-layout-creator + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: | + cd diy-layout-creator/diylc + mvn -B test --file pom.xml \ No newline at end of file diff --git a/diylc/.github/workflows/tests.yml b/diylc/.github/workflows/tests.yml new file mode 100644 index 00000000..f9d01b4d --- /dev/null +++ b/diylc/.github/workflows/tests.yml @@ -0,0 +1,51 @@ +name: Java CI Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: '11' # Adjust version as needed + distribution: 'temurin' + cache: maven + + - name: Run Tests + run: mvn test + + # Generate and report coverage without failing + - name: Generate Coverage Report + run: mvn jacoco:report + + - name: Report Coverage + run: | + COVERAGE=$(mvn jacoco:report | grep -oP 'Total coverage: \K[0-9.]+' || echo "unknown") + echo "Current test coverage: $COVERAGE%" + + - name: Upload Coverage Report + uses: actions/upload-artifact@v3 + with: + name: coverage-report + path: target/site/jacoco/ + + # Optional: Comment test results on PR + - name: Add Test Results Comment + uses: marocchino/sticky-pull-request-comment@v2 + if: github.event_name == 'pull_request' + with: + message: | + ### Test Results Summary + ✅ Tests completed + 📊 Coverage: ${{ env.COVERAGE }}% + + Coverage report available in workflow artifacts \ No newline at end of file diff --git a/diylc/README.md b/diylc/README.md new file mode 100644 index 00000000..3b96434f --- /dev/null +++ b/diylc/README.md @@ -0,0 +1 @@ +[![Java CI Tests](https://github.com/{owner}/{repo}/actions/workflows/tests.yml/badge.svg)](https://github.com/{owner}/{repo}/actions/workflows/tests.yml) \ No newline at end of file diff --git a/diylc/diylc-core/.classpath b/diylc/diylc-core/.classpath deleted file mode 100644 index ad4f9a9e..00000000 --- a/diylc/diylc-core/.classpath +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/diylc/diylc-core/.project b/diylc/diylc-core/.project index 8ea4afa3..f030609a 100644 --- a/diylc/diylc-core/.project +++ b/diylc/diylc-core/.project @@ -5,30 +5,7 @@ - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.jdt.core.javanature - - - 1741597028960 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - diff --git a/diylc/diylc-core/pom.xml b/diylc/diylc-core/pom.xml index 65ad66a3..77b60fe1 100644 --- a/diylc/diylc-core/pom.xml +++ b/diylc/diylc-core/pom.xml @@ -92,11 +92,5 @@ system ${project.basedir}/../lib/java-http-proxy.jar - - org.mockito - mockito-core - 5.3.1 - test - diff --git a/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java b/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java index 575b2a77..ba31063a 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java +++ b/diylc/diylc-core/src/main/java/org/diylc/core/annotations/EditableProperty.java @@ -25,7 +25,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import org.diylc.core.AllowAllValidator; -import org.diylc.core.IDynamicPropertySource; import org.diylc.core.IPropertyValidator; /** diff --git a/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java b/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java new file mode 100644 index 00000000..64fd22f3 --- /dev/null +++ b/diylc/diylc-core/src/main/java/org/diylc/netlist/NetlistAnalyzer.java @@ -0,0 +1,281 @@ +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + */ +package org.diylc.netlist; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.diylc.core.IDIYComponent; + +public abstract class NetlistAnalyzer { + + public NetlistAnalyzer() { + } + + public List summarize(List netlists, Node preferredOutput) + throws TreeException { + Map summaries = new HashMap(); + for (Netlist n : netlists) { + Summary s = summarize(n, preferredOutput); + if (summaries.containsKey(s.getSummary())) + summaries.get(s.getSummary()).append(n); + else + summaries.put(s.getSummary(), s); + } + + List res = new ArrayList(summaries.values()); + Collections.sort(res); + return res; + } + + protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException; + + public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) { + Tree tree = new Tree(TreeConnectionType.Parallel); + connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), + new HashSet()); + + return tree; + } + + protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List concurrentPaths, + Tree currentPath, Set visited) { + if (nodeA == nodeB) { + concurrentPaths.add(currentPath); + return; + } + + Group groupA = findGroup(netlist, nodeA); + if (groupA == null) + return; + + if (groupA.getNodes().contains(nodeB)) { + concurrentPaths.add(currentPath); + return; + } + + Set pathVisited = new HashSet<>(visited); + pathVisited.add(nodeA); + + // First collect all immediate next nodes and their paths + Map> nextNodes = new HashMap<>(); + for (Node n : groupA.getNodes()) { + if (pathVisited.contains(n)) + continue; + + IDIYComponent c = n.getComponent(); + for (int i = 0; i < c.getControlPointCount(); i++) { + int targetPoint = i; + int sourcePoint = n.getPointIndex(); + + if (targetPoint == sourcePoint) + continue; + + if (c.getInternalLinkName(targetPoint, sourcePoint) != null) { + Node newNodeA = new Node(c, targetPoint, n.getZIndex()); + if (pathVisited.contains(newNodeA)) + continue; + + try { + Tree newPath = (Tree) currentPath.clone(); + TreeLeaf leaf = new TreeLeaf(c, targetPoint, sourcePoint); + Tree newItem = new Tree(leaf); + + if (!newPath.getChildren().contains(newItem)) { + newPath.getChildren().add(newItem); + nextNodes.computeIfAbsent(newNodeA, k -> new ArrayList<>()).add(newPath); + } + } catch (CloneNotSupportedException e) { + // Skip this path if clone fails + } + } + } + } + + // Now explore each next node + List allPaths = new ArrayList<>(); + for (Map.Entry> entry : nextNodes.entrySet()) { + for (Tree path : entry.getValue()) { + List branchPaths = new ArrayList<>(); + connectNodes(netlist, entry.getKey(), nodeB, branchPaths, path, pathVisited); + allPaths.addAll(branchPaths); + } + } + + if (allPaths.isEmpty()) + return; + + if (allPaths.size() > 1) { + // Find common prefix among all paths + List commonPrefix = findCommonElements(allPaths, true, false); + + // Create a new tree for the merged result + Tree mergedTree = new Tree(TreeConnectionType.Series); + + // Add common prefix elements + for (Tree prefixElement : commonPrefix) { + mergedTree.getChildren().add(prefixElement); + } + + // Extract unique parts + List uniqueParts = new ArrayList<>(); + for (Tree path : allPaths) { + Tree uniquePart = extractUniquePart(path, commonPrefix.size(), 0); + if (uniquePart != null) { + if (uniquePart.getChildren().size() == 1) { + uniqueParts.add(uniquePart.getChildren().get(0)); + } else { + uniqueParts.add(uniquePart); + } + } + } + + // Create parallel section for unique parts + if (!uniqueParts.isEmpty()) { + Tree parallelSection = new Tree(TreeConnectionType.Parallel); + parallelSection.getChildren().addAll(uniqueParts); + + // Add parallel section to series container + Tree parallelContainer = new Tree(TreeConnectionType.Series); + parallelContainer.getChildren().add(parallelSection); + mergedTree.getChildren().add(parallelContainer); + } + + concurrentPaths.add(mergedTree); + } else { + concurrentPaths.add(allPaths.get(0)); + } + } + + private List findCommonElements(List paths, boolean fromStart, boolean backward) { + if (paths.isEmpty()) + return new ArrayList<>(); + + List common = new ArrayList<>(); + Tree template = paths.get(0); + int maxLength = template.getChildren().size(); + + for (int i = 0; i < maxLength; i++) { + int index = fromStart ? + (backward ? template.getChildren().size() - i - 1 : i) : + (backward ? i : template.getChildren().size() - i - 1); + + if (index < 0 || index >= template.getChildren().size()) + break; + + Tree element = template.getChildren().get(index); + boolean isCommon = true; + + for (int j = 1; j < paths.size(); j++) { + Tree current = paths.get(j); + if (current.getChildren().size() <= i || index >= current.getChildren() + .size() || !current.getChildren().get(index).equals(element)) { + isCommon = false; + break; + } + } + + if (isCommon) { + common.add(element); + } else { + break; + } + } + + return common; + } + + private Tree extractUniquePart(Tree path, int prefixSize, int suffixSize) { + if (path.getChildren().size() <= prefixSize + suffixSize) + return null; + + Tree uniquePart = new Tree(TreeConnectionType.Series); + for (int i = prefixSize; i < path.getChildren().size() - suffixSize; i++) { + uniquePart.getChildren().add(path.getChildren().get(i)); + } + + return uniquePart.getChildren().isEmpty() ? null : uniquePart; + } + + protected Group findGroup(Netlist netlist, Node node) { + for (Group g : netlist.getGroups()) + if (g.getNodes().contains(node)) + return g; + return null; + } + + protected List find(Set typeNames, String nodeName, Netlist netlist) { + List res = new ArrayList(); + for (Group g : netlist.getGroups()) { + for (Node n : g.getNodes()) { + if (typeNames.contains(n.getComponent().getClass() + .getCanonicalName()) && (nodeName == null || n.getDisplayName() + .equalsIgnoreCase(nodeName))) { + res.add(n); + } + } + } + return res; + } + + public static List>> extractComponentGroups(List netlists) { + List>> res = new ArrayList>>(); + for (Netlist n : netlists) { + res.addAll(extractComponentGroups(n)); + } + return res; + } + + public static List>> extractComponentGroups(Netlist netlist) { + List>> res = new ArrayList>>(); + for (Group g : netlist.getGroups()) { + Set> components = new HashSet>(); + for (Node n : g.getNodes()) + components.add(n.getComponent()); + res.add(components); + } + return res; + } + + protected int find(Node node, List groups) { + for (int i = 0; i < groups.size(); i++) + if (groups.get(i).getNodes().contains(node)) + return i; + return -1; + } + + protected boolean intersect(List groups, Node node) { + for (Group g : groups) + if (g.getNodes().contains(node)) + return true; + return false; + } + + protected Node intersect(List groups, Group group) { + for (Group g : groups) + for (Node node : group.getNodes()) + if (g.getNodes().contains(node)) + return node; + return null; + } +} diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java index 7a865ddf..7503354c 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java +++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/ComponentProcessor.java @@ -41,9 +41,16 @@ import org.diylc.common.IComponentTransformer; import org.diylc.common.PropertyWrapper; import org.diylc.core.CreationMethod; import org.diylc.core.IDIYComponent; + import org.diylc.core.IDynamicPropertySource; import org.diylc.core.IPropertyValidator; import org.diylc.core.annotations.*; + +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; + import org.diylc.lang.LangUtil; /** diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java index ef28e0cc..c7e38eaf 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java +++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/InstantiationManager.java @@ -36,7 +36,9 @@ import org.apache.log4j.Logger; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.clipboard.ComponentTransferable; + import org.diylc.common.*; + import org.diylc.core.Angle; import org.diylc.core.CreationMethod; import org.diylc.core.IDIYComponent; diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index c4834eaf..967e8b2a 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -1,5 +1,5 @@ - + 4 @@ -12,27 +12,27 @@ NEW_FEATURE Buzzer component and symbol added (thanks M0JXD) - + NEW_FEATURE Resistor symbol now has two draw standards - ANSI and IEC (thanks M0JXD) - + IMPROVEMENT Fixed run.sh application starter for Linux and Apple OSX with M1/M2 processors when using Java 17 or newer - + IMPROVEMENT When editing Label components, default focus to the text editor - + BUG_FIX Unable to move selected components if one of them is close to being reduced to a point - + BUG_FIX Toroidal Inductor hangs the application if it doesn't have inductance value set - + https://github.com/bancika/diy-layout-creator/releases @@ -48,7 +48,7 @@ IMPROVEMENT Upgraded JRE version of Mac builds to Temurin 17 and switched OpenGL to Metal rendering engine for improved performance - + BUG_FIX Choosing "Print" option from the menu starts printing immediately before choosing printing preferences @@ -88,7 +88,7 @@ NEW_FEATURE Ability to change pitch and appearance of PCB Terminal Block component - + IMPROVEMENT Better rendering of the effective circuit graph in the guitar wiring analyzer, showing series and parallel connections in a more intuitive way @@ -188,7 +188,7 @@ BUG_FIX 'Highlight Continuity Areas' sometimes renders stale areas when clicked - + https://github.com/bancika/diy-layout-creator/releases @@ -200,7 +200,7 @@ 2025-03-08 00:00:00.000 CET - + BUG_FIX Do not mirror bottom layers for Gerber export as fabrication service providers expect a top view for everything @@ -220,7 +220,7 @@ 2025-03-09 00:00:00.000 CET - + NEW_FEATURE Switched to AppImage distribution for Linux system, abandoning Flatpak as a means of distribution. DIYLC AppImage will be available alongside with other executables on the official DIYLC GitHub page. @@ -251,11 +251,6 @@ NEW_FEATURE - 'Virtual Multimeter' from 'Analyze' menu traces the circuit finding all possible paths of electricity between two points designated by the probe symbol. - - - NEW_FEATURE - Added ability to highlight connected switch lugs in selected position in order to illustrate how it works internally. Configurable 'High DPI Rendering' feature which makes the diagram smoother on high-resolution displays but can affect performance @@ -272,10 +267,11 @@ IMPROVEMENT - Improved robustness of series/parallel graph construction code used in circuit analysis + Omit boards, wires, traces, terminals, etc from Spice netlist output + IMPROVEMENT - Omit boards, wires, traces, terminals, etc from Spice netlist output + Updated the windows installer to avoid false positive virus detection BUG_FIX @@ -288,5 +284,25 @@ https://github.com/bancika/diy-layout-creator/releases + + + 5 + 2 + 0 + + 2025-03-20 00:00:00.000 CET + + + + NEW_FEATURE + 'Virtual Multimeter' from 'Analyze' menu traces the circuit finding all possible paths of electricity between two points designated by the probe symbol. + + + NEW_FEATURE + Added ability to highlight connected switch lugs in selected position in order to illustrate how it works internally. + + + https://github.com/bancika/diy-layout-creator/releases + diff --git a/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java b/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java index 98cf2fbd..7086d32e 100644 --- a/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java +++ b/diylc/diylc-core/src/test/java/org/diylc/netlist/TreeAsciiUtilTest.java @@ -9,6 +9,9 @@ import java.util.Collections; import java.util.List; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.junit.Test; import org.diylc.netlist.TreeAsciiUtil; diff --git a/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java b/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java index b0dc53f9..f8047716 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java +++ b/diylc/diylc-library/src/main/java/org/diylc/netlist/GuitarDiagramAnalyzer.java @@ -46,6 +46,14 @@ import org.diylc.components.passive.RadialFilmCapacitor; import org.diylc.components.passive.RadialMicaCapacitor; import org.diylc.components.passive.Resistor; import org.diylc.core.IDIYComponent; +import org.diylc.netlist.Netlist; +import org.diylc.netlist.NetlistAnalyzer; +import org.diylc.netlist.Node; +import org.diylc.netlist.Summary; +import org.diylc.netlist.Tree; +import org.diylc.netlist.TreeConnectionType; +import org.diylc.netlist.TreeException; +import org.diylc.netlist.TreeLeaf; import org.diylc.netlist.Tree.ITreeWalker; public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer { diff --git a/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java b/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java index d873b294..af46a9a2 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java +++ b/diylc/diylc-library/src/main/java/org/diylc/netlist/SpiceAnalyzer.java @@ -27,6 +27,12 @@ import java.util.stream.Collectors; import org.diylc.common.INetlistAnalyzer; import org.diylc.core.IDIYComponent; +import org.diylc.netlist.Group; +import org.diylc.netlist.Netlist; +import org.diylc.netlist.NetlistAnalyzer; +import org.diylc.netlist.Node; +import org.diylc.netlist.Summary; +import org.diylc.netlist.TreeException; public class SpiceAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer { diff --git a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java index e2c74ed0..29fccfe8 100644 --- a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java +++ b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java @@ -21,8 +21,11 @@ package org.diylc.netlist; import static org.junit.Assert.assertEquals; import java.util.Arrays; +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java import org.diylc.components.passive.AxialFilmCapacitor; import org.diylc.components.passive.Resistor; +======== +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java import org.junit.Test; import org.diylc.components.electromechanical.OpenJack1_4; @@ -30,6 +33,14 @@ import org.diylc.components.guitar.HumbuckerPickup; import org.diylc.components.guitar.SingleCoilPickup; import org.diylc.components.passive.PotentiometerPanel; import org.diylc.components.passive.RadialCeramicDiskCapacitor; +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java +======== +import org.diylc.netlist.Group; +import org.diylc.netlist.GuitarDiagramAnalyzer; +import org.diylc.netlist.Netlist; +import org.diylc.netlist.Tree; +import org.diylc.netlist.TreeException; +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java public class GuitarDiagramAnalyzerTests { @@ -62,6 +73,7 @@ public class GuitarDiagramAnalyzerTests { Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); String s = tree.toString(); assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s); +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java } @Test @@ -105,6 +117,8 @@ public class GuitarDiagramAnalyzerTests { Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); String s = tree.toString(); assertEquals("(((Cbleed || Rbleed || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s); +======== +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java } @Test @@ -127,7 +141,11 @@ public class GuitarDiagramAnalyzerTests { netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup); Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); String s = tree.toString(); +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java assertEquals("((Volume.1-2 + ((Tone.2-3 + Cap) || Pickup.North<-)) || Volume.2-3)", s); +======== + assertEquals("((Volume.1-2 + (Tone.2-3 + Cap) || Pickup.North<-) || Volume.2-3)", s); +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java } @Test @@ -161,7 +179,11 @@ public class GuitarDiagramAnalyzerTests { Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); String s = tree.toString(); assertEquals( +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java "((Volume.1-2 + (Pickup1.North<- || Pickup2.North<- || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)", +======== + "((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)", +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java s); } @@ -325,7 +347,11 @@ public class GuitarDiagramAnalyzerTests { Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); String s = tree.toString(); assertEquals( +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java "((Volume.1-2 + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)", +======== + "((Volume.1-2 + (Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2)) || Volume.2-3)", +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java s); } } diff --git a/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java new file mode 100644 index 00000000..29fccfe8 --- /dev/null +++ b/diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java @@ -0,0 +1,357 @@ +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + * + */ +package org.diylc.netlist; + +import static org.junit.Assert.assertEquals; +import java.util.Arrays; + +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java +import org.diylc.components.passive.AxialFilmCapacitor; +import org.diylc.components.passive.Resistor; +======== +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java +import org.junit.Test; + +import org.diylc.components.electromechanical.OpenJack1_4; +import org.diylc.components.guitar.HumbuckerPickup; +import org.diylc.components.guitar.SingleCoilPickup; +import org.diylc.components.passive.PotentiometerPanel; +import org.diylc.components.passive.RadialCeramicDiskCapacitor; +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java +======== +import org.diylc.netlist.Group; +import org.diylc.netlist.GuitarDiagramAnalyzer; +import org.diylc.netlist.Netlist; +import org.diylc.netlist.Tree; +import org.diylc.netlist.TreeException; +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java + +public class GuitarDiagramAnalyzerTests { + + @Test + public void testOneSinglePickup() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 1); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2); + netlist.add(tipGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("Pickup.North<-", s); + } + + @Test + public void testOneSinglePickupVolPot() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol)); + Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("((Volume.1-2 + Pickup.North<-) || Volume.2-3)", s); +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java + } + + @Test + public void testOneSinglePickupVolPotTrebleBleedSeries() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + AxialFilmCapacitor cap = new AxialFilmCapacitor(); + cap.setName("Cbleed"); + Resistor resistor = new Resistor(); + resistor.setName("Rbleed"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol)); + Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(resistor, 1); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1).connect(cap, 1); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2); + Group trebleBleedGroup = new Group().connect(cap, 0).connect(resistor, 0); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(trebleBleedGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("((((Cbleed + Rbleed) || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s); + } + + @Test + public void testOneSinglePickupVolPotTrebleBleedParallel() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + AxialFilmCapacitor cap = new AxialFilmCapacitor(); + cap.setName("Cbleed"); + Resistor resistor = new Resistor(); + resistor.setName("Rbleed"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol)); + Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(resistor, 1).connect(cap, 1); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1).connect(resistor, 0).connect(cap, 0); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(((Cbleed || Rbleed || Volume.1-2) + Pickup.North<-) || Volume.2-3)", s); +======== +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java + } + + @Test + public void testOneSinglePickupVolTonePot() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + PotentiometerPanel tone = new PotentiometerPanel(); + tone.setName("Tone"); + RadialCeramicDiskCapacitor cap = new RadialCeramicDiskCapacitor(); + cap.setName("Cap"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup, vol, tone, cap)); + Group hotGroup = new Group().connect(pickup, 1).connect(vol, 0).connect(tone, 2); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); + Group sleeveGroup = + new Group().connect(jack, 1).connect(pickup, 2).connect(vol, 2).connect(cap, 0); + Group toneGroup = new Group().connect(tone, 1).connect(cap, 1); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(toneGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java + assertEquals("((Volume.1-2 + ((Tone.2-3 + Cap) || Pickup.North<-)) || Volume.2-3)", s); +======== + assertEquals("((Volume.1-2 + (Tone.2-3 + Cap) || Pickup.North<-) || Volume.2-3)", s); +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java + } + + @Test + public void testTwoSinglePickupsMasterVolSeparateTone() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup1 = new SingleCoilPickup(); + pickup1.setName("Pickup1"); + SingleCoilPickup pickup2 = new SingleCoilPickup(); + pickup2.setName("Pickup2"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + PotentiometerPanel tone1 = new PotentiometerPanel(); + tone1.setName("Tone1"); + PotentiometerPanel tone2 = new PotentiometerPanel(); + tone2.setName("Tone2"); + RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor(); + cap1.setName("Cap1"); + RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor(); + cap2.setName("Cap2"); + Netlist netlist = + new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2)); + Group hotGroup = new Group().connect(pickup1, 1).connect(vol, 0).connect(tone1, 2) + .connect(pickup2, 1).connect(tone2, 2); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 2).connect(pickup2, 2) + .connect(vol, 2).connect(cap1, 0).connect(cap2, 0); + Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1); + Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group) + .add(tone2Group); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals( +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java + "((Volume.1-2 + (Pickup1.North<- || Pickup2.North<- || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)", +======== + "((Volume.1-2 + (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2) || Pickup1.North<- || Pickup2.North<-) || Volume.2-3)", +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java + s); + } + + @Test + public void testOneSinglePickupReverse() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + SingleCoilPickup pickup = new SingleCoilPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1); + netlist.add(tipGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("Pickup.North->", s); + } + + @Test + public void testOneHumbuckerSeries() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup = new HumbuckerPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0); + Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 3); + netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(Pickup.North<- + Pickup.South<-)", s); + } + + @Test + public void testOneHumbuckerSeriesReverse() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup = new HumbuckerPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 3); + Group coilTapGroup = new Group().connect(pickup, 1).connect(pickup, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 0); + netlist.add(tipGroup).add(coilTapGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(Pickup.South-> + Pickup.North->)", s); + } + + @Test + public void testOneHumbuckerParallel() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup = new HumbuckerPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 3); + netlist.add(tipGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(Pickup.North<- || Pickup.South<-)", s); + } + + @Test + public void testOneHumbuckerParallelOutOfPhase() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup = new HumbuckerPickup(); + pickup.setName("Pickup"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup, 0).connect(pickup, 3); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup, 1).connect(pickup, 2); + netlist.add(tipGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(Pickup.North<- || Pickup.South->)", s); + } + + @Test + public void testTwoHumbuckersSeries() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup1 = new HumbuckerPickup(); + pickup1.setName("Pickup1"); + HumbuckerPickup pickup2 = new HumbuckerPickup(); + pickup2.setName("Pickup2"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0); + Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); + Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); + Group joinGroup = new Group().connect(pickup1, 3).connect(pickup2, 0); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup2, 3); + netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(joinGroup).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("(Pickup1.North<- + Pickup1.South<- + Pickup2.North<- + Pickup2.South<-)", s); + } + + @Test + public void testTwoHumbuckersParallel() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup1 = new HumbuckerPickup(); + pickup1.setName("Pickup1"); + HumbuckerPickup pickup2 = new HumbuckerPickup(); + pickup2.setName("Pickup2"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 0); + Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); + Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3); + netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-))", s); + } + + @Test + public void testTwoHumbuckersParallelOutOfPhase() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup1 = new HumbuckerPickup(); + pickup1.setName("Pickup1"); + HumbuckerPickup pickup2 = new HumbuckerPickup(); + pickup2.setName("Pickup2"); + Netlist netlist = new Netlist(Arrays.asList(jack, pickup1, pickup2)); + Group tipGroup = new Group().connect(jack, 0).connect(pickup1, 0).connect(pickup2, 3); + Group coilTapGroup1 = new Group().connect(pickup1, 1).connect(pickup1, 2); + Group coilTapGroup2 = new Group().connect(pickup2, 1).connect(pickup2, 2); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 0); + netlist.add(tipGroup).add(coilTapGroup1).add(coilTapGroup2).add(sleeveGroup); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals("((Pickup1.North<- + Pickup1.South<-) || (Pickup2.South-> + Pickup2.North->))", s); + } + + @Test + public void testTwoHumbuckersMasterVolSeparateTone() throws TreeException { + OpenJack1_4 jack = new OpenJack1_4(); + HumbuckerPickup pickup1 = new HumbuckerPickup(); + pickup1.setName("Pickup1"); + HumbuckerPickup pickup2 = new HumbuckerPickup(); + pickup2.setName("Pickup2"); + PotentiometerPanel vol = new PotentiometerPanel(); + vol.setName("Volume"); + PotentiometerPanel tone1 = new PotentiometerPanel(); + tone1.setName("Tone1"); + PotentiometerPanel tone2 = new PotentiometerPanel(); + tone2.setName("Tone2"); + RadialCeramicDiskCapacitor cap1 = new RadialCeramicDiskCapacitor(); + cap1.setName("Cap1"); + RadialCeramicDiskCapacitor cap2 = new RadialCeramicDiskCapacitor(); + cap2.setName("Cap2"); + Netlist netlist = + new Netlist(Arrays.asList(jack, pickup1, pickup2, vol, tone1, tone2, cap1, cap2)); + Group hotGroup = new Group().connect(pickup1, 0).connect(vol, 0).connect(tone1, 2) + .connect(pickup2, 0).connect(tone2, 2); + Group tipGroup = new Group().connect(jack, 0).connect(vol, 1); + Group sleeveGroup = new Group().connect(jack, 1).connect(pickup1, 3).connect(pickup2, 3) + .connect(vol, 2).connect(cap1, 0).connect(cap2, 0); + Group tone1Group = new Group().connect(tone1, 1).connect(cap1, 1); + Group tone2Group = new Group().connect(tone2, 1).connect(cap2, 1); + Group coilTap1 = new Group().connect(pickup1, 1).connect(pickup1, 2); + Group coilTap2 = new Group().connect(pickup2, 1).connect(pickup2, 2); + netlist.add(tipGroup).add(tipGroup).add(sleeveGroup).add(hotGroup).add(tone1Group) + .add(tone2Group).add(coilTap1).add(coilTap2); + Tree tree = new GuitarDiagramAnalyzer().constructTree(netlist); + String s = tree.toString(); + assertEquals( +<<<<<<<< HEAD:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarDiagramAnalyzerTests.java + "((Volume.1-2 + ((Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2))) || Volume.2-3)", +======== + "((Volume.1-2 + (Pickup1.North<- + Pickup1.South<-) || (Pickup2.North<- + Pickup2.South<-) || (Tone1.2-3 + Cap1) || (Tone2.2-3 + Cap2)) || Volume.2-3)", +>>>>>>>> master:diylc/diylc-library/src/test/java/org/diylc/netlist/GuitarNetlistAnalyzerTests.java + s); + } +} diff --git a/diylc/diylc-swing/deploy/mac/README.md b/diylc/diylc-swing/deploy/mac/README.md new file mode 100644 index 00000000..1c0f346e --- /dev/null +++ b/diylc/diylc-swing/deploy/mac/README.md @@ -0,0 +1,166 @@ +# Setting up macOS Build Environment for DIYLC + +This document describes how to set up a macOS machine for building and signing DIYLC application bundles. + +## Prerequisites + +1. **macOS System** + - macOS 11 (Big Sur) or later + - Xcode Command Line Tools installed + ```bash + xcode-select --install + ``` + +2. **Java Development Kit** + - Install JDK 17 (recommended to use SDKMAN!) + ```bash + # Install SDKMAN! + curl -s "https://get.sdkman.io" | bash + source "$HOME/.sdkman/bin/sdkman-init.sh" + + # Install JDK 17 + sdk install java 17.0.14-tem + ``` + +3. **Maven** + - Install Maven 3.9 or later + ```bash + sdk install maven + ``` + +## Apple Developer Account Setup + +1. **Apple Developer Account** + - Enroll in the [Apple Developer Program](https://developer.apple.com/programs/) + - You need a paid membership ($99/year) for distribution signing + +2. **Developer Certificate** + - Open Keychain Access + - Go to Certificate Assistant → Request a Certificate from a Certificate Authority + - Fill in your email and name + - Save to disk + - Go to [Apple Developer Certificates](https://developer.apple.com/account/resources/certificates/list) + - Create a new Developer ID Application certificate + - Download and double-click to install in Keychain + +3. **Notarization Setup** + - Create an app-specific password: + 1. Go to [Apple ID Account](https://appleid.apple.com/) + 2. Security → App-Specific Passwords → Generate Password + 3. Save this password securely + + - Create a keychain profile for notarization: + ```bash + xcrun notarytool store-credentials "AC_PASSWORD" \ + --apple-id "your.email@example.com" \ + --team-id "YOUR_TEAM_ID" \ + --password "app-specific-password" + ``` + +## Environment Configuration + +1. **Set Developer Identity** + - Find your Developer ID in Keychain Access + ```bash + security find-identity -v -p codesigning + ``` + - Set the environment variable (add to your ~/.zshrc): + ```bash + export APPLE_DEVELOPER_IDENTITY="Developer ID Application: Your Name (TEAM_ID)" + ``` + +2. **Verify Setup** + ```bash + # Verify codesign is available + codesign --version + + # Verify notarytool is available + xcrun notarytool --version + + # Verify your identity is set + echo $APPLE_DEVELOPER_IDENTITY + ``` + +## Building DIYLC + +1. **Clone the Repository** + ```bash + git clone https://github.com/bancika/diy-layout-creator.git + cd diy-layout-creator/diylc + ``` + +2. **Build for Intel Macs** + ```bash + mvn clean package -P mac-x86 + ``` + +3. **Build for Apple Silicon Macs** + ```bash + mvn clean package -P mac-arm + ``` + +4. **Build Both Architectures** + ```bash + mvn clean package -P mac-x86,mac-arm + ``` + +## Output Files + +After successful builds, you'll find these files in the `diylc-swing/target` directory: + +**Signed and Notarized Builds:** +- `diylc--osx-x86.zip` - Signed and notarized Intel build +- `diylc--osx-arm.zip` - Signed and notarized ARM build + +**Unsigned Builds:** +- `diylc--osx-x86-unsigned.zip` - Unsigned Intel build +- `diylc--osx-arm-unsigned.zip` - Unsigned ARM build + +The unsigned builds are created before the signing and notarization process and can be useful for testing or in environments where code signing is not required. + +## Troubleshooting + +1. **Signing Issues** + - Verify your certificate is valid: + ```bash + security find-identity -v -p codesigning + ``` + - Check certificate expiration in Keychain Access + +2. **Notarization Issues** + - Check notarization status: + ```bash + xcrun notarytool log --keychain-profile "AC_PASSWORD" + ``` + - Verify entitlements are correct in `deploy/mac/entitlements.plist` + +3. **Build Issues** + - Clear Maven cache: + ```bash + rm -rf ~/.m2/repository/org/diylc + ``` + - Verify JDK version: + ```bash + java -version + ``` + +## Common Issues + +1. **"The specified item could not be found in the keychain"** + - Solution: Verify your Developer ID certificate is in the keychain + - Check the exact name matches `APPLE_DEVELOPER_IDENTITY` + +2. **"No account for team found"** + - Solution: Verify your Apple Developer membership is active + - Check team ID in notarytool credentials + +3. **"The binary is not signed"** + - Solution: Check that the signing process isn't being skipped + - Verify all dependencies are properly signed + +## Support + +For additional help: +- Check the [Apple Code Signing Documentation](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution) +- File an issue on the DIYLC GitHub repository +- Contact the development team \ No newline at end of file diff --git a/diylc/diylc-swing/deploy/mac/README.txt b/diylc/diylc-swing/deploy/mac/README.txt new file mode 100644 index 00000000..2e48c691 --- /dev/null +++ b/diylc/diylc-swing/deploy/mac/README.txt @@ -0,0 +1,17 @@ +Thank you for downloading DIY Layout Creator! + +This app bundle is fully functional but not officially notarized by Apple. +To run it on your Mac, you'll need to approve it in the 'Privacy & Security' settings. + +Without this approval, macOS will mark it as potentially damaged and prevent it from opening. + +A notarized version is available, but due to Apple Developer Program costs and additional requirements, +it is exclusively offered to DIYLC Patreon supporters. For a small monthly membership fee, +you'll receive several benefits: + +- Access to the notarized version +- Early access to upcoming features +- Voting rights to influence the development roadmap +- Direct developer support + +Join our community at http://www.diy-fever.com/patreon diff --git a/diylc/diylc-swing/deploy/mac/entitlements.plist b/diylc/diylc-swing/deploy/mac/entitlements.plist new file mode 100644 index 00000000..b0612d04 --- /dev/null +++ b/diylc/diylc-swing/deploy/mac/entitlements.plist @@ -0,0 +1,20 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.debugger + + com.apple.security.get-task-allow + + com.apple.security.files.user-selected.read-write + + com.apple.security.files.downloads.read-write + + + \ No newline at end of file diff --git a/diylc/diylc-swing/pom.xml b/diylc/diylc-swing/pom.xml index 7e9de833..95c2456b 100644 --- a/diylc/diylc-swing/pom.xml +++ b/diylc/diylc-swing/pom.xml @@ -180,6 +180,17 @@ false diylc + + + org.diylc.DIYLCStarter + + + + + + *:* + + *:* @@ -190,11 +201,104 @@ - - - org.diylc.DIYLCStarter - - + false + false + true + ${project.build.directory}/dependency-reduced-pom.xml + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.1 + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.1 + + + copy-system-dependencies + prepare-package + + copy-dependencies + + + system + ${project.build.directory}/system-libs + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.1.0 + + + merge-system-jars + package + + run + + + + + + + + + + + + + + sign-jar-launcher + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -304,21 +408,22 @@ compression="gzip" /> - - + + - + + + + + JAVA_HOME="$APPDIR/usr/lib/jre" + JAVA_HOME="$APPDIR/usr/bin/jre" + - - - - - @@ -554,7 +659,7 @@ 17.0.14_7 OpenJDK17U-jre_x64_mac_hotspot_${jdk.version.file}.tar.gz https://github.com/adoptium/temurin17-binaries/releases/download/jdk-${jdk.version}/${jdk.archive.osx} - ${project.build.directory}/jre_x86 + ${project.build.directory}/jre_x86.bundle @@ -656,10 +761,158 @@